/********************************************************************************/ /* */ /* CZ80 opcode include source file */ /* C Z80 emulator version 0.91 */ /* Copyright 2004-2005 Stephane Dallongeville */ /* */ /********************************************************************************/ #if CZ80_USE_JUMPTABLE goto *JumpTable[Opcode]; #else switch (Opcode) { #endif // 8 BITS LOAD OP(0x00): // NOP OP(0x40): // LD B,B OP(0x49): // LD C,C OP(0x52): // LD D,D OP(0x5b): // LD E,E OP(0x64): // LD H,H OP(0x6d): // LD L,L OP(0x7f): // LD A,A OP_NOP: RET(4) OP(0x41): // LD B,C OP(0x42): // LD B,D OP(0x43): // LD B,E OP(0x44): // LD B,H OP(0x45): // LD B,L OP(0x47): // LD B,A OP(0x48): // LD C,B OP(0x4a): // LD C,D OP(0x4b): // LD C,E OP(0x4c): // LD C,H OP(0x4d): // LD C,L OP(0x4f): // LD C,A OP(0x50): // LD D,B OP(0x51): // LD D,C OP(0x53): // LD D,E OP(0x54): // LD D,H OP(0x55): // LD D,L OP(0x57): // LD D,A OP(0x58): // LD E,B OP(0x59): // LD E,C OP(0x5a): // LD E,D OP(0x5c): // LD E,H OP(0x5d): // LD E,L OP(0x5f): // LD E,A OP(0x60): // LD H,B OP(0x61): // LD H,C OP(0x62): // LD H,D OP(0x63): // LD H,E OP(0x65): // LD H,L OP(0x67): // LD H,A OP(0x68): // LD L,B OP(0x69): // LD L,C OP(0x6a): // LD L,D OP(0x6b): // LD L,E OP(0x6c): // LD L,H OP(0x6f): // LD L,A OP(0x78): // LD A,B OP(0x79): // LD A,C OP(0x7a): // LD A,D OP(0x7b): // LD A,E OP(0x7c): // LD A,H OP(0x7d): // LD A,L OP_LD_R_R: zR8((Opcode >> 3) & 7) = zR8(Opcode & 7); RET(4) OP(0x06): // LD B,#imm OP(0x0e): // LD C,#imm OP(0x16): // LD D,#imm OP(0x1e): // LD E,#imm OP(0x26): // LD H,#imm OP(0x2e): // LD L,#imm OP(0x3e): // LD A,#imm OP_LD_R_imm: zR8(Opcode >> 3) = FETCH_BYTE; RET(7) OP(0x46): // LD B,(HL) OP(0x4e): // LD C,(HL) OP(0x56): // LD D,(HL) OP(0x5e): // LD E,(HL) OP(0x66): // LD H,(HL) OP(0x6e): // LD L,(HL) OP(0x7e): // LD A,(HL) /* OP_LD_R_mHL: */ PRE_IO READ_BYTE(zHL, zR8((Opcode >> 3) & 7)) POST_IO RET(7) OP(0x70): // LD (HL),B OP(0x71): // LD (HL),C OP(0x72): // LD (HL),D OP(0x73): // LD (HL),E OP(0x74): // LD (HL),H OP(0x75): // LD (HL),L OP(0x77): // LD (HL),A /* OP_LD_mHL_R: */ PRE_IO WRITE_BYTE(zHL, zR8(Opcode & 7)) POST_IO RET(7) OP(0x36): // LD (HL), #imm /* OP_LD_mHL_imm: */ PRE_IO WRITE_BYTE(zHL, FETCH_BYTE) POST_IO RET(10) { uint16_t adr; OP(0x0a): // LD A,(BC) OP_LOAD_A_mBC: adr = zBC; goto OP_LOAD_A_mxx; OP(0x1a): // LD A,(DE) OP_LOAD_A_mDE: adr = zDE; OP_LOAD_A_mxx: PRE_IO READ_BYTE(adr, zA) POST_IO RET(7) OP(0x3a): // LD A,(nn) OP_LOAD_A_mNN: PRE_IO FETCH_WORD(adr) READ_BYTE(adr, zA) POST_IO RET(13) OP(0x02): // LD (BC),A OP_LOAD_mBC_A: adr = zBC; goto OP_LOAD_mxx_A; OP(0x12): // LD (DE),A OP_LOAD_mDE_A: adr = zDE; OP_LOAD_mxx_A: PRE_IO WRITE_BYTE(adr, zA) POST_IO RET(7) OP(0x32): // LD (nn),A OP_LOAD_mNN_A: PRE_IO FETCH_WORD(adr) WRITE_BYTE(adr, zA) POST_IO RET(13) } // 16 BITS LOAD OP(0x01): // LD BC,nn OP(0x11): // LD DE,nn OP(0x21): // LD HL,nn OP_LOAD_RR_imm16: FETCH_WORD(zR16(Opcode >> 4)) RET(10) OP(0x31): // LD SP,nn OP_LOAD_SP_imm16: FETCH_WORD(zSP) RET(10) OP(0xf9): // LD SP,HL OP_LD_SP_xx: zSP = data->W; RET(6) { uint16_t adr; OP(0x2a): // LD HL,(nn) OP_LD_xx_mNN: PRE_IO FETCH_WORD(adr) READ_WORD_LE(adr, data->W) POST_IO RET(16) OP(0x22): // LD (nn),HL OP_LD_mNN_xx: PRE_IO FETCH_WORD(adr) WRITE_WORD_LE(adr, data->W) POST_IO RET(16) } // PUSH / POP OP(0xf1): // POP AF OP_POP_AF: { uint16_t res; PRE_IO POP_16(res) zA = res >> 8; zF = res & 0xFF; POST_IO RET(10) } OP(0xc1): // POP BC OP(0xd1): // POP DE OP_POP_RR: data = pzR16((Opcode >> 4) & 3); OP(0xe1): // POP HL OP_POP: PRE_IO POP_16(data->W) POST_IO RET(10) OP(0xf5): // PUSH AF OP_PUSH_AF: PRE_IO PUSH_16((zA << 8) | zF); POST_IO RET(11) OP(0xc5): // PUSH BC OP(0xd5): // PUSH DE OP_PUSH_RR: data = pzR16((Opcode >> 4) & 3); OP(0xe5): // PUSH HL OP_PUSH: PRE_IO PUSH_16(data->W); POST_IO RET(11) // EXCHANGE & BLOCK TRANSFERT / SEARCH { uint16_t tmp; OP(0x08): // EX AF,AF' OP_EX_AF_AF2: tmp = zFA; zFA = zFA2; zFA2 = tmp; RET(4) OP(0xeb): // EX DE,HL OP_EX_DE_HL: tmp = zDE; zDE = zHL; zHL = tmp; RET(4) OP(0xd9): // EXX OP_EXX: tmp = zBC; zBC = zBC2; zBC2 = tmp; tmp = zDE; zDE = zDE2; zDE2 = tmp; tmp = zHL; zHL = zHL2; zHL2 = tmp; RET(4) } OP(0xe3): // EX HL,(SP) { uint16_t adr; uint16_t tmp; OP_EX_xx_mSP: PRE_IO adr = zSP; tmp = data->W; READ_WORD_LE(adr, data->W) WRITE_WORD_LE(adr, tmp) POST_IO RET(19) } // 8 BITS ARITHMETIC OP(0x04): // INC B OP(0x0c): // INC C OP(0x14): // INC D OP(0x1c): // INC E OP(0x24): // INC H OP(0x2c): // INC L OP(0x3c): // INC A OP_INC_R: zR8(Opcode >> 3)++; zF = (zF & CZ80_CF) | SZXYHV_inc[zR8(Opcode >> 3)]; RET(4) { uint16_t adr; uint16_t res; OP_INC_mIx: adr = data->W + FETCH_BYTE_S; CCnt -= 11; goto OP_INC_m; OP(0x34): // INC (HL) adr = zHL; OP_INC_m: PRE_IO READ_BYTE(adr, res) res = (res + 1) & 0xFF; WRITE_BYTE(adr, res) zF = (zF & CZ80_CF) | SZXYHV_inc[res]; POST_IO RET(11) } OP(0x05): // DEC B OP(0x0d): // DEC C OP(0x15): // DEC D OP(0x1d): // DEC E OP(0x25): // DEC H OP(0x2d): // DEC L OP(0x3d): // DEC A OP_DEC_R: zR8(Opcode >> 3)--; zF = (zF & CZ80_CF) | SZXYHV_dec[zR8(Opcode >> 3)]; RET(4) { uint16_t adr; uint16_t res; OP_DEC_mIx: adr = data->W + FETCH_BYTE_S; CCnt -= 11; goto OP_DEC_m; OP(0x35): // DEC (HL) adr = zHL; OP_DEC_m: PRE_IO READ_BYTE(adr, res) res = (res - 1) & 0xFF; WRITE_BYTE(adr, res) zF = (zF & CZ80_CF) | SZXYHV_dec[res]; POST_IO RET(11) } { uint8_t val; uint16_t res; // ADD OP_ADD_mIx: PRE_IO READ_BYTE(data->W + FETCH_BYTE_S, val) POST_IO CCnt -= 11; goto OP_ADD; OP(0xc6): // ADD A,n OP_ADD_imm: val = FETCH_BYTE; CCnt -= 3; goto OP_ADD; OP(0x86): // ADD A,(HL) /* OP_ADD_mHL: */ PRE_IO READ_BYTE(zHL, val) POST_IO CCnt -= 3; goto OP_ADD; OP_ADD_IxH: val = data->B.H; goto OP_ADD; OP_ADD_IxL: val = data->B.L; goto OP_ADD; OP(0x80): // ADD A,B OP(0x81): // ADD A,C OP(0x82): // ADD A,D OP(0x83): // ADD A,E OP(0x84): // ADD A,H OP(0x85): // ADD A,L OP(0x87): // ADD A,A OP_ADD_R: val = zR8(Opcode & 7); OP_ADD: // bench : maybe use src instead of zA in zF calculation res = zA + val; zF = SZXY[res & 0xFF] | // S/Z/X/Y flag ((zA ^ res ^ val) & CZ80_HF) | // H flag (((val ^ zA ^ 0x80) & (val ^ res) & 0x80) >> 5) | // V flag ((res >> 8) & CZ80_CF); // C flag zA = res; RET(4) // ADC OP_ADC_mIx: PRE_IO READ_BYTE(data->W + FETCH_BYTE_S, val) POST_IO CCnt -= 11; goto OP_ADC; OP(0xce): // ADC A,n OP_ADC_imm: val = FETCH_BYTE; CCnt -= 3; goto OP_ADC; OP(0x8e): // ADC A,(HL) /* OP_ADC_mHL: */ PRE_IO READ_BYTE(zHL, val) POST_IO CCnt -= 3; goto OP_ADC; OP_ADC_IxH: val = data->B.H; goto OP_ADC; OP_ADC_IxL: val = data->B.L; goto OP_ADC; OP(0x88): // ADC A,B OP(0x89): // ADC A,C OP(0x8a): // ADC A,D OP(0x8b): // ADC A,E OP(0x8c): // ADC A,H OP(0x8d): // ADC A,L OP(0x8f): // ADC A,A OP_ADC_R: val = zR8(Opcode & 7); OP_ADC: // bench : maybe use src instead of zA in zF calculation res = (zA + val) + (zF & CZ80_CF); zF = SZXY[res & 0xFF] | // S/Z/X/Y flag ((zA ^ res ^ val) & CZ80_HF) | // H flag (((val ^ zA ^ 0x80) & (val ^ res) & 0x80) >> 5) | // V flag ((res >> 8) & CZ80_CF); // C flag zA = res; RET(4) // SUB OP_SUB_mIx: PRE_IO READ_BYTE(data->W + FETCH_BYTE_S, val) POST_IO CCnt -= 11; goto OP_SUB; OP(0xd6): // SUB A,n OP_SUB_imm: val = FETCH_BYTE; CCnt -= 3; goto OP_SUB; OP(0x96): // SUB (HL) /* OP_SUB_mHL: */ PRE_IO READ_BYTE(zHL, val) POST_IO CCnt -= 3; goto OP_SUB; OP_SUB_IxH: val = data->B.H; goto OP_SUB; OP_SUB_IxL: val = data->B.L; goto OP_SUB; OP(0x90): // SUB B OP(0x91): // SUB C OP(0x92): // SUB D OP(0x93): // SUB E OP(0x94): // SUB H OP(0x95): // SUB L OP(0x97): // SUB A OP_SUB_R: val = zR8(Opcode & 7); OP_SUB: // bench : maybe use src instead of zA in zF calculation res = zA - val; zF = SZXY[res & 0xFF] | // S/Z/X/Y flag ((zA ^ res ^ val) & CZ80_HF) | // H flag (((val ^ zA) & (zA ^ res) & 0x80) >> 5) | // V flag ((res >> 8) & CZ80_CF) | CZ80_NF; // C/N flag zA = res; RET(4) // SBC OP_SBC_mIx: PRE_IO READ_BYTE(data->W + FETCH_BYTE_S, val) POST_IO CCnt -= 11; goto OP_SBC; OP(0xde): // SBC A,n OP_SBC_imm: val = FETCH_BYTE; CCnt -= 3; goto OP_SBC; OP(0x9e): // SBC A,(HL) /* OP_SBC_mHL: */ PRE_IO READ_BYTE(zHL, val) POST_IO CCnt -= 3; goto OP_SBC; OP_SBC_IxH: val = data->B.H; goto OP_SBC; OP_SBC_IxL: val = data->B.L; goto OP_SBC; OP(0x98): // SBC A,B OP(0x99): // SBC A,C OP(0x9a): // SBC A,D OP(0x9b): // SBC A,E OP(0x9c): // SBC A,H OP(0x9d): // SBC A,L OP(0x9f): // SBC A,A OP_SBC_R: val = zR8(Opcode & 7); OP_SBC: // bench : maybe use src instead of zA in zF calculation res = zA - (val + (zF & CZ80_CF)); zF = SZXY[res & 0xFF] | // S/Z/X/Y flag ((zA ^ res ^ val) & CZ80_HF) | // H flag (((val ^ zA) & (zA ^ res) & 0x80) >> 5) | // V flag ((res >> 8) & CZ80_CF) | CZ80_NF; // C/N flag zA = res; RET(4) // CP OP_CP_mIx: PRE_IO READ_BYTE(data->W + FETCH_BYTE_S, val) POST_IO CCnt -= 11; goto OP_CP; OP(0xfe): // CP n OP_CP_imm: val = FETCH_BYTE; CCnt -= 3; goto OP_CP; OP(0xbe): // CP (HL) /* OP_CP_mHL: */ PRE_IO READ_BYTE(zHL, val) POST_IO CCnt -= 3; goto OP_CP; OP_CP_IxH: val = data->B.H; goto OP_CP; OP_CP_IxL: val = data->B.L; goto OP_CP; OP(0xb8): // CP B OP(0xb9): // CP C OP(0xba): // CP D OP(0xbb): // CP E OP(0xbc): // CP H OP(0xbd): // CP L OP(0xbf): // CP A OP_CP_R: val = zR8(Opcode & 7); OP_CP: // bench : maybe use src instead of zA in zF calculation res = zA - val; #if CZ80_DEBUG zF = SZXY[res & 0xFF] | // S/Z/X/Y flag ((zA ^ res ^ val) & CZ80_HF) | // H flag (((val ^ zA) & (zA ^ res) & 0x80) >> 5) | // V flag ((res >> 8) & CZ80_CF) | CZ80_NF; // C/N flag #else zF = (SZXY[res & 0xFF] & ~(CZ80_XF | CZ80_YF)) | // S/Z flag (val & (CZ80_XF | CZ80_YF)) | // X/Y flag ((zA ^ res ^ val) & CZ80_HF) | // H flag (((val ^ zA) & (zA ^ res) & 0x80) >> 5) | // V flag ((res >> 8) & CZ80_CF) | CZ80_NF; // C/N flag #endif RET(4) } // AND { uint8_t val; OP(0xa6): // AND (HL) /* OP_AND_mHL: */ PRE_IO READ_BYTE(zHL, val) POST_IO goto OP_AND_; OP(0xe6): // AND A,n OP_AND_imm: val = FETCH_BYTE; OP_AND_: zA = zA & val; zF = SZXYP[zA] | CZ80_HF; RET(7) OP_AND_IxL: val = data->B.L; goto OP_AND; OP_AND_IxH: val = data->B.H; goto OP_AND; OP(0xa0): // AND B OP(0xa1): // AND C OP(0xa2): // AND D OP(0xa3): // AND E OP(0xa4): // AND H OP(0xa5): // AND L OP_AND_R: val = zR8(Opcode & 7); OP_AND: zA = zA & val; OP(0xa7): // AND A OP_AND_A: zF = SZXYP[zA] | CZ80_HF; RET(4) // XOR OP(0xae): // XOR (HL) /* OP_XOR_mHL: */ PRE_IO READ_BYTE(zHL, val) POST_IO goto OP_XOR_; OP(0xee): // XOR A,n OP_XOR_imm: val = FETCH_BYTE; OP_XOR_: zA = zA ^ val; zF = SZXYP[zA]; RET(7) OP_XOR_IxL: val = data->B.L; goto OP_XOR; OP_XOR_IxH: val = data->B.H; goto OP_XOR; OP(0xa8): // XOR B OP(0xa9): // XOR C OP(0xaa): // XOR D OP(0xab): // XOR E OP(0xac): // XOR H OP(0xad): // XOR L OP_XOR_R: val = zR8(Opcode & 7); OP_XOR: zA = zA ^ val; zF = SZXYP[zA]; RET(4) OP(0xaf): // XOR A OP_XOR_A: zA = 0; zF = SZXYP[zA]; RET(4) // OR OP(0xb6): // OR (HL) /* OP_OR_mHL: */ PRE_IO READ_BYTE(zHL, val) POST_IO goto OP_OR_; OP(0xf6): // OR A,n OP_OR_imm: val = FETCH_BYTE; OP_OR_: zA = zA | val; zF = SZXYP[zA]; RET(7) OP_OR_IxL: val = data->B.L; goto OP_OR; OP_OR_IxH: val = data->B.H; goto OP_OR; OP(0xb0): // OR B OP(0xb1): // OR C OP(0xb2): // OR D OP(0xb3): // OR E OP(0xb4): // OR H OP(0xb5): // OR L OP_OR_R: val = zR8(Opcode & 7); OP_OR: zA = zA | val; OP(0xb7): // OR A OP_OR_A: zF = SZXYP[zA]; RET(4) } // MISC ARITHMETIC & CPU CONTROL OP(0x27): // DAA OP_DAA: { uint8_t _F; uint8_t cf, nf, hf, lo, hi, diff; _F = zF; cf = _F & CZ80_CF; nf = _F & CZ80_NF; hf = _F & CZ80_HF; lo = zA & 0x0F; hi = zA >> 4; if (cf) { diff = (lo <= 9 && !hf) ? 0x60 : 0x66; } else { if (lo >= 10) { diff = hi <= 8 ? 0x06 : 0x66; } else { if (hi >= 10) { diff = hf ? 0x66 : 0x60; } else { diff = hf ? 0x06 : 0x00; } } } if (nf) zA -= diff; else zA += diff; _F = SZXYP[zA] | (_F & CZ80_NF); if (cf || (lo <= 9 ? hi >= 10 : hi >= 9)) _F |= CZ80_CF; if (nf ? hf && lo <= 5 : lo >= 10) _F |= CZ80_HF; zF = _F; RET(4) } OP(0x2f): // CPL OP_CPL: zA ^= 0xFF; zF = (zF & (CZ80_SF | CZ80_ZF | CZ80_PF | CZ80_CF)) | CZ80_HF | CZ80_NF | (zA & (CZ80_XF | CZ80_YF)); RET(4) OP(0x37): // SCF OP_SCF: zF = (zF & (CZ80_SF | CZ80_ZF | CZ80_PF)) | (zA & (CZ80_XF | CZ80_YF)) | CZ80_CF; RET(4) OP(0x3f): // CCF OP_CCF: zF = ((zF & (CZ80_SF | CZ80_ZF | CZ80_PF | CZ80_CF)) | ((zF & CZ80_CF) << 4) | (zA & (CZ80_XF | CZ80_YF))) ^ CZ80_CF; RET(4) OP(0x76): // HALT OP_HALT: // HALTED state CPU->Status |= CZ80_HALTED; // release remaining cycles... CCnt = 0; goto Cz80_Exec_Really_End; OP(0xf3): // DI OP_DI: zIFF = 0; #if CZ80_DEBUG RET(4) #else CCnt -= 4; // can't take interrupt after DI so we force next instruction execution goto Cz80_Exec; #endif OP(0xfb): // EI OP_EI: zIFF = CZ80_IFF | (CZ80_IFF << 8); #if CZ80_DEBUG RET(4) #else // release remaining cycles... CPU->CycleSup += CCnt - 4; CCnt = 0; // can't take interrupt after EI so we force next instruction execution goto Cz80_Exec; #endif // 16 BITS ARITHMETIC OP(0x03): // INC BC OP_INC_BC: zBC++; RET(6) OP(0x13): // INC DE OP_INC_DE: zDE++; RET(6) OP(0x23): // INC HL OP_INC_xx: data->W++; RET(6) OP(0x33): // INC SP OP_INC_SP: zSP++; RET(6) OP(0x0b): // DEC BC OP_DEC_BC: zBC--; RET(6) OP(0x1b): // DEC DE OP_DEC_DE: zDE--; RET(6) OP(0x2b): // DEC HL OP_DEC_xx: data->W--; RET(6) OP(0x3b): // DEC SP OP_DEC_SP: zSP--; RET(6) // ADD16 { uint16_t src; uint32_t res; OP(0x39): // ADD xx,SP OP_ADD16_xx_SP: src = zSP; goto OP_ADD16; OP(0x29): // ADD xx,xx OP_ADD16_xx_xx: src = data->W; goto OP_ADD16; OP(0x09): // ADD xx,BC OP_ADD16_xx_BC: src = zBC; goto OP_ADD16; OP(0x19): // ADD xx,DE OP_ADD16_xx_DE: src = zDE; OP_ADD16: res = src + data->W; #if CZ80_DEBUG zF = (zF & (CZ80_SF | CZ80_ZF | CZ80_VF)) | // S/Z/V flag (((src ^ data->W ^ res) >> 8) & CZ80_HF) | // H flag ((res >> 16) & CZ80_CF); // C flag #else zF = (zF & (CZ80_SF | CZ80_ZF | CZ80_VF)) | // S/Z/V flag (((src ^ data->W ^ res) >> 8) & CZ80_HF) | // H flag ((res >> 8) & (CZ80_XF | CZ80_YF)) | // X/Y flag ((res >> 16) & CZ80_CF); // C flag #endif data->W = res; RET(11) } // ROTATE { uint8_t A; uint8_t F; OP(0x07): // RLCA OP_RLCA: A = zA; zA = (A << 1) | (A >> 7); zF = (zF & (CZ80_SF | CZ80_ZF | CZ80_PF)) | // S/Z/P flag (zA & (CZ80_XF | CZ80_YF | CZ80_CF)); // X/Y/C RET(4) OP(0x0f): // RRCA OP_RRCA: A = zA; zA = (A >> 1) | (A << 7); zF = (zF & (CZ80_SF | CZ80_ZF | CZ80_PF)) | // S/Z/P flag (zA & (CZ80_XF | CZ80_YF)) | // X/Y flag (A & CZ80_CF); // C flag RET(4) OP(0x17): // RLA OP_RLA: A = zA; F = zF; zA = (A << 1) | (F & CZ80_CF); zF = (F & (CZ80_SF | CZ80_ZF | CZ80_PF)) | // S/Z/P flag (zA & (CZ80_XF | CZ80_YF)) | // X/Y flag (A >> 7); // C flag RET(4) OP(0x1f): // RRA OP_RRA: A = zA; F = zF; zA = (A >> 1) | (F << 7); zF = (F & (CZ80_SF | CZ80_ZF | CZ80_PF)) | // S/Z/P flag (zA & (CZ80_XF | CZ80_YF)) | // X/Y flag (A & CZ80_CF); // C flag RET(4) } // JUMP OP(0xd2): // JP NC,nn OP_JP_NC: if (!(zF & CZ80_CF)) goto OP_JP; PC += 2; RET(10); OP(0xda): // JP C,nn OP_JP_C: if (zF & CZ80_CF) goto OP_JP; PC += 2; RET(10); OP(0xe2): // JP PO,nn OP_JP_PO: if (!(zF & CZ80_VF)) goto OP_JP; PC += 2; RET(10); OP(0xea): // JP PE,nn OP_JP_PE: if (zF & CZ80_VF) goto OP_JP; PC += 2; RET(10); OP(0xf2): // JP P,nn OP_JP_P: if (!(zF & CZ80_SF)) goto OP_JP; PC += 2; RET(10); OP(0xfa): // JP M,nn OP_JP_M: if (zF & CZ80_SF) goto OP_JP; PC += 2; RET(10); OP(0xca): // JP Z,nn OP_JP_Z: if (zF & CZ80_ZF) goto OP_JP; PC += 2; RET(10); OP(0xc2): // JP NZ,nn OP_JP_NZ: if (!(zF & CZ80_ZF)) goto OP_JP; PC += 2; RET(10); { uint16_t newPC; OP(0xc3): // JP nn OP_JP: newPC = GET_WORD; SET_PC(newPC); RET(10) OP(0xe9): // JP (xx) OP_JP_xx: newPC = data->W; SET_PC(newPC); RET(4) } OP(0x38): // JR C,n OP_JR_C: if (zF & CZ80_CF) goto OP_JR; PC++; RET(7) OP(0x30): // JR NC,n OP_JR_NC: if (!(zF & CZ80_CF)) goto OP_JR; PC++; RET(7) OP(0x28): // JR Z,n OP_JR_Z: if (zF & CZ80_ZF) goto OP_JR; PC++; RET(7) OP(0x20): // JR NZ,n OP_JR_NZ: if (!(zF & CZ80_ZF)) goto OP_JR; PC++; RET(7) OP(0x10): // DJNZ n OP_DJNZ: CCnt--; if (--zB) goto OP_JR; PC++; RET(9) OP(0x18): // JR n OP_JR: { uintptr_t adr; adr = FETCH_BYTE_S; // no rebase needed here... PC += adr; RET(12) } // CALL & RETURN OP(0xd4): // CALL NC,nn OP_CALL_NC: if (!(zF & CZ80_CF)) goto OP_CALL; PC += 2; RET(10) OP(0xdc): // CALL C,nn OP_CALL_C: if (zF & CZ80_CF) goto OP_CALL; PC += 2; RET(10) OP(0xe4): // CALL PO,nn OP_CALL_PO: if (!(zF & CZ80_VF)) goto OP_CALL; PC += 2; RET(10) OP(0xec): // CALL PE,nn OP_CALL_PE: if (zF & CZ80_VF) goto OP_CALL; PC += 2; RET(10) OP(0xf4): // CALL P,nn OP_CALL_P: if (!(zF & CZ80_SF)) goto OP_CALL; PC += 2; RET(10) OP(0xfc): // CALL M,nn OP_CALL_M: if (zF & CZ80_SF) goto OP_CALL; PC += 2; RET(10) OP(0xcc): // CALL Z,nn OP_CALL_Z: if (zF & CZ80_ZF) goto OP_CALL; PC += 2; RET(10) OP(0xc4): // CALL NZ,nn OP_CALL_NZ: if (!(zF & CZ80_ZF)) goto OP_CALL; PC += 2; RET(10) OP(0xcd): // CALL nn OP_CALL: { uint16_t oldRPC; uint16_t newPC; PRE_IO FETCH_WORD(newPC); oldRPC = PC; PUSH_16(oldRPC); SET_PC(newPC); POST_IO RET(17) } OP(0xd0): // RET NC OP_RET_NC: if (!(zF & CZ80_CF)) goto OP_RET_COND; RET(5) OP(0xd8): // RET C OP_RET_C: if (zF & CZ80_CF) goto OP_RET_COND; RET(5) OP(0xe0): // RET PO OP_RET_PO: if (!(zF & CZ80_VF)) goto OP_RET_COND; RET(5) OP(0xe8): // RET PE OP_RET_PE: if (zF & CZ80_VF) goto OP_RET_COND; RET(5) OP(0xf0): // RET P OP_RET_P: if (!(zF & CZ80_SF)) goto OP_RET_COND; RET(5) OP(0xf8): // RET M OP_RET_M: if (zF & CZ80_SF) goto OP_RET_COND; RET(5) OP(0xc0): // RET NZ OP_RET_NZ: if (!(zF & CZ80_ZF)) goto OP_RET_COND; RET(5) OP(0xc8): // RET Z OP_RET_Z: if (zF & CZ80_ZF) goto OP_RET_COND; RET(5) OP_RET_COND: CCnt -= 7; OP(0xc9): // RET OP_RET: { uint16_t newPC; PRE_IO POP_16(newPC); SET_PC(newPC); POST_IO RET(10) } OP(0xc7): // RST 0 OP(0xcf): // RST 1 OP(0xd7): // RST 2 OP(0xdf): // RST 3 OP(0xe7): // RST 4 OP(0xef): // RST 5 OP(0xf7): // RST 6 OP(0xff): // RST 7 OP_RST: { uint16_t src; uint16_t newPC; src = PC; PUSH_16(src); newPC = Opcode & 0x38; SET_PC(newPC); RET(11) } // INPUT & OUTPUT { uint16_t adr; OP(0xd3): // OUT (n),A OP_OUT_mN_A: adr = (zA << 8) | FETCH_BYTE; OUT(adr, zA) RET(11) OP(0xdb): // IN A,(n) OP_IN_A_mN: adr = (zA << 8) | FETCH_BYTE; IN(adr, zA) RET(11) } // PREFIXE OP(0xcb): // CB PREFIXE (BIT & SHIFT INSTRUCTIONS) /* CB_PREFIXE: */ Opcode = FETCH_BYTE; #include "cz80_opcb.inc" OP(0xed): // ED PREFIXE ED_PREFIXE: CCnt -= 4; Opcode = FETCH_BYTE; #include "cz80_oped.inc" OP(0xdd): // DD PREFIXE (IX) DD_PREFIXE: data = pzIX; goto XY_PREFIXE; OP(0xfd): // FD PREFIXE (IY) FD_PREFIXE: data = pzIY; XY_PREFIXE: CCnt -= 4; Opcode = FETCH_BYTE; #include "cz80_opxy.inc" #if CZ80_USE_JUMPTABLE #else } #endif