more MBC3 work

This commit is contained in:
2026-03-17 01:46:28 -07:00
parent 037ba0c76d
commit 80e23312de
3 changed files with 48 additions and 69 deletions

View File

@@ -19,7 +19,11 @@ add_executable(GameBoy++ src/main.cpp
src/testing.hpp src/testing.hpp
src/joypad.cpp src/joypad.cpp
) )
target_compile_options(GameBoy++ PRIVATE -O2)
target_link_libraries(GameBoy++ ${SDL2_LIBRARIES}) target_link_libraries(GameBoy++ ${SDL2_LIBRARIES})
target_compile_options(GameBoy++ PRIVATE
$<$<CONFIG:Release>:-O2>
)
if(CMAKE_EXPORT_COMPILE_COMMANDS) if(CMAKE_EXPORT_COMPILE_COMMANDS)
add_custom_target(copy_compile_commands ALL add_custom_target(copy_compile_commands ALL

View File

@@ -93,8 +93,7 @@ public:
void loadGame(const std::string &filename); void loadGame(const std::string &filename);
void determineMBCInfo(); void determineMBCInfo();
bool MBCWrite(Word address); Byte *MBCWrite(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;
@@ -114,10 +113,10 @@ public:
void dmaTransfer(); void dmaTransfer();
// MBC registers // MBC registers
// Selected ROM Bank = (Secondary Bank << 5) + ROM Bank // Selected ROM Bank in MBC1 = (Secondary Bank << 5) + ROM Bank
Byte selectedRomBank = 0; Byte selectedRomBank = 0;
Byte romBankRegister = 0x00; Byte romBankRegister = 0x00;
// 2 bit register acts as secondary rom bank register or ram bank number // 2 bit register acts as secondary rom bank register or ram bank number in MBC1
Byte twoBitBankRegister = 0x0; Byte twoBitBankRegister = 0x0;
Byte selectedExternalRamBank = 0; Byte selectedExternalRamBank = 0;
Byte romRamSelect = 0x00; Byte romRamSelect = 0x00;
@@ -138,34 +137,33 @@ public:
return testRam[address]; return testRam[address];
if (address < 0x0100 && bootromLoaded) if (address < 0x0100 && bootromLoaded)
return bootrom[address]; return bootrom[address];
if (address < 0x4000) else if (address < 0x4000)
return memoryLayout.romBank0[address]; return memoryLayout.romBank0[address];
if (address < 0x8000) else if (address < 0x8000)
return memoryLayout.romBankSwitch[address - 0x4000]; return memoryLayout.romBankSwitch[address - 0x4000];
if (address < 0xA000) else if (address < 0xA000)
return memoryLayout.vram[address - 0x8000]; return memoryLayout.vram[address - 0x8000];
if (address < 0xC000) { else if (address < 0xC000) {
if (externalRamSize == 0) if (externalRamSize == 0)
return 0xFF; return 0xFF;
// MBC2 echos 15 times and only stores lower 4 bits // MBC2 echos 15 times and only stores lower 4 bits
if (MBC == MBC2 || MBC == MBC2Battery) else if (MBC == MBC2 || MBC == MBC2Battery)
return memoryLayout.externalRam[(address - 0xA000) & 0x01FF] | 0xF0; return memoryLayout.externalRam[(address - 0xA000) & 0x01FF] | 0xF0;
else
return memoryLayout.externalRam[address - 0xA000]; return memoryLayout.externalRam[address - 0xA000];
} } else if (address < 0xD000)
if (address < 0xD000)
return memoryLayout.memoryBank1[address - 0xC000]; return memoryLayout.memoryBank1[address - 0xC000];
if (address < 0xE000) else if (address < 0xE000)
return memoryLayout.memoryBank2[address - 0xD000]; return memoryLayout.memoryBank2[address - 0xD000];
if (address < 0xFE00) else if (address < 0xFE00)
return memoryLayout.memoryBank1[address - 0xE000]; return memoryLayout.memoryBank1[address - 0xE000];
if (address < 0xFEA0) else if (address < 0xFEA0)
return memoryLayout.oam[address - 0xFE00]; return memoryLayout.oam[address - 0xFE00];
if (address < 0xFF00) { else if (address < 0xFF00) {
if ((memoryLayout.STAT & 0x03) == 2 || (memoryLayout.STAT & 0x03) == 3) if ((memoryLayout.STAT & 0x03) == 2 || (memoryLayout.STAT & 0x03) == 3)
return 0xFF; return 0xFF;
return 0x00; return 0x00;
} } else if (address < 0xFF80)
if (address < 0xFF80)
switch (address) { switch (address) {
case 0xFF00: case 0xFF00:
return memoryLayout.JOYP; return memoryLayout.JOYP;
@@ -235,8 +233,6 @@ public:
case 0xFF43: case 0xFF43:
return memoryLayout.SCX; return memoryLayout.SCX;
case 0xFF44: case 0xFF44:
// for debugging only
// return 0x90;
return memoryLayout.LY; return memoryLayout.LY;
case 0xFF45: case 0xFF45:
return memoryLayout.LYC; return memoryLayout.LYC;
@@ -258,7 +254,7 @@ public:
} }
return 0xFF; return 0xFF;
} }
if (address < 0xFFFF) else if (address < 0xFFFF)
return memoryLayout.specialRam[address - 0xFF80]; return memoryLayout.specialRam[address - 0xFF80];
// 0xFFFF // 0xFFFF
return memoryLayout.IE; return memoryLayout.IE;
@@ -269,28 +265,27 @@ public:
dummyVal = 0xFF; dummyVal = 0xFF;
if (testing) if (testing)
return testRam[address]; return testRam[address];
if (address < 0x0100 && bootromLoaded) else if (address < 0x0100 && bootromLoaded)
return bootrom[address]; return bootrom[address];
if (address < 0x8000) else if (address < 0x8000)
return (*MBCRead(address)); return (*MBCWrite(address));
if (address < 0xA000) else if (address < 0xA000)
return memoryLayout.vram[address - 0x8000]; return memoryLayout.vram[address - 0x8000];
if (address < 0xC000) { else if (address < 0xC000) {
if (externalRamSize == 0) if (externalRamSize == 0)
return dummyVal; return dummyVal;
return memoryLayout.externalRam[address - 0xA000]; return memoryLayout.externalRam[address - 0xA000];
} } else if (address < 0xD000)
if (address < 0xD000)
return memoryLayout.memoryBank1[address - 0xC000]; return memoryLayout.memoryBank1[address - 0xC000];
if (address < 0xE000) else if (address < 0xE000)
return memoryLayout.memoryBank2[address - 0xD000]; return memoryLayout.memoryBank2[address - 0xD000];
if (address < 0xFE00) else if (address < 0xFE00)
return memoryLayout.memoryBank1[address - 0xE000]; return memoryLayout.memoryBank1[address - 0xE000];
if (address < 0xFEA0) else if (address < 0xFEA0)
return memoryLayout.oam[address - 0xFE00]; return memoryLayout.oam[address - 0xFE00];
if (address < 0xFF00) else if (address < 0xFF00)
return memoryLayout.notUsable[address - 0xFEA0]; return memoryLayout.notUsable[address - 0xFEA0];
if (address < 0xFF80) else if (address < 0xFF80)
switch (address) { switch (address) {
case 0xFF00: case 0xFF00:
return memoryLayout.JOYP; return memoryLayout.JOYP;
@@ -384,7 +379,7 @@ public:
} }
return dummyVal; return dummyVal;
} }
if (address < 0xFFFF) else if (address < 0xFFFF)
return memoryLayout.specialRam[address - 0xFF80]; return memoryLayout.specialRam[address - 0xFF80];
// 0xFFFF // 0xFFFF
return memoryLayout.IE; return memoryLayout.IE;

View File

@@ -35,13 +35,7 @@ void AddressSpace::determineMBCInfo() {
} }
} }
bool AddressSpace::MBCWrite(const Word address) { Byte *AddressSpace::MBCWrite(const Word address) {
if (address <= 0x7FFF)
return true;
return false;
}
Byte *AddressSpace::MBCRead(const Word address) {
if (MBC == MBC1) { if (MBC == MBC1) {
if (address <= 0x1FFF) if (address <= 0x1FFF)
return &ramEnable; return &ramEnable;
@@ -70,8 +64,16 @@ Byte *AddressSpace::MBCRead(const Word address) {
return &ramEnable; return &ramEnable;
} }
} else if (MBC == MBC3 || MBC == MBC3TimerBattery) { } else if (MBC == MBC3 || MBC == MBC3TimerBattery) {
if (address <= 0x1FFF)
return &ramEnable;
} else if (MBC == MBC3Ram || MBC == MBC3RamBattery || } else if (MBC == MBC3Ram || MBC == MBC3RamBattery ||
MBC == MBC3TimerRamBattery) { MBC == MBC3TimerRamBattery) {
if (address <= 0x1FFF)
return &ramEnable;
if (address <= 0x3FFF)
return &romBankRegister;
if (address <= 0x5FFF)
return &ramBankRTCRegister;
} }
return &dummyVal; return &dummyVal;
} }
@@ -131,38 +133,16 @@ void AddressSpace::MBCUpdate() {
loadRomBank(); loadRomBank();
loadRamBank(); loadRamBank();
} else if (MBC == MBC3 || MBC == MBC3TimerBattery) { } else if (MBC == MBC3 || MBC == MBC3TimerBattery) {
romBankRegister &= 0b11111; selectedRomBank = romBankRegister & 0x7F;
twoBitBankRegister &= 0b11;
// 512 KiB can only have 8KiB of ram loadRomBank();
if (romSize >= 524288) { loadRamBank();
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 || } else if (MBC == MBC3Ram || MBC == MBC3RamBattery ||
MBC == MBC3TimerRamBattery) { MBC == MBC3TimerRamBattery) {
romBankRegister &= 0b11111; selectedRomBank = romBankRegister & 0x7F;
twoBitBankRegister &= 0b11;
// 512 KiB can only have 8KiB of ram loadRomBank();
if (romSize >= 524288) { loadRamBank();
if (romBankRegister == 0)
selectedRomBank = (twoBitBankRegister << 5) + 1;
selectedRomBank = (twoBitBankRegister << 5) + romBankRegister;
selectedExternalRamBank = 0;
} else {
if (romBankRegister == 0)
selectedRomBank = 1;
else
selectedRomBank = romBankRegister;
selectedExternalRamBank = twoBitBankRegister;
}
} }
} }