aboutsummaryrefslogtreecommitdiff
path: root/src/memory.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/memory.rs')
-rw-r--r--src/memory.rs64
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)
}