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

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.

63% of Meet The Machine

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 — start X, our finger and our counter, at 0.
  • inx — step it on after each write.
  • cpx #40 — compare X with 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 solid red bar running the full width of the screen, near the top.
The whole 40-cell top row, painted by a loop that ran one body forty times — written once.

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 inx is missing or sits outside the loop, so every pass writes the same box. The step belongs inside, before the cpx.
  • The whole screen fills with blocks. Your cpx value is too big, or it's missing entirely so the loop never stops at the right place. Check it reads cpx #40.
  • acme can't find fill. The label and the bne fill must 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.