From 45d0b9f9d112f06ae84e52014fec483718ea3904 Mon Sep 17 00:00:00 2001 From: Thomas Date: Thu, 23 Nov 2023 16:40:34 +0100 Subject: [PATCH] SPC700: implement POP/PUSH --- src/snes/cpu_spc700/cpu.rs | 47 +++++++++++++++++++++++++------ src/test/processortests_spc700.rs | 16 +++++------ 2 files changed, 47 insertions(+), 16 deletions(-) diff --git a/src/snes/cpu_spc700/cpu.rs b/src/snes/cpu_spc700/cpu.rs index ef3cc2c..9abf5ec 100644 --- a/src/snes/cpu_spc700/cpu.rs +++ b/src/snes/cpu_spc700/cpu.rs @@ -162,13 +162,13 @@ where /// Pushes 8-bits onto the stack fn push8(&mut self, val: u8) { - let addr = SpcAddress::from(self.regs.read_dec(Register::SP)); + let addr = SpcAddress::from(self.regs.read_dec(Register::SP) | 0x0100); self.write_tick(addr, val); } - /// Pulls 8-bits from the stack - fn pull8(&mut self) -> u8 { - let addr = SpcAddress::from(self.regs.read_inc(Register::SP).wrapping_add(1)); + /// Pops 8-bits from the stack + fn pop8(&mut self) -> u8 { + let addr = SpcAddress::from(self.regs.read_inc(Register::SP).wrapping_add(1) | 0x0100); self.read_tick(addr) } @@ -178,10 +178,10 @@ where self.push8(val as u8); } - /// Pulls 16-bits from the stack - fn pull16(&mut self) -> u16 { - let lo = self.pull8() as u16; - let hi = self.pull8() as u16; + /// Pops 16-bits from the stack + fn pop16(&mut self) -> u16 { + let lo = self.pop8() as u16; + let hi = self.pop8() as u16; lo | hi << 8 } @@ -238,6 +238,8 @@ where InstructionType::XCN => self.op_xcn(instr), InstructionType::ASL => self.op_asl(instr), InstructionType::LSR => self.op_lsr(instr), + InstructionType::PUSH => self.op_push(instr), + InstructionType::POP => self.op_pop(instr), _ => todo!(), } } @@ -741,4 +743,33 @@ where Ok(()) } + + /// PUSH + fn op_push(&mut self, instr: &Instruction) -> Result<()> { + let (_, val, _) = self.resolve_value(instr, 0, 0)?; + + // Internal delay + self.tick_bus(1)?; + + self.push8(val); + + // Internal delay + self.tick_bus(1)?; + + Ok(()) + } + + /// POP + fn op_pop(&mut self, instr: &Instruction) -> Result<()> { + let Operand::Register(reg) = instr.def.operands[0] else { + unreachable!() + }; + + // Internal delays + self.tick_bus(2)?; + + let val = self.pop8(); + self.regs.write(reg, val.into()); + Ok(()) + } } diff --git a/src/test/processortests_spc700.rs b/src/test/processortests_spc700.rs index 32760fa..0885fbf 100644 --- a/src/test/processortests_spc700.rs +++ b/src/test/processortests_spc700.rs @@ -190,7 +190,7 @@ cpu_test_no_trace!(instr_09, 0x09); //cpu_test!(instr_0a, 0x0a); cpu_test!(instr_0b, 0x0b); cpu_test!(instr_0c, 0x0c); -//cpu_test!(instr_0d, 0x0d); +cpu_test!(instr_0d, 0x0d); //cpu_test!(instr_0e, 0x0e); //cpu_test!(instr_0f, 0x0f); //cpu_test!(instr_10, 0x10); @@ -226,7 +226,7 @@ cpu_test_no_trace!(instr_29, 0x29); //cpu_test!(instr_2a, 0x2a); //cpu_test!(instr_2b, 0x2b); //cpu_test!(instr_2c, 0x2c); -//cpu_test!(instr_2d, 0x2d); +cpu_test!(instr_2d, 0x2d); //cpu_test!(instr_2e, 0x2e); //cpu_test!(instr_2f, 0x2f); //cpu_test!(instr_30, 0x30); @@ -262,7 +262,7 @@ cpu_test_no_trace!(instr_49, 0x49); //cpu_test!(instr_4a, 0x4a); cpu_test!(instr_4b, 0x4b); cpu_test!(instr_4c, 0x4c); -//cpu_test!(instr_4d, 0x4d); +cpu_test!(instr_4d, 0x4d); //cpu_test!(instr_4e, 0x4e); //cpu_test!(instr_4f, 0x4f); //cpu_test!(instr_50, 0x50); @@ -297,7 +297,7 @@ cpu_test_no_trace!(instr_69, 0x69); //cpu_test!(instr_6a, 0x6a); //cpu_test!(instr_6b, 0x6b); //cpu_test!(instr_6c, 0x6c); -//cpu_test!(instr_6d, 0x6d); +cpu_test!(instr_6d, 0x6d); //cpu_test!(instr_6e, 0x6e); //cpu_test!(instr_6f, 0x6f); //cpu_test!(instr_70, 0x70); @@ -332,7 +332,7 @@ cpu_test_no_trace!(instr_89, 0x89); cpu_test!(instr_8b, 0x8b); cpu_test!(instr_8c, 0x8c); cpu_test!(instr_8d, 0x8d); -//cpu_test!(instr_8e, 0x8e); +cpu_test!(instr_8e, 0x8e); cpu_test!(instr_8f, 0x8f); //cpu_test!(instr_90, 0x90); //cpu_test!(instr_91, 0x91); @@ -366,7 +366,7 @@ cpu_test_no_trace!(instr_a9, 0xa9); cpu_test!(instr_ab, 0xab); cpu_test!(instr_ac, 0xac); cpu_test!(instr_ad, 0xad); -//cpu_test!(instr_ae, 0xae); +cpu_test!(instr_ae, 0xae); // Wait during fetch cpu_test_no_trace!(instr_af, 0xaf); //cpu_test!(instr_b0, 0xb0); @@ -400,7 +400,7 @@ cpu_test!(instr_c9, 0xc9); cpu_test!(instr_cb, 0xcb); cpu_test!(instr_cc, 0xcc); cpu_test!(instr_cd, 0xcd); -//cpu_test!(instr_ce, 0xce); +cpu_test!(instr_ce, 0xce); //cpu_test!(instr_cf, 0xcf); //cpu_test!(instr_d0, 0xd0); //cpu_test!(instr_d1, 0xd1); @@ -433,7 +433,7 @@ cpu_test!(instr_e9, 0xe9); cpu_test!(instr_eb, 0xeb); cpu_test!(instr_ec, 0xec); cpu_test!(instr_ed, 0xed); -//cpu_test!(instr_ee, 0xee); +cpu_test!(instr_ee, 0xee); //cpu_test!(instr_ef, 0xef); //cpu_test!(instr_f0, 0xf0); //cpu_test!(instr_f1, 0xf1);