diff --git a/src/z80_flags.inc.c b/src/z80_flags.inc.c index c966be1..d64cf35 100644 --- a/src/z80_flags.inc.c +++ b/src/z80_flags.inc.c @@ -146,6 +146,17 @@ static inline void set_flags_bitshift(Z80 *z80, uint8_t res, uint8_t bit) SIGN(res), 0xFF); } +/* + Set the flags for a NEG instruction. +*/ +static inline void set_flags_neg(Z80 *z80) +{ + uint8_t val = z80->regs.a; + uint8_t res = -val; + set_flags(z80, CARRY(0, -, val), SUB, OV_SUB(0, val, res), F3(res), + HALF(0, -, val), F5(res), ZERO(res), SIGN(res), 0xFF); +} + #undef POS #undef NEG #undef CARRY diff --git a/src/z80_ops.inc.c b/src/z80_ops.inc.c index e352916..3003872 100644 --- a/src/z80_ops.inc.c +++ b/src/z80_ops.inc.c @@ -335,6 +335,7 @@ static uint8_t z80_inst_ld_sp_hl(Z80 *z80, uint8_t opcode) { (void) opcode; z80->regs.sp = z80->regs.hl; + z80->regs.pc++; return 6; } @@ -346,6 +347,7 @@ static uint8_t z80_inst_ld_sp_ixy(Z80 *z80, uint8_t opcode) { (void) opcode; *z80->regs.ixy = z80->regs.hl; + z80->regs.pc++; return 10; } @@ -1119,7 +1121,18 @@ static uint8_t z80_inst_dec_ixy(Z80 *z80, uint8_t opcode) // TODO: CPL -// TODO: NEG +/* + NEG (0xED44, 0xED4C, 0xED54, 0xED5C, 0xED64, 0xED6C, 0xED74, 0xED7C): + Negate A. +*/ +static uint8_t z80_inst_neg(Z80 *z80, uint8_t opcode) +{ + (void) opcode; + set_flags_neg(z80); + z80->regs.a = -z80->regs.a; + z80->regs.pc++; + return 8; +} // TODO: CCF diff --git a/src/z80_tables.inc.c b/src/z80_tables.inc.c index a91a452..f94cf72 100644 --- a/src/z80_tables.inc.c +++ b/src/z80_tables.inc.c @@ -329,7 +329,7 @@ static DispatchTable instruction_table_extended = { [0x41] = z80_inst_out_c_r, [0x42] = z80_inst_sbc_hl_ss, [0x43] = z80_inst_ld_inn_dd, - [0x44] = z80_inst_unimplemented, // TODO + [0x44] = z80_inst_neg, [0x45] = z80_inst_retn, [0x46] = z80_inst_im, [0x47] = z80_inst_ld_i_a, @@ -337,7 +337,7 @@ static DispatchTable instruction_table_extended = { [0x49] = z80_inst_out_c_r, [0x4A] = z80_inst_adc_hl_ss, [0x4B] = z80_inst_ld_dd_inn, - [0x4C] = z80_inst_unimplemented, // TODO + [0x4C] = z80_inst_neg, [0x4D] = z80_inst_reti, [0x4E] = z80_inst_im, [0x4F] = z80_inst_ld_r_a, @@ -345,7 +345,7 @@ static DispatchTable instruction_table_extended = { [0x51] = z80_inst_out_c_r, [0x52] = z80_inst_sbc_hl_ss, [0x53] = z80_inst_ld_inn_dd, - [0x54] = z80_inst_unimplemented, // TODO + [0x54] = z80_inst_neg, [0x55] = z80_inst_retn, [0x56] = z80_inst_im, [0x57] = z80_inst_unimplemented, // TODO @@ -353,7 +353,7 @@ static DispatchTable instruction_table_extended = { [0x59] = z80_inst_out_c_r, [0x5A] = z80_inst_adc_hl_ss, [0x5B] = z80_inst_ld_dd_inn, - [0x5C] = z80_inst_unimplemented, // TODO + [0x5C] = z80_inst_neg, [0x5D] = z80_inst_retn, [0x5E] = z80_inst_im, [0x5F] = z80_inst_unimplemented, // TODO @@ -361,7 +361,7 @@ static DispatchTable instruction_table_extended = { [0x61] = z80_inst_out_c_r, [0x62] = z80_inst_sbc_hl_ss, [0x63] = z80_inst_ld_inn_dd, - [0x64] = z80_inst_unimplemented, // TODO + [0x64] = z80_inst_neg, [0x65] = z80_inst_retn, [0x66] = z80_inst_im, [0x67] = z80_inst_unimplemented, // TODO @@ -369,7 +369,7 @@ static DispatchTable instruction_table_extended = { [0x69] = z80_inst_out_c_r, [0x6A] = z80_inst_adc_hl_ss, [0x6B] = z80_inst_ld_dd_inn, - [0x6C] = z80_inst_unimplemented, // TODO + [0x6C] = z80_inst_neg, [0x6D] = z80_inst_retn, [0x6E] = z80_inst_im, [0x6F] = z80_inst_unimplemented, // TODO @@ -377,7 +377,7 @@ static DispatchTable instruction_table_extended = { [0x71] = z80_inst_out_c_r, [0x72] = z80_inst_sbc_hl_ss, [0x73] = z80_inst_ld_inn_dd, - [0x74] = z80_inst_unimplemented, // TODO + [0x74] = z80_inst_neg, [0x75] = z80_inst_retn, [0x76] = z80_inst_im, [0x77] = z80_inst_nop2, @@ -385,7 +385,7 @@ static DispatchTable instruction_table_extended = { [0x79] = z80_inst_out_c_r, [0x7A] = z80_inst_adc_hl_ss, [0x7B] = z80_inst_ld_dd_inn, - [0x7C] = z80_inst_unimplemented, // TODO + [0x7C] = z80_inst_neg, [0x7D] = z80_inst_retn, [0x7E] = z80_inst_im, [0x7F] = z80_inst_nop2,