/* do one opcode (instruction or prefix) */ int z80ex_step(void) { Z80EX_BYTE opcode, d; z80ex_opcode_fn ofn = NULL; z80ex.doing_opcode = 1; z80ex.noint_once = 0; z80ex.reset_PV_on_int = 0; z80ex.tstate = 0; z80ex.op_tstate = 0; opcode = READ_OP_M1(); /* fetch opcode */ if (z80ex.int_vector_req) { TSTATES(2); /* interrupt eats two extra wait-states */ } R++; /* R increased by one on every first M1 cycle */ T_WAIT_UNTIL(4); /* M1 cycle eats min 4 t-states */ if (!z80ex.prefix) opcodes_base[opcode](); else { if ((z80ex.prefix | 0x20) == 0xFD && ((opcode | 0x20) == 0xFD || opcode == 0xED)) { z80ex.prefix = opcode; z80ex.noint_once = 1; /* interrupts are not accepted immediately after prefix */ } else { switch (z80ex.prefix) { case 0xDD: case 0xFD: if (opcode == 0xCB) { /* FD/DD prefixed CB opcodes */ d = READ_OP(); /* displacement */ temp_byte_s = (d & 0x80)? -(((~d) & 0x7f)+1): d; opcode = READ_OP(); #ifdef Z80EX_Z180_SUPPORT if (Z180_LIKELY(z80ex.z180)) { if (unlikely((opcode & 7) != 6 || opcode == 0x36)) ofn = trapping(z80ex.prefix, 0xCB, opcode, ITC_B3); else ofn = (z80ex.prefix == 0xDD) ? opcodes_ddcb[opcode] : opcodes_fdcb[opcode]; } else #endif ofn = (z80ex.prefix == 0xDD) ? opcodes_ddcb[opcode] : opcodes_fdcb[opcode]; } else { /* FD/DD prefixed base opcodes */ #ifdef Z80EX_Z180_SUPPORT if (unlikely(z80ex.z180 && opcodes_ddfd_bad_for_z180[opcode])) { ofn = trapping(z80ex.prefix, 0x00, opcode, ITC_B2); } else { #endif ofn = (z80ex.prefix == 0xDD) ? opcodes_dd[opcode] : opcodes_fd[opcode]; if (unlikely(ofn == NULL)) ofn = opcodes_base[opcode]; /* 'mirrored' instructions NOTE: this should NOT happen with Z180! */ #ifdef Z80EX_Z180_SUPPORT } #endif } break; case 0xED: /* ED opcodes */ #ifdef Z80EX_ED_TRAPPING_SUPPORT if (unlikely(opcode > 0xBB)) { /* check if ED-trap emu func accepted the opcode as its own "faked" */ if (z80ex_ed_cb(opcode)) { ofn = opcodes_base[0x00]; break; } } #endif #ifdef Z80EX_Z180_SUPPORT if (Z180_LIKELY(z80ex.z180)) ofn = opcodes_ed_z180[opcode]; else #endif ofn = opcodes_ed[opcode]; if (ofn == NULL) { #ifdef Z80EX_Z180_SUPPORT if (unlikely(z80ex.z180)) ofn = trapping(0x00, 0xED, opcode, ITC_B2); else #endif ofn = opcodes_base[0x00]; } break; case 0xCB: /* CB opcodes */ #ifdef Z80EX_Z180_SUPPORT if (unlikely(z80ex.z180 && (opcode & 0xF8) == 0x30)) ofn = trapping(0x00, 0xCB, opcode, ITC_B2); else #endif ofn = opcodes_cb[opcode]; break; default: /* this must'nt happen! */ assert(0); break; } ofn(); z80ex.prefix = 0; } } z80ex.doing_opcode = 0; return z80ex.tstate; }
/* do one opcode (instruction or prefix) */ LIB_EXPORT int z80ex_step(Z80EX_CONTEXT *cpu) { Z80EX_BYTE opcode, d; z80ex_opcode_fn ofn=NULL; cpu->doing_opcode=1; cpu->noint_once=0; cpu->reset_PV_on_int=0; cpu->tstate=0; cpu->op_tstate=0; opcode=READ_OP_M1(); /*fetch opcode*/ if(cpu->int_vector_req) { TSTATES(2); /*interrupt eats two extra wait-states*/ } R++; /*R increased by one on every first M1 cycle*/ T_WAIT_UNTIL(4); /*M1 cycle eats min 4 t-states*/ if(!cpu->prefix) opcodes_base[opcode](cpu); else { if((cpu->prefix | 0x20) == 0xFD && ((opcode | 0x20) == 0xFD || opcode == 0xED)) { cpu->prefix=opcode; cpu->noint_once=1; /*interrupts are not accepted immediately after prefix*/ } else { switch(cpu->prefix) { case 0xDD: case 0xFD: if(opcode == 0xCB) { d=READ_OP(); /*displacement*/ temp_byte_s=(d & 0x80)? -(((~d) & 0x7f)+1): d; opcode=READ_OP(); ofn = (cpu->prefix == 0xDD)? opcodes_ddcb[opcode]: opcodes_fdcb[opcode]; } else { ofn = (cpu->prefix == 0xDD)? opcodes_dd[opcode]: opcodes_fd[opcode]; if(ofn == NULL) ofn=opcodes_base[opcode]; /*'mirrored' instructions*/ } break; case 0xED: ofn = opcodes_ed[opcode]; if(ofn == NULL) ofn=opcodes_base[0x00]; break; case 0xCB: ofn = opcodes_cb[opcode]; break; default: /*this must'nt happen!*/ break; } ofn(cpu); cpu->prefix=0; } } cpu->doing_opcode=0; return(cpu->tstate); }