Make VBLANK_CYCLES editable at runtime

This change replaces the constant `VBLANK_CYCLES` with a global variable that can be edited at runtime. This allows the timing to be changed by other code, which is needed for PAL support.
This commit is contained in:
Biggs McWedge
2026-08-29 23:35:27 +01:00
committed by Biggs
parent cd6b16b900
commit 96c3a46ebd
+9 -9
View File
@@ -178,8 +178,8 @@ void psx_irq_raise(uint32_t bit, uint32_t detail)
/* Dispatch counter for vblank scheduling. */
#define VBLANK_INTERVAL 50000 /* legacy: dispatch-count fallback (unused for VBlank gating now) */
#define VBLANK_CYCLES 564480u /* 33.8688 MHz / 60 Hz — real PSX NTSC VBlank period */
#define VBLANK_DEFER_STALE_CYCLES (VBLANK_CYCLES * 10ull)
#define VBLANK_DEFER_STALE_CYCLES (vblank_cycles * 10ull)
uint32_t vblank_cycles = 564480u; /* 33.8688 MHz / 60 Hz — real PSX NTSC VBlank period */
static uint32_t dispatch_count;
static uint64_t total_checks;
static uint32_t cycles_since_vblank; /* incremented by interrupts_advance_cycles */
@@ -471,13 +471,13 @@ static void fire_vblank_edge(void) {
/* Subtract one VBlank period rather than reset to 0 so cycle overshoot
* carries forward. Prevents long-running blocks from rounding multiple
* VBlanks together. */
cycles_since_vblank -= VBLANK_CYCLES;
cycles_since_vblank -= vblank_cycles;
dispatch_count = 0;
/* DEQUEUE: this VBlank fired. ENQUEUE: next VBlank scheduled one period out. */
event_ring_record_aux(EV_DEQ, (uint8_t)SRC_VBLANK,
(uint32_t)psx_get_cycle_count());
event_ring_record_aux(EV_ENQ, (uint8_t)SRC_VBLANK,
(uint32_t)(psx_get_cycle_count() + VBLANK_CYCLES));
(uint32_t)(psx_get_cycle_count() + vblank_cycles));
psx_irq_raise(IRQ_VBLANK, 0);
g_vblank_raise_count++;
event_ring_record(EV_ISTAT_RAISE, IRQ_VBLANK);
@@ -493,15 +493,15 @@ static void fire_vblank_edge(void) {
void interrupts_service_scheduled_events(void) {
note_sio_progress_cycle();
if (in_exception) return;
while (cycles_since_vblank >= VBLANK_CYCLES) {
while (cycles_since_vblank >= vblank_cycles) {
if (should_defer_vblank_for_sio()) return;
fire_vblank_edge();
}
}
uint32_t interrupts_cycles_to_vblank(void) {
if (cycles_since_vblank >= VBLANK_CYCLES) return 0;
return VBLANK_CYCLES - cycles_since_vblank;
if (cycles_since_vblank >= vblank_cycles) return 0;
return vblank_cycles - cycles_since_vblank;
}
uint32_t interrupts_get_cycles_since_vblank(void) {
@@ -984,8 +984,8 @@ uint32_t cycles_to_next_event(void) {
* card-SIO case only pushes VBlank LATER, so this estimate stays a safe
* under-estimate. */
if (i_mask & (1u << IRQ_VBLANK)) {
uint32_t d = (cycles_since_vblank >= VBLANK_CYCLES)
? 0u : (VBLANK_CYCLES - cycles_since_vblank);
uint32_t d = (cycles_since_vblank >= vblank_cycles)
? 0u : (vblank_cycles - cycles_since_vblank);
if (d < best) best = d;
}
uint32_t t = timers_cycles_to_irq(i_mask); if (t < best) best = t;