From 6d26e7de54aac46e9f173d01efd0c0439aa906b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20L=C3=B6ffler?= Date: Sat, 28 Jan 2023 05:24:15 +0100 Subject: [PATCH] fix memory related bugs god fucking damnit that's not how the program counter works lea --- src/emulator/main.rs | 22 ++------------ src/emulator/structs.rs | 67 +++++++++++++++++++++++++++++++++++++---- 2 files changed, 63 insertions(+), 26 deletions(-) diff --git a/src/emulator/main.rs b/src/emulator/main.rs index a750231..378a6b5 100644 --- a/src/emulator/main.rs +++ b/src/emulator/main.rs @@ -9,25 +9,7 @@ mod structs; pub const MEMORY_SIZE: usize = 8192; fn main() { - let mut state = EmulatorState { - a: 0, - b: 0, - c: 0, - d: 0, - e: 0, - h: 0, - l: 0, - sp: 0, - cc: ConditionCodes { - z: true, - s: true, - p: true, - c: true, - }, - pc: 0, - ei: true, - memory: [0; MEMORY_SIZE], - }; + let mut state = EmulatorState::default(); // Load the ROM into memory let mut args = env::args(); @@ -48,7 +30,7 @@ fn main() { } fn tick(state: &mut EmulatorState) { - let instruction = state.memory[state.pc as usize]; + let instruction = state.next_byte(); match instruction { 0x00 => {} // NOP diff --git a/src/emulator/structs.rs b/src/emulator/structs.rs index 64599da..4d586d7 100644 --- a/src/emulator/structs.rs +++ b/src/emulator/structs.rs @@ -25,21 +25,23 @@ pub struct EmulatorState { impl EmulatorState { // Read the next byte from memory pointed at by PC pub fn next_byte(&mut self) -> u8 { - self.pc += 1; - self.memory[self.pc as usize] + let value = self.memory[self.pc as usize]; + (self.pc, ..) = self.pc.overflowing_add(1); + value } // Read the next 16-bit word from memory pointed at by PC, in little endian order pub fn next_word(&mut self) -> u16 { - self.pc += 2; - self.read_word(self.pc - 1) + let value = self.read_word(self.pc); + (self.pc, ..) = self.pc.overflowing_add(2); + value } // Read a 16-bit word at a specific address pub fn read_word(&mut self, address: u16) -> u16 { u16::from_le_bytes([ self.memory[address as usize], - self.memory[address as usize + 1], + self.memory[address.overflowing_add(1).0 as usize], ]) } @@ -47,7 +49,31 @@ impl EmulatorState { pub fn write_word(&mut self, address: u16, value: u16) { let [low, high] = u16::to_le_bytes(value); self.memory[address as usize] = low; - self.memory[address as usize + 1] = high; + self.memory[address.overflowing_add(1).0 as usize] = high; + } +} + +impl Default for EmulatorState { + fn default() -> Self { + Self { + a: 0, + b: 0, + c: 0, + d: 0, + e: 0, + h: 0, + l: 0, + sp: 0, + cc: ConditionCodes { + z: true, + s: true, + p: true, + c: true, + }, + pc: 0, + ei: false, + memory: [0; MEMORY_SIZE], + } } } @@ -198,3 +224,32 @@ pub fn print_state(state: &EmulatorState) { state.cc.z, state.cc.s, state.cc.p, state.cc.c ); } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn read_word() { + let mut state = EmulatorState::default(); + state.memory[0x10] = 0x34; + state.memory[0x11] = 0x12; + assert_eq!(state.read_word(0x10), 0x1234); + } + + #[test] + fn write_word() { + let mut state = EmulatorState::default(); + state.write_word(0x10, 0x1234); + assert_eq!([0x34, 0x12], state.memory[0x10..0x12]); + } + + #[test] + fn next_word_at_pc() { + let mut state = EmulatorState::default(); + state.memory[0x10] = 0x34; + state.memory[0x11] = 0x12; + state.pc = 0x10; + assert_eq!(state.next_word(), 0x1234); + } +}