Cycle Accuracy
Emulation timing tiers
Cycle-accurate emulation reproduces what the hardware does on each clock cycle. The sources here show why: games that hang when timing is approximate, chips that steal bus cycles from the CPU by documented rules, and emulator authors who set "cycle-exact" as the goal.
Cycle accuracy is an emulator design goal: reproduce what the hardware does on each clock cycle, rather than per instruction or per frame. The sources held here explain why it matters (games that hang or tear when timing is off), what the hardware does that makes the cycle the unit (a shared bus on the Amiga, a gated CPU clock on the Spectrum, stolen cycles on the C64), and who set it as a goal in print.
Fast facts
- Accuracy vs compatibility: an emulator is compatible if it runs known programs correctly, accurate if it would run an unknown one correctly (NESdev wiki).
- Cannot be measured directly: test ROMs and known-tricky games are the proxy.
- Games that expose it: Battletoads hangs, Super Mario Bros. freezes on its title screen, Crystalis shows a moving seam.
- Stated as a goal: Richard Bannister on his Mac port of bsnes, Retro Gamer 21 (2005): “as accurate as you can get”.
Accuracy and compatibility
The NES development community draws the distinction on its wiki: “Compatibility is how well an emulator produces the same output as the original system when running a particular known program. Accuracy refers to how well an emulator produces the same output as the original system when running an arbitrary unknown program.” An emulator can have the first without the second. NESticle in the 1990s ran a wide selection of commercial games while, for instance, allowing writes to the PPU data port “at any time, while the NES only allows it during scanlines 240-260 of each frame (vertical blanking)” or with rendering forced off. The cost fell on the next generation of programmers: “Inaccuracies like these led to inadvertent development of programs that the NES itself cannot run during the early years of NES homebrew.”
The same page states the limit plainly: “Accuracy cannot be measured directly.” Its footnote gives the reason — measuring an arbitrary emulator’s accuracy “reduces to the halting problem over linear bounded automata” — and the alternative: formally proving equivalence to the netlist of the Visual 2A03 and 2C02 projects. In practice, compatibility with test ROMs and with games that rely on obscure behaviour stands in as the predictor.
What timing-sensitive games expose
The NESdev wiki keeps a list of games that break when an emulator’s timing is approximate:
- Battletoads is “infamous among emulator developers for requiring fairly precise CPU and PPU timing (including the cycle penalty for crossing pages) and a fairly robust sprite 0 implementation.” It streams animation into CHR RAM with rendering off for part of the visible frame, then turns it on; if the background lands too high or too low, “a sprite zero hit will fail to trigger, hanging the game.”
- Super Mario Bros. is “probably the hardest game to emulate among the most popular NROM games”, needing “sprite 0 detection (otherwise the game will freeze on the title screen)” and the one-byte read delay through PPUDATA.
- Crystalis uses the MMC3 scanline counter for a moving vertical split; “Incorrect MMC3 timing will create a moving seam as you wander up and down the map.”
- G.I. Joe turns sprites off and leaves the background on, so “Correct timing of MMC3 IRQs requires that the sprite fetches still clock the scanline counter”.
- Bio Miracle Bokutte Upa modulates Famicom Disk System audio in a way that “requires cycle-accurate timing to emulate correctly.”
The list’s advice for a first target runs the other way: “try anything made in 1984 or earlier, such as Donkey Kong.”
Hardware where the cycle is the unit
Timing matters because the original chips shared a bus and stole time from each other, and the machines’ own documentation says so.
Amiga. The Amiga Hardware Reference Manual (1989) sets out the priority order on the chip bus: disk, audio, display and sprite DMA first, then the Copper, then the blitter, then the 68000 last. Each horizontal line has “227.5 ‘color clocks’, or memory access cycles”, each “approximately 280 ns in duration”, allocated per line as 4 for memory refresh, 3 for disk, 4 for audio, 16 for sprites and 80 for bit-planes. With more than four bit-planes, “bit-plane DMA will begin to steal cycles from the 68000 during the display” — half the processor’s slots in a six-plane low-resolution screen. An emulator that ignores the slot allocation runs code at the wrong speed whenever the display is busy. See Agnus.
ZX Spectrum. The ULA has to share the lower 16K of RAM with the Z80. Chris Smith’s reverse-engineering of the chip (The ZX Spectrum ULA, 2010) describes Richard Altwasser’s solution: rather than wait states or bus requests, the ULA pauses the processor by “stopping the clock signal it sends to the Z80 at stra[te]gic T-states, whenever it detects a contention condition is about to occur.” The book also records that the contention controller went through several revisions during manufacture because early ULA versions “contained” errors “that affected the reliability of the machine” — so a cycle-accurate Spectrum emulator must also choose which ULA issue it reproduces.
Commodore 64. The VIC-II steals cycles from the 6510 to fetch character and sprite data, and the demo scene wrote its own literature on programming around it. The Codebase64 index lists Marko Mäkelä’s “Making stable raster routines”, Pasi Ojala’s “Missing Cycles - Syncing with a sprite” from C=Hacking 3, Jackasser’s “Stable timing approaches” series and tfg’s “cycle exact measuring of routine execution times”. Code written to these depends on the stolen cycles landing where the chip puts them. See stable raster and raster interrupts.
“Cycle-exact” as a goal
Richard Bannister, who ported 28 emulators to the Macintosh starting with Frodo, told Retro Gamer in 2005 that the work he was proudest of was “the cycle-exact emulators I’ve converted. Traditional emulators often take shortcuts to run at acceptable speeds on today’s hardware. Although this rarely affects emulated software, it’s nice to see all these hacks removed for true authenticity. The most recent example from me is BSNES, which only attains full speed on the fastest Macs Apple has produced, but the end result is as accurate as you can get.” The trade is stated in the same breath: authenticity against speed. On why it is worth it: “Major titles — Pac-Man, Sonic, et al — will always be preserved, but many others would be lost without emulation to keep them alive.” bsnes was byuu’s work; Bannister’s was the port.
Not every platform reached that bar. The ZX Spectrum Next wiki notes, in passing, that emulating “in less than cycle-accurate way” had “become a ‘norm’ for classic ZX Spectrum after two decades of emulators development”, and tells developers to test on real hardware. And the goal has an open end: the SNESdev wiki’s “Open Problems in Accurate SNES Emulation” still asks “What exactly happens in the DMA crash bug on the v1 CPU?” and what the exact timing of the garbage is when a mode switches mid-frame, adding that “Most of these problems require access to a logic analyzer.”
Emu198x takes cycle accuracy as its standard for the same reason the NESdev page gives: code written on an approximate emulator may not run on the machine.