Refinements to LCD timing (breaks vblank_stat_intr-GS for now)
@@ -293,8 +293,11 @@ static void update_display_state(GB_gameboy_t *gb, uint8_t cycles)
these findings.
Todo: Investigate what causes the difference between our findings */
uint8_t stat_delay = gb->cgb_double_speed? 2 : 4; // (gb->cgb_mode? 0 : 4);
- /* Todo: This is correct for DMG. Is it correct for the 3 CGB modes (DMG/single/double)?*/
- uint8_t scx_delay = ((gb->effective_scx & 7) + atomic_increase - 1) & ~(atomic_increase - 1);
+ /* Todo: This is correct for DMG and single speed CGB. Is it correct for double speed and DMG mode CGB?*/
+ uint8_t scx_delay = ((uint8_t []){0, 2, 2, 4, 4, 6, 6, 8})[gb->effective_scx];
+ if (!gb->cgb_double_speed) {
+ scx_delay &= ~3;
+ }
/* Todo: These are correct for DMG, DMG-mode CGB, and single speed CGB. Is is correct for double speed CGB? */
uint8_t oam_blocking_rush = gb->cgb_double_speed? 2 : 4;
uint8_t vram_blocking_rush = gb->is_cgb? 0 : 4;
@@ -303,7 +306,7 @@ static void update_display_state(GB_gameboy_t *gb, uint8_t cycles)
gb->display_cycles += atomic_increase;
/* The very first line is 4 clocks shorter when the LCD turns on. Verified on SGB2, CGB in CGB mode and
CGB in double speed mode. */
- if (gb->first_scanline && gb->display_cycles >= LINE_LENGTH - 4) {
+ if (gb->first_scanline && gb->display_cycles >= LINE_LENGTH - 8) {
gb->first_scanline = false;
gb->display_cycles += 4;
}
@@ -382,7 +385,7 @@ static void update_display_state(GB_gameboy_t *gb, uint8_t cycles)
gb->oam_write_blocked = true;
gb->vram_write_blocked = true;
}
- else if (gb->display_cycles == MODE2_LENGTH + MODE3_LENGTH) {
+ else if (gb->display_cycles == MODE2_LENGTH + MODE3_LENGTH + scx_delay) {
gb->io_registers[GB_IO_STAT] &= ~3;
gb->oam_read_blocked = false;
gb->vram_read_blocked = false;
