/*	
 *	clipc62i.h
 *
 *	P/ECE HuC6280 Emulator
 *
 *	CLiP - Common Library for P/ECE
 *	Copyright (C) 2001-2004 Naoyuki Sawa
 *
 *	* Mon Feb 23 04:28:00 JST 2004 Naoyuki Sawa
 *	- 作成開始。
 */
#ifndef __CLIP_C62I_H__
#define __CLIP_C62I_H__

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

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

/*
 *	HUC6280構造体メンバアクセスの簡略表記
 */
/*===== レジスタ =====*/
#define P		(huc6280->p)
#define A		(huc6280->a)
#define X		(huc6280->x)
#define Y		(huc6280->y)
#define PC		(huc6280->pc)
#define S		(huc6280->s)
#define MPR_EN		(huc6280->mpr_en)
#define MPR		(huc6280->mpr)
/*===== 内部状態 =====*/
#define CYCLE		(huc6280->cycle)
#define HALT		(huc6280->halt)
#define PENDING		(huc6280->pending)
/*===== 外部関数 =====*/
#define READ(a)		    ((huc6280->read )(huc6280, (unsigned short)(a)))
#define WRITE(a, n)	do { (huc6280->write)(huc6280, (unsigned short)(a), (unsigned char)(n)); } while(0)
#define MPRSET(a, n)	do { (huc6280->mprset)(huc6280, (int)(a), (unsigned char)(n)); } while(0)
#define VDCOUT(a, n)	do { (huc6280->mprset)(huc6280, (int)(a), (unsigned char)(n)); } while(0)

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

/*
 *	16ビットレジスタの上位/下位8ビットアクセス
 */
#define LO(nn)	(*(((unsigned char*)&(nn)) + 0))			/* HostOrder(S1C33): LittleEndian */
#define HI(nn)	(*(((unsigned char*)&(nn)) + 1))			/* HostOrder(S1C33): LittleEndian */

/*
 *	16ビットメモリアクセス
 */
#define READW(a)	(READ(a) | READ((a) + 1) << 8)			/* TargetOrder(HuC6280): LittleEndian */

/*
 *	PUSH/PULL
 *
 *	* HuC6280のスタック領域は、 論理アドレス0x2100〜0x21ffです。
 *	  ちなみにゼロページ領域は、論理アドレス0x2000〜0x20ffです。
 */
#define PUSH(r)		do { WRITE(0x2100 | S, (r)); S--; } while(0)
#define PULL(r)		do { S++; (r) = READ(0x2100 | S); } while(0)
#define PUSHW(rr)	do { PUSH(HI(rr)); PUSH(LO(rr)); } while(0)	/* TargetOrder(HuC6280): LittleEndian */
#define PULLW(rr)	do { PULL(LO(rr)); PULL(HI(rr)); } while(0)	/* TargetOrder(HuC6280): LittleEndian */

/*
 *	インストラクションフェッチ/実行
 */
#define FETCH(n)	do {		\
	(n) = READ(PC++);		\
	HUC6280TRACE("%02x ", (n));	\
} while(0)
#define FETCHW(nn)	do {		\
	int hi, lo;			\
	FETCH(lo);			\
	FETCH(hi);			\
	(nn) = lo | hi << 8;		\
} while(0)
#define EXEC()		do {					\
	HUC6280TRACE("[%s]", &huc6280_op_name_table[op->name]);	\
	op->proc(huc6280, code, arg1, arg2, arg3);		\
	CYCLE -= op->cycle;					\
} while(0)

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

/* Tをクリアします。頻繁に使うので、マクロ定義しました。 */
#define CLT		do { P &= ~0x20; } while(0)

/* N,Zをセットorリセット、Tをクリア、それ以外は保持します。 */
#define TEST(n)		do { P = (P & ~0xa2) | ((n) & 0x80) | (!(n) << 1); } while(0)

#define ADC(a, b)	huc6280_ADC(huc6280, a, b)
int huc6280_ADC(HUC6280* huc6280, int a, int b);
#define SBC(a, b)	huc6280_SBC(huc6280, a, b)
int huc6280_SBC(HUC6280* huc6280, int a, int b);
#define CMP(a, b)	huc6280_CMP(huc6280, a, b)
void huc6280_CMP(HUC6280* huc6280, int a, int b);

#define AND(a, b)	huc6280_AND(huc6280, a, b)
int huc6280_AND(HUC6280* huc6280, int a, int b);
#define ORA(a, b)	huc6280_ORA(huc6280, a, b)
int huc6280_ORA(HUC6280* huc6280, int a, int b);
#define EOR(a, b)	huc6280_EOR(huc6280, a, b)
int huc6280_EOR(HUC6280* huc6280, int a, int b);
#define BIT(a, b)	huc6280_BIT(huc6280, a, b)
void huc6280_BIT(HUC6280* huc6280, int a, int b);

#define INC(a)		huc6280_INC(huc6280, a)
int huc6280_INC(HUC6280* huc6280, int a);
#define DEC(a)		huc6280_DEC(huc6280, a)
int huc6280_DEC(HUC6280* huc6280, int a);

#define ASL(a)		huc6280_ASL(huc6280, a)
int huc6280_ASL(HUC6280* huc6280, int a);
#define LSR(a)		huc6280_LSR(huc6280, a)
int huc6280_LSR(HUC6280* huc6280, int a);
#define ROL(a)		huc6280_ROL(huc6280, a)
int huc6280_ROL(HUC6280* huc6280, int a);
#define ROR(a)		huc6280_ROR(huc6280, a)
int huc6280_ROR(HUC6280* huc6280, int a);

#define ADCD(a, b)	huc6280_ADCD(huc6280, a, b)
int huc6280_ADCD(HUC6280* huc6280, int a, int b);
#define SBCD(a, b)	huc6280_SBCD(huc6280, a, b)
int huc6280_SBCD(HUC6280* huc6280, int a, int b);

#endif /*__CLIP_C62I_H__*/
