From 45adf0a2b8b00a3ed65891c86ec20e79bb1a2d68 Mon Sep 17 00:00:00 2001 From: John Breaux Date: Mon, 17 Apr 2023 06:34:48 -0500 Subject: [PATCH] cpu.rs: Remove stack from main memory --- src/bin/chirp-minifb/main.rs | 3 --- src/cpu.rs | 9 ++++----- src/cpu/bus.rs | 5 +---- src/cpu/instruction.rs | 14 ++++++-------- src/cpu/tests.rs | 21 +++++++++------------ tests/integration.rs | 10 +++++----- 6 files changed, 25 insertions(+), 37 deletions(-) diff --git a/src/bin/chirp-minifb/main.rs b/src/bin/chirp-minifb/main.rs index ff61e92..d2d9d45 100644 --- a/src/bin/chirp-minifb/main.rs +++ b/src/bin/chirp-minifb/main.rs @@ -129,14 +129,11 @@ impl State { Program [0x0200..0x1000] = &read(&options.file)?, // Create a screen Screen [0x1000..0x1100], - // Create a stack - Stack [0x0EA0..0x0F00], }, cpu: CPU::new( 0x1000, 0x50, 0x200, - 0xefe, Dis::default(), options.breakpoints, Flags { diff --git a/src/cpu.rs b/src/cpu.rs index 907bc5d..4514759 100644 --- a/src/cpu.rs +++ b/src/cpu.rs @@ -55,9 +55,10 @@ pub struct CPU { // memory map info screen: Adr, font: Adr, + // memory + stack: Vec, // registers pc: Adr, - sp: Adr, i: Adr, v: [u8; 16], delay: f64, @@ -93,7 +94,6 @@ impl CPU { screen: Adr, font: Adr, pc: Adr, - sp: Adr, disassembler: Dis, breakpoints: Vec, flags: Flags, @@ -103,7 +103,6 @@ impl CPU { screen, font, pc, - sp, breakpoints, flags, ..Default::default() @@ -548,7 +547,7 @@ impl CPU { std::println!( "PC: {:04x}, SP: {:04x}, I: {:04x}\n{}DLY: {}, SND: {}, CYC: {:6}", self.pc, - self.sp, + self.stack.len(), self.i, self.v .into_iter() @@ -588,10 +587,10 @@ impl Default for CPU { /// ``` fn default() -> Self { CPU { + stack: vec![], screen: 0xf00, font: 0x050, pc: 0x200, - sp: 0xefe, i: 0, v: [0; 16], delay: 0.0, diff --git a/src/cpu/bus.rs b/src/cpu/bus.rs index 04c9331..24df972 100644 --- a/src/cpu/bus.rs +++ b/src/cpu/bus.rs @@ -88,8 +88,6 @@ pub enum Region { Program, /// Screen buffer Screen, - /// Stack space - Stack, #[doc(hidden)] /// Total number of named regions Count, @@ -104,7 +102,6 @@ impl Display for Region { Region::Charset => "Charset", Region::Program => "Program", Region::Screen => "Screen", - Region::Stack => "Stack", _ => "", } ) @@ -348,7 +345,7 @@ impl Bus { #[cfg(feature = "drawille")] { use drawille::Canvas; - let mut canvas = Canvas::new(dbg!(width * 8), dbg!(height)); + let mut canvas = Canvas::new(width * 8, height); let width = width * 8; screen .iter() diff --git a/src/cpu/instruction.rs b/src/cpu/instruction.rs index 48284f2..a71fa87 100644 --- a/src/cpu/instruction.rs +++ b/src/cpu/instruction.rs @@ -13,9 +13,9 @@ impl CPU { match instruction { // Core Chip-8 instructions Insn::cls => self.clear_screen(bus), - Insn::ret => self.ret(bus), + Insn::ret => self.ret(), Insn::jmp { A } => self.jump(A), - Insn::call { A } => self.call(A, bus), + Insn::call { A } => self.call(A), Insn::seb { x, B } => self.skip_equals_immediate(x, B), Insn::sneb { x, B } => self.skip_not_equals_immediate(x, B), Insn::se { y, x } => self.skip_equals(x, y), @@ -74,9 +74,8 @@ impl CPU { } /// |`00ee`| Returns from subroutine #[inline(always)] - pub(super) fn ret(&mut self, bus: &impl ReadWrite) { - self.sp = self.sp.wrapping_add(2); - self.pc = bus.read(self.sp); + pub(super) fn ret(&mut self) { + self.pc = self.stack.pop().unwrap_or(0x200); } } @@ -97,9 +96,8 @@ impl CPU { impl CPU { /// |`2aaa`| Pushes pc onto the stack, then jumps to a #[inline(always)] - pub(super) fn call(&mut self, a: Adr, bus: &mut impl ReadWrite) { - bus.write(self.sp, self.pc); - self.sp = self.sp.wrapping_sub(2); + pub(super) fn call(&mut self, a: Adr) { + self.stack.push(self.pc); self.pc = a; } } diff --git a/src/cpu/tests.rs b/src/cpu/tests.rs index 1eb89b5..d2573d4 100644 --- a/src/cpu/tests.rs +++ b/src/cpu/tests.rs @@ -106,17 +106,14 @@ mod sys { #[test] fn ret() { let test_addr = random::() & 0x7ff; - let (mut cpu, mut bus) = setup_environment(); - let sp_orig = cpu.sp; + let (mut cpu, _) = setup_environment(); // Place the address on the stack - bus.write(cpu.sp.wrapping_add(2), test_addr); + cpu.stack.push(test_addr); - cpu.ret(&bus); + cpu.ret(); // Verify the current address is the address from the stack assert_eq!(test_addr, cpu.pc); - // Verify the stack pointer has moved - assert!(dbg!(cpu.sp.wrapping_sub(sp_orig)) == 0x2); } } @@ -132,9 +129,9 @@ mod cf { let (mut cpu, _) = setup_environment(); // Test all valid addresses for addr in 0x000..0xffe { - // Call an address + // Jump to an address cpu.jump(addr); - // Verify the current address is the called address + // Verify the current address is the jump target address assert_eq!(addr, cpu.pc); } } @@ -143,15 +140,15 @@ mod cf { #[test] fn call() { let test_addr = random::(); - let (mut cpu, mut bus) = setup_environment(); + let (mut cpu, _) = setup_environment(); // Save the current address let curr_addr = cpu.pc; // Call an address - cpu.call(test_addr, &mut bus); + cpu.call(test_addr); // Verify the current address is the called address assert_eq!(test_addr, cpu.pc); // Verify the previous address was stored on the stack (sp+2) - let stack_addr: u16 = bus.read(cpu.sp.wrapping_add(2)); + let stack_addr: u16 = cpu.stack.pop().expect("This should return test_addr"); assert_eq!(stack_addr, curr_addr); } @@ -595,7 +592,7 @@ mod math { for reg in 0..=0xff { let (x, y) = (reg & 0xf, reg >> 4); // set the register under test to `word` - (cpu.v[x], cpu.v[y]) = dbg!(0, word); + (cpu.v[x], cpu.v[y]) = (0, word); cpu.shift_left(x, y); diff --git a/tests/integration.rs b/tests/integration.rs index bae07db..445a627 100644 --- a/tests/integration.rs +++ b/tests/integration.rs @@ -30,11 +30,11 @@ mod bus { } #[test] fn display() { - println!("{Charset}{Program}{Screen}{Stack}{Count}"); + println!("{Charset}{Program}{Screen}{Count}"); } #[test] fn debug() { - println!("{Charset:?}{Program:?}{Screen:?}{Stack:?}{Count:?}"); + println!("{Charset:?}{Program:?}{Screen:?}{Count:?}"); } // lmao the things you do for test coverage #[test] @@ -44,13 +44,13 @@ mod bus { } #[test] fn ord() { - assert_eq!(Stack, Charset.max(Program).max(Screen).max(Stack)); - assert!(Charset < Program && Program < Screen && Screen < Stack); + assert_eq!(Screen, Charset.max(Program).max(Screen)); + assert!(Charset < Program && Program < Screen); } #[test] fn hash() { let mut hasher = DefaultHasher::new(); - Stack.hash(&mut hasher); + Program.hash(&mut hasher); println!("{hasher:?}"); } }