The Screen Is Memory
Meet the C64's defining trick: the screen is just memory. POKE a screen code into an address from 1024 onward and a character appears there — no PRINT, no cursor. An address formula puts it anywhere.
Everything so far has used PRINT, which follows a cursor down the screen. Now meet the
C64's defining idea: the screen is a block of memory. Each of its 1000 cells (40
across, 25 down) is one byte in RAM, starting at address 1024. Write a number into that
byte with POKE, and the matching character appears in that cell — instantly, wherever it
is, with no cursor involved. This is how the C64 does graphics: there are no drawing
keywords; you write to the screen's memory directly.
Milestone 1 — one character, placed by hand
10 PRINT CHR$(147)
20 POKE 1024,1
Line 10 clears the screen; line 20 pokes the number 1 into address 1024 — the top-left
cell. RUN it:
Why does 1 mean A? The number you poke is a screen code, the C64's internal
character number — and it is not the same as PETSCII or ASCII. In screen codes, @ is 0,
A is 1, B is 2, and so on. (The character appears in light blue because that's the
default colour already sitting in the screen's colour memory — that memory is the next
unit's subject.)
Milestone 2 — a row, by counting addresses
Cells sit in memory one after another: 1024, 1025, 1026… across the top row. A loop can walk them, poking a rising screen code into each:
10 PRINT CHR$(147)
20 FOR I=0 TO 9
30 POKE 1024+I,1+I
40 NEXT I
POKE 1024+I, 1+I writes screen code 1+I into cell 1024+I. RUN it for the alphabet's
first ten letters, laid down by address:
Milestone 3 — anywhere, by row and column
The screen is 40 cells wide, so the cell at row R, column C is at address
1024 + R*40 + C. That one formula reaches any cell on the screen:
10 PRINT CHR$(147)
20 LET R=12
30 LET C=20
40 POKE 1024+R*40+C,42
RUN it to drop a * (screen code 42) at row 12, column 20 — the middle of the screen:
That 1024 + R*40 + C is one of the most useful lines on the C64: it turns a row and a
column into a memory address. Every character you place in a game goes through it.
When it doesn't work
- Nothing appeared. The character may be there but invisible — its colour cell matches the background. After a clear the default colour shows; if a cell stays hidden, set its colour too (next unit).
- The character is wrong. You used a PETSCII or ASCII code, not a screen code.
Ais screen code 1, not 65. Letters are 1–26; digits 48–57;*is 42. ?ILLEGAL QUANTITY ERROR. APOKEvalue must be 0–255, and the address 0–65535. Check yourR*40+Cdidn't run past the screen (max cell is 1024+999).
Before and after
You started placing text with PRINT and a cursor, and finished writing characters
straight into the screen's memory — one cell, a row, then any cell by formula. The idea
underneath, and the heart of this whole primer: the C64 screen is memory at 1024, and
POKE writes to it directly. No drawing keywords — just addresses.
Try this
- Your initials, centred. Work out the address for the middle row and poke two or three screen codes side by side.
- A border line. Loop
Cfrom 0 to 39 and poke the same code along row 0. - Read it back.
PRINT PEEK(1024)after poking —PEEKreads a byte wherePOKEwrites one. You'll lean onPEEKfor input later.
What you've learnt
- The C64 screen is memory starting at address 1024 — 40×25 cells, one byte each.
POKE address, codewrites a screen code into a cell; the character appears there.- Screen codes are the C64's own numbering —
Ais 1, not 65. 1024 + R*40 + Cis the address of the cell at rowR, columnC.
What's next
Your characters all came out light blue — the one colour already in the screen's colour memory. In Unit 10 we write to that memory too, at 55296, and the border and background registers — and the screen finally has colour you choose.