more MBC3 work
This commit is contained in:
@@ -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
|
||||||
|
|||||||
@@ -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;
|
||||||
return memoryLayout.externalRam[address - 0xA000];
|
else
|
||||||
}
|
return memoryLayout.externalRam[address - 0xA000];
|
||||||
if (address < 0xD000)
|
} else 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;
|
||||||
|
|||||||
50
src/mbc.cpp
50
src/mbc.cpp
@@ -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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user