Skip to content
Game 0 Unit 3 of 18 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.

17% 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 character. 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 NES screen filled with deep blue.
A deep blue set by storing the letter 'A' — which the machine reads as 65, its low bits landing on colour $01. A letter was a number all along.

A deep blue screen. Here's the strange part: we didn't load a colour number. We loaded the letter 'A'. The machine didn't blink — to it, 'A' is 65, and the harness handed 65 to the palette, where its low bits land on colour $01, a deep 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
lda #65decimal65
lda #$41hex (the $ says "hex")65
lda #'A'a letter (its character code)65
lda #%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 debuggers and palette tables show 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 plenty of hex from here on; it fits a byte more neatly than decimal does.

And that last one — %01000001 — shows the byte's eight actual bits, the on/off switches the machine stores. The screen proves it: the NES palette is six bits wide — 64 entries, $00 to $3F — so it keeps only the low six bits of what you write. The low six bits of %01000001 are %000001, which is $01, a deep blue. (Writing $41 and writing $01 to the palette give the same colour for exactly this reason — the top two bits are thrown away.) We'll start flipping individual bits like these in Unit 15.

The program

Same sealed harness; only the one line in the middle is new:

; ============================================================================
; Meet the Machine (NES) - Unit 3: Everything Is a Number
;
; Same sealed harness - it shows whatever colour you leave in A. This time we
; load a LETTER and let the machine show us it was a number all along.
; ============================================================================

.segment "HEADER"
    .byte "NES", $1a
    .byte 2
    .byte 1
    .byte $00, $00

.segment "CODE"

reset:
    sei
    cld
    ldx #$40
    stx $4017
    ldx #$ff
    txs
    inx
    stx $2000
    stx $2001
    stx $4010
warm1:
    bit $2002
    bpl warm1
warm2:
    bit $2002
    bpl warm2

    ; ----------------------------------------------------------- YOUR CODE START
    lda #'A'                ; load the LETTER 'A' - to the machine just $41 (65)
    ; ------------------------------------------------------------- YOUR CODE END

    sta $00
    bit $2002
    lda #$3f
    sta $2006
    lda #$00
    sta $2006
    lda $00
    sta $2007

forever:
    jmp forever

nmi:
    rti
irq:
    rti

.segment "VECTORS"
    .word nmi
    .word reset
    .word irq

.segment "CHARS"
    .byte $00,$00,$00,$00,$00,$00,$00,$00
    .byte $00,$00,$00,$00,$00,$00,$00,$00
    .byte $ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff
    .byte $00,$00,$00,$00,$00,$00,$00,$00
    .res 8192 - 32, $00

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

Assemble and run

ca65 letter.asm -o letter.o && ld65 -C nes.cfg letter.o -o letter.nes

Load it, and the screen is deep blue — colour $01, which is 'A''s low six bits, which came from 65, which is $41, which is %01000001. All the same byte.

Try this: the same byte, four ways

Change lda #'A' to lda #65, assemble and run — same deep blue. Now try lda #$41, then lda #%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 lda #'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.) The palette keeps 90's low six bits — %011010, which is $1a — and the screen comes up green. The machine knows these as numbers; the letters are our idea.

If it doesn't work

  • ca65 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 screen isn't blue. Check you loaded a value whose low six bits are $01'A' (65), or 1, or $41. The palette reads only the bottom six bits, so it's the value mod 64 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. The NES palette keeps the low six bits of whatever byte it's handed.

What's next

If a byte can be a letter or a colour, where do bytes live when they're not in a register? Next — A Street of Numbered Boxes — we meet memory: a row of numbered slots, each holding a byte. The NES has fewer of them than you might expect.