diff options
Diffstat (limited to 'src/memory.rs')
-rw-r--r-- | src/memory.rs | 102 |
1 files changed, 49 insertions, 53 deletions
diff --git a/src/memory.rs b/src/memory.rs index f8b6632..6a62678 100644 --- a/src/memory.rs +++ b/src/memory.rs @@ -1,47 +1,47 @@ #![allow(dead_code)] use ppu::PPU; use mos6502::CPU; -use cartridge::{MirrorType, Cartridge}; +use cartridge::MirrorType; use controller::Controller; -use core::cell::{UnsafeCell, Cell}; +use core::cell::RefCell; use core::ptr::null_mut; pub trait VMem { fn read(&self, addr: u16) -> u8; - fn write(&self, addr: u16, data: u8); + fn write(&mut self, addr: u16, data: u8); } pub struct CPUMemory<'a> { - sram: UnsafeCell<[u8; 2048]>, - ppu: Cell<*mut PPU<'a>>, - cpu: Cell<*mut CPU<'a>>, - mapper: &'a VMem, + sram: [u8; 2048], + ppu: *mut PPU<'a>, + cpu: *mut CPU<'a>, + mapper: &'a RefCell<&'a mut VMem>, ctl1: Option<&'a Controller>, ctl2: Option<&'a Controller> } impl<'a> CPUMemory<'a> { pub fn new(ppu: &mut PPU<'a>, - mapper: &'a VMem, + mapper: &'a RefCell<&'a mut VMem>, ctl1: Option<&'a Controller>, ctl2: Option<&'a Controller>) -> Self { - CPUMemory{sram: UnsafeCell::new([0; 2048]), - cpu: Cell::new(null_mut()), - ppu: Cell::new(ppu), + CPUMemory{sram: [0; 2048], + cpu: null_mut(), + ppu: ppu, mapper, ctl1, ctl2} } - pub fn init(&self, cpu: *mut CPU<'a>) { - self.cpu.set(cpu); + pub fn init(&mut self, cpu: *mut CPU<'a>) { + self.cpu = cpu; } } impl<'a> VMem for CPUMemory<'a> { fn read(&self, addr: u16) -> u8 { if addr < 0x2000 { - unsafe{(*self.sram.get())[(addr & 0x07ff) as usize]} + self.sram[(addr & 0x07ff) as usize] } else if addr < 0x4000 { - let ppu = unsafe {&mut *self.ppu.get()}; + let ppu = unsafe {&mut *self.ppu}; match addr & 0x7 { 0x2 => ppu.read_status(), 0x4 => ppu.read_oamdata(), @@ -57,15 +57,15 @@ impl<'a> VMem for CPUMemory<'a> { } else if addr < 0x6000 { 0 } else { - self.mapper.read(addr) + self.mapper.borrow().read(addr) } } - fn write(&self, addr: u16, data: u8) { - let ppu = unsafe {&mut *self.ppu.get()}; - let cpu = unsafe {&mut *self.cpu.get()}; + fn write(&mut self, addr: u16, data: u8) { + let ppu = unsafe {&mut *self.ppu}; + let cpu = unsafe {&mut *self.cpu}; if addr < 0x2000 { - unsafe{(*self.sram.get())[(addr & 0x07ff) as usize] = data;} + self.sram[(addr & 0x07ff) as usize] = data; } else if addr < 0x4000 { match addr & 0x7 { 0x0 => { @@ -94,38 +94,36 @@ impl<'a> VMem for CPUMemory<'a> { } } else if addr < 0x6000 { } else { - self.mapper.write(addr, data) + self.mapper.borrow_mut().write(addr, data) } } } pub struct PPUMemory<'a> { - nametable: UnsafeCell<[u8; 0x800]>, - palette: UnsafeCell<[u8; 0x20]>, - cart: &'a Cartridge, - mapper: &'a VMem, + nametable: [u8; 0x800], + palette: [u8; 0x20], + mirror_type: MirrorType, + mapper: &'a RefCell<&'a mut VMem>, } impl<'a> PPUMemory<'a> { - pub fn new(mapper: &'a VMem, - cart: &'a Cartridge) -> Self { + pub fn new(mapper: &'a RefCell<&'a mut VMem>, + mirror_type: MirrorType) -> Self { PPUMemory{ - nametable: UnsafeCell::new([0; 0x800]), - palette: UnsafeCell::new([0; 0x20]), - cart, + nametable: [0; 0x800], + palette: [0; 0x20], + mirror_type, mapper} } pub fn dump(&self) { - unsafe { - for (i, v) in (*self.palette.get()).iter().enumerate() { - print!("{:02x} ", *v); - if (i & 0x7) == 0x7 {println!("@{:02x}", i)} - } - for (i, v) in (*self.nametable.get()).iter().enumerate() { - print!("{:02x} ", *v); - if (i & 0x1f) == 0x1f {println!("@{:02x}", i)} - } + for (i, v) in self.palette.iter().enumerate() { + print!("{:02x} ", *v); + if (i & 0x7) == 0x7 {println!("@{:02x}", i)} + } + for (i, v) in self.nametable.iter().enumerate() { + print!("{:02x} ", *v); + if (i & 0x1f) == 0x1f {println!("@{:02x}", i)} } } } @@ -155,34 +153,32 @@ fn get_mirror_palette(addr: u16) -> u16 { impl<'a> PPUMemory<'a> { #[inline(always)] pub fn read_nametable(&self, addr: u16) -> u8 { - let kind = self.cart.mirror_type; - unsafe {(*self.nametable.get())[(get_mirror_addr(kind, addr) & 0x7ff) as usize]} + self.nametable[(get_mirror_addr(self.mirror_type, addr) & 0x7ff) as usize] } #[inline(always)] - pub fn read_palette(&self, addr: u16) -> u8 { unsafe { - (*self.palette.get())[get_mirror_palette(addr) as usize] - }} + pub fn read_palette(&self, addr: u16) -> u8 { + self.palette[get_mirror_palette(addr) as usize] + } #[inline(always)] - pub fn write_nametable(&self, addr: u16, data: u8) { - let kind = self.cart.mirror_type; - unsafe {(*self.nametable.get())[(get_mirror_addr(kind, addr) & 0x7ff) as usize] = data} + pub fn write_nametable(&mut self, addr: u16, data: u8) { + self.nametable[(get_mirror_addr(self.mirror_type, addr) & 0x7ff) as usize] = data } #[inline(always)] - pub fn write_palette(&self, addr: u16, data: u8) { unsafe { - (*self.palette.get())[get_mirror_palette(addr) as usize] = data; - }} + pub fn write_palette(&mut self, addr: u16, data: u8) { + self.palette[get_mirror_palette(addr) as usize] = data + } #[inline(always)] pub fn read_mapper(&self, addr: u16) -> u8 { - self.mapper.read(addr) + self.mapper.borrow().read(addr) } #[inline(always)] fn write_mapper(&self, addr: u16, data: u8) { - self.mapper.write(addr, data); + self.mapper.borrow_mut().write(addr, data); } } @@ -200,7 +196,7 @@ impl<'a> VMem for PPUMemory<'a> { } } - fn write(&self, mut addr: u16, data: u8) { + fn write(&mut self, mut addr: u16, data: u8) { addr &= 0x3fff; if addr < 0x2000 { self.write_mapper(addr, data); |