Skip to content
Game 0 Unit 9 of 16 1 hr learning time

A Finger on the Boxes

Stop baking the address into every instruction. Meet indexed addressing — X as a finger you slide along the memory street, writing as it goes — the idea behind every loop that fills the screen.

56% of Meet The Machine

Back in Unit 5 you wrote a block to the screen: sta $0400. The address $0400 was baked into the instruction. To write the box next to it you'd need a whole new instruction with $0401 baked in, then $0402, and so on — a fresh line for every box. That doesn't scale, and last unit's repeated stores were the same problem wearing a different hat.

The fix is indexed addressing. Pick up the X register again — last time it just held a number; now we use it as a finger pointing into the memory street:

  • ldx #0 — put the finger at offset 0.
  • sta $0400,x — store into the box at $0400 plus X — wherever the finger is resting.
  • inx — slide the finger one box along.

The base $0400 stays put; X is the part that moves. sta $0400,x with X at 2 writes to $0402. Change X, and the same instruction writes somewhere new.

(This is the C64's gentle pointer. The fuller kind — where the address itself lives in memory and can point anywhere, not just "base plus a small offset" — comes later, when a game needs it. For now: a fixed start, a moving finger.)

What you'll see by the end

Three solid red blocks in a row at the top-left of the C64 screen.
Three red blocks from a single STA $0400,X — one write, the index sliding the 'finger' one box along each time.

Three red blocks in a row. We never wrote three addresses — we wrote one, sta $0400,x, and slid the finger between writes. Point, write, step; point, write, step.

Sliding the finger along

; Meet the Machine - Unit 9: A Finger on the Boxes
; Assemble with: acme -f cbm -o finger.prg finger.asm

*= $0801
!byte $0c,$08,$0a,$00,$9e,$32,$30,$36,$31,$00,$00,$00

*= $080d
        ldx #0          ; X is the finger — offset 0
        lda #$a0        ; the block to write
        sta $0400,x     ; shape into box $0400 + X ...
        lda #2          ; red
        sta $d800,x     ; ... and its colour, same finger (Unit 6's two maps)
        lda #$a0        ; reload the block
        inx             ; move the finger one box along
        sta $0400,x
        lda #2
        sta $d800,x
        lda #$a0
        inx
        sta $0400,x
        lda #2
        sta $d800,x
loop    jmp loop

ldx #0 aims the finger at the first box. At each stop the same X reaches both maps from Unit 6 — sta $0400,x lays the block's shape, sta $d800,x colours that same cell red — and then inx slides the finger to the next. Same instructions, three boxes — because the index moved, not the instruction. (The block and the colour swap turns in A, so we reload #$a0 before each write — a small price for one finger driving both maps.)

This is the heart of how every C64 screen gets drawn: an index walking through memory, laying down bytes as it goes.

Assemble and run

acme -f cbm -o finger.prg finger.asm

Three red blocks, drawn by one sliding finger.

Try this: a longer reach

Add another stop — inx, then the shape-and-colour pair again — to draw a fourth block, then a fifth. It works, but you can feel the repetition piling up: every new cell is four more lines. That's exactly the itch the next unit's loop scratches — tell the machine "do this forty times" and let it slide the finger.

If it doesn't work

  • Only one block appears. An inx is missing, so every write lands on the same box. Each write needs a step after it.
  • The blocks are in the wrong place. Check the base is $0400 (the screen). A different base points the finger somewhere else entirely.
  • acme errors on sta $0400,x. That exact form — store, comma, x — is right; check the comma and that it's a lowercase x.

What you've learnt

X is a movable index: sta $0400,x writes to the box at the base plus X, and inx slides the finger to the next — so one instruction can write all the way along memory.

What's next

You've stepped the finger by hand, three times. Next — The Counted Loop — we hand the repetition to the machine: load a count, slide-and-write, step on, and branch back until you've done them all. One loop fills a whole row.