diff --git a/fpt/src/memory/mbc0.rs b/fpt/src/memory/mbc0.rs new file mode 100644 index 0000000..84c8393 --- /dev/null +++ b/fpt/src/memory/mbc0.rs @@ -0,0 +1,22 @@ +/// Memory controller 0. No memory controller + +use crate::memory::GBAddress; +use crate::memory::MemoryController; + +pub struct Mbc0 {} + +impl Mbc0 { + pub fn new() -> Mbc0 { + Mbc0 {} + } +} + +impl MemoryController for Mbc0 { + fn write(&mut self, address: GBAddress, value: u8, cartridge: &mut Vec) { + cartridge[address] = value + } + + fn read(&self, address: GBAddress, cartridge: &Vec) -> u8 { + cartridge[address] + } +} diff --git a/fpt/src/memory/mbc1.rs b/fpt/src/memory/mbc1.rs index 3840cd2..1ce4afe 100644 --- a/fpt/src/memory/mbc1.rs +++ b/fpt/src/memory/mbc1.rs @@ -1,12 +1,29 @@ -struct Mbc1 {} +use crate::memory::GBAddress; +use crate::memory::MemoryController; -impl MemoryController for Mbc1 { - fn write(&mut self, _address: GBAddress, value: u8) { +pub struct Mbc1 {} +impl Mbc1 { + pub fn new() -> Mbc1 { + Mbc1 {} } +} - fn read(&self, _address: GBAdress) -> u8 { +impl MemoryController for Mbc1 { + fn write(&mut self, address: GBAddress, value: u8, cartridge: &mut Vec) { + if 0x0000 <= address && address <= 0x1fff { + if value & 0xF == 0xA { + // ram enable + } else { + // ram disable + } + } else if 0x2000 <= address && address <= 0x3fff { + let rom_select = value & 0x1F; + } else if 0x4000 <= address && address <= 0x5fff { + } + } + fn read(&self, _address: GBAddress, cartridge: &Vec) -> u8 { + 0 } } - diff --git a/fpt/src/memory/memory.rs b/fpt/src/memory/memory.rs index 11f24fb..361fbb4 100644 --- a/fpt/src/memory/memory.rs +++ b/fpt/src/memory/memory.rs @@ -1,3 +1,5 @@ +use crate::memory::Mbc1; +use crate::memory::MemoryController; use std::cell::{RefCell, RefMut}; use std::ops::Range; use std::rc::Rc; @@ -60,11 +62,12 @@ pub mod map { pub const INTERRUPT_SWITCH: Address = 0xFFFF; } -#[derive(Clone)] +//#[derive(Clone)] pub struct Memory { mem: [u8; 65536], cartridge: Vec, bootrom: [u8; 256], + memory_controller: Box, } impl PartialEq for Memory { @@ -85,9 +88,19 @@ impl Memory { mem: [0; 65536], cartridge: Vec::new(), bootrom: [0; 256], + memory_controller: Box::new(Mbc1::new()), } } + pub fn read(&self, address: GBAddress) -> u8 { + self.memory_controller.read(address, &self.cartridge) + } + + pub fn write(&mut self, address: GBAddress, value: u8) { + self.memory_controller + .write(address, value, &mut self.cartridge) + } + pub fn slice(&self, range: MemoryRange) -> &[u8] { &self.mem[range.start..range.end] } @@ -137,11 +150,11 @@ impl Bus { } fn _read(&self, address: Address) -> u8 { - self.memory().mem[address] + self.memory().read(address as GBAddress) } fn _write(&mut self, address: Address, value: u8) { - self.memory().mem[address] = value; + self.memory().write(address as GBAddress, value); } pub fn clone_from_slice(&mut self, range: MemoryRange, slice: &[u8]) { diff --git a/fpt/src/memory/memory_controller.rs b/fpt/src/memory/memory_controller.rs index 653b30d..af8981d 100644 --- a/fpt/src/memory/memory_controller.rs +++ b/fpt/src/memory/memory_controller.rs @@ -1,4 +1,6 @@ -trait MemoryController { - fn write(&mut self, address: GBAddress, value: u8); - fn read(&self, address: GBAddress) -> u8; -} \ No newline at end of file +use crate::memory::GBAddress; + +pub trait MemoryController { + fn write(&mut self, address: GBAddress, value: u8, cartridge: &mut Vec); + fn read(&self, address: GBAddress, cartridge: &Vec) -> u8; +} diff --git a/fpt/src/memory/mod.rs b/fpt/src/memory/mod.rs index c65f7bc..f5dcb11 100644 --- a/fpt/src/memory/mod.rs +++ b/fpt/src/memory/mod.rs @@ -1,3 +1,7 @@ +mod mbc1; mod memory; +mod memory_controller; -pub use memory::Bus; +pub use mbc1::Mbc1; +pub use memory::{Bus, GBAddress}; +pub use memory_controller::MemoryController;