Skip to content

Game Loop (Basic)

Simple frame-synchronised game loop using the raster register. Foundation for all C64 games.

Taught in Game 1, Unit 3 game-looprastervic-iitiming

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

AspectCost
CPUBurns cycles waiting for raster
Memory~40 bytes
LimitationCan’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.

Patterns: Joystick Reading | Raster Interrupts

Vault: Inside the VIC-II | Commodore 64

Evolution: Basic → IRQ-DrivenDouble-Buffered