/*	
 *	clipssmi.h
 *
 *	P/ECE S-SMP (SPC700) Emulator
 *
 *	CLiP - Common Library for P/ECE
 *	Copyright (C) 2001-2004 Naoyuki Sawa
 *
 *	* Sun Jan 04 21:33:00 JST 2004 Naoyuki Sawa
 *	- 作成開始。
 */
#ifndef __CLIP_SSMI_H__
#define __CLIP_SSMI_H__

/*
 *	SSMPコア実装用のマクロを定義します。
 *	マクロ名が単純すぎて、既存の他のマクロと衝突する恐れがあるので、
 *	SSMPコアを実装するソースファイルからのみインクルードしてください。
 */

/****************************************************************************
 *
 ****************************************************************************/

/*
 *	SSMP構造体メンバアクセスの簡略表記
 */
/*===== レジスタ =====*/
#define PSW		(ssmp->psw)
#define SP		(ssmp->sp)
#define PC		(ssmp->pc)
#define YA		(ssmp->ya)
#define X		(ssmp->x)
/*===== 内部状態 =====*/
#define CYCLE		(ssmp->cycle)
#define SLEEP		(ssmp->sleep)
/*===== 外部関数 =====*/
#define READ(a)		    ((ssmp->read )(ssmp, (unsigned short)(a)))
#define WRITE(a, n)	do { (ssmp->write)(ssmp, (unsigned short)(a), (unsigned char)(n)); } while(0)

/****************************************************************************
 *
 ****************************************************************************/

/*
 *	16ビットレジスタの上位/下位8ビットアクセス
 */
#define LO(nn)		(*(((unsigned char*)&(nn)) + 0))
#define HI(nn)		(*(((unsigned char*)&(nn)) + 1))
#define PCL		LO(PC)
#define PCH		HI(PC)
#define A		LO(YA)
#define Y		HI(YA)

/*
 *	16ビットメモリアクセス
 */
#define READW(a)	(READ(a) | READ((a) + 1) << 8)
#define WRITEW(a, nn)	do { WRITE(a, LO(nn)); WRITE((a) + 1, HI(nn)); } while(0)

/*
 *	PUSH/POP
 */
#define PUSH(r)		do { WRITE(0x0100 | SP, (r)); SP--; } while(0)
#define POP(r)		do { SP++; (r) = READ(0x0100 | SP); } while(0)

/*
 *	インストラクションフェッチ/実行
 */
#define FETCH(n)	do {		\
	(n) = READ(PC++);		\
	SSMPTRACE("%02x ", (n));	\
} while(0)
#define EXEC()		do {					\
	SSMPTRACE("[%s]", &ssmp_op_name_table[op->name]);	\
	op->proc(ssmp, code, arg1, arg2);			\
	CYCLE -= op->cycle;					\
} while(0)

/****************************************************************************
 *
 ****************************************************************************/

#define TEST(a)		do { PSW = (PSW & ~0x82) | ((a)      & 0x80) | (!(a) << 1); } while(0)
#define TESTW(a)	do { PSW = (PSW & ~0x82) | ((a) >> 8 & 0x80) | (!(a) << 1); } while(0)

#define ADC(a, b)	ssmp_ADC(ssmp, (unsigned char)(a), (unsigned char)(b))
unsigned char ssmp_ADC(SSMP* ssmp, unsigned char a, unsigned char b);
#define SBC(a, b)	ssmp_SBC(ssmp, (unsigned char)(a), (unsigned char)(b))
unsigned char ssmp_SBC(SSMP* ssmp, unsigned char a, unsigned char b);
#define CMP(a, b)	ssmp_CMP(ssmp, (unsigned char)(a), (unsigned char)(b))
void ssmp_CMP(SSMP* ssmp, unsigned char a, unsigned char b);

#define AND(a, b)	ssmp_AND(ssmp, (unsigned char)(a), (unsigned char)(b))
unsigned char ssmp_AND(SSMP* ssmp, unsigned char a, unsigned char b);
#define OR(a, b)	ssmp_OR(ssmp, (unsigned char)(a), (unsigned char)(b))
unsigned char ssmp_OR(SSMP* ssmp, unsigned char a, unsigned char b);
#define EOR(a, b)	ssmp_EOR(ssmp, (unsigned char)(a), (unsigned char)(b))
unsigned char ssmp_EOR(SSMP* ssmp, unsigned char a, unsigned char b);

#define INC(a)		ssmp_INC(ssmp, (unsigned char)(a))
unsigned char ssmp_INC(SSMP* ssmp, unsigned char a);
#define DEC(a)		ssmp_DEC(ssmp, (unsigned char)(a))
unsigned char ssmp_DEC(SSMP* ssmp, unsigned char a);

#define ASL(a)		ssmp_ASL(ssmp, (unsigned char)(a))
unsigned char ssmp_ASL(SSMP* ssmp, unsigned char a);
#define LSR(a)		ssmp_LSR(ssmp, (unsigned char)(a))
unsigned char ssmp_LSR(SSMP* ssmp, unsigned char a);
#define ROL(a)		ssmp_ROL(ssmp, (unsigned char)(a))
unsigned char ssmp_ROL(SSMP* ssmp, unsigned char a);
#define ROR(a)		ssmp_ROR(ssmp, (unsigned char)(a))
unsigned char ssmp_ROR(SSMP* ssmp, unsigned char a);

#define ADDW(a, b)	ssmp_ADDW(ssmp, (unsigned short)(a), (unsigned short)(b))
unsigned short ssmp_ADDW(SSMP* ssmp, unsigned short a, unsigned short b);
#define SUBW(a, b)	ssmp_SUBW(ssmp, (unsigned short)(a), (unsigned short)(b))
unsigned short ssmp_SUBW(SSMP* ssmp, unsigned short a, unsigned short b);
#define CMPW(a, b)	ssmp_CMPW(ssmp, (unsigned short)(a), (unsigned short)(b))
void ssmp_CMPW(SSMP* ssmp, unsigned short a, unsigned short b);

#define INCW(a)		ssmp_INCW(ssmp, (unsigned short)(a))
unsigned short ssmp_INCW(SSMP* ssmp, unsigned short a);
#define DECW(a)		ssmp_DECW(ssmp, (unsigned short)(a))
unsigned short ssmp_DECW(SSMP* ssmp, unsigned short a);

#endif /*__CLIP_SSMI_H__*/
