File:  [RetroPC.NET] / xmil / z80c / z80c.mcr
Revision 1.7: download - view: text, annotated - select for diffs
Tue Jun 3 05:07:32 2008 JST (17 years, 4 months ago) by yui
Branches: MAIN
CVS tags: HEAD
change to c style comment

/* -----------------------------------------------------------------------
 *
 * Z80C : Z80 Engine - GENERIC
 *
 *                              Copyright by Studio Milmake 1999-2000,2004
 *
 *------------------------------------------------------------------------ */

/* #define	PCCOUNTER */

#if defined(TRACE) && defined(PCCOUNTER)
extern	UINT	pccnt;
extern	UINT	pccnt2;
extern	UINT	pccnt3;
extern	UINT	lastpc;
#endif

#define Z80_COUNT(clock)												\
	do {																\
		CPU_REMCLOCK -= (clock);										\
	} while (/*CONSTCOND*/ 0)


#if defined(TRACE) && defined(PCCOUNTER)
#define	GET_PC_BYTE(b)													\
	do {																\
		if ((lastpc ^ R_Z80PC) & 0x8000) {								\
			TRACEOUT(("%.4x->%.4x", lastpc, R_Z80PC));					\
			lastpc = R_Z80PC;											\
			pccnt2++;													\
		}																\
		pccnt++;														\
		(b) = mem_read8(R_Z80PC++);										\
	} while (/*CONSTCOND*/ 0)

#define	GET_PC_WORD(w)													\
	do {																\
		pccnt3++;														\
		(w) = mem_read16(R_Z80PC);										\
		R_Z80PC += 2;													\
	} while (/*CONSTCOND*/ 0)
#else
#define	GET_PC_BYTE(b)													\
	do {																\
		(b) = mem_read8(R_Z80PC++);										\
	} while (/*CONSTCOND*/ 0)

#define	GET_PC_WORD(w)													\
	do {																\
		(w) = mem_read16(R_Z80PC);										\
		R_Z80PC += 2;													\
	} while (/*CONSTCOND*/ 0)
#endif


#define MCR_EX1(r1, r2)													\
	do {																\
		REG16 tmp;														\
		tmp = (r1);														\
		(r1) = (r2);													\
		(r2) = tmp;														\
	} while (/*CONSTCOND*/ 0)

#define JRBYFLAG(flg)													\
	do {																\
		if ((flg)) {													\
			SINT ofst;													\
			ofst = mem_read8s(R_Z80PC++);								\
			R_Z80PC += ofst;											\
			Z80_COUNT(5);												\
		}																\
		else {															\
			R_Z80PC++;													\
		}																\
	} while (/*CONSTCOND*/ 0)



#define	LDW_w(reg) {													\
		(reg) = mem_read16(R_Z80PC);									\
		R_Z80PC += 2;													\
	}

#define	LDx_B(dst, src) {												\
		mem_write8((dst), (src));										\
	}

#define	MCR_INC_W(reg) {												\
		(reg)++;														\
	}

#define	MCR_INC(reg) {													\
		R_Z80F &= C_FLAG;												\
		R_Z80F |= z80inc_flag2[(reg)];									\
		(reg)++;														\
	}

#define	MCR_DEC(reg) {													\
		R_Z80F &= C_FLAG;												\
		R_Z80F |= z80dec_flag2[(reg)];									\
		(reg)--;														\
	}

#define	LDB_b(reg) {													\
		(reg) = mem_read8(R_Z80PC++);									\
	}

#define	MCR_RLCA {														\
		REG8 tmp;														\
		tmp = (UINT8)(R_Z80A >> 7);										\
		R_Z80A = (R_Z80A << 1) | tmp;									\
		R_Z80F &= 0xec;													\
		R_Z80F |= tmp;													\
	}

#define MCR_EX(reg1, reg2) {											\
		MCR_EX1(reg1, reg2);											\
	}

#define MCR_ADD_W(dst, src) {											\
		UINT32 tmp;														\
		R_Z80F &= (S_FLAG | Z_FLAG | V_FLAG);							\
		tmp = (dst) + (src);											\
		R_Z80F |= (UINT8)(tmp >> 16);									\
		R_Z80F |= ((tmp ^ (dst) ^ (src)) >> 8) & H_FLAG;				\
		(dst) = (UINT16)tmp;											\
	}

#define	LDB_x(b, w) {													\
		(b) = mem_read8((w));											\
	}

#define MCR_DEC_W(reg) {												\
		(reg)--;														\
	}

#define MCR_RRCA {														\
		REG8 tmp;														\
		tmp = (UINT8)(R_Z80A & 1);										\
		R_Z80F &= 0xec;													\
		R_Z80F |= tmp;													\
		R_Z80A = (R_Z80A >> 1) | (tmp << 7);							\
	}


#define MCR_DJNZ {														\
		R_Z80B--;														\
		JRBYFLAG(R_Z80B);												\
	}

#define MCR_RLA {														\
		REG8 tmp;														\
		tmp = (UINT8)(R_Z80A >> 7);										\
		R_Z80A = (R_Z80A << 1) | (R_Z80F & 1);							\
		R_Z80F &= 0xec;													\
		R_Z80F |= tmp;													\
	}

#define MCR_JR {														\
		SINT ofst;														\
		ofst = mem_read8s(R_Z80PC++);									\
		R_Z80PC += ofst;												\
		Z80_COUNT(5);													\
	}

#define MCR_RRA {														\
		REG8 tmp;														\
		tmp = (UINT8)(R_Z80A & 1);										\
		R_Z80A = (R_Z80A >> 1) | (R_Z80F << 7);							\
		R_Z80F &= 0xec;													\
		R_Z80F |= tmp;													\
	}


#define	MCR_JRNFLG(flg) {												\
		JRBYFLAG(!(R_Z80F & (flg)));									\
	}

#define LDx_W(reg) {													\
		UINT adrs;														\
		GET_PC_WORD(adrs);												\
		mem_write16(adrs, (reg));										\
	}

#define	MCR_DDA {														\
		SINT dst;														\
		REG8 flg;														\
		SINT alow;														\
		dst = R_Z80A;													\
		alow = R_Z80A & 0x0f;											\
		flg = R_Z80F & N_FLAG;											\
		if (!flg) {														\
			if (alow >= 10) {											\
				flg |= H_FLAG;											\
				dst += 6;												\
			}															\
			else if (R_Z80F & H_FLAG) {									\
				dst += 6;												\
			}															\
			if ((dst >= 0xa0) || (R_Z80F & C_FLAG)) {					\
				flg |= C_FLAG;											\
				dst += 0x60;											\
			}															\
		}																\
		else {															\
			if ((dst > 0x99) || (R_Z80F & C_FLAG)) {					\
				dst -= 0x60;											\
				flg |= C_FLAG;											\
			}															\
			if ((alow > 9) || (R_Z80F & H_FLAG)) {						\
				if (alow < 6) {											\
					flg |= H_FLAG;										\
				}														\
				dst -= 6;												\
				if ((dst < 0) && (!(R_Z80F & H_FLAG))) {				\
					flg |= C_FLAG;										\
				}														\
			}															\
		}																\
		R_Z80A = (UINT8)dst;											\
		R_Z80F = flg | z80szp_flag[dst & 0xff];							\
	}

#define	MCR_JRFLG(flg) {												\
		JRBYFLAG(R_Z80F & (flg));										\
	}

#define MCR_ADDx2(reg) {												\
			R_Z80F &= (S_FLAG | Z_FLAG | V_FLAG);						\
			R_Z80F |= (UINT8)((reg) >> 15);								\
			(reg) <<= 1;												\
			R_Z80F |= ((reg) >> 8) & H_FLAG;							\
		}

#define LDW_x(reg) {													\
		UINT adrs;														\
		GET_PC_WORD(adrs);												\
		(reg) = mem_read16(adrs);										\
	}

#define	MCR_CPL {														\
		R_Z80A = (UINT8)(~R_Z80A);										\
		R_Z80F |= (H_FLAG | N_FLAG);									\
	}


#define LDB_x_a {														\
		UINT adrs;														\
		GET_PC_WORD(adrs);												\
		mem_write8(adrs, R_Z80A);										\
	}

#define MCR_INC_MEM(adrs) {												\
		REG8 tmp;														\
		tmp = mem_read8((adrs));										\
		R_Z80F &= C_FLAG;												\
		R_Z80F |= z80inc_flag2[tmp];									\
		mem_write8((adrs), (REG8)(tmp + 1));							\
	}

#define	MCR_DEC_MEM(adrs) {												\
		REG8 tmp;														\
		tmp = mem_read8((adrs));										\
		R_Z80F &= C_FLAG;												\
		R_Z80F |= z80dec_flag2[tmp];									\
		mem_write8((adrs), (REG8)(tmp - 1));							\
	}

#define LDB_xhl_b {														\
		REG8 tmp;														\
		GET_PC_BYTE(tmp);												\
		mem_write8(R_Z80HL, tmp);										\
	}

#define MCR_SCF {														\
		R_Z80F &= ~(H_FLAG | N_FLAG);									\
		R_Z80F |= C_FLAG;												\
	}

#define LDB_a_x {														\
		UINT adrs;														\
		GET_PC_WORD(adrs);												\
		R_Z80A = mem_read8(adrs);										\
	}

#define MCR_CCF {														\
		R_Z80F &= ~(H_FLAG | N_FLAG);									\
		if (R_Z80F & C_FLAG) {											\
			R_Z80F |= H_FLAG;											\
		}																\
		R_Z80F ^= C_FLAG;												\
	}

#define MCR_LD(d, s) {													\
		(d) = (s);														\
	}

#define MCR_HALT {														\
		R_Z80PC--;														\
		Z80_IFF |= (1 << IFF_HALT);										\
		CPU_REMCLOCK = 0;												\
	}


#define	MCR_ADD(b) {													\
		UINT res;														\
		res = R_Z80A + (b);												\
		R_Z80F = z80szc_flag[res & 0x1ff];								\
		R_Z80F |= (res ^ R_Z80A ^ (b)) & H_FLAG;						\
		R_Z80F |= (((res ^ R_Z80A) & (res ^ (b))) >> 5) & V_FLAG;		\
		R_Z80A = (UINT8)res;											\
	}

#define	MCR_ADD_XHL {													\
		REG8 tmp;														\
		tmp = mem_read8(R_Z80HL);										\
		MCR_ADD(tmp)													\
	}

#define	MCR_ADC(b) {													\
		UINT res;														\
		res = R_Z80A + (b) + (R_Z80F & 1);								\
		R_Z80F = z80szc_flag[res & 0x1ff];								\
		R_Z80F |= (res ^ R_Z80A ^ (b)) & H_FLAG;						\
		R_Z80F |= (((res ^ R_Z80A) & (res ^ (b))) >> 5) & V_FLAG;		\
		R_Z80A = (UINT8)res;											\
	}

#define	MCR_ADC_XHL {													\
		REG8 tmp;														\
		tmp = mem_read8(R_Z80HL);										\
		MCR_ADC(tmp)													\
	}


#define	MCR_SUB(b) {													\
		UINT res;														\
		res = R_Z80A - (b);												\
		R_Z80F = z80szc_flag[res & 0x1ff] | N_FLAG;						\
		R_Z80F |= (res ^ R_Z80A ^ (b)) & H_FLAG;						\
		R_Z80F |= (((R_Z80A ^ res) & (R_Z80A ^ (b))) >> 5) & V_FLAG;	\
		R_Z80A = (UINT8)res;											\
	}

#define	MCR_SUB_XHL {													\
		REG8 tmp;														\
		tmp = mem_read8(R_Z80HL);										\
		MCR_SUB(tmp)													\
	}

#define	MCR_SBC(b) {													\
		UINT res;														\
		res = R_Z80A - (b) - (R_Z80F & 1);								\
		R_Z80F = z80szc_flag[res & 0x1ff] | N_FLAG;						\
		R_Z80F |= (res ^ R_Z80A ^ (b)) & H_FLAG;						\
		R_Z80F |= (((R_Z80A ^ res) & (R_Z80A ^ (b))) >> 5) & V_FLAG;	\
		R_Z80A = (UINT8)res;											\
	}

#define	MCR_SBC_XHL {													\
		REG8 tmp;														\
		tmp = mem_read8(R_Z80HL);										\
		MCR_SBC(tmp)													\
	}


#define	MCR_AND(b) {													\
		R_Z80A &= (b);													\
		R_Z80F = z80szp_flag[R_Z80A];									\
	}

#define	MCR_AND_XHL {													\
		REG8 tmp;														\
		tmp = mem_read8(R_Z80HL);										\
		MCR_AND(tmp)													\
	}

#define	MCR_XOR(b) {													\
		R_Z80A ^= (b);													\
		R_Z80F = z80szp_flag[R_Z80A];									\
	}

#define	MCR_XOR_XHL {													\
		REG8 tmp;														\
		tmp = mem_read8(R_Z80HL);										\
		MCR_XOR(tmp)													\
	}


#define	MCR_OR(b) {														\
		R_Z80A |= (b);													\
		R_Z80F = z80szp_flag[R_Z80A];									\
	}

#define	MCR_OR_XHL {													\
		REG8 tmp;														\
		tmp = mem_read8(R_Z80HL);										\
		MCR_OR(tmp)														\
	}

#define	MCR_CP(b) {														\
		UINT res;														\
		res = R_Z80A - (b);												\
		R_Z80F = z80szc_flag[res & 0x1ff] | N_FLAG;						\
		R_Z80F |= (res ^ R_Z80A ^ (b)) & H_FLAG;						\
		R_Z80F |= (((R_Z80A ^ res) & (R_Z80A ^ (b))) >> 5) & V_FLAG;	\
	}

#define	MCR_CP_XHL {													\
		REG8 tmp;														\
		tmp = mem_read8(R_Z80HL);										\
		MCR_CP(tmp)														\
	}


#define MCR_RETNFLG(flg) {												\
		if (!(R_Z80F & (flg))) {										\
			R_Z80PC = mem_read16(R_Z80SP);								\
			R_Z80SP += 2;												\
			Z80_COUNT(6);												\
		}																\
	}

#define MCR_POP(reg) {													\
		(reg) = mem_read16(R_Z80SP);									\
		R_Z80SP += 2;													\
	}

#define MCR_JPNFLG(flg) {												\
		if (!(R_Z80F & (flg))) {										\
			R_Z80PC = mem_read16(R_Z80PC);								\
		}																\
		else {															\
			R_Z80PC += 2;												\
		}																\
	}

#define	MCR_JP {														\
		R_Z80PC = mem_read16(R_Z80PC);									\
	}

#define MCR_CALLNFLG(flg) {												\
		if (!(R_Z80F & (flg))) {										\
			REG16 tmp;													\
			GET_PC_WORD(tmp);											\
			R_Z80SP -= 2;												\
			mem_write16(R_Z80SP, R_Z80PC);								\
			R_Z80PC = tmp;												\
			Z80_COUNT(7);												\
		}																\
		else {															\
			R_Z80PC += 2;												\
		}																\
	}

#define MCR_PUSH(reg) {													\
		R_Z80SP -= 2;													\
		mem_write16(R_Z80SP, (reg));									\
	}

#define MCR_ADD_BYTE {													\
		REG8 tmp;														\
		GET_PC_BYTE(tmp);												\
		MCR_ADD(tmp)													\
	}

#define MCR_RST(vect) {													\
		R_Z80SP -= 2;													\
		mem_write16(R_Z80SP, R_Z80PC);									\
		R_Z80PC = (vect);												\
	}

#define MCR_RETFLG(flg) {												\
		if (R_Z80F & (flg)) {											\
			R_Z80PC = mem_read16(R_Z80SP);								\
			R_Z80SP += 2;												\
			Z80_COUNT(6);												\
		}																\
	}

#define MCR_RET {														\
		R_Z80PC = mem_read16(R_Z80SP);									\
		R_Z80SP += 2;													\
		Z80_COUNT(6);													\
	}

#define MCR_JPFLG(flg) {												\
		if (R_Z80F & (flg)) {											\
			R_Z80PC = mem_read16(R_Z80PC);								\
		}																\
		else {															\
			R_Z80PC += 2;												\
		}																\
	}

#define MCR_CALLFLG(flg) {												\
		if (R_Z80F & (flg)) {											\
			REG16 tmp;													\
			GET_PC_WORD(tmp);											\
			R_Z80SP -= 2;												\
			mem_write16(R_Z80SP, R_Z80PC);								\
			R_Z80PC = tmp;												\
			Z80_COUNT(7);												\
		}																\
		else {															\
			R_Z80PC += 2;												\
		}																\
	}

#define MCR_CALL {														\
		REG16 tmp;														\
		GET_PC_WORD(tmp);												\
		R_Z80SP -= 2;													\
		mem_write16(R_Z80SP, R_Z80PC);									\
		R_Z80PC = tmp;													\
		Z80_COUNT(7);													\
	}

#define MCR_ADC_BYTE {													\
		REG8 tmp;														\
		GET_PC_BYTE(tmp);												\
		MCR_ADC(tmp)													\
	}


#define MCR_OUT_BYTE {													\
		REG8 tmp;														\
		GET_PC_BYTE(tmp);												\
		iocore_out((R_Z80A << 8) + tmp, tmp);							\
	}

#define MCR_SUB_BYTE {													\
		REG8 tmp;														\
		GET_PC_BYTE(tmp);												\
		MCR_SUB(tmp)													\
	}

#define	MCR_EXX {														\
		MCR_EX(R_Z80BC, R_Z80BC2)										\
		MCR_EX(R_Z80DE, R_Z80DE2)										\
		MCR_EX(R_Z80HL, R_Z80HL2)										\
	}

#define MCR_IN_BYTE {													\
		REG8 tmp;														\
		GET_PC_BYTE(tmp);												\
		R_Z80A = iocore_inp((R_Z80A << 8) | tmp);						\
	}

#define MCR_SBC_BYTE {													\
		REG8 tmp;														\
		GET_PC_BYTE(tmp);												\
		MCR_SBC(tmp)													\
	}


#define MCR_EX_XSP(reg) {												\
		REG16 tmp;														\
		tmp = mem_read16(R_Z80SP);										\
		mem_write16(R_Z80SP, (reg));									\
		(reg) = tmp;													\
	}

#define MCR_AND_BYTE {													\
		REG8 tmp;														\
		GET_PC_BYTE(tmp);												\
		MCR_AND(tmp)													\
	}

#define MCR_LD_W(dst, src) {											\
		(dst) = (src);													\
	}

#define MCR_XOR_BYTE {													\
		REG8 tmp;														\
		GET_PC_BYTE(tmp);												\
		MCR_XOR(tmp)													\
	}


#define MCR_DI {														\
		Z80_IFF |= (1 << IFF_IFLAG);									\
	}

#define MCR_OR_BYTE {													\
		REG8 tmp;														\
		GET_PC_BYTE(tmp);												\
		MCR_OR(tmp)														\
	}

#define MCR_EI {														\
		REG8 iff;														\
		SINT32 rem;														\
		iff = Z80_IFF;													\
		if (iff & (1 << IFF_IFLAG)) {									\
			Z80_IFF = (UINT8)(iff & (~(1 << IFF_IFLAG)));				\
			rem = CPU_REMCLOCK - 1;										\
			if ((rem < 0) ||											\
				((!(iff & (1 << IFF_NMI))) && (CPU_REQIRQ != 0))) {		\
				CPU_BASECLOCK -= rem;									\
				CPU_REMCLOCK = 1;										\
			}															\
		}																\
	}

#define MCR_CP_BYTE {													\
		REG8 tmp;														\
		GET_PC_BYTE(tmp);												\
		MCR_CP(tmp)														\
	}



RetroPC.NET-CVS <cvs@retropc.net>