Improved time syncing when turning the LCD on and off, fixes #193

This commit is contained in:
Lior Halphon 2021-03-21 15:15:04 +02:00
parent 5c1b89e82d
commit ad54dc57b0
2 changed files with 7 additions and 1 deletions

View File

@ -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 */

View File

@ -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;
}