#![allow(dead_code)]
extern crate core;
use core::cell::UnsafeCell;
use memory::{VMem, CPUBus};
use cartridge::{Cartridge, BankType, MirrorType};
pub trait Mapper : VMem {
fn get_cart(&self) -> &Cartridge;
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],
chr_banks: [&'a mut [u8]; 2],
sram: &'a mut [u8],
ctl_reg: u8,
load_reg: u8,
prg_nbank: usize, /* num of 16k PRG ROM banks */
chr_nbank: usize /* num of 8k PRG ROM banks */
}
impl<'a, C> VMem for Mapper1<'a, C> where C: Cartridge {
fn read(&self, addr: u16) -> u8 {
let addr = addr as usize;
match addr >> 12 {
/* [0x0000..0x2000) */
0 | 1 => self.chr_banks[(addr >> 12) & 1][addr & 0xfff],
/* [0x2000..0x6000) */
2 | 3 | 4 | 5 => panic!("unmapped address: 0x{:04x}", addr),
/* [0x6000..0x8000) */
6 | 7 => self.sram[addr - 0x6000],
/* [0x8000..0xffff] */
_ => self.prg_banks[(addr >> 14) & 1][addr & 0x3fff]
}
}
fn write(&mut self, addr: u16, data: u8) {
let addr = addr as usize;
match addr >> 12 {
/* [0x0000..0x2000) */
0 | 1 => self.chr_banks[(addr >> 12) & 1][addr & 0xfff] = data,
/* [0x2000..0x6000) */
2 | 3 | 4 | 5 => panic!("unmapped address: 0x{:04x}", addr),
/* [0x6000..0x8000) */
6 | 7 => self.sram[addr - 0x6000] = <