SCSI Disk Open — the "Last Block" Read, and What SINTRAN Does With It¶
Full path: SINTRAN/Devices/SCSI/scsi-open-last-block-read.md
Status: Live-trace reverse engineering. Every claim below is tagged [VERIFIED] (read directly from the execution trace bytes/registers) or [INFERRED] (reasoned, not yet proven from bytes). Assume nothing that is not tagged VERIFIED.
Evidence source: full ND-100 opcode+register execution trace of
@ENTER-DIRECTORY,,DISC-SCSI-1,0 on SINTRAN III VSX/500 version K, captured to
C:\Users\ronny\AppData\Local\trace\file-trace.txt (438,631 lines; Opcodes; lines carry
X B A D T L registers in octal, interleaved with Device; [SCSI-TRACE] lines). Version
confirmed K by byte-matching the running code at 035766 (135106) to the carved
versions/K-VSX-500/segments/006-S3FS.bin.
Disk under test: raw dump from real ND hardware, D:\ND\HDD\SCSI-K.image, 129,312 SCSI
blocks (LBA 0..129311), 1024-byte sectors (2 sectors = 1 ND page of 1024 words / 2048 bytes),
directory PACK-ONE.
1. Executive answer¶
During SCSI disk open, SINTRAN issues READ CAPACITY, then reads exactly one block — the disk's last physical block (LBA = the lastLBA that READ CAPACITY reported) — and consumes those 1024 bytes as a checksum-validated data structure: a SINTRAN disk area/layout table. It is never executed as code and never copied wholesale. After parsing that table into the device datafield, SINTRAN issues no directory (block-0) read, so the directory does not enter.
The APPROACHING END OF ACCOUNTING FILE console message is a [INFERRED] coincident background
warning from the accounting subsystem, not part of this disc-open path.
Correction to earlier notes: the last LBA is an ordinary host data block. Real SCSI drives keep defect data internal (obtained via the
READ DEFECT DATAcommand), never in the data area. The08 00 54 D9 ...content at LBA 129311 is therefore SINTRAN/ND filesystem data, not a SCSI defect/reallocation table. The old "defect table" label — and the READ-CAPACITY-as-usable hack built on it — were a misreading and have been dropped.
2. Which block, and why that block — [VERIFIED, proven]¶
- Line 281496:
[SCSI-TRACE] READ CAPACITY -> blockSize=1024 lastLBA=129311. The controller builds the 8-byte reply00 01 F9 1F 00 00 04 00(lastLBA =0x0001F91F= 129311, block size0x400= 1024) and DMAs it into ND memory at MAR0x8C4E..0x8C52(theDMA->ND xferlines are the controller writing memory, not the CPU). - The value
0xF91F(174437₃) appears in no CPU register and is never stored by any CPU instruction before the read is built (both trace searches return empty). It reaches memory only via the READ CAPACITY DMA. - At PC
114504–114530the resident SCSI driver loads that value back out of the response buffer (low wordD=174437=0xF91F, high wordA=000001) and packs the double-word disc address0x0001F91F= 129311 into the READ_6 CDB (STDTX/STATX), with length002000₃ = 1024. - Line 283792:
CDB op=0x08 (SC_READ_6) lba=129311 blocks=1 len=1024. The CDB LBA bytes01 F9 1Fare byte-identical to the READ CAPACITY reply's lastLBA field.
Conclusion: the read address is not computed and is not a filesystem block-0 translation. SINTRAN deliberately reads the last block reported by READ CAPACITY. This settles the long-standing ambiguity: it is a driver-level last-block read keyed off READ CAPACITY, not a capacity-relative address translation.
3. The block is a SINTRAN disk area/layout structure — [VERIFIED decode]¶
The 1024 data bytes DMA to physical MAR 0x03FE00..0x040200 (WHMAR=0x0003, WLMAR=0xFE00,
WTC2=0x04 WTCL=0x00 = 1024), completing at line 288122. Content (first 32 bytes) and decode
as big-endian 16-bit words:
08 00 54 D9 80 00 00 00 00 00 00 00 00 01 DC D8 C0 00 00 00 00 01 F9 1F 00 00 00 01 C0 00 00 00
| word | octal | value | meaning (interpretation) |
|---|---|---|---|
| w0 | 004000 | 2048 | bytes per ND page (page size) |
| w1 | 052331 | 0x54D9 | magic / identifier (unconfirmed) |
| w2 | 100000 | 0x8000 | area-descriptor #0 flag (bit15) |
| w6:w7 | — | 122072 | area #0 size = usable blocks (61036 pages × 2) |
| w8 | 140000 | 0xC000 | area-descriptor #1 flag (bit15+bit14) |
| w10:w11 | — | 129311 | area #1 size = physical last LBA |
| w14 | 140000 | 0xC000 | area-descriptor #2 flag |
The structure is a table of area/partition descriptors laid out at stride 6 words
({flag, ..., size-doubleword}), preceded by a header (page size + magic).
4. What SINTRAN does with it — [VERIFIED]¶
4a. Whole-block XOR checksum, tested against zero (validation)¶
Loop at PC 111051–111055, running 512 iterations (the full 512-word block, buffer virtual
base 0177000 — confirmed because the first LDATX returns 004000₃ = 0x0800 = block
word 0):
111051 LDATX 0 A := block[X] (alt page table, T=3)
111052 REXO SA DD D := D XOR A (accumulate)
111053 AAX 1 X := X + 1
111054 MIN *-27 decrement counter, skip when zero
111055 JMP *-4 loop
Exit test at PC 111056: SKP IF DD EQL 0 with D=000000 → the running XOR is zero → the
checksum PASSES. (The block carries its own trailing checksum word so the 512 words XOR to 0.)
4b. Parse of the area descriptors into the device datafield¶
Loop at PC 111072–111140. For each descriptor it computes an entry pointer
(MPY *110, LDX 16,B, RADD SA DX), reads the flag word and two double-words from the buffer
(LDATX 0, LDDTX 2, LDDTX 4), and stores them into per-unit datafield slots
(STA 23,B,X, STD 35,B,X, STD 61,B,X). Observed values threaded through the registers match
the decoded table (flag 0x8000 then size 122072; flag 0xC000 then size 129311; …).
The loop exits at 111140 (STDTX 1) and calls (111151 JPL I *35) a validation/dispatch
routine at 110132+ (line 292018) that does further field extraction and equality tests
(REXO SL DT, SKP IF DT EQL 0, BSKP …).
4c. It is a data STRUCTURE, not CODE — [VERIFIED]¶
Across all instructions executed after the read (lines 288122–300600), no PC ever falls in the
buffer's virtual range 0177000–0177777, and no JMP/JPL targets that range. The block
is read and parsed as data; it is never jumped into or executed. (Contrast: only the boot block is
executed in ND systems — this is the ordinary data path.)
4d. The parsed values, and what is written to the device datafield — [VERIFIED]¶
The block is a SINTRAN disk area / spare-block map: descriptors of the form
{flag (1 word), rangeStart (doubleword), rangeEnd (doubleword)}. Decoded live from the parse
loop stores (device datafield base B = 031707):
| # | flag | rangeStart | rangeEnd | meaning |
|---|---|---|---|---|
| 0 | 0x8000 |
0 | 122072 | main USABLE area [0 … 122072) = 61036 pages (= PACK-ONE's size) |
| 1 | 0xC000 |
129311 | 129312 | reserved block |
| 2 | 0xC000 |
129310 | 129311 | reserved block |
| 3 | 0xE000 |
129309 | 129310 | reserved block |
| 4 | 0xE000 |
129289 | 129309 | reserved region (20 blocks) |
| 5 | 0xE000 |
129269 | 129289 | reserved region (20 blocks) |
| 6 | 0 |
0 | 0 | empty slot |
| 7 | 0xE000 |
129098 | 129269 | reserved region (171 blocks) |
| 8–11 | 0 |
0 | 0 | empty |
So the last block records one usable area [0, 122072) plus a set of reserved/spare regions
at the top of the disk (129098 … 129312). This is SINTRAN's own in-filesystem area/spare map —
not the SCSI drive's internal defect list (which is obtained via READ DEFECT DATA, never from
the data area).
Writes to the device datafield (B = 031707), per descriptor index X:
| datafield field | absolute address (octal) | store instruction | contents |
|---|---|---|---|
| flag array | 031732 + X |
STA 23,B,X |
0x8000, 0xC000, 0xC000, 0xE000, … |
| rangeStart array (doubleword) | 031744 + X |
STD 35,B,X |
0, 129311, 129310, 129309, … |
| rangeEnd array (doubleword) | 031770 + X |
STD 61,B,X |
122072, 129312, 129311, 129310, … |
i.e. the disc-open copies the area map out of the block buffer into the device datafield at
031732 (flags), 031744 (starts), 031770 (ends), then finalizes (STDTX 1) and returns. The
derived usable size (122072 blocks = 61036 pages) is correct and matches the directory.
4e. Data-integrity validation: disk = memory, nothing corrupts it — [VERIFIED by byte comparison]¶
Verified the whole transfer path against the on-disk image D:\ND\HDD\SCSI-K.image
(132,415,488 bytes = 129,312 blocks; last LBA = 129311):
- The bytes at LBA 129311 on disk are byte-identical to the bytes the trace shows DMA'd into ND
memory (
08 00 54 D9 80 00 00 00 …). - The XOR of all 512 words of the on-disk block = 0 — the identical value SINTRAN's checksum
loop produced in memory (
D=0, PC 111056). This confirms SINTRAN's own checksum test passes; it does not independently detect corruption. See the note below.
CORRECTED 2026-08-02 — the XOR argument here proved less than it claimed. This bullet read: "A single dropped/shifted/byte-swapped/truncated word would make this nonzero and SINTRAN would reject the block." XOR-to-zero is invariant under exactly the corruptions listed:
- Byte-swapped words: the XOR of the swapped set is the byte-swap of the XOR, and
swap(0) = 0. A wholly byte-swapped block still XORs to zero. (This is the same fallacy that let a byte-swapped allocation bitmap stand as VERIFIED inpage-bitmap.mdfor months — see that file's section 2.)- Shifted or reordered words: XOR is commutative, so any permutation of the 512 words gives the same result. A rotated buffer is completely invisible.
- A dropped word: detected only if that word was nonzero — and 483 of the 512 words here are zero, so a dropped word is about 94% likely to pass.
Only truncation at a nonzero-word boundary is genuinely caught.
The conclusion still stands, because the first bullet carries it: the on-disk bytes at LBA 129311 are byte-identical to what the trace shows arriving in ND memory. That comparison is against an artefact this analysis did not produce and would have failed if the transfer were wrong. It is the evidence; the XOR is not. - The block is a valid sparse structure (29 of 512 words nonzero, valid trailing checksum).
Conclusion: the block SINTRAN reads is genuine, valid, and correctly delivered SINTRAN filesystem data. The mount failure is therefore not data corruption, not a checksum failure, and not a DMA/transfer fault — it is a logical decision in the FS-object code acting on correct data.
5. Outcome — the mount ends by silent completion, not by a value-comparison abort — [VERIFIED]¶
There is no single "reject" branch. The disc-open reaches "done" and the directory read simply never becomes a request:
- Checksum gate (the one hard requirement) — PASSES. PC
111056SKP IF DD EQL 0,D=0(line 291672). The 512-word XOR includes word 0 (004000) and the magic word 1 (052331=0x54D9) — the magic is folded into the checksum but never compared against a constant. - No further validation. Searching the whole post-read window, the magic
0x54D9, the sizes (122072/129311), and the flags (0x8000/0xC000) are never tested against a constant or against the SCSI-reported capacity. The parsed geometry is accepted as-is. - Disc-open returns, queue empty. PC
111153–111201: phase field[B+5]steps3→1, the request-queue head[B+1]loadsX=0(empty),JXZ→return; the process reachesWAIT 0(PC 027540, line 292084) and idles. The resident disc-open code110xxx/111xxxnever runs again. - The FS requester is woken but enqueues nothing. Completion wakes the higher file-system
process (datafield
B=066642) around lines 298425–299482 (IRW 130 …, then resumes at PC033701/032510). It traverses FS objects (LDATX/LDXTX) and returns without issuing the directory-master (block-0) read. - Result: the last SCSI CDB in the entire trace is the READ_6 at line 283792; block 0 is never
read; control returns to command level and prints
@(line 326768). The directory does not enter.
[INFERRED — the remaining gap] The branch that decides not to enqueue the directory read
lives in the FS-object / enter-directory layer (segments 032xxx/033xxx, process B=066642,
entry PC 033701/032510). That code is not in the current K carve, so the exact test —
almost certainly the derived directory-master address vs the parsed area geometry — is not yet
proven. See §7.
5b. The whole command is a disc IDENTIFY, not a directory read — [VERIFIED]¶
The entire SCSI conversation for @ENTER-DIRECTORY,,DISC-SCSI-1,0 is three CDBs, then silence:
| CDB | line | purpose |
|---|---|---|
INQUIRY (0x12) |
279508 | device identify |
READ CAPACITY (0x25) |
281496 | size → lastLBA 129311 |
READ_6 lba=129311 (0x08) |
283792 | read the last block (area map) |
No READ_6 lba=0 (directory master) is ever issued — 283792 is the last CDB in the trace. So
the directory read is not attempted, not merely failed.
The proximate branch (resident driver, B=031707):
111154 LDA 5,B ; phase = 3
111155 AAA -2 ; -> 1
111156 STA 5,B ; phase 3 -> 1 (idle)
111157 LDX 1,B ; X <- [031707+1] = request-queue head
111160 JXZ 21 ; queue head == 0 -> branch to 111201 (start no I/O)
...
111201 JMP I *7 ; return -> 027540 WAIT 0
[VERIFIED] At line 292083 111160 JXZ executes with X=000000 → branch taken → WAIT.
The disc datafield request-queue head [031707+1] is 0 (empty): no block-0 request was ever
placed in the queue, so the driver starts nothing and idles. The woken FS process (B=066642,
resumes line 299482, PC 033701) runs doubly-linked-list unlink cleanup (carved routines
032510/032461 in 016-S3SRPIT) that returns the identify read's buffer to a free pool — it
contains no code that computes or enqueues a block-0 directory read.
[INFERRED — the real locus] The choice "do identify only, never the directory" was made in the enter-directory / disc-connect sequencer that ran before the identify read (the command-parse → first-disc-request window, before line 283792). That sequencer is the next thing to trace; the post-completion code (both resident driver and carved FS handler) behaves correctly given an empty queue.
5c. How to mount — what a mountable SCSI disk must present [VERIFIED where noted]¶
- [VERIFIED] The last physical block (LBA = the drive's READ-CAPACITY lastLBA) must be a genuine SINTRAN area/layout table whose 512-word XOR checksum is 0 (PC 111056). The current disk already satisfies this (§4d, §4e) — geometry is valid, so the block content is not the blocker.
- [VERIFIED] For the directory to be read, a
READ_6 lba=0request must be enqueued in the disc datafield ([031707+1]non-zero, phase driven active) at/after identify completion — in this run it never is. - [INFERRED] The trigger that should build that request lives in the enter-directory sequencer before line 283792. Whether it is suppressed by an INQUIRY/device-type check, a command-parameter decision, or a missing "directory phase" is the open question (§7). Since the geometry is valid, the fix is almost certainly not a disk-byte change but a condition in that sequencer / the way the emulator presents the unit to it.
5d. DEFINITIVE: the directory-mount worker is never dispatched — [VERIFIED]¶
Direct trace checks (not inference):
ENDIR(140176B) executes 0 times. The mount worker chain (ENDIR → ForceReserve → CHDSI → RXDIR → RCBLO) and the high-level SCSI builders (SCSID/SCSI1/SCSI2/SCDTS) run zero times. NoREAD_6 lba=0is ever issued.- The 3-CDB identify/connect fully succeeds: all CDBs
SS_GOOD, device datafield031707[+5]=1(valid), geometry stored — no error/status word is set. INQUIRY returned00 00 05 01 34 00 00 00(device-type 0x00 = direct-access disk), not a rejection trigger. - After the successful connect, the FS object is torn down (list-unlink
032510/032461) and control returns; the directory read is never built.
Conclusion (VERIFIED behavior; INFERRED cause): SINTRAN abandons the mount at the resident
enter-directory command dispatch (uncarved 140xxx) — it takes a skip arm and never calls
ENDIR. Because the connect fully succeeds, no emulator-side disk value can fix this
(INQUIRY, READ CAPACITY size, completion interrupt, and block content are all already correct —
this also retires the older "lost RSTAU interrupt" and "wrong device size" theories in
SCSI-MOUNT-FIX-PLAN.md). The lever is SINTRAN-side: a device-kind / configuration gate
that does not treat DISC-SCSI-1 as a mountable directory device. The exact guard PC is in
uncarved resident code and, being the never-taken arm, leaves no trace — so the specific gate
is not yet proven.
To prove the guard: capture an ENTER-DIRECTORY trace of a disk that does mount (e.g. the
Winchester DISC-75MB-1/PACK-UNO) and diff the resident dispatch — the working one takes the arm
that calls ENDIR; the divergence word is the device-kind/config gate DISC-SCSI-1 fails. (Or
carve the resident 140xxx dispatch.)
6. The accounting message — [VERIFIED: tied to command completion, not the mount skip]¶
- Reconstructed from the per-character
CONOUTlogs, the console prints exactlyCR LF "APPROACHING END OF ACCOUNTING FILE" CR LF "@"(first char at line 300511) via the shared terminal-output primitive at PC057505 LBYT→057512 CONOUT, terminal DCBB=122200, at PIL 10. - [INFERRED] It is driven from a pre-queued string by background accounting activity at level 3
(PID
0E) around lines 297405–300039 — the accounting subsystem warning that its log file is near full — with no data dependency found from the LBA-129311 block bytes. Treat it as a coincident warning, temporally adjacent to (not caused by) the failed mount.
7. Open questions / next steps¶
- The abort branch (highest priority). Isolate, in the live trace from line ~292008 onward
(routine
110132+), the exact compare+branch that decides not to read the directory, the field it tests, and the value/condition that would make SINTRAN proceed — that condition is the direct "how to mount" answer. This code is largely resident (110xxx/111xxx) and not present in the current K carve, so it must be read from the live trace + registers. (In progress.) - What creates this structure (task #29). The area/layout table at the last block is
SINTRAN-written. Find the routine in the carved filesystem code (
006-S3FS+ the create- directory logic underSINTRAN/Filesystem/) that builds and writes it on create-directory/format for SCSI drives: its exact field layout, the checksum algorithm, and the trigger. That gives the authoritative structure needed to reproduce a mountable SCSI image (retrofs) and to know precisely what a mountable disk must present. - Magic/flags. Confirm whether
w1 = 0x54D9and the descriptor flags0x8000/0xC000are tested against expected constants during dispatch.
8. Evidence index (trace line numbers)¶
| line | event |
|---|---|
| 281496 | READ CAPACITY reply lastLBA=129311, DMA'd to memory 0x8C4E |
| 114504–114530 (PCs) | driver loads lastLBA from response buffer, packs READ_6 CDB |
| 283792 | READ_6 lba=129311 CDB emitted |
| 288122 | 1024 data bytes DMA complete at physical 0x03FE00 |
| 289167–291672 | XOR-checksum loop (512 words), PC 111051–111055 |
| 291672 | checksum test PC 111056, D=0 → PASS |
| 291673–292008 | area-descriptor parse loop, PC 111072–111140 |
| 292018+ | dispatch/validation routine at PC 110132+ |
| 300511 | first char of "APPROACHING END OF ACCOUNTING FILE" |
| 326768 | @ prompt (command returned; directory not entered) |
Related:
SINTRAN/Devices/SCSI/SCSI-MOUNT-FIX-PLAN.md,
SINTRAN/Devices/SCSI/scsi-disk-format.md,
SINTRAN/Filesystem/ (create-directory + on-disk format).