diff --git a/src/defines.hpp b/src/defines.hpp index 043466d..2ab5e4e 100644 --- a/src/defines.hpp +++ b/src/defines.hpp @@ -37,8 +37,8 @@ #define SCANLINE_DURATION 456 #define FRAME_DURATION 70224 #define MODE2_DURATION 80 -#define MODE3_BASE_DURATION 168 -#define MODE0_3_DURATION 376 //mode3 is 168 to 291, mode0 85 to 208 +#define MODE3_MIN_DURATION 172 +#define MODE0_3_DURATION 376 //mode3 is 172 to 289, mode0 87 to 204 #define MODE1_DURATION 4560 #define H_SYNC 9198 diff --git a/src/gameboy.hpp b/src/gameboy.hpp index f2f969f..6774e9a 100644 --- a/src/gameboy.hpp +++ b/src/gameboy.hpp @@ -188,6 +188,7 @@ class GameBoy { SDL_Event event; void opcodeHandler(); + void incLY(); void ppuUpdate(); void drawLine(); void SDL2present(); diff --git a/src/ppu.cpp b/src/ppu.cpp index 6a3d8dd..6bcd9f8 100644 --- a/src/ppu.cpp +++ b/src/ppu.cpp @@ -20,13 +20,11 @@ void GameBoy::ppuUpdate() { Byte mode = (*STAT) & 0x03; switch (mode) { case 0: - if (cyclesSinceLastScanline() > MODE2_DURATION + MODE3_BASE_DURATION) { + if (cyclesSinceLastScanline() > MODE2_DURATION + MODE3_MIN_DURATION) { drawLine(); cyclesToStayInHblank = SCANLINE_DURATION - cyclesSinceLastScanline(); lastScanline = cycles; - (*LY)++; - if ((*LY) > 153) - (*LY) = 0; + incLY(); } currentMode = PPUMode::mode0; break; @@ -35,14 +33,11 @@ void GameBoy::ppuUpdate() { case 1: if (currentMode != PPUMode::mode1) { setPPUMode(PPUMode::mode1); - //drawLine(); *IF |= 0x1; } if (cyclesSinceLastScanline() > SCANLINE_DURATION) { lastScanline = cycles; - (*LY)++; - if ((*LY) > 153) - (*LY) = 0; + incLY(); } currentMode = PPUMode::mode1; break; @@ -55,8 +50,8 @@ void GameBoy::ppuUpdate() { } if ((*LY) == (*LYC) || (*STAT) & (1 << 6)) { // Request STAT interrupt if LY matches LYC - //bug on DMG models triggers a STAT interrupt anytime the STAT register is written - //Road Rage and Zerd no Denetsu rely on this + // bug on DMG models triggers a STAT interrupt anytime the STAT register is written + // Road Rage and Zerd no Denetsu rely on this (*STAT) |= (1 << 2); } else { (*STAT) &= ~(1 << 2); @@ -74,31 +69,37 @@ void GameBoy::ppuUpdate() { } } +void GameBoy::incLY() { + (*LY)++; + if ((*LY) > 153) + (*LY) = 0; +} + uint32_t GameBoy::cyclesSinceLastScanline() { - uint32_t difference = cycles - lastScanline; + const uint32_t difference = cycles - lastScanline; return difference; } uint32_t GameBoy::cyclesSinceLastRefresh() { - uint32_t difference = cycles - lastRefresh; + const uint32_t difference = cycles - lastRefresh; return difference; } void GameBoy::checkPPUMode() { - int oamFetchTime = 0; + uint32_t oamFetchTime = 0; if ((*LY) < 144) { - uint32_t currentDuration = cyclesSinceLastScanline(); + const uint32_t currentDuration = cyclesSinceLastScanline(); // Active Display Period (HBlank, OAM Search, and Pixel Transfer) if (currentDuration < MODE2_DURATION) setPPUMode(PPUMode::mode2); - else if (currentDuration < MODE2_DURATION + MODE3_BASE_DURATION + oamFetchTime) + else if (currentDuration < MODE2_DURATION + MODE3_MIN_DURATION + oamFetchTime) setPPUMode(PPUMode::mode3); else setPPUMode(PPUMode::mode0); - } - // VBlank Period - else + } else { + // VBlank Period setPPUMode(PPUMode::mode1); + } } void GameBoy::setPPUMode(PPUMode mode) {