The Machine Trusts You
The last unit, and the most important. There's no error message, no bounds check, no guard rail — the machine does exactly what you wrote, even when you're wrong. Learn to debug by observing, not by reading errors.
Every unit so far ended with something that worked. This one ends with something that's wrong — on purpose — because the single most important thing to learn about this machine is what it does when you are wrong.
What you'll see by the end
That was supposed to be one row of 40. It's six and a bit. The machine filled precisely 255 cells — right down to the last one — because 255 is the number we wrote. It is only a "mistake" because we know we meant 40. The machine couldn't know, and didn't ask.
The bug, running
; Meet the Machine - Unit 15: The Machine Trusts You
; Assemble with: acme -f cbm -o oops.prg oops.asm
*= $0801
!byte $0c,$08,$0a,$00,$9e,$32,$30,$36,$31,$00,$00,$00
*= $080d
ldx #0
fill lda #$a0
sta $0400,x ; shape
lda #2 ; red
sta $d800,x ; colour, same cell
inx
cpx #255 ; BUG: we meant 40 (one row)
bne fill
loop jmp loop
This is the row-fill from The Counted Loop with one wrong number: cpx #255 where we meant cpx #40. It assembled without a murmur — a wrong count is not a wrong spelling, so the assembler had nothing to object to. Then it ran exactly as written, laying 255 blocks across six rows.
There is no safety net
In BASIC, mistakes were met with a friendly stop: ?SYNTAX ERROR, ?ILLEGAL QUANTITY, ?OUT OF MEMORY. The language watched over you and halted when something looked off.
The bare machine does none of that. There is no bounds check, no type check, no "are you sure," no error at all. Write past where you meant to, point at the wrong address, leave a jsr without its rts — and the 6510 does exactly what the bytes say and carries straight on, overwriting whatever it touches, never pausing to warn you. The machine trusts you completely. That trust is the freedom that lets you draw the screen with a single store — and the responsibility that means every byte is yours to get right.
So debugging here is a different craft. It is not reading an error message, because there isn't one. It is observing the state — the register view, the memory view, the stack you watched in Call, Return, and a Stack — and reasoning about what the machine did versus what you meant. Every view you've leaned on through this Primer was you learning to debug by looking. That's the discipline the whole course rests on.
Assemble and run
acme -f cbm -o oops.prg oops.asm
Six rows of red blocks where you wanted one — and not a word of complaint.
Try this: it was never broken — your number was
Change cpx #255 to cpx #40. One clean row. Nothing about the machine changed; only your number did. That's the whole lesson in one edit: the machine was doing its job perfectly the entire time.
Try this: break it a different way
Change the shape load lda #$a0 to lda #1 (screen code for A) and run the buggy 255 version again. Now six rows fill with red letter As instead of blocks — the same faithful execution of a different wrong intention. Predict what you'll see before you run it, then confirm. Again: no error, just the wrong thing done exactly.
If it doesn't work
- The machine seems to freeze or the screen fills further than expected. Push the count higher and the fill runs past the screen into other memory — exactly the "no guard rail" lesson biting for real. Reset, and bring the count back down.
- Nothing happens at all. The
fillloop or itsbneis mistyped, so the body never runs. Compare against the listing. - You wanted it to misbehave and it didn't. Then you fixed the bug — the happiest failure on this page.
What you've learnt
The machine has no safety net: it does exactly what you wrote, even when you're wrong, and never warns you — so you debug by observing the state, not by reading errors.
What's next — you've met the machine
That's the Primer. Look back at what stopped being magic: the build-run loop; the three registers; bytes with no type; memory as a street of boxes; the screen and its colour as just memory; decisions built from test-and-branch; reading the joystick; the sliding index; counted loops; subroutines and the stack; arithmetic and the carry it makes you mind; setting and clearing bits; numbers bigger than a byte; making the SID sing — and now the mindset that ties it together.
You haven't built a game yet — that's the point. You've built the understanding a game needs. Next comes Starfield, your first complete game, where this all turns into something you play — and where the two things we deliberately left open get solved: reading the whole joystick at once (The Machine Can Hear You), and the movable pointer that writes through an address you compute (A Finger on the Boxes), each resolved exactly when the game needs it.
Go and write something the machine will trust you to get right.