Teach the console the sequences the corpus already speaks, and let the status port see the window

Three things Snake found the moment somebody ran it in a window, and all three are the same
kind of mistake: the console grew a screen and kept asking the terminal.

IT COULD NOT CLEAR THE SCREEN. Every program here that moves a cursor does it with ANSI
escapes, because until there was a screen the thing on the other end was somebody's
terminal. The controller drew "[2J" as three letters and left the board underneath. It now
parses them, which is what a video terminal did - a VT100 is exactly this. The whole corpus
uses two, ESC[2J and ESC[H, and the general shape is recognised so anything else is
swallowed rather than drawn: a sequence nobody implemented should leave no marks. Cursor
positioning is in too, since it is the same parse and one line more.

IT DID NOT SEE KEYS FROM THE WINDOW, but did when the terminal behind it was focused, which
is the whole diagnosis in one sentence. Snake polls the READY bit and never blocks, and
consoleFetch - what the status port asks - was polling standard input regardless of whether
a front end had installed a hook. So a window's keys were invisible to every program that
looks before it reads, and a keystroke aimed at the terminal would be picked up instead.

The hook now takes a question. Zero is the status port looking, and must not present or
sleep: a program polling in a loop would otherwise be charged a frame for every glance. One
is the data port blocking, where presenting is exactly right, because a machine waiting for
a key is still a machine somebody is looking at. One value for both would have made either
polling ruinous or waiting dead.

AND IT RAN SLOWLY, which was the same bug wearing a hat: a game that never receives a
steering key is a game that only ever goes one way.

Six more checks in Tests/video.sh, to 32: that ESC[2J clears, that ESC[H goes to the corner
without disturbing what is drawn, that ESC[3;5H counts rows and columns from one, and that
an unknown sequence is swallowed and leaves nothing behind.

The hook itself is still the one thing here the suite cannot reach - it exists only when
there is a window, and this host has no display. It was found by a person playing Snake,
which is where the Test Manual says these go on being found.

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-28 22:43:27 -04:00
co-authored by Claude Opus 5
parent 6f8ad42277
commit 556a14b288
5 changed files with 183 additions and 8 deletions
+13
View File
@@ -589,6 +589,19 @@ The font is in ASCII order, so a byte becomes a glyph by subtracting 32. Bytes b
Writing past the last column wraps to the next row, the same as a newline.
**And it understands the escape sequences this machine already sends.** Every program here that moves a cursor does it with ANSI escapes, because until there was a screen the thing on the other end was somebody's terminal. A controller that ignored them would draw `[2J` on the screen and leave the picture underneath it, so it parses them - which is what a video terminal did.
| Sequence | Does |
| --- | --- |
| `ESC [ 2 J` | Clears the whole screen. The cursor does not move. |
| `ESC [ J` | Clears from the cursor to the end of the screen. |
| `ESC [ H` | Puts the cursor in the corner. |
| `ESC [ row ; column H` | Puts the cursor there, counting from one. |
Anything else in that shape - an escape, a bracket, some numbers, a letter - is recognised and **swallowed rather than drawn**. A sequence nobody implemented should leave no marks, which is what a terminal does with one it does not know, and drawing it would be worse than ignoring it.
Clearing does not touch the scrollback. It clears what is on the screen, and what has already gone off the top is still in the map where the Scroll register can find it.
**Scrolling moves the video device's Scroll register and no memory at all.** The row that comes into view at the bottom is cleared, because the map is a ring and it is holding whatever was there 128 rows ago. The rows that go off the top are *not* cleared, and that is the point: a hundred rows of what has already been said are still in the map, so a machine has scrollback without anything having to keep it.
**It is one screen.** A program that writes its own tiles and its own map has taken the screen, and a console still writing characters into it will scribble on what that program drew. This is not an oversight to be worked around - it is what one screen means, and it is why a program that wants the screen takes it.