diff options
Diffstat (limited to 'src/memory.rs')
-rw-r--r-- | src/memory.rs | 64 |
1 files changed, 36 insertions, 28 deletions
diff --git a/src/memory.rs b/src/memory.rs index a3e9d70..7d14b61 100644 --- a/src/memory.rs +++ b/src/memory.rs @@ -2,7 +2,7 @@ use ppu::PPU; use mos6502::CPU; use cartridge::{MirrorType, Cartridge}; -use core::cell::{RefCell, Cell}; +use core::cell::{UnsafeCell, Cell}; use core::ptr::null_mut; pub trait VMem { @@ -11,7 +11,7 @@ pub trait VMem { } pub struct CPUMemory<'a> { - sram: RefCell<[u8; 2048]>, + sram: UnsafeCell<[u8; 2048]>, ppu: Cell<*mut PPU<'a>>, cpu: Cell<*mut CPU<'a>>, mapper: &'a VMem @@ -19,7 +19,7 @@ pub struct CPUMemory<'a> { impl<'a> CPUMemory<'a> { pub fn new(mapper: &'a VMem) -> Self { - CPUMemory{sram: RefCell::new([0; 2048]), + CPUMemory{sram: UnsafeCell::new([0; 2048]), cpu: Cell::new(null_mut()), ppu: Cell::new(null_mut()), mapper} @@ -37,7 +37,7 @@ impl<'a> VMem for CPUMemory<'a> { fn read(&self, addr: u16) -> u8 { match addr { _ => if addr < 0x2000 { - self.sram.borrow()[(addr & 0x07ff) as usize] + unsafe{(*self.sram.get())[(addr & 0x07ff) as usize]} } else if addr < 0x4000 { let ppu = unsafe {&mut *self.ppu.get()}; match addr & 0x7 { @@ -47,7 +47,6 @@ impl<'a> VMem for CPUMemory<'a> { _ => 0 } } else if addr < 0x6000 { - println!("feeding dummy data for 0x{:04x}", addr); 0 } else { self.mapper.read(addr) @@ -58,7 +57,7 @@ impl<'a> VMem for CPUMemory<'a> { let ppu = unsafe {&mut *self.ppu.get()}; let cpu = unsafe {&mut *self.cpu.get()}; if addr < 0x2000 { - self.sram.borrow_mut()[(addr & 0x07ff) as usize] = data; + unsafe{(*self.sram.get())[(addr & 0x07ff) as usize] = data;} } else if addr < 0x4000 { match addr & 0x7 { 0x0 => ppu.write_ctl(data), @@ -83,9 +82,8 @@ impl<'a> VMem for CPUMemory<'a> { } pub struct PPUMemory<'a> { - pattern_table: RefCell<[u8; 0x2000]>, - nametable: RefCell<[u8; 0x800]>, - palette: RefCell<[u8; 0x20]>, + nametable: UnsafeCell<[u8; 0x800]>, + palette: UnsafeCell<[u8; 0x20]>, cart: &'a Cartridge, mapper: &'a VMem, } @@ -94,21 +92,22 @@ impl<'a> PPUMemory<'a> { pub fn new(mapper: &'a VMem, cart: &'a Cartridge) -> Self { PPUMemory{ - pattern_table: RefCell::new([0; 0x2000]), - nametable: RefCell::new([0; 0x800]), - palette: RefCell::new([0; 0x20]), + nametable: UnsafeCell::new([0; 0x800]), + palette: UnsafeCell::new([0; 0x20]), cart, mapper} } pub fn dump(&self) { - for (i, v) in self.palette.borrow().iter().enumerate() { - print!("{:02x} ", *v); - if (i & 0x7) == 0x7 {println!("@{:02x}", i)} - } - for (i, v) in self.nametable.borrow().iter().enumerate() { - print!("{:02x} ", *v); - if (i & 0x1f) == 0x1f {println!("@{:02x}", i)} + 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)} + } } } } @@ -121,6 +120,7 @@ const MIRROR_IDX: [[u8; 4]; 5] = [ [0, 1, 2, 3], ]; +#[inline(always)] fn get_mirror_addr(kind: MirrorType, mut addr: u16) -> u16 { addr = (addr - 0x2000) & 0x0fff; let table = addr >> 10; @@ -128,7 +128,8 @@ fn get_mirror_addr(kind: MirrorType, mut addr: u16) -> u16 { 0x2000 + ((MIRROR_IDX[kind as usize][table as usize] as u16) << 10) + offset } -fn mirror_palette(addr: u16) -> u16 { +#[inline(always)] +fn get_mirror_palette(addr: u16) -> u16 { if addr >= 0x10 && addr & 3 == 0 { addr - 0x10 } else { addr } @@ -141,11 +142,15 @@ impl<'a> VMem for PPUMemory<'a> { self.mapper.read(addr) } else if addr < 0x3f00 { let kind = self.cart.mirror_type; - self.nametable.borrow() + unsafe { + (*self.nametable.get()) [(get_mirror_addr(kind, addr) & 0x07ff) as usize] + } } else if addr < 0x4000 { - self.palette.borrow() - [mirror_palette(addr & 0x1f) as usize] + unsafe { + (*self.palette.get()) + [get_mirror_palette(addr & 0x1f) as usize] + } } else { panic!("invalid ppu read access at 0x{:04x}", addr) } @@ -153,16 +158,19 @@ impl<'a> VMem for PPUMemory<'a> { fn write(&self, mut addr: u16, data: u8) { addr &= 0x3fff; - println!("writing 0x{:02x} to 0x{:04x}", data, addr); if addr < 0x2000 { self.mapper.write(addr, data) } else if addr < 0x3f00 { let kind = self.cart.mirror_type; - self.nametable.borrow_mut() - [(get_mirror_addr(kind, addr) & 0x07ff) as usize] = data + unsafe { + (*self.nametable.get()) + [(get_mirror_addr(kind, addr) & 0x07ff) as usize] = data; + } } else if addr < 0x4000 { - self.palette.borrow_mut() - [mirror_palette(addr & 0x1f) as usize] = data + unsafe { + (*self.palette.get()) + [get_mirror_palette(addr & 0x1f) as usize] = data; + } } else { panic!("invalid ppu write access at 0x{:04x}", addr) } |