Emulate the JOYP mode switching delay on the DMG

This commit is contained in:
Lior Halphon 2022-07-23 19:29:23 +03:00
parent 0e1d6545e9
commit 33ba353c3a
3 changed files with 24 additions and 0 deletions

View File

@ -559,6 +559,8 @@ struct GB_gameboy_internal_s {
bool lcd_disabled_outside_of_vblank;
int32_t allowed_pending_cycles;
uint16_t mode3_batching_length;
uint8_t joyp_switching_delay;
uint8_t joyp_switch_value;
)
/* APU */

View File

@ -627,6 +627,10 @@ static uint8_t read_high_memory(GB_gameboy_t *gb, uint16_t addr)
case GB_IO_JOYP:
gb->joyp_accessed = true;
GB_timing_sync(gb);
if (unlikely(gb->joyp_switching_delay)) {
return (gb->io_registers[addr & 0xFF] & ~0x30) | (gb->joyp_switch_value & 0x30);
}
return gb->io_registers[addr & 0xFF];
case GB_IO_TMA:
case GB_IO_LCDC:
case GB_IO_SCY:
@ -1497,6 +1501,14 @@ static void write_high_memory(GB_gameboy_t *gb, uint16_t addr, uint8_t value)
GB_update_joyp(gb);
}
else if ((gb->io_registers[GB_IO_JOYP] & 0x30) != (value & 0x30)) {
if (gb->model < GB_MODEL_SGB) { // DMG only
if (gb->joyp_switching_delay) {
gb->io_registers[GB_IO_JOYP] = (gb->joyp_switch_value & 0xF0) | (gb->io_registers[GB_IO_JOYP] & 0x0F);
}
gb->joyp_switch_value = value;
gb->joyp_switching_delay = 24;
value &= gb->io_registers[GB_IO_JOYP];
}
GB_sgb_write(gb, value);
gb->io_registers[GB_IO_JOYP] = (value & 0xF0) | (gb->io_registers[GB_IO_JOYP] & 0x0F);
GB_update_joyp(gb);

View File

@ -449,6 +449,16 @@ void GB_advance_cycles(GB_gameboy_t *gb, uint8_t cycles)
gb->rumble_on_cycles += gb->rumble_strength & 3;
gb->rumble_off_cycles += (gb->rumble_strength & 3) ^ 3;
if (gb->joyp_switching_delay) {
if (gb->joyp_switching_delay > cycles) {
gb->joyp_switching_delay -= cycles;
}
else {
gb->joyp_switching_delay = 0;
gb->io_registers[GB_IO_JOYP] = (gb->joyp_switch_value & 0xF0) | (gb->io_registers[GB_IO_JOYP] & 0x0F);
GB_update_joyp(gb);
}
}
GB_apu_run(gb, false);
GB_display_run(gb, cycles, false);