Overview
Synchronise your game to the display by waiting for a specific raster line. This prevents tearing and gives consistent timing at 50fps (PAL) or 60fps (NTSC). Use for simple games; graduate to IRQ-driven loops for more complex timing needs.
Code
; =============================================================================
; GAME LOOP - BASIC (RASTER SYNC)
; Wait for vertical blank, then run game logic
; Taught: Game 1 (SID Symphony), Unit 3
; CPU: Variable (waits for raster) | Memory: ~40 bytes
; =============================================================================
VIC_RASTER = $D012 ; Current raster line (low 8 bits)
VIC_CTRL1 = $D011 ; VIC control register 1 (bit 7 = raster bit 8)
SYNC_LINE = 250 ; Line to sync on (in lower border)
; Main game loop with raster sync
game_loop:
; Wait for raster to reach sync line
- lda VIC_RASTER
cmp #SYNC_LINE
bne -
; Optional: wait for raster to leave sync line
; (prevents running twice if loop is very fast)
- lda VIC_RASTER
cmp #SYNC_LINE
beq -
; === GAME LOGIC GOES HERE ===
jsr read_input
jsr update_game
jsr draw_screen
; ============================
jmp game_loop
Usage:
; Initialisation
jsr init_game
; Enter main loop
jmp game_loop
Trade-offs
| Aspect | Cost |
|---|---|
| CPU | Burns cycles waiting for raster |
| Memory | ~40 bytes |
| Limitation | Can’t do work during wait; no badline handling |
When to use: Simple games, prototypes, learning projects.
When to avoid: Games needing precise timing, raster effects, or maximum CPU utilisation.
Related
Patterns: Joystick Reading | Raster Interrupts
Vault: Inside the VIC-II | Commodore 64
Evolution: Basic → IRQ-Driven → Double-Buffered