/*	
 *	clipw65.h
 *
 *	P/ECE W65C02 Emulator
 *
 *	CLiP - Common Library for P/ECE
 *	Copyright (C) 2001-2005 Naoyuki Sawa
 *
 *	* Sun Apr 10 06:09:00 JST 2005 Naoyuki Sawa
 *	- 作成開始。
 */
#ifndef __CLIP_W65_H__
#define __CLIP_W65_H__

/****************************************************************************
 *	定数・構造体
 ****************************************************************************/

/* [note]
 *	* BフラグはPレジスタの中に存在しません。(http://www.nesworld.com/dev/bbrkinst.txtより引用)
 *	  ----------------------------------------------------------------------------------------
 *	   The B flag
 *	   ----------
 *	   No actual "B" flag exists inside the 6502's processor status register. 
 *	   The B flag only exists in the status flag byte pushed to the stack.
 *	   Naturally, when the flags are restored (via PLP or RTI), the B bit is discarded.
 *	   Depending on the means, the B status flag will be pushed to the stack as either 0 or 1.
 *	    software instructions BRK & PHP will push the B flag as being 1.
 *	    hardware interrupts IRQ & NMI will push the B flag as being 0.
 *	  ----------------------------------------------------------------------------------------
 *	* W65C02構造体において、Xレジスタ値よりもYレジスタ値のフィールドを先に置いた理由は、
 *	  W65C02S Microprocessor DATA SHEET のレジスタセットの図が A,Y,X,PC,S,P の順なので、
 *	  それに合わせたためです。
 */
typedef struct _W65C02 {
	unsigned char a;	/* + 0,1          AAAAAAAA */
	unsigned char c;	/* + 1,1          -------C */
	unsigned short nz;	/* + 2,2 N------- NZZZZZZZ */
	unsigned char di;	/* + 4,1          ----DI-- */
	unsigned char v;	/* + 5,1          V------- */
	unsigned char y;	/* + 6,1          YYYYYYYY */
	unsigned char x;	/* + 7,1          XXXXXXXX */
	unsigned short pc;	/* + 8,2 PCPCPCPC PCPCPCPC */
	unsigned char s;	/* +10,1          SSSSSSSS */
	unsigned char wi;	/* +11,1          ------WI */
	int cycle;		/* +12,4 残りサイクル数    */
} W65C02;			/* =16 */

/* W65C02.flags */
#define W65C02_IRQ (1<<0)	/* IRQ保留 0=無し,1=有り */
#define W65C02_WAI (1<<1)	/* WAI状態 0=通常,1=停止 */

/****************************************************************************
 *	グローバル変数
 ****************************************************************************/

extern W65C02 w65c02; /* P/ECEの場合は高速RAMに配置 -> framw65a.s */

typedef struct _W65C02SEQ {
	unsigned char resv0;	/* (予約) */
	unsigned char resv1;	/* (予約) */
	unsigned char resv2;	/* (予約) */
	unsigned char cycle;	/* 消費サイクル数 */
	void (*fn1)();		/* ｱｸｼｮﾝ | ｱｸｼｮﾝ    | ｱｸｼｮﾝ     | jmp/jsr   */
	void (*fn2)();		/* NULL  | ｵﾍﾟﾚｰｼｮﾝ | ｱﾄﾞﾚｽﾓｰﾄﾞ | ｱﾄﾞﾚｽﾓｰﾄﾞ */
	void (*fn3)();		/* NULL  | NULL     | ｵﾍﾟﾚｰｼｮﾝ  | NULL      */
} W65C02SEQ;
extern const W65C02SEQ w65c02seq[0x100]; /* シーケンステーブル */

/****************************************************************************
 *	アプリケーション定義
 ****************************************************************************/

#ifndef PIECE
int w65c02_read(int addr);		/* メモリRead */
void w65c02_write(int addr, int data);	/* メモリWrite */
#else /*PIECE*/
/* %r1 w65c02_read(%r0); */		/* メモリRead */
/* void w65c02_write(%r0, %r1); */	/* メモリWrite */
#endif /*PIECE*/

/****************************************************************************
 *	アプリケーション用関数
 ****************************************************************************/

/* CPUをリセットします。
 */
void w65c02_reset();

/* Pレジスタ値を取得します。
 * [out]
 *	戻り値		Pレジスタ値。(NV11DIZC)
 * [note]
 *	* bit4(Bフラグ)とbit5(予約)は、常に1を返します。
 *	  Bが1固定である理由は、W65C02構造体のコメントを参照してください。
 */
#define w65c02_get_p w65c02_get_p_C /* アセンブラ版内部関数との名前衝突回避 */
int w65c02_get_p();

/* Pレジスタ値を設定します。
 * [in]
 *	p		Pレジスタ値。(NV??DIZC)
 * [note]
 *	* bit4(Bフラグ)とbit5(予約)は保持しないので、不定で構いません。
 *	  Bを保持しない理由は、W65C02構造体のコメントを参照してください。
 */
#define w65c02_set_p w65c02_set_p_C /* アセンブラ版内部関数との名前衝突回避 */
void w65c02_set_p(int p);

/* CPUを実行します。
 * [in]
 *	cycle		実行サイクル数。
 */
void w65c02_run(int cycle);

/* IRQを実行、または保留します。
 */
void w65c02_irq();

/* NMIを実行します。
 */
void w65c02_nmi();

#endif /*__CLIP_W65_H__*/
