The Counted Loop
Hand the repetition to the machine. Load a count, run the body, step on, and branch back until you've done them all — one loop fills a whole row where last unit you stepped by hand.
Last unit you slid the finger by hand — write, step, write, step — and you could feel the repetition piling up. Three blocks was fine; forty would be absurd. So you don't write it forty times. You tell the machine to.
That's a loop, and you build it from pieces you already have: an index, a step, and the test-then-branch from Unit 7.
ldx #0— startX, our finger and our counter, at 0.inx— step it on after each write.cpx #40— compareXwith 40: have we done them all?bne fill— if not equal yet, branch back and go round again.
Put the body between the start and the cpx, and it runs once for each value of X from 0 up to 39. It's BASIC's FOR I = 0 TO 39 … NEXT, assembled from an index and a branch you already know.
What you'll see by the end
A red bar clear across the top — the whole 40-cell top row, painted by a loop that ran the same body forty times. You wrote that body once.
The loop
; Meet the Machine - Unit 10: The Counted Loop
; Assemble with: acme -f cbm -o loop.prg loop.asm
*= $0801
!byte $0c,$08,$0a,$00,$9e,$32,$30,$36,$31,$00,$00,$00
*= $080d
ldx #0 ; X is the counter AND the finger — start at 0
fill lda #$a0 ; the block ...
sta $0400,x ; ... into the cell the finger rests on
lda #2 ; red
sta $d800,x ; colour the same cell, same X (Unit 6's two maps)
inx ; step on / bump the count
cpx #40 ; done all 40 cells?
bne fill ; if not, go round again
loop jmp loop
The body is Unit 9's shape-and-colour pair — sta $0400,x then sta $d800,x, both indexed by the same finger. The new part is the wrapper: ldx #0 sets the finger going, inx steps it, and cpx #40 / bne fill asks "done yet?" each pass and goes round if not. X does double duty — it's both where to write and how many we've done. The finger walks all 40 cells; the bar appears.
(There's a leaner way the CPU quietly prefers — counting down to zero, where the test comes free and you can drop the cpx entirely. It takes one small trick to line up, so we'll save it for later, once the plain loop is second nature. Counting up is the clearer place to start.)
Assemble and run
acme -f cbm -o loop.prg loop.asm
One loop, a full red row.
Try this: change the count
Set cpx #20 for half a row, cpx #10 for ten cells. The number in the cpx is your FOR I = 0 TO N-1 — it's the loop's whole story. Predict how much of the row fills before you run it.
Try this: a different colour
Change lda #2 (the colour load inside the loop) to another value, 0 to 15. The whole bar repaints in one go — because the colour write rides the same finger as the shape, every cell you fill gets the new colour for free.
If it doesn't work
- Only one cell fills. The
inxis missing or sits outside the loop, so every pass writes the same box. The step belongs inside, before thecpx. - The whole screen fills with blocks. Your
cpxvalue is too big, or it's missing entirely so the loop never stops at the right place. Check it readscpx #40. acmecan't findfill. The label and thebne fillmust match exactly, case and all — labels are the assembler's rule, from Unit 7.
What you've learnt
ldx #0, a body, inx, then cpx #N / bne runs the loop body N times — an index that's also the counter — so one loop does what would be N lines by hand.
What's next
Your programs are growing, and chunks of them want names. Next — Call, Return, and a Stack You Can See — we package a job into a subroutine you can jsr to from anywhere and rts from, and watch where the machine remembers its way back: the stack, sitting in plain memory.