Add support for MBC1.

TODO: Refactor the cartridge code
This commit is contained in:
Kevin Hamacher 2016-05-29 18:36:40 +02:00
parent 1e04879770
commit 6455732043

View File

@ -25,6 +25,9 @@ pub struct Cartridge {
ram_size: RamSize,
rom_banks: u16,
bank_mode: u8,
bank_no_high: u8,
}
impl Cartridge {
@ -77,15 +80,18 @@ impl Cartridge {
ram_size: ram_size,
rom_banks: rom_banks,
ram: ram
ram: ram,
bank_mode: 0,
bank_no_high: 0,
}
}
pub fn read_byte(&self, addr: u16) -> u8 {
pub fn read_byte_mbc3(&self, addr: u16) -> u8 {
match addr {
0x0000 ... 0x3FFF => self.rom[addr as usize],
0x4000 ... 0x7FFF => {
let addr = addr - 0x4000;
println!("BankNo: {:02X}", self.bank_no);
let abs_addr: usize = addr as usize + self.bank_no as usize * 0x4000;
let val: u8 = self.rom[abs_addr];
val
@ -106,6 +112,43 @@ impl Cartridge {
}
}
pub fn read_byte_mbc1(&self, addr: u16) -> u8 {
match addr {
0x0000 ... 0x3FFF => self.rom[addr as usize],
0x4000 ... 0x7FFF => {
let addr = addr - 0x4000;
let mut bank: u8 = self.bank_no;
if self.bank_mode == 0 {
bank |= self.bank_no_high << 5;
}
println!("BankNo: {:02X}", bank);
let abs_addr: usize = addr as usize + bank as usize * 0x4000;
let val: u8 = self.rom[abs_addr];
val
},
0xA000 ... 0xBFFF => {
// TODO: Safty checks? Or let rust handle this?
let addr = addr - 0xA000;
let mut bank: u8 = 0;
if self.bank_mode == 1 {
bank = self.bank_no_high
}
self.ram[bank as usize * 0x2000 + addr as usize]
}
_ => {
panic!("Cartride: Unable to read from {:04X}", addr);
}
}
}
pub fn read_byte(&self, addr: u16) -> u8{
match self.mbc_type {
MemoryBankControllerType::MBC1 => self.read_byte_mbc1(addr),
MemoryBankControllerType::MBC3 | MemoryBankControllerType::None => self.read_byte_mbc3(addr),
_ => panic!("MBC not supported.")
}
}
fn write_byte_none(&mut self, addr: u16, val: u8) {
match addr {
0xA000 ... 0xBFFF => {
@ -116,6 +159,27 @@ impl Cartridge {
}
}
fn write_byte_mbc1(&mut self, addr: u16, val: u8) {
match addr {
0x2000 ... 0x3FFF => {
// Write low bits of addr.
self.bank_no &= 0xE0;
self.bank_no |= val & 0x1F;
// Can't select 0x00, 0x20, 0x40, 0x60. Adapt it to 0x01, 0x21, 0x41, 0x61
if self.bank_no & 0x1F == 0 {
self.bank_no |= 1;
}
}
0x4000 ... 0x5FFF => {
self.bank_no_high = val & 3;
}
0x6000 ... 0x7FFF => {
self.bank_mode = val & 1;
}
_ => panic!("MBC1 Write {:02X} to {:04X} unsupported", val, addr),
}
}
fn write_byte_mbc3(&mut self, addr: u16, val: u8) {
match addr {
0x0000 ... 0x1FFF => {
@ -154,6 +218,7 @@ impl Cartridge {
pub fn write_byte(&mut self, addr: u16, val: u8) {
match self.mbc_type {
MemoryBankControllerType::None => self.write_byte_none(addr, val),
MemoryBankControllerType::MBC1 => self.write_byte_mbc1(addr, val),
MemoryBankControllerType::MBC3 => self.write_byte_mbc3(addr, val),
_ => panic!("MBC not supported.")
}