Timers: Correctly handle sync mode 0/3 for timer 2

pull/3745/head
Stenzek 4 months ago
parent d7464e2951
commit 2467a7b1b5
No known key found for this signature in database

@ -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<InterruptController::IRQ>(static_cast<u32>(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;

Loading…
Cancel
Save