diff --git a/Core/memory.c b/Core/memory.c index 8aacf41..b1619a6 100644 --- a/Core/memory.c +++ b/Core/memory.c @@ -919,6 +919,7 @@ static void write_high_memory(GB_gameboy_t *gb, uint16_t addr, uint8_t value) else if (gb->frame_skip_state == GB_FRAMESKIP_SECOND_FRAME_RENDERED) { gb->frame_skip_state = GB_FRAMESKIP_LCD_TURNED_ON; } + GB_timing_sync(gb); } else if (!(value & 0x80) && (gb->io_registers[GB_IO_LCDC] & 0x80)) { /* Sync after turning off LCD */ diff --git a/Core/timing.c b/Core/timing.c index dedc5a0..18cf571 100644 --- a/Core/timing.c +++ b/Core/timing.c @@ -64,11 +64,16 @@ void GB_timing_sync(GB_gameboy_t *gb) uint64_t target_nanoseconds = gb->cycles_since_last_sync * 1000000000LL / 2 / GB_get_clock_rate(gb); /* / 2 because we use 8MHz units */ int64_t nanoseconds = get_nanoseconds(); int64_t time_to_sleep = target_nanoseconds + gb->last_sync - nanoseconds; - if (time_to_sleep > 0 && time_to_sleep < LCDC_PERIOD * 1000000000LL / GB_get_clock_rate(gb)) { + if (time_to_sleep > 0 && time_to_sleep < LCDC_PERIOD * 1200000000LL / GB_get_clock_rate(gb)) { // +20% to be more forgiving nsleep(time_to_sleep); gb->last_sync += target_nanoseconds; } else { + if (-time_to_sleep < LCDC_PERIOD * 1200000000LL / GB_get_clock_rate(gb)) { + // We're running a bit too slow, but the difference is small enough, + // just skip this sync and let it even out + return; + } gb->last_sync = nanoseconds; }