Skip to content

Commit 1a96364

Browse files
committed
Fix counter scheduling when target equals max value
When target is 0xFFFF, the CountToTarget and CountToOverflow events coincide at the same counter value. Skip the redundant target phase and schedule CountToOverflow directly, so the overflow flag is visible on the first mode register read without requiring two update() calls. Restore small target values for tests that only check flag presence, keeping the larger target only for the back-to-back read test. Signed-off-by: Nicolas 'Pixel' Noble <nicolas@nobis-crew.org>
1 parent 76df40a commit 1a96364

2 files changed

Lines changed: 10 additions & 4 deletions

File tree

src/core/psxcounters.cc

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,13 @@ inline void PCSX::Counters::writeCounterInternal(uint32_t index, uint32_t value)
4848
// The comparison boundary needs more precise measurement to determine if
4949
// reset happens on the same cycle as reaching target or the next cycle.
5050
// TODO: determine exact reset timing with cycle-accurate measurement.
51-
if (value < m_rcnts[index].target) {
51+
// Schedule next event: target hit first (for flag/IRQ), then overflow.
52+
// If RcCountToTarget is not set, the counter doesn't reset at target,
53+
// but bit 11 (RcCountEqTarget) is still set when the counter passes
54+
// the target value. However, if target == 0xFFFF, the target and
55+
// overflow events coincide - skip straight to overflow to avoid
56+
// redundant processing.
57+
if (value < m_rcnts[index].target && m_rcnts[index].target != 0xffff) {
5258
m_rcnts[index].cycle = m_rcnts[index].target * m_rcnts[index].rate;
5359
m_rcnts[index].counterState = CountToTarget;
5460
} else {

src/mips/tests/timers/timers.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -159,15 +159,15 @@ CESTER_TEST(timerModeWriteResetsCounter, timer_tests,
159159
* ================================================================= */
160160
CESTER_TEST(timerHitTargetFlagSetAndCleared, timer_tests,
161161
/* Warmup pass to prime icache */
162-
COUNTERS[2].target = 0x0010;
162+
COUNTERS[2].target = 0x1000;
163163
COUNTERS[2].mode = TM_RESET_TARGET;
164-
BUSY_WAIT(500);
164+
BUSY_WAIT(50000);
165165
(void)COUNTERS[2].mode;
166166
(void)COUNTERS[2].mode;
167167

168168
/* Real measurement */
169169
COUNTERS[2].mode = TM_RESET_TARGET;
170-
BUSY_WAIT(500);
170+
BUSY_WAIT(50000);
171171

172172
uint16_t mode1 = COUNTERS[2].mode;
173173
uint16_t mode2 = COUNTERS[2].mode;

0 commit comments

Comments
 (0)