LESSON 3 — THE SCREEN, ONE BYTE AT A TIME

click the black screen first to grab the keyboard · this lesson wants a real keyboard — you are here to type assembly, and no on-screen panel makes that pleasant · back to the arcade
Type MAKE, then RUN. Seven frames — a key moves on, Esc leaves early.

1 · A DOT

One byte, written to one address. There is no draw call underneath it, because there is nothing underneath it.

2 · EVERY COLOUR

64000 bytes, each one greater than the last. Watch which way the stripes lean — that slant is the lesson.

3 · BLACK

And nothing else. The screen only goes empty because we asked it to, in one instruction that repeats itself.

4 · TWO LINES

One of them is a single instruction. The other cannot be, and the reason is the whole of graphics on this machine.

5 · AN OUTLINE

Drawn straight on top. The lines are still underneath it, because nothing here is ever cleared unless you clear it.

6 · A FILLED SQUARE

The line from frame 4, done once per row. Nothing new was invented between them.

7 · TWO HUNDRED

Same routine, random colours, random places, and four lines of arithmetic pretending to be chance.

WHY THE STRIPES LEAN

Frame 2 writes every byte of the screen in order: nought, one, two, all the way to 255, and round again. Nothing in that loop says where a colour goes. The colours are simply laid down the memory one after another — and what comes out is diagonal.

That slant is the proof of the whole lesson. A row is 320 bytes wide and there are only 256 colours, so every row begins 64 colours further along than the row above it. The picture leans because 320 does not divide by 256. If the screen were really a grid of rows, it could not.

offset = y * 320 + x

That is the same line lesson 1 wrote in C, and it is still the only arithmetic in the file. The screen is not a grid. It is one long row of 64000 bytes, and it only looks like a grid because the card reads 320 of them, drops a line, and reads 320 more.

WHAT A LINE COSTS

mov  di, 100*320 + 60     ; across
mov  cx, 200
rep  stosb                ; ...and that is the whole line

mov  di, 40*320 + 160     ; down
mov  cx, 120
.down:  mov  byte [es:di], 14
        add  di, 320      ; the pixel below is 320 bytes further on
        loop .down

Same line on the glass, completely different price. Across, the pixels are neighbours in memory and one instruction draws all two hundred; down, they are 320 bytes apart and it has to be a loop. That difference is why everything in these games is drawn in horizontal spans — the terrain, the aircraft, the cockpit. It is not a style, it is what the memory layout charges you.

CHANGE SOMETHING

The assembler is in the tab with you, which is the point of this page rather than a video of it. The dot in frame 1 is colour 15, white:

EDIT PIXEL.ASM
MAKE
RUN

Try 4. Try 40. Try moving it. Reload the page and everything is back as it was, so there is nothing you can break.

the lesson's source and notes · lesson 2 · back to the arcade · the assembler is flat assembler, and the DOS is DOSBox compiled to WebAssembly via js-dos