Lag frame detection API (#422)

This commit is contained in:
Lior Halphon 2021-12-18 01:25:06 +02:00
parent c3d9141b7c
commit c63ddbe771
6 changed files with 25 additions and 1 deletions

View File

@ -1151,6 +1151,9 @@ uint8_t GB_run(GB_gameboy_t *gb)
GB_debugger_handle_async_commands(gb); GB_debugger_handle_async_commands(gb);
GB_rewind_push(gb); GB_rewind_push(gb);
} }
if (!(gb->io_registers[GB_IO_IF] & 0x10) && (gb->io_registers[GB_IO_JOYP] & 0x30) != 0x30) {
gb->joyp_accessed = true;
}
return gb->cycles_since_run; return gb->cycles_since_run;
} }

View File

@ -632,6 +632,7 @@ struct GB_gameboy_internal_s {
bool has_sgb_border; bool has_sgb_border;
bool objects_disabled; bool objects_disabled;
bool background_disabled; bool background_disabled;
bool joyp_accessed;
/* Timing */ /* Timing */
uint64_t last_sync; uint64_t last_sync;

View File

@ -121,3 +121,13 @@ void GB_set_key_mask_for_player(GB_gameboy_t *gb, GB_key_mask_t mask, unsigned p
GB_update_joyp(gb); GB_update_joyp(gb);
} }
bool GB_get_joyp_accessed(GB_gameboy_t *gb)
{
return gb->joyp_accessed;
}
void GB_clear_joyp_accessed(GB_gameboy_t *gb)
{
gb->joyp_accessed = false;
}

View File

@ -34,6 +34,9 @@ void GB_set_key_state_for_player(GB_gameboy_t *gb, GB_key_t index, unsigned play
void GB_set_key_mask(GB_gameboy_t *gb, GB_key_mask_t mask); void GB_set_key_mask(GB_gameboy_t *gb, GB_key_mask_t mask);
void GB_set_key_mask_for_player(GB_gameboy_t *gb, GB_key_mask_t mask, unsigned player); void GB_set_key_mask_for_player(GB_gameboy_t *gb, GB_key_mask_t mask, unsigned player);
void GB_icd_set_joyp(GB_gameboy_t *gb, uint8_t value); void GB_icd_set_joyp(GB_gameboy_t *gb, uint8_t value);
bool GB_get_joyp_accessed(GB_gameboy_t *gb);
void GB_clear_joyp_accessed(GB_gameboy_t *gb);
#ifdef GB_INTERNAL #ifdef GB_INTERNAL
internal void GB_update_joyp(GB_gameboy_t *gb); internal void GB_update_joyp(GB_gameboy_t *gb);

View File

@ -568,6 +568,7 @@ static uint8_t read_high_memory(GB_gameboy_t *gb, uint16_t addr)
return ((gb->apu.is_active[GB_NOISE] ? (gb->apu.samples[GB_NOISE] << 4) : 0) | return ((gb->apu.is_active[GB_NOISE] ? (gb->apu.samples[GB_NOISE] << 4) : 0) |
(gb->apu.is_active[GB_WAVE] ? (gb->apu.samples[GB_WAVE]) : 0)) & (gb->model <= GB_MODEL_CGB_C? gb->apu.pcm_mask[1] : 0xFF); (gb->apu.is_active[GB_WAVE] ? (gb->apu.samples[GB_WAVE]) : 0)) & (gb->model <= GB_MODEL_CGB_C? gb->apu.pcm_mask[1] : 0xFF);
case GB_IO_JOYP: case GB_IO_JOYP:
gb->joyp_accessed = true;
GB_timing_sync(gb); GB_timing_sync(gb);
case GB_IO_TMA: case GB_IO_TMA:
case GB_IO_LCDC: case GB_IO_LCDC:

View File

@ -363,6 +363,9 @@ static void leave_stop_mode(GB_gameboy_t *gb)
static void stop(GB_gameboy_t *gb, uint8_t opcode) static void stop(GB_gameboy_t *gb, uint8_t opcode)
{ {
flush_pending_cycles(gb); flush_pending_cycles(gb);
if ((gb->io_registers[GB_IO_JOYP] & 0x30) != 0x30) {
gb->joyp_accessed = true;
}
bool exit_by_joyp = ((gb->io_registers[GB_IO_JOYP] & 0xF) != 0xF); bool exit_by_joyp = ((gb->io_registers[GB_IO_JOYP] & 0xF) != 0xF);
bool speed_switch = (gb->io_registers[GB_IO_KEY1] & 0x1) && !exit_by_joyp; bool speed_switch = (gb->io_registers[GB_IO_KEY1] & 0x1) && !exit_by_joyp;
bool immediate_exit = speed_switch || exit_by_joyp; bool immediate_exit = speed_switch || exit_by_joyp;
@ -1575,6 +1578,9 @@ void GB_cpu_run(GB_gameboy_t *gb)
if (gb->stopped) { if (gb->stopped) {
GB_timing_sync(gb); GB_timing_sync(gb);
GB_advance_cycles(gb, 4); GB_advance_cycles(gb, 4);
if ((gb->io_registers[GB_IO_JOYP] & 0x30) != 0x30) {
gb->joyp_accessed = true;
}
if ((gb->io_registers[GB_IO_JOYP] & 0xF) != 0xF) { if ((gb->io_registers[GB_IO_JOYP] & 0xF) != 0xF) {
leave_stop_mode(gb); leave_stop_mode(gb);
GB_advance_cycles(gb, 8); GB_advance_cycles(gb, 8);