diff --git a/src/z80_flags.inc.c b/src/z80_flags.inc.c index bdc7eb5..fd6e3ae 100644 --- a/src/z80_flags.inc.c +++ b/src/z80_flags.inc.c @@ -147,6 +147,15 @@ static inline void set_flags_bitshift(Z80 *z80, uint8_t res, uint8_t bit) } /* + Set the flags for a RLD or RRD instruction. +*/ +static inline void set_flags_rd(Z80 *z80) +{ + uint8_t a = z80->regs.a; + set_flags(z80, 0, 0, PARITY(a), F3(a), 0, F5(a), ZERO(a), SIGN(a), 0xFE); +} + +/* Set the flags for a DAA instruction. */ static inline void set_flags_daa(Z80 *z80, uint8_t old, uint8_t adjust) diff --git a/src/z80_ops.inc.c b/src/z80_ops.inc.c index 8bf22ff..6754bb6 100644 --- a/src/z80_ops.inc.c +++ b/src/z80_ops.inc.c @@ -1767,9 +1767,39 @@ static uint8_t z80_inst_srl_hl(Z80 *z80, uint8_t opcode) TODO */ -// TODO: RLD +/* + RLD (0xED6F): + Low nibble of (HL) is copied to high nibble of (HL). Old high nibble of + (HL) is copied to low nibble of A. Old low nibble of A is copied to low + nibble of (HL). +*/ +static uint8_t z80_inst_rld(Z80 *z80, uint8_t opcode) +{ + (void) opcode; + uint8_t hl = mmu_read_byte(z80->mmu, z80->regs.hl); + uint8_t newhl = (hl << 4) | (z80->regs.a & 0x0F); + z80->regs.a = (z80->regs.a & 0xF0) | (hl >> 4); + mmu_write_byte(z80->mmu, z80->regs.hl, newhl); + set_flags_rd(z80); + return 18; +} -// TODO: RRD +/* + RRD (0xED67): + Low nibble of A is copied to high nibble of (HL). Old high nibble of + (HL) is copied to low nibble of (HL). Old low nibble of (HL) is copied to + low nibble of A. +*/ +static uint8_t z80_inst_rrd(Z80 *z80, uint8_t opcode) +{ + (void) opcode; + uint8_t hl = mmu_read_byte(z80->mmu, z80->regs.hl); + uint8_t newhl = (z80->regs.a << 4) | (hl >> 4); + z80->regs.a = (z80->regs.a & 0xF0) | (hl & 0x0F); + mmu_write_byte(z80->mmu, z80->regs.hl, newhl); + set_flags_rd(z80); + return 18; +} /* BIT b, r (0xCB40, 0xCB41, 0xCB42, 0xCB43, 0xCB44, 0xCB45, 0xCB47, 0xCB48, diff --git a/src/z80_tables.inc.c b/src/z80_tables.inc.c index 5c4faec..adc0520 100644 --- a/src/z80_tables.inc.c +++ b/src/z80_tables.inc.c @@ -364,7 +364,7 @@ static DispatchTable instruction_table_extended = { [0x64] = z80_inst_neg, [0x65] = z80_inst_retn, [0x66] = z80_inst_im, - [0x67] = z80_inst_unimplemented, // TODO + [0x67] = z80_inst_rrd, [0x68] = z80_inst_in_r_c, [0x69] = z80_inst_out_c_r, [0x6A] = z80_inst_adc_hl_ss, @@ -372,7 +372,7 @@ static DispatchTable instruction_table_extended = { [0x6C] = z80_inst_neg, [0x6D] = z80_inst_retn, [0x6E] = z80_inst_im, - [0x6F] = z80_inst_unimplemented, // TODO + [0x6F] = z80_inst_rld, [0x70] = z80_inst_in_r_c, [0x71] = z80_inst_out_c_r, [0x72] = z80_inst_sbc_hl_ss,