diff --git a/sapemu/src/smp/ops.rs b/sapemu/src/smp/ops.rs index b0590fc..b08b57e 100644 --- a/sapemu/src/smp/ops.rs +++ b/sapemu/src/smp/ops.rs @@ -2021,19 +2021,17 @@ fn sbc_a_dp(cpu: &mut Smp, memory: &mut Memory, cycle: usize, state: Instruction 2 => { let value = cpu.read(state.address, memory); - let expanded_result = (cpu.a as u16).wrapping_add((!value) as u16) + (!cpu.carry()) as u16; + let expanded_result = (cpu.a as u16).wrapping_add((!value) as u16) + cpu.carry() as u16; + trace!("{} + {} + {} = {}", cpu.a, !value, cpu.carry(), expanded_result); let result = (expanded_result & 0xff) as u8; - cpu.psw.set(ProgramStatusWord::Sign, (result as i16) < 0); + cpu.psw.set(ProgramStatusWord::Sign, (result as i8) < 0); cpu.psw.set(ProgramStatusWord::Zero, result == 0); - cpu.psw.set(ProgramStatusWord::Carry, expanded_result >= 0x1_0000); - cpu.psw.set( - ProgramStatusWord::Overflow, - (cpu.a as i16).overflowing_sub((value as i16).wrapping_add((!cpu.carry()) as i16)).1, - ); - - let half_carry_result = (cpu.a & 0x0f) + ((!value) & 0x0f) + ((!cpu.carry()) as u8) >= 0x10; + cpu.psw.set(ProgramStatusWord::Overflow, (cpu.a as i8).borrowing_sub(value as i8, !cpu.carry()).1); + let half_carry_result = (cpu.a & 0x0f) + ((!value) & 0x0f) + cpu.carry() as u8 >= 0x10; cpu.psw.set(ProgramStatusWord::HalfCarry, half_carry_result); + cpu.psw.set(ProgramStatusWord::Carry, expanded_result >= 0x100); + cpu.a = result; MicroArchAction::Next }, diff --git a/sapemu/src/test.rs b/sapemu/src/test.rs index e87b844..e8a1ae6 100644 --- a/sapemu/src/test.rs +++ b/sapemu/src/test.rs @@ -75,6 +75,31 @@ impl PartialEq for ProcessorState { } } +impl ProcessorState { + pub fn mismatch_info(&self, smp: &Smp) -> String { + let mut info = String::new(); + if smp.a != self.a { + info.push_str(&format!("expected a = {:02x} but got {:02x}\n", self.a, smp.a)); + } + if smp.x != self.x { + info.push_str(&format!("expected a = {:02x} but got {:02x}\n", self.x, smp.x)); + } + if smp.y != self.y { + info.push_str(&format!("expected a = {:02x} but got {:02x}\n", self.y, smp.y)); + } + if smp.psw.bits() != self.psw { + info.push_str(&format!("expected a = {} but got {}\n", ProgramStatusWord(self.psw), smp.psw)); + } + if smp.sp != self.sp { + info.push_str(&format!("expected a = 01{:02x} but got 01{:02x}\n", self.sp, smp.sp)); + } + if smp.pc != self.pc { + info.push_str(&format!("expected a = {:04x} but got {:04x}\n", self.pc, smp.pc)); + } + info + } +} + #[derive(Deserialize, Debug, Clone)] #[repr(transparent)] struct RamState(Vec); @@ -260,10 +285,9 @@ fn single_instruction( ); assert!( test.final_state == smp, - "cpu mismatch at test {}:\nexpected {:#?}\ngot {:#?}", + "cpu mismatch at test {}: {}", test.name, - test.final_state, - smp, + test.final_state.mismatch_info(&smp) ); } },