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;
|
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->debugger_ticks = 0;
|
||||||
|
gb->absolute_debugger_ticks = 0;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -532,6 +532,7 @@ struct GB_gameboy_internal_s {
|
|||||||
uint8_t double_speed_alignment;
|
uint8_t double_speed_alignment;
|
||||||
uint8_t serial_count;
|
uint8_t serial_count;
|
||||||
int32_t speed_switch_halt_countdown;
|
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
|
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 */
|
/* Ticks command */
|
||||||
uint64_t debugger_ticks;
|
uint64_t debugger_ticks;
|
||||||
|
uint64_t absolute_debugger_ticks;
|
||||||
|
|
||||||
/* Undo */
|
/* Undo */
|
||||||
uint8_t *undo_state;
|
uint8_t *undo_state;
|
||||||
|
@ -374,6 +374,7 @@ static void leave_stop_mode(GB_gameboy_t *gb)
|
|||||||
gb->cgb_palettes_ppu_blocked = false;
|
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)
|
static void stop(GB_gameboy_t *gb, uint8_t opcode)
|
||||||
{
|
{
|
||||||
flush_pending_cycles(gb);
|
flush_pending_cycles(gb);
|
||||||
@ -387,29 +388,39 @@ static void stop(GB_gameboy_t *gb, uint8_t opcode)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!interrupt_pending) {
|
if (!interrupt_pending) {
|
||||||
/* Todo: is PC being actually read? */
|
|
||||||
cycle_read_inc_oam_bug(gb, gb->pc++);
|
cycle_read_inc_oam_bug(gb, gb->pc++);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Todo: speed switching takes a fractional number of M-cycles. It make
|
/* Todo: speed switching takes 2 extra T-cycles (so 2 PPU ticks in single->double and 1 PPU tick in double->single) */
|
||||||
every active component (APU, PPU) unaligned with the CPU. */
|
|
||||||
if (speed_switch) {
|
if (speed_switch) {
|
||||||
flush_pending_cycles(gb);
|
flush_pending_cycles(gb);
|
||||||
|
|
||||||
if (gb->io_registers[GB_IO_LCDC] & 0x80) {
|
if (gb->io_registers[GB_IO_LCDC] & 0x80 && gb->cgb_double_speed) {
|
||||||
GB_log(gb, "ROM triggered PPU odd mode, which is currently not supported. Reverting to even-mode.\n");
|
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) {
|
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 {
|
else {
|
||||||
gb->speed_switch_freeze = 4;
|
gb->speed_switch_countdown = 6;
|
||||||
}
|
gb->speed_switch_freeze = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
gb->cgb_double_speed ^= true;
|
if (interrupt_pending) {
|
||||||
gb->io_registers[GB_IO_KEY1] = 0;
|
}
|
||||||
|
else {
|
||||||
gb->speed_switch_halt_countdown = 0x20008;
|
gb->speed_switch_halt_countdown = 0x20008;
|
||||||
|
gb->speed_switch_freeze = 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
gb->io_registers[GB_IO_KEY1] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (immediate_exit) {
|
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)
|
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
|
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
|
// Affected by speed boost
|
||||||
gb->dma_cycles += cycles;
|
gb->dma_cycles += cycles;
|
||||||
@ -378,6 +394,8 @@ void GB_advance_cycles(GB_gameboy_t *gb, uint8_t cycles)
|
|||||||
cycles <<= 1;
|
cycles <<= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gb->absolute_debugger_ticks += cycles;
|
||||||
|
|
||||||
// Not affected by speed boost
|
// Not affected by speed boost
|
||||||
if (gb->io_registers[GB_IO_LCDC] & 0x80) {
|
if (gb->io_registers[GB_IO_LCDC] & 0x80) {
|
||||||
gb->double_speed_alignment += cycles;
|
gb->double_speed_alignment += cycles;
|
||||||
|
Loading…
Reference in New Issue
Block a user