|
|
@@ -24,17 +24,179 @@ static uint8_t z80_inst_unimplemented(Z80 *z80, uint8_t opcode) |
|
|
|
return 2; |
|
|
|
} |
|
|
|
|
|
|
|
// LD r, r' |
|
|
|
|
|
|
|
/* |
|
|
|
NOP (0x00): |
|
|
|
No operation is performed. |
|
|
|
LD r, n (0x06, 0x0E, 0x16, 0x1E, 0x26, 0x2E, 0x3E): |
|
|
|
Load the immediate value into the 8-bit register. |
|
|
|
*/ |
|
|
|
static uint8_t z80_inst_nop(Z80 *z80, uint8_t opcode) |
|
|
|
static uint8_t z80_inst_ld_r_n(Z80 *z80, uint8_t opcode) |
|
|
|
{ |
|
|
|
(void) opcode; |
|
|
|
uint8_t *reg; |
|
|
|
|
|
|
|
switch(opcode) { |
|
|
|
case 0x3E: reg = &z80->regfile.a; break; |
|
|
|
case 0x06: reg = &z80->regfile.b; break; |
|
|
|
case 0x0E: reg = &z80->regfile.c; break; |
|
|
|
case 0x16: reg = &z80->regfile.d; break; |
|
|
|
case 0x1E: reg = &z80->regfile.e; break; |
|
|
|
case 0x26: reg = &z80->regfile.h; break; |
|
|
|
case 0x2E: reg = &z80->regfile.l; break; |
|
|
|
} |
|
|
|
|
|
|
|
*reg = mmu_read_byte(z80->mmu, ++z80->regfile.pc); |
|
|
|
z80->regfile.pc++; |
|
|
|
return 4; |
|
|
|
return 7; |
|
|
|
} |
|
|
|
|
|
|
|
// LD r, (HL) |
|
|
|
|
|
|
|
// LD r, (IX+d) |
|
|
|
|
|
|
|
// LD r, (IY+d) |
|
|
|
|
|
|
|
// LD (HL), r |
|
|
|
|
|
|
|
// LD (IX+d), r |
|
|
|
|
|
|
|
// LD (IY+d), r |
|
|
|
|
|
|
|
// LD (HL), n |
|
|
|
|
|
|
|
// LD (IX+d), n |
|
|
|
|
|
|
|
// LD (IY+d), n |
|
|
|
|
|
|
|
// LD A, (BC) |
|
|
|
|
|
|
|
// LD A, (DE) |
|
|
|
|
|
|
|
// LD A, (nn) |
|
|
|
|
|
|
|
// LD (BC), A |
|
|
|
|
|
|
|
// LD (DE), A |
|
|
|
|
|
|
|
// LD (nn), A |
|
|
|
|
|
|
|
// LD A, I |
|
|
|
|
|
|
|
// LD A, R |
|
|
|
|
|
|
|
// LD I,A |
|
|
|
|
|
|
|
// LD R, A |
|
|
|
|
|
|
|
/* |
|
|
|
LD dd, nn (0x01, 0x11, 0x21, 0x31): |
|
|
|
Load the two-byte immediate into the 16-bit register. |
|
|
|
*/ |
|
|
|
static uint8_t z80_inst_ld_dd_nn(Z80 *z80, uint8_t opcode) |
|
|
|
{ |
|
|
|
uint8_t pair; |
|
|
|
|
|
|
|
switch(opcode) { |
|
|
|
case 0x01: pair = REG_BC; break; |
|
|
|
case 0x11: pair = REG_DE; break; |
|
|
|
case 0x21: pair = REG_HL; break; |
|
|
|
case 0x31: pair = REG_SP; break; |
|
|
|
} |
|
|
|
|
|
|
|
set_pair(z80, pair, mmu_read_double(z80->mmu, ++z80->regfile.pc)); |
|
|
|
z80->regfile.pc += 2; |
|
|
|
return 6; |
|
|
|
} |
|
|
|
|
|
|
|
// LD IX, nn |
|
|
|
|
|
|
|
// LD IY, nn |
|
|
|
|
|
|
|
// LD HL, (nn) |
|
|
|
|
|
|
|
// LD dd, (nn) |
|
|
|
|
|
|
|
// LD IX, (nn) |
|
|
|
|
|
|
|
// LD IY, (nn) |
|
|
|
|
|
|
|
// LD (nn), HL |
|
|
|
|
|
|
|
// LD (nn), dd |
|
|
|
|
|
|
|
// LD (nn), IX |
|
|
|
|
|
|
|
// LD (nn), IY |
|
|
|
|
|
|
|
// LD SP, HL |
|
|
|
|
|
|
|
// LD SP, IX |
|
|
|
|
|
|
|
// LD SP, IY |
|
|
|
|
|
|
|
// PUSH qq |
|
|
|
|
|
|
|
// PUSH IX |
|
|
|
|
|
|
|
// PUSH IY |
|
|
|
|
|
|
|
// POP qq |
|
|
|
|
|
|
|
// POP IX |
|
|
|
|
|
|
|
// POP IY |
|
|
|
|
|
|
|
// EX DE, HL |
|
|
|
|
|
|
|
// EX AF, AF′ |
|
|
|
|
|
|
|
// EXX |
|
|
|
|
|
|
|
// EX (SP), HL |
|
|
|
|
|
|
|
// EX (SP), IX |
|
|
|
|
|
|
|
// EX (SP), IY |
|
|
|
|
|
|
|
// LDI |
|
|
|
|
|
|
|
// LDIR |
|
|
|
|
|
|
|
// LDD |
|
|
|
|
|
|
|
// LDDR |
|
|
|
|
|
|
|
// CPI |
|
|
|
|
|
|
|
// CPIR |
|
|
|
|
|
|
|
// CPD |
|
|
|
|
|
|
|
// CPDR |
|
|
|
|
|
|
|
// ADD A, r |
|
|
|
|
|
|
|
// ADD A, n |
|
|
|
|
|
|
|
// ADD A, (HL) |
|
|
|
|
|
|
|
// ADD A, (IX + d) |
|
|
|
|
|
|
|
// ADD A, (IY + d) |
|
|
|
|
|
|
|
// ADC A, s |
|
|
|
|
|
|
|
// SUB s |
|
|
|
|
|
|
|
// SBC A, s |
|
|
|
|
|
|
|
// AND s |
|
|
|
|
|
|
|
// OR s |
|
|
|
|
|
|
|
// XOR s |
|
|
|
|
|
|
|
// CP s |
|
|
|
|
|
|
|
/* |
|
|
|
INC r (0x04, 0x0C, 0x14, 0x1C, 0x24, 0x2C, 0x3C): |
|
|
|
Increment the 8-bit register encoded in the opcode. |
|
|
@@ -62,36 +224,205 @@ static uint8_t z80_inst_inc_r(Z80 *z80, uint8_t opcode) |
|
|
|
return 4; |
|
|
|
} |
|
|
|
|
|
|
|
// INC (HL) |
|
|
|
|
|
|
|
// INC (IX+d) |
|
|
|
|
|
|
|
// INC (IY+d) |
|
|
|
|
|
|
|
// DEC m |
|
|
|
|
|
|
|
// DAA |
|
|
|
|
|
|
|
// CPL |
|
|
|
|
|
|
|
// NEG |
|
|
|
|
|
|
|
// CCF |
|
|
|
|
|
|
|
// SCF |
|
|
|
|
|
|
|
/* |
|
|
|
NOP (0x00): |
|
|
|
No operation is performed. |
|
|
|
*/ |
|
|
|
static uint8_t z80_inst_nop(Z80 *z80, uint8_t opcode) |
|
|
|
{ |
|
|
|
(void) opcode; |
|
|
|
z80->regfile.pc++; |
|
|
|
return 4; |
|
|
|
} |
|
|
|
|
|
|
|
// HALT |
|
|
|
|
|
|
|
// DI |
|
|
|
|
|
|
|
// EI |
|
|
|
|
|
|
|
// IM 0 |
|
|
|
|
|
|
|
// IM 1 |
|
|
|
|
|
|
|
// IM 2 |
|
|
|
|
|
|
|
// ADD HL, ss |
|
|
|
|
|
|
|
// ADC HL, ss |
|
|
|
|
|
|
|
// SBC HL, ss |
|
|
|
|
|
|
|
// ADD IX, pp |
|
|
|
|
|
|
|
// ADD IY, rr |
|
|
|
|
|
|
|
/* |
|
|
|
INC ss (0x03, 0x13, 0x23, 0x33): |
|
|
|
Increment the 16-bit register encoded in the opcode. |
|
|
|
*/ |
|
|
|
static uint8_t z80_inst_inc_ss(Z80 *z80, uint8_t opcode) |
|
|
|
{ |
|
|
|
if (opcode == 0x33) { |
|
|
|
z80->regfile.sp++; |
|
|
|
} else { |
|
|
|
uint8_t pair; |
|
|
|
switch(opcode) { |
|
|
|
case 0x03: pair = REG_BC; break; |
|
|
|
case 0x13: pair = REG_DE; break; |
|
|
|
case 0x23: pair = REG_HL; break; |
|
|
|
} |
|
|
|
set_pair(z80, pair, get_pair(z80, pair) + 1); |
|
|
|
uint8_t pair; |
|
|
|
|
|
|
|
switch(opcode) { |
|
|
|
case 0x03: pair = REG_BC; break; |
|
|
|
case 0x13: pair = REG_DE; break; |
|
|
|
case 0x23: pair = REG_HL; break; |
|
|
|
case 0x33: pair = REG_SP; break; |
|
|
|
} |
|
|
|
|
|
|
|
set_pair(z80, pair, get_pair(z80, pair) + 1); |
|
|
|
z80->regfile.pc++; |
|
|
|
return 6; |
|
|
|
} |
|
|
|
|
|
|
|
// INC IX |
|
|
|
|
|
|
|
// INC IY |
|
|
|
|
|
|
|
// DEC ss |
|
|
|
|
|
|
|
// DEC IX |
|
|
|
|
|
|
|
// DEC IY |
|
|
|
|
|
|
|
// RLCA |
|
|
|
|
|
|
|
// RLA |
|
|
|
|
|
|
|
// RRCA |
|
|
|
|
|
|
|
// RRA |
|
|
|
|
|
|
|
// RLC r |
|
|
|
|
|
|
|
// RLC (HL) |
|
|
|
|
|
|
|
// RLC (IX+d) |
|
|
|
|
|
|
|
// RLC (IY+d) |
|
|
|
|
|
|
|
// RL m |
|
|
|
|
|
|
|
// RRC m |
|
|
|
|
|
|
|
// RR m |
|
|
|
|
|
|
|
// SLA m |
|
|
|
|
|
|
|
// SRA m |
|
|
|
|
|
|
|
// SRL m |
|
|
|
|
|
|
|
// RLD |
|
|
|
|
|
|
|
// RRD |
|
|
|
|
|
|
|
// BIT b, r |
|
|
|
|
|
|
|
// BIT b, (HL) |
|
|
|
|
|
|
|
// BIT b, (IX+d) |
|
|
|
|
|
|
|
// BIT b, (IY+d) |
|
|
|
|
|
|
|
// SET b, r |
|
|
|
|
|
|
|
// SET b, (HL) |
|
|
|
|
|
|
|
// SET b, (IX+d) |
|
|
|
|
|
|
|
// SET b, (IY+d) |
|
|
|
|
|
|
|
// RES b, m |
|
|
|
|
|
|
|
// JP nn |
|
|
|
|
|
|
|
// JP cc, nn |
|
|
|
|
|
|
|
// JR e |
|
|
|
|
|
|
|
// JR C, e |
|
|
|
|
|
|
|
// JR NC, e |
|
|
|
|
|
|
|
// JR Z, e |
|
|
|
|
|
|
|
// JR NZ, e |
|
|
|
|
|
|
|
// JP (HL) |
|
|
|
|
|
|
|
// JP (IX) |
|
|
|
|
|
|
|
// JP (IY) |
|
|
|
|
|
|
|
// DJNZ, e |
|
|
|
|
|
|
|
// CALL nn |
|
|
|
|
|
|
|
// CALL cc, nn |
|
|
|
|
|
|
|
// RET |
|
|
|
|
|
|
|
// RET cc |
|
|
|
|
|
|
|
// RETI |
|
|
|
|
|
|
|
// RETN |
|
|
|
|
|
|
|
// RST p |
|
|
|
|
|
|
|
// IN A, (n) |
|
|
|
|
|
|
|
// IN r (C) |
|
|
|
|
|
|
|
// INI |
|
|
|
|
|
|
|
// INIR |
|
|
|
|
|
|
|
// IND |
|
|
|
|
|
|
|
// INDR |
|
|
|
|
|
|
|
// OUT (n), A |
|
|
|
|
|
|
|
// OUT (C), r |
|
|
|
|
|
|
|
// OUTI |
|
|
|
|
|
|
|
// OTIR |
|
|
|
|
|
|
|
// OUTD |
|
|
|
|
|
|
|
// OTDR |
|
|
|
|
|
|
|
static uint8_t (*instruction_lookup_table[256])(Z80*, uint8_t) = { |
|
|
|
[0x00] = z80_inst_nop, |
|
|
|
[0x01] = z80_inst_unimplemented, // TODO |
|
|
|
[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_unimplemented, // TODO |
|
|
|
[0x06] = z80_inst_ld_r_n, |
|
|
|
[0x07] = z80_inst_unimplemented, // TODO |
|
|
|
[0x08] = z80_inst_unimplemented, // TODO |
|
|
|
[0x09] = z80_inst_unimplemented, // TODO |
|
|
@@ -99,15 +430,15 @@ static uint8_t (*instruction_lookup_table[256])(Z80*, uint8_t) = { |
|
|
|
[0x0B] = z80_inst_unimplemented, // TODO |
|
|
|
[0x0C] = z80_inst_inc_r, |
|
|
|
[0x0D] = z80_inst_unimplemented, // TODO |
|
|
|
[0x0E] = z80_inst_unimplemented, // TODO |
|
|
|
[0x0E] = z80_inst_ld_r_n, |
|
|
|
[0x0F] = z80_inst_unimplemented, // TODO |
|
|
|
[0x10] = z80_inst_unimplemented, // TODO |
|
|
|
[0x11] = 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_unimplemented, // TODO |
|
|
|
[0x16] = z80_inst_ld_r_n, |
|
|
|
[0x17] = z80_inst_unimplemented, // TODO |
|
|
|
[0x18] = z80_inst_unimplemented, // TODO |
|
|
|
[0x19] = z80_inst_unimplemented, // TODO |
|
|
@@ -115,15 +446,15 @@ static uint8_t (*instruction_lookup_table[256])(Z80*, uint8_t) = { |
|
|
|
[0x1B] = z80_inst_unimplemented, // TODO |
|
|
|
[0x1C] = z80_inst_inc_r, |
|
|
|
[0x1D] = z80_inst_unimplemented, // TODO |
|
|
|
[0x1E] = z80_inst_unimplemented, // TODO |
|
|
|
[0x1E] = z80_inst_ld_r_n, |
|
|
|
[0x1F] = z80_inst_unimplemented, // TODO |
|
|
|
[0x20] = z80_inst_unimplemented, // TODO |
|
|
|
[0x21] = 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_unimplemented, // TODO |
|
|
|
[0x26] = z80_inst_ld_r_n, |
|
|
|
[0x27] = z80_inst_unimplemented, // TODO |
|
|
|
[0x28] = z80_inst_unimplemented, // TODO |
|
|
|
[0x29] = z80_inst_unimplemented, // TODO |
|
|
@@ -131,10 +462,10 @@ static uint8_t (*instruction_lookup_table[256])(Z80*, uint8_t) = { |
|
|
|
[0x2B] = z80_inst_unimplemented, // TODO |
|
|
|
[0x2C] = z80_inst_inc_r, |
|
|
|
[0x2D] = z80_inst_unimplemented, // TODO |
|
|
|
[0x2E] = z80_inst_unimplemented, // TODO |
|
|
|
[0x2E] = z80_inst_ld_r_n, |
|
|
|
[0x2F] = z80_inst_unimplemented, // TODO |
|
|
|
[0x30] = z80_inst_unimplemented, // TODO |
|
|
|
[0x31] = 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 |
|
|
@@ -147,7 +478,7 @@ static uint8_t (*instruction_lookup_table[256])(Z80*, uint8_t) = { |
|
|
|
[0x3B] = z80_inst_unimplemented, // TODO |
|
|
|
[0x3C] = z80_inst_inc_r, |
|
|
|
[0x3D] = z80_inst_unimplemented, // TODO |
|
|
|
[0x3E] = z80_inst_unimplemented, // TODO |
|
|
|
[0x3E] = z80_inst_ld_r_n, |
|
|
|
[0x3F] = z80_inst_unimplemented, // TODO |
|
|
|
[0x40] = z80_inst_unimplemented, // TODO |
|
|
|
[0x41] = z80_inst_unimplemented, // TODO |
|
|
|