📄 z80.c
字号:
case 0xd4:prefix##_##d4();break; case 0xd5:prefix##_##d5();break; case 0xd6:prefix##_##d6();break; case 0xd7:prefix##_##d7();break; \
case 0xd8:prefix##_##d8();break; case 0xd9:prefix##_##d9();break; case 0xda:prefix##_##da();break; case 0xdb:prefix##_##db();break; \
case 0xdc:prefix##_##dc();break; case 0xdd:prefix##_##dd();break; case 0xde:prefix##_##de();break; case 0xdf:prefix##_##df();break; \
case 0xe0:prefix##_##e0();break; case 0xe1:prefix##_##e1();break; case 0xe2:prefix##_##e2();break; case 0xe3:prefix##_##e3();break; \
case 0xe4:prefix##_##e4();break; case 0xe5:prefix##_##e5();break; case 0xe6:prefix##_##e6();break; case 0xe7:prefix##_##e7();break; \
case 0xe8:prefix##_##e8();break; case 0xe9:prefix##_##e9();break; case 0xea:prefix##_##ea();break; case 0xeb:prefix##_##eb();break; \
case 0xec:prefix##_##ec();break; case 0xed:prefix##_##ed();break; case 0xee:prefix##_##ee();break; case 0xef:prefix##_##ef();break; \
case 0xf0:prefix##_##f0();break; case 0xf1:prefix##_##f1();break; case 0xf2:prefix##_##f2();break; case 0xf3:prefix##_##f3();break; \
case 0xf4:prefix##_##f4();break; case 0xf5:prefix##_##f5();break; case 0xf6:prefix##_##f6();break; case 0xf7:prefix##_##f7();break; \
case 0xf8:prefix##_##f8();break; case 0xf9:prefix##_##f9();break; case 0xfa:prefix##_##fa();break; case 0xfb:prefix##_##fb();break; \
case 0xfc:prefix##_##fc();break; case 0xfd:prefix##_##fd();break; case 0xfe:prefix##_##fe();break; case 0xff:prefix##_##ff();break; \
} \
}
#else
#define EXEC_INLINE EXEC
#endif
/***************************************************************
* Input a byte from given I/O port
***************************************************************/
#define IN(port) ((UINT8)cpu_readport(port))
/***************************************************************
* Output a byte to given I/O port
***************************************************************/
#define OUT(port,value) cpu_writeport(port,value)
/***************************************************************
* Read a byte from given memory location
***************************************************************/
#define RM(Addr) cpu_readmem16(Addr)
INLINE UINT16 RM16(unsigned Addr)
{
return RM(Addr) | (RM((Addr+1) & 0xffff) << 8);
}
/***************************************************************
* Write a byte to given memory location
***************************************************************/
#define WM(Addr,Value) cpu_writemem16(Addr,Value)
INLINE void WM16(unsigned Addr, Z80_pair *r )
{
WM( Addr, r->B.l );
WM( Addr+1, r->B.h );
}
/***************************************************************
* ROP() is identical to RM() except it is used for
* reading opcodes. In case of system with memory mapped I/O,
* this function can be used to greatly speed up emulation
***************************************************************/
INLINE UINT8 ROP(void)
{
unsigned pc = _PCD;
_PC++;
return cpu_readop(pc);
}
/****************************************************************
* ARG() is identical to ROP() except it is used
* for reading opcode arguments. This difference can be used to
* support systems that use different encoding mechanisms for
* opcodes and opcode arguments
***************************************************************/
INLINE UINT8 ARG(void)
{
unsigned pc = _PCD;
_PC++;
return cpu_readop_arg(pc);
}
#ifdef LSB_FIRST
INLINE UINT16 ARG16(void)
{
unsigned pc = _PCD;
_PC += 2;
return cpu_readop_arg16(pc);
}
#else
INLINE UINT16 ARG16(void)
{
unsigned pc = _PCD;
_PC += 2;
return cpu_readop_arg(pc)|(cpu_readop_arg(pc+1)<<8);
}
#endif
/***************************************************************
* Calculate the effective address EA of an opcode using
* IX+offset resp. IY+offset addressing.
***************************************************************/
#define EAX EA = (UINT16)(_IX+(INT8)ARG())
#define EAY EA = (UINT16)(_IY+(INT8)ARG())
/***************************************************************
* POP
***************************************************************/
#define POP(DR) { Z80.DR.D = RM16( _SPD ); _SP += 2; }
/***************************************************************
* PUSH
***************************************************************/
#define PUSH(SR) { _SP -= 2; WM16( _SPD, &Z80.SR ); }
/***************************************************************
* JP
***************************************************************/
#if BUSY_LOOP_HACKS
#define JP { \
unsigned oldpc = _PCD-1; \
_PCD = ARG16(); \
/* speed up busy loop */ \
if (_PCD == oldpc) { \
if (Z80_ICount > 0) Z80_ICount = 0; \
} else \
/* NOP - JP */ \
if (_PCD == oldpc-1 && cpu_readop(_PCD) == 0x00) { \
if (Z80_ICount > 0) Z80_ICount = 0; \
} else \
/* LD SP,#xxxx - Galaga */ \
if (_PCD == oldpc-3 && cpu_readop(_PCD) == 0x31) { \
if (Z80_ICount > 10) Z80_ICount = 10; \
} else \
/* EI - JP */ \
if (_PCD == oldpc-1 && cpu_readop(_PCD) == 0xfb && Z80.pending_irq == 0) { \
if (Z80_ICount > 4) Z80_ICount = 4; \
} \
change_pc16(_PCD); \
}
#else
#define JP { \
_PCD = ARG16(); \
change_pc16(_PCD); \
}
#endif
/***************************************************************
* JP_COND
***************************************************************/
#define JP_COND(cond) \
if (cond) { \
_PCD = ARG16(); \
change_pc16(_PCD); \
} else { \
_PC += 2; \
}
/***************************************************************
* JR
***************************************************************/
#define JR(cond) \
if (cond) { \
_PC += (INT8)ARG(); \
CY(5); \
change_pc16(_PCD); \
} else _PC++; \
/***************************************************************
* CALL
***************************************************************/
#define CALL(cond) \
if (cond) { \
EA = ARG16(); \
PUSH( PC ); \
_PCD = EA; \
CY(7); \
change_pc16(_PCD); \
} else { \
_PC+=2; \
}
/***************************************************************
* RET
***************************************************************/
#define RET(cond) \
if (cond) { \
POP(PC); \
change_pc16(_PCD); \
CY(6); \
}
/***************************************************************
* RETN
***************************************************************/
#if NEW_INTERRUPT_SYSTEM
#define RETN { \
if (!_IFF1 && _IFF2) { \
if (Z80.irq_state != CLEAR_LINE) { \
Z80.pending_irq |= INT_IRQ; \
} \
} \
_IFF1 = _IFF2; \
RET(1); \
}
#else
#define RETN { \
_IFF1 = _IFF2; \
RET(1); \
}
#endif
/***************************************************************
* RETI
***************************************************************/
#define RETI { \
int device = Z80.service_irq; \
if (device >= 0) { \
Z80.irq[device].interrupt_reti(Z80.irq[device].irq_param); \
} \
RET(1); \
}
/***************************************************************
* LD R,A
***************************************************************/
#if INC_R_ONCE
#define LD_R_A { \
_R = _A; \
_R2 = _A & 0x80; /* keep bit 7 of R */ \
}
#else
#define LD_R_A { \
/* R register counts T-States (M-cycles = T-States / 4) */ \
_R = _A << 2; \
_R2 = _A & 0x80; /* keep bit 7 of R */ \
}
#endif
/***************************************************************
* LD A,R
***************************************************************/
#if INC_R_ONCE
#define LD_A_R { \
_A = (_R & 0x7f) | _R2; \
_F = (_F & CF) | SZ[_A] | (_IFF2 << 2); \
}
#else
#define LD_A_R { \
/* our R counts T-States (M-cycles = T-States / 4) */ \
_A = ((_R >> 2) & 0x7f) | _R2; \
_F = (_F & CF) | SZ[_A] | (_IFF2 << 2); \
}
#endif
/***************************************************************
* LD I,A
***************************************************************/
#define LD_I_A { \
_I = _A; \
}
/***************************************************************
* LD A,I
***************************************************************/
#define LD_A_I { \
_A = _I; \
_F = (_F & CF) | SZ[_A] | (_IFF2 << 2); \
}
/***************************************************************
* RST
***************************************************************/
#define RST(Addr) \
PUSH( PC ); \
_PCD = Addr; \
change_pc16(_PCD)
/***************************************************************
* INC r8
***************************************************************/
INLINE UINT8 INC(UINT8 Value)
{
unsigned res = (Value + 1) & 0xff;
_F = (_F & CF) | SZHV_inc[res];
return (UINT8)res;
}
/***************************************************************
* DEC r8
***************************************************************/
INLINE UINT8 DEC(UINT8 Value)
{
unsigned res = (Value - 1) & 0xff;
_F = (_F & CF) | SZHV_dec[res];
return res;
}
/***************************************************************
* RLCA
***************************************************************/
#define RLCA \
_A = (_A << 1) | (_A >> 7); \
_F = (_F & (SF | ZF | YF | XF | PF)) | (_A & CF)
/***************************************************************
* RRCA
***************************************************************/
#define RRCA \
_F = (_F & (SF | ZF | YF | XF | PF)) | (_A & CF); \
_A = (_A >> 1) | (_A << 7)
/***************************************************************
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -