diff --git a/Programs/Boot/slotData.asm b/Programs/Boot/slotData.asm new file mode 100644 index 0000000..dc9b73d --- /dev/null +++ b/Programs/Boot/slotData.asm @@ -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 diff --git a/Tests/expected/bootDataRuns.out b/Tests/expected/bootDataRuns.out new file mode 100644 index 0000000..53dc6fe --- /dev/null +++ b/Tests/expected/bootDataRuns.out @@ -0,0 +1,3 @@ +a payload with data of its own +Execution halted. +[exit 0] diff --git a/Tests/lint-baseline.txt b/Tests/lint-baseline.txt index 3042a1b..c7d6a01 100644 --- a/Tests/lint-baseline.txt +++ b/Tests/lint-baseline.txt @@ -1,3 +1,4 @@ +Programs/Boot/slotData.asm redundant-setd 1 Programs/Boot/stage1.asm redundant-setd 2 Programs/CosmOS/Apps/Copy.asm redundant-setd 2 Programs/CosmOS/Apps/Edit.asm redundant-setd 3 diff --git a/Tests/makedisks.sh b/Tests/makedisks.sh index 4d5f7f2..7e5bf43 100755 --- a/Tests/makedisks.sh +++ b/Tests/makedisks.sh @@ -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. cp "$DISKS/chain.img" "$DISKS/chainAlt.img" "$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 diff --git a/Tests/manifest b/Tests/manifest index 0ae5409..64176f6 100644 --- a/Tests/manifest +++ b/Tests/manifest @@ -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 # room to say anything in. 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 # 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.