Give the screen back: osTakeScreen, and the RAM disk earns its keep

A program that takes the whole screen leaves the shell a blank one, and
whatever was on it is gone. There was nowhere to put 48K of video memory on
a machine with 64K of Data Memory that CosmOS already lives in.

A DRIVE MADE OF MEMORY IS SOMEWHERE. The screen goes to a file on the
scratch drive - the first volatile drive found at boot - like any other
file, and comes back from handleExit alongside the vectors and console mode
already put back there. The filesystem does the allocating, so this
invented nothing: it is 196 pages of tiles, map and palette, with a block
on the front holding the cursor, the four scroll registers and the mode.

NOT AUTOMATIC, and that is the whole design. Saving on every program start
would be cheap enough; restoring on every exit would be wrong, because dir
and Files and Say print and stop and their output is the reason you ran
them. A program says it took the screen, and one that says nothing behaves
exactly as every program did before this existed.

It deleted thirty lines of Grid, and they were all wrong anyway: four
scroll registers put back by hand, the map filled with spaces, the cursor
sent home, palette bank 0 written out - and the other fifteen banks kept
Grid's colours, because there was nowhere to have kept the real ones. Grid
is 64 bytes smaller and gives back what was actually there.

The check compares the screen before against the screen after, CELL BY
CELL, and allows only the rows around the cursor to differ - found from
where the text ends rather than guessed at, because the first version
assumed the cursor was near the bottom of the screen and let three real
differences through.

Two things cost time and neither was the feature:

  - An edit adding "SWI osTakeScreen" to Grid was in the same script as a
    failing s.index, so the file was never written - and the COMMENT
    describing the call did land, from a later edit. Grid documented a call
    it did not make, and read as though it should have worked.
  - docs.sh caught osTakeScreen having no row in the services table, which
    is the check the service layer added for exactly this and the second
    time it has earned itself.

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-31 18:47:44 -04:00
co-authored by Claude Opus 5
parent 04f1ffabd4
commit ab72443b99
12 changed files with 551 additions and 71 deletions
+14 -65
View File
@@ -44,6 +44,14 @@ start:
INIA 0x03
OUTA 0xE8 ; RegisterBank.
; ---- Asking for the screen back afterwards ----
;
; Everything below overwrites a tile, all sixteen colour schemes and every cell of the map,
; and none of that is this program's to keep. The system puts it somewhere and gives it back
; at exit - and if it says it cannot, this carries on anyway, because it did before there
; was anywhere to put it.
SWI osTakeScreen
CALL putTile
CALL putPalette
CALL putMap
@@ -119,74 +127,15 @@ finished:
; ---- Putting the screen back ----
;
; All four scroll registers, or the shell inherits a view that begins half way into a cell.
RSTA
OUTA 0x36
OUTA 0x37
OUTA 0x38
; The row origin too, and then every cell of the map and not just the visible ones. A
; console that scrolls would otherwise walk down into rows this program filled, and find a
; grid underneath its own output.
OUTA 0x34 ; A is still nought, from the three above.
INIA 0d4
OUTA 0xE3
INIA 0x40
OUTA 0xE4
RSTA
OUTA 0xE5
OUTA 0xE2 ; The byte to write: tile 0 is the space, attribute 0 is plain.
INIA 0x80
OUTA 0xE6
RSTA
OUTA 0xE7 ; 0x8000 bytes, which is the whole map.
INIA 0x02
OUTA 0xE8 ; Fill.
; ---- And the cursor back to the top ----
; ---- What used to be here ----
;
; The Fill above empties the map and says nothing to the console about it, so the shell
; carried on writing from wherever the cursor had been left standing when this program
; started - part way down a screen that no longer has anything on it. Clearing is what
; puts a cursor home, and it costs one write.
INIA 0x01
OUTA 0x05
; ---- And the colours it woke up with ----
; Four scroll registers put back, the whole map filled with spaces, the cursor sent home,
; and palette bank 0 written out by hand - and it was STILL wrong, because the other fifteen
; banks kept this program's colours and there was nowhere to have put the real ones.
;
; Only the first pair, and that is worth being honest about. The console's own scheme is
; sixteen banks - colours on black in 0 to 7, the same colours inverted in 8 to 15 - and
; this program wrote over all of them, because the attribute nibble lands on exactly the
; entries the console uses and there is nowhere else for it to land. Putting all thirty two
; back would mean copying the device's own table into an application, which is the kind of
; duplication that goes stale the first time somebody picks a nicer green.
;
; So it restores bank 0, grey on black, which is what plain text has always been and what
; the shell will be using when it gets the machine back. The other fifteen keep this
; program's colours until something else writes them, which is visible only to a program
; that sets the console's attribute port.
;
; THE REAL ANSWER IS A COMMAND TO THE SCREEN saying "give me back what you woke up with",
; the same way the console has one for clearing. There is not one, and this program is the
; first thing that ever wanted it.
INIA 0d4
OUTA 0xE3
INIA 0xFC
OUTA 0xE4
; All of it is osTakeScreen's now, and it gives back what was actually there rather than
; what a clean machine looks like.
RSTA
OUTA 0xE5
OUTA 0xE9 ; Entry 0, the paper: black.
OUTA 0xE9
OUTA 0xE9
OUTA 0xE9
INIA 0xD8
OUTA 0xE9 ; Entry 1, the ink: grey.
OUTA 0xE9
OUTA 0xE9
RSTA
OUTA 0xE9
OUTA 0x02 ; Line mode, the way it was found.
RSTA ; splitlint[redundant-assignment]: an exit status, not a mode
SWI osExit