|
|
@@ -13,6 +13,14 @@ |
|
|
|
- http://www.z80.info/z80sflag.htm |
|
|
|
*/ |
|
|
|
|
|
|
|
typedef uint8_t (*DispatchTable[256])(Z80*, uint8_t); |
|
|
|
|
|
|
|
static DispatchTable instruction_table; |
|
|
|
static DispatchTable instruction_table_extended; |
|
|
|
static DispatchTable instruction_table_bits; |
|
|
|
static DispatchTable instruction_table_index; |
|
|
|
static DispatchTable instruction_table_index_bits; |
|
|
|
|
|
|
|
/* |
|
|
|
Unimplemented opcode handler. |
|
|
|
*/ |
|
|
@@ -360,11 +368,35 @@ static uint8_t z80_inst_ei(Z80 *z80, uint8_t opcode) |
|
|
|
return 4; |
|
|
|
} |
|
|
|
|
|
|
|
// IM 0 |
|
|
|
|
|
|
|
// IM 1 |
|
|
|
/* |
|
|
|
IM (0xED46, 0xED4E, 0xED56, 0xED5E, 0xED66, 0xED6E, 0xED76, 0xED7E): |
|
|
|
Set the interrupt mode. |
|
|
|
*/ |
|
|
|
static uint8_t z80_inst_im(Z80 *z80, uint8_t opcode) |
|
|
|
{ |
|
|
|
switch (opcode) { |
|
|
|
case 0x46: |
|
|
|
case 0x4E: |
|
|
|
case 0x66: |
|
|
|
case 0x6E: |
|
|
|
z80->regfile.im_a = false; // Interrupt mode 0 |
|
|
|
z80->regfile.im_b = false; |
|
|
|
break; |
|
|
|
case 0x56: |
|
|
|
case 0x76: |
|
|
|
z80->regfile.im_a = true; // Interrupt mode 1 |
|
|
|
z80->regfile.im_b = false; |
|
|
|
break; |
|
|
|
case 0x5E: |
|
|
|
case 0x7E: |
|
|
|
z80->regfile.im_a = true; // Interrupt mode 2 |
|
|
|
z80->regfile.im_b = true; |
|
|
|
break; |
|
|
|
} |
|
|
|
|
|
|
|
// IM 2 |
|
|
|
z80->regfile.pc++; |
|
|
|
return 8; |
|
|
|
} |
|
|
|
|
|
|
|
// ADD HL, ss |
|
|
|
|
|
|
@@ -448,7 +480,16 @@ static uint8_t z80_inst_inc_ss(Z80 *z80, uint8_t opcode) |
|
|
|
|
|
|
|
// RES b, m |
|
|
|
|
|
|
|
// JP nn |
|
|
|
/* |
|
|
|
JP nn (0xC3): |
|
|
|
Jump to nn (16-bit immediate). |
|
|
|
*/ |
|
|
|
static uint8_t z80_inst_jp_nn(Z80 *z80, uint8_t opcode) |
|
|
|
{ |
|
|
|
(void) opcode; |
|
|
|
z80->regfile.pc = mmu_read_double(z80->mmu, ++z80->regfile.pc); |
|
|
|
return 10; |
|
|
|
} |
|
|
|
|
|
|
|
// JP cc, nn |
|
|
|
|
|
|
@@ -508,261 +549,44 @@ static uint8_t z80_inst_inc_ss(Z80 *z80, uint8_t opcode) |
|
|
|
|
|
|
|
// OTDR |
|
|
|
|
|
|
|
static uint8_t (*instruction_lookup_table[256])(Z80*, uint8_t) = { |
|
|
|
[0x00] = z80_inst_nop, |
|
|
|
[0x01] = z80_inst_ld_dd_nn, |
|
|
|
[0x02] = z80_inst_unimplemented, // TODO |
|
|
|
[0x03] = z80_inst_inc_ss, |
|
|
|
[0x04] = z80_inst_inc_r, |
|
|
|
[0x05] = z80_inst_unimplemented, // TODO |
|
|
|
[0x06] = z80_inst_ld_r_n, |
|
|
|
[0x07] = z80_inst_unimplemented, // TODO |
|
|
|
[0x08] = z80_inst_unimplemented, // TODO |
|
|
|
[0x09] = z80_inst_unimplemented, // TODO |
|
|
|
[0x0A] = z80_inst_unimplemented, // TODO |
|
|
|
[0x0B] = z80_inst_unimplemented, // TODO |
|
|
|
[0x0C] = z80_inst_inc_r, |
|
|
|
[0x0D] = z80_inst_unimplemented, // TODO |
|
|
|
[0x0E] = z80_inst_ld_r_n, |
|
|
|
[0x0F] = z80_inst_unimplemented, // TODO |
|
|
|
[0x10] = z80_inst_unimplemented, // TODO |
|
|
|
[0x11] = z80_inst_ld_dd_nn, |
|
|
|
[0x12] = z80_inst_unimplemented, // TODO |
|
|
|
[0x13] = z80_inst_inc_ss, |
|
|
|
[0x14] = z80_inst_inc_r, |
|
|
|
[0x15] = z80_inst_unimplemented, // TODO |
|
|
|
[0x16] = z80_inst_ld_r_n, |
|
|
|
[0x17] = z80_inst_unimplemented, // TODO |
|
|
|
[0x18] = z80_inst_unimplemented, // TODO |
|
|
|
[0x19] = z80_inst_unimplemented, // TODO |
|
|
|
[0x1A] = z80_inst_unimplemented, // TODO |
|
|
|
[0x1B] = z80_inst_unimplemented, // TODO |
|
|
|
[0x1C] = z80_inst_inc_r, |
|
|
|
[0x1D] = z80_inst_unimplemented, // TODO |
|
|
|
[0x1E] = z80_inst_ld_r_n, |
|
|
|
[0x1F] = z80_inst_unimplemented, // TODO |
|
|
|
[0x20] = z80_inst_unimplemented, // TODO |
|
|
|
[0x21] = z80_inst_ld_dd_nn, |
|
|
|
[0x22] = z80_inst_unimplemented, // TODO |
|
|
|
[0x23] = z80_inst_inc_ss, |
|
|
|
[0x24] = z80_inst_inc_r, |
|
|
|
[0x25] = z80_inst_unimplemented, // TODO |
|
|
|
[0x26] = z80_inst_ld_r_n, |
|
|
|
[0x27] = z80_inst_unimplemented, // TODO |
|
|
|
[0x28] = z80_inst_unimplemented, // TODO |
|
|
|
[0x29] = z80_inst_unimplemented, // TODO |
|
|
|
[0x2A] = z80_inst_unimplemented, // TODO |
|
|
|
[0x2B] = z80_inst_unimplemented, // TODO |
|
|
|
[0x2C] = z80_inst_inc_r, |
|
|
|
[0x2D] = z80_inst_unimplemented, // TODO |
|
|
|
[0x2E] = z80_inst_ld_r_n, |
|
|
|
[0x2F] = z80_inst_unimplemented, // TODO |
|
|
|
[0x30] = z80_inst_unimplemented, // TODO |
|
|
|
[0x31] = z80_inst_ld_dd_nn, |
|
|
|
[0x32] = z80_inst_unimplemented, // TODO |
|
|
|
[0x33] = z80_inst_inc_ss, |
|
|
|
[0x34] = z80_inst_unimplemented, // TODO |
|
|
|
[0x35] = z80_inst_unimplemented, // TODO |
|
|
|
[0x36] = z80_inst_unimplemented, // TODO |
|
|
|
[0x37] = z80_inst_unimplemented, // TODO |
|
|
|
[0x38] = z80_inst_unimplemented, // TODO |
|
|
|
[0x39] = z80_inst_unimplemented, // TODO |
|
|
|
[0x3A] = z80_inst_unimplemented, // TODO |
|
|
|
[0x3B] = z80_inst_unimplemented, // TODO |
|
|
|
[0x3C] = z80_inst_inc_r, |
|
|
|
[0x3D] = z80_inst_unimplemented, // TODO |
|
|
|
[0x3E] = z80_inst_ld_r_n, |
|
|
|
[0x3F] = z80_inst_unimplemented, // TODO |
|
|
|
[0x40] = z80_inst_ld_r_r, |
|
|
|
[0x41] = z80_inst_ld_r_r, |
|
|
|
[0x42] = z80_inst_ld_r_r, |
|
|
|
[0x43] = z80_inst_ld_r_r, |
|
|
|
[0x44] = z80_inst_ld_r_r, |
|
|
|
[0x45] = z80_inst_ld_r_r, |
|
|
|
[0x46] = z80_inst_ld_r_hl, |
|
|
|
[0x47] = z80_inst_ld_r_r, |
|
|
|
[0x48] = z80_inst_ld_r_r, |
|
|
|
[0x49] = z80_inst_ld_r_r, |
|
|
|
[0x4A] = z80_inst_ld_r_r, |
|
|
|
[0x4B] = z80_inst_ld_r_r, |
|
|
|
[0x4C] = z80_inst_ld_r_r, |
|
|
|
[0x4D] = z80_inst_ld_r_r, |
|
|
|
[0x4E] = z80_inst_ld_r_hl, |
|
|
|
[0x4F] = z80_inst_ld_r_r, |
|
|
|
[0x50] = z80_inst_ld_r_r, |
|
|
|
[0x51] = z80_inst_ld_r_r, |
|
|
|
[0x52] = z80_inst_ld_r_r, |
|
|
|
[0x53] = z80_inst_ld_r_r, |
|
|
|
[0x54] = z80_inst_ld_r_r, |
|
|
|
[0x55] = z80_inst_ld_r_r, |
|
|
|
[0x56] = z80_inst_ld_r_hl, |
|
|
|
[0x57] = z80_inst_ld_r_r, |
|
|
|
[0x58] = z80_inst_ld_r_r, |
|
|
|
[0x59] = z80_inst_ld_r_r, |
|
|
|
[0x5A] = z80_inst_ld_r_r, |
|
|
|
[0x5B] = z80_inst_ld_r_r, |
|
|
|
[0x5C] = z80_inst_ld_r_r, |
|
|
|
[0x5D] = z80_inst_ld_r_r, |
|
|
|
[0x5E] = z80_inst_ld_r_hl, |
|
|
|
[0x5F] = z80_inst_ld_r_r, |
|
|
|
[0x60] = z80_inst_ld_r_r, |
|
|
|
[0x61] = z80_inst_ld_r_r, |
|
|
|
[0x62] = z80_inst_ld_r_r, |
|
|
|
[0x63] = z80_inst_ld_r_r, |
|
|
|
[0x64] = z80_inst_ld_r_r, |
|
|
|
[0x65] = z80_inst_ld_r_r, |
|
|
|
[0x66] = z80_inst_ld_r_hl, |
|
|
|
[0x67] = z80_inst_ld_r_r, |
|
|
|
[0x68] = z80_inst_ld_r_r, |
|
|
|
[0x69] = z80_inst_ld_r_r, |
|
|
|
[0x6A] = z80_inst_ld_r_r, |
|
|
|
[0x6B] = z80_inst_ld_r_r, |
|
|
|
[0x6C] = z80_inst_ld_r_r, |
|
|
|
[0x6D] = z80_inst_ld_r_r, |
|
|
|
[0x6E] = z80_inst_ld_r_hl, |
|
|
|
[0x6F] = z80_inst_ld_r_r, |
|
|
|
[0x70] = z80_inst_unimplemented, // TODO |
|
|
|
[0x71] = z80_inst_unimplemented, // TODO |
|
|
|
[0x72] = z80_inst_unimplemented, // TODO |
|
|
|
[0x73] = z80_inst_unimplemented, // TODO |
|
|
|
[0x74] = z80_inst_unimplemented, // TODO |
|
|
|
[0x75] = z80_inst_unimplemented, // TODO |
|
|
|
[0x76] = z80_inst_halt, |
|
|
|
[0x77] = z80_inst_unimplemented, // TODO |
|
|
|
[0x78] = z80_inst_ld_r_r, |
|
|
|
[0x79] = z80_inst_ld_r_r, |
|
|
|
[0x7A] = z80_inst_ld_r_r, |
|
|
|
[0x7B] = z80_inst_ld_r_r, |
|
|
|
[0x7C] = z80_inst_ld_r_r, |
|
|
|
[0x7D] = z80_inst_ld_r_r, |
|
|
|
[0x7E] = z80_inst_ld_r_hl, |
|
|
|
[0x7F] = z80_inst_ld_r_r, |
|
|
|
[0x80] = z80_inst_unimplemented, // TODO |
|
|
|
[0x81] = z80_inst_unimplemented, // TODO |
|
|
|
[0x82] = z80_inst_unimplemented, // TODO |
|
|
|
[0x83] = z80_inst_unimplemented, // TODO |
|
|
|
[0x84] = z80_inst_unimplemented, // TODO |
|
|
|
[0x85] = z80_inst_unimplemented, // TODO |
|
|
|
[0x86] = z80_inst_unimplemented, // TODO |
|
|
|
[0x87] = z80_inst_unimplemented, // TODO |
|
|
|
[0x88] = z80_inst_unimplemented, // TODO |
|
|
|
[0x89] = z80_inst_unimplemented, // TODO |
|
|
|
[0x8A] = z80_inst_unimplemented, // TODO |
|
|
|
[0x8B] = z80_inst_unimplemented, // TODO |
|
|
|
[0x8C] = z80_inst_unimplemented, // TODO |
|
|
|
[0x8D] = z80_inst_unimplemented, // TODO |
|
|
|
[0x8E] = z80_inst_unimplemented, // TODO |
|
|
|
[0x8F] = z80_inst_unimplemented, // TODO |
|
|
|
[0x90] = z80_inst_unimplemented, // TODO |
|
|
|
[0x91] = z80_inst_unimplemented, // TODO |
|
|
|
[0x92] = z80_inst_unimplemented, // TODO |
|
|
|
[0x93] = z80_inst_unimplemented, // TODO |
|
|
|
[0x94] = z80_inst_unimplemented, // TODO |
|
|
|
[0x95] = z80_inst_unimplemented, // TODO |
|
|
|
[0x96] = z80_inst_unimplemented, // TODO |
|
|
|
[0x97] = z80_inst_unimplemented, // TODO |
|
|
|
[0x98] = z80_inst_unimplemented, // TODO |
|
|
|
[0x99] = z80_inst_unimplemented, // TODO |
|
|
|
[0x9A] = z80_inst_unimplemented, // TODO |
|
|
|
[0x9B] = z80_inst_unimplemented, // TODO |
|
|
|
[0x9C] = z80_inst_unimplemented, // TODO |
|
|
|
[0x9D] = z80_inst_unimplemented, // TODO |
|
|
|
[0x9E] = z80_inst_unimplemented, // TODO |
|
|
|
[0x9F] = z80_inst_unimplemented, // TODO |
|
|
|
[0xA0] = z80_inst_unimplemented, // TODO |
|
|
|
[0xA1] = z80_inst_unimplemented, // TODO |
|
|
|
[0xA2] = z80_inst_unimplemented, // TODO |
|
|
|
[0xA3] = z80_inst_unimplemented, // TODO |
|
|
|
[0xA4] = z80_inst_unimplemented, // TODO |
|
|
|
[0xA5] = z80_inst_unimplemented, // TODO |
|
|
|
[0xA6] = z80_inst_unimplemented, // TODO |
|
|
|
[0xA7] = z80_inst_unimplemented, // TODO |
|
|
|
[0xA8] = z80_inst_unimplemented, // TODO |
|
|
|
[0xA9] = z80_inst_unimplemented, // TODO |
|
|
|
[0xAA] = z80_inst_unimplemented, // TODO |
|
|
|
[0xAB] = z80_inst_unimplemented, // TODO |
|
|
|
[0xAC] = z80_inst_unimplemented, // TODO |
|
|
|
[0xAD] = z80_inst_unimplemented, // TODO |
|
|
|
[0xAE] = z80_inst_unimplemented, // TODO |
|
|
|
[0xAF] = z80_inst_unimplemented, // TODO |
|
|
|
[0xB0] = z80_inst_unimplemented, // TODO |
|
|
|
[0xB1] = z80_inst_unimplemented, // TODO |
|
|
|
[0xB2] = z80_inst_unimplemented, // TODO |
|
|
|
[0xB3] = z80_inst_unimplemented, // TODO |
|
|
|
[0xB4] = z80_inst_unimplemented, // TODO |
|
|
|
[0xB5] = z80_inst_unimplemented, // TODO |
|
|
|
[0xB6] = z80_inst_unimplemented, // TODO |
|
|
|
[0xB7] = z80_inst_unimplemented, // TODO |
|
|
|
[0xB8] = z80_inst_unimplemented, // TODO |
|
|
|
[0xB9] = z80_inst_unimplemented, // TODO |
|
|
|
[0xBA] = z80_inst_unimplemented, // TODO |
|
|
|
[0xBB] = z80_inst_unimplemented, // TODO |
|
|
|
[0xBC] = z80_inst_unimplemented, // TODO |
|
|
|
[0xBD] = z80_inst_unimplemented, // TODO |
|
|
|
[0xBE] = z80_inst_unimplemented, // TODO |
|
|
|
[0xBF] = z80_inst_unimplemented, // TODO |
|
|
|
[0xC0] = z80_inst_unimplemented, // TODO |
|
|
|
[0xC1] = z80_inst_unimplemented, // TODO |
|
|
|
[0xC2] = z80_inst_unimplemented, // TODO |
|
|
|
[0xC3] = z80_inst_unimplemented, // TODO |
|
|
|
[0xC4] = z80_inst_unimplemented, // TODO |
|
|
|
[0xC5] = z80_inst_unimplemented, // TODO |
|
|
|
[0xC6] = z80_inst_unimplemented, // TODO |
|
|
|
[0xC7] = z80_inst_unimplemented, // TODO |
|
|
|
[0xC8] = z80_inst_unimplemented, // TODO |
|
|
|
[0xC9] = z80_inst_unimplemented, // TODO |
|
|
|
[0xCA] = z80_inst_unimplemented, // TODO |
|
|
|
[0xCB] = z80_inst_unimplemented, // TODO |
|
|
|
[0xCC] = z80_inst_unimplemented, // TODO |
|
|
|
[0xCD] = z80_inst_unimplemented, // TODO |
|
|
|
[0xCE] = z80_inst_unimplemented, // TODO |
|
|
|
[0xCF] = z80_inst_unimplemented, // TODO |
|
|
|
[0xD0] = z80_inst_unimplemented, // TODO |
|
|
|
[0xD1] = z80_inst_unimplemented, // TODO |
|
|
|
[0xD2] = z80_inst_unimplemented, // TODO |
|
|
|
[0xD3] = z80_inst_unimplemented, // TODO |
|
|
|
[0xD4] = z80_inst_unimplemented, // TODO |
|
|
|
[0xD5] = z80_inst_unimplemented, // TODO |
|
|
|
[0xD6] = z80_inst_unimplemented, // TODO |
|
|
|
[0xD7] = z80_inst_unimplemented, // TODO |
|
|
|
[0xD8] = z80_inst_unimplemented, // TODO |
|
|
|
[0xD9] = z80_inst_exx, |
|
|
|
[0xDA] = z80_inst_unimplemented, // TODO |
|
|
|
[0xDB] = z80_inst_unimplemented, // TODO |
|
|
|
[0xDC] = z80_inst_unimplemented, // TODO |
|
|
|
[0xDD] = z80_inst_unimplemented, // TODO |
|
|
|
[0xDE] = z80_inst_unimplemented, // TODO |
|
|
|
[0xDF] = z80_inst_unimplemented, // TODO |
|
|
|
[0xE0] = z80_inst_unimplemented, // TODO |
|
|
|
[0xE1] = z80_inst_unimplemented, // TODO |
|
|
|
[0xE2] = z80_inst_unimplemented, // TODO |
|
|
|
[0xE3] = z80_inst_unimplemented, // TODO |
|
|
|
[0xE4] = z80_inst_unimplemented, // TODO |
|
|
|
[0xE5] = z80_inst_unimplemented, // TODO |
|
|
|
[0xE6] = z80_inst_unimplemented, // TODO |
|
|
|
[0xE7] = z80_inst_unimplemented, // TODO |
|
|
|
[0xE8] = z80_inst_unimplemented, // TODO |
|
|
|
[0xE9] = z80_inst_unimplemented, // TODO |
|
|
|
[0xEA] = z80_inst_unimplemented, // TODO |
|
|
|
[0xEB] = z80_inst_unimplemented, // TODO |
|
|
|
[0xEC] = z80_inst_unimplemented, // TODO |
|
|
|
[0xED] = z80_inst_unimplemented, // TODO |
|
|
|
[0xEE] = z80_inst_unimplemented, // TODO |
|
|
|
[0xEF] = z80_inst_unimplemented, // TODO |
|
|
|
[0xF0] = z80_inst_unimplemented, // TODO |
|
|
|
[0xF1] = z80_inst_unimplemented, // TODO |
|
|
|
[0xF2] = z80_inst_unimplemented, // TODO |
|
|
|
[0xF3] = z80_inst_di, |
|
|
|
[0xF4] = z80_inst_unimplemented, // TODO |
|
|
|
[0xF5] = z80_inst_unimplemented, // TODO |
|
|
|
[0xF6] = z80_inst_unimplemented, // TODO |
|
|
|
[0xF7] = z80_inst_unimplemented, // TODO |
|
|
|
[0xF8] = z80_inst_unimplemented, // TODO |
|
|
|
[0xF9] = z80_inst_unimplemented, // TODO |
|
|
|
[0xFA] = z80_inst_unimplemented, // TODO |
|
|
|
[0xFB] = z80_inst_ei, |
|
|
|
[0xFC] = z80_inst_unimplemented, // TODO |
|
|
|
[0xFD] = z80_inst_unimplemented, // TODO |
|
|
|
[0xFE] = z80_inst_unimplemented, // TODO |
|
|
|
[0xFF] = z80_inst_unimplemented // TODO |
|
|
|
}; |
|
|
|
/* |
|
|
|
0xED: |
|
|
|
Handle an extended instruction. |
|
|
|
*/ |
|
|
|
static uint8_t z80_prefix_extended(Z80 *z80, uint8_t opcode) |
|
|
|
{ |
|
|
|
opcode = mmu_read_byte(z80->mmu, ++z80->regfile.pc); |
|
|
|
return (*instruction_table_extended[opcode])(z80, opcode); |
|
|
|
} |
|
|
|
|
|
|
|
/* |
|
|
|
0xED: |
|
|
|
Handle a bit instruction. |
|
|
|
*/ |
|
|
|
static uint8_t z80_prefix_bits(Z80 *z80, uint8_t opcode) |
|
|
|
{ |
|
|
|
opcode = mmu_read_byte(z80->mmu, ++z80->regfile.pc); |
|
|
|
return (*instruction_table_bits[opcode])(z80, opcode); |
|
|
|
} |
|
|
|
|
|
|
|
/* |
|
|
|
0xDD, 0xFD: |
|
|
|
Handle an index instruction. |
|
|
|
*/ |
|
|
|
static uint8_t z80_prefix_index(Z80 *z80, uint8_t opcode) |
|
|
|
{ |
|
|
|
opcode = mmu_read_byte(z80->mmu, ++z80->regfile.pc); |
|
|
|
return (*instruction_table_index[opcode])(z80, opcode); |
|
|
|
} |
|
|
|
|
|
|
|
/* |
|
|
|
0xDDCB, 0xFDCB: |
|
|
|
Handle an index-bit instruction. |
|
|
|
*/ |
|
|
|
static uint8_t z80_prefix_index_bits(Z80 *z80, uint8_t opcode) |
|
|
|
{ |
|
|
|
opcode = mmu_read_byte(z80->mmu, ++z80->regfile.pc); |
|
|
|
return (*instruction_table_index_bits[opcode])(z80, opcode); |
|
|
|
} |
|
|
|
|
|
|
|
#include "z80_tables.inc.c" |