diff --git a/src/z80_ops.inc.c b/src/z80_ops.inc.c index c495c52..b3cc9f5 100644 --- a/src/z80_ops.inc.c +++ b/src/z80_ops.inc.c @@ -307,13 +307,75 @@ static uint8_t z80_inst_exx(Z80 *z80, uint8_t opcode) // EX (SP), IY -// LDI +/* + LDI (0xEDA0): + LD (DE), (HL); INC HL; INC DE; DEC BC; +*/ +static uint8_t z80_inst_ldi(Z80 *z80, uint8_t opcode) +{ + (void) opcode; + uint16_t hl = get_pair(z80, REG_HL), + de = get_pair(z80, REG_DE), + bc = get_pair(z80, REG_BC); + uint16_t value = mmu_read_double(z80->mmu, hl); + + mmu_write_double(z80->mmu, de, value); + set_pair(z80, REG_HL, ++hl); + set_pair(z80, REG_DE, ++de); + set_pair(z80, REG_BC, --bc); + + update_flags(z80, 0, 0, bc == 0, 0, 0, 0, 0, 0, 0x16); + z80->regfile.pc++; + return 16; +} + +/* + LDIR (0xEDB0): + LDI; JR PV, -2 +*/ +static uint8_t z80_inst_ldir(Z80 *z80, uint8_t opcode) +{ + z80_inst_ldi(z80, opcode); + if (get_pair(z80, REG_BC) == 0) + return 16; + z80->regfile.pc -= 2; + return 21; +} -// LDIR +/* + LDD (0xEDA8): + LD (DE), (HL); DEC HL; DEC DE; DEC BC; +*/ +static uint8_t z80_inst_ldd(Z80 *z80, uint8_t opcode) +{ + (void) opcode; + uint16_t hl = get_pair(z80, REG_HL), + de = get_pair(z80, REG_DE), + bc = get_pair(z80, REG_BC); + uint16_t value = mmu_read_double(z80->mmu, hl); -// LDD + mmu_write_double(z80->mmu, de, value); + set_pair(z80, REG_HL, --hl); + set_pair(z80, REG_DE, --de); + set_pair(z80, REG_BC, --bc); -// LDDR + update_flags(z80, 0, 0, bc == 0, 0, 0, 0, 0, 0, 0x16); + z80->regfile.pc++; + return 16; +} + +/* + LDDR (0xEDB8): + LDD; JR PV, -2 +*/ +static uint8_t z80_inst_lddr(Z80 *z80, uint8_t opcode) +{ + z80_inst_ldd(z80, opcode); + if (get_pair(z80, REG_BC) == 0) + return 16; + z80->regfile.pc -= 2; + return 21; +} // CPI @@ -807,7 +869,7 @@ static uint8_t z80_inst_ini(Z80 *z80, uint8_t opcode) /* INIR (0xEDB2): - INI; JR NZ, -1 + INI; JR NZ, -2 */ static uint8_t z80_inst_inir(Z80 *z80, uint8_t opcode) { @@ -841,7 +903,7 @@ static uint8_t z80_inst_ind(Z80 *z80, uint8_t opcode) /* INDR (0xEDBA): - IND; JR NZ, -1 + IND; JR NZ, -2 */ static uint8_t z80_inst_indr(Z80 *z80, uint8_t opcode) { @@ -901,7 +963,7 @@ static uint8_t z80_inst_outi(Z80 *z80, uint8_t opcode) /* OTIR (0xEDB3): - OUTI; JR NZ, -1 + OUTI; JR NZ, -2 */ static uint8_t z80_inst_otir(Z80 *z80, uint8_t opcode) { @@ -935,7 +997,7 @@ static uint8_t z80_inst_outd(Z80 *z80, uint8_t opcode) /* OTDR (0xEDBB): - OUTD; JR NZ, -1 + OUTD; JR NZ, -2 */ static uint8_t z80_inst_otdr(Z80 *z80, uint8_t opcode) { diff --git a/src/z80_tables.inc.c b/src/z80_tables.inc.c index 760b6f7..fa57cf6 100644 --- a/src/z80_tables.inc.c +++ b/src/z80_tables.inc.c @@ -421,7 +421,7 @@ static DispatchTable instruction_table_extended = { [0x9D] = z80_inst_unimplemented, // TODO [0x9E] = z80_inst_unimplemented, // TODO [0x9F] = z80_inst_unimplemented, // TODO - [0xA0] = z80_inst_unimplemented, // TODO + [0xA0] = z80_inst_ldi, [0xA1] = z80_inst_unimplemented, // TODO [0xA2] = z80_inst_ini, [0xA3] = z80_inst_outi, @@ -429,7 +429,7 @@ static DispatchTable instruction_table_extended = { [0xA5] = z80_inst_nop2, [0xA6] = z80_inst_nop2, [0xA7] = z80_inst_nop2, - [0xA8] = z80_inst_unimplemented, // TODO + [0xA8] = z80_inst_ldd, [0xA9] = z80_inst_unimplemented, // TODO [0xAA] = z80_inst_ind, [0xAB] = z80_inst_outd, @@ -437,7 +437,7 @@ static DispatchTable instruction_table_extended = { [0xAD] = z80_inst_nop2, [0xAE] = z80_inst_nop2, [0xAF] = z80_inst_nop2, - [0xB0] = z80_inst_unimplemented, // TODO + [0xB0] = z80_inst_ldir, [0xB1] = z80_inst_unimplemented, // TODO [0xB2] = z80_inst_inir, [0xB3] = z80_inst_otir, @@ -445,7 +445,7 @@ static DispatchTable instruction_table_extended = { [0xB5] = z80_inst_nop2, [0xB6] = z80_inst_nop2, [0xB7] = z80_inst_nop2, - [0xB8] = z80_inst_unimplemented, // TODO + [0xB8] = z80_inst_lddr, [0xB9] = z80_inst_unimplemented, // TODO [0xBA] = z80_inst_indr, [0xBB] = z80_inst_otdr,