Flip says the true thing, and the checks that let it lie
Two bugs, both in what the demo claimed rather than in the device. The assembler has no string escapes, so the "\n" written in a literal printed as a backslash and an n. A newline is a byte; Say.asm has always written one as 0x0A 0x00 and this now writes it out of the console port. And the line whose whole job was to still be there afterwards was wiped out on the way back, because the program called osTakeScreen - which restores the screen AS IT WAS BEFORE, so the tidy-up erased the one thing the demo was pointing at. It did not need saving: nothing it touches is the shell's. A program that damages nothing should not ask, and asking anyway costs it the screen it was standing on. Which turned out to be untrue as written, and that is the third thing. Flip drew with a tile of its own, and the system copies the font back over every tile at exit - so the filled screen went blank the moment the program left, and the check that the system put the display back could not tell a restored screen from an abandoned one. It passed with the restore deleted. So did the check that a program can show the other screen at all: a blank screen counts as one colour just as well as a filled one does. Now it fills with 0x0A, which is an asterisk in one of the reversed colour schemes: paper is the colour and ink is black, so a whole screen is drawn with NO TILE REDEFINED and it survives leaving. Both checks ask for the commonest colour in the picture rather than counting colours or naming a pixel - the font's only blank glyph is the space, whose attribute nibble is nought, so a filled screen is always a pattern and which pixel lands on paper depends on the character. Both were re-broken afterwards and both failed this time. Also cosmosFlip, a transcript test, which is what would have caught the printed backslash in the first place. 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
023362b05a
commit
eee95ef0ce
@@ -28,18 +28,11 @@
|
||||
#Base 0x5000
|
||||
|
||||
start:
|
||||
; ---- The two banks this touches ----
|
||||
; ---- The one bank this touches ----
|
||||
;
|
||||
; Four is the atlas, where the tiles are. Six is the other screen: three is the disk's and
|
||||
; four and five are the ones the system registers to save a screen with, so six is the
|
||||
; first number free. Nothing hands these out - see the table in the CosmOS README.
|
||||
INIA 0d4
|
||||
OUTA 0xE3
|
||||
INIA 0x30
|
||||
OUTA 0xE2
|
||||
INIA 0x03
|
||||
OUTA 0xE8
|
||||
|
||||
; Six: three is the disk's and four and five are the ones the system registers to save a
|
||||
; screen with, so six is the first number free. Nothing hands these out - see the table in
|
||||
; the CosmOS README.
|
||||
INIA 0d6
|
||||
OUTA 0xE3
|
||||
INIA 0x3B
|
||||
@@ -47,50 +40,57 @@ start:
|
||||
INIA 0x03
|
||||
OUTA 0xE8
|
||||
|
||||
; The screen back afterwards, because the tile overwritten below is one the shell spells
|
||||
; with. Refused is survivable and is not checked: there is nothing this could do about it,
|
||||
; and the system puts the font back at exit whether or not it saved anything.
|
||||
SWI osTakeScreen
|
||||
; ---- And it does NOT take the screen ----
|
||||
;
|
||||
; osTakeScreen saves what is on the screen and puts it back at exit, and this program
|
||||
; called it at first. That was wrong in a way worth keeping written down: it saves the
|
||||
; screen AS IT WAS BEFORE, so the line printed below - the line whose whole job is to still
|
||||
; be there afterwards - was wiped out by the restore that was meant to be tidy.
|
||||
;
|
||||
; It was not needed either. NOTHING THIS TOUCHES IS THE SHELL'S: the only memory it writes
|
||||
; is the map of the screen nobody is looking at, and the only register it leaves changed is
|
||||
; which screen that is - which the system puts back itself.
|
||||
;
|
||||
; A program that wants a screen saved should ask. A program that damages nothing should
|
||||
; not, and asking anyway is not free - it costs the screen it was standing on.
|
||||
|
||||
SETD.0 Message
|
||||
SWI osPrintString
|
||||
INIA 0x0A
|
||||
OUTA 0x00 ; The assembler has no escapes; a newline is a byte.
|
||||
|
||||
; Key mode, so a key arrives when it is pressed rather than when Return is.
|
||||
INIA 0x01
|
||||
OUTA 0x02
|
||||
|
||||
; ---- Tile one, made solid ----
|
||||
; ---- Every cell of the other screen, in one command ----
|
||||
;
|
||||
; Sixty four pixels of index one, FILLED rather than blitted, which is why this program
|
||||
; carries no picture of its own.
|
||||
INIA 0d4
|
||||
OUTA 0xE3
|
||||
RSTA
|
||||
OUTA 0xE4
|
||||
INIA 0x40
|
||||
OUTA 0xE5 ; Tile one begins at sixty four.
|
||||
INIA 0x01
|
||||
OUTA 0xE2 ; Fill takes the byte it writes from SourceLow.
|
||||
RSTA
|
||||
OUTA 0xE6
|
||||
INIA 0x40
|
||||
OUTA 0xE7 ; Sixty four bytes of it.
|
||||
INIA 0x02
|
||||
OUTA 0xE8
|
||||
|
||||
; ---- And every cell of the other screen ----
|
||||
; TEN, and the reason is worth the paragraph. Fill writes one byte, and a cell is two, so
|
||||
; whatever is filled with is BOTH the tile and the attribute - there is no filling a map
|
||||
; with a tile and a colour that are different numbers.
|
||||
;
|
||||
; One byte fills both halves of a cell, so this is tile one and attribute one everywhere:
|
||||
; the tile is index one at every pixel and the attribute adds sixteen to all of them, which
|
||||
; comes out as a screen solidly in scheme one's ink.
|
||||
; Ten as a tile is an asterisk, because the font begins at the space and glyph n is
|
||||
; character n plus thirty two. Ten as an attribute is one of the eight REVERSED schemes,
|
||||
; whose paper is a colour and whose ink is black. So the screen comes out green, covered in
|
||||
; black asterisks, without a single tile being redefined.
|
||||
;
|
||||
; The high nibble stays at nought, which the manual asks for: it is reserved. That is the
|
||||
; real constraint on which byte this can be - it has to be under sixteen to leave the
|
||||
; nibble alone, and eight or over to land on a reversed scheme whose PAPER is the colour.
|
||||
;
|
||||
; Which means THIS PROGRAM WRITES NOTHING BUT THE SCREEN NOBODY IS LOOKING AT. It was
|
||||
; drawn with a tile of its own first, and that tile was one the system copies the font back
|
||||
; over at every exit - so the screen it had filled turned blank the moment it left, and a
|
||||
; check that it had been put back could not tell a restored screen from an abandoned one.
|
||||
; A picture that depends on the atlas does not survive leaving.
|
||||
INIA 0d6
|
||||
OUTA 0xE3
|
||||
INIA 0x40
|
||||
OUTA 0xE4
|
||||
RSTA
|
||||
OUTA 0xE5
|
||||
INIA 0x01
|
||||
OUTA 0xE2
|
||||
INIA 0x0A
|
||||
OUTA 0xE2 ; Fill takes the byte it writes from SourceLow.
|
||||
INIA 0x80
|
||||
OUTA 0xE6
|
||||
RSTA
|
||||
@@ -141,5 +141,8 @@ waitKey:
|
||||
|
||||
#Base 0x3000
|
||||
|
||||
; One line and no newline in it. A string literal is terminated where it ends, so a second
|
||||
; one after a 0x0A byte would never be reached - printing stops at the first terminator. The
|
||||
; newline is written to the console directly instead.
|
||||
Message:
|
||||
"A whole screen is about to be drawn where you cannot see it - this line will still\nbe here when it is done. Press a key to show it, and another to come back.\n"
|
||||
"A screen is drawn where you cannot see it. A key shows it, another comes back."
|
||||
|
||||
@@ -725,7 +725,7 @@ from every assembly file in it. Several are old programs written for the bare ma
|
||||
| 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 it diagonally a pixel at a time. |
|
||||
| Flip | Draws a whole screen into the bank that is not being shown, waits, and then shows it in one byte out of one port. It deliberately does not put the displayed screen back, because that is the system's to restore - a program that faulted while flipped could not have. |
|
||||
| Flip | Draws a whole screen into the bank that is not being shown, waits, and then shows it in one byte out of one port. It writes nothing else at all - not a tile, not a colour - so it does not ask for the screen to be saved, and the line it printed is still there when it comes back. It deliberately does not put the displayed screen back either, because that is the system's to restore: a program that faulted while flipped could not have. |
|
||||
| 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. |
|
||||
|
||||
Reference in New Issue
Block a user