The clean install disk is one the machine can start itself from

make run-cosmos handed the emulator a boot image AND a disk, so it took the
direct path every time: memory placed from outside, nothing on the disk
consulted about it. The whole boot chain was built and tested and then not
used by the one command that runs the system.

The disk is formatted with a boot area now, stage two goes into slot zero
as raw bytes, and the system is an ordinary file at /System/Boot/cosmos.bin
- which is what boot.cfg would choose between if there were one. There is
not: stage two falls back to that name when the file is missing, and a
clean install with nothing to configure is the right default.

run-cosmos names no image, so the machine starts itself. The old behaviour
is run-cosmos-direct, which is worth keeping and worth naming honestly: it
is what a debugger does, and it is what to use when the thing being
debugged is the boot chain, since it skips the boot chain.

/Source gains stage1.asm and stage2.asm, so the machine can rebuild what
starts it. Everything stage two includes is already in /Lib, so Asm
stage2.asm on the machine produces the bytes a boot slot takes. Stage one
is the exception and always will be: it is the ROM, and the one part of
this that a disk cannot replace.

Second slot left empty, which is what makes replacing the first survivable.
This commit is contained in:
Anachronaut
2026-08-27 18:45:52 -04:00
parent f1cc2e56b2
commit b4206673a6
2 changed files with 73 additions and 4 deletions
+26
View File
@@ -473,6 +473,32 @@ These are ordinary SBEX files on SBFS. None of them is built into the operating
a disk can be filled from either side: the host tool puts files on, and so does the machine, a disk can be filled from either side: the host tool puts files on, and so does the machine,
which assembles its own now. which assembles its own now.
### A Clean Install:
`make cosmos-disk` in `Programs/` lays down a disk the machine can start itself from, and
`make run-cosmos` starts it - with no boot image named, so the emulator shadows its ROM and
reads the disk for everything else.
```
/ Apps Source Lib System
/Apps what you run, and the second place the shell looks for a word
/Source what you assemble, including stage1.asm and stage2.asm
/Lib what those include
/System/Boot cosmos.bin, and the slots the loader lives in
```
**The loader's own source is on the disk**, which means the machine can rebuild what starts
it: `Asm stage2.asm` produces the bytes that go in a boot slot, and everything stage two
includes is already in `/Lib`. Stage one is the exception and always will be - it is the
ROM, and the one part of this a disk cannot replace.
No `boot.cfg` is written. Stage two falls back to `/System/Boot/cosmos.bin` when there is
none, and a clean install having nothing to configure is the right default.
`make run-cosmos-direct` hands the system over the old way instead, memory placed from
outside with nothing on the disk consulted. That is what a debugger does, and it is what to
use when the thing being debugged is the boot chain, since it skips the boot chain.
## The Application Model: ## The Application Model:
CosmOS divides the two SplitBit address spaces by convention: CosmOS divides the two SplitBit address spaces by convention:
+47 -4
View File
@@ -79,6 +79,23 @@ DISKTOOL ?= ../SplitDisk
COSMOS = $(BUILD)/CosmOS/Source/cosmos.bin COSMOS = $(BUILD)/CosmOS/Source/cosmos.bin
APPS = $(patsubst CosmOS/Apps/%.asm,$(BUILD)/CosmOS/Apps/%.sbx,$(wildcard CosmOS/Apps/*.asm)) APPS = $(patsubst CosmOS/Apps/%.asm,$(BUILD)/CosmOS/Apps/%.sbx,$(wildcard CosmOS/Apps/*.asm))
COSMOS_DISK = $(BUILD)/cosmos.img COSMOS_DISK = $(BUILD)/cosmos.img
# ---- What starts the machine ----
#
# Stage two goes into a boot slot as RAW BYTES: stage one reads blocks into Program Memory
# and jumps to the first one, so a sixteen byte header would be sixteen bytes of nonsense
# executed first. Its Data Segment travels with it and it copies that down itself.
#
# Stage one is not here at all. It is the ROM, built into the emulator by the top level
# makefile from the same source, which is what makes it the one part of this that a disk
# cannot replace.
STAGE2 = $(BUILD)/Boot/stage2.raw
DEPENDENCIES += $(BUILD)/Boot/stage2.d
$(STAGE2): Boot/stage2.asm
@mkdir -p $(@D)
$(ASM) $(INCLUDES) -M $(BUILD)/Boot/stage2.d -o $(BUILD)/Boot/stage2.sbx $<
tail -c +17 $(BUILD)/Boot/stage2.sbx > $@
DEPENDENCIES += $(APPS:.sbx=.d) DEPENDENCIES += $(APPS:.sbx=.d)
$(BUILD)/CosmOS/Apps/%.sbx: CosmOS/Apps/%.asm $(BUILD)/CosmOS/Apps/%.sbx: CosmOS/Apps/%.asm
@@ -111,12 +128,17 @@ cosmos: $(COSMOS) $(APPS) $(NATIVE_ASM)
# blocks of four thousand and ninety six - three tenths of one per cent - to buy a hundred # blocks of four thousand and ninety six - three tenths of one per cent - to buy a hundred
# and twenty eight more names. The superblock has carried this number per disk since the # and twenty eight more names. The superblock has carried this number per disk since the
# format was written, so nothing but this line knows what it is. # format was written, so nothing but this line knows what it is.
$(COSMOS_DISK): $(APPS) $(NATIVE_ASM) testPrograms/stringKeyword.asm \ $(COSMOS_DISK): $(APPS) $(NATIVE_ASM) $(COSMOS) $(STAGE2) testPrograms/stringKeyword.asm \
$(wildcard CosmOS/Apps/*.asm) \ $(wildcard CosmOS/Apps/*.asm) \
$(wildcard CosmOS/Source/*.asm) $(wildcard CosmOS/Assembler/*.asm) $(wildcard CosmOS/Source/*.asm) $(wildcard CosmOS/Assembler/*.asm)
@mkdir -p $(@D) @mkdir -p $(@D)
rm -f $@ rm -f $@
$(DISKTOOL) format $@ 4096 24 @# A BOOT AREA, so that this is a disk the machine can start itself from rather than
@# one it has to be handed. Forty blocks a slot and two slots: stage two is about
@# eight thousand bytes, and the second slot is what makes replacing it survivable,
@# since raw blocks have no name and so nothing to rename.
$(DISKTOOL) format $@ 4096 24 40
$(DISKTOOL) boot $@ $(STAGE2) 0
@# THREE DIRECTORIES, WHICH IS WHAT A CLEAN INSTALL LOOKS LIKE: what you run, what you @# THREE DIRECTORIES, WHICH IS WHAT A CLEAN INSTALL LOOKS LIKE: what you run, what you
@# assemble, and what those include. It was thirty nine files in one list with @# assemble, and what those include. It was thirty nine files in one list with
@# cosmos.asm sitting between fileStream.asm and sbfs.asm. @# cosmos.asm sitting between fileStream.asm and sbfs.asm.
@@ -130,6 +152,12 @@ $(COSMOS_DISK): $(APPS) $(NATIVE_ASM) testPrograms/stringKeyword.asm \
$(DISKTOOL) mkdir $@ /Apps $(DISKTOOL) mkdir $@ /Apps
$(DISKTOOL) mkdir $@ /Source $(DISKTOOL) mkdir $@ /Source
$(DISKTOOL) mkdir $@ /Lib $(DISKTOOL) mkdir $@ /Lib
$(DISKTOOL) mkdir $@ /System
$(DISKTOOL) mkdir $@ /System/Boot
@# The system itself, as a file, which is the whole of what boot.cfg chooses between.
@# No boot.cfg is written: stage two falls back to this name when there is none, and a
@# clean install having nothing to configure is the right default.
$(DISKTOOL) put $@ $(COSMOS) /System/Boot/cosmos.bin
@# What you run. /Apps is the second place the shell looks when a word it does not know @# What you run. /Apps is the second place the shell looks when a word it does not know
@# turns out to be a program, so anything in here starts by name from anywhere. @# turns out to be a program, so anything in here starts by name from anywhere.
@for app in $(APPS); do \ @for app in $(APPS); do \
@@ -159,10 +187,16 @@ $(COSMOS_DISK): $(APPS) $(NATIVE_ASM) testPrograms/stringKeyword.asm \
$(DISKTOOL) put $@ CosmOS/Apps/Say.asm /Source/Say.asm $(DISKTOOL) put $@ CosmOS/Apps/Say.asm /Source/Say.asm
$(DISKTOOL) put $@ CosmOS/Apps/Keys.asm /Source/Keys.asm $(DISKTOOL) put $@ CosmOS/Apps/Keys.asm /Source/Keys.asm
$(DISKTOOL) put $@ testPrograms/stringKeyword.asm /Source/strings.asm $(DISKTOOL) put $@ testPrograms/stringKeyword.asm /Source/strings.asm
@# And the loader, so the machine can rebuild what starts it. Assembling stage2.asm on
@# the machine and writing the result into the other boot slot is the whole of a
@# self-hosted boot chain, and everything it includes is already in /Lib.
$(DISKTOOL) put $@ Boot/stage1.asm /Source/stage1.asm
$(DISKTOOL) put $@ Boot/stage2.asm /Source/stage2.asm
@# And what those include. Everything here is named by an #Include somewhere and by @# And what those include. Everything here is named by an #Include somewhere and by
@# nothing else, which is exactly what makes it a library rather than a source. @# nothing else, which is exactly what makes it a library rather than a source.
@for f in CosmOS/Source/console.asm CosmOS/Source/fileStream.asm \ @for f in CosmOS/Source/console.asm CosmOS/Source/fileStream.asm \
CosmOS/Source/sbfs.asm CosmOS/Source/services.asm CosmOS/Source/text.asm \ CosmOS/Source/sbfs.asm CosmOS/Source/services.asm CosmOS/Source/text.asm \
CosmOS/Source/config.asm \
CosmOS/Assembler/classify.asm CosmOS/Assembler/labels.asm \ CosmOS/Assembler/classify.asm CosmOS/Assembler/labels.asm \
CosmOS/Assembler/numbers.asm CosmOS/Assembler/scratch.asm \ CosmOS/Assembler/numbers.asm CosmOS/Assembler/scratch.asm \
CosmOS/Assembler/source.asm CosmOS/Assembler/table.asm \ CosmOS/Assembler/source.asm CosmOS/Assembler/table.asm \
@@ -174,7 +208,16 @@ $(COSMOS_DISK): $(APPS) $(NATIVE_ASM) testPrograms/stringKeyword.asm \
# match the programs on it. # match the programs on it.
cosmos-disk: $(COSMOS) $(COSMOS_DISK) cosmos-disk: $(COSMOS) $(COSMOS_DISK)
run-cosmos: $(COSMOS) $(COSMOS_DISK) # THE MACHINE STARTS ITSELF. No image is named, so the emulator shadows its ROM into
# Program Memory and that reads the disk for everything else - a boot slot, then a loader,
# then whatever /System/Boot/boot.cfg names, or cosmos.bin when it names nothing.
run-cosmos: $(COSMOS_DISK)
$(EMU) --disk $(COSMOS_DISK)
# The same disk with the system handed over directly instead, which is what a debugger
# does: memory is placed from outside and nothing on the disk is consulted about it. Useful
# when the thing being debugged is the boot chain itself, since it skips the boot chain.
run-cosmos-direct: $(COSMOS) $(COSMOS_DISK)
$(EMU) --disk $(COSMOS_DISK) $(COSMOS) $(EMU) --disk $(COSMOS_DISK) $(COSMOS)
clean: clean:
@@ -184,4 +227,4 @@ clean:
# reassembles every program that includes it. # reassembles every program that includes it.
-include $(DEPENDENCIES) -include $(DEPENDENCIES)
.PHONY: all clean cosmos cosmos-disk run-cosmos .PHONY: all clean cosmos cosmos-disk run-cosmos run-cosmos-direct