diff --git a/src/addressSpace.hpp b/src/addressSpace.hpp index b87b84f..cac6c99 100644 --- a/src/addressSpace.hpp +++ b/src/addressSpace.hpp @@ -97,7 +97,10 @@ public: Byte *MBCRead(Word address); // prevents seg faults when programs with no MBC try to write to ROM Byte dummyVal = 0; + + // called after every op void MBCUpdate(); + void loadRomBank(); void createRamBank(); void loadRamBank(); @@ -110,6 +113,7 @@ public: bool dmaTransferRequested = false; void dmaTransfer(); + // MBC registers // Selected ROM Bank = (Secondary Bank << 5) + ROM Bank Byte selectedRomBank = 0; Byte romBankRegister = 0x00; @@ -117,6 +121,10 @@ public: Byte twoBitBankRegister = 0x0; Byte selectedExternalRamBank = 0; Byte romRamSelect = 0x00; + // 0xA if enabled in MBC1/3, else off + // in MBC2 also the rom bank number + // in MBC3 also timer enable + // reading ram while disabled is undefined behaviour Byte ramEnable = 0x00; // MBC3 Byte latchClockData = 0x00; @@ -139,6 +147,9 @@ public: if (address < 0xC000) { if (externalRamSize == 0) return 0xFF; + // MBC2 echos 15 times and only stores lower 4 bits + if (MBC == MBC2 || MBC == MBC2Battery) + return memoryLayout.externalRam[(address - 0xA000) & 0x01FF] | 0xF0; return memoryLayout.externalRam[address - 0xA000]; } if (address < 0xD000) diff --git a/src/mbc.cpp b/src/mbc.cpp index f0016bf..3fd40e9 100644 --- a/src/mbc.cpp +++ b/src/mbc.cpp @@ -64,6 +64,14 @@ Byte *AddressSpace::MBCRead(const Word address) { if (address <= 0x7FFF) return &romRamSelect; } + if (MBC == MBC2 || MBC == MBC2Battery) { + if (address <= 0x3FFF) { + if (address & 0x0100) + return &romBankRegister; + else + return &ramEnable; + } + } return &dummyVal; } @@ -93,8 +101,7 @@ void AddressSpace::MBCUpdate() { loadRomBank(); loadRamBank(); - } - if (MBC == MBC1Ram || MBC == MBC1RamBattery) { + } else if (MBC == MBC1Ram || MBC == MBC1RamBattery) { // Selected ROM Bank = (Secondary Bank << 5) + ROM Bank romBankRegister &= 0b11111; twoBitBankRegister &= 0b11; @@ -119,7 +126,9 @@ void AddressSpace::MBCUpdate() { loadRomBank(); loadRamBank(); } else if (MBC == MBC2 || MBC == MBC2Battery) { - // TODO + selectedRomBank = romBankRegister & 0x0F; + loadRomBank(); + loadRamBank(); } else if (MBC == MBC3 || MBC == MBC3TimerBattery) { romBankRegister &= 0b11111; twoBitBankRegister &= 0b11; @@ -168,7 +177,8 @@ void AddressSpace::createRamBank() { } void AddressSpace::loadRamBank() { - if (cartridgeRam != nullptr) + if (cartridgeRam != nullptr) { memoryLayout.externalRam = cartridgeRam + (RAM_BANK_SIZE * selectedExternalRamBank); + } }