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

Everything Is a Number

A byte has no type. Discover that 65, $41, the letter 'A' and the bit-pattern %01000001 are one and the same byte — and meet hex, the way you'll read bytes from here on.

19% of Meet The Machine

You've been moving bytes between registers. Now the question nobody asked in BASIC: what is a byte, exactly?

In BASIC, the kinds were kept firmly apart — 5 was a number, "A" was a string, and mixing them was an error. The machine has no such manners. A register holds a byte — a number from 0 to 255 — and that's the only kind of thing there is. Not a letter, not a colour, not a pixel pattern. Those are meanings you decide to read into a number. The byte itself has no type.

The cleanest way to feel this is to load a letter into a number register and watch the machine shrug.

What you'll see by the end

The Spectrum's default screen surrounded by a solid blue border.
A blue border — drawn by loading the letter 'A'. To the machine that letter is just 65, and 65's low three bits pick blue.

A blue border. Here's the strange part: we didn't load the number 1 (blue's code). We loaded the letter 'A'. The machine didn't blink — to it, 'A' is 65, and we showed 65 on the border, where it lands on blue. A letter was a number all along.

One byte, four ways to write it

These four lines all put the same byte into A:

You writeWhat it isValue
ld a, 65decimal65
ld a, $41hex (the $ says "hex")65
ld a, 'A'a letter (its character code)65
ld a, %01000001binary (the % says "bits")65

Four notations, one byte: $41. They're not "equal" — they're identical. The assembler turns every one of them into the same eight bits before the machine ever sees them.

Hex ($41) is worth getting used to now, because the register view shows bytes in it. It's base 16: two hex digits cover one byte exactly, $00 to $FF. $41 is 4 × 16 + 1 = 65. You'll read hex constantly from here on; it fits a byte more neatly than decimal does.

And that last one — %01000001 — is also a row of pixels: eight bits, eight dots, .X.....X. Same byte, read as a picture instead of a number. We'll light those exact dots up in Beat 5.

The program

; ============================================================================
; PRIMER — Beat 3: Everything Is a Number
; ============================================================================
; A register holds a byte: a number from 0 to 255. That's all it holds. It
; does NOT hold a "letter" or a "colour" or a "pixel pattern" — those are just
; things we decide a number means. The byte has no type; meaning is whatever
; you choose to DO with it.
;
; To prove the machine doesn't know a letter from a number, we load the
; LETTER 'A' — and the register just fills with 65. Because that's what 'A'
; is: the number 65. These four lines would ALL put the same byte in A:
;
;       ld a, 65            ; decimal
;       ld a, $41           ; hex      ($ means hex; $41 = 65)
;       ld a, 'A'           ; a letter (the machine sees its code, 65)
;       ld a, %01000001     ; binary   (a row of bits — also a pixel pattern!)
;
; All four are the byte $41. Open the register view and you'll see A = $41
; (65) however you wrote it. We use the letter here because it's the most
; surprising: a "letter" was a number all along.
; ============================================================================

            org     32768

start:
            ld      a, 'A'           ; load the LETTER 'A' — to the CPU, just 65
            out     ($FE), a         ; show it on the border (65 -> low 3 bits = 1 = blue)

.loop:
            halt
            jr      .loop

            end     start

We load the letter and show it. Open your emulator's register view and you'll see A holding $41 — the machine's honest opinion of what a letter is.

Assemble and run

pasmonext --sna everything-is-a-number.asm primer.sna

Load it, and the border is blue — colour 65, which is the letter 'A', which is $41, which is %01000001. All the same byte.

Try this: the same byte, four ways

Change ld a, 'A' to ld a, 65, assemble and run — same blue border. Now try ld a, $41, then ld a, %01000001. Same blue every time, because they're the same byte. You're not changing the program's behaviour; you're changing how you wrote a number the machine reads identically.

Try this: read a different letter

What number is the letter 'Z'? Change the load to ld a, 'Z', and before you run it, predict the value — then check the register view. (It's 90; the capital letters run from 'A' = 65 upward.) Try a space too: ld a, ' ' is 32. The machine knows these as numbers; the letters are our idea.

When it's wrong, see why

  • pasmonext errors on the 'A' line. Use straight single quotes around exactly one character — 'A', not ‘A’ (curly quotes) and not "A" (double quotes make a string, not a byte).
  • The border isn't blue. Check you're loading a value whose low 3 bits are 1 — 'A' (65), or 1, or 9. Remember the border reads only the bottom 3 bits, so it's the value mod 8 that picks the colour.
  • %01000001 won't assemble. The binary prefix is %, with exactly eight bits and no spaces.

What you've learnt

A byte has no type: the same value can be written as a number, as hex, as a letter or as a bit-pattern, and the machine treats every one of them identically.

What's next

If a byte can be a letter or a colour or a pixel, where do bytes live when they're not in a register? Next — A Street of Numbered Boxes — we meet memory: one long row of numbered slots, each holding a byte, all of it yours to write and read.