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

Assemble and Run

Write three lines of assembly, turn them into a program with a build step, run it on the Spectrum, and watch the border change colour. Meet the loop you'll use all course.

6% of Meet The Machine

New to programming entirely? You'll have a smoother time starting with General Programming first — this track assumes you've already met variables, loops and subroutines somewhere. If you have, in any language, you're in the right place.

This is the Primer — Meet the Machine. Its whole job is to make the Spectrum stop feeling like magic, one small idea at a time. No game yet, no sprites, no clever code. Just you and the machine, getting introduced.

And the first idea is the smallest one there is: there's a build step now. In BASIC you typed RUN and it went. In assembly you write text, a tool called an assembler turns that text into a program the machine can run, and then it goes. That extra step — write, assemble, run — is the loop you'll repeat for the rest of the course. This unit is just that loop, done once, with the quickest visible result on the whole machine.

What you'll see by the end

The Spectrum's empty default screen surrounded by a solid red border.
A red border — and that's the win. Two instructions sent the value 2 to port $FE the instant the program ran.

A red border. That's it — and that's the win. You wrote it, you built it, the machine did it. The instant the program runs, the border turns red.

The three words you need

Before the code, three pieces of vocabulary — the model, then the syntax:

  • Register A. A tiny store inside the CPU that holds one number. The machine has a handful of these; A is the one we use most. Think of it as the value you're holding in your hand right now.
  • A port. A numbered doorway out of the CPU to a piece of hardware. The border lives behind port $FE (that $ just means the number is written in hex — more on that later; for now it's a name).
  • The border. The frame around the screen. It reads the bottom three bits of whatever you send to port $FE, and those three bits pick one of eight colours. 2 is red.

So the plan in plain words: put 2 into A; send A to port $FE. Two instructions. The border turns red.

The program

This is the whole thing:

; ============================================================================
; PRIMER — Beat 1: Assemble and Run
; ============================================================================
; This is the whole program. Three things happen, no more:
;
;   1. We put a number into the register A.
;   2. We send that number to the border, through port $FE.
;   3. We stop, holding the picture still.
;
; The point of this beat is not the border. The point is the *loop you just
; ran*: you wrote text, an assembler turned it into a program, and the machine
; ran it. There is a build step now. That is the whole idea.
;
; The border is just the quickest thing on the Spectrum to change — one
; instruction, and you can see it the instant the program runs.
; ============================================================================

            org     32768           ; load our program at address 32768

start:
            ld      a, 2             ; 2 is red (the border reads the low 3 bits)
            out     ($FE), a         ; send it to port $FE — the border changes

; ----------------------------------------------------------------------------
; Hold the picture. HALT waits for the next interrupt (50 times a second);
; the jump sends us straight back to wait again. Without this the program
; would run off the end into whatever bytes follow, and the machine would do
; something we never asked for.
; ----------------------------------------------------------------------------
.loop:
            halt
            jr      .loop

            end     start

ld a, 2 puts the number 2 into register A. out ($FE), a sends it through the door to the border. The halt / jr pair at the end just holds the picture still — without it the machine would carry on past our two instructions into whatever bytes happen to come next, and do something we never asked for. (That "the machine just keeps going" is a big idea; we'll meet it properly at the end of the Primer.)

One thing for when you type it in: the assembler doesn't care about capitals in instruction names — ld and LD are the same instruction. We write instructions in lowercase all course, so pick the habit up now.

Don't worry about understanding every line yet. Right now we're learning the loop, not the instructions.

Assemble and run

From this unit's directory, turn the source into a snapshot the emulator can load:

pasmonext --sna border.asm primer.sna

That's the build step — border.asm (the text you wrote) goes in, primer.sna (a program the Spectrum can run) comes out. Load primer.sna in your emulator and the border is red the moment it starts.

You just did the whole cycle: write → assemble → run. Everything else in this course is that loop, again and again, with more interesting things in the middle.

Try this: a different colour

Change the 2 in ld a, 2 to another number from 0 to 7, then assemble and run again. The eight border colours are: 0 black, 1 blue, 2 red, 3 magenta, 4 green, 5 cyan, 6 yellow, 7 white. Predict the colour before you run it, then check. (This is the loop again — change, assemble, run — and it's already becoming second nature.)

Try this: make it black

Set the border to 0. Black border, empty screen — the calm starting point many games open from. Notice you didn't write any new kind of instruction to do it; you changed one number and rebuilt. That's the difference between a value and a program.

When it's wrong, see why

  • pasmonext reports an error and writes no .sna. Read the line number it gives — usually a mistyped instruction or a missing comma. Fix that one line and assemble again; the rest of the file is fine.
  • The border doesn't change — it's still white (or whatever it was). The .sna didn't load, or it's an old build. Re-run the pasmonext line, then load the freshly-written primer.sna.
  • The screen fills with garbage or the machine locks up. The halt / jr .loop at the end is missing or mistyped, so the program ran off into nonsense. Put it back exactly as shown.

What you've learnt

Writing assembly means write → assemble → run — there's a build step between your text and a running program, and you've now been all the way round it once.

What's next

You used register A without properly meeting it. Next — LD Is Not LET — we slow down and look at what a register is: not an unlimited pool of named variables like BASIC's LET, but a handful of physical, finite, 8-bit stores inside the chip. It's the first place the machine stops behaving like the language you came from.