Put CosmOS on the screen without changing a line of it
The console is now a display controller as well as a port: it owns a font, keeps a cursor, handles newline, carriage return, backspace and wrapping, and scrolls. That is an ordinary kind of chip - it is what a video terminal's character generator did - and it is the reason this rung needed no changes to CosmOS at all. CosmOS already writes bytes to port 0x00. It writes to BOTH the screen and standard output, which is deliberate. A machine with a screen and a serial line is an ordinary machine, the emulator's standard output is that serial line, and one console drives both. It is also what keeps all 165 recorded results passing under Voyager, and what makes --screen work on the plain SplitBit: there is one console and it drives everything it has. Scrolling moves the video device's origin and no memory. The row arriving at the bottom is cleared because the map is a ring and it holds what was there 128 rows ago; the rows going off the top are not, and that is a hundred rows of scrollback nothing had to keep. The test reads the register back rather than looking at the screen, because a console blitting rows instead would look identical and cost twelve percent of a frame for every line printed. The font is vendored from Hatchet-GPU with a note saying where it came from, since that repository is not part of this one. 135 glyphs in ASCII order, which is the thing that makes it worth keeping - PETSCII's whole inconvenience was that its order was not ASCII's, so a machine using it needed a translation table in front of every string. Here the machine subtracts 32. It is stored one bit a pixel and expanded into tile memory at reset: 1,088 bytes against 16 kilobytes. Voyager gets a keyboard. A window has no standard input, and a machine blocking on it inside a frame would stop drawing and stop answering, so a front end with a window installs a hook that the console calls while it has nothing: it keeps the window alive and hands back a key. The hook has to tell "nobody has typed yet", which happens sixty times a second, apart from "the window has gone", which is the end of input - one value for both would have made the first keystroke look like a closed machine. In line mode the console echoes what it is given, because there is no terminal behind a window to do it and that was always the terminal's job. Tests/video.sh grew from 14 checks to 26, half of them about the console rather than the device: those programs ask the video device for nothing and write bytes to port 0x00 like every SplitBit program always has. Verified by breaking two things - removing the scroll failed exactly the two checks about scrolling, and removing the cursor advance failed exactly the three that depend on it. Two video checks had quietly depended on palette entry 0 being black, which stopped being true the moment a machine woke up able to show text. They now set what they are about to look at, and a new check pins the waking state itself. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01E2JrLzFvuFX9fgi1LDRjrW
This commit is contained in:
co-authored by
Claude Opus 5
parent
83623a3df3
commit
773b0f8add
@@ -261,7 +261,10 @@ Nothing in that program names a Data Pointer, so all of it runs through Data Poi
|
||||
|
||||
## The Console:
|
||||
|
||||
Port 0x00 is the oldest thing on this machine and it has not changed: writing sends a byte out, reading takes one in and waits until there is one. Every program ever written for SplitBit uses it that way and still does. What is new is that a program can say what it wants a keypress to mean, can ask whether a read would have to wait, and can arrange to be told when a byte arrives instead of having to ask at all.
|
||||
Port 0x00 is the oldest thing on this machine and it has not changed: writing sends a byte out, reading takes one in and waits until there is one.
|
||||
|
||||
**On a machine with a screen, the console draws.** It is a display controller as well as a port: it owns a font, keeps a cursor, and scrolls - which is what a video terminal's character generator did, and is why a program written before there was a screen puts text on one without being changed. See Writing On The Screen below.
|
||||
Every program ever written for SplitBit uses it that way and still does. What is new is that a program can say what it wants a keypress to mean, can ask whether a read would have to wait, and can arrange to be told when a byte arrives instead of having to ask at all.
|
||||
|
||||
| Port | Register |
|
||||
| --- | --- |
|
||||
@@ -570,6 +573,26 @@ Scrolling therefore moves a register and no memory at all. That is not a small s
|
||||
|
||||
And the rows that scrolled off are still in the map, which is where a terminal on this machine gets scrollback without having to keep any.
|
||||
|
||||
### Writing On The Screen:
|
||||
|
||||
A console on a machine with a screen sends every byte to both, because a machine with a screen and a serial line is an ordinary machine and there is one console driving both.
|
||||
|
||||
At reset the font is expanded into tile memory and the palette is given two entries: 0 is paper and 1 is ink. That is all a machine needs to be able to say something before any program has run, and it is deliberately not more - a program that wants colour sets it, and sixteen guessed entries would be sixteen a program had to overwrite.
|
||||
|
||||
The font is in ASCII order, so a byte becomes a glyph by subtracting 32. Bytes below that have no glyph and are not drawn; three of them do something instead.
|
||||
|
||||
| Byte | Does |
|
||||
| --- | --- |
|
||||
| 0x0A | Newline. The cursor goes to the start of the next row, and at the last row the screen scrolls instead. |
|
||||
| 0x0D | Carriage return. The cursor goes to the start of the row it is on. |
|
||||
| 0x08 | Backspace. The cursor steps back and rubs out what was there. |
|
||||
|
||||
Writing past the last column wraps to the next row, the same as a newline.
|
||||
|
||||
**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.
|
||||
|
||||
## Asking What Is There:
|
||||
|
||||
A program that only ever runs on one machine can be told where everything is. A program meant to run on more than one has to ask, and the bus registry on port 0xFF is what it asks.
|
||||
|
||||
Reference in New Issue
Block a user