A disk made of memory, brought up by whoever owns it

THE MACHINE SUPPLIES BLOCKS AND SAYS WHAT A DRIVE IS. It says nothing about
filesystems, which is what leaves room for a system that would rather have
its own - and is why the volatile bit is a fact about the hardware rather
than a promise about SBFS.

  0x26        what the selected drive is: bit 0, contents do not survive
  0x27, 0x28  how many blocks it has
  --ram-disk N   a drive of N blocks with memory behind it

A drive of memory selects, reads, writes and has a size like any other, and
a program cannot tell the difference except by how fast it was. The one
thing it cannot work out for itself is that the contents are volatile,
because an empty disk and a volatile disk look identical from outside.

THAT BIT IS THE DIFFERENCE BETWEEN A DRIVE A SYSTEM MAY FORMAT ON SIGHT AND
ONE IT MUST NOT. CosmOS formats a volatile drive it cannot read, because
there was never anything on it to lose, and leaves every other unreadable
drive alone - an unformatted floppy is not an invitation, it is a blank
floppy. Removing that check formats somebody's blank disk, which is checked
rather than asserted: cosmosBlankDisk boots with one and requires it to be
refused.

So CosmOS grew a format. The size comes from the drive rather than from a
superblock, since a superblock states a size too and that is no use on a
disk which has not got one yet. Sixteen directory blocks, 128 names, chosen
rather than worked out: a scratch disk runs out of names long before room,
and this machine cannot divide.

The RAM disk is no faster on this emulator by default, and that is honest
rather than disappointing: the emulated disk has no seek time unless asked
for one. With --disk-cycles 10000 the same copy is 7.94M cycles against
8.70M, the difference being every write.

run.sh takes "ram:2048" where an image name goes, which needs no removing
between runs because there is nothing to remove.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01E2JrLzFvuFX9fgi1LDRjrW
This commit is contained in:
Anachronaut
2026-08-31 17:56:41 -04:00
co-authored by Claude Opus 5
parent 6b51d6391f
commit 04f1ffabd4
15 changed files with 351 additions and 6 deletions
+155 -1
View File
@@ -136,6 +136,138 @@ sbfsMountTooBig:
ADD ; Q is not zero: not a disk this will mount.
RET
; ---- Making a disk into a filesystem ----
;
; The machine hands out blocks and says how many; what they mean is the system's business.
; That is the whole reason this exists here rather than only in the host tool: a machine with
; a drive made of memory comes up with a drive full of zeroes, and zeroes are not a
; filesystem. Somebody has to write the first one, and it should be whoever is going to read
; it - which is also what leaves room for a system that would rather have its own.
;
; Q is zero if it worked. Everything on the drive is lost, which is why nothing calls this
; except on a drive the machine has said is volatile.
sbfsFormat:
; How big it is, which only the drive can say. A superblock would say too, and a disk with
; no superblock is exactly the case this is for.
INA 0x27
SETD.1 SbfsScratch
STA.1
INA 0x28
INCD.1
STA.1
; The buffer, cleared, because everything not written below has to be nought and the
; controller's buffer holds whatever was last read.
SETD.0 SbfsBuffer
RSTB
sbfsFormatClear:
RSTA
STA.0
INCD.0
DECB
BNB sbfsFormatClear ; 256 of them: B wraps from nought to 255 and back to nought.
; "SBFS", and the version. Two, because a disk made now has directories.
SETD.0 SbfsMagic
SETD.1 SbfsBuffer
INIB 0d4
sbfsFormatMagic:
LDA.0
STA.1
INCD.0
INCD.1
DECB
BNB sbfsFormatMagic
INIA 0d2
STA.1 ; Offset 4: the version.
; Offset 6, how many blocks the disk has, as the drive reported it.
SETD.1 SbfsBuffer
DPUP.1 0d06
SETD.0 SbfsScratch
LDA.0
STA.1
INCD.0
INCD.1
LDA.0
STA.1
; Offset 8, where the directory starts: block one, straight after this one.
SETD.1 SbfsBuffer
DPUP.1 0d08
RSTA
STA.1
INCD.1
INIA 0d1
STA.1
; Offset 10, how many blocks of directory. SIXTEEN, WHICH IS 128 NAMES, and chosen rather
; than worked out: a scratch disk runs out of names long before it runs out of room, and
; this machine cannot divide, so a number that fits every size this is used for is worth
; more than arithmetic to find a better one.
SETD.1 SbfsBuffer
DPUP.1 0d10
RSTA
STA.1
INCD.1
INIA 0d16
STA.1
; Block nought, written.
SETD.0 SbfsBlock
RSTA
STA.0
INCD.0
STA.0
SETD.1 SbfsBuffer
CALL sbfsBufferIn
CALL sbfsWriteBlock
BNQ sbfsFormatFailed
; And the directory cleared, so that no entry is in use. The buffer is already nought
; everywhere the superblock did not reach, so it is cleared once more and written sixteen
; times rather than built again each time.
SETD.0 SbfsBuffer
RSTB
sbfsFormatBlank:
RSTA
STA.0
INCD.0
DECB
BNB sbfsFormatBlank
INIA 0d16
SETD.1 SbfsCount
STA.1
sbfsFormatDirectory:
SETD.0 SbfsBlock
INCD.0
LDA.0
INCA
STA.0 ; Blocks one to sixteen. A directory never crosses 255 here.
SETD.1 SbfsBuffer
CALL sbfsBufferIn
CALL sbfsWriteBlock
BNQ sbfsFormatFailed
SETD.1 SbfsCount
LDA.1
DECA
STA.1
BNA sbfsFormatDirectory
RSTA
RSTB
CCF
ADD
RET
sbfsFormatFailed:
RSTA
INIB 0d1
CCF
ADD
RET
; ---- Every drive the machine has ----
;
; Asked for rather than assumed: the controller says how many are plugged in, and each is
@@ -192,7 +324,29 @@ sbfsMountEach:
STA.1
CALL sbfsMount
BNQ sbfsMountNext ; Nothing readable in that drive, and its slot stays empty.
BRQ sbfsMountGot
; ---- Nothing readable, and whether that is an invitation ----
;
; A drive the machine calls VOLATILE loses everything when the machine stops, so a volatile
; drive with no filesystem on it never had one to lose and bringing it up is the system's
; job. Anything else is somebody's disk: an unformatted floppy is not an invitation, it is
; a blank floppy, and a system that formatted it on sight would be a system you could not
; safely put a disk into.
;
; THE MACHINE SAYS WHAT THE DRIVE IS AND NOTHING ABOUT FILESYSTEMS. A system that would
; rather have its own reads the same bit and writes whatever it likes.
INA 0x26
INIB 0x01 ; VOLATILE
AND
BRQ sbfsMountNext ; Not ours to touch.
CALL sbfsFormat
BNQ sbfsMountNext
CALL sbfsMount
BNQ sbfsMountNext
sbfsMountGot:
; Mounted: remember which, and put the live record where it belongs.
SETD.1 SbfsDriveAt