Michael Heilemann, The Norseman / The Viking — Field notes from the disk revival project: Apple II archiving
A claim I'll stand behind after building this whole pipeline: if you only implement one filesystem check on a DOS 3.3 disk beyond "does the catalog parse," make it this one. It catches more real corruption than the T/S-list walk from last post, it catches corruption that looks completely fine from every other angle, and as far as I can tell, almost nobody bothers to write it. Here's why.
-=[ DOS 3.3 KEEPS A SECOND, INDEPENDENT RECORD OF THE TRUTH ]=-
Every disk validator worth using will walk the catalog and follow every file's track/sector chain, the way the last post described. That tells you what DOS 3.3's files claim about themselves. What it doesn't check is whether that story agrees with DOS 3.3's other bookkeeping: the allocation bitmap sitting in the VTOC, four bytes per track, one bit per sector, that DOS uses to answer a completely different question: is this sector free, or is it in use?
That bitmap is written independently of the catalog and T/S list structures. It isn't derived from them at read time. It's DOS's own separate ledger, updated whenever a file is created, deleted, or resized. Which means it gives you something the catalog walk alone can never give you: a second, structurally independent opinion on the same question. When two independent sources of truth about the same disk disagree, that disagreement is real signal, not noise.
off = 0x38 + 4 * track
if sector < 8:
byte, bit = vtoc[off + 1], sector
else:
byte, bit = vtoc[off], sector - 8
free = bool(byte & (1 << bit))
return not free
-=[ THE CHECK THAT CATCHES SOMETHING ]=-
Here's the walkthrough that matters. While following every file's T/S list (from the last post), this pipeline tracks who "owns" every sector it touches: the VTOC itself, the catalog chain, and each file's own T/S list and data sectors. Once that ownership map is built for the whole disk, it gets checked against the bitmap, sector by sector, in both directions:
| Bitmap says | Ownership map says | Meaning |
|---|---|---|
| Free | In use by a real file | Hard corruption. DOS's own free-space ledger disagrees with a file that claims to live there. One of the two is wrong, and it means this disk's bookkeeping is inconsistent with itself. |
| Allocated | Not owned by anything found | Usually benign. DOS reserves boot tracks it never assigns to a cataloged file, and deleted files leave their old sectors marked used until something overwrites them. Noted, not flagged as a problem. |
The first row is the one worth dwelling on, because of exactly how it can happen without anything else on the disk looking wrong. Picture a file that legitimately occupied track 12, sectors 4 through 9. It gets deleted. DOS updates the bitmap to mark those sectors free again, but doesn't zero them out; it just changes one bit per sector. Now imagine a marginal read during a later transfer subtly corrupts a byte somewhere in a different file's T/S list, and that corrupted pointer happens to land on track 12, sector 6, one of those "freed" sectors. The catalog walk from the last post will happily follow that pointer, read whatever stale data is still physically sitting there, and never notice anything is wrong. It's a valid track, a valid sector, readable data. Only the bitmap cross-check catches it: DOS's own ledger says that sector is free, but a file is confidently claiming it.
This is the check most tools skip. It requires building and holding an entire disk's worth of sector-ownership bookkeeping just to compare it against 140 bytes of bitmap at the end. More code than "does the T/S chain terminate," for a payoff that only shows up on disks where everything else already looks fine. It's exactly the kind of check that's easy to leave out of a first version, and easy to forget you left out, right up until it's the only thing standing between you and archiving a silently corrupted disk as a clean copy.
-=[ TWO SILENT SECTORS, ONE REAL BUG ]=-
There's a second direction this same ownership map catches, and it's not about the bitmap at all: two different files silently claiming the exact same sector. If "LANDER.BAS" and "LANDER.DATA" both have a T/S list entry pointing at track 8, sector 3, that's flagged the moment both show up in the ownership map for the same coordinates. A sector cannot belong to two files on a disk that's actually consistent with itself. This one doesn't even need the bitmap; it falls out of the same ownership-tracking machinery for free.
Put together, allocation-bitmap cross-checking and duplicate-sector detection are the two checks in this pipeline that consistently find damage nothing else does. Not because the underlying idea is exotic, but because it requires building the full picture of a disk's sector usage instead of stopping the moment each individual file's chain terminates cleanly.
Next up: the same idea, a different filesystem. ProDOS keeps its own version of this ledger, a volume-wide free-block bitmap instead of DOS 3.3's per-track scheme, and the cross-check translates almost directly.
Fair winds and following seas,
The Norseman