;
;	clipc16a.h
;
;	P/ECE CP1610 Emulator
;
;	CLiP - Common Library for P/ECE
;	Copyright (C) 2001-2005 Naoyuki Sawa
;
;	* Sun May 15 21:34:00 JST 2005 Naoyuki Sawa
;	- 作成開始。
;

; clipc16a.s、framc16a.sにインクルードして使います。

;****************************************************************************
;	CP1610構造体
;****************************************************************************

				; typedef struct _CP1610 {
#define R		 0	; 	unsigned short r[8];	/* + 0,16: R0,R1,R2,R3,R4,R5,R6,R7 */
#define _SZ_		16	; 	int sz;			/* +16, 4: S------- -------- SZZZZZZZ ZZZZZZZZ */
#define C		20	; 	int c;			/* +20, 4: -------- -------C -------- -------- */
#define OV		24	; 	unsigned short ov;	/* +24, 2:                   V------- -------- */
				; 	//
#define FLAGS		26	; 	unsigned char flags;	/* +26, 1: 各種フラグ (CP1610_*の組合せ) */
#define EBC		27	; 	unsigned char ebc;	/* +27, 1: External Branch Condition (0..15) */
#define IAB		28	; 	unsigned short iab;	/* +28, 2: 割り込みベクタ ($0000..$FFFF) */
				; 	//			/* +30, 2: (パディング) */
#define _CYCLE_		32	; 	int cycle;		/* +32, 4 */
#define SIZEOF_CP1610	36	; } CP1610;			/* =36 */

/* CP1610.r[0..7] */
#define R0		(0*2)	; CP1610構造体の先頭から、r[0..7]の各レジスタフィールドへのオフセットです。
#define R1		(1*2)	;	&cp1610.r[0] == &cp1610
#define R2		(2*2)	; ですから、cp1610相対のオフセットと見なすこともできます。
#define R3		(3*2)	; 従って、たとえばr[4]にアクセスする場合、
#define R4		(4*2)	; 	xld.w %tmp, [%CPU+R+R4]
#define R5		(5*2)	; と厳密に表記しなくても、
#define R6		(6*2)	;	xld.w %tmp, [%CPU+R4]
#define R7		(7*2)	; と表記して構いません。

/* CP1610.flags */
#define IRQ_BIT		 0	; /* 割り込みが要求されたら1 */
#define IFF_BIT		 1	; /* 割り込み許可状態ならば1 */
#define DBD_BIT		 2	; /* SDBD命令実行直後ならば1 */
#define HLT_BIT		 3	; /* HLT中ならば1 */

;****************************************************************************
;	CP1610OP構造体
;****************************************************************************

; * cp1610_run()にて、%opがCP1610OP.dstを指した状態で、各命令の処理関数が呼ばれます。
;   従って、各フィールドへのオフセットシンボルは、CP1610OP.dst相対で定義してあります。
; * CP1610OP.dst相対とした理由は、命令長の節約と高速化のためです。
;   fnとcycleフィールドは、各命令の処理関数からはもう参照しないので、アクセス不要です。
;   また、dstフィールドへのアクセス頻度がいちばん高いので、dstフィールドをオフセット0で
;   アクセスできれば、命令長が短く、処理も高速になります。
;   そこで、dstフィールドへのアクセスがオフセット0となるように、%opレジスタを設定しました。
; * 各命令の処理関数から戻った後に、cp1610_run()がniフィールドにアクセスします。
;   各命令の処理関数は、%opレジスタの値を変化させないよう、注意してください。
;
				; typedef struct _CP1610OP {
				; 	void (*fn)();		/* +0,4: 命令を処理する関数 */
				; 	unsigned char cycle;	/* +4,1: 消費サイクル数 */
#define DST		 0	; 	unsigned char dst;	/* +5,1: 転送先レジスタ、分岐方向(0/-1) */
#define SRC		 1	; 	unsigned char src;	/* +6,1: 転送元レジスタ、Condition Code */
#define NI		 2	; 	unsigned char ni;	/* +7,1: bit0=割り込みマスク命令ならば1 */
				; 				/*       bit1=SDBD修飾可能な命令ならば1 */
				; } CP1610OP;			/* =8 */

;****************************************************************************
;	レジスタ割り当て
;****************************************************************************

#define op	r0		; 現在の命令に対応する、CP1610OP.dstへのポインタを保持します。
				; cp1610_run()が設定し、各命令の処理関数が利用します。
				; cp1610_run()以外の関数が、このレジスタ値を変更してはいけません。
				; 一時的にコンテキストを抜ける場合にも、値が保持されます。
#define dst	r1		; 汎用。主にCP1610OP.dstの読み込み等に利用します。
				; 各命令の処理関数や、サブルーチンにて利用します。
				; 一時的にコンテキストを抜ける場合にも、値が保持されます。
#define src	r2		; 汎用。主にCP1610OP.srcの読み込み等に利用します。
				; 各命令の処理関数や、サブルーチンにて利用します。
				; 一時的にコンテキストを抜ける場合にも、値が保持されます。
#define tmp	r3		; 汎用。
				; 各命令の処理関数や、サブルーチンにて利用します。
				; 一時的にコンテキストを抜ける場合にも、値が保持されます。
#define CPU	r4		; cp1610構造体の先頭アドレスを保持します。
				; cp1610_enter()が設定し、cp1610_leave()まで不変です。
#define SZ	r5		; CP1610.szフィールドの値を保持します。
				; cp1610_enter()にて読み出し、cp1610_leave()にて書き戻します。
#define CYCLE	r6		; CP1610.cycleフィールドの値を保持します。
				; cp1610_enter()にて読み出し、cp1610_leave()にて書き戻します。

;****************************************************************************
;	
;****************************************************************************
