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
| Aspect | Cost |
|---|---|
| CPU | ~20 cycles per read |
| Memory | ~30 bytes |
| Limitation | No 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.
Related
Patterns: Game Loop (Basic)
Vault: Commodore 64
Evolution: Basic → Debounced