A boot payload can arrange its own Data Segment

Stage one places Program Memory and nothing else, because knowing where a
payload's data ends and its code begins would mean knowing a format, and
knowing formats is what ROM must do as little of as possible. But the real
second stage needs a Data Segment: sbfs.asm has variables and a string it
compares against.

The answer needs nothing new. A loadable image is written into the slot as
code followed by data, so the data image is already in Program Memory just
past the code - and the payload's first instructions blit it down to where
it was assembled for. Proved by slotData.asm, which prints from a string it
placed itself.

The padding is the part worth recording. The blit needs a length and the
assembler will not work out the difference between two labels, so the
segment is padded to a round number and that number is what gets copied.
The first draft padded to 257 and copied 256, and the byte that did not
arrive was padding, so it worked by luck. It is exact now and says why.

This is the shape the user asked for and it goes further than the
mechanism: the second stage becomes a loader for the machine's ORDINARY
image format rather than for anything boot-specific, so bare metal SplitBit
stops being a special case. A program that wants no operating system is
just an image, developed under CosmOS like any other, and selectable at
boot because it is a file.
This commit is contained in:
Anachronaut
2026-08-27 13:45:11 -04:00
parent d07b23f90b
commit 82adeeb193
5 changed files with 84 additions and 0 deletions
+65
View File
@@ -0,0 +1,65 @@
; slotData.asm
; A boot slot payload that arranges its own Data Segment.
;
; Stage one places Program Memory and nothing else, because knowing where a payload's data
; ends and its code begins would mean knowing a format, and knowing formats is the thing
; ROM must do as little of as possible. So a payload that wants initialised data arranges
; it: a loadable image is written into the slot as code followed by data, which leaves the
; data image sitting in Program Memory just past the code, and the first thing the payload
; does is blit it down to where it was assembled for.
;
; This is how the real second stage will get the Data Segment that sbfs.asm needs.
;
; THE PADDING IS NOT DECORATION. The blit needs a length, the assembler will not work out
; a difference between two labels, so the segment is padded to a round number and that
; number is what gets copied. Reserve one byte too many and the last byte does not arrive:
; the first draft of this padded to 257 and copied 256.
;
; Written by Anachronaut
#Program
#Base 0xC000
start:
RSTA
OUTA 0xE0 ; SourceBank: Program Memory, where stage one put everything.
SETD.0 codeEnd
PSHD.0
POPA
POPB
OUTB 0xE1
OUTA 0xE2
INIA 0d1
OUTA 0xE3 ; DestBank: Data Memory.
SETD.0 Greeting
PSHD.0
POPA
POPB
OUTB 0xE4
OUTA 0xE5
INIA 0x01
OUTA 0xE6
RSTA
OUTA 0xE7 ; A round 256 bytes, which the segment is padded to.
INIA 0x01
OUTA 0xE8
SETD.0 Greeting
sayLoop:
LDA.0
BRA sayDone
OUTA 0x00
INCD.0
BRI sayLoop
sayDone:
HALT
codeEnd:
#Data
#Base 0x3000
Greeting:
"a payload with data of its own
"
Padding:
#Reserve 0d224
+3
View File
@@ -0,0 +1,3 @@
a payload with data of its own
Execution halted.
[exit 0]
+1
View File
@@ -1,3 +1,4 @@
Programs/Boot/slotData.asm redundant-setd 1
Programs/Boot/stage1.asm redundant-setd 2 Programs/Boot/stage1.asm redundant-setd 2
Programs/CosmOS/Apps/Copy.asm redundant-setd 2 Programs/CosmOS/Apps/Copy.asm redundant-setd 2
Programs/CosmOS/Apps/Edit.asm redundant-setd 3 Programs/CosmOS/Apps/Edit.asm redundant-setd 3
+9
View File
@@ -377,3 +377,12 @@ tail -c +17 "$WORK/otherSlot.sbx" > "$WORK/otherSlot.raw"
# And the same disk with the other slot chosen, so both are exercised. # And the same disk with the other slot chosen, so both are exercised.
cp "$DISKS/chain.img" "$DISKS/chainAlt.img" cp "$DISKS/chain.img" "$DISKS/chainAlt.img"
"$TOOL" bootslot "$DISKS/chainAlt.img" 1 >/dev/null "$TOOL" bootslot "$DISKS/chainAlt.img" 1 >/dev/null
# And a slot whose payload has a Data Segment of its own. Stage one places Program Memory
# and nothing else, so the payload copies its data down from just past its own code - which
# is the mechanism the real second stage will need, since sbfs.asm has variables and a
# string it compares against.
"$TOOL" format "$DISKS/chainData.img" 256 4 4 >/dev/null
"$ROOT/Assembler" "$ROOT/Programs/Boot/slotData.asm" -o "$WORK/slotData.sbx" >/dev/null
tail -c +17 "$WORK/slotData.sbx" > "$WORK/slotData.raw"
"$TOOL" boot "$DISKS/chainData.img" "$WORK/slotData.raw" 0 >/dev/null
+6
View File
@@ -368,6 +368,12 @@ bootChainAlt | Boot/stage1.asm | run | -
# A disk with no boot area cannot be started, and says so in the one character a ROM has # A disk with no boot area cannot be started, and says so in the one character a ROM has
# room to say anything in. # room to say anything in.
bootNoArea | Boot/stage1.asm | run | - | - | disks/sbfs.img bootNoArea | Boot/stage1.asm | run | - | - | disks/sbfs.img
# A payload that arranges its own Data Segment, by copying it down from just past its own
# code. Stage one places Program Memory and nothing else - knowing where a payload's data
# ended would mean knowing a format - so this is how the real second stage will get the
# variables and the string that sbfs.asm needs.
bootData | Boot/slotData.asm | assemble | - | -
bootDataRuns | Boot/stage1.asm | run | - | - | disks/chainData.img
# Reading a disk that has directories on it. The machine can walk a path at this point but # Reading a disk that has directories on it. The machine can walk a path at this point but
# cannot make a directory, so the disk is built by the host tool and read here - which is # cannot make a directory, so the disk is built by the host tool and read here - which is
# the two implementations checking each other rather than either checking itself. # the two implementations checking each other rather than either checking itself.