Once: start something else on the next start, and only that one
A program that owns the whole machine had nowhere to run. It cannot be started from the shell, because starting it means there is no shell, and pointing boot.cfg at it means a machine that keeps starting it - which is a poor place to find a mistake in something written five minutes ago. Once writes /System/Boot/once.cfg, in the same format as boot.cfg and read with the same routines, because a second format for one setting would be a second format. The loader reads it before boot.cfg and DELETES IT BEFORE IT JUMPS, which is the only moment there is: after the jump the loader does not exist. Consumed by being read rather than by working, so a one shot that hangs cannot hang twice - the request is gone before the image ran, and the next start reads boot.cfg like any other. THE BOOT STATE IS NOT TOUCHED, and the first version got that wrong. It marked the start the way any other start is marked, and then every successful bare metal boot reported that it had never arrived - because a program with the whole machine has no filesystem to clear a mark with and is doing nothing wrong by not having one. Found by running it: the image printed its line and the next start still said the last one did not. Three disks, each a start further along, so none of the tests depends on another having run. The loop is closed on the machine now: write it in Edit, assemble it with Asm, ask for it with Once, restart, watch it own the machine, and the system comes back without being asked.
This commit is contained in:
@@ -0,0 +1,138 @@
|
||||
; Once.asm
|
||||
; Starts something else next time, and only next time.
|
||||
;
|
||||
; > Once /System/Boot/mine.bin
|
||||
; next start: /System/Boot/mine.bin, once
|
||||
; > reboot
|
||||
;
|
||||
; Writes /System/Boot/once.cfg, which the loader reads before boot.cfg and DELETES BEFORE
|
||||
; IT JUMPS. So the image runs on the next start and on no other, whatever happens to it -
|
||||
; a one shot that hangs cannot hang twice, because the request is gone before it ran.
|
||||
;
|
||||
; ---- What this is for ----
|
||||
;
|
||||
; A program that owns the whole machine has nowhere to run. It cannot be started from the
|
||||
; shell, because starting it means there is no shell; and pointing boot.cfg at it means a
|
||||
; machine that keeps starting it, which is a poor place to find a mistake. This is the
|
||||
; missing step: write it, ask for it once, and the system comes back by itself.
|
||||
;
|
||||
; The file is the same format as boot.cfg because a second format for one setting would be
|
||||
; a second format. It says `system` for the same reason.
|
||||
;
|
||||
; Written by Anachronaut
|
||||
|
||||
#Include services.asm
|
||||
|
||||
#Program
|
||||
|
||||
#Base 0x4000
|
||||
|
||||
start:
|
||||
SETD.0 Wanted
|
||||
INIB 0d128
|
||||
SWI osArgument
|
||||
MVQA
|
||||
BNA noName
|
||||
|
||||
SETD.0 Wanted
|
||||
LDA.0
|
||||
BRA noName
|
||||
|
||||
; The line, built as "system " and then the name. One write, because the file is the
|
||||
; whole of the request and half of it would be a request for half a thing.
|
||||
SETD.0 Prefix
|
||||
SETD.1 Line
|
||||
RCAL copyString
|
||||
SETD.0 Wanted
|
||||
RCAL copyString
|
||||
INIA 0x0A
|
||||
STA.1
|
||||
INCD.1
|
||||
RSTA
|
||||
STA.1
|
||||
|
||||
; How long it came to, which is what the write is told.
|
||||
SETD.0 Line
|
||||
RCAL measure
|
||||
|
||||
SETD.0 OncePath
|
||||
SETD.1 Line
|
||||
SWI osFileSave
|
||||
MVQA
|
||||
BNA noWrite
|
||||
|
||||
SETD.0 DoneText
|
||||
SWI osPrintString
|
||||
SETD.0 Wanted
|
||||
SWI osPrintString
|
||||
SETD.0 OnceText
|
||||
SWI osPrintString
|
||||
RSTA
|
||||
SWI osExit
|
||||
|
||||
noName:
|
||||
SETD.0 Usage
|
||||
SWI osPrintString
|
||||
INIA 0d2
|
||||
SWI osExit
|
||||
|
||||
noWrite:
|
||||
SETD.0 NoWriteText
|
||||
SWI osPrintString
|
||||
INIA 0d1
|
||||
SWI osExit
|
||||
|
||||
; DP0 names a string and DP1 where it goes. DP1 is left on the zero at the end, so one
|
||||
; string can be written straight after another.
|
||||
copyString:
|
||||
LDA.0
|
||||
BRA copyDone
|
||||
STA.1
|
||||
INCD.0
|
||||
INCD.1
|
||||
BRI copyString
|
||||
copyDone:
|
||||
RRET
|
||||
|
||||
; DP0 names the line. osFileSave wants a size, and a file of whole blocks and a tail is
|
||||
; that count with the blocks in A and the tail in B - one block is never full here.
|
||||
measure:
|
||||
RSTB
|
||||
measureLoop:
|
||||
LDA.0
|
||||
BRA measureDone
|
||||
INCD.0
|
||||
MVQB
|
||||
INIA 0d1
|
||||
CCF
|
||||
ADD
|
||||
MVQB
|
||||
BRI measureLoop
|
||||
measureDone:
|
||||
RSTA
|
||||
RRET
|
||||
|
||||
#Data
|
||||
|
||||
#Base 0x2000
|
||||
|
||||
Prefix:
|
||||
"system "
|
||||
Usage:
|
||||
"once what? try: Once /System/Boot/something.bin
|
||||
"
|
||||
DoneText:
|
||||
"next start: "
|
||||
OnceText:
|
||||
", once
|
||||
"
|
||||
NoWriteText:
|
||||
"it would not write
|
||||
"
|
||||
OncePath:
|
||||
"/System/Boot/once.cfg"
|
||||
|
||||
Wanted:
|
||||
#Reserve 0d129
|
||||
Line:
|
||||
#Reserve 0d160
|
||||
@@ -361,6 +361,7 @@ from every assembly file in it. Several are old programs written for the bare ma
|
||||
| Snake | A game. Draws a whole screen with cursor addressing and steers with single keys, asking the console once a frame and never waiting. |
|
||||
| Keys | The console interrupting rather than being asked. The only one that brings a vector of its own, which is what the version two format exists for. |
|
||||
| Say | Prints whatever it was told, which is the shortest thing that shows osArgument working. |
|
||||
| Once | Asks the loader to start something else on the next start, and only that one, in 569 bytes. |
|
||||
| Status | Says what the last program made of what it was asked to do, in 222 bytes. The shell keeps the number and does not print it; this is how a person looks. |
|
||||
| Settle | Says how the last start went and tells the machine to stop falling back, in 353 bytes. A program rather than a shell word, because the shell is for what cannot be done without it. |
|
||||
| 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. |
|
||||
|
||||
Reference in New Issue
Block a user