/*	
 *	clipm65i.h
 *
 *	P/ECE MOS6502 Emulator
 *
 *	CLiP - Common Library for P/ECE
 *	Copyright (C) 2001-2003 Naoyuki Sawa
 *
 *	* Sat Dec 07 12:00:00 JST 2003 Naoyuki Sawa
 *	- 作成開始。
 *	* Wed Mar 16 07:13:00 JST 2005 Naoyuki Sawa
 *	- m6502_runの、C言語版とAsm版の相違について、コメント追加。
 *	  C言語版のプログラムは変更済み、Asm版のプログラムは未変更です。
 *	  2005/03/16現在、C言語版とAsm版とで、サイクルカウントの動作が異なっています。
 *	* Wed Nov 18 21:37:53 JST 2015 Naoyuki Sawa
 *	- 'extern "C" {'〜'}'で囲みました。.cppを含むWin32プロジェクトからもインクルード出来るようにするためです。
 */
#ifndef __CLIP_M65I_H__
#define __CLIP_M65I_H__

#ifdef  __cplusplus
extern "C" {
#endif//__cplusplus

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

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

/*
 *	M6502構造体メンバアクセスの簡略表記
 */
/*===== レジスタ =====*/
#define A		(m6502->a)
#define X		(m6502->x)
#define Y		(m6502->y)
#define PC		(m6502->pc)
#define SP		(m6502->sp)
#define PSR		(m6502->psr)
/*===== 内部状態 =====*/
#define CYCLE		(m6502->cycle)
#define WAIT		(m6502->wait)
/*===== 外部関数 =====*/
#define READ(a)		    ((m6502->read )(m6502, (unsigned short)(a)))
#define WRITE(a, n)	do { (m6502->write)(m6502, (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)

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

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

/*
 *	インストラクションフェッチ/実行
 */
#define FETCH(n)	do {		\
	(n) = READ(PC++);		\
	M6502TRACE("%02x ", (n));	\
} while(0)
//#define EXEC()		do {				\
//	M6502TRACE("[%s]", &m6502_op_name_table[op->name]);	\
//	op->proc(m6502, code, arg);				\
//	CYCLE -= op->cycle;					\
//} while(0)
//↓※2005/03/16
//↓命令実行前にサイクルカウントを減らすよう変更しました。
//↓ATARI VCSエミュレーションにて、TIAへの書き込み前にタイミングを確定する必要があるためです。
//↓これまでに作成したプログラムで、書き込みタイミングに依存するものはなかったと思うので、
//↓この変更によって、これまでに作成したプログラムに問題が出ることはないと思います。
//↓なお、アセンブラ版ルーチン(framm65a.s m6502_run)は、まだ変更していません。
//↓P/ECE上のMOS6502エミュレーションは、既に高速版(clip65c.*)へ移行しているので、
//↓今後、低速版のアセンブラ版ルーチンを使うことは無いと思いますが、もしも使うときは修正が必要です。
#define EXEC()		do {					\
	M6502TRACE("[%s]", &m6502_op_name_table[op->name]);	\
	CYCLE -= op->cycle;					\
	op->proc(m6502, code, arg);				\
} while(0)

#ifdef  __cplusplus
}//extern "C"
#endif//__cplusplus

#endif /*__CLIP_M65I_H__*/
