diff --git a/Programs/CosmOS/README.md b/Programs/CosmOS/README.md index 30585cc..6adc125 100644 --- a/Programs/CosmOS/README.md +++ b/Programs/CosmOS/README.md @@ -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, 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: CosmOS divides the two SplitBit address spaces by convention: diff --git a/Programs/makefile b/Programs/makefile index b9dadec..942c0ea 100644 --- a/Programs/makefile +++ b/Programs/makefile @@ -79,6 +79,23 @@ DISKTOOL ?= ../SplitDisk COSMOS = $(BUILD)/CosmOS/Source/cosmos.bin APPS = $(patsubst CosmOS/Apps/%.asm,$(BUILD)/CosmOS/Apps/%.sbx,$(wildcard CosmOS/Apps/*.asm)) 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) $(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 # 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. -$(COSMOS_DISK): $(APPS) $(NATIVE_ASM) testPrograms/stringKeyword.asm \ +$(COSMOS_DISK): $(APPS) $(NATIVE_ASM) $(COSMOS) $(STAGE2) testPrograms/stringKeyword.asm \ $(wildcard CosmOS/Apps/*.asm) \ $(wildcard CosmOS/Source/*.asm) $(wildcard CosmOS/Assembler/*.asm) @mkdir -p $(@D) 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 @# assemble, and what those include. It was thirty nine files in one list with @# 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 $@ /Source $(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 @# turns out to be a program, so anything in here starts by name from anywhere. @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/Keys.asm /Source/Keys.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 @# 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 \ 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/numbers.asm CosmOS/Assembler/scratch.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. 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) clean: @@ -184,4 +227,4 @@ clean: # reassembles every program that includes it. -include $(DEPENDENCIES) -.PHONY: all clean cosmos cosmos-disk run-cosmos +.PHONY: all clean cosmos cosmos-disk run-cosmos run-cosmos-direct