Grid: the first program to use the screen as a screen

Everything drawn on this machine so far has been text or a bitmap. The tile
engine has been there since the screen was built and only the console had
touched it, and only ever to put a letter in a cell - the one thing it can
do that a plain character display could do too.

Grid redefines a tile, fills all 128 map rows with it, and scrolls by
writing ONE BYTE A FRAME. Nothing moves. The rows above and below the
screen are already drawn, so a screenful of movement costs one OUTA and the
rows that leave the top are still there.

Its tile goes at 200 because the machine wakes with the font in tile memory
- glyph n at tile n, for 135 of the 256 - so a program starting at zero
paints over the alphabet and the shell it is about to hand the machine back
to. Its sixteen colour bands are one tile and not sixteen: the attribute
nibble is added to every index in a cell, so the same 64 bytes come out in
sixteen colourings.

Three things it cost, all of them the same lesson about this machine:

  - "SETD.0 X" then "STD.0.1" stores through DP1, which had not been set
    yet. It assembles, and the blit then reads its 64 bytes from wherever
    DP1 was last left, so the tile came out as noise.
  - The palette entry for scheme n is at 0xFC00 + 64n, which reaches
    0xFFC0 - four pages, not one. And doubling A by adding B needs B to
    hold A, which RSTB is the opposite of. Both went away by writing all
    256 entries in order and letting the controller step the address, so
    nothing computes an address at all.
  - The screen it hands back had the right cells and the wrong colours,
    because restoring the map is not restoring the palette.

That last one is a gap in the machine rather than in this program, and is
written up in the CosmOS README. The console's colours live at exactly the
entries the attribute nibble lands on, so any program using the nibble
overwrites them and has nowhere else to write. Grid puts bank 0 back - grey
on black - and leaves the other fifteen. The real answer is a command to
the screen meaning "give me back what you woke up with", the way the
console has one for clearing. There is not one, and this is the first
program that ever wanted it.

Two checks in video.sh, which boots the whole system and reads the pixels
the renderer produced rather than trusting what the program believed.
Breaking the tile fails one and breaking the attribute fails the other.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01E2JrLzFvuFX9fgi1LDRjrW
This commit is contained in:
Anachronaut
2026-08-30 17:38:30 -04:00
co-authored by Claude Opus 5
parent 0e0731e2b1
commit 1a8a5efe03
7 changed files with 472 additions and 2 deletions
+26
View File
@@ -531,6 +531,7 @@ from every assembly file in it. Several are old programs written for the bare ma
| Settle | Says how the last start went and tells the machine to stop falling back, in 353 bytes. A program rather than a shell word, because the shell is for what cannot be done without it. |
| Files | Writes a file, reads it back, renames it and deletes it, in 675 bytes, including nothing but the service names. It is what says a program does not need a filesystem inside it. |
| Break | Stops itself twice with SWI osBreak, so that the registers can be seen changing between one stop and the next. |
| Grid | The first program to use the screen as a screen. Redefines a tile above the font, fills all 128 map rows, and scrolls by writing one byte a frame. |
| Edit | A line editor. |
| Stream | Reads an 84,000 byte file through a buffer of 256, which is what says a file bigger than Data Memory can be read at all. |
| Type | Prints a named text file a block at a time, including one too large to fit in Data Memory. |
@@ -679,6 +680,31 @@ none, and a clean install having nothing to configure is the right default.
outside with nothing on the disk consulted. That is what a debugger does, and it is what to
use when the thing being debugged is the boot chain, since it skips the boot chain.
### Grid, and what a tile engine costs:
Everything else drawn on this machine has been text or a bitmap. `Grid` is the first program
to use the tile engine as an engine, and it is worth reading for the size of the numbers.
It writes **one byte a frame** to scroll. The map is 128 rows and the screen shows 25, so the
rows above and below are already drawn - scrolling moves the origin rather than 2,000 bytes of
screen, and the rows that leave the top have not gone anywhere. A screenful of movement costs
one `OUTA`.
It puts its tile at **200**, because the machine wakes with the font in tile memory - glyph n
at tile n, for 135 of the 256 - so a program that starts at zero paints over the alphabet and
the shell it is about to hand the machine back to. Above 135 is empty and nobody else's.
Its sixteen colour schemes are **one tile**, not sixteen. A cell's attribute nibble is added
to every palette index in it, sixteen at a time, so the same 64 bytes come out in sixteen
colourings and the map bands down the screen as it scrolls.
**What it cannot give back is the palette.** The console's colours are sixteen banks at
exactly the entries the attribute nibble lands on, so any program using the nibble overwrites
them and there is nowhere else for it to write. `Grid` restores bank 0 - grey on black, what
plain text has always been - and leaves the other fifteen as it made them. The proper answer
is a command to the screen meaning "give me back what you woke up with", the way the console
has one for clearing. There is not one yet, and this is the first program that ever wanted it.
## The Application Model:
CosmOS divides the two SplitBit address spaces by convention: