/*	
 *	clipdmgi.c
 *
 *	P/ECE DMG-CPU Emulator
 *
 *	CLiP - Common Library for P/ECE
 *	Copyright (C) 2001-2004 Naoyuki Sawa
 *
 *	* Thu Jan 15 20:09:00 JST 2004 Naoyuki Sawa
 *	- 作成開始。
 *	* Sat Feb 19 00:02:00 JST 2005 Naoyuki Sawa
 *	- DAA命令を実装しました。
 *	* Sat Mar 05 04:41:00 JST 2005 Naoyuki Sawa
 *	- EI命令の割り込み許可を、1命令遅らせました。
 *	  これまでは、EI命令実行直後に割り込み許可していました。
 *	  1命令遅れて割り込み許可するのが、正しい動作です。
 */
#include "clip.h"
#include "clipdmgi.h"	/*DMGエミュレータ実装用マクロ*/

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

/* 無効命令を処理します。
 */
DMGFN_(ERROR)
{
	DIE();
}

/****************************************************************************
 *	8-Bit Loads
 ****************************************************************************/

#ifndef DMG_ASM

DMGFN_(LD_B_B) { B = B; }
DMGFN_(LD_B_C) { B = C; }
DMGFN_(LD_B_D) { B = D; }
DMGFN_(LD_B_E) { B = E; }
DMGFN_(LD_B_H) { B = H; }
DMGFN_(LD_B_L) { B = L; }
DMGFN_(LD_B_IHLI) { B = READ(HL); }
DMGFN_(LD_B_A) { B = A; }

DMGFN_(LD_C_B) { C = B; }
DMGFN_(LD_C_C) { C = C; }
DMGFN_(LD_C_D) { C = D; }
DMGFN_(LD_C_E) { C = E; }
DMGFN_(LD_C_H) { C = H; }
DMGFN_(LD_C_L) { C = L; }
DMGFN_(LD_C_IHLI) { C = READ(HL); }
DMGFN_(LD_C_A) { C = A; }

DMGFN_(LD_D_B) { D = B; }
DMGFN_(LD_D_C) { D = C; }
DMGFN_(LD_D_D) { D = D; }
DMGFN_(LD_D_E) { D = E; }
DMGFN_(LD_D_H) { D = H; }
DMGFN_(LD_D_L) { D = L; }
DMGFN_(LD_D_IHLI) { D = READ(HL); }
DMGFN_(LD_D_A) { D = A; }

DMGFN_(LD_E_B) { E = B; }
DMGFN_(LD_E_C) { E = C; }
DMGFN_(LD_E_D) { E = D; }
DMGFN_(LD_E_E) { E = E; }
DMGFN_(LD_E_H) { E = H; }
DMGFN_(LD_E_L) { E = L; }
DMGFN_(LD_E_IHLI) { E = READ(HL); }
DMGFN_(LD_E_A) { E = A; }

DMGFN_(LD_H_B) { H = B; }
DMGFN_(LD_H_C) { H = C; }
DMGFN_(LD_H_D) { H = D; }
DMGFN_(LD_H_E) { H = E; }
DMGFN_(LD_H_H) { H = H; }
DMGFN_(LD_H_L) { H = L; }
DMGFN_(LD_H_IHLI) { H = READ(HL); }
DMGFN_(LD_H_A) { H = A; }

DMGFN_(LD_L_B) { L = B; }
DMGFN_(LD_L_C) { L = C; }
DMGFN_(LD_L_D) { L = D; }
DMGFN_(LD_L_E) { L = E; }
DMGFN_(LD_L_H) { L = H; }
DMGFN_(LD_L_L) { L = L; }
DMGFN_(LD_L_IHLI) { L = READ(HL); }
DMGFN_(LD_L_A) { L = A; }

DMGFN_(LD_IHLI_B) { WRITE(HL, B); }
DMGFN_(LD_IHLI_C) { WRITE(HL, C); }
DMGFN_(LD_IHLI_D) { WRITE(HL, D); }
DMGFN_(LD_IHLI_E) { WRITE(HL, E); }
DMGFN_(LD_IHLI_H) { WRITE(HL, H); }
DMGFN_(LD_IHLI_L) { WRITE(HL, L); }
DMGFN_(LD_IHLI_A) { WRITE(HL, A); }

DMGFN_(LD_A_B) { A = B; }
DMGFN_(LD_A_C) { A = C; }
DMGFN_(LD_A_D) { A = D; }
DMGFN_(LD_A_E) { A = E; }
DMGFN_(LD_A_H) { A = H; }
DMGFN_(LD_A_L) { A = L; }
DMGFN_(LD_A_IHLI) { A = READ(HL); }
DMGFN_(LD_A_A) { A = A; }

DMGFN_(LD_B_n) { B = arg; }
DMGFN_(LD_C_n) { C = arg; }
DMGFN_(LD_D_n) { D = arg; }
DMGFN_(LD_E_n) { E = arg; }
DMGFN_(LD_H_n) { H = arg; }
DMGFN_(LD_L_n) { L = arg; }
DMGFN_(LD_IHLI_n) { WRITE(HL, arg); }
DMGFN_(LD_A_n) { A = arg; }

DMGFN_(LD_IBCI_A) { WRITE(BC, A); }
DMGFN_(LD_A_IBCI) { A = READ(BC); }
DMGFN_(LD_IDEI_A) { WRITE(DE, A); }
DMGFN_(LD_A_IDEI) { A = READ(DE); }

#endif /*DMG_ASM*/

DMGFN_(LDI_IHLI_A) { WRITE(HL, A); HL++; }
DMGFN_(LDI_A_IHLI) { A = READ(HL); HL++; }
DMGFN_(LDD_IHLI_A) { WRITE(HL, A); HL--; }
DMGFN_(LDD_A_IHLI) { A = READ(HL); HL--; }

DMGFN_(LDH_InI_A) { WRITE(arg | 0xff00, A); }
DMGFN_(LDH_A_InI) { A = READ(arg | 0xff00); }

DMGFN_(LD_ICI_A) { WRITE(C | 0xff00, A); }
DMGFN_(LD_A_ICI) { A = READ(C | 0xff00); }

DMGFN_(LD_InnI_A) { WRITE(arg, A); }
DMGFN_(LD_A_InnI) { A = READ(arg); }

/****************************************************************************
 *	16-Bit Loads
 ****************************************************************************/

#ifndef DMG_ASM

DMGFN_(LD_BC_nn) { BC = arg; }
DMGFN_(LD_DE_nn) { DE = arg; }
DMGFN_(LD_HL_nn) { HL = arg; }
DMGFN_(LD_SP_nn) { SP = arg; }

DMGFN_(PUSH_AF) { PUSH(AF); }
DMGFN_(PUSH_BC) { PUSH(BC); }
DMGFN_(PUSH_DE) { PUSH(DE); }
DMGFN_(PUSH_HL) { PUSH(HL); }

DMGFN_(POP_AF) { POP(AF); }
DMGFN_(POP_BC) { POP(BC); }
DMGFN_(POP_DE) { POP(DE); }
DMGFN_(POP_HL) { POP(HL); }

#endif /*DMG_ASM*/

DMGFN_(LD_InnI_SP) { WRITE16(arg, SP); }
DMGFN_(LDHL_SP_e) { /*※未検証*/
	int nn = (unsigned short)(char)arg;
	int tmp = SP + nn;
	F =							/* Z */
								/* N */
	    ((((SP & 0xfff) + (nn & 0xfff)) >> 7) & 0x20) |	/* H */
	    ((tmp >> 12) & 0x10);				/* C */
	HL = tmp;
}
DMGFN_(LD_SP_HL) { SP = HL; }

/****************************************************************************
 *	8-Bit ALU
 ****************************************************************************/

#ifndef DMG_ASM

/*	Z - Set if result is zero.
 *	N - Reset.
 *	H - Set if carry from bit 3.
 *	C - Set if carry from bit 7.
 */
void
dmg_ADD(DMG* dmg, unsigned char n)
{
	int tmp = A + n;
	F = (!(tmp & 0xff) << 7) |				/* Z */
								/* N */
	    ((((A & 0xf) + (n & 0xf)) & 0x10) << 1) |		/* H */
	    ((tmp >> 4) & 0x10);				/* C */
	A = tmp;
}

/*	Z - Set if result is zero.
 *	N - Reset.
 *	H - Set if carry from bit 3.
 *	C - Set if carry from bit 7.
 */
void
dmg_ADC(DMG* dmg, unsigned char n)
{
	int c = (F >> 4) & 1;
	int tmp = A + n + c;
	F = (!(tmp & 0xff) << 7) |				/* Z */
								/* N */
	    ((((A & 0xf) + (n & 0xf) + c) & 0x10) << 1) |	/* H */
	    ((tmp >> 4) & 0x10);				/* C */
	A = tmp;
}

/*	Z - Set if result is zero.
 *	N - Set.
 *	H - Set if borrow from bit 4.
 *	C - Set if borrow.
 *
 *	※「GameBoy(TM) CPU Manual」(GBCPUman.pdf)には
 *		H - Set if no borrow from bit 4.
 *		C - Set if no borrow.
 *	  と書いてありますが、ミスプリントだと思います。
 */
void
dmg_SUB(DMG* dmg, unsigned char n)
{
	int tmp = A - n;
	F = (!(tmp & 0xff) << 7) |				/* Z */
	    0x40 |						/* N */
	    ((((A & 0xf) - (n & 0xf)) & 0x10) << 1) |		/* H */
	    ((tmp >> 4) & 0x10);				/* C */
	A = tmp;
}

/*	Z - Set if result is zero.
 *	N - Set.
 *	H - Set if borrow from bit 4.
 *	C - Set if borrow.
 *
 *	※「GameBoy(TM) CPU Manual」(GBCPUman.pdf)には
 *		H - Set if no borrow from bit 4.
 *		C - Set if no borrow.
 *	  と書いてありますが、ミスプリントだと思います。
 */
void
dmg_SBC(DMG* dmg, unsigned char n)
{
	int c = (F >> 4) & 1;
	int tmp = A - n - c;
	F = (!(tmp & 0xff) << 7) |				/* Z */
	    0x40 |						/* N */
	    ((((A & 0xf) - (n & 0xf) - c) & 0x10) << 1) |	/* H */
	    ((tmp >> 4) & 0x10);				/* C */
	A = tmp;
}

/*	Z - Set if result is zero.
 *	N - Reset.
 *	H - Set.
 *	C - Reset.
 */
void
dmg_AND(DMG* dmg, unsigned char n)
{
	A &= n;
	F = (!A << 7) |	/* Z */
			/* N */
	    0x20;	/* H */
	    		/* C */
}

/*	Z - Set if result is zero.
 *	N - Reset.
 *	H - Reset.
 *	C - Reset.
 */
void
dmg_XOR(DMG* dmg, unsigned char n)
{
	A ^= n;
	F = (!A << 7);	/* Z */
			/* N */
			/* H */
			/* C */
}

/*	Z - Set if result is zero.
 *	N - Reset.
 *	H - Reset.
 *	C - Reset.
 */
void
dmg_OR(DMG* dmg, unsigned char n)
{
	A |= n;
	F = (!A << 7);	/* Z */
			/* N */
			/* H */
			/* C */
}

/*	Z - Set if result is zero.
 *	N - Set.
 *	H - Set if borrow from bit 4.
 *	C - Set if borrow.
 *
 *	※「GameBoy(TM) CPU Manual」(GBCPUman.pdf)には
 *		H - Set if no borrow from bit 4.
 *		C - Set if no borrow.
 *	  と書いてありますが、ミスプリントだと思います。
 */
void
dmg_CP(DMG* dmg, unsigned char n)
{
	int tmp = A - n;
	F = (!(tmp & 0xff) << 7) |			/* Z */
	    0x40 |					/* N */
	    ((((A & 0xf) - (n & 0xf)) & 0x10) << 1) |	/* H */
	    ((tmp >> 4) & 0x10);			/* C */
}

/*	Z - Set if result is zero.
 *	N - Reset.
 *	H - Set if carry from bit 3.
 *	C - Not affected.
 */
unsigned char
dmg_INC(DMG* dmg, unsigned char n)
{
	n++;
	F = (!n << 7) |			/* Z */
					/* N */
	    (!(n & 0xf) << 5) |		/* H */
	    (F & 0x10);			/* C */
	return n;
}

/*	Z - Set if reselt is zero.
 *	N - Set.
 *	H - Set if borrow from bit 4.
 *	C - Not affected.
 */
unsigned char
dmg_DEC(DMG* dmg, unsigned char n)
{
	n--;
	F = (!n << 7) |			/* Z */
	    0x40 |			/* N */
	    (((n & 0xf) == 0xf) << 5) |	/* H */
	    (F & 0x10);			/* C */
	return n;
}

#endif /*DMG_ASM*/

DMGFN_(ADD_A_B) { ADD(B); }
DMGFN_(ADD_A_C) { ADD(C); }
DMGFN_(ADD_A_D) { ADD(D); }
DMGFN_(ADD_A_E) { ADD(E); }
DMGFN_(ADD_A_H) { ADD(H); }
DMGFN_(ADD_A_L) { ADD(L); }
DMGFN_(ADD_A_IHLI) { ADD(READ(HL)); }
DMGFN_(ADD_A_A) { ADD(A); }

DMGFN_(ADC_A_B) { ADC(B); }
DMGFN_(ADC_A_C) { ADC(C); }
DMGFN_(ADC_A_D) { ADC(D); }
DMGFN_(ADC_A_E) { ADC(E); }
DMGFN_(ADC_A_H) { ADC(H); }
DMGFN_(ADC_A_L) { ADC(L); }
DMGFN_(ADC_A_IHLI) { ADC(READ(HL)); }
DMGFN_(ADC_A_A) { ADC(A); }

DMGFN_(SUB_B) { SUB(B); }
DMGFN_(SUB_C) { SUB(C); }
DMGFN_(SUB_D) { SUB(D); }
DMGFN_(SUB_E) { SUB(E); }
DMGFN_(SUB_H) { SUB(H); }
DMGFN_(SUB_L) { SUB(L); }
DMGFN_(SUB_IHLI) { SUB(READ(HL)); }
DMGFN_(SUB_A) { SUB(A); }

DMGFN_(SBC_A_B) { SBC(B); }
DMGFN_(SBC_A_C) { SBC(C); }
DMGFN_(SBC_A_D) { SBC(D); }
DMGFN_(SBC_A_E) { SBC(E); }
DMGFN_(SBC_A_H) { SBC(H); }
DMGFN_(SBC_A_L) { SBC(L); }
DMGFN_(SBC_A_IHLI) { SBC(READ(HL)); }
DMGFN_(SBC_A_A) { SBC(A); }

DMGFN_(AND_B) { AND(B); }
DMGFN_(AND_C) { AND(C); }
DMGFN_(AND_D) { AND(D); }
DMGFN_(AND_E) { AND(E); }
DMGFN_(AND_H) { AND(H); }
DMGFN_(AND_L) { AND(L); }
DMGFN_(AND_IHLI) { AND(READ(HL)); }
DMGFN_(AND_A) { AND(A); }

DMGFN_(XOR_B) { XOR(B); }
DMGFN_(XOR_C) { XOR(C); }
DMGFN_(XOR_D) { XOR(D); }
DMGFN_(XOR_E) { XOR(E); }
DMGFN_(XOR_H) { XOR(H); }
DMGFN_(XOR_L) { XOR(L); }
DMGFN_(XOR_IHLI) { XOR(READ(HL)); }
DMGFN_(XOR_A) { XOR(A); }

DMGFN_(OR_B) { OR(B); }
DMGFN_(OR_C) { OR(C); }
DMGFN_(OR_D) { OR(D); }
DMGFN_(OR_E) { OR(E); }
DMGFN_(OR_H) { OR(H); }
DMGFN_(OR_L) { OR(L); }
DMGFN_(OR_IHLI) { OR(READ(HL)); }
DMGFN_(OR_A) { OR(A); }

DMGFN_(CP_B) { CP(B); }
DMGFN_(CP_C) { CP(C); }
DMGFN_(CP_D) { CP(D); }
DMGFN_(CP_E) { CP(E); }
DMGFN_(CP_H) { CP(H); }
DMGFN_(CP_L) { CP(L); }
DMGFN_(CP_IHLI) { CP(READ(HL)); }
DMGFN_(CP_A) { CP(A); }

DMGFN_(ADD_A_n) { ADD((unsigned char)arg); } /* VC++6.0では(unsigned char)キャストしないと警告出ます。 */
DMGFN_(ADC_A_n) { ADC((unsigned char)arg); } /* P/ECE開発環境のgcc33ではキャストしなくても大丈夫です。 */
DMGFN_(SUB_n) { SUB((unsigned char)arg); }
DMGFN_(SBC_A_n) { SBC((unsigned char)arg); }
DMGFN_(AND_n) { AND((unsigned char)arg); }
DMGFN_(XOR_n) { XOR((unsigned char)arg); }
DMGFN_(OR_n) { OR((unsigned char)arg); }
DMGFN_(CP_n) { CP((unsigned char)arg); }

DMGFN_(INC_B) { INC(B); }
DMGFN_(INC_C) { INC(C); }
DMGFN_(INC_D) { INC(D); }
DMGFN_(INC_E) { INC(E); }
DMGFN_(INC_H) { INC(H); }
DMGFN_(INC_L) { INC(L); }
DMGFN_(INC_IHLI) { unsigned char tmp = READ(HL); INC(tmp); WRITE(HL, tmp); }
DMGFN_(INC_A) { INC(A); }

DMGFN_(DEC_B) { DEC(B); }
DMGFN_(DEC_C) { DEC(C); }
DMGFN_(DEC_D) { DEC(D); }
DMGFN_(DEC_E) { DEC(E); }
DMGFN_(DEC_H) { DEC(H); }
DMGFN_(DEC_L) { DEC(L); }
DMGFN_(DEC_IHLI) { unsigned char tmp = READ(HL); DEC(tmp); WRITE(HL, tmp); }
DMGFN_(DEC_A) { DEC(A); }

/****************************************************************************
 *	16-Bit Arithmetic
 ****************************************************************************/

#ifndef DMG_ASM

/*	Z - Not affected.
 *	N - Reset.
 *	H - Set if carry from bit 11.
 *	C - Set if carry from bit 15.
 */
void
dmg_ADDW(DMG* dmg, unsigned short nn)
{
	int tmp = HL + nn;
	F = (F & 0x80) |					/* Z */
								/* N */
	    ((((HL & 0xfff) + (nn & 0xfff)) >> 7) & 0x20) |	/* H */
	    ((tmp >> 12) & 0x10);				/* C */
	HL = tmp;
}

#endif /*DMG_ASM*/

DMGFN_(ADD_HL_BC) { ADDW(BC); }
DMGFN_(ADD_HL_DE) { ADDW(DE); }
DMGFN_(ADD_HL_HL) { ADDW(HL); }
DMGFN_(ADD_HL_SP) { ADDW(SP); }

DMGFN_(ADD_SP_e) { /*※未検証*/
	int nn = (unsigned short)(char)arg;
	int tmp = SP + nn;
	F =							/* Z */
								/* N */
	    ((((SP & 0xfff) + (nn & 0xfff)) >> 7) & 0x20) |	/* H */
	    ((tmp >> 12) & 0x10);				/* C */
	SP = tmp;
}

#ifndef DMG_ASM

DMGFN_(INC_BC) { BC++; }
DMGFN_(INC_DE) { DE++; }
DMGFN_(INC_HL) { HL++; }
DMGFN_(INC_SP) { SP++; }

DMGFN_(DEC_BC) { BC--; }
DMGFN_(DEC_DE) { DE--; }
DMGFN_(DEC_HL) { HL--; }
DMGFN_(DEC_SP) { SP--; }

#endif /*DMG_ASM*/

/****************************************************************************
 *	Miscellaneous
 ****************************************************************************/

/*	Z - Set if result is zero.
 *	N - Reset.
 *	H - Reset.
 *	C - Reset.
 */
unsigned char
dmg_SWAP(DMG* dmg, unsigned char n)
{
	n = (n >> 4) | (n << 4);
	F = (!n << 7);		/* Z */
				/* N */
				/* H */
				/* C */
	return n;
}

DMGFN_(NOP) { /** nop **/ }
DMGFN_(STOP) { DIE(); }
DMGFN_(HALT) { HALT = 1; }
DMGFN_(DI) { IME = 0; }
DMGFN_(EI) {
	/* EIの直後の命令を実行した後で、割り込みを許可します。
	 * すぐに割り込みを許可してしまうと、"Bubble_Bobble_(J).zip"が動作しません。
	 */
	/*{{dmg_run()からコピー*/
	const DMGOP* op;
	int tmp;
#ifdef DMG_TRACE
	dmg_dump(dmg);
#endif /*DMG_TRACE*/
	DMGTRACE("%04x: ", PC);
	FETCH(code);
	op = &dmg_op_table[code];
	if(op->argc >= 1) {
		FETCH(arg);
		if(op->argc >= 2) {
			FETCH(tmp);
			arg |= tmp << 8;
		}
	}
	EXEC();
	DMGTRACE("\n");
	/*}}dmg_run()からコピー*/
	IME = 1;
	dmg_check_pending(dmg);
}

/* * (未実装)
 *   たぶんZ80のDAAと同じ動作で、フラグの位置を変えるだけでいいと思うのですが、
 *   DAA命令を使っているソフトが見つからず、検証できないので保留としてあります。
 *   実際にDAA命令を使っているソフトを見つけてから実装する予定です。(2004/01/24)
 * ↓
 * * Sat Feb 19 00:02:00 JST 2005 Naoyuki Sawa
 * - DAA命令を実装しました。
 *   Z80エミュレーションのコードを流用して、フラグの位置を変えただけです。
 *   「Dr._Mario_(JU)_(V1.1)」がDAA命令を利用しています。
 *
 *	Z - Set if register A is zero.
 *	N - Not affected.
 *	H - Reset.
 *	C - Set or reset according to operation.
 */
DMGFN_(DAA) {
	int hi = A >> 4;     /* A[7:4] */
	int lo = A & 15;     /* A[3:0] */
	int cf = F & (1<<4); /* CF     */
	int hf = F & (1<<5); /* HF     */
	int nf = F & (1<<6); /* NF     */
	//
	int n;
	int c;
	//
	if(!nf) { /* ADD/ADC/INC */
		if(!cf) {
			if(!hf) {
				if(lo <= 9) {
					if(hi <= 9) {
						n = 0x00, c = 0;	/*( 1)*/
					} else {
						n = 0x60, c = 1;	/*( 4)*/
					}
				} else {
					if(hi <= 8) {
						n = 0x06, c = 0;	/*( 2)*/
					} else {
						n = 0x66, c = 1;	/*( 5)*/
					}
				}
			} else {
				if(hi <= 9) {
					n = 0x06, c = 0;		/*( 3)*/
				} else {
					n = 0x66, c = 1;		/*( 6)*/
				}
			}
		} else {
			if(!hf) {
				if(lo <= 9) {
					n = 0x60, c = 1;		/*( 7)*/
				} else {
					n = 0x66, c = 1;		/*( 8)*/
				}
			} else {
				n = 0x66, c = 1;			/*( 9)*/
			}
		}
	} else { /* SUB/SBC/DEC/NEG */
		if(!cf) {
			if(!hf) {
				n = 0x00, c = 0;			/*(10)*/
			} else {
				n = 0xfa, c = 0;			/*(11)*/
			}
		} else {
			if(!hf) {
				n = 0xa0, c = 1;			/*(12)*/
			} else {
				n = 0x9a, c = 1;			/*(13)*/
			}
		}
	}
	//
	A += n;                  /* A     */
	F &= (1<<6);             /* NF    */
	F |= (c<<4) | ((!A)<<7); /* CF,ZF */
}

/*	Z - Not affected.
 *	N - Set.
 *	H - Set.
 *	C - Not affected.
 */
DMGFN_(CPL) {
	A = ~A;
	F = (F & 0x90) |	/* Z,C */
	    0x60;		/* N,H */
}

/*	Z - Not affected.
 *	N - Reset.
 *	H - Reset.
 *	C - Set.
 */
DMGFN_(SCF) {
	F = (F & 0x80) |	/* Z */
				/* N */
				/* H */
	    0x10;		/* C */
}

/*	Z - Not affected.
 *	N - Reset.
 *	H - Reset.
 *	C - Complemented.
 */
DMGFN_(CCF) {
	F = (F & 0x80) |		/* Z */
					/* N */
					/* H */
	    ((F & 0x10) ^ 0x10);	/* C */
}

DMGFN_(SWAP_B) { SWAP(B); }
DMGFN_(SWAP_C) { SWAP(C); }
DMGFN_(SWAP_D) { SWAP(D); }
DMGFN_(SWAP_E) { SWAP(E); }
DMGFN_(SWAP_H) { SWAP(H); }
DMGFN_(SWAP_L) { SWAP(L); }
DMGFN_(SWAP_IHLI) { unsigned char tmp = READ(HL); SWAP(tmp); WRITE(HL, tmp); }
DMGFN_(SWAP_A) { SWAP(A); }

/****************************************************************************
 *	Rotates & Shifts
 ****************************************************************************/

/*	Z - Set if result is zero.
 *	N - Reset.
 *	H - Reset.
 *	C - Contains old bit 7 data.
 */
unsigned char
dmg_RLC(DMG* dmg, unsigned char n)
{
	unsigned char tmp = (n << 1) | (n >> 7);
	F = (!tmp << 7) |	/* Z */
				/* N */
				/* H */
	    ((n >> 3) & 0x10);	/* C */
	return tmp;
}

/*	Z - Set if result is zero.
 *	N - Reset.
 *	H - Reset.
 *	C - Contains old bit 0 data.
 */
unsigned char
dmg_RRC(DMG* dmg, unsigned char n)
{
	unsigned char tmp = (n >> 1) | (n << 7);
	F = (!tmp << 7) |	/* Z */
				/* N */
				/* H */
	    ((n << 4) & 0x10);	/* C */
	return tmp;
}

/*	Z - Set if result is zero.
 *	N - Reset.
 *	H - Reset.
 *	C - Contains old bit 7 data.
 */
unsigned char
dmg_RL(DMG* dmg, unsigned char n)
{
	unsigned char tmp = (n << 1) | ((F & 0x10) >> 4);
	F = (!tmp << 7) |	/* Z */
				/* N */
				/* H */
	    ((n >> 3) & 0x10);	/* C */
	return tmp;
}

/*	Z - Set if result is zero.
 *	N - Reset.
 *	H - Reset.
 *	C - Contains old bit 0 data.
 */
unsigned char
dmg_RR(DMG* dmg, unsigned char n)
{
	unsigned char tmp = (n >> 1) | ((F & 0x10) << 3);
	F = (!tmp << 7) |	/* Z */
				/* N */
				/* H */
	    ((n << 4) & 0x10);	/* C */
	return tmp;
}

/*	Z - Set if result is zero.
 *	N - Reset.
 *	H - Reset.
 *	C - Contains old bit 7 data.
 */
unsigned char
dmg_SLA(DMG* dmg, unsigned char n)
{
	unsigned char tmp = n << 1;
	F = (!tmp << 7) |	/* Z */
				/* N */
				/* H */
	    ((n >> 3) & 0x10);	/* C */
	return tmp;
}

/*	Z - Set if result is zero.
 *	N - Reset.
 *	H - Reset.
 *	C - Contains old bit 0 data.
 */
unsigned char
dmg_SRA(DMG* dmg, unsigned char n)
{
	unsigned char tmp = (char)n >> 1;
	F = (!tmp << 7) |	/* Z */
				/* N */
				/* H */
	    ((n << 4) & 0x10);	/* C */
	return tmp;
}

/*	Z - Set if result is zero.
 *	N - Reset.
 *	H - Reset.
 *	C - Contains old bit 0 data.
 */
unsigned char
dmg_SRL(DMG* dmg, unsigned char n)
{
	unsigned char tmp = n >> 1;
	F = (!tmp << 7) |	/* Z */
				/* N */
				/* H */
	    ((n << 4) & 0x10);	/* C */
	return tmp;
}

/*
 *	Z - Reset.
 *	N - Reset.
 *	H - Reset.
 *	C - Contains old bit 7 data.
 *
 *	※「GameBoy(TM) CPU Manual」(GBCPUman.pdf)には
 *		Z - Set if result is zero.
 *	  と書いてありますが、ミスプリントだと思います。
 */
DMGFN_(RLCA) {
	unsigned char tmp = (A << 1) | (A >> 7);
	F =			/* Z */
				/* N */
				/* H */
	    ((A >> 3) & 0x10);	/* C */
	A = tmp;
}

/*
 *	Z - Reset.
 *	N - Reset.
 *	H - Reset.
 *	C - Contains old bit 0 data.
 *
 *	※「GameBoy(TM) CPU Manual」(GBCPUman.pdf)には
 *		Z - Set if result is zero.
 *	  と書いてありますが、ミスプリントだと思います。
 */
DMGFN_(RRCA) {
	unsigned char tmp = (A >> 1) | (A << 7);
	F =			/* Z */
				/* N */
				/* H */
	    ((A << 4) & 0x10);	/* C */
	A = tmp;
}

/*
 *	Z - Reset.
 *	N - Reset.
 *	H - Reset.
 *	C - Contains old bit 7 data.
 *
 *	※「GameBoy(TM) CPU Manual」(GBCPUman.pdf)には
 *		Z - Set if result is zero.
 *	  と書いてありますが、ミスプリントだと思います。
 */
DMGFN_(RLA) {
	unsigned char tmp = (A << 1) | ((F & 0x10) >> 4);
	F =			/* Z */
				/* N */
				/* H */
	    ((A >> 3) & 0x10);	/* C */
	A = tmp;
}

/*
 *	Z - Reset.
 *	N - Reset.
 *	H - Reset.
 *	C - Contains old bit 0 data.
 *
 *	※「GameBoy(TM) CPU Manual」(GBCPUman.pdf)には
 *		Z - Set if result is zero.
 *	  と書いてありますが、ミスプリントだと思います。
 */
DMGFN_(RRA) {
	unsigned char tmp = (A >> 1) | ((F & 0x10) << 3);
	F =			/* Z */
				/* N */
				/* H */
	    ((A << 4) & 0x10);	/* C */
	A = tmp;
}

DMGFN_(RLC_B) { RLC(B); }
DMGFN_(RLC_C) { RLC(C); }
DMGFN_(RLC_D) { RLC(D); }
DMGFN_(RLC_E) { RLC(E); }
DMGFN_(RLC_H) { RLC(H); }
DMGFN_(RLC_L) { RLC(L); }
DMGFN_(RLC_IHLI) { unsigned char tmp = READ(HL); RLC(tmp); WRITE(HL, tmp); }
DMGFN_(RLC_A) { RLC(A); }

DMGFN_(RRC_B) { RRC(B); }
DMGFN_(RRC_C) { RRC(C); }
DMGFN_(RRC_D) { RRC(D); }
DMGFN_(RRC_E) { RRC(E); }
DMGFN_(RRC_H) { RRC(H); }
DMGFN_(RRC_L) { RRC(L); }
DMGFN_(RRC_IHLI) { unsigned char tmp = READ(HL); RRC(tmp); WRITE(HL, tmp); }
DMGFN_(RRC_A) { RRC(A); }

DMGFN_(RL_B) { RL(B); }
DMGFN_(RL_C) { RL(C); }
DMGFN_(RL_D) { RL(D); }
DMGFN_(RL_E) { RL(E); }
DMGFN_(RL_H) { RL(H); }
DMGFN_(RL_L) { RL(L); }
DMGFN_(RL_IHLI) { unsigned char tmp = READ(HL); RL(tmp); WRITE(HL, tmp); }
DMGFN_(RL_A) { RL(A); }

DMGFN_(RR_B) { RR(B); }
DMGFN_(RR_C) { RR(C); }
DMGFN_(RR_D) { RR(D); }
DMGFN_(RR_E) { RR(E); }
DMGFN_(RR_H) { RR(H); }
DMGFN_(RR_L) { RR(L); }
DMGFN_(RR_IHLI) { unsigned char tmp = READ(HL); RR(tmp); WRITE(HL, tmp); }
DMGFN_(RR_A) { RR(A); }

DMGFN_(SLA_B) { SLA(B); }
DMGFN_(SLA_C) { SLA(C); }
DMGFN_(SLA_D) { SLA(D); }
DMGFN_(SLA_E) { SLA(E); }
DMGFN_(SLA_H) { SLA(H); }
DMGFN_(SLA_L) { SLA(L); }
DMGFN_(SLA_IHLI) { unsigned char tmp = READ(HL); SLA(tmp); WRITE(HL, tmp); }
DMGFN_(SLA_A) { SLA(A); }

DMGFN_(SRA_B) { SRA(B); }
DMGFN_(SRA_C) { SRA(C); }
DMGFN_(SRA_D) { SRA(D); }
DMGFN_(SRA_E) { SRA(E); }
DMGFN_(SRA_H) { SRA(H); }
DMGFN_(SRA_L) { SRA(L); }
DMGFN_(SRA_IHLI) { unsigned char tmp = READ(HL); SRA(tmp); WRITE(HL, tmp); }
DMGFN_(SRA_A) { SRA(A); }

DMGFN_(SRL_B) { SRL(B); }
DMGFN_(SRL_C) { SRL(C); }
DMGFN_(SRL_D) { SRL(D); }
DMGFN_(SRL_E) { SRL(E); }
DMGFN_(SRL_H) { SRL(H); }
DMGFN_(SRL_L) { SRL(L); }
DMGFN_(SRL_IHLI) { unsigned char tmp = READ(HL); SRL(tmp); WRITE(HL, tmp); }
DMGFN_(SRL_A) { SRL(A); }

/****************************************************************************
 *	Bit Opcodes
 ****************************************************************************/

/*	Z - Set if bit b of register r is 0.
 *	N - Reset.
 *	H - Set.
 *	C - Not affected.
 */
void
dmg_BIT(DMG* dmg, unsigned char b, unsigned char n)
{
	unsigned char tmp = n & (1 << b);
	F = (!tmp << 7) |	/* Z */
				/* N */
	    0x20 |		/* H */
	    (F & 0x10);		/* C */
}

DMGFN_(BIT_0_B) { BIT(0, B); }
DMGFN_(BIT_0_C) { BIT(0, C); }
DMGFN_(BIT_0_D) { BIT(0, D); }
DMGFN_(BIT_0_E) { BIT(0, E); }
DMGFN_(BIT_0_H) { BIT(0, H); }
DMGFN_(BIT_0_L) { BIT(0, L); }
DMGFN_(BIT_0_IHLI) { BIT(0, READ(HL)); }
DMGFN_(BIT_0_A) { BIT(0, A); }

DMGFN_(BIT_1_B) { BIT(1, B); }
DMGFN_(BIT_1_C) { BIT(1, C); }
DMGFN_(BIT_1_D) { BIT(1, D); }
DMGFN_(BIT_1_E) { BIT(1, E); }
DMGFN_(BIT_1_H) { BIT(1, H); }
DMGFN_(BIT_1_L) { BIT(1, L); }
DMGFN_(BIT_1_IHLI) { BIT(1, READ(HL)); }
DMGFN_(BIT_1_A) { BIT(1, A); }

DMGFN_(BIT_2_B) { BIT(2, B); }
DMGFN_(BIT_2_C) { BIT(2, C); }
DMGFN_(BIT_2_D) { BIT(2, D); }
DMGFN_(BIT_2_E) { BIT(2, E); }
DMGFN_(BIT_2_H) { BIT(2, H); }
DMGFN_(BIT_2_L) { BIT(2, L); }
DMGFN_(BIT_2_IHLI) { BIT(2, READ(HL)); }
DMGFN_(BIT_2_A) { BIT(2, A); }

DMGFN_(BIT_3_B) { BIT(3, B); }
DMGFN_(BIT_3_C) { BIT(3, C); }
DMGFN_(BIT_3_D) { BIT(3, D); }
DMGFN_(BIT_3_E) { BIT(3, E); }
DMGFN_(BIT_3_H) { BIT(3, H); }
DMGFN_(BIT_3_L) { BIT(3, L); }
DMGFN_(BIT_3_IHLI) { BIT(3, READ(HL)); }
DMGFN_(BIT_3_A) { BIT(3, A); }

DMGFN_(BIT_4_B) { BIT(4, B); }
DMGFN_(BIT_4_C) { BIT(4, C); }
DMGFN_(BIT_4_D) { BIT(4, D); }
DMGFN_(BIT_4_E) { BIT(4, E); }
DMGFN_(BIT_4_H) { BIT(4, H); }
DMGFN_(BIT_4_L) { BIT(4, L); }
DMGFN_(BIT_4_IHLI) { BIT(4, READ(HL)); }
DMGFN_(BIT_4_A) { BIT(4, A); }

DMGFN_(BIT_5_B) { BIT(5, B); }
DMGFN_(BIT_5_C) { BIT(5, C); }
DMGFN_(BIT_5_D) { BIT(5, D); }
DMGFN_(BIT_5_E) { BIT(5, E); }
DMGFN_(BIT_5_H) { BIT(5, H); }
DMGFN_(BIT_5_L) { BIT(5, L); }
DMGFN_(BIT_5_IHLI) { BIT(5, READ(HL)); }
DMGFN_(BIT_5_A) { BIT(5, A); }

DMGFN_(BIT_6_B) { BIT(6, B); }
DMGFN_(BIT_6_C) { BIT(6, C); }
DMGFN_(BIT_6_D) { BIT(6, D); }
DMGFN_(BIT_6_E) { BIT(6, E); }
DMGFN_(BIT_6_H) { BIT(6, H); }
DMGFN_(BIT_6_L) { BIT(6, L); }
DMGFN_(BIT_6_IHLI) { BIT(6, READ(HL)); }
DMGFN_(BIT_6_A) { BIT(6, A); }

DMGFN_(BIT_7_B) { BIT(7, B); }
DMGFN_(BIT_7_C) { BIT(7, C); }
DMGFN_(BIT_7_D) { BIT(7, D); }
DMGFN_(BIT_7_E) { BIT(7, E); }
DMGFN_(BIT_7_H) { BIT(7, H); }
DMGFN_(BIT_7_L) { BIT(7, L); }
DMGFN_(BIT_7_IHLI) { BIT(7, READ(HL)); }
DMGFN_(BIT_7_A) { BIT(7, A); }

DMGFN_(SET_0_B) { SET(0, B); }
DMGFN_(SET_0_C) { SET(0, C); }
DMGFN_(SET_0_D) { SET(0, D); }
DMGFN_(SET_0_E) { SET(0, E); }
DMGFN_(SET_0_H) { SET(0, H); }
DMGFN_(SET_0_L) { SET(0, L); }
DMGFN_(SET_0_IHLI) { unsigned char tmp = READ(HL); SET(0, tmp); WRITE(HL, tmp); }
DMGFN_(SET_0_A) { SET(0, A); }

DMGFN_(SET_1_B) { SET(1, B); }
DMGFN_(SET_1_C) { SET(1, C); }
DMGFN_(SET_1_D) { SET(1, D); }
DMGFN_(SET_1_E) { SET(1, E); }
DMGFN_(SET_1_H) { SET(1, H); }
DMGFN_(SET_1_L) { SET(1, L); }
DMGFN_(SET_1_IHLI) { unsigned char tmp = READ(HL); SET(1, tmp); WRITE(HL, tmp); }
DMGFN_(SET_1_A) { SET(1, A); }

DMGFN_(SET_2_B) { SET(2, B); }
DMGFN_(SET_2_C) { SET(2, C); }
DMGFN_(SET_2_D) { SET(2, D); }
DMGFN_(SET_2_E) { SET(2, E); }
DMGFN_(SET_2_H) { SET(2, H); }
DMGFN_(SET_2_L) { SET(2, L); }
DMGFN_(SET_2_IHLI) { unsigned char tmp = READ(HL); SET(2, tmp); WRITE(HL, tmp); }
DMGFN_(SET_2_A) { SET(2, A); }

DMGFN_(SET_3_B) { SET(3, B); }
DMGFN_(SET_3_C) { SET(3, C); }
DMGFN_(SET_3_D) { SET(3, D); }
DMGFN_(SET_3_E) { SET(3, E); }
DMGFN_(SET_3_H) { SET(3, H); }
DMGFN_(SET_3_L) { SET(3, L); }
DMGFN_(SET_3_IHLI) { unsigned char tmp = READ(HL); SET(3, tmp); WRITE(HL, tmp); }
DMGFN_(SET_3_A) { SET(3, A); }

DMGFN_(SET_4_B) { SET(4, B); }
DMGFN_(SET_4_C) { SET(4, C); }
DMGFN_(SET_4_D) { SET(4, D); }
DMGFN_(SET_4_E) { SET(4, E); }
DMGFN_(SET_4_H) { SET(4, H); }
DMGFN_(SET_4_L) { SET(4, L); }
DMGFN_(SET_4_IHLI) { unsigned char tmp = READ(HL); SET(4, tmp); WRITE(HL, tmp); }
DMGFN_(SET_4_A) { SET(4, A); }

DMGFN_(SET_5_B) { SET(5, B); }
DMGFN_(SET_5_C) { SET(5, C); }
DMGFN_(SET_5_D) { SET(5, D); }
DMGFN_(SET_5_E) { SET(5, E); }
DMGFN_(SET_5_H) { SET(5, H); }
DMGFN_(SET_5_L) { SET(5, L); }
DMGFN_(SET_5_IHLI) { unsigned char tmp = READ(HL); SET(5, tmp); WRITE(HL, tmp); }
DMGFN_(SET_5_A) { SET(5, A); }

DMGFN_(SET_6_B) { SET(6, B); }
DMGFN_(SET_6_C) { SET(6, C); }
DMGFN_(SET_6_D) { SET(6, D); }
DMGFN_(SET_6_E) { SET(6, E); }
DMGFN_(SET_6_H) { SET(6, H); }
DMGFN_(SET_6_L) { SET(6, L); }
DMGFN_(SET_6_IHLI) { unsigned char tmp = READ(HL); SET(6, tmp); WRITE(HL, tmp); }
DMGFN_(SET_6_A) { SET(6, A); }

DMGFN_(SET_7_B) { SET(7, B); }
DMGFN_(SET_7_C) { SET(7, C); }
DMGFN_(SET_7_D) { SET(7, D); }
DMGFN_(SET_7_E) { SET(7, E); }
DMGFN_(SET_7_H) { SET(7, H); }
DMGFN_(SET_7_L) { SET(7, L); }
DMGFN_(SET_7_IHLI) { unsigned char tmp = READ(HL); SET(7, tmp); WRITE(HL, tmp); }
DMGFN_(SET_7_A) { SET(7, A); }

DMGFN_(RES_0_B) { RES(0, B); }
DMGFN_(RES_0_C) { RES(0, C); }
DMGFN_(RES_0_D) { RES(0, D); }
DMGFN_(RES_0_E) { RES(0, E); }
DMGFN_(RES_0_H) { RES(0, H); }
DMGFN_(RES_0_L) { RES(0, L); }
DMGFN_(RES_0_IHLI) { unsigned char tmp = READ(HL); RES(0, tmp); WRITE(HL, tmp); }
DMGFN_(RES_0_A) { RES(0, A); }

DMGFN_(RES_1_B) { RES(1, B); }
DMGFN_(RES_1_C) { RES(1, C); }
DMGFN_(RES_1_D) { RES(1, D); }
DMGFN_(RES_1_E) { RES(1, E); }
DMGFN_(RES_1_H) { RES(1, H); }
DMGFN_(RES_1_L) { RES(1, L); }
DMGFN_(RES_1_IHLI) { unsigned char tmp = READ(HL); RES(1, tmp); WRITE(HL, tmp); }
DMGFN_(RES_1_A) { RES(1, A); }

DMGFN_(RES_2_B) { RES(2, B); }
DMGFN_(RES_2_C) { RES(2, C); }
DMGFN_(RES_2_D) { RES(2, D); }
DMGFN_(RES_2_E) { RES(2, E); }
DMGFN_(RES_2_H) { RES(2, H); }
DMGFN_(RES_2_L) { RES(2, L); }
DMGFN_(RES_2_IHLI) { unsigned char tmp = READ(HL); RES(2, tmp); WRITE(HL, tmp); }
DMGFN_(RES_2_A) { RES(2, A); }

DMGFN_(RES_3_B) { RES(3, B); }
DMGFN_(RES_3_C) { RES(3, C); }
DMGFN_(RES_3_D) { RES(3, D); }
DMGFN_(RES_3_E) { RES(3, E); }
DMGFN_(RES_3_H) { RES(3, H); }
DMGFN_(RES_3_L) { RES(3, L); }
DMGFN_(RES_3_IHLI) { unsigned char tmp = READ(HL); RES(3, tmp); WRITE(HL, tmp); }
DMGFN_(RES_3_A) { RES(3, A); }

DMGFN_(RES_4_B) { RES(4, B); }
DMGFN_(RES_4_C) { RES(4, C); }
DMGFN_(RES_4_D) { RES(4, D); }
DMGFN_(RES_4_E) { RES(4, E); }
DMGFN_(RES_4_H) { RES(4, H); }
DMGFN_(RES_4_L) { RES(4, L); }
DMGFN_(RES_4_IHLI) { unsigned char tmp = READ(HL); RES(4, tmp); WRITE(HL, tmp); }
DMGFN_(RES_4_A) { RES(4, A); }

DMGFN_(RES_5_B) { RES(5, B); }
DMGFN_(RES_5_C) { RES(5, C); }
DMGFN_(RES_5_D) { RES(5, D); }
DMGFN_(RES_5_E) { RES(5, E); }
DMGFN_(RES_5_H) { RES(5, H); }
DMGFN_(RES_5_L) { RES(5, L); }
DMGFN_(RES_5_IHLI) { unsigned char tmp = READ(HL); RES(5, tmp); WRITE(HL, tmp); }
DMGFN_(RES_5_A) { RES(5, A); }

DMGFN_(RES_6_B) { RES(6, B); }
DMGFN_(RES_6_C) { RES(6, C); }
DMGFN_(RES_6_D) { RES(6, D); }
DMGFN_(RES_6_E) { RES(6, E); }
DMGFN_(RES_6_H) { RES(6, H); }
DMGFN_(RES_6_L) { RES(6, L); }
DMGFN_(RES_6_IHLI) { unsigned char tmp = READ(HL); RES(6, tmp); WRITE(HL, tmp); }
DMGFN_(RES_6_A) { RES(6, A); }

DMGFN_(RES_7_B) { RES(7, B); }
DMGFN_(RES_7_C) { RES(7, C); }
DMGFN_(RES_7_D) { RES(7, D); }
DMGFN_(RES_7_E) { RES(7, E); }
DMGFN_(RES_7_H) { RES(7, H); }
DMGFN_(RES_7_L) { RES(7, L); }
DMGFN_(RES_7_IHLI) { unsigned char tmp = READ(HL); RES(7, tmp); WRITE(HL, tmp); }
DMGFN_(RES_7_A) { RES(7, A); }

/****************************************************************************
 *	Jumps
 ****************************************************************************/

#ifndef DMG_ASM

DMGFN_(JP_IHLI) { PC = HL; }
DMGFN_(JP_nn) { PC = arg; }

DMGFN_(JP_NZ_nn) { if(!(F & 0x80)) { PC = arg; CYCLE -= 4; } }
DMGFN_(JP_Z_nn)  { if( (F & 0x80)) { PC = arg; CYCLE -= 4; } }
DMGFN_(JP_NC_nn) { if(!(F & 0x10)) { PC = arg; CYCLE -= 4; } }
DMGFN_(JP_C_nn)  { if( (F & 0x10)) { PC = arg; CYCLE -= 4; } }

DMGFN_(JR_e) { PC += (char)arg; }

DMGFN_(JR_NZ_e) { if(!(F & 0x80)) { PC += (char)arg; CYCLE -= 4; } }
DMGFN_(JR_Z_e)  { if( (F & 0x80)) { PC += (char)arg; CYCLE -= 4; } }
DMGFN_(JR_NC_e) { if(!(F & 0x10)) { PC += (char)arg; CYCLE -= 4; } }
DMGFN_(JR_C_e)  { if( (F & 0x10)) { PC += (char)arg; CYCLE -= 4; } }

#endif /*DMG_ASM*/

/****************************************************************************
 *	Calls
 ****************************************************************************/

#ifndef DMG_ASM

DMGFN_(CALL_nn) { PUSH(PC); PC = arg; }

DMGFN_(CALL_NZ_nn) { if(!(F & 0x80)) { PUSH(PC); PC = arg; CYCLE -= 12; } }
DMGFN_(CALL_Z_nn)  { if( (F & 0x80)) { PUSH(PC); PC = arg; CYCLE -= 12; } }
DMGFN_(CALL_NC_nn) { if(!(F & 0x10)) { PUSH(PC); PC = arg; CYCLE -= 12; } }
DMGFN_(CALL_C_nn)  { if( (F & 0x10)) { PUSH(PC); PC = arg; CYCLE -= 12; } }

#endif /*DMG_ASM*/

/****************************************************************************
 *	Restarts
 ****************************************************************************/

DMGFN_(RST_00H) { PUSH(PC); PC = 0x00; }
DMGFN_(RST_08H) { PUSH(PC); PC = 0x08; }
DMGFN_(RST_10H) { PUSH(PC); PC = 0x10; }
DMGFN_(RST_18H) { PUSH(PC); PC = 0x18; }
DMGFN_(RST_20H) { PUSH(PC); PC = 0x20; }
DMGFN_(RST_28H) { PUSH(PC); PC = 0x28; }
DMGFN_(RST_30H) { PUSH(PC); PC = 0x30; }
DMGFN_(RST_38H) { PUSH(PC); PC = 0x38; }

/****************************************************************************
 *	Returns
 ****************************************************************************/

#ifndef DMG_ASM

DMGFN_(RET) { POP(PC); }

DMGFN_(RET_NZ) { if(!(F & 0x80)) { POP(PC); CYCLE -= 12; } }
DMGFN_(RET_Z)  { if( (F & 0x80)) { POP(PC); CYCLE -= 12; } }
DMGFN_(RET_NC) { if(!(F & 0x10)) { POP(PC); CYCLE -= 12; } }
DMGFN_(RET_C)  { if( (F & 0x10)) { POP(PC); CYCLE -= 12; } }

#endif /*DMG_ASM*/

DMGFN_(RETI) { POP(PC); IME = 1; dmg_check_pending(dmg); } /* DMGのRETIはZ80と違ってEIの効果付き!! */
