mame/src/emu/cpu/z180/z180ops.h
2008-11-27 05:22:51 +00:00

1042 lines
31 KiB
C

/***************************************************************
* Enter HALT state; write 1 to fake port on first execution
***************************************************************/
#define ENTER_HALT { \
_PC--; \
_HALT = 1; \
if( !Z180.after_EI ) \
CPU_BURN_NAME(z180)( NULL, z180_icount ); \
}
/***************************************************************
* Leave HALT state; write 0 to fake port
***************************************************************/
#define LEAVE_HALT { \
if( _HALT ) \
{ \
_HALT = 0; \
_PC++; \
} \
}
/***************************************************************
* Input a byte from given I/O port
***************************************************************/
#define IN(port) \
(((port ^ IO_IOCR) & 0xffc0) == 0) ? \
z180_readcontrol(port) : memory_read_byte_8le(Z180.iospace, port)
/***************************************************************
* Output a byte to given I/O port
***************************************************************/
#define OUT(port,value) \
if (((port ^ IO_IOCR) & 0xffc0) == 0) \
z180_writecontrol(port,value); \
else memory_write_byte_8le(Z180.iospace,port,value)
/***************************************************************
* MMU calculate the memory managemant lookup table
* bb and cb specify a 4K page
* If the 4 most significant bits of an 16 bit address are
* greater or equal to the bank base, the bank base register
* specifies the 4K offset into the 20 bit address space.
* If the 4 bits are also greater or equal to the common base,
* the common base register is used to specify the offset.
***************************************************************/
INLINE void z180_mmu( void )
{
offs_t addr, page, bb, cb;
bb = IO_CBAR & 15;
cb = IO_CBAR >> 4;
for( page = 0; page < 16; page++ )
{
addr = page << 12;
if (page >= bb)
{
if (page >= cb)
addr += IO_CBR << 12;
else
addr += IO_BBR << 12;
}
Z180.mmu[page] = addr;
}
}
#define MMU_REMAP_ADDR(addr) (Z180.mmu[((addr)>>12)&15]|((addr)&4095))
/***************************************************************
* Read a byte from given memory location
***************************************************************/
#define RM(addr) memory_read_byte_8le(Z180.program, MMU_REMAP_ADDR(addr))
UINT8 z180_readmem(offs_t offset)
{
return RM(offset);
}
/***************************************************************
* Write a byte to given memory location
***************************************************************/
#define WM(addr,value) memory_write_byte_8le(Z180.program, MMU_REMAP_ADDR(addr),value)
void z180_writemem(offs_t offset, UINT8 data)
{
WM(offset, data);
}
/***************************************************************
* Read a word from given memory location
***************************************************************/
INLINE void RM16( offs_t addr, PAIR *r )
{
r->b.l = RM(addr);
r->b.h = RM(addr+1);
}
/***************************************************************
* Write a word to given memory location
***************************************************************/
INLINE void WM16( offs_t addr, 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)
{
offs_t addr = _PCD;
_PC++;
return memory_decrypted_read_byte(Z180.program, MMU_REMAP_ADDR(addr));
}
/****************************************************************
* 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)
{
offs_t addr = _PCD;
_PC++;
return memory_raw_read_byte(Z180.program, MMU_REMAP_ADDR(addr));
}
INLINE UINT32 ARG16(void)
{
offs_t addr = _PCD;
_PC += 2;
return memory_raw_read_byte(Z180.program, MMU_REMAP_ADDR(addr)) | (memory_raw_read_byte(Z180.program, MMU_REMAP_ADDR(addr+1)) << 8);
}
/****************************************************************************
* Change program counter - MMU lookup
****************************************************************************/
void z180_setOPbase(int pc)
{
}
/***************************************************************
* Calculate the effective addess EA of an opcode using
* IX+offset resp. IY+offset addressing.
***************************************************************/
#define EAX EA = (UINT32)(UINT16)(_IX+(INT8)ARG())
#define EAY EA = (UINT32)(UINT16)(_IY+(INT8)ARG())
/***************************************************************
* POP
***************************************************************/
#define POP(DR) { RM16( _SPD, &Z180.DR ); _SP += 2; }
/***************************************************************
* PUSH
***************************************************************/
#define PUSH(SR) { _SP -= 2; WM16( _SPD, &Z180.SR ); }
/***************************************************************
* JP
***************************************************************/
#define JP { \
_PCD = ARG16(); \
}
/***************************************************************
* JP_COND
***************************************************************/
#define JP_COND(cond) \
if( cond ) \
{ \
_PCD = ARG16(); \
} \
else \
{ \
_PC += 2; \
}
/***************************************************************
* JR
***************************************************************/
#define JR() \
{ \
unsigned oldpc = _PCD-1; \
INT8 arg = (INT8)ARG(); /* ARG() also increments _PC */ \
_PC += arg; /* so don't do _PC += ARG() */ \
/* speed up busy loop */ \
if( _PCD == oldpc ) \
{ \
if( !Z180.after_EI ) \
BURNODD( z180_icount, 1, cc[Z180_TABLE_op][0x18] ); \
} \
else \
{ \
UINT8 op = memory_decrypted_read_byte(Z180.program, _PCD); \
if( _PCD == oldpc-1 ) \
{ \
/* NOP - JR $-1 or EI - JR $-1 */ \
if ( op == 0x00 || op == 0xfb ) \
{ \
if( !Z180.after_EI ) \
BURNODD( z180_icount-cc[Z180_TABLE_op][0x00],\
2, cc[Z180_TABLE_op][0x00]+cc[Z180_TABLE_op][0x18]); \
} \
} \
else \
/* LD SP,#xxxx - JR $-3 */ \
if( _PCD == oldpc-3 && op == 0x31 ) \
{ \
if( !Z180.after_EI ) \
BURNODD( z180_icount-cc[Z180_TABLE_op][0x31], \
2, cc[Z180_TABLE_op][0x31]+cc[Z180_TABLE_op][0x18]); \
} \
} \
}
/***************************************************************
* JR_COND
***************************************************************/
#define JR_COND(cond,opcode) \
if( cond ) \
{ \
INT8 arg = (INT8)ARG(); /* ARG() also increments _PC */ \
_PC += arg; /* so don't do _PC += ARG() */ \
CC(ex,opcode); \
} \
else _PC++; \
/***************************************************************
* CALL
***************************************************************/
#define CALL() \
EA = ARG16(); \
PUSH( PC ); \
_PCD = EA;
/***************************************************************
* CALL_COND
***************************************************************/
#define CALL_COND(cond,opcode) \
if( cond ) \
{ \
EA = ARG16(); \
PUSH( PC ); \
_PCD = EA; \
CC(ex,opcode); \
} \
else \
{ \
_PC+=2; \
}
/***************************************************************
* RET_COND
***************************************************************/
#define RET_COND(cond,opcode) \
if( cond ) \
{ \
POP(PC); \
CC(ex,opcode); \
}
/***************************************************************
* RETN
***************************************************************/
#define RETN { \
LOG(("Z180 '%s' RETN IFF1:%d IFF2:%d\n", Z180.device->tag, _IFF1, _IFF2)); \
POP(PC); \
_IFF1 = _IFF2; \
}
/***************************************************************
* RETI
***************************************************************/
#define RETI { \
POP(PC); \
/* according to http://www.msxnet.org/tech/Z80/z80undoc.txt */ \
/* _IFF1 = _IFF2; */ \
if (Z180.daisy) \
z80daisy_call_reti_device(Z180.daisy); \
}
/***************************************************************
* LD R,A
***************************************************************/
#define LD_R_A { \
_R = _A; \
_R2 = _A & 0x80; /* keep bit 7 of R */ \
}
/***************************************************************
* LD A,R
***************************************************************/
#define LD_A_R { \
_A = (_R & 0x7f) | _R2; \
_F = (_F & CF) | SZ[_A] | ( _IFF2 << 2 ); \
}
/***************************************************************
* 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;
/***************************************************************
* INC r8
***************************************************************/
INLINE UINT8 INC(UINT8 value)
{
UINT8 res = value + 1;
_F = (_F & CF) | SZHV_inc[res];
return (UINT8)res;
}
/***************************************************************
* DEC r8
***************************************************************/
INLINE UINT8 DEC(UINT8 value)
{
UINT8 res = value - 1;
_F = (_F & CF) | SZHV_dec[res];
return res;
}
/***************************************************************
* RLCA
***************************************************************/
#define RLCA \
_A = (_A << 1) | (_A >> 7); \
_F = (_F & (SF | ZF | PF)) | (_A & (YF | XF | CF))
/***************************************************************
* RRCA
***************************************************************/
#define RRCA \
_F = (_F & (SF | ZF | PF)) | (_A & (YF | XF | CF)); \
_A = (_A >> 1) | (_A << 7)
/***************************************************************
* RLA
***************************************************************/
#define RLA { \
UINT8 res = (_A << 1) | (_F & CF); \
UINT8 c = (_A & 0x80) ? CF : 0; \
_F = (_F & (SF | ZF | PF)) | c | (res & (YF | XF)); \
_A = res; \
}
/***************************************************************
* RRA
***************************************************************/
#define RRA { \
UINT8 res = (_A >> 1) | (_F << 7); \
UINT8 c = (_A & 0x01) ? CF : 0; \
_F = (_F & (SF | ZF | PF)) | c | (res & (YF | XF)); \
_A = res; \
}
/***************************************************************
* RRD
***************************************************************/
#define RRD { \
UINT8 n = RM(_HL); \
WM( _HL, (n >> 4) | (_A << 4) ); \
_A = (_A & 0xf0) | (n & 0x0f); \
_F = (_F & CF) | SZP[_A]; \
}
/***************************************************************
* RLD
***************************************************************/
#define RLD { \
UINT8 n = RM(_HL); \
WM( _HL, (n << 4) | (_A & 0x0f) ); \
_A = (_A & 0xf0) | (n >> 4); \
_F = (_F & CF) | SZP[_A]; \
}
/***************************************************************
* ADD A,n
***************************************************************/
#if BIG_FLAGS_ARRAY
#define ADD(value) \
{ \
UINT32 ah = _AFD & 0xff00; \
UINT32 res = (UINT8)((ah >> 8) + value); \
_F = SZHVC_add[ah | res]; \
_A = res; \
}
#else
#define ADD(value) \
{ \
unsigned val = value; \
unsigned res = _A + val; \
_F = SZ[(UINT8)res] | ((res >> 8) & CF) | \
((_A ^ res ^ val) & HF) | \
(((val ^ _A ^ 0x80) & (val ^ res) & 0x80) >> 5); \
_A = (UINT8)res; \
}
#endif
/***************************************************************
* ADC A,n
***************************************************************/
#if BIG_FLAGS_ARRAY
#define ADC(value) \
{ \
UINT32 ah = _AFD & 0xff00, c = _AFD & 1; \
UINT32 res = (UINT8)((ah >> 8) + value + c); \
_F = SZHVC_add[(c << 16) | ah | res]; \
_A = res; \
}
#else
#define ADC(value) \
{ \
unsigned val = value; \
unsigned res = _A + val + (_F & CF); \
_F = SZ[res & 0xff] | ((res >> 8) & CF) | \
((_A ^ res ^ val) & HF) | \
(((val ^ _A ^ 0x80) & (val ^ res) & 0x80) >> 5); \
_A = res; \
}
#endif
/***************************************************************
* SUB n
***************************************************************/
#if BIG_FLAGS_ARRAY
#define SUB(value) \
{ \
UINT32 ah = _AFD & 0xff00; \
UINT32 res = (UINT8)((ah >> 8) - value); \
_F = SZHVC_sub[ah | res]; \
_A = res; \
}
#else
#define SUB(value) \
{ \
unsigned val = value; \
unsigned res = _A - val; \
_F = SZ[res & 0xff] | ((res >> 8) & CF) | NF | \
((_A ^ res ^ val) & HF) | \
(((val ^ _A) & (_A ^ res) & 0x80) >> 5); \
_A = res; \
}
#endif
/***************************************************************
* SBC A,n
***************************************************************/
#if BIG_FLAGS_ARRAY
#define SBC(value) \
{ \
UINT32 ah = _AFD & 0xff00, c = _AFD & 1; \
UINT32 res = (UINT8)((ah >> 8) - value - c); \
_F = SZHVC_sub[(c<<16) | ah | res]; \
_A = res; \
}
#else
#define SBC(value) \
{ \
unsigned val = value; \
unsigned res = _A - val - (_F & CF); \
_F = SZ[res & 0xff] | ((res >> 8) & CF) | NF | \
((_A ^ res ^ val) & HF) | \
(((val ^ _A) & (_A ^ res) & 0x80) >> 5); \
_A = res; \
}
#endif
/***************************************************************
* NEG
***************************************************************/
#define NEG { \
UINT8 value = _A; \
_A = 0; \
SUB(value); \
}
/***************************************************************
* DAA
***************************************************************/
#define DAA { \
int idx = _A; \
if( _F & CF ) idx |= 0x100; \
if( _F & HF ) idx |= 0x200; \
if( _F & NF ) idx |= 0x400; \
_AF = DAATable[idx]; \
}
/***************************************************************
* AND n
***************************************************************/
#define AND(value) \
_A &= value; \
_F = SZP[_A] | HF
/***************************************************************
* OR n
***************************************************************/
#define OR(value) \
_A |= value; \
_F = SZP[_A]
/***************************************************************
* XOR n
***************************************************************/
#define XOR(value) \
_A ^= value; \
_F = SZP[_A]
/***************************************************************
* CP n
***************************************************************/
#if BIG_FLAGS_ARRAY
#define CP(value) \
{ \
UINT32 ah = _AFD & 0xff00; \
UINT32 res = (UINT8)((ah >> 8) - value); \
_F = SZHVC_sub[ah | res]; \
}
#else
#define CP(value) \
{ \
unsigned val = value; \
unsigned res = _A - val; \
_F = SZ[res & 0xff] | ((res >> 8) & CF) | NF | \
((_A ^ res ^ val) & HF) | \
((((val ^ _A) & (_A ^ res)) >> 5) & VF); \
}
#endif
/***************************************************************
* EX AF,AF'
***************************************************************/
#define EX_AF { \
PAIR tmp; \
tmp = Z180.AF; Z180.AF = Z180.AF2; Z180.AF2 = tmp; \
}
/***************************************************************
* EX DE,HL
***************************************************************/
#define EX_DE_HL { \
PAIR tmp; \
tmp = Z180.DE; Z180.DE = Z180.HL; Z180.HL = tmp; \
}
/***************************************************************
* EXX
***************************************************************/
#define EXX { \
PAIR tmp; \
tmp = Z180.BC; Z180.BC = Z180.BC2; Z180.BC2 = tmp; \
tmp = Z180.DE; Z180.DE = Z180.DE2; Z180.DE2 = tmp; \
tmp = Z180.HL; Z180.HL = Z180.HL2; Z180.HL2 = tmp; \
}
/***************************************************************
* EX (SP),r16
***************************************************************/
#define EXSP(DR) \
{ \
PAIR tmp = { { 0, 0, 0, 0 } }; \
RM16( _SPD, &tmp ); \
WM16( _SPD, &Z180.DR ); \
Z180.DR = tmp; \
}
/***************************************************************
* ADD16
***************************************************************/
#define ADD16(DR,SR) \
{ \
UINT32 res = Z180.DR.d + Z180.SR.d; \
_F = (_F & (SF | ZF | VF)) | \
(((Z180.DR.d ^ res ^ Z180.SR.d) >> 8) & HF) | \
((res >> 16) & CF); \
Z180.DR.w.l = (UINT16)res; \
}
/***************************************************************
* ADC r16,r16
***************************************************************/
#define ADC16(DR) \
{ \
UINT32 res = _HLD + Z180.DR.d + (_F & CF); \
_F = (((_HLD ^ res ^ Z180.DR.d) >> 8) & HF) | \
((res >> 16) & CF) | \
((res >> 8) & SF) | \
((res & 0xffff) ? 0 : ZF) | \
(((Z180.DR.d ^ _HLD ^ 0x8000) & (Z180.DR.d ^ res) & 0x8000) >> 13); \
_HL = (UINT16)res; \
}
/***************************************************************
* SBC r16,r16
***************************************************************/
#define SBC16(DR) \
{ \
UINT32 res = _HLD - Z180.DR.d - (_F & CF); \
_F = (((_HLD ^ res ^ Z180.DR.d) >> 8) & HF) | NF | \
((res >> 16) & CF) | \
((res >> 8) & SF) | \
((res & 0xffff) ? 0 : ZF) | \
(((Z180.DR.d ^ _HLD) & (_HLD ^ res) &0x8000) >> 13); \
_HL = (UINT16)res; \
}
/***************************************************************
* RLC r8
***************************************************************/
INLINE UINT8 RLC(UINT8 value)
{
unsigned res = value;
unsigned c = (res & 0x80) ? CF : 0;
res = ((res << 1) | (res >> 7)) & 0xff;
_F = SZP[res] | c;
return res;
}
/***************************************************************
* RRC r8
***************************************************************/
INLINE UINT8 RRC(UINT8 value)
{
unsigned res = value;
unsigned c = (res & 0x01) ? CF : 0;
res = ((res >> 1) | (res << 7)) & 0xff;
_F = SZP[res] | c;
return res;
}
/***************************************************************
* RL r8
***************************************************************/
INLINE UINT8 RL(UINT8 value)
{
unsigned res = value;
unsigned c = (res & 0x80) ? CF : 0;
res = ((res << 1) | (_F & CF)) & 0xff;
_F = SZP[res] | c;
return res;
}
/***************************************************************
* RR r8
***************************************************************/
INLINE UINT8 RR(UINT8 value)
{
unsigned res = value;
unsigned c = (res & 0x01) ? CF : 0;
res = ((res >> 1) | (_F << 7)) & 0xff;
_F = SZP[res] | c;
return res;
}
/***************************************************************
* SLA r8
***************************************************************/
INLINE UINT8 SLA(UINT8 value)
{
unsigned res = value;
unsigned c = (res & 0x80) ? CF : 0;
res = (res << 1) & 0xff;
_F = SZP[res] | c;
return res;
}
/***************************************************************
* SRA r8
***************************************************************/
INLINE UINT8 SRA(UINT8 value)
{
unsigned res = value;
unsigned c = (res & 0x01) ? CF : 0;
res = ((res >> 1) | (res & 0x80)) & 0xff;
_F = SZP[res] | c;
return res;
}
/***************************************************************
* SLL r8
***************************************************************/
INLINE UINT8 SLL(UINT8 value)
{
unsigned res = value;
unsigned c = (res & 0x80) ? CF : 0;
res = ((res << 1) | 0x01) & 0xff;
_F = SZP[res] | c;
return res;
}
/***************************************************************
* SRL r8
***************************************************************/
INLINE UINT8 SRL(UINT8 value)
{
unsigned res = value;
unsigned c = (res & 0x01) ? CF : 0;
res = (res >> 1) & 0xff;
_F = SZP[res] | c;
return res;
}
/***************************************************************
* BIT bit,r8
***************************************************************/
#undef BIT
#define BIT(bit,reg) \
_F = (_F & CF) | HF | SZ_BIT[reg & (1<<bit)]
/***************************************************************
* BIT bit,(IX/Y+o)
***************************************************************/
#define BIT_XY(bit,reg) \
_F = (_F & CF) | HF | (SZ_BIT[reg & (1<<bit)] & ~(YF|XF)) | ((EA>>8) & (YF|XF))
/***************************************************************
* RES bit,r8
***************************************************************/
INLINE UINT8 RES(UINT8 bit, UINT8 value)
{
return value & ~(1<<bit);
}
/***************************************************************
* SET bit,r8
***************************************************************/
INLINE UINT8 SET(UINT8 bit, UINT8 value)
{
return value | (1<<bit);
}
/***************************************************************
* LDI
***************************************************************/
#define LDI { \
UINT8 io = RM(_HL); \
WM( _DE, io ); \
_F &= SF | ZF | CF; \
if( (_A + io) & 0x02 ) _F |= YF; /* bit 1 -> flag 5 */ \
if( (_A + io) & 0x08 ) _F |= XF; /* bit 3 -> flag 3 */ \
_HL++; _DE++; _BC--; \
if( _BC ) _F |= VF; \
}
/***************************************************************
* CPI
***************************************************************/
#define CPI { \
UINT8 val = RM(_HL); \
UINT8 res = _A - val; \
_HL++; _BC--; \
_F = (_F & CF) | (SZ[res] & ~(YF|XF)) | ((_A ^ val ^ res) & HF) | NF; \
if( _F & HF ) res -= 1; \
if( res & 0x02 ) _F |= YF; /* bit 1 -> flag 5 */ \
if( res & 0x08 ) _F |= XF; /* bit 3 -> flag 3 */ \
if( _BC ) _F |= VF; \
}
/***************************************************************
* INI
***************************************************************/
#define INI { \
UINT8 io = IN(_BC); \
_B--; \
WM( _HL, io ); \
_HL++; \
_F = SZ[_B]; \
if( io & SF ) _F |= NF; \
if( (_C + io + 1) & 0x100 ) _F |= HF | CF; \
if( (irep_tmp1[_C & 3][io & 3] ^ \
breg_tmp2[_B] ^ \
(_C >> 2) ^ \
(io >> 2)) & 1 ) \
_F |= PF; \
}
/***************************************************************
* OUTI
***************************************************************/
#define OUTI { \
UINT8 io = RM(_HL); \
_B--; \
OUT( _BC, io ); \
_HL++; \
_F = SZ[_B]; \
if( io & SF ) _F |= NF; \
if( (_C + io + 1) & 0x100 ) _F |= HF | CF; \
if( (irep_tmp1[_C & 3][io & 3] ^ \
breg_tmp2[_B] ^ \
(_C >> 2) ^ \
(io >> 2)) & 1 ) \
_F |= PF; \
}
/***************************************************************
* LDD
***************************************************************/
#define LDD { \
UINT8 io = RM(_HL); \
WM( _DE, io ); \
_F &= SF | ZF | CF; \
if( (_A + io) & 0x02 ) _F |= YF; /* bit 1 -> flag 5 */ \
if( (_A + io) & 0x08 ) _F |= XF; /* bit 3 -> flag 3 */ \
_HL--; _DE--; _BC--; \
if( _BC ) _F |= VF; \
}
/***************************************************************
* CPD
***************************************************************/
#define CPD { \
UINT8 val = RM(_HL); \
UINT8 res = _A - val; \
_HL--; _BC--; \
_F = (_F & CF) | (SZ[res] & ~(YF|XF)) | ((_A ^ val ^ res) & HF) | NF; \
if( _F & HF ) res -= 1; \
if( res & 0x02 ) _F |= YF; /* bit 1 -> flag 5 */ \
if( res & 0x08 ) _F |= XF; /* bit 3 -> flag 3 */ \
if( _BC ) _F |= VF; \
}
/***************************************************************
* IND
***************************************************************/
#define IND { \
UINT8 io = IN(_BC); \
_B--; \
WM( _HL, io ); \
_HL--; \
_F = SZ[_B]; \
if( io & SF ) _F |= NF; \
if( (_C + io - 1) & 0x100 ) _F |= HF | CF; \
if( (drep_tmp1[_C & 3][io & 3] ^ \
breg_tmp2[_B] ^ \
(_C >> 2) ^ \
(io >> 2)) & 1 ) \
_F |= PF; \
}
/***************************************************************
* OUTD
***************************************************************/
#define OUTD { \
UINT8 io = RM(_HL); \
_B--; \
OUT( _BC, io ); \
_HL--; \
_F = SZ[_B]; \
if( io & SF ) _F |= NF; \
if( (_C + io - 1) & 0x100 ) _F |= HF | CF; \
if( (drep_tmp1[_C & 3][io & 3] ^ \
breg_tmp2[_B] ^ \
(_C >> 2) ^ \
(io >> 2)) & 1 ) \
_F |= PF; \
}
/***************************************************************
* LDIR
***************************************************************/
#define LDIR \
LDI; \
if( _BC ) \
{ \
_PC -= 2; \
CC(ex,0xb0); \
}
/***************************************************************
* CPIR
***************************************************************/
#define CPIR \
CPI; \
if( _BC && !(_F & ZF) ) \
{ \
_PC -= 2; \
CC(ex,0xb1); \
}
/***************************************************************
* INIR
***************************************************************/
#define INIR \
INI; \
if( _B ) \
{ \
_PC -= 2; \
CC(ex,0xb2); \
}
/***************************************************************
* OTIR
***************************************************************/
#define OTIR \
OUTI; \
if( _B ) \
{ \
_PC -= 2; \
CC(ex,0xb3); \
}
/***************************************************************
* LDDR
***************************************************************/
#define LDDR \
LDD; \
if( _BC ) \
{ \
_PC -= 2; \
CC(ex,0xb8); \
}
/***************************************************************
* CPDR
***************************************************************/
#define CPDR \
CPD; \
if( _BC && !(_F & ZF) ) \
{ \
_PC -= 2; \
CC(ex,0xb9); \
}
/***************************************************************
* INDR
***************************************************************/
#define INDR \
IND; \
if( _B ) \
{ \
_PC -= 2; \
CC(ex,0xba); \
}
/***************************************************************
* OTDR
***************************************************************/
#define OTDR \
OUTD; \
if( _B ) \
{ \
_PC -= 2; \
CC(ex,0xbb); \
}
/***************************************************************
* EI
***************************************************************/
#define EI { \
_IFF1 = _IFF2 = 1; \
Z180.after_EI = 1; \
}
/***************************************************************
* TST n
***************************************************************/
#define TST(value) \
_F = SZP[_A & value] | HF
/***************************************************************
* MLT rr
***************************************************************/
#define MLT(DR) { \
Z180.DR.w.l = Z180.DR.b.l * Z180.DR.b.h; \
}
/***************************************************************
* OTIM
***************************************************************/
#define OTIM { \
_B--; \
OUT( _C, RM(_HL) ); \
_HL++; \
_C++; \
_F = (_B) ? NF : NF | ZF; \
}
/***************************************************************
* OTDM
***************************************************************/
#define OTDM { \
_B--; \
OUT( _C, RM(_HL) ); \
_HL--; \
_C--; \
_F = (_B) ? NF : NF | ZF; \
}
/***************************************************************
* OTIMR
***************************************************************/
#define OTIMR \
OTIM; \
if( _B ) \
{ \
_PC -= 2; \
CC(ex,0xb3); \
}
/***************************************************************
* OTDMR
***************************************************************/
#define OTDMR \
OTDM; \
if( _B ) \
{ \
_PC -= 2; \
CC(ex,0xb3); \
}
/***************************************************************
* OTDMR
***************************************************************/
#define SLP { \
z180_icount = 0; \
_HALT = 2; \
}