mirror of https://github.com/bsnes-emu/bsnes.git
Fix a regression in speed switch timing, reset DIV on speed switch, better odd-mode detection and avoidance
This commit is contained in:
parent
159d9d0348
commit
4bbd27735f
|
@ -895,6 +895,7 @@ static void write_high_memory(GB_gameboy_t *gb, uint16_t addr, uint8_t value)
|
||||||
if ((value & 0x80) && !(gb->io_registers[GB_IO_LCDC] & 0x80)) {
|
if ((value & 0x80) && !(gb->io_registers[GB_IO_LCDC] & 0x80)) {
|
||||||
gb->display_cycles = 0;
|
gb->display_cycles = 0;
|
||||||
gb->display_state = 0;
|
gb->display_state = 0;
|
||||||
|
gb->double_speed_alignment = 0;
|
||||||
if (GB_is_sgb(gb)) {
|
if (GB_is_sgb(gb)) {
|
||||||
gb->frame_skip_state = GB_FRAMESKIP_SECOND_FRAME_RENDERED;
|
gb->frame_skip_state = GB_FRAMESKIP_SECOND_FRAME_RENDERED;
|
||||||
}
|
}
|
||||||
|
|
|
@ -332,6 +332,7 @@ static void nop(GB_gameboy_t *gb, uint8_t opcode)
|
||||||
|
|
||||||
static void enter_stop_mode(GB_gameboy_t *gb)
|
static void enter_stop_mode(GB_gameboy_t *gb)
|
||||||
{
|
{
|
||||||
|
GB_write_memory(gb, 0xFF00 + GB_IO_DIV, 0);
|
||||||
gb->stopped = true;
|
gb->stopped = true;
|
||||||
gb->oam_ppu_blocked = !gb->oam_read_blocked;
|
gb->oam_ppu_blocked = !gb->oam_read_blocked;
|
||||||
gb->vram_ppu_blocked = !gb->vram_read_blocked;
|
gb->vram_ppu_blocked = !gb->vram_read_blocked;
|
||||||
|
@ -340,30 +341,30 @@ static void enter_stop_mode(GB_gameboy_t *gb)
|
||||||
|
|
||||||
static void leave_stop_mode(GB_gameboy_t *gb)
|
static void leave_stop_mode(GB_gameboy_t *gb)
|
||||||
{
|
{
|
||||||
/* The CPU takes more time to wake up then the other components */
|
|
||||||
for (unsigned i = 0x200; i--;) {
|
|
||||||
GB_advance_cycles(gb, 0x10);
|
|
||||||
}
|
|
||||||
gb->stopped = false;
|
gb->stopped = false;
|
||||||
gb->oam_ppu_blocked = false;
|
gb->oam_ppu_blocked = false;
|
||||||
gb->vram_ppu_blocked = false;
|
gb->vram_ppu_blocked = false;
|
||||||
gb->cgb_palettes_ppu_blocked = false;
|
gb->cgb_palettes_ppu_blocked = false;
|
||||||
|
/* The CPU takes more time to wake up then the other components */
|
||||||
|
for (unsigned i = 0x2000; i--;) {
|
||||||
|
GB_advance_cycles(gb, 0x10);
|
||||||
|
}
|
||||||
|
GB_write_memory(gb, 0xFF00 + GB_IO_DIV, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void stop(GB_gameboy_t *gb, uint8_t opcode)
|
static void stop(GB_gameboy_t *gb, uint8_t opcode)
|
||||||
{
|
{
|
||||||
if (gb->io_registers[GB_IO_KEY1] & 0x1) {
|
if (gb->io_registers[GB_IO_KEY1] & 0x1) {
|
||||||
if (gb->cgb_double_speed && gb->io_registers[GB_IO_LCDC] & 0x80) {
|
|
||||||
GB_log(gb, "Returning from double speed mode while the PPU is on may trigger odd-mode\n");
|
|
||||||
}
|
|
||||||
flush_pending_cycles(gb);
|
flush_pending_cycles(gb);
|
||||||
bool needs_alignment = false;
|
bool needs_alignment = false;
|
||||||
|
|
||||||
GB_advance_cycles(gb, 0x4);
|
GB_advance_cycles(gb, 0x4);
|
||||||
/* Make sure we keep the CPU ticks aligned correctly when returning from double speed mode */
|
/* Make sure we keep the CPU ticks aligned correctly when returning from double speed mode */
|
||||||
|
|
||||||
if (gb->double_speed_alignment & 7) {
|
if (gb->double_speed_alignment & 7) {
|
||||||
GB_advance_cycles(gb, 0x4);
|
GB_advance_cycles(gb, 0x4);
|
||||||
needs_alignment = true;
|
needs_alignment = true;
|
||||||
|
GB_log(gb, "ROM triggered PPU odd mode, which is currently not supported. Reverting to even-mode.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
gb->cgb_double_speed ^= true;
|
gb->cgb_double_speed ^= true;
|
||||||
|
@ -388,7 +389,6 @@ static void stop(GB_gameboy_t *gb, uint8_t opcode)
|
||||||
enter_stop_mode(gb);
|
enter_stop_mode(gb);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Todo: is PC being actually read? */
|
/* Todo: is PC being actually read? */
|
||||||
gb->pc++;
|
gb->pc++;
|
||||||
}
|
}
|
||||||
|
|
|
@ -157,7 +157,9 @@ static void GB_set_internal_div_counter(GB_gameboy_t *gb, uint32_t value)
|
||||||
static void GB_timers_run(GB_gameboy_t *gb, uint8_t cycles)
|
static void GB_timers_run(GB_gameboy_t *gb, uint8_t cycles)
|
||||||
{
|
{
|
||||||
if (gb->stopped) {
|
if (gb->stopped) {
|
||||||
gb->apu.apu_cycles += 4 << !gb->cgb_double_speed;
|
if (GB_is_cgb(gb)) {
|
||||||
|
gb->apu.apu_cycles += 4 << !gb->cgb_double_speed;
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -248,7 +250,9 @@ void GB_advance_cycles(GB_gameboy_t *gb, uint8_t cycles)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Not affected by speed boost
|
// Not affected by speed boost
|
||||||
gb->double_speed_alignment += cycles;
|
if (gb->io_registers[GB_IO_LCDC] & 0x80) {
|
||||||
|
gb->double_speed_alignment += cycles;
|
||||||
|
}
|
||||||
gb->hdma_cycles += cycles;
|
gb->hdma_cycles += cycles;
|
||||||
gb->apu_output.sample_cycles += cycles;
|
gb->apu_output.sample_cycles += cycles;
|
||||||
gb->cycles_since_last_sync += cycles;
|
gb->cycles_since_last_sync += cycles;
|
||||||
|
|
Loading…
Reference in New Issue