diff options
Diffstat (limited to 'trunk/src/emu/cpu/z180/z180ops.h')
-rw-r--r-- | trunk/src/emu/cpu/z180/z180ops.h | 954 |
1 files changed, 954 insertions, 0 deletions
diff --git a/trunk/src/emu/cpu/z180/z180ops.h b/trunk/src/emu/cpu/z180/z180ops.h new file mode 100644 index 00000000000..b2efef210cb --- /dev/null +++ b/trunk/src/emu/cpu/z180/z180ops.h @@ -0,0 +1,954 @@ +/*************************************************************** + * Enter HALT state; write 1 to fake port on first execution + ***************************************************************/ +#define ENTER_HALT(cs) { \ + (cs)->_PC--; \ + (cs)->HALT = 1; \ +} + +/*************************************************************** + * Leave HALT state; write 0 to fake port + ***************************************************************/ +#define LEAVE_HALT(cs) { \ + if( (cs)->HALT ) \ + { \ + (cs)->HALT = 0; \ + (cs)->_PC++; \ + } \ +} + +/*************************************************************** + * Input a byte from given I/O port + ***************************************************************/ +#define IN(cs,port) \ + (((port ^ (cs)->IO_IOCR) & 0xffc0) == 0) ? \ + z180_readcontrol(cs, port) : (cs)->iospace->read_byte(port) + +/*************************************************************** + * Output a byte to given I/O port + ***************************************************************/ +#define OUT(cs,port,value) \ + if (((port ^ (cs)->IO_IOCR) & 0xffc0) == 0) \ + z180_writecontrol(cs,port,value); \ + else (cs)->iospace->write_byte(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(z180_state *cpustate) +{ + offs_t addr, page, bb, cb; + bb = cpustate->IO_CBAR & 15; + cb = cpustate->IO_CBAR >> 4; + for( page = 0; page < 16; page++ ) + { + addr = page << 12; + if (page >= bb) + { + if (page >= cb) + addr += (cpustate->IO_CBR << 12); + else + addr += (cpustate->IO_BBR << 12); + } + cpustate->mmu[page] = (addr & 0xfffff); + } +} + + +#define MMU_REMAP_ADDR(cs,addr) ((cs)->mmu[((addr)>>12)&15]|((addr)&4095)) + +/*************************************************************** + * Read a byte from given memory location + ***************************************************************/ +#define RM(cs,addr) (cs)->program->read_byte(MMU_REMAP_ADDR(cs,addr)) +#ifdef UNUSED_FUNCTION +UINT8 z180_readmem(device_t *device, offs_t offset) +{ + z180_state *cpustate = get_safe_token(device); + return RM(cpustate, offset); +} +#endif + +/*************************************************************** + * Write a byte to given memory location + ***************************************************************/ +#define WM(cs,addr,value) (cs)->program->write_byte(MMU_REMAP_ADDR(cs,addr),value) +#ifdef UNUSED_FUNCTION +void z180_writemem(device_t *device, offs_t offset, UINT8 data) +{ + z180_state *cpustate = get_safe_token(device); + WM(cpustate, offset, data); +} +#endif + +/*************************************************************** + * Read a word from given memory location + ***************************************************************/ +INLINE void RM16( z180_state *cpustate, offs_t addr, PAIR *r ) +{ + r->b.l = RM(cpustate, addr); + r->b.h = RM(cpustate, addr+1); +} + +/*************************************************************** + * Write a word to given memory location + ***************************************************************/ +INLINE void WM16( z180_state *cpustate, offs_t addr, PAIR *r ) +{ + WM(cpustate, addr, r->b.l); + WM(cpustate, addr+1, r->b.h); +} + +/*************************************************************** + * ROP(cpustate) 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(z180_state *cpustate) +{ + offs_t addr = cpustate->_PCD; + cpustate->_PC++; + return cpustate->direct->read_decrypted_byte(MMU_REMAP_ADDR(cpustate, addr)); +} + +/**************************************************************** + * ARG(cpustate) is identical to ROP(cpustate) 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(z180_state *cpustate) +{ + offs_t addr = cpustate->_PCD; + cpustate->_PC++; + return cpustate->direct->read_raw_byte(MMU_REMAP_ADDR(cpustate, addr)); +} + +INLINE UINT32 ARG16(z180_state *cpustate) +{ + offs_t addr = cpustate->_PCD; + cpustate->_PC += 2; + return cpustate->direct->read_raw_byte(MMU_REMAP_ADDR(cpustate, addr)) | (cpustate->direct->read_raw_byte(MMU_REMAP_ADDR(cpustate, addr+1)) << 8); +} + +/*************************************************************** + * Calculate the effective addess cpustate->ea of an opcode using + * IX+offset resp. IY+offset addressing. + ***************************************************************/ +#define EAX(cs) (cs)->ea = (UINT32)(UINT16)((cs)->_IX + (INT8)ARG(cs)) +#define EAY(cs) (cs)->ea = (UINT32)(UINT16)((cs)->_IY + (INT8)ARG(cs)) + +/*************************************************************** + * POP + ***************************************************************/ +#define POP(cs,DR) { RM16(cs, (cs)->_SPD, &(cs)->DR ); (cs)->_SP += 2; } + +/*************************************************************** + * PUSH + ***************************************************************/ +#define PUSH(cs,SR) { (cs)->_SP -= 2; WM16(cs, (cs)->_SPD, &(cs)->SR); } + +/*************************************************************** + * JP + ***************************************************************/ +#define JP { \ + cpustate->_PCD = ARG16(cpustate); \ +} + +/*************************************************************** + * JP_COND + ***************************************************************/ + +#define JP_COND(cond) \ + if( cond ) \ + { \ + cpustate->_PCD = ARG16(cpustate); \ + } \ + else \ + { \ + cpustate->_PC += 2; \ + } + +/*************************************************************** + * JR + ***************************************************************/ +#define JR() \ +{ \ + INT8 arg = (INT8)ARG(cpustate); /* ARG(cpustate) also increments cpustate->_PC */ \ + cpustate->_PC += arg; /* so don't do cpustate->_PC += ARG(cpustate) */ \ +} + +/*************************************************************** + * JR_COND + ***************************************************************/ +#define JR_COND(cond,opcode) \ + if( cond ) \ + { \ + INT8 arg = (INT8)ARG(cpustate); /* ARG(cpustate) also increments cpustate->_PC */ \ + cpustate->_PC += arg; /* so don't do cpustate->_PC += ARG(cpustate) */ \ + CC(ex,opcode); \ + } \ + else cpustate->_PC++; \ + +/*************************************************************** + * CALL + ***************************************************************/ +#define CALL() \ + cpustate->ea = ARG16(cpustate); \ + PUSH(cpustate, PC ); \ + cpustate->_PCD = cpustate->ea; + +/*************************************************************** + * CALL_COND + ***************************************************************/ +#define CALL_COND(cond,opcode) \ + if( cond ) \ + { \ + cpustate->ea = ARG16(cpustate); \ + PUSH(cpustate, PC ); \ + cpustate->_PCD = cpustate->ea; \ + CC(ex,opcode); \ + } \ + else \ + { \ + cpustate->_PC+=2; \ + } + +/*************************************************************** + * RET_COND + ***************************************************************/ +#define RET_COND(cond,opcode) \ + if( cond ) \ + { \ + POP(cpustate, PC); \ + CC(ex,opcode); \ + } + +/*************************************************************** + * RETN + ***************************************************************/ +#define RETN { \ + LOG(("Z180 '%s' RETN IFF1:%d IFF2:%d\n", cpustate->device->tag(), cpustate->IFF1, cpustate->IFF2)); \ + POP(cpustate, PC); \ + cpustate->IFF1 = cpustate->IFF2; \ +} + +/*************************************************************** + * RETI + ***************************************************************/ +#define RETI { \ + POP(cpustate, PC); \ +/* according to http://www.msxnet.org/tech/Z80/z80undoc.txt */ \ +/* cpustate->IFF1 = cpustate->IFF2; */ \ + cpustate->daisy.call_reti_device(); \ +} + +/*************************************************************** + * LD R,A + ***************************************************************/ +#define LD_R_A { \ + cpustate->R = cpustate->_A; \ + cpustate->R2 = cpustate->_A & 0x80; /* keep bit 7 of R */ \ +} + +/*************************************************************** + * LD A,R + ***************************************************************/ +#define LD_A_R { \ + cpustate->_A = (cpustate->R & 0x7f) | cpustate->R2; \ + cpustate->_F = (cpustate->_F & CF) | SZ[cpustate->_A] | ( cpustate->IFF2 << 2 ); \ +} + +/*************************************************************** + * LD I,A + ***************************************************************/ +#define LD_I_A { \ + cpustate->I = cpustate->_A; \ +} + +/*************************************************************** + * LD A,I + ***************************************************************/ +#define LD_A_I { \ + cpustate->_A = cpustate->I; \ + cpustate->_F = (cpustate->_F & CF) | SZ[cpustate->_A] | ( cpustate->IFF2 << 2 ); \ +} + +/*************************************************************** + * RST + ***************************************************************/ +#define RST(addr) \ + PUSH(cpustate, PC ); \ + cpustate->_PCD = addr; + +/*************************************************************** + * INC r8 + ***************************************************************/ +INLINE UINT8 INC(z180_state *cpustate, UINT8 value) +{ + UINT8 res = value + 1; + cpustate->_F = (cpustate->_F & CF) | SZHV_inc[res]; + return (UINT8)res; +} + +/*************************************************************** + * DEC r8 + ***************************************************************/ +INLINE UINT8 DEC(z180_state *cpustate, UINT8 value) +{ + UINT8 res = value - 1; + cpustate->_F = (cpustate->_F & CF) | SZHV_dec[res]; + return res; +} + +/*************************************************************** + * RLCA + ***************************************************************/ +#define RLCA \ + cpustate->_A = (cpustate->_A << 1) | (cpustate->_A >> 7); \ + cpustate->_F = (cpustate->_F & (SF | ZF | PF)) | (cpustate->_A & (YF | XF | CF)) + +/*************************************************************** + * RRCA + ***************************************************************/ +#define RRCA \ + cpustate->_F = (cpustate->_F & (SF | ZF | PF)) | (cpustate->_A & (YF | XF | CF)); \ + cpustate->_A = (cpustate->_A >> 1) | (cpustate->_A << 7) + +/*************************************************************** + * RLA + ***************************************************************/ +#define RLA { \ + UINT8 res = (cpustate->_A << 1) | (cpustate->_F & CF); \ + UINT8 c = (cpustate->_A & 0x80) ? CF : 0; \ + cpustate->_F = (cpustate->_F & (SF | ZF | PF)) | c | (res & (YF | XF)); \ + cpustate->_A = res; \ +} + +/*************************************************************** + * RRA + ***************************************************************/ +#define RRA { \ + UINT8 res = (cpustate->_A >> 1) | (cpustate->_F << 7); \ + UINT8 c = (cpustate->_A & 0x01) ? CF : 0; \ + cpustate->_F = (cpustate->_F & (SF | ZF | PF)) | c | (res & (YF | XF)); \ + cpustate->_A = res; \ +} + +/*************************************************************** + * RRD + ***************************************************************/ +#define RRD { \ + UINT8 n = RM(cpustate, cpustate->_HL); \ + WM(cpustate, cpustate->_HL, (n >> 4) | (cpustate->_A << 4) ); \ + cpustate->_A = (cpustate->_A & 0xf0) | (n & 0x0f); \ + cpustate->_F = (cpustate->_F & CF) | SZP[cpustate->_A]; \ +} + +/*************************************************************** + * RLD + ***************************************************************/ +#define RLD { \ + UINT8 n = RM(cpustate, cpustate->_HL); \ + WM(cpustate, cpustate->_HL, (n << 4) | (cpustate->_A & 0x0f) ); \ + cpustate->_A = (cpustate->_A & 0xf0) | (n >> 4); \ + cpustate->_F = (cpustate->_F & CF) | SZP[cpustate->_A]; \ +} + +/*************************************************************** + * ADD A,n + ***************************************************************/ +#define ADD(value) \ +{ \ + UINT32 ah = cpustate->_AFD & 0xff00; \ + UINT32 res = (UINT8)((ah >> 8) + value); \ + cpustate->_F = SZHVC_add[ah | res]; \ + cpustate->_A = res; \ +} + +/*************************************************************** + * ADC A,n + ***************************************************************/ +#define ADC(value) \ +{ \ + UINT32 ah = cpustate->_AFD & 0xff00, c = cpustate->_AFD & 1; \ + UINT32 res = (UINT8)((ah >> 8) + value + c); \ + cpustate->_F = SZHVC_add[(c << 16) | ah | res]; \ + cpustate->_A = res; \ +} + +/*************************************************************** + * SUB n + ***************************************************************/ +#define SUB(value) \ +{ \ + UINT32 ah = cpustate->_AFD & 0xff00; \ + UINT32 res = (UINT8)((ah >> 8) - value); \ + cpustate->_F = SZHVC_sub[ah | res]; \ + cpustate->_A = res; \ +} + +/*************************************************************** + * SBC A,n + ***************************************************************/ +#define SBC(value) \ +{ \ + UINT32 ah = cpustate->_AFD & 0xff00, c = cpustate->_AFD & 1; \ + UINT32 res = (UINT8)((ah >> 8) - value - c); \ + cpustate->_F = SZHVC_sub[(c<<16) | ah | res]; \ + cpustate->_A = res; \ +} + +/*************************************************************** + * NEG + ***************************************************************/ +#define NEG { \ + UINT8 value = cpustate->_A; \ + cpustate->_A = 0; \ + SUB(value); \ +} + +/*************************************************************** + * DAA + ***************************************************************/ +#define DAA { \ + UINT8 r = cpustate->_A; \ + if (cpustate->_F&NF) { \ + if ((cpustate->_F&HF)|((cpustate->_A&0xf)>9)) r-=6; \ + if ((cpustate->_F&CF)|(cpustate->_A>0x99)) r-=0x60; \ + } \ + else { \ + if ((cpustate->_F&HF)|((cpustate->_A&0xf)>9)) r+=6; \ + if ((cpustate->_F&CF)|(cpustate->_A>0x99)) r+=0x60; \ + } \ + cpustate->_F=(cpustate->_F&3)|(cpustate->_A>0x99)|((cpustate->_A^r)&HF)|SZP[r]; \ + cpustate->_A=r; \ +} + +/*************************************************************** + * AND n + ***************************************************************/ +#define AND(value) \ + cpustate->_A &= value; \ + cpustate->_F = SZP[cpustate->_A] | HF + +/*************************************************************** + * OR n + ***************************************************************/ +#define OR(value) \ + cpustate->_A |= value; \ + cpustate->_F = SZP[cpustate->_A] + +/*************************************************************** + * XOR n + ***************************************************************/ +#define XOR(value) \ + cpustate->_A ^= value; \ + cpustate->_F = SZP[cpustate->_A] + +/*************************************************************** + * CP n + ***************************************************************/ +#define CP(value) \ +{ \ + UINT32 ah = cpustate->_AFD & 0xff00; \ + UINT32 res = (UINT8)((ah >> 8) - value); \ + cpustate->_F = SZHVC_sub[ah | res]; \ +} + +/*************************************************************** + * EX AF,AF' + ***************************************************************/ +#define EX_AF { \ + PAIR tmp; \ + tmp = cpustate->AF; cpustate->AF = cpustate->AF2; cpustate->AF2 = tmp; \ +} + +/*************************************************************** + * EX DE,HL + ***************************************************************/ +#define EX_DE_HL { \ + PAIR tmp; \ + tmp = cpustate->DE; cpustate->DE = cpustate->HL; cpustate->HL = tmp; \ +} + +/*************************************************************** + * EXX + ***************************************************************/ +#define EXX { \ + PAIR tmp; \ + tmp = cpustate->BC; cpustate->BC = cpustate->BC2; cpustate->BC2 = tmp; \ + tmp = cpustate->DE; cpustate->DE = cpustate->DE2; cpustate->DE2 = tmp; \ + tmp = cpustate->HL; cpustate->HL = cpustate->HL2; cpustate->HL2 = tmp; \ +} + +/*************************************************************** + * EX (SP),r16 + ***************************************************************/ +#define EXSP(DR) \ +{ \ + PAIR tmp = { { 0, 0, 0, 0 } }; \ + RM16(cpustate, cpustate->_SPD, &tmp ); \ + WM16(cpustate, cpustate->_SPD, &cpustate->DR ); \ + cpustate->DR = tmp; \ +} + + +/*************************************************************** + * ADD16 + ***************************************************************/ +#define ADD16(DR,SR) \ +{ \ + UINT32 res = cpustate->DR.d + cpustate->SR.d; \ + cpustate->_F = (cpustate->_F & (SF | ZF | VF)) | \ + (((cpustate->DR.d ^ res ^ cpustate->SR.d) >> 8) & HF) | \ + ((res >> 16) & CF); \ + cpustate->DR.w.l = (UINT16)res; \ +} + +/*************************************************************** + * ADC r16,r16 + ***************************************************************/ +#define ADC16(DR) \ +{ \ + UINT32 res = cpustate->_HLD + cpustate->DR.d + (cpustate->_F & CF); \ + cpustate->_F = (((cpustate->_HLD ^ res ^ cpustate->DR.d) >> 8) & HF) | \ + ((res >> 16) & CF) | \ + ((res >> 8) & SF) | \ + ((res & 0xffff) ? 0 : ZF) | \ + (((cpustate->DR.d ^ cpustate->_HLD ^ 0x8000) & (cpustate->DR.d ^ res) & 0x8000) >> 13); \ + cpustate->_HL = (UINT16)res; \ +} + +/*************************************************************** + * SBC r16,r16 + ***************************************************************/ +#define SBC16(DR) \ +{ \ + UINT32 res = cpustate->_HLD - cpustate->DR.d - (cpustate->_F & CF); \ + cpustate->_F = (((cpustate->_HLD ^ res ^ cpustate->DR.d) >> 8) & HF) | NF | \ + ((res >> 16) & CF) | \ + ((res >> 8) & SF) | \ + ((res & 0xffff) ? 0 : ZF) | \ + (((cpustate->DR.d ^ cpustate->_HLD) & (cpustate->_HLD ^ res) &0x8000) >> 13); \ + cpustate->_HL = (UINT16)res; \ +} + +/*************************************************************** + * RLC r8 + ***************************************************************/ +INLINE UINT8 RLC(z180_state *cpustate, UINT8 value) +{ + unsigned res = value; + unsigned c = (res & 0x80) ? CF : 0; + res = ((res << 1) | (res >> 7)) & 0xff; + cpustate->_F = SZP[res] | c; + return res; +} + +/*************************************************************** + * RRC r8 + ***************************************************************/ +INLINE UINT8 RRC(z180_state *cpustate, UINT8 value) +{ + unsigned res = value; + unsigned c = (res & 0x01) ? CF : 0; + res = ((res >> 1) | (res << 7)) & 0xff; + cpustate->_F = SZP[res] | c; + return res; +} + +/*************************************************************** + * RL r8 + ***************************************************************/ +INLINE UINT8 RL(z180_state *cpustate, UINT8 value) +{ + unsigned res = value; + unsigned c = (res & 0x80) ? CF : 0; + res = ((res << 1) | (cpustate->_F & CF)) & 0xff; + cpustate->_F = SZP[res] | c; + return res; +} + +/*************************************************************** + * RR r8 + ***************************************************************/ +INLINE UINT8 RR(z180_state *cpustate, UINT8 value) +{ + unsigned res = value; + unsigned c = (res & 0x01) ? CF : 0; + res = ((res >> 1) | (cpustate->_F << 7)) & 0xff; + cpustate->_F = SZP[res] | c; + return res; +} + +/*************************************************************** + * SLA r8 + ***************************************************************/ +INLINE UINT8 SLA(z180_state *cpustate, UINT8 value) +{ + unsigned res = value; + unsigned c = (res & 0x80) ? CF : 0; + res = (res << 1) & 0xff; + cpustate->_F = SZP[res] | c; + return res; +} + +/*************************************************************** + * SRA r8 + ***************************************************************/ +INLINE UINT8 SRA(z180_state *cpustate, UINT8 value) +{ + unsigned res = value; + unsigned c = (res & 0x01) ? CF : 0; + res = ((res >> 1) | (res & 0x80)) & 0xff; + cpustate->_F = SZP[res] | c; + return res; +} + +/*************************************************************** + * SLL r8 + ***************************************************************/ +INLINE UINT8 SLL(z180_state *cpustate, UINT8 value) +{ + unsigned res = value; + unsigned c = (res & 0x80) ? CF : 0; + res = ((res << 1) | 0x01) & 0xff; + cpustate->_F = SZP[res] | c; + return res; +} + +/*************************************************************** + * SRL r8 + ***************************************************************/ +INLINE UINT8 SRL(z180_state *cpustate, UINT8 value) +{ + unsigned res = value; + unsigned c = (res & 0x01) ? CF : 0; + res = (res >> 1) & 0xff; + cpustate->_F = SZP[res] | c; + return res; +} + +/*************************************************************** + * BIT bit,r8 + ***************************************************************/ +#undef BIT +#define BIT(bit,reg) \ + cpustate->_F = (cpustate->_F & CF) | HF | SZ_BIT[reg & (1<<bit)] + +/*************************************************************** + * BIT bit,(IX/Y+o) + ***************************************************************/ +#define BIT_XY(bit,reg) \ + cpustate->_F = (cpustate->_F & CF) | HF | (SZ_BIT[reg & (1<<bit)] & ~(YF|XF)) | ((cpustate->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(cpustate, cpustate->_HL); \ + WM(cpustate, cpustate->_DE, io ); \ + cpustate->_F &= SF | ZF | CF; \ + if( (cpustate->_A + io) & 0x02 ) cpustate->_F |= YF; /* bit 1 -> flag 5 */ \ + if( (cpustate->_A + io) & 0x08 ) cpustate->_F |= XF; /* bit 3 -> flag 3 */ \ + cpustate->_HL++; cpustate->_DE++; cpustate->_BC--; \ + if( cpustate->_BC ) cpustate->_F |= VF; \ +} + +/*************************************************************** + * CPI + ***************************************************************/ +#define CPI { \ + UINT8 val = RM(cpustate, cpustate->_HL); \ + UINT8 res = cpustate->_A - val; \ + cpustate->_HL++; cpustate->_BC--; \ + cpustate->_F = (cpustate->_F & CF) | (SZ[res] & ~(YF|XF)) | ((cpustate->_A ^ val ^ res) & HF) | NF; \ + if( cpustate->_F & HF ) res -= 1; \ + if( res & 0x02 ) cpustate->_F |= YF; /* bit 1 -> flag 5 */ \ + if( res & 0x08 ) cpustate->_F |= XF; /* bit 3 -> flag 3 */ \ + if( cpustate->_BC ) cpustate->_F |= VF; \ +} + +/*************************************************************** + * INI + ***************************************************************/ +#define INI { \ + UINT8 io = IN(cpustate, cpustate->_BC); \ + cpustate->_B--; \ + WM(cpustate, cpustate->_HL, io ); \ + cpustate->_HL++; \ + cpustate->_F = SZ[cpustate->_B]; \ + if( io & SF ) cpustate->_F |= NF; \ + if( (cpustate->_C + io + 1) & 0x100 ) cpustate->_F |= HF | CF; \ + if( (irep_tmp1[cpustate->_C & 3][io & 3] ^ \ + breg_tmp2[cpustate->_B] ^ \ + (cpustate->_C >> 2) ^ \ + (io >> 2)) & 1 ) \ + cpustate->_F |= PF; \ +} + +/*************************************************************** + * OUTI + ***************************************************************/ +#define OUTI { \ + UINT8 io = RM(cpustate, cpustate->_HL); \ + cpustate->_B--; \ + OUT(cpustate, cpustate->_BC, io ); \ + cpustate->_HL++; \ + cpustate->_F = SZ[cpustate->_B]; \ + if( io & SF ) cpustate->_F |= NF; \ + if( (cpustate->_C + io + 1) & 0x100 ) cpustate->_F |= HF | CF; \ + if( (irep_tmp1[cpustate->_C & 3][io & 3] ^ \ + breg_tmp2[cpustate->_B] ^ \ + (cpustate->_C >> 2) ^ \ + (io >> 2)) & 1 ) \ + cpustate->_F |= PF; \ +} + +/*************************************************************** + * LDD + ***************************************************************/ +#define LDD { \ + UINT8 io = RM(cpustate, cpustate->_HL); \ + WM(cpustate, cpustate->_DE, io ); \ + cpustate->_F &= SF | ZF | CF; \ + if( (cpustate->_A + io) & 0x02 ) cpustate->_F |= YF; /* bit 1 -> flag 5 */ \ + if( (cpustate->_A + io) & 0x08 ) cpustate->_F |= XF; /* bit 3 -> flag 3 */ \ + cpustate->_HL--; cpustate->_DE--; cpustate->_BC--; \ + if( cpustate->_BC ) cpustate->_F |= VF; \ +} + +/*************************************************************** + * CPD + ***************************************************************/ +#define CPD { \ + UINT8 val = RM(cpustate, cpustate->_HL); \ + UINT8 res = cpustate->_A - val; \ + cpustate->_HL--; cpustate->_BC--; \ + cpustate->_F = (cpustate->_F & CF) | (SZ[res] & ~(YF|XF)) | ((cpustate->_A ^ val ^ res) & HF) | NF; \ + if( cpustate->_F & HF ) res -= 1; \ + if( res & 0x02 ) cpustate->_F |= YF; /* bit 1 -> flag 5 */ \ + if( res & 0x08 ) cpustate->_F |= XF; /* bit 3 -> flag 3 */ \ + if( cpustate->_BC ) cpustate->_F |= VF; \ +} + +/*************************************************************** + * IND + ***************************************************************/ +#define IND { \ + UINT8 io = IN(cpustate, cpustate->_BC); \ + cpustate->_B--; \ + WM(cpustate, cpustate->_HL, io ); \ + cpustate->_HL--; \ + cpustate->_F = SZ[cpustate->_B]; \ + if( io & SF ) cpustate->_F |= NF; \ + if( (cpustate->_C + io - 1) & 0x100 ) cpustate->_F |= HF | CF; \ + if( (drep_tmp1[cpustate->_C & 3][io & 3] ^ \ + breg_tmp2[cpustate->_B] ^ \ + (cpustate->_C >> 2) ^ \ + (io >> 2)) & 1 ) \ + cpustate->_F |= PF; \ +} + +/*************************************************************** + * OUTD + ***************************************************************/ +#define OUTD { \ + UINT8 io = RM(cpustate, cpustate->_HL); \ + cpustate->_B--; \ + OUT(cpustate, cpustate->_BC, io ); \ + cpustate->_HL--; \ + cpustate->_F = SZ[cpustate->_B]; \ + if( io & SF ) cpustate->_F |= NF; \ + if( (cpustate->_C + io - 1) & 0x100 ) cpustate->_F |= HF | CF; \ + if( (drep_tmp1[cpustate->_C & 3][io & 3] ^ \ + breg_tmp2[cpustate->_B] ^ \ + (cpustate->_C >> 2) ^ \ + (io >> 2)) & 1 ) \ + cpustate->_F |= PF; \ +} + +/*************************************************************** + * LDIR + ***************************************************************/ +#define LDIR \ + LDI; \ + if( cpustate->_BC ) \ + { \ + cpustate->_PC -= 2; \ + CC(ex,0xb0); \ + } + +/*************************************************************** + * CPIR + ***************************************************************/ +#define CPIR \ + CPI; \ + if( cpustate->_BC && !(cpustate->_F & ZF) ) \ + { \ + cpustate->_PC -= 2; \ + CC(ex,0xb1); \ + } + +/*************************************************************** + * INIR + ***************************************************************/ +#define INIR \ + INI; \ + if( cpustate->_B ) \ + { \ + cpustate->_PC -= 2; \ + CC(ex,0xb2); \ + } + +/*************************************************************** + * OTIR + ***************************************************************/ +#define OTIR \ + OUTI; \ + if( cpustate->_B ) \ + { \ + cpustate->_PC -= 2; \ + CC(ex,0xb3); \ + } + +/*************************************************************** + * LDDR + ***************************************************************/ +#define LDDR \ + LDD; \ + if( cpustate->_BC ) \ + { \ + cpustate->_PC -= 2; \ + CC(ex,0xb8); \ + } + +/*************************************************************** + * CPDR + ***************************************************************/ +#define CPDR \ + CPD; \ + if( cpustate->_BC && !(cpustate->_F & ZF) ) \ + { \ + cpustate->_PC -= 2; \ + CC(ex,0xb9); \ + } + +/*************************************************************** + * INDR + ***************************************************************/ +#define INDR \ + IND; \ + if( cpustate->_B ) \ + { \ + cpustate->_PC -= 2; \ + CC(ex,0xba); \ + } + +/*************************************************************** + * OTDR + ***************************************************************/ +#define OTDR \ + OUTD; \ + if( cpustate->_B ) \ + { \ + cpustate->_PC -= 2; \ + CC(ex,0xbb); \ + } + +/*************************************************************** + * EI + ***************************************************************/ +#define EI { \ + cpustate->IFF1 = cpustate->IFF2 = 1; \ + cpustate->after_EI = 1; \ +} + +/*************************************************************** + * TST n + ***************************************************************/ +#define TST(value) \ + cpustate->_F = SZP[cpustate->_A & value] | HF + +/*************************************************************** + * MLT rr + ***************************************************************/ +#define MLT(DR) { \ + cpustate->DR.w.l = cpustate->DR.b.l * cpustate->DR.b.h; \ +} + +/*************************************************************** + * OTIM + ***************************************************************/ +#define OTIM { \ + cpustate->_B--; \ + OUT(cpustate, cpustate->_C, RM(cpustate, cpustate->_HL) ); \ + cpustate->_HL++; \ + cpustate->_C++; \ + cpustate->_F = (cpustate->_B) ? NF : NF | ZF; \ +} + +/*************************************************************** + * OTDM + ***************************************************************/ +#define OTDM { \ + cpustate->_B--; \ + OUT(cpustate, cpustate->_C, RM(cpustate, cpustate->_HL) ); \ + cpustate->_HL--; \ + cpustate->_C--; \ + cpustate->_F = (cpustate->_B) ? NF : NF | ZF; \ +} + +/*************************************************************** + * OTIMR + ***************************************************************/ +#define OTIMR \ + OTIM; \ + if( cpustate->_B ) \ + { \ + cpustate->_PC -= 2; \ + CC(ex,0xb3); \ + } + +/*************************************************************** + * OTDMR + ***************************************************************/ +#define OTDMR \ + OTDM; \ + if( cpustate->_B ) \ + { \ + cpustate->_PC -= 2; \ + CC(ex,0xb3); \ + } + +/*************************************************************** + * OTDMR + ***************************************************************/ +#define SLP { \ + cpustate->icount = 0; \ + cpustate->HALT = 2; \ +} + |