diff --git a/Programs/CosmOS/Apps/Mode.asm b/Programs/CosmOS/Apps/Mode.asm new file mode 100644 index 0000000..feb4a9e --- /dev/null +++ b/Programs/CosmOS/Apps/Mode.asm @@ -0,0 +1,50 @@ +; Forty columns or eighty, whichever the screen is not in. +; +; A machine wakes up in the forty column mode and CosmOS asks for eighty, because that is +; what its own output was written for. A game is the other way round: Snake on a forty column +; screen is the same board drawn twice the size, which is what a person sitting in front of +; it actually wants. +; +; ---- The smallest program this system can load ---- +; +; Ten instructions and NO DATA AT ALL, which is not a curiosity: it is the shape that found +; a bug in the loader. Every program written for CosmOS until this one had something in its +; Data Segment, so the loader had never been asked to move a segment of no bytes - and a +; length of zero asks the memory controller for the whole 64K, which does not fit, which it +; refused, which stopped the machine in the middle of loading. On a terminal that printed a +; fault. Behind a window it looked exactly like a hang. +; +; So this is kept dataless on purpose. The two digits it prints are put in a register one at +; a time rather than being a string, which is the only reason it can say anything at all. +; +; Written by Anachronaut + +#Include services.asm + +#Program + + #Base 0x4000 + +start: + INA 0x31 ; Which mode the screen is in now. + BRA modeWide ; Nought is the forty column one, so go the other way. + + ; Anything else becomes forty, and that deliberately includes bitmap mode. A program that + ; left the screen with no text on it left nowhere to print, so coming back to a mode that + ; has characters in it is more use than refusing. + RSTA + OUTA 0x31 + INIA 0x34 ; '4' + BRI modeSay +modeWide: + INIA 0x01 + OUTA 0x31 + INIA 0x38 ; '8' +modeSay: + OUTA 0x00 + INIA 0x30 ; '0' + OUTA 0x00 + INIA 0x0A + OUTA 0x00 + RSTA + SWI osExit diff --git a/Programs/CosmOS/README.md b/Programs/CosmOS/README.md index 399d274..b0bdc58 100644 --- a/Programs/CosmOS/README.md +++ b/Programs/CosmOS/README.md @@ -572,6 +572,8 @@ from every assembly file in it. Several are old programs written for the bare ma | Compare | Compares two files a block at a time, stopping at their real tails rather than comparing unused bytes in the final disk blocks. | | Wander | Goes to the directory it is given and reads a file there by a bare name. The only thing that moves the machine from inside a program, and so the only thing that can check the shell puts the working directory back afterwards. | | More | A forward-only pager. Space advances a screen, Return one line, and q stops. | +| Press | Says what the console handed it, in hexadecimal and by name. It reads a line and then keys, because the keys that are not characters are dropped in line mode and delivered in key mode, and both halves of that rule want showing. | +| Mode | Forty columns or eighty, whichever the screen is not in. Ten instructions and no data at all, which is the point of it: it is the smallest shape a loadable program can take, and the loader used to stop the machine dead on one. | ### The Monitor: diff --git a/Programs/CosmOS/Source/cosmos.asm b/Programs/CosmOS/Source/cosmos.asm index ceb19a0..9388e59 100644 --- a/Programs/CosmOS/Source/cosmos.asm +++ b/Programs/CosmOS/Source/cosmos.asm @@ -1548,11 +1548,29 @@ loadVersionKnown: LDA.0 OUTA 0xE6 INCD.0 - LDA.0 - OUTA 0xE7 + LDB.0 + OUTB 0xE7 + + ; ---- Nothing to move is not the same as everything to move ---- + ; + ; A LENGTH OF ZERO ASKS THE CONTROLLER FOR THE WHOLE 64K, which is the machine's rule and + ; a sensible one for a length somebody typed: two bytes cannot say 65536, and a transfer + ; of no bytes is not usually what anybody meant. It is exactly what is meant here. A + ; segment can genuinely be empty - a five instruction program that only writes to a port + ; has no data at all - and this asked to move 65536 bytes into a bank that has not got + ; them, so the controller refused and the machine stopped in the middle of loading. + ; + ; The header says how long the segment is, so the loader knows before it asks. It has + ; both bytes of the length in hand here, so testing them costs one instruction. + ; + ; NOTHING IS LOST BY SKIPPING IT. A blit leaves the controller's addresses past whatever + ; it touched, and a blit of nothing would have left them exactly where they are. + OR + BRQ loadNoCode INIA 0x01 OUTA 0xE8 ; Blit. +loadNoCode: ; Then the data. A blit leaves its addresses past whatever it touched, so the source is ; already sitting on the first byte of the data and only the destination changes. @@ -1571,11 +1589,16 @@ loadVersionKnown: LDA.0 OUTA 0xE6 INCD.0 - LDA.0 - OUTA 0xE7 + LDB.0 + OUTB 0xE7 + + ; And the same for the data, which is the segment that is actually empty in practice. + OR + BRQ loadNoData INIA 0x01 OUTA 0xE8 ; Blit. +loadNoData: ; ---- The vectors it brought ---- ; diff --git a/SplitBit Test Manual.md b/SplitBit Test Manual.md index 0ee7f1a..35693f2 100644 --- a/SplitBit Test Manual.md +++ b/SplitBit Test Manual.md @@ -79,7 +79,7 @@ from `make`, not from here. ### 1. Recorded output `Tests/run.sh` assembles each program named in `Tests/manifest`, runs it, and compares -everything it printed against a file in `Tests/expected`. 189 tests, of which 127 run, 35 +everything it printed against a file in `Tests/expected`. 190 tests, of which 128 run, 35 only assemble, 16 are expected to fail to assemble, and 11 boot from ROM with no image given at all. @@ -443,7 +443,7 @@ than reading all of them: ## The Lint Baseline: `Tests/lint-baseline.txt` records how many warnings of each rule SplitLint finds in each -file across the whole corpus - 34 file-and-rule pairs. It is checked on every run, and it +file across the whole corpus - 33 file-and-rule pairs. It is checked on every run, and it is checked **in both directions.** A new warning appearing is a regression. A recorded warning *disappearing* is also diff --git a/Tests/expected/cosmosCrossDisk.out b/Tests/expected/cosmosCrossDisk.out index b999df1..28d1470 100644 --- a/Tests/expected/cosmosCrossDisk.out +++ b/Tests/expected/cosmosCrossDisk.out @@ -21,6 +21,7 @@ Say.sbx 156 Break.sbx 149 Grid.sbx 559 Press.sbx 872 +Mode.sbx 48 notes.txt 21 Apps