diff --git a/Programs/CosmOS/README.md b/Programs/CosmOS/README.md index 8c6bacc..8efeb37 100644 --- a/Programs/CosmOS/README.md +++ b/Programs/CosmOS/README.md @@ -951,6 +951,13 @@ drive made of memory in **drive 2**. The scratch drive is what `osTakeScreen` wr 1 is yours and comes after nothing, so adding the scratch drive later did not renumber it. It is made the first time it is needed and then left alone: never rebuilt, never cleaned, never committed. +It is **copied** before every start, though, and kept three starts back. One copy taken at +every start would be worse than none: a disk is lost when something goes wrong, and the next +thing anybody does is start the machine again to look, which is when a single backup gets +overwritten by the wreckage. Nor is the copy guarded by any check that the disk still looks +right, because no such check can be written - the disk that went missing here was a perfectly +valid and perfectly empty filesystem, because the format had succeeded. + That last part is the point. Everything else in this repository is made from source and can be thrown away without losing anything - but a disk is where something *made on the machine* lives, and a disk that `make clean` deletes is not a disk of your own. It sits outside diff --git a/README.md b/README.md index d150f1d..9d3a2a6 100644 --- a/README.md +++ b/README.md @@ -146,6 +146,11 @@ Both put a second disk in drive 1, at `Disks/personal.img`. It is made once and rebuilt, cleaned or committed: everything else here can be thrown away and made again from source, and that one is where anything made ON the machine lives. +Starting the machine copies it first, three starts back, as `personal.img.1` and so on. Not +one copy: the way a disk is lost is that something goes wrong and the very next thing anybody +does is start the machine again to see how bad it is, which is exactly when a single backup +would be overwritten by the wreckage. + Then `dir` to see what is there, `load Snake.sbx` and `run` to play something, or `load Asm.sbx` and `run cosmos.asm` to watch the machine build itself. Every source in `Programs/` is on that disk, under `/Source`, so anything not shipped as a diff --git a/makefile b/makefile index 6243e50..112e57c 100644 --- a/makefile +++ b/makefile @@ -171,6 +171,8 @@ COSMOS_DISK = $(PROG_BUILD)/cosmos.img # own that a clean deletes is not a disk of your own. It is a rule with no prerequisites, so # once it exists make never looks at it again. PERSONAL_DISK = Disks/personal.img +# How many starts back the personal disk is kept. See personalBackup for why it is not one. +PERSONAL_BACKUPS = 3 # ---- And a drive made of memory, as drive 2 ---- # @@ -615,16 +617,44 @@ disk: $(COSMOS) $(COSMOS_DISK) $(PERSONAL_DISK): @mkdir -p $(@D) $(DISKTOOL) format $@ 2048 8 - @echo " That disk is yours. It is drive 1, and nothing in this makefile will touch it" - @echo " again - not clean, not a rebuild. Delete it by hand if you want a new one." + @echo " That disk is yours. It is drive 1, and nothing in this makefile will write to" + @echo " it again - not clean, not a rebuild. Delete it by hand if you want a new one." + @echo " Starting the machine copies it to $(PERSONAL_DISK).1, keeping $(PERSONAL_BACKUPS) starts back." -run-cosmos: $(COSMOS_DISK) $(PERSONAL_DISK) +# ---- And kept a few starts back ---- +# +# Copied before every start, and KEPT SEVERAL DEEP rather than copied over one file. +# +# ONE BACKUP TAKEN AT EVERY START IS WORSE THAN NONE. The way a disk is lost is that +# something goes wrong - and the very next thing anybody does is start the machine again to +# see how bad it is, which is exactly when a single backup is overwritten by the wreckage. +# Three deep means the damage has to happen and then be started past three times before the +# copy that would have helped is gone. +# +# AND IT IS NOT GUARDED BY "does the disk still look all right", because that check cannot +# be written. The disk that went missing here was a perfectly valid and perfectly empty +# filesystem: the format had succeeded. Nothing about a disk says it has lost anything, +# which is the whole reason to keep the old ones rather than to judge the new one. +# +# Outside clean's reach, like the disk itself. A backup a rebuild deletes is not one. +personalBackup: + @if [ -f $(PERSONAL_DISK) ]; then \ + n=$(PERSONAL_BACKUPS); \ + while [ $$n -gt 1 ]; do \ + p=$$((n - 1)); \ + if [ -f $(PERSONAL_DISK).$$p ]; then cp -f $(PERSONAL_DISK).$$p $(PERSONAL_DISK).$$n; fi; \ + n=$$p; \ + done; \ + cp -f $(PERSONAL_DISK) $(PERSONAL_DISK).1; \ + fi + +run-cosmos: $(COSMOS_DISK) $(PERSONAL_DISK) personalBackup $(EMU_RUN) --disk $(COSMOS_DISK) --disk $(PERSONAL_DISK) --ram-disk $(SCRATCH_BLOCKS) # 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) $(PERSONAL_DISK) +run-cosmos-direct: $(COSMOS) $(COSMOS_DISK) $(PERSONAL_DISK) personalBackup $(EMU_RUN) --disk $(COSMOS_DISK) --disk $(PERSONAL_DISK) --ram-disk $(SCRATCH_BLOCKS) $(COSMOS) # ---- The same disk, on the machine with a screen ---- @@ -636,10 +666,10 @@ run-cosmos-direct: $(COSMOS) $(COSMOS_DISK) $(PERSONAL_DISK) # was built when the disk was made, so a machine whose console has changed will happily boot # an image full of programs written for the old one - and they will draw whatever the old way # now means. Making the disk a dependency of running it is what stops that being a puzzle. -run-voyager: $(COSMOS_DISK) $(PERSONAL_DISK) +run-voyager: $(COSMOS_DISK) $(PERSONAL_DISK) personalBackup $(VOY_RUN) --disk $(COSMOS_DISK) --disk $(PERSONAL_DISK) --ram-disk $(SCRATCH_BLOCKS) -run-voyager-direct: $(COSMOS) $(COSMOS_DISK) $(PERSONAL_DISK) +run-voyager-direct: $(COSMOS) $(COSMOS_DISK) $(PERSONAL_DISK) personalBackup $(VOY_RUN) --disk $(COSMOS_DISK) --disk $(PERSONAL_DISK) --ram-disk $(SCRATCH_BLOCKS) $(COSMOS) # Pull in the dependency rules the assembler wrote with -M, so that touching a library @@ -647,5 +677,5 @@ run-voyager-direct: $(COSMOS) $(COSMOS_DISK) $(PERSONAL_DISK) -include $(PROG_DEPS) # Phony targets -.PHONY: all clean install test bless sanitize strict \ +.PHONY: all clean install test bless sanitize strict personalBackup \ programs cosmos disk run-cosmos run-cosmos-direct run-voyager run-voyager-direct