diff --git a/Core/gb.c b/Core/gb.c index ab35b78..2afeb81 100644 --- a/Core/gb.c +++ b/Core/gb.c @@ -1151,6 +1151,9 @@ uint8_t GB_run(GB_gameboy_t *gb) GB_debugger_handle_async_commands(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; } diff --git a/Core/gb.h b/Core/gb.h index e5bb128..0a3b5da 100644 --- a/Core/gb.h +++ b/Core/gb.h @@ -632,7 +632,8 @@ struct GB_gameboy_internal_s { bool has_sgb_border; bool objects_disabled; bool background_disabled; - + bool joyp_accessed; + /* Timing */ uint64_t last_sync; uint64_t cycles_since_last_sync; // In 8MHz units diff --git a/Core/joypad.c b/Core/joypad.c index 06fb53f..f16aa9e 100644 --- a/Core/joypad.c +++ b/Core/joypad.c @@ -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); } + +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; +} diff --git a/Core/joypad.h b/Core/joypad.h index beb532e..a360af1 100644 --- a/Core/joypad.h +++ b/Core/joypad.h @@ -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_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); +bool GB_get_joyp_accessed(GB_gameboy_t *gb); +void GB_clear_joyp_accessed(GB_gameboy_t *gb); + #ifdef GB_INTERNAL internal void GB_update_joyp(GB_gameboy_t *gb); diff --git a/Core/memory.c b/Core/memory.c index 7ca770a..43a9dde 100644 --- a/Core/memory.c +++ b/Core/memory.c @@ -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) | (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: + gb->joyp_accessed = true; GB_timing_sync(gb); case GB_IO_TMA: case GB_IO_LCDC: diff --git a/Core/sm83_cpu.c b/Core/sm83_cpu.c index 035779b..130bfb3 100644 --- a/Core/sm83_cpu.c +++ b/Core/sm83_cpu.c @@ -363,6 +363,9 @@ static void leave_stop_mode(GB_gameboy_t *gb) static void stop(GB_gameboy_t *gb, uint8_t opcode) { 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 speed_switch = (gb->io_registers[GB_IO_KEY1] & 0x1) && !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) { GB_timing_sync(gb); 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) { leave_stop_mode(gb); GB_advance_cycles(gb, 8);