Published September 30, 2026 | Version v1

Where the Frame Goes

Authors/Creators

Description

A rebuilt Street Fighter III: 3rd Strike program can reproduce the game's logic and still disagree with the original about which frames slow down. This report locates the mechanism that decides slowdown in the emulator most players use, and measures it. The game's operating system runs eight coroutine tasks from a round-robin scheduler; the VBlank interrupt re-arms sleeping tasks, and a task that is still running at VBlank is simply not re-armed, so an overrun costs exactly one frame with no catch-up. Fightcade's FBNeo build installs an idle shortcut on the scheduler's read of task~0's state byte. \textbf{Disassembly shows that this read is the first instruction of every scheduler pass, so the shortcut fires immediately after the VBlank handler has made the game runnable, and the CPU stays suspended until the emulator's periodic IRQ10, which is asserted every third 104,166-cycle slice. The game's frame work therefore begins at a slice boundary and has 3, 2 or 1 slices left before the next VBlank, rotating with a period of three frames.} A whole-RAM-exact model of that build, run on four recorded episodes (4,660 frames), confirms the schedule and measures the case a rebuild team reports as their first failure, the entry screen wipe. \textbf{The pass that starts the wipe takes 278,000--302,000 cycles and fits only a three-slice window, by under 10,000 cycles in one episode; in the other two phases it loses a frame. Each wipe-in frame then takes 87,000--101,000 cycles, and every third one lands in a one-slice window with 2,803--16,841 cycles to spare: the nine tightest margins in the whole dataset.} Ordinary play, by contrast, takes a median of about 52,000 cycles and never approaches a deadline. The earlier finding that the free-running-timer compare event is usually missed is explained by the same suspension and is shown to be gameplay-inert: the timer handler only debounces the coin and start switches. A specific claim that a 26-cycle compiler difference in \file{move_effect_work} flips a slowdown decision is checked against the ROM and the emulator's cycle table; \textbf{the arithmetic holds, but the decision it flips is a property of one emulator's schedule, not of the arcade board, and it depends on the frame's position in the three-frame rotation.} Upstream FBNeo keeps the same shortcut and cadence with a different budget, cycle carry and a delayed palette-DMA interrupt; MAME has neither the shortcut nor the periodic IRQ10. \textbf{Two emulators, or two revisions of one, therefore give different answers to ``does the arcade slow down here'', and a rebuild judged against a moving oracle can appear to miss slowdowns for reasons unrelated to its code.

Files

cps3_timing.pdf

Files (358.9 kB)

Name Size
md5:eec15b9e95a73b5450d4ec3f2a19f128
317.0 kB Preview Download
md5:a3d0730132b6022329916be46cc805b0
41.9 kB Download