From 57c2ac681c9698156648e5c00ef7f007a25f58b4 Mon Sep 17 00:00:00 2001 From: John Breaux Date: Sat, 29 Apr 2023 18:34:24 -0500 Subject: [PATCH] cpu: fix renaming mistake "screen" -> "mem" --- src/cpu.rs | 51 ++++++++++++++++++++++------------------- src/cpu/behavior.rs | 27 ++++++++-------------- src/cpu/tests.rs | 17 ++++++-------- src/cpu/tests/decode.rs | 2 +- 4 files changed, 45 insertions(+), 52 deletions(-) diff --git a/src/cpu.rs b/src/cpu.rs index 2539f22..5a98acf 100644 --- a/src/cpu.rs +++ b/src/cpu.rs @@ -43,7 +43,7 @@ pub struct CPU { /// chip-8. Includes [Quirks], target IPF, etc. pub flags: Flags, // memory map info - screen: Bus, + mem: Bus, font: Adr, // memory stack: Vec, @@ -108,11 +108,26 @@ impl CPU { /// Loads bytes into the CPU's program space pub fn load_program_bytes(&mut self, rom: &[u8]) -> Result<&mut Self> { - self.screen.clear_region(Program); - self.screen.load_region(Program, rom)?; + self.mem.clear_region(Program); + self.mem.load_region(Program, rom)?; Ok(self) } + /// Pokes a value into memory + pub fn poke(&mut self, addr: Adr, data: u8) { + self.mem.write(addr, data) + } + + /// Peeks a value from memory + pub fn peek(&mut self, addr: Adr) -> u8 { + self.mem.read(addr) + } + + /// Grabs a reference to the [CPU]'s memory + pub fn introspect(&mut self) -> &Bus { + &self.mem + } + /// Presses a key, and reports whether the key's state changed. /// If key does not exist, returns [Error::InvalidKey]. /// @@ -453,12 +468,12 @@ impl CPU { /// # cpu.flags.debug = true; // enable live disassembly /// # cpu.flags.monotonic = true; // enable monotonic/test timing /// let mut bus = bus!{ - /// Program [0x0200..0x0f00] = &[ - /// 0xff, 0xff, // invalid! - /// 0x22, 0x02, // jump 0x202 (pc) - /// ], /// Screen [0x0f00..0x1000], /// }; + /// cpu.load_program_bytes(&[ + /// 0xff, 0xff, // invalid! + /// 0x22, 0x02, // jump 0x202 + /// ]); /// dbg!(cpu.tick(&mut bus)) /// .expect_err("Should return Error::InvalidInstruction { 0xffff }"); /// ``` @@ -472,23 +487,13 @@ impl CPU { return Ok(self); } self.cycle += 1; + // Fetch slice of memory starting at pc, for var-width opcode 0xf000_iiii let opchunk = self - .screen + .mem .get(self.pc as usize..) .ok_or(Error::InvalidAddressRange { range: (self.pc as usize..).into(), })?; - // fetch opcode - let opcode: &[u8; 2] = - if let Some(slice) = self.screen.get(self.pc as usize..self.pc as usize + 2) { - slice - .try_into() - .expect("`slice` should be exactly 4 bytes.") - } else { - return Err(Error::InvalidAddressRange { - range: (self.pc as usize..self.pc as usize + 4).into(), - }); - }; // Print opcode disassembly: if self.flags.debug { @@ -496,7 +501,7 @@ impl CPU { "{:3} {:03x}: {:<36}", self.cycle.bright_black(), self.pc, - self.disassembler.once(u16::from_be_bytes(*opcode)) + self.disassembler.once(self.mem.read(self.pc)) ); } @@ -506,7 +511,7 @@ impl CPU { self.execute(screen, insn); } else { return Err(Error::UnimplementedInstruction { - word: u16::from_be_bytes(*opcode), + word: self.mem.read(self.pc), }); } @@ -515,7 +520,7 @@ impl CPU { self.flags.pause = true; return Err(Error::BreakpointHit { addr: self.pc, - next: self.screen.read(self.pc), + next: self.mem.read(self.pc), }); } Ok(self) @@ -600,7 +605,7 @@ impl Default for CPU { fn default() -> Self { CPU { stack: vec![], - screen: bus! { + mem: bus! { Charset [0x0050..0x00a0] = include_bytes!("mem/charset.bin"), Program [0x0200..0x1000], }, diff --git a/src/cpu/behavior.rs b/src/cpu/behavior.rs index ae9cb16..3735471 100644 --- a/src/cpu/behavior.rs +++ b/src/cpu/behavior.rs @@ -407,10 +407,7 @@ impl CPU { pub(super) fn draw_sprite(&mut self, x: u16, y: u16, n: Nib, w: u16, h: u16, screen: &mut Bus) { let w_bytes = w / 8; self.v[0xf] = 0; - if let Some(sprite) = self - .screen - .get(self.i as usize..(self.i + n as u16) as usize) - { + if let Some(sprite) = self.mem.get(self.i as usize..(self.i + n as u16) as usize) { for (line, &sprite) in sprite.iter().enumerate() { let line = line as u16; let sprite = ((sprite as u16) << (8 - (x % 8))).to_be_bytes(); @@ -460,7 +457,7 @@ impl CPU { pub(super) fn draw_schip_sprite(&mut self, x: u16, y: u16, w: u16, screen: &mut Bus) { self.v[0xf] = 0; let w_bytes = w / 8; - if let Some(sprite) = self.screen.get(self.i as usize..(self.i + 32) as usize) { + if let Some(sprite) = self.mem.get(self.i as usize..(self.i + 32) as usize) { let sprite = sprite.to_owned(); for (line, sprite) in sprite.chunks_exact(2).enumerate() { let sprite = u16::from_be_bytes( @@ -572,9 +569,9 @@ impl CPU { #[inline(always)] pub(super) fn bcd_convert(&mut self, x: Reg) { let x = self.v[x]; - self.screen.write(self.i.wrapping_add(2), x % 10); - self.screen.write(self.i.wrapping_add(1), x / 10 % 10); - self.screen.write(self.i, x / 100 % 10); + self.mem.write(self.i.wrapping_add(2), x % 10); + self.mem.write(self.i.wrapping_add(1), x / 10 % 10); + self.mem.write(self.i, x / 100 % 10); } /// |`Fx55`| DMA Stor from I to registers 0..=X /// @@ -585,7 +582,7 @@ impl CPU { pub(super) fn store_dma(&mut self, x: Reg) { let i = self.i as usize; for (reg, value) in self - .screen + .mem .get_mut(i..=i + x) .unwrap_or_default() .iter_mut() @@ -606,7 +603,7 @@ impl CPU { pub(super) fn load_dma(&mut self, x: Reg) { let i = self.i as usize; for (reg, value) in self - .screen + .mem .get(i..=i + x) .unwrap_or_default() .iter() @@ -642,7 +639,7 @@ impl CPU { pub(super) fn store_flags(&mut self, x: Reg) { // TODO: Save these, maybe for (reg, value) in self - .screen + .mem .get_mut(0..=x) .unwrap_or_default() .iter_mut() @@ -656,13 +653,7 @@ impl CPU { /// I just chuck it in 0x0..0xf. Screw it. #[inline(always)] pub(super) fn load_flags(&mut self, x: Reg) { - for (reg, value) in self - .screen - .get(0..=x) - .unwrap_or_default() - .iter() - .enumerate() - { + for (reg, value) in self.mem.get(0..=x).unwrap_or_default().iter().enumerate() { self.v[reg] = *value; } } diff --git a/src/cpu/tests.rs b/src/cpu/tests.rs index 4f13510..f1d2d1b 100644 --- a/src/cpu/tests.rs +++ b/src/cpu/tests.rs @@ -33,7 +33,7 @@ fn setup_environment() -> (CPU, Bus) { }, bus! { // Create a screen - Screen [0x0F00..0x1000] = include_bytes!("../../chip8Archive/roms/1dcell.ch8"), + Screen [0x000..0x100] = include_bytes!("../../chip8Archive/roms/1dcell.ch8"), }, ); ch8.0 @@ -755,7 +755,7 @@ mod io { // Debug mode is 5x slower cpu.flags.debug = false; // Load the test program - cpu.screen.load_region(Program, test.program).unwrap(); + cpu.mem.load_region(Program, test.program).unwrap(); // Run the test program for the specified number of steps while cpu.cycle() < test.steps { cpu.multistep(&mut bus, 10.min(test.steps - cpu.cycle())) @@ -958,7 +958,7 @@ mod io { let addr = cpu.i as usize; assert_eq!( - cpu.screen + cpu.mem .get(addr..addr.wrapping_add(5)) .expect("Region at addr should exist!"), test.output, @@ -1004,10 +1004,7 @@ mod io { cpu.bcd_convert(5); - assert_eq!( - cpu.screen.get(addr..addr.saturating_add(3)), - Some(test.output) - ) + assert_eq!(cpu.mem.get(addr..addr.saturating_add(3)), Some(test.output)) } } } @@ -1030,7 +1027,7 @@ mod io { cpu.store_dma(len); // Check that bus grabbed the correct data let bus = cpu - .screen + .mem .get_mut(addr..addr + DATA.len()) .expect("Getting a mutable slice at addr 0x0456 should not fail"); assert_eq!(bus[0..=len], DATA[0..=len]); @@ -1048,7 +1045,7 @@ mod io { const DATA: &[u8] = b"ABCDEFGHIJKLMNOP"; // Load some test data into memory let addr = 0x456; - cpu.screen + cpu.mem .get_mut(addr..addr + DATA.len()) .expect("Getting a mutable slice at addr 0x0456..0x0466 should not fail") .write_all(DATA) @@ -1088,8 +1085,8 @@ mod behavior { #[test] fn sound() { let (mut cpu, mut bus) = setup_environment(); - cpu.flags.monotonic = None; // disable monotonic timing cpu.sound = 10.0; + cpu.flags.monotonic = false; // disable monotonic timing for _ in 0..2 { cpu.multistep(&mut bus, 8) .expect("Running valid instructions should always succeed"); diff --git a/src/cpu/tests/decode.rs b/src/cpu/tests/decode.rs index 5f14970..875d19f 100644 --- a/src/cpu/tests/decode.rs +++ b/src/cpu/tests/decode.rs @@ -15,7 +15,7 @@ fn run_single_op(op: &[u8]) -> CPU { Screen[0x0..0x1000], }, ); - cpu.screen + cpu.mem .load_region(Program, op).unwrap(); cpu.v = *INDX; cpu.flags.quirks = Quirks::from(false);