Improved ticks command, more accurate speed switch timings, better odd-mode warnings
This commit is contained in:
parent
6f6f72dcbd
commit
a5325d3374
@ -1606,8 +1606,12 @@ static bool ticks(GB_gameboy_t *gb, char *arguments, char *modifiers, const debu
|
||||
return true;
|
||||
}
|
||||
|
||||
GB_log(gb, "Ticks: %llu. (Resetting)\n", (unsigned long long)gb->debugger_ticks);
|
||||
GB_log(gb, "T-cycles: %llu\n", (unsigned long long)gb->debugger_ticks);
|
||||
GB_log(gb, "M-cycles: %llu\n", (unsigned long long)gb->debugger_ticks / 4);
|
||||
GB_log(gb, "Absolute 8MHz ticks: %llu\n", (unsigned long long)gb->absolute_debugger_ticks);
|
||||
GB_log(gb, "Tick count reset.\n");
|
||||
gb->debugger_ticks = 0;
|
||||
gb->absolute_debugger_ticks = 0;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -532,6 +532,7 @@ struct GB_gameboy_internal_s {
|
||||
uint8_t double_speed_alignment;
|
||||
uint8_t serial_count;
|
||||
int32_t speed_switch_halt_countdown;
|
||||
uint8_t speed_switch_countdown; // To compensate for the lack of pipeline emulation
|
||||
uint8_t speed_switch_freeze; // Solely for realigning the PPU, should be removed when the odd modes are implemented
|
||||
);
|
||||
|
||||
@ -718,6 +719,7 @@ struct GB_gameboy_internal_s {
|
||||
|
||||
/* Ticks command */
|
||||
uint64_t debugger_ticks;
|
||||
uint64_t absolute_debugger_ticks;
|
||||
|
||||
/* Undo */
|
||||
uint8_t *undo_state;
|
||||
|
@ -374,6 +374,7 @@ static void leave_stop_mode(GB_gameboy_t *gb)
|
||||
gb->cgb_palettes_ppu_blocked = false;
|
||||
}
|
||||
|
||||
/* TODO: Speed switch timing needs far more tests. Double to single is wrong to avoid odd mode. */
|
||||
static void stop(GB_gameboy_t *gb, uint8_t opcode)
|
||||
{
|
||||
flush_pending_cycles(gb);
|
||||
@ -387,29 +388,39 @@ static void stop(GB_gameboy_t *gb, uint8_t opcode)
|
||||
}
|
||||
|
||||
if (!interrupt_pending) {
|
||||
/* Todo: is PC being actually read? */
|
||||
cycle_read_inc_oam_bug(gb, gb->pc++);
|
||||
}
|
||||
|
||||
/* Todo: speed switching takes a fractional number of M-cycles. It make
|
||||
every active component (APU, PPU) unaligned with the CPU. */
|
||||
/* Todo: speed switching takes 2 extra T-cycles (so 2 PPU ticks in single->double and 1 PPU tick in double->single) */
|
||||
if (speed_switch) {
|
||||
flush_pending_cycles(gb);
|
||||
|
||||
if (gb->io_registers[GB_IO_LCDC] & 0x80) {
|
||||
GB_log(gb, "ROM triggered PPU odd mode, which is currently not supported. Reverting to even-mode.\n");
|
||||
if (gb->io_registers[GB_IO_LCDC] & 0x80 && gb->cgb_double_speed) {
|
||||
GB_log(gb, "ROM triggered a PPU odd mode, which is currently not supported. Reverting to even-mode.\n");
|
||||
if (gb->double_speed_alignment & 7) {
|
||||
gb->speed_switch_freeze = 6;
|
||||
gb->speed_switch_freeze = 2;
|
||||
}
|
||||
}
|
||||
if (gb->apu.global_enable && gb->cgb_double_speed) {
|
||||
GB_log(gb, "ROM triggered an APU odd mode, which is currently not tested.\n");
|
||||
}
|
||||
|
||||
if (gb->cgb_double_speed) {
|
||||
gb->cgb_double_speed = false;
|
||||
}
|
||||
else {
|
||||
gb->speed_switch_freeze = 4;
|
||||
}
|
||||
gb->speed_switch_countdown = 6;
|
||||
gb->speed_switch_freeze = 1;
|
||||
}
|
||||
|
||||
gb->cgb_double_speed ^= true;
|
||||
gb->io_registers[GB_IO_KEY1] = 0;
|
||||
|
||||
if (interrupt_pending) {
|
||||
}
|
||||
else {
|
||||
gb->speed_switch_halt_countdown = 0x20008;
|
||||
gb->speed_switch_freeze = 5;
|
||||
}
|
||||
|
||||
gb->io_registers[GB_IO_KEY1] = 0;
|
||||
}
|
||||
|
||||
if (immediate_exit) {
|
||||
|
@ -346,6 +346,22 @@ static void GB_rtc_run(GB_gameboy_t *gb, uint8_t cycles)
|
||||
|
||||
void GB_advance_cycles(GB_gameboy_t *gb, uint8_t cycles)
|
||||
{
|
||||
if (gb->speed_switch_countdown) {
|
||||
if (gb->speed_switch_countdown == cycles) {
|
||||
gb->cgb_double_speed ^= true;
|
||||
gb->speed_switch_countdown = 0;
|
||||
}
|
||||
else if (gb->speed_switch_countdown > cycles) {
|
||||
gb->speed_switch_countdown -= cycles;
|
||||
}
|
||||
else {
|
||||
uint8_t old_cycles = gb->speed_switch_countdown;
|
||||
cycles -= old_cycles;
|
||||
gb->speed_switch_countdown = 0;
|
||||
GB_advance_cycles(gb, old_cycles);
|
||||
gb->cgb_double_speed ^= true;
|
||||
}
|
||||
}
|
||||
gb->apu.pcm_mask[0] = gb->apu.pcm_mask[1] = 0xFF; // Sort of hacky, but too many cross-component interactions to do it right
|
||||
// Affected by speed boost
|
||||
gb->dma_cycles += cycles;
|
||||
@ -378,6 +394,8 @@ void GB_advance_cycles(GB_gameboy_t *gb, uint8_t cycles)
|
||||
cycles <<= 1;
|
||||
}
|
||||
|
||||
gb->absolute_debugger_ticks += cycles;
|
||||
|
||||
// Not affected by speed boost
|
||||
if (gb->io_registers[GB_IO_LCDC] & 0x80) {
|
||||
gb->double_speed_alignment += cycles;
|
||||
|
Loading…
Reference in New Issue
Block a user