aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDeterminant <ted.sybil@gmail.com>2018-01-04 15:40:18 +0800
committerDeterminant <ted.sybil@gmail.com>2018-01-04 15:40:18 +0800
commitd77c884c4e0826e80a3eda01a129a2792ae509f5 (patch)
tree3a84a75cd8eec1838a2e3d7486ece2cc32d32e44
parent8b41532e597b6bf6fc16fe17700fd0a91d15f129 (diff)
remove RefCell in memory/mapper to improve performance
-rw-r--r--src/bin.rs3
-rw-r--r--src/mapper.rs24
-rw-r--r--src/memory.rs24
3 files changed, 37 insertions, 14 deletions
diff --git a/src/bin.rs b/src/bin.rs
index 7d94c7b..839b630 100644
--- a/src/bin.rs
+++ b/src/bin.rs
@@ -3,7 +3,6 @@ extern crate core;
use std::fs::File;
use std::sync::{Mutex, Condvar};
use std::io::Read;
-use std::cell::RefCell;
use std::intrinsics::transmute;
use std::process::exit;
@@ -423,7 +422,7 @@ fn main() {
_ => panic!("unsupported mapper {}", mapper_id)
};
- let mapper = RefCell::new(&mut (*m) as &mut mapper::Mapper);
+ let mapper = mapper::RefMapper::new(&mut (*m) as &mut mapper::Mapper);
let mut cpu = CPU::new(CPUMemory::new(&mapper, Some(&p1ctl), None));
let mut ppu = PPU::new(PPUMemory::new(&mapper), &mut (*win));
let mut apu = APU::new(&mut spkr);
diff --git a/src/mapper.rs b/src/mapper.rs
index cf946a2..446d5b9 100644
--- a/src/mapper.rs
+++ b/src/mapper.rs
@@ -1,5 +1,6 @@
#![allow(dead_code)]
extern crate core;
+use core::cell::UnsafeCell;
use memory::{VMem, CPUBus};
use cartridge::{Cartridge, BankType, MirrorType};
@@ -8,6 +9,29 @@ pub trait Mapper : VMem {
fn tick(&mut self, _bus: &CPUBus) {}
}
+pub struct RefMapper<'a> {
+ mapper: UnsafeCell<&'a mut Mapper>
+}
+
+impl<'a> RefMapper<'a> {
+ pub fn new(mapper: &'a mut Mapper) -> Self {
+ RefMapper { mapper: UnsafeCell::new(mapper) }
+ }
+
+ #[inline(always)]
+ pub fn get_mut(&self) -> &'a mut Mapper {
+ unsafe { *self.mapper.get() }
+ }
+}
+
+impl<'a> core::ops::Deref for RefMapper<'a> {
+ type Target = &'a mut Mapper;
+ #[inline(always)]
+ fn deref(&self) -> &&'a mut Mapper {
+ unsafe { &*self.mapper.get() }
+ }
+}
+
pub struct Mapper1<'a, C> where C: Cartridge {
cart: C,
prg_banks: [&'a [u8]; 2],
diff --git a/src/memory.rs b/src/memory.rs
index 985070f..765aeb5 100644
--- a/src/memory.rs
+++ b/src/memory.rs
@@ -3,7 +3,7 @@ use ppu::PPU;
use apu::{APU, Sampler};
use mos6502::{CPU, CPU_FREQ};
use cartridge::MirrorType;
-use mapper::Mapper;
+use mapper::RefMapper;
use controller::Controller;
use core::cell::{RefCell, Cell};
use core::ptr::null_mut;
@@ -89,14 +89,14 @@ impl<'a> CPUBus<'a> {
pub struct CPUMemory<'a> {
sram: [u8; 2048],
pub bus: CPUBus<'a>,
- mapper: &'a RefCell<&'a mut Mapper>,
+ mapper: &'a RefMapper<'a>,
ctl1: Option<&'a Controller>,
ctl2: Option<&'a Controller>
}
impl<'a> CPUMemory<'a> {
pub fn new(
- mapper: &'a RefCell<&'a mut Mapper>,
+ mapper: &'a RefMapper<'a>,
ctl1: Option<&'a Controller>,
ctl2: Option<&'a Controller>) -> Self {
CPUMemory{sram: [0; 2048],
@@ -137,7 +137,7 @@ impl<'a> CPUMemory<'a> {
} else if addr < 0x6000 {
0
} else {
- self.mapper.borrow().read(addr)
+ self.mapper.read(addr)
}
}
@@ -200,7 +200,7 @@ impl<'a> CPUMemory<'a> {
}
} else if addr < 0x6000 {
} else {
- self.mapper.borrow_mut().write(addr, data)
+ self.mapper.get_mut().write(addr, data)
}
}
}
@@ -220,11 +220,11 @@ impl<'a> VMem for CPUMemory<'a> {
pub struct PPUMemory<'a> {
nametable: [u8; 0x800],
palette: [u8; 0x20],
- mapper: &'a RefCell<&'a mut Mapper>,
+ mapper: &'a RefMapper<'a>
}
impl<'a> PPUMemory<'a> {
- pub fn new(mapper: &'a RefCell<&'a mut Mapper>) -> Self {
+ pub fn new(mapper: &'a RefMapper<'a>) -> Self {
PPUMemory{
nametable: [0; 0x800],
palette: [0; 0x20],
@@ -257,7 +257,7 @@ fn get_mirror_palette(addr: u16) -> u16 {
impl<'a> PPUMemory<'a> {
#[inline(always)]
pub fn read_nametable(&self, addr: u16) -> u8 {
- let mt = self.mapper.borrow().get_cart().get_mirror_type();
+ let mt = self.mapper.get_cart().get_mirror_type();
self.nametable[(get_mirror_addr(mt, addr) & 0x7ff) as usize]
}
@@ -268,7 +268,7 @@ impl<'a> PPUMemory<'a> {
#[inline(always)]
pub fn write_nametable(&mut self, addr: u16, data: u8) {
- let mt = self.mapper.borrow().get_cart().get_mirror_type();
+ let mt = self.mapper.get_cart().get_mirror_type();
self.nametable[(get_mirror_addr(mt, addr) & 0x7ff) as usize] = data
}
@@ -279,17 +279,17 @@ impl<'a> PPUMemory<'a> {
#[inline(always)]
pub fn read_mapper(&self, addr: u16) -> u8 {
- self.mapper.borrow().read(addr)
+ self.mapper.read(addr)
}
#[inline(always)]
fn write_mapper(&self, addr: u16, data: u8) {
- self.mapper.borrow_mut().write(addr, data)
+ self.mapper.get_mut().write(addr, data)
}
#[inline(always)]
pub fn tick(&self, bus: &CPUBus) {
- self.mapper.borrow_mut().tick(bus)
+ self.mapper.get_mut().tick(bus)
}
}