diff --git a/src/bus.rs b/src/bus.rs index 4a57ddf..fcc7b4f 100644 --- a/src/bus.rs +++ b/src/bus.rs @@ -37,7 +37,7 @@ impl Bus { } 0x02 => { // we're reading the framebuffer pointer of this overlay - overlay_lock[overlay_number].framebuffer_pointer + 0x02000000 + overlay_lock[overlay_number].framebuffer_pointer + 0x80000000 } 0x03 => { // we're reading the enable status of this overlay @@ -108,7 +108,7 @@ impl Bus { if word < 0x02000000 { panic!("overlay framebuffer must be within shared memory"); } - overlay_lock[overlay_number].framebuffer_pointer = word - 0x02000000; + overlay_lock[overlay_number].framebuffer_pointer = word - 0x80000000; } 0x03 => { // we're setting the enable status of this overlay @@ -121,7 +121,7 @@ impl Bus { if word < 0x02000000 { panic!("audio buffer must be within shared memory"); } - let address = word as usize - 0x02000000; + let address = word as usize - 0x80000000; let shared_memory_lock = self.memory.shared_memory.lock().unwrap(); let length = u32::from_le_bytes(shared_memory_lock[address..address+4].try_into().unwrap()) as usize; diff --git a/src/main.rs b/src/main.rs index 2e97a3c..df53ece 100644 --- a/src/main.rs +++ b/src/main.rs @@ -61,11 +61,7 @@ fn main() { let mouse = Arc::new(Mutex::new(Mouse::new())); // 32 MiB of shared memory - // add some "bonus bytes" at the end of memory to prevent dumb errors - (lua was here) - // see the ImmediatePtr match arm in read_source() in cpu.rs for more info - // basically all immediate pointers read 32 bits, even if the opcode size is smaller - // so attempting to read something like the last byte of shared memory (0x03FFFFFF) would previously panic - let shared_memory = Arc::new(Mutex::new(vec![0u8; 0x0200000F])); + let shared_memory = Arc::new(Mutex::new(vec![0u8; 0x02000000])); let mut cpu = { // 32 MiB of fast memory @@ -80,7 +76,7 @@ fn main() { println!("Fast memory: {:.2}MB mapped at {:#010X}-{:#010X}", fast_size / 1048576, fast_bottom_address, fast_top_address); let shared_size = { cpu_shared_memory.lock().unwrap().len() }; - let shared_bottom_address = 0x02000000; + let shared_bottom_address = 0x80000000; let shared_top_address = shared_bottom_address + shared_size - 1; println!("Shared memory: {:.2}MB mapped at {:#010X}-{:#010X}", shared_size / 1048576, shared_bottom_address, shared_top_address); diff --git a/src/memory.rs b/src/memory.rs index f1362b3..df21937 100644 --- a/src/memory.rs +++ b/src/memory.rs @@ -1,38 +1,56 @@ // memory.rs -use crate::{Overlay}; +use crate::Overlay; use std::sync::{Arc, Mutex}; pub struct Memory { pub fast_memory: Vec, + fast_memory_size: usize, pub shared_memory: Arc>>, + shared_memory_size: usize, pub overlays: Arc>>, pub rom: Vec, + rom_size: usize, } impl Memory { pub fn new(fast_memory: Vec, shared_memory: Arc>>, overlays: Arc>>, rom: Vec) -> Self { + let shared_memory_size = { shared_memory.lock().unwrap().len() }; Memory { + fast_memory_size: fast_memory.len(), fast_memory, + shared_memory_size, shared_memory, overlays, + rom_size: rom.len(), rom, } } pub fn read_8(&self, address: u32) -> u8 { let address = address as usize; - if address < 0x02000000 { + + let fast_bottom_address = 0x00000000; + let fast_top_address = fast_bottom_address + self.fast_memory_size - 1; + + let shared_bottom_address = 0x80000000; + let shared_top_address = shared_bottom_address + self.shared_memory_size - 1; + + let rom_bottom_address = 0xF0000000; + let rom_top_address = rom_bottom_address + self.rom_size - 1; + + if address >= fast_bottom_address && address <= fast_top_address { self.fast_memory[address] - } else if address >= 0xF0000000 { - let address = address - 0xF0000000; - self.rom[address] - } else { - let address = address - 0x02000000; + } else if address >= shared_bottom_address && address <= shared_top_address { let shared_memory_lock = self.shared_memory.lock().unwrap(); - shared_memory_lock[address] + shared_memory_lock[address - shared_bottom_address] + } else if address >= rom_bottom_address && address <= rom_top_address { + self.rom[address - rom_bottom_address] + } else { + println!("Warning: attempting to read unmapped memory address: {:#010X}", address); + 0 } } pub fn read_16(&self, address: u32) -> u16 { @@ -40,35 +58,32 @@ impl Memory { (self.read_8(address) as u16) } pub fn read_32(&self, address: u32) -> u32 { - let address = address as usize; - if address < 0x02000000 { - (self.fast_memory[address + 3] as u32) << 24 | - (self.fast_memory[address + 2] as u32) << 16 | - (self.fast_memory[address + 1] as u32) << 8 | - (self.fast_memory[address] as u32) - } else if address >= 0xF0000000 { - let address = address - 0xF0000000; - (self.rom[address + 3] as u32) << 24 | - (self.rom[address + 2] as u32) << 16 | - (self.rom[address + 1] as u32) << 8 | - (self.rom[address] as u32) - } else { - let address = address - 0x02000000; - let shared_memory_lock = self.shared_memory.lock().unwrap(); - (shared_memory_lock[address + 3] as u32) << 24 | - (shared_memory_lock[address + 2] as u32) << 16 | - (shared_memory_lock[address + 1] as u32) << 8 | - (shared_memory_lock[address] as u32) - } + (self.read_8(address + 3) as u32) << 24 | + (self.read_8(address + 2) as u32) << 16 | + (self.read_8(address + 1) as u32) << 8 | + (self.read_8(address) as u32) } pub fn write_8(&mut self, address: u32, byte: u8) { let address = address as usize; - if address < 0x02000000 { + + let fast_bottom_address = 0x00000000; + let fast_top_address = fast_bottom_address + self.fast_memory_size - 1; + + let shared_bottom_address = 0x80000000; + let shared_top_address = shared_bottom_address + self.shared_memory_size - 1; + + let rom_bottom_address = 0xF0000000; + let rom_top_address = rom_bottom_address + self.rom_size - 1; + + if address >= fast_bottom_address && address <= fast_top_address { self.fast_memory[address] = byte; - } else { - let address = address - 0x02000000; + } else if address >= shared_bottom_address && address <= shared_top_address { let mut shared_memory_lock = self.shared_memory.lock().unwrap(); - shared_memory_lock[address] = byte; + shared_memory_lock[address - shared_bottom_address] = byte; + } else if address >= rom_bottom_address && address <= rom_top_address { + println!("Warning: attempting to write to ROM address: {:#010X}", address); + } else { + println!("Warning: attempting to write to unmapped memory address: {:#010X}", address); } } pub fn write_16(&mut self, address: u32, half: u16) { @@ -76,19 +91,9 @@ impl Memory { self.write_8(address + 1, (half >> 8) as u8); } pub fn write_32(&mut self, address: u32, word: u32) { - let address = address as usize; - if address < 0x02000000 { - self.fast_memory[address] = (word & 0x000000FF) as u8; - self.fast_memory[address + 1] = ((word & 0x0000FF00) >> 8) as u8; - self.fast_memory[address + 2] = ((word & 0x00FF0000) >> 16) as u8; - self.fast_memory[address + 3] = ((word & 0xFF000000) >> 24) as u8; - } else { - let address = address - 0x02000000; - let mut shared_memory_lock = self.shared_memory.lock().unwrap(); - shared_memory_lock[address] = (word & 0x000000FF) as u8; - shared_memory_lock[address + 1] = ((word & 0x0000FF00) >> 8) as u8; - shared_memory_lock[address + 2] = ((word & 0x00FF0000) >> 16) as u8; - shared_memory_lock[address + 3] = ((word & 0xFF000000) >> 24) as u8; - } + self.write_8(address, (word & 0x000000FF) as u8); + self.write_8(address + 1, ((word & 0x0000FF00) >> 8) as u8); + self.write_8(address + 2, ((word & 0x00FF0000) >> 16) as u8); + self.write_8(address + 3, ((word & 0xFF000000) >> 24) as u8); } } \ No newline at end of file