aboutsummaryrefslogtreecommitdiff
path: root/src/mapper.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/mapper.rs')
-rw-r--r--src/mapper.rs137
1 files changed, 125 insertions, 12 deletions
diff --git a/src/mapper.rs b/src/mapper.rs
index 4ecebbf..3d72189 100644
--- a/src/mapper.rs
+++ b/src/mapper.rs
@@ -3,10 +3,13 @@ extern crate core;
use core::cell::UnsafeCell;
use memory::{VMem, CPUBus};
use cartridge::{Cartridge, BankType, MirrorType};
+use utils::{Read, Write, load_prefix, save_prefix};
pub trait Mapper : VMem {
fn get_cart(&self) -> &Cartridge;
fn tick(&mut self, _bus: &CPUBus) {}
+ fn load(&mut self, reader: &mut Read) -> bool;
+ fn save(&self, writer: &mut Write) -> bool;
}
pub struct RefMapper<'a> {
@@ -93,10 +96,10 @@ impl<'a, C> Mapper1<'a, C> where C: Cartridge {
c.get_bank((prg_nbank - 1) << 14, 0x4000, BankType::PrgRom)
];
m.chr_banks = [
- c.get_bank(0, 0x1000, BankType::ChrRom),
- c.get_bank(0x1000, 0x1000, BankType::ChrRom)
+ c.get_bank_mut(0, 0x1000, BankType::ChrRom),
+ c.get_bank_mut(0x1000, 0x1000, BankType::ChrRom)
];
- m.sram = c.get_bank(0, 0x2000, BankType::Sram);
+ m.sram = c.get_bank_mut(0, 0x2000, BankType::Sram);
}
m
}
@@ -128,18 +131,18 @@ impl<'a, C> Mapper1<'a, C> where C: Cartridge {
0x0 => {
let base = ((load_reg & 0xfe) as usize % self.chr_nbank) << 13;
self.chr_banks = [
- self.cart.get_bank(base, 0x1000, BankType::ChrRom),
- self.cart.get_bank(base + 0x1000, 0x1000, BankType::ChrRom)];
+ self.cart.get_bank_mut(base, 0x1000, BankType::ChrRom),
+ self.cart.get_bank_mut(base + 0x1000, 0x1000, BankType::ChrRom)];
},
_ =>
- self.chr_banks[0] = self.cart.get_bank(
+ self.chr_banks[0] = self.cart.get_bank_mut(
(load_reg as usize % (self.chr_nbank << 1)) << 12,
0x1000, BankType::ChrRom)
}
},
0x2 => {
if (self.ctl_reg >> 4) & 1 == 1 {
- self.chr_banks[1] = self.cart.get_bank(
+ self.chr_banks[1] = self.cart.get_bank_mut(
(load_reg as usize % (self.chr_nbank << 1)) << 12,
0x1000, BankType::ChrRom)
}
@@ -174,6 +177,42 @@ impl<'a, C> Mapper1<'a, C> where C: Cartridge {
impl<'a, C> Mapper for Mapper1<'a, C> where C: Cartridge {
fn get_cart(&self) -> &Cartridge {&self.cart}
+
+ fn load(&mut self, reader: &mut Read) -> bool {
+ for v in self.prg_banks.iter_mut() {
+ let mut offset: usize = 0;
+ if !load_prefix(&mut offset, 0, reader) { return false }
+ *v = self.cart.get_bank(offset, 0x4000, BankType::PrgRom);
+ }
+ for v in self.chr_banks.iter_mut() {
+ let mut offset: usize = 0;
+ if !load_prefix(&mut offset, 0, reader) { return false }
+ *v = self.cart.get_bank_mut(offset, 0x1000, BankType::ChrRom);
+ }
+ load_prefix(&mut self.ctl_reg, 0, reader) &&
+ load_prefix(&mut self.load_reg, 0, reader) &&
+ self.cart.load(reader)
+ }
+
+ fn save(&self, writer: &mut Write) -> bool {
+ let prg_base = self.cart.get_bank(0, 0, BankType::PrgRom).as_ptr();
+ let chr_base = self.cart.get_bank(0, 0, BankType::ChrRom).as_ptr();
+ for v in self.prg_banks.iter() {
+ if !save_prefix(&(v.as_ptr() as usize - prg_base as usize),
+ 0, writer) {
+ return false
+ }
+ }
+ for v in self.chr_banks.iter() {
+ if !save_prefix(&(v.as_ptr() as usize - chr_base as usize),
+ 0, writer) {
+ return false
+ }
+ }
+ save_prefix(&self.ctl_reg, 0, writer) &&
+ save_prefix(&self.load_reg, 0, writer) &&
+ self.cart.save(writer)
+ }
}
pub struct Mapper2<'a, C> where C: Cartridge {
@@ -233,8 +272,8 @@ impl<'a, C> Mapper2<'a, C> where C: Cartridge {
c.get_bank(0, 0x4000, BankType::PrgRom),
c.get_bank((nbank - 1) << 14, 0x4000, BankType::PrgRom)
];
- m.chr_bank = c.get_bank(0, 0x2000, BankType::ChrRom);
- m.sram = c.get_bank(0, 0x2000, BankType::Sram);
+ m.chr_bank = c.get_bank_mut(0, 0x2000, BankType::ChrRom);
+ m.sram = c.get_bank_mut(0, 0x2000, BankType::Sram);
}
m
}
@@ -243,6 +282,34 @@ impl<'a, C> Mapper2<'a, C> where C: Cartridge {
impl<'a, C> Mapper for Mapper2<'a, C> where C: Cartridge {
fn get_cart(&self) -> &Cartridge {&self.cart}
+
+ fn load(&mut self, reader: &mut Read) -> bool {
+ for v in self.prg_banks.iter_mut() {
+ let mut offset: usize = 0;
+ if !load_prefix(&mut offset, 0, reader) { return false }
+ *v = self.cart.get_bank(offset, 0x4000, BankType::PrgRom);
+ }
+ let mut offset: usize = 0;
+ if !load_prefix(&mut offset, 0, reader) { return false }
+ self.chr_bank = self.cart.get_bank_mut(offset, 0x2000, BankType::ChrRom);
+ self.cart.load(reader)
+ }
+
+ fn save(&self, writer: &mut Write) -> bool {
+ let prg_base = self.cart.get_bank(0, 0, BankType::PrgRom).as_ptr();
+ let chr_base = self.cart.get_bank(0, 0, BankType::ChrRom).as_ptr();
+ for v in self.prg_banks.iter() {
+ if !save_prefix(&(v.as_ptr() as usize - prg_base as usize),
+ 0, writer) {
+ return false
+ }
+ }
+ if !save_prefix(&(self.chr_bank.as_ptr() as usize - chr_base as usize),
+ 0, writer) {
+ return false
+ }
+ self.cart.save(writer)
+ }
}
pub struct Mapper4<'a, C> where C: Cartridge {
@@ -336,13 +403,13 @@ impl<'a, C> Mapper4<'a, C> where C: Cartridge {
}
#[inline(always)]
- fn get_prgbank<'b>(&mut self, idx: u8) -> &'b mut [u8] {
+ fn get_prgbank<'b>(&self, idx: u8) -> &'b [u8] {
self.cart.get_bank(0x2000 * idx as usize, 0x2000, BankType::PrgRom)
}
#[inline(always)]
fn get_chrbank<'b>(&mut self, idx: u8) -> &'b mut [u8] {
- self.cart.get_bank(0x400 * idx as usize, 0x400, BankType::ChrRom)
+ self.cart.get_bank_mut(0x400 * idx as usize, 0x400, BankType::ChrRom)
}
fn update_banks(&mut self) {
@@ -424,7 +491,7 @@ impl<'a, C> Mapper4<'a, C> where C: Cartridge {
m.get_chrbank(0)];
{
let c = &mut m.cart;
- m.sram = c.get_bank(0, 0x2000, BankType::Sram);
+ m.sram = c.get_bank_mut(0, 0x2000, BankType::Sram);
}
m
}
@@ -453,4 +520,50 @@ impl<'a, C> Mapper for Mapper4<'a, C> where C: Cartridge {
}
}
}
+
+ fn load(&mut self, reader: &mut Read) -> bool {
+ for v in self.prg_banks.iter_mut() {
+ let mut offset: usize = 0;
+ if !load_prefix(&mut offset, 0, reader) { return false }
+ *v = self.cart.get_bank(offset, 0x2000, BankType::PrgRom);
+ }
+ for v in self.chr_banks.iter_mut() {
+ let mut offset: usize = 0;
+ if !load_prefix(&mut offset, 0, reader) { return false }
+ *v = self.cart.get_bank_mut(offset, 0x400, BankType::ChrRom);
+ }
+ load_prefix(&mut self.chr_inv, 0, reader) &&
+ load_prefix(&mut self.prg_mode, 0, reader) &&
+ load_prefix(&mut self.reg_idx, 0, reader) &&
+ load_prefix(&mut self.regs, 0, reader) &&
+ load_prefix(&mut self.irq_reload, 0, reader) &&
+ load_prefix(&mut self.irq_counter, 0, reader) &&
+ load_prefix(&mut self.irq_enable, 0, reader) &&
+ self.cart.load(reader)
+ }
+
+ fn save(&self, writer: &mut Write) -> bool {
+ let prg_base = self.cart.get_bank(0, 0, BankType::PrgRom).as_ptr();
+ let chr_base = self.cart.get_bank(0, 0, BankType::ChrRom).as_ptr();
+ for v in self.prg_banks.iter() {
+ if !save_prefix(&(v.as_ptr() as usize - prg_base as usize),
+ 0, writer) {
+ return false
+ }
+ }
+ for v in self.chr_banks.iter() {
+ if !save_prefix(&(v.as_ptr() as usize - chr_base as usize),
+ 0, writer) {
+ return false
+ }
+ }
+ save_prefix(&self.chr_inv, 0, writer) &&
+ save_prefix(&self.prg_mode, 0, writer) &&
+ save_prefix(&self.reg_idx, 0, writer) &&
+ save_prefix(&self.regs, 0, writer) &&
+ save_prefix(&self.irq_reload, 0, writer) &&
+ save_prefix(&self.irq_counter, 0, writer) &&
+ save_prefix(&self.irq_enable, 0, writer) &&
+ self.cart.save(writer)
+ }
}