Add support for MBC1.
TODO: Refactor the cartridge code
This commit is contained in:
parent
1e04879770
commit
6455732043
@ -25,6 +25,9 @@ pub struct Cartridge {
|
|||||||
|
|
||||||
ram_size: RamSize,
|
ram_size: RamSize,
|
||||||
rom_banks: u16,
|
rom_banks: u16,
|
||||||
|
|
||||||
|
bank_mode: u8,
|
||||||
|
bank_no_high: u8,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Cartridge {
|
impl Cartridge {
|
||||||
@ -77,15 +80,18 @@ impl Cartridge {
|
|||||||
ram_size: ram_size,
|
ram_size: ram_size,
|
||||||
rom_banks: rom_banks,
|
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 {
|
match addr {
|
||||||
0x0000 ... 0x3FFF => self.rom[addr as usize],
|
0x0000 ... 0x3FFF => self.rom[addr as usize],
|
||||||
0x4000 ... 0x7FFF => {
|
0x4000 ... 0x7FFF => {
|
||||||
let addr = addr - 0x4000;
|
let addr = addr - 0x4000;
|
||||||
|
println!("BankNo: {:02X}", self.bank_no);
|
||||||
let abs_addr: usize = addr as usize + self.bank_no as usize * 0x4000;
|
let abs_addr: usize = addr as usize + self.bank_no as usize * 0x4000;
|
||||||
let val: u8 = self.rom[abs_addr];
|
let val: u8 = self.rom[abs_addr];
|
||||||
val
|
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) {
|
fn write_byte_none(&mut self, addr: u16, val: u8) {
|
||||||
match addr {
|
match addr {
|
||||||
0xA000 ... 0xBFFF => {
|
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) {
|
fn write_byte_mbc3(&mut self, addr: u16, val: u8) {
|
||||||
match addr {
|
match addr {
|
||||||
0x0000 ... 0x1FFF => {
|
0x0000 ... 0x1FFF => {
|
||||||
@ -154,6 +218,7 @@ impl Cartridge {
|
|||||||
pub fn write_byte(&mut self, addr: u16, val: u8) {
|
pub fn write_byte(&mut self, addr: u16, val: u8) {
|
||||||
match self.mbc_type {
|
match self.mbc_type {
|
||||||
MemoryBankControllerType::None => self.write_byte_none(addr, val),
|
MemoryBankControllerType::None => self.write_byte_none(addr, val),
|
||||||
|
MemoryBankControllerType::MBC1 => self.write_byte_mbc1(addr, val),
|
||||||
MemoryBankControllerType::MBC3 => self.write_byte_mbc3(addr, val),
|
MemoryBankControllerType::MBC3 => self.write_byte_mbc3(addr, val),
|
||||||
_ => panic!("MBC not supported.")
|
_ => panic!("MBC not supported.")
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user