Skip to content

Joystick Reading

Read joystick input from CIA#1 for player control. Simple, reliable, and cycle-efficient.

Taught in Game 1, Unit 4 joystickciainput

Overview

Read the joystick by checking CIA#1 data port A ($DC00). Each direction and the fire button is a single bit, active low (0 = pressed). Use when you need simple, responsive player control with minimal CPU overhead.

Code

; =============================================================================
; JOYSTICK READING - BASIC
; Read joystick 2 from CIA#1
; Taught: Game 1 (SID Symphony), Unit 4
; CPU: ~20 cycles | Memory: ~30 bytes
; =============================================================================

CIA1_PRA    = $DC00     ; CIA#1 Data Port A (joystick 2)

JOY_UP      = %00000001
JOY_DOWN    = %00000010
JOY_LEFT    = %00000100
JOY_RIGHT   = %00001000
JOY_FIRE    = %00010000

; Read joystick and store state
; Returns: A = raw joystick bits (inverted: 0 = pressed)
read_joystick:
    lda CIA1_PRA        ; Read joystick port
    eor #$FF            ; Invert so 1 = pressed
    rts

; Check if specific direction/button pressed
; Usage: jsr read_joystick, then check with AND
;
; Example:
;   jsr read_joystick
;   and #JOY_FIRE
;   bne fire_pressed

Usage:

game_loop:
    jsr read_joystick
    sta joy_state       ; Store for multiple checks

    and #JOY_UP
    beq +
    dec player_y        ; Move up
+   lda joy_state
    and #JOY_DOWN
    beq +
    inc player_y        ; Move down
+   ; ... continue for left/right/fire
    jmp game_loop

Trade-offs

AspectCost
CPU~20 cycles per read
Memory~30 bytes
LimitationNo debouncing (fire button may register multiple times)

When to use: Any game needing joystick input. Start here.

When to avoid: Menu systems where you want button debouncing.

Patterns: Game Loop (Basic)

Vault: Commodore 64

Evolution: Basic → Debounced