enums and RTC work
This commit is contained in:
@@ -43,7 +43,6 @@ public:
|
|||||||
Byte TAC = 0xF8;
|
Byte TAC = 0xF8;
|
||||||
// interrupt flag and enable
|
// interrupt flag and enable
|
||||||
Byte IF = 0xE1;
|
Byte IF = 0xE1;
|
||||||
;
|
|
||||||
// Sound registers
|
// Sound registers
|
||||||
Byte NR10;
|
Byte NR10;
|
||||||
Byte NR11;
|
Byte NR11;
|
||||||
@@ -103,7 +102,7 @@ public:
|
|||||||
void loadRomBank();
|
void loadRomBank();
|
||||||
void createRamBank();
|
void createRamBank();
|
||||||
void loadRamBank();
|
void loadRamBank();
|
||||||
MBCType MBC = {};
|
MBCType_enum MBC = {};
|
||||||
uint32_t romSize = 0;
|
uint32_t romSize = 0;
|
||||||
uint32_t romBanks = 0;
|
uint32_t romBanks = 0;
|
||||||
uint32_t externalRamSize = 0;
|
uint32_t externalRamSize = 0;
|
||||||
@@ -116,7 +115,8 @@ public:
|
|||||||
// Selected ROM Bank in MBC1 = (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 in MBC1
|
// 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;
|
||||||
@@ -128,6 +128,13 @@ public:
|
|||||||
// MBC3
|
// MBC3
|
||||||
Byte latchClockData = 0x00;
|
Byte latchClockData = 0x00;
|
||||||
Byte ramBankRTCRegister = 0x00;
|
Byte ramBankRTCRegister = 0x00;
|
||||||
|
// RTC registers
|
||||||
|
enabledRTCRegister_enum enabledRTCRegister = NONE;
|
||||||
|
Byte RTCSeconds = 0x0;
|
||||||
|
Byte RTCMinutes = 0x0;
|
||||||
|
Byte RTCHours = 0x0;
|
||||||
|
Byte RTCDayLower = 0x0;
|
||||||
|
Byte RTCDayHigher = 0x0;
|
||||||
|
|
||||||
void setTesting(bool state);
|
void setTesting(bool state);
|
||||||
|
|
||||||
@@ -144,6 +151,20 @@ public:
|
|||||||
else if (address < 0xA000)
|
else if (address < 0xA000)
|
||||||
return memoryLayout.vram[address - 0x8000];
|
return memoryLayout.vram[address - 0x8000];
|
||||||
else if (address < 0xC000) {
|
else if (address < 0xC000) {
|
||||||
|
if (enabledRTCRegister != NONE) {
|
||||||
|
switch (enabledRTCRegister) {
|
||||||
|
case RTCS:
|
||||||
|
return RTCSeconds;
|
||||||
|
case RTCM:
|
||||||
|
return RTCMinutes;
|
||||||
|
case RTCH:
|
||||||
|
return RTCHours;
|
||||||
|
case RTCDL:
|
||||||
|
return RTCDayLower;
|
||||||
|
case RTCDH:
|
||||||
|
return RTCDayHigher;
|
||||||
|
}
|
||||||
|
}
|
||||||
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
|
||||||
|
|||||||
@@ -79,7 +79,7 @@ struct Input {
|
|||||||
bool SELECT = false;
|
bool SELECT = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum MBCType {
|
enum MBCType_enum {
|
||||||
romOnly = 0x00,
|
romOnly = 0x00,
|
||||||
MBC1 = 0x01,
|
MBC1 = 0x01,
|
||||||
MBC1Ram = 0x02,
|
MBC1Ram = 0x02,
|
||||||
@@ -111,7 +111,7 @@ enum MBCType {
|
|||||||
HuC1RamBattery = 0xFF
|
HuC1RamBattery = 0xFF
|
||||||
};
|
};
|
||||||
|
|
||||||
enum PPUMode {
|
enum PPUMode_enum {
|
||||||
mode0, // Horizontal Blank (Mode 0): No access to video RAM, occurs during
|
mode0, // Horizontal Blank (Mode 0): No access to video RAM, occurs during
|
||||||
// horizontal blanking period.
|
// horizontal blanking period.
|
||||||
mode1, // Vertical Blank (Mode 1): No access to video RAM, occurs during
|
mode1, // Vertical Blank (Mode 1): No access to video RAM, occurs during
|
||||||
@@ -122,4 +122,12 @@ enum PPUMode {
|
|||||||
// pixel transfer to the screen.
|
// pixel transfer to the screen.
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum enabledRTCRegister_enum {
|
||||||
|
NONE = 0x00,
|
||||||
|
RTCS = 0x08,
|
||||||
|
RTCM = 0x09,
|
||||||
|
RTCH = 0x0A,
|
||||||
|
RTCDL = 0x0B,
|
||||||
|
RTCDH = 0x0C
|
||||||
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ class GameBoy {
|
|||||||
AddressSpace addressSpace;
|
AddressSpace addressSpace;
|
||||||
const AddressSpace &readOnlyAddressSpace = addressSpace;
|
const AddressSpace &readOnlyAddressSpace = addressSpace;
|
||||||
|
|
||||||
PPUMode currentMode = PPUMode::mode0;
|
PPUMode_enum currentMode = PPUMode_enum::mode0;
|
||||||
Byte windowLineCounter = 0;
|
Byte windowLineCounter = 0;
|
||||||
int16_t cyclesUntilDMATransfer = 160;
|
int16_t cyclesUntilDMATransfer = 160;
|
||||||
|
|
||||||
@@ -86,7 +86,7 @@ class GameBoy {
|
|||||||
void SDL2present();
|
void SDL2present();
|
||||||
|
|
||||||
void checkPPUMode();
|
void checkPPUMode();
|
||||||
void setPPUMode(PPUMode mode);
|
void setPPUMode(PPUMode_enum mode);
|
||||||
uint64_t cyclesSinceLastScanline() const;
|
uint64_t cyclesSinceLastScanline() const;
|
||||||
uint64_t cyclesSinceLastRefresh() const;
|
uint64_t cyclesSinceLastRefresh() const;
|
||||||
|
|
||||||
|
|||||||
19
src/mbc.cpp
19
src/mbc.cpp
@@ -1,7 +1,8 @@
|
|||||||
#include "addressSpace.hpp"
|
#include "addressSpace.hpp"
|
||||||
|
#include "defines.hpp"
|
||||||
|
|
||||||
void AddressSpace::determineMBCInfo() {
|
void AddressSpace::determineMBCInfo() {
|
||||||
MBC = static_cast<MBCType>(memoryLayout.romBank0[0x147]);
|
MBC = static_cast<MBCType_enum>(memoryLayout.romBank0[0x147]);
|
||||||
romSize = 32768 * (1 << memoryLayout.romBank0[0x147]);
|
romSize = 32768 * (1 << memoryLayout.romBank0[0x147]);
|
||||||
romBanks = 1 << (memoryLayout.romBank0[0x147] + 1);
|
romBanks = 1 << (memoryLayout.romBank0[0x147] + 1);
|
||||||
|
|
||||||
@@ -130,17 +131,33 @@ void AddressSpace::MBCUpdate() {
|
|||||||
loadRamBank();
|
loadRamBank();
|
||||||
} else if (MBC == MBC2 || MBC == MBC2Battery) {
|
} else if (MBC == MBC2 || MBC == MBC2Battery) {
|
||||||
selectedRomBank = romBankRegister & 0x0F;
|
selectedRomBank = romBankRegister & 0x0F;
|
||||||
|
selectedExternalRamBank = 0;
|
||||||
|
|
||||||
loadRomBank();
|
loadRomBank();
|
||||||
loadRamBank();
|
loadRamBank();
|
||||||
} else if (MBC == MBC3 || MBC == MBC3TimerBattery) {
|
} else if (MBC == MBC3 || MBC == MBC3TimerBattery) {
|
||||||
selectedRomBank = romBankRegister & 0x7F;
|
selectedRomBank = romBankRegister & 0x7F;
|
||||||
|
selectedExternalRamBank = 0;
|
||||||
|
|
||||||
|
if (MBC == MBC3TimerBattery) {
|
||||||
|
if(ramBankRTCRegister >= 0x8 && ramBankRTCRegister <= 0xC)
|
||||||
|
enabledRTCRegister = static_cast<enabledRTCRegister_enum>(ramBankRTCRegister);
|
||||||
|
else
|
||||||
|
enabledRTCRegister = NONE;
|
||||||
|
}
|
||||||
loadRomBank();
|
loadRomBank();
|
||||||
loadRamBank();
|
loadRamBank();
|
||||||
} else if (MBC == MBC3Ram || MBC == MBC3RamBattery ||
|
} else if (MBC == MBC3Ram || MBC == MBC3RamBattery ||
|
||||||
MBC == MBC3TimerRamBattery) {
|
MBC == MBC3TimerRamBattery) {
|
||||||
selectedRomBank = romBankRegister & 0x7F;
|
selectedRomBank = romBankRegister & 0x7F;
|
||||||
|
selectedExternalRamBank = ramBankRTCRegister & 0b11;
|
||||||
|
|
||||||
|
if (MBC == MBC3TimerRamBattery) {
|
||||||
|
if(ramBankRTCRegister >= 0x8 && ramBankRTCRegister <= 0xC)
|
||||||
|
enabledRTCRegister = static_cast<enabledRTCRegister_enum>(ramBankRTCRegister);
|
||||||
|
else
|
||||||
|
enabledRTCRegister = NONE;
|
||||||
|
}
|
||||||
loadRomBank();
|
loadRomBank();
|
||||||
loadRamBank();
|
loadRamBank();
|
||||||
}
|
}
|
||||||
|
|||||||
16
src/ppu.cpp
16
src/ppu.cpp
@@ -46,9 +46,9 @@ void GameBoy::ppuUpdate() {
|
|||||||
readOnlyAddressSpace.memoryLayout.STAT & (1 << 5);
|
readOnlyAddressSpace.memoryLayout.STAT & (1 << 5);
|
||||||
const bool previousInterruptLine = statInteruptLine;
|
const bool previousInterruptLine = statInteruptLine;
|
||||||
|
|
||||||
if (currentMode == PPUMode::mode0 && hBlankInterruptEnabled ||
|
if (currentMode == PPUMode_enum::mode0 && hBlankInterruptEnabled ||
|
||||||
currentMode == PPUMode::mode3 && drawingInterruptEnabled ||
|
currentMode == PPUMode_enum::mode3 && drawingInterruptEnabled ||
|
||||||
currentMode == PPUMode::mode2 && oamInterruptEnabled) {
|
currentMode == PPUMode_enum::mode2 && oamInterruptEnabled) {
|
||||||
statInteruptLine = true;
|
statInteruptLine = true;
|
||||||
} else {
|
} else {
|
||||||
statInteruptLine = false;
|
statInteruptLine = false;
|
||||||
@@ -84,13 +84,13 @@ void GameBoy::checkPPUMode() {
|
|||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
if (cyclesSinceScanline > MODE2_DURATION) {
|
if (cyclesSinceScanline > MODE2_DURATION) {
|
||||||
setPPUMode(PPUMode::mode3);
|
setPPUMode(PPUMode_enum::mode3);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
if (cyclesSinceScanline > MODE2_DURATION + MODE3_MIN_DURATION) {
|
if (cyclesSinceScanline > MODE2_DURATION + MODE3_MIN_DURATION) {
|
||||||
drawLine();
|
drawLine();
|
||||||
setPPUMode(PPUMode::mode0);
|
setPPUMode(PPUMode_enum::mode0);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -98,14 +98,14 @@ void GameBoy::checkPPUMode() {
|
|||||||
|
|
||||||
void GameBoy::incLY() {
|
void GameBoy::incLY() {
|
||||||
addressSpace.memoryLayout.LY += 1;
|
addressSpace.memoryLayout.LY += 1;
|
||||||
setPPUMode(PPUMode::mode2);
|
setPPUMode(PPUMode_enum::mode2);
|
||||||
if (addressSpace.memoryLayout.LY > SCANLINES_PER_FRAME - 1) {
|
if (addressSpace.memoryLayout.LY > SCANLINES_PER_FRAME - 1) {
|
||||||
addressSpace.memoryLayout.LY = 0;
|
addressSpace.memoryLayout.LY = 0;
|
||||||
windowLineCounter = 0;
|
windowLineCounter = 0;
|
||||||
} else if (addressSpace.memoryLayout.LY == 144) {
|
} else if (addressSpace.memoryLayout.LY == 144) {
|
||||||
// VBlank Period
|
// VBlank Period
|
||||||
SDL2present();
|
SDL2present();
|
||||||
setPPUMode(PPUMode::mode1);
|
setPPUMode(PPUMode_enum::mode1);
|
||||||
addressSpace.memoryLayout.IF |= 0x1;
|
addressSpace.memoryLayout.IF |= 0x1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -120,7 +120,7 @@ uint64_t GameBoy::cyclesSinceLastRefresh() const {
|
|||||||
return difference;
|
return difference;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GameBoy::setPPUMode(const PPUMode mode) {
|
void GameBoy::setPPUMode(const PPUMode_enum mode) {
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
case mode0:
|
case mode0:
|
||||||
addressSpace.memoryLayout.STAT &= ~0x03;
|
addressSpace.memoryLayout.STAT &= ~0x03;
|
||||||
|
|||||||
Reference in New Issue
Block a user