The Machine Trusts You
The last unit, and the most important. There's no error message, no bounds check, no guard rail — the 68000 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 a small block, twenty-four rows tall, the way Unit 6 drew one. It's a column the full height of the screen. The machine filled exactly 256 rows — every one — because 256 is the number we wrote. It is only a "mistake" because we know we meant 24. The machine couldn't know, and didn't ask.
The bug, running
;──────────────────────────────────────────────────────────────
; Meet the Machine (Amiga) - Unit 19: The Machine Trusts You
;
; This program has a bug, on purpose. We MEANT to draw a small 24-row block,
; the way Unit 6 did. We wrote 256 instead - the height of the whole screen -
; and the machine drew exactly that. No warning, no error. It trusts the number.
;──────────────────────────────────────────────────────────────
CUSTOM equ $dff000
DMACON equ $096
INTENA equ $09a
INTREQ equ $09c
COP1LC equ $080
COPJMP1 equ $088
DIWSTRT equ $08e
DIWSTOP equ $090
DDFSTRT equ $092
DDFSTOP equ $094
BPLCON0 equ $100
BPL1MOD equ $108
BPL1PTH equ $0e0
BPL1PTL equ $0e2
COLOR00 equ $180
COLOR01 equ $182
ROWBYTES equ 40
BPHEIGHT equ 256
BPSIZE equ ROWBYTES*BPHEIGHT
section code,code_c
start:
lea CUSTOM,a5
move.w #$7fff,INTENA(a5)
move.w #$7fff,INTREQ(a5)
move.w #$7fff,DMACON(a5)
; --- clear the bitplane to all 0 ---
lea bitplane,a0
move.w #(BPSIZE/4)-1,d0
.clr: clr.l (a0)+
dbra d0,.clr
; ----------------------------------------------- YOUR CODE START
; We meant a 24-row block. We wrote 256. The machine obeys.
lea bitplane,a0
move.w #256-1,d1 ; <-- the bug: should have been 24-1
.row: move.l #$ffffffff,(a0)
lea ROWBYTES(a0),a0
dbra d1,.row
; ------------------------------------------------- YOUR CODE END
; --- point the display at the bitplane (patch the Copper) ---
lea bitplane,a0
move.l a0,d0
swap d0
move.w d0,bplhi
swap d0
move.w d0,bpllo
lea copperlist,a0
move.l a0,COP1LC(a5)
move.w d0,COPJMP1(a5)
move.w #$8380,DMACON(a5) ; DMA on: master + bitplane + Copper
forever:
bra.s forever
copperlist:
dc.w DIWSTRT,$2c81
dc.w DIWSTOP,$2cc1
dc.w DDFSTRT,$0038
dc.w DDFSTOP,$00d0
dc.w BPLCON0,$1200
dc.w BPL1MOD,$0000
dc.w BPL1PTH
bplhi: dc.w $0000
dc.w BPL1PTL
bpllo: dc.w $0000
dc.w COLOR00,$0000
dc.w COLOR01,$0ff0
dc.w $ffff,$fffe
section bss,bss_c
bitplane: ds.b BPSIZE
This is the block-fill from The Screen Is a Bitmap with one wrong number: move.w #256-1,d1 where we meant #24-1. 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, drawing all 256 rows.
There is no safety net
In BASIC, mistakes were met with a friendly stop: a ?SYNTAX ERROR, an out-of-range complaint, a halt. The language watched over you and stopped 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 an address register at the wrong place, leave a bsr without its rts, hand Paula a length that runs off the end of the sample — and the 68000 does exactly what the bytes say and carries straight on, writing over whatever it touches, never pausing to warn you. The machine trusts you completely. That trust is the freedom that let you take the whole machine over in Unit 1 and drive the Copper, the Blitter, the sprites, and Paula with nothing but moves to memory — 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 what the machine did — the screen in front of you, the colour that came out wrong, the block that ran too far — and reasoning about that against what you meant. Every time you predicted a colour and then checked it through this Primer, you were learning to debug by looking. That's the discipline the whole course rests on.
Assemble, master, and run
make
A full-height column where you wanted a small block — and not a word of complaint.
Try this: it was never broken — your number was
Change #256-1 to #24-1. A neat little block, exactly as in Unit 6. 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 fill value #$ffffffff to #$00000000 and run the buggy 256 version again. Now the loop dutifully draws 256 rows of nothing — the same faithful execution of a different wrong intention, writing blank pixels exactly where you said. Predict what you'll see before you run it, then confirm. Again: no error, just the wrong thing done exactly.
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 what happened, not by reading errors.
What's next — you've met the machine
That's the Primer. Look back at what stopped being magic: the assemble-and-run loop; MOVE and the registers; bytes, words and longs with no type; the eight address registers and the vast street of memory; the bitmap behind the display, its colours painted by the Copper in step with the beam; decisions built from compare-and-branch; the vertical-blank heartbeat; reading the player; pointers walking a table; counted loops; subroutines and the stack; arithmetic and the carry; setting and clearing bits; and the four custom chips — Blitter, sprite, Paula — that make an Amiga an Amiga.
You haven't built a game yet — that's the point. You've built the understanding a game needs. Next comes Exodus, your first complete Amiga game in assembly: a terrain puzzle where the Blitter you met in Unit 16 is the gameplay. Everything you've assembled here — the takeover, the bitmap, the Copper, the Blitter, reading the player — turns into something you play.
And this is one road into the Amiga, not the only one. Later tracks meet the same machine through AMOS, Blitz BASIC, and C — higher-level languages that sit on top of the same chips you've just driven by hand. You'll recognise all of it, because you've seen what's underneath. Go and write something the Amiga will trust you to get right.