From d77c884c4e0826e80a3eda01a129a2792ae509f5 Mon Sep 17 00:00:00 2001 From: Determinant Date: Thu, 4 Jan 2018 15:40:18 +0800 Subject: remove RefCell in memory/mapper to improve performance --- src/bin.rs | 3 +-- src/mapper.rs | 24 ++++++++++++++++++++++++ src/memory.rs | 24 ++++++++++++------------ 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) } } -- cgit v1.2.3