start of mbc3

This commit is contained in:
2026-01-30 16:18:01 -08:00
parent ab258d177e
commit 712ee55e7b
2 changed files with 150 additions and 111 deletions

View File

@@ -92,7 +92,7 @@ public:
void loadGame(const std::string& filename); void loadGame(const std::string& filename);
void determineMBCInfo(); void determineMBCInfo();
static bool testMBCWrite(Word address); bool MBCWrite(Word address);
Byte* MBCRead(Word address); Byte* MBCRead(Word address);
//prevents seg faults when programs with no MBC try to write to ROM //prevents seg faults when programs with no MBC try to write to ROM
Byte dummyVal = 0; Byte dummyVal = 0;

View File

@@ -30,18 +30,18 @@ void AddressSpace::determineMBCInfo() {
} }
if (MBC == MBC2 || MBC == MBC2Battery) { if (MBC == MBC2 || MBC == MBC2Battery) {
//only the lower 4 bits are usable // only the lower 4 bits are usable
externalRamSize = 512; externalRamSize = 512;
} }
} }
bool AddressSpace::testMBCWrite(const Word address) { bool AddressSpace::MBCWrite(const Word address) {
if (address <= 0x7FFF) if (address <= 0x7FFF)
return true; return true;
return false; return false;
} }
Byte* AddressSpace::MBCRead(const Word address) { Byte *AddressSpace::MBCRead(const Word address) {
if (MBC == MBC1) { if (MBC == MBC1) {
if (address <= 0x1FFF) if (address <= 0x1FFF)
return &ramEnable; return &ramEnable;
@@ -55,7 +55,7 @@ Byte* AddressSpace::MBCRead(const Word address) {
if (MBC == MBC1Ram || MBC == MBC1RamBattery) { if (MBC == MBC1Ram || MBC == MBC1RamBattery) {
if (address <= 0x1FFF) if (address <= 0x1FFF)
return &ramEnable; return &ramEnable;
//bits 0-4 // bits 0-4
if (address <= 0x3FFF) if (address <= 0x3FFF)
return &romBankRegister; return &romBankRegister;
if (address <= 0x5FFF) { if (address <= 0x5FFF) {
@@ -68,51 +68,91 @@ Byte* AddressSpace::MBCRead(const Word address) {
} }
void AddressSpace::MBCUpdate() { void AddressSpace::MBCUpdate() {
//TODO: multicart roms need to be able to switch the first rom bank as well // TODO: multicart roms need to be able to switch the first rom bank as well
//see: https://gbdev.io/pandocs/MBC1.html // see: https://gbdev.io/pandocs/MBC1.html
if (MBC == MBC1) { if (MBC == MBC1) {
//Selected ROM Bank = (Secondary Bank << 5) + ROM Bank // Selected ROM Bank = (Secondary Bank << 5) + ROM Bank
romBankRegister &= 0x1F; romBankRegister &= 0b11111;
twoBitBankRegister &= 0x3; twoBitBankRegister &= 0b11;
//512 KiB can only have 8KiB of ram // 512 KiB can only have 8KiB of ram
if (romSize >= 524288) { if (romSize >= 524288) {
if (romBankRegister == 0) if (romBankRegister == 0)
selectedRomBank = (twoBitBankRegister << 5) + 1; selectedRomBank = (twoBitBankRegister << 5) + 1;
selectedRomBank = (twoBitBankRegister << 5) + romBankRegister; selectedRomBank = (twoBitBankRegister << 5) + romBankRegister;
} } else {
else {
if (romBankRegister == 0) if (romBankRegister == 0)
selectedRomBank = 1; selectedRomBank = 1;
else else
selectedRomBank = romBankRegister; selectedRomBank = romBankRegister;
} }
if (romBankRegister == 0x20 || romBankRegister == 0x40 ||
romBankRegister == 0x60)
romBankRegister += 1;
selectedExternalRamBank = 0; selectedExternalRamBank = 0;
loadRomBank(); loadRomBank();
loadRamBank(); loadRamBank();
} }
if (MBC == MBC1Ram || MBC == MBC1RamBattery) { if (MBC == MBC1Ram || MBC == MBC1RamBattery) {
//Selected ROM Bank = (Secondary Bank << 5) + ROM Bank // Selected ROM Bank = (Secondary Bank << 5) + ROM Bank
romBankRegister &= 0x1F; romBankRegister &= 0b11111;
twoBitBankRegister &= 0x3; twoBitBankRegister &= 0b11;
//512 KiB can only have 8KiB of ram // 512 KiB can only have 8KiB of ram
if (romSize >= 524288) { if (romSize >= 524288) {
if (romBankRegister == 0) if (romBankRegister == 0)
selectedRomBank = (twoBitBankRegister << 5) + 1; selectedRomBank = (twoBitBankRegister << 5) + 1;
selectedRomBank = (twoBitBankRegister << 5) + romBankRegister; selectedRomBank = (twoBitBankRegister << 5) + romBankRegister;
selectedExternalRamBank = 0; selectedExternalRamBank = 0;
} } else {
else {
if (romBankRegister == 0) if (romBankRegister == 0)
selectedRomBank = 1; selectedRomBank = 1;
else else
selectedRomBank = romBankRegister; selectedRomBank = romBankRegister;
selectedExternalRamBank = twoBitBankRegister; selectedExternalRamBank = twoBitBankRegister;
} }
if (romBankRegister == 0x20 || romBankRegister == 0x40 ||
romBankRegister == 0x60)
romBankRegister += 1;
loadRomBank(); loadRomBank();
loadRamBank(); loadRamBank();
} else if (MBC == MBC2 || MBC == MBC2Battery) {
// TODO
} else if (MBC == MBC3 || MBC == MBC3TimerBattery) {
romBankRegister &= 0b11111;
twoBitBankRegister &= 0b11;
// 512 KiB can only have 8KiB of ram
if (romSize >= 524288) {
if (romBankRegister == 0)
selectedRomBank = (twoBitBankRegister << 5) + 1;
selectedRomBank = (twoBitBankRegister << 5) + romBankRegister;
} else {
if (romBankRegister == 0)
selectedRomBank = 1;
else
selectedRomBank = romBankRegister;
}
} else if (MBC == MBC3Ram || MBC == MBC3RamBattery ||
MBC == MBC3TimerRamBattery) {
romBankRegister &= 0b11111;
twoBitBankRegister &= 0b11;
// 512 KiB can only have 8KiB of ram
if (romSize >= 524288) {
if (romBankRegister == 0)
selectedRomBank = (twoBitBankRegister << 5) + 1;
selectedRomBank = (twoBitBankRegister << 5) + romBankRegister;
selectedExternalRamBank = 0;
} else {
if (romBankRegister == 0)
selectedRomBank = 1;
else
selectedRomBank = romBankRegister;
selectedExternalRamBank = twoBitBankRegister;
}
} }
} }
@@ -129,7 +169,6 @@ void AddressSpace::createRamBank() {
void AddressSpace::loadRamBank() { void AddressSpace::loadRamBank() {
if (cartridgeRam != nullptr) if (cartridgeRam != nullptr)
memoryLayout.externalRam = cartridgeRam + (RAM_BANK_SIZE * selectedExternalRamBank); memoryLayout.externalRam =
cartridgeRam + (RAM_BANK_SIZE * selectedExternalRamBank);
} }