fox32: Clean up Memory stuff, and change the shared memory base

Shared memory is now mapped starting at 0x80000000
This commit is contained in:
ry755 2022-01-27 17:50:07 -08:00 committed by Ry
parent 34de523f4d
commit d56648aa79
3 changed files with 56 additions and 55 deletions

View File

@ -37,7 +37,7 @@ impl Bus {
} }
0x02 => { 0x02 => {
// we're reading the framebuffer pointer of this overlay // we're reading the framebuffer pointer of this overlay
overlay_lock[overlay_number].framebuffer_pointer + 0x02000000 overlay_lock[overlay_number].framebuffer_pointer + 0x80000000
} }
0x03 => { 0x03 => {
// we're reading the enable status of this overlay // we're reading the enable status of this overlay
@ -108,7 +108,7 @@ impl Bus {
if word < 0x02000000 { if word < 0x02000000 {
panic!("overlay framebuffer must be within shared memory"); 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 => { 0x03 => {
// we're setting the enable status of this overlay // we're setting the enable status of this overlay
@ -121,7 +121,7 @@ impl Bus {
if word < 0x02000000 { if word < 0x02000000 {
panic!("audio buffer must be within shared memory"); 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 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; let length = u32::from_le_bytes(shared_memory_lock[address..address+4].try_into().unwrap()) as usize;

View File

@ -61,11 +61,7 @@ fn main() {
let mouse = Arc::new(Mutex::new(Mouse::new())); let mouse = Arc::new(Mutex::new(Mouse::new()));
// 32 MiB of shared memory // 32 MiB of shared memory
// add some "bonus bytes" at the end of memory to prevent dumb errors - (lua was here) let shared_memory = Arc::new(Mutex::new(vec![0u8; 0x02000000]));
// 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 mut cpu = { let mut cpu = {
// 32 MiB of fast memory // 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); 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_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; 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); println!("Shared memory: {:.2}MB mapped at {:#010X}-{:#010X}", shared_size / 1048576, shared_bottom_address, shared_top_address);

View File

@ -1,38 +1,56 @@
// memory.rs // memory.rs
use crate::{Overlay}; use crate::Overlay;
use std::sync::{Arc, Mutex}; use std::sync::{Arc, Mutex};
pub struct Memory { pub struct Memory {
pub fast_memory: Vec<u8>, pub fast_memory: Vec<u8>,
fast_memory_size: usize,
pub shared_memory: Arc<Mutex<Vec<u8>>>, pub shared_memory: Arc<Mutex<Vec<u8>>>,
shared_memory_size: usize,
pub overlays: Arc<Mutex<Vec<Overlay>>>, pub overlays: Arc<Mutex<Vec<Overlay>>>,
pub rom: Vec<u8>, pub rom: Vec<u8>,
rom_size: usize,
} }
impl Memory { impl Memory {
pub fn new(fast_memory: Vec<u8>, shared_memory: Arc<Mutex<Vec<u8>>>, overlays: Arc<Mutex<Vec<Overlay>>>, rom: Vec<u8>) -> Self { pub fn new(fast_memory: Vec<u8>, shared_memory: Arc<Mutex<Vec<u8>>>, overlays: Arc<Mutex<Vec<Overlay>>>, rom: Vec<u8>) -> Self {
let shared_memory_size = { shared_memory.lock().unwrap().len() };
Memory { Memory {
fast_memory_size: fast_memory.len(),
fast_memory, fast_memory,
shared_memory_size,
shared_memory, shared_memory,
overlays, overlays,
rom_size: rom.len(),
rom, rom,
} }
} }
pub fn read_8(&self, address: u32) -> u8 { pub fn read_8(&self, address: u32) -> u8 {
let address = address as usize; 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] self.fast_memory[address]
} else if address >= 0xF0000000 { } else if address >= shared_bottom_address && address <= shared_top_address {
let address = address - 0xF0000000;
self.rom[address]
} else {
let address = address - 0x02000000;
let shared_memory_lock = self.shared_memory.lock().unwrap(); 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 { pub fn read_16(&self, address: u32) -> u16 {
@ -40,35 +58,32 @@ impl Memory {
(self.read_8(address) as u16) (self.read_8(address) as u16)
} }
pub fn read_32(&self, address: u32) -> u32 { pub fn read_32(&self, address: u32) -> u32 {
let address = address as usize; (self.read_8(address + 3) as u32) << 24 |
if address < 0x02000000 { (self.read_8(address + 2) as u32) << 16 |
(self.fast_memory[address + 3] as u32) << 24 | (self.read_8(address + 1) as u32) << 8 |
(self.fast_memory[address + 2] as u32) << 16 | (self.read_8(address) as u32)
(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)
}
} }
pub fn write_8(&mut self, address: u32, byte: u8) { pub fn write_8(&mut self, address: u32, byte: u8) {
let address = address as usize; 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; self.fast_memory[address] = byte;
} else { } else if address >= shared_bottom_address && address <= shared_top_address {
let address = address - 0x02000000;
let mut shared_memory_lock = self.shared_memory.lock().unwrap(); 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) { 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); self.write_8(address + 1, (half >> 8) as u8);
} }
pub fn write_32(&mut self, address: u32, word: u32) { pub fn write_32(&mut self, address: u32, word: u32) {
let address = address as usize; self.write_8(address, (word & 0x000000FF) as u8);
if address < 0x02000000 { self.write_8(address + 1, ((word & 0x0000FF00) >> 8) as u8);
self.fast_memory[address] = (word & 0x000000FF) as u8; self.write_8(address + 2, ((word & 0x00FF0000) >> 16) as u8);
self.fast_memory[address + 1] = ((word & 0x0000FF00) >> 8) as u8; self.write_8(address + 3, ((word & 0xFF000000) >> 24) 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;
}
} }
} }