Level 28: Moving Dot

Open the level →

Task

Write a program that moves a dot on the screen using the gamepad.

For a moving dot:

Related Materials

Solution

In assembly there are no variables — there is a memory map. We ourselves agree: RAM[0] is X, RAM[1] is Y. This agreement holds for the rest of the program: break it in one place and the program silently breaks. The coordinates "live" in RAM, and the code only reads and rewrites them.

1. Store X and Y coordinates in RAM (e.g. RAM[0]=X, RAM[1]=Y). 2. Each step, read gamepad: LDA 254 (port 0xFE). Buttons: bit 0=Up, 1=Down, 2=Left, 3=Right. 3. Update X/Y in RAM based on pressed buttons (compare via SUB+JN/JZ). 4. Clear old pixel: STA 255 with Acc=0. 5. Write new X/Y via ports 252/253. 6. Light pixel: STA 255 with Acc=1. 7. Loop via JMP.

Tip: start with a simple program that draws a dot at a fixed position. The checkpoint will verify writing to (3,5).

Complete program (moves the dot with the gamepad; the same program is inserted by the in-game hint button):

; RAM: RAM[0]=X, RAM[1]=Y; constants:
;   RAM[2]=1, RAM[3]=2, RAM[4]=4, RAM[5]=8, RAM[6]=15
; Ports: 252=MatrixX, 253=MatrixY, 254=gamepad, 255=pixel
init:
  LDA 7
  STA 0              ; X = 7
  LDA 7
  STA 1              ; Y = 7
  LDA 1
  STA 2              ; const 1
  LDA 2
  STA 3              ; const 2
  LDA 4
  STA 4              ; const 4
  LDA 8
  STA 5              ; const 8
  LDA 15
  STA 6              ; const 15
loop:
  ; 1. Erase the old pixel
  LDA 0
  ADD 0              ; Acc = X
  STA 252            ; MatrixX
  LDA 0
  ADD 1              ; Acc = Y
  STA 253            ; MatrixY
  LDA 0
  STA 255            ; pixel = 0
  ; 2. Read the gamepad
  LDA 0
  ADD 254            ; Acc = buttons
  STA 7
  JZ draw            ; no buttons — just redraw
  ; Up (bit 0)
  LDA 0
  ADD 7
  AND 2              ; & 1
  JZ chk_dn
  LDA 0
  ADD 1
  SUB 2              ; Y - 1
  AND 6              ; & 15 — wrap around the edge
  STA 1
  JMP draw
chk_dn:
  ; Down (bit 1)
  LDA 0
  ADD 7
  AND 3              ; & 2
  JZ chk_lt
  LDA 0
  ADD 1
  ADD 2              ; Y + 1
  AND 6
  STA 1
  JMP draw
chk_lt:
  ; Left (bit 2)
  LDA 0
  ADD 7
  AND 4              ; & 4
  JZ chk_rt
  LDA 0
  ADD 0
  SUB 2              ; X - 1
  AND 6
  STA 0
  JMP draw
chk_rt:
  ; Right (bit 3)
  LDA 0
  ADD 7
  AND 5              ; & 8
  JZ draw
  LDA 0
  ADD 0
  ADD 2              ; X + 1
  AND 6
  STA 0
draw:
  ; 3. Draw the dot at its new position
  LDA 0
  ADD 0
  STA 252
  LDA 0
  ADD 1
  STA 253
  LDA 1
  STA 255            ; pixel = 1
  ; 4. Delay
  NOP
  NOP
  NOP
  NOP
  JMP loop
HLT

Assembler help →