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.
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$0400plusX— 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 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
inxis 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. acmeerrors onsta $0400,x. That exact form — store, comma,x— is right; check the comma and that it's a lowercasex.
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.