diff --git a/src/snes/cpu_spc700/cpu.rs b/src/snes/cpu_spc700/cpu.rs index 0f1df0f..999c7a4 100644 --- a/src/snes/cpu_spc700/cpu.rs +++ b/src/snes/cpu_spc700/cpu.rs @@ -208,6 +208,7 @@ where InstructionType::MOVNoFlags => self.op_mov(instr, false), InstructionType::ADC => self.op_adc(instr), InstructionType::SBC => self.op_sbc(instr), + InstructionType::CMP => self.op_cmp(instr), _ => todo!(), } } @@ -433,9 +434,9 @@ where let (_, val, _) = self.resolve_value(instr, 1, src_idx)?; // Extra wait cycles - match (instr.def.operands[0], instr.def.operands[1]) { - (Operand::Register(_), Operand::Register(_)) - | (Operand::Register(_), Operand::IndirectXAutoInc) => self.tick_bus(1)?, + match instr.def.operands { + [Operand::Register(_), Operand::Register(_)] + | [Operand::Register(_), Operand::IndirectXAutoInc] => self.tick_bus(1)?, _ => (), } @@ -521,4 +522,28 @@ where Ok(()) } + + /// CMP + fn op_cmp(&mut self, instr: &Instruction) -> Result<()> { + let (src_idx, a, odest_addr) = self.resolve_value(instr, 0, 0)?; + let (_, b, _) = self.resolve_value(instr, 1, src_idx)?; + + let result = (a as i16) - (b as i16); + + // Extra internal cycles + match instr.def.operands { + [Operand::DirectPage, Operand::DirectPage] + | [Operand::DirectPage, Operand::Immediate] + | [Operand::IndirectX, Operand::IndirectY] => self.tick_bus(1)?, + _ => (), + } + + self.regs.write_flags(&[ + (Flag::Z, (result & 0xFF) == 0), + (Flag::N, result & 0x80 != 0), + (Flag::C, result >= 0), + ]); + + Ok(()) + } } diff --git a/src/test/processortests_spc700.rs b/src/test/processortests_spc700.rs index 594e4cc..fb5ba76 100644 --- a/src/test/processortests_spc700.rs +++ b/src/test/processortests_spc700.rs @@ -202,7 +202,7 @@ cpu_test_no_trace!(instr_19, 0x19); //cpu_test!(instr_1b, 0x1b); //cpu_test!(instr_1c, 0x1c); //cpu_test!(instr_1d, 0x1d); -//cpu_test!(instr_1e, 0x1e); +cpu_test!(instr_1e, 0x1e); //cpu_test!(instr_1f, 0x1f); cpu_test!(instr_20, 0x20); //cpu_test!(instr_21, 0x21); @@ -238,7 +238,7 @@ cpu_test_no_trace!(instr_39, 0x39); //cpu_test!(instr_3b, 0x3b); //cpu_test!(instr_3c, 0x3c); //cpu_test!(instr_3d, 0x3d); -//cpu_test!(instr_3e, 0x3e); +cpu_test!(instr_3e, 0x3e); //cpu_test!(instr_3f, 0x3f); cpu_test!(instr_40, 0x40); //cpu_test!(instr_41, 0x41); @@ -274,18 +274,19 @@ cpu_test_no_trace!(instr_59, 0x59); //cpu_test!(instr_5b, 0x5b); //cpu_test!(instr_5c, 0x5c); cpu_test!(instr_5d, 0x5d); -//cpu_test!(instr_5e, 0x5e); +cpu_test!(instr_5e, 0x5e); //cpu_test!(instr_5f, 0x5f); cpu_test!(instr_60, 0x60); //cpu_test!(instr_61, 0x61); cpu_test!(instr_62, 0x62); //cpu_test!(instr_63, 0x63); -//cpu_test!(instr_64, 0x64); -//cpu_test!(instr_65, 0x65); -//cpu_test!(instr_66, 0x66); -//cpu_test!(instr_67, 0x67); -//cpu_test!(instr_68, 0x68); -//cpu_test!(instr_69, 0x69); +cpu_test!(instr_64, 0x64); +cpu_test!(instr_65, 0x65); +cpu_test!(instr_66, 0x66); +cpu_test!(instr_67, 0x67); +cpu_test!(instr_68, 0x68); +// Read indirection during fetch +cpu_test_no_trace!(instr_69, 0x69); //cpu_test!(instr_6a, 0x6a); //cpu_test!(instr_6b, 0x6b); //cpu_test!(instr_6c, 0x6c); @@ -296,17 +297,18 @@ cpu_test!(instr_62, 0x62); //cpu_test!(instr_71, 0x71); cpu_test!(instr_72, 0x72); //cpu_test!(instr_73, 0x73); -//cpu_test!(instr_74, 0x74); -//cpu_test!(instr_75, 0x75); -//cpu_test!(instr_76, 0x76); -//cpu_test!(instr_77, 0x77); -//cpu_test!(instr_78, 0x78); -//cpu_test!(instr_79, 0x79); +cpu_test!(instr_74, 0x74); +cpu_test!(instr_75, 0x75); +cpu_test!(instr_76, 0x76); +cpu_test!(instr_77, 0x77); +cpu_test!(instr_78, 0x78); +// Read indirection during fetch +cpu_test_no_trace!(instr_79, 0x79); //cpu_test!(instr_7a, 0x7a); //cpu_test!(instr_7b, 0x7b); //cpu_test!(instr_7c, 0x7c); cpu_test!(instr_7d, 0x7d); -//cpu_test!(instr_7e, 0x7e); +cpu_test!(instr_7e, 0x7e); //cpu_test!(instr_7f, 0x7f); cpu_test!(instr_80, 0x80); //cpu_test!(instr_81, 0x81); @@ -356,7 +358,7 @@ cpu_test_no_trace!(instr_a9, 0xa9); //cpu_test!(instr_aa, 0xaa); //cpu_test!(instr_ab, 0xab); //cpu_test!(instr_ac, 0xac); -//cpu_test!(instr_ad, 0xad); +cpu_test!(instr_ad, 0xad); //cpu_test!(instr_ae, 0xae); // Wait during fetch cpu_test_no_trace!(instr_af, 0xaf);