Stable Raster
Cycle-exact timing
The double-IRQ technique that achieves cycle-exact synchronisation with the VIC-II raster beam, enabling perfect mid-screen effects on the Commodore 64.
Overview
Stable raster is the Commodore 64 technique for achieving cycle-exact synchronisation with the VIC-II's raster beam. Because the CPU and VIC-II share the bus, interrupt timing has inherent jitter (0-7 cycles). The stable raster technique eliminates this jitter, enabling perfectly timed mid-screen effects.
Fast Facts
| Aspect | Detail |
|---|---|
| Problem | IRQ timing varies by 0-7 cycles |
| Solution | Double-IRQ with self-modifying code |
| Precision | Cycle-exact (0 jitter) |
| Used for | Border removal, split screens, colour bars |
The Jitter Problem
When a raster interrupt fires, the CPU might be mid-instruction:
| Instruction Length | Jitter |
|---|---|
| 2 cycles | 0-2 cycle variation |
| 3 cycles | 0-3 cycle variation |
| 7 cycles | 0-7 cycle variation |
This jitter causes visible glitches in timing-sensitive effects.
The Double-IRQ Solution
The technique uses two interrupts:
| IRQ | Purpose |
|---|---|
| First IRQ | Sets up second IRQ one line later |
| Second IRQ | Triggers inside a long NOP slide |
Step by Step
- First IRQ fires with unknown jitter
- Set second IRQ for next raster line
- Execute NOP slide (many 2-cycle NOPs)
- Second IRQ fires inside NOP slide
- Jitter is now only 0-1 cycles
- Measure exact cycle position
- Compensate with calculated delay
Code Structure
; First IRQ - unstable, sets up second one line later
first_irq:
lda #<second_irq
sta $0314 ; Point CINV at second handler
lda #>second_irq
sta $0315
inc $d012 ; Next IRQ one line down
lda #$01
sta $d019 ; Acknowledge
tsx
cli ; Re-enable IRQs (so second can fire)
nop : nop : nop : nop : nop : nop : nop : nop
; ... long NOP slide ...
; The second IRQ will fire somewhere inside this slide,
; at one of two cycle positions (jitter is now 0 or 1).
; Second IRQ - stabilised
second_irq:
; Read $d012 to compensate for the remaining 0-1 cycle jitter
lda $d012
cmp $d012 ; If line just changed, branch to align
beq @aligned
@aligned:
; Now cycle-exact — perform the effect
sta $d020 ; Example: change border colour
; ... acknowledge and exit ...
The standard idiom is "first IRQ enables nested IRQ, NOP slide gives the second IRQ a known entry point, then a CMP+BEQ trick eliminates the last cycle of jitter." This is the backbone of every cycle-exact C64 effect.
Why It Works
| Mechanism | Effect |
|---|---|
| NOP slide | All instructions same length (2 cycles) |
| Maximum jitter = 1 | Only 0 or 1 cycle variation |
| Cycle counting | Determine exact position |
| Branch compensation | Conditional delay to align |
Applications
| Effect | Requirement |
|---|---|
| Border removal | Exact $D011 / $D016 bit-3 writes at cycle-precise raster positions |
| Raster bars | Colour changes per scanline |
| Split screens | Mode changes mid-frame (text/bitmap split, multicolour switch) |
| FLD (Flexible Line Distance) | Manipulate $D011 YSCROLL to space rendered lines vertically — produces the "stretchy screen" effect |
| FLI (Flexible Line Interpretation) | Per-line $D018 change combined with forced badlines — yields 8 colours per 8×8 cell |
| Tech-tech | Per-line $D016 XSCROLL change so text undulates in a sine wave |
Historical Development
| Era | Advancement |
|---|---|
| 1986 | Basic double-IRQ discovered |
| 1987 | Refined techniques |
| 1990s | Demo scene mastery — Crest's Wonderland series, Censor Design's productions |
| Today | Still essential for C64 effects; modern toolchains (KickAssembler, Acme) treat stable raster as a standard preamble |
Crest's Wonderland XII (1996) is the canonical reference demo for stable raster — every effect in it relies on cycle-exact raster timing.
Performance Cost
| Factor | Impact |
|---|---|
| CPU time | Two IRQs per stable point |
| Code space | NOP slides, handler code |
| Complexity | Requires deep understanding |
Modern Relevance
Understanding stable raster teaches:
- Interrupt handling fundamentals
- Cycle-exact timing
- Hardware synchronisation
- Why modern GPUs use VSync