diff --git a/src/core/timers.cpp b/src/core/timers.cpp index 1b580f6e8..c3b6edd26 100644 --- a/src/core/timers.cpp +++ b/src/core/timers.cpp @@ -64,7 +64,7 @@ struct CounterState } // namespace -static void UpdateCountingEnabled(CounterState& cs); +static void UpdateCountingEnabled(u32 index, CounterState& cs); static void CheckForIRQ(u32 index, u32 old_counter); static void AddSysClkTicks(void*, TickCount sysclk_ticks); @@ -198,7 +198,7 @@ void Timers::SetGate(u32 timer, bool state) UnreachableCode(); } - UpdateCountingEnabled(cs); + UpdateCountingEnabled(timer, cs); UpdateSysClkEvent(); } @@ -432,7 +432,7 @@ void Timers::WriteRegister(u32 offset, u32 value) InterruptController::SetLineState( static_cast(static_cast(InterruptController::IRQ::TMR0) + timer_index), false); - UpdateCountingEnabled(cs); + UpdateCountingEnabled(timer_index, cs); CheckForIRQ(timer_index, cs.counter); UpdateSysClkEvent(); } @@ -454,32 +454,41 @@ void Timers::WriteRegister(u32 offset, u32 value) } } -void Timers::UpdateCountingEnabled(CounterState& cs) +void Timers::UpdateCountingEnabled(u32 index, CounterState& cs) { - if (cs.mode.sync_enable) + if (index != 2) { - switch (cs.mode.sync_mode) + if (cs.mode.sync_enable) { - case SyncMode::PauseWhileGateActive: - cs.counting_enabled = !cs.gate; - break; + switch (cs.mode.sync_mode) + { + case SyncMode::PauseWhileGateActive: + cs.counting_enabled = !cs.gate; + break; - case SyncMode::ResetOnGateEnd: - cs.counting_enabled = true; - break; + case SyncMode::ResetOnGateEnd: + cs.counting_enabled = true; + break; - case SyncMode::ResetAndRunOnGateStart: - case SyncMode::FreeRunOnGateEnd: - cs.counting_enabled = cs.gate; - break; + case SyncMode::ResetAndRunOnGateStart: + case SyncMode::FreeRunOnGateEnd: + cs.counting_enabled = cs.gate; + break; - default: - UnreachableCode(); + default: + UnreachableCode(); + } + } + else + { + cs.counting_enabled = true; } } else { - cs.counting_enabled = true; + // Timer 2 doesn't have a gate source. With sync enabled, modes 0/3 stop counting and 1/2 free-run. + cs.counting_enabled = (!cs.mode.sync_enable || cs.mode.sync_mode == SyncMode::ResetOnGateEnd || + cs.mode.sync_mode == SyncMode::ResetAndRunOnGateStart); } cs.external_counting_enabled = cs.use_external_clock && cs.counting_enabled;