CosmOS knows about all four drives
A mounted disk is EIGHT BYTES - where its directory starts, how many
blocks it is, how big the disk is, and where you are on it. They now sit
together in the data segment, and changing drives is one copy out and one
copy in. The other three thousand lines of filesystem go on reading the
same four names they always have and never learn there is more than one
disk, which is the whole reason this was affordable.
The version is not in the record. It is checked at mount and thrown away,
because a version one disk's zero parent already reads as "in the root".
Every drive is mounted at boot: the controller says how many are plugged
in and each is tried in turn. One with nothing in it, or a disk this
cannot read, is left unmounted rather than stopping the others, so a
machine with a good disk in drive 0 and a blank in drive 1 starts.
'drive' says which one, 'drive 1' goes to another, and the working
directory goes with it - where you are on a disk is part of which disk you
are on. A drive the machine has not got is refused, and refused
differently from one that is there with nothing readable in it.
Three things the assembly caught me on, all the same misunderstanding of
what survives a call:
- OR reads A and B, and the bit came back from sbfsDriveBit in Q, which
RET does not disturb - but RET does put A back. The mounted mask never
got set and drive 0 was reported unmountable.
- MVQA then RSTA throws away the copy it just made, so doubling a bit
doubled nothing. SHL does it in one instruction, because A and B are
one register to it.
- There is no move from A to B. INB reads a port straight into B, which
is what the drive count comparison wanted.
run.sh takes more than one image now, separated by a plus, since the
machine has four drives and a test that could only name one could not
check any of this.
The buffer note is forgotten on a drive change and that is DELIBERATELY
kept although nothing can currently reach it: only the file read-ahead
consults it, a directory scan does not, and finding a file requires a
scan which overwrites the note on the way past. Two disks were built with
the same file at the same block to try to catch it and the answer was
right either way. Three instructions to hold an invariant rather than a
story about a bug - and the comment says so instead of claiming a fix.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01E2JrLzFvuFX9fgi1LDRjrW
This commit is contained in:
co-authored by
Claude Opus 5
parent
b1538e0618
commit
5644c24113
@@ -0,0 +1,27 @@
|
||||
CosmOS
|
||||
> 0
|
||||
> greet.sbx 211
|
||||
hello.sbx 53
|
||||
Life.sbx 1396
|
||||
Snake.sbx 2164
|
||||
Keys.sbx 664
|
||||
Say.sbx 156
|
||||
Break.sbx 149
|
||||
Grid.sbx 543
|
||||
notes.txt 21
|
||||
hi.script 121
|
||||
bad.script 45
|
||||
plain.script 24
|
||||
cross.script 280
|
||||
nonl.script 38
|
||||
outer.script 376
|
||||
inner.script 44
|
||||
loop.script 35
|
||||
17 files
|
||||
> > other.txt 28
|
||||
notes <dir>
|
||||
1 file, 1 directory
|
||||
> /notes> > /notes> > /notes> drive: this machine has no such drive
|
||||
/notes> halted
|
||||
Execution halted.
|
||||
[exit 0]
|
||||
@@ -0,0 +1,11 @@
|
||||
drive
|
||||
dir
|
||||
drive 1
|
||||
dir
|
||||
cd /notes
|
||||
drive 0
|
||||
drive 1
|
||||
drive 0
|
||||
drive 1
|
||||
drive 3
|
||||
exit
|
||||
@@ -115,6 +115,16 @@ for i in 1 2 3 4 5 6 7 8; do "$TOOL" put "$DISKS/sbfs.img" "filler$i.txt" >/dev/
|
||||
printf 'this is not a program' > notes.txt
|
||||
"$TOOL" put "$DISKS/cosmos.img" notes.txt >/dev/null
|
||||
|
||||
# ---- A second disk, for the second drive ----
|
||||
#
|
||||
# Deliberately nothing like the first: its own file and its own directory, so that a test
|
||||
# looking at one cannot be looking at the other by accident. Small, because what is on it
|
||||
# matters and how much does not.
|
||||
"$TOOL" format "$DISKS/other.img" 512 4 >/dev/null
|
||||
printf 'this lives on the other disk' > other.txt
|
||||
"$TOOL" put "$DISKS/other.img" other.txt >/dev/null
|
||||
"$TOOL" mkdir "$DISKS/other.img" /notes >/dev/null
|
||||
|
||||
# ---- Scripts, including the ones that are meant to go wrong ----
|
||||
#
|
||||
# Built here rather than committed, because two of them are about BYTE POSITIONS and a
|
||||
|
||||
@@ -808,6 +808,18 @@ cosmosGrid | CosmOS/Source/cosmos.asm | run | cosmosGri
|
||||
# drive that exists with nothing in it - selectable, and failing to read, like an empty
|
||||
# floppy drive.
|
||||
driveSelectTest | testPrograms/driveSelectTest.asm | run | - | 200000 | disks/sbfs.img
|
||||
# ---- Two disks ----
|
||||
#
|
||||
# The first thing on this machine to have more than one. drive says which, and going to the
|
||||
# other shows a disk with nothing in common with the first - so a listing that looked right
|
||||
# could not have come from the wrong one.
|
||||
#
|
||||
# THE WORKING DIRECTORY GOES WITH THE DRIVE, which is the whole point of the mount record.
|
||||
# Drive 1 is left standing in /notes and drive 0 at the root, and the prompt says which on
|
||||
# every trip between them - three times each way, because a record that is copied one way
|
||||
# and not the other would still look right once. A drive this machine has not got is
|
||||
# refused.
|
||||
cosmosDrives | CosmOS/Source/cosmos.asm | run | cosmosDrives.in | 60000000 | disks/cosmos.img+disks/other.img
|
||||
printDecimalTest | testPrograms/printDecimalTest.asm | xfail | - | -
|
||||
printDigitTest | testPrograms/printDigitTest.asm | xfail | - | -
|
||||
printHexTest | testPrograms/printHexTest.asm | xfail | - | -
|
||||
|
||||
+10
-3
@@ -251,10 +251,16 @@ while IFS='|' read -r name src mode stdin limit disk keys; do
|
||||
# A disk starts fresh for every run, so a test cannot pass because of what a
|
||||
# previous one left lying on it. The emulator makes the image if it is
|
||||
# missing, which is what removing it first arranges for.
|
||||
if [ "$disk" != "-" ]; then
|
||||
# ---- More than one, separated by a plus ----
|
||||
#
|
||||
# The machine has four drives, so a test may name up to four images and they
|
||||
# become drives 0 upwards in the order written. Each keeps its own :ro and @N,
|
||||
# because those are properties of a disk rather than of the machine.
|
||||
for onedisk in ${disk//+/ }; do
|
||||
if [ "$onedisk" != "-" ]; then
|
||||
# A trailing :ro attaches the image write protected, so that a test can
|
||||
# check the device bars writes rather than the filesystem asking nicely.
|
||||
DISKFILE="${disk%:ro}"
|
||||
DISKFILE="${onedisk%:ro}"
|
||||
# And a trailing @N gives the disk a latency, so that a test can check the
|
||||
# filesystem waits for it. Every other test runs with the answer there
|
||||
# before the next instruction, which is the one condition under which not
|
||||
@@ -273,8 +279,9 @@ while IFS='|' read -r name src mode stdin limit disk keys; do
|
||||
esac
|
||||
EMUARGS+=(--disk "$BUILD/$DISKFILE")
|
||||
[ -n "$DISKWAIT" ] && EMUARGS+=(--disk-cycles "$DISKWAIT")
|
||||
case "$disk" in *:ro) EMUARGS+=(--write-protect) ;; esac
|
||||
case "$onedisk" in *:ro) EMUARGS+=(--write-protect) ;; esac
|
||||
fi
|
||||
done
|
||||
# A rom test names no image. The emulator then shadows its built in stage
|
||||
# one into Program Memory and reads the disk for everything else, which is
|
||||
# what a machine with no debugger attached does.
|
||||
|
||||
Reference in New Issue
Block a user