MON 62B (octal) - GetBytesInFile (RMAX)¶
Gets the number of data bytes in an open file, returned as a 32-bit (INTEGER4 / double-word) value. Only the bytes containing data are counted, and the count is only meaningful for sequentially accessed files.
Status: GOTAB dispatch head byte-proven as fall-through
(GOTAB[62B] = 000000, no per-call stub); the RMAX worker body is real SINTRAN L
bytes and its call to the deeper worker RMAXB (72016B) is byte-proven via a
resolved link cell; the exact MON 62 -> worker link crosses an uncarved kernel
bridge (see Honest caveats). All addresses/values are
octal.
- Full disassembly:
62B-GetBytesInFile.ASM- the actual code (the RMAX worker body; there is no entry stub because the GOTAB slot is zero). - Bytes live once in the canonical segment layer:
../../segments-ref/.
Dispatch path¶
flowchart LR
A["User program<br/>MON 62B"] --> B["ENT14 level-14<br/>T = MON number"]
B --> C["GOTAB[62B] = 000000<br/>(byte-proven: fall-through)"]
C -.uncarved MFELL / CALLPROC.-> E["RMAX byte-count worker<br/>006-S3FS :103767B"]
E --> F["RMAXB deeper worker<br/>006-S3FS :72016B"]
class A blue
class B,C blue
class E,F green
classDef blue fill:#E3F2FD,stroke:#0D47A1,color:#0D47A1
classDef teal fill:#E0F7FA,stroke:#00838F,color:#00838F
classDef green fill:#E8F5E9,stroke:#2E7D32,color:#2E7D32
The GOTAB slot is zero, so there is no per-call entry stub. The dashed hop
(C -> E) is the resident MFELL/CALLPROC fall-through second-level dispatch -
it is not present in any carved segment, so it is the one link that cannot be
followed statically. The E -> F hop (RMAX -> RMAXB) is byte-proven: link
cell 104033 = 072016B = RMAXB.
Code location (dispatch path)¶
Every row is a real region you can open. Byte offset = (addr - loadbase) in octal words x 2.
| Role | Segment (full disasm) | Addr range (octal) | Byte offset | Symbol | Verdict |
|---|---|---|---|---|---|
| GOTAB[62] dispatch word | commoncode.asm - .hex | 071315B (1 word) |
58778 | GOTAB+62 = 000000 |
VERIFIED (fall-through) |
| resident MFELL/CALLPROC bridge | - (uncarved) | - | - | CALLPROC |
UNVERIFIED |
| RMAX byte-count worker body | 006-S3FS.asm - .hex | 103767B-104004B (14w) |
47086 | RMAX |
real bytes; link MISATTRIBUTED |
| RMAXB deeper worker (called) | 006-S3FS.asm - .hex | 72016B (entry) |
36892 | RMAXB |
VERIFIED (link cell) |
Verify by hand: grep '^103767 ' ../../segments-ref/006-S3FS/006-S3FS.hex -> byte offset 47086;
then dd if=../../../segments/006-S3FS.bin bs=1 skip=47086 count=8 | od -An -tx1 -> 22 1c cc 65 cc 59 f0 06
(= octal 021034 146145 146131 170006 = STD I 34 / RADD CLD SL DA / RADD CLD SB DD / SAB 6, the RMAX entry).
The GOTAB slot itself:
dd if=../../../resident/SINTRAN-DATA_commoncode.bin bs=1 skip=58778 count=2 | od -An -tx1 -> 00 00 (= 000000, fall-through).
Instruction walkthrough¶
Full listing: 62B-GetBytesInFile.ASM. The body is short
and clean (14 words). There is no F16xx stub because GOTAB[62] = 0. The three
indirect calls go through pointer-word link cells (104024, 104030, 104033)
in the shared pointer block just past RMAX; those words are data (worker
addresses), not code.
- Prologue (
103767-103772) -103767 STD I 34stashes the caller'sD(parameter pointer);103772 SAB 6builds the local frameB. - Setup + work (
103773-103775) -103773 JPL I 31->003752runs a resident prologue worker;103774 STT I 31stashesT(the file number);103775 JPL I 36->RMAXB(072016B) is the deeper worker that computes the byte count. - Success / error split (
103776-104004) -RMAXBreturns SKIP on success and NO-SKIP on error. The no-skip (error) path falls to103776 JMP 5->104003 STA ,B 2(store the error codeAinto the caller's slot). The skip (success) path lands at103777 STD ,B 2(store the double-word byte countDinto the caller's slot) and104000 MIN ,B 4(bump the caller's skip-return flag). Both paths converge at104001 SAA -6/104002 JMP I 26->003776, the resident return cell.
The skip-return-on-success shape matches the MAC calling pattern in the manual
(MON 62 / JMP ERROR / STD BYTES - the double word is stored only on the skip
return), and STD ,B 2 writing a double word matches the INTEGER4 result.
Parameter / register contract¶
| Reg / field | Dir | Meaning | Verdict |
|---|---|---|---|
T |
in | file number (from an earlier OpenFile); stashed at 103774 STT I 31 |
VERIFIED (STT); role per manual MAC example |
D (double) |
in | caller parameter pointer, saved first (103767 STD I 34) |
VERIFIED (bytes); role inferred |
RMAXB result |
internal | byte count computed by RMAXB (72016B), returned in D |
inferred |
B+2 |
out | on success = INTEGER4 byte count (STD ,B 2); on error = error code (STA ,B 2) |
VERIFIED (bytes) |
B+4 |
out | caller skip-return / OK flag, bumped on success (MIN ,B 4) |
VERIFIED (bytes) |
| skip return | out | success = SKIP return; error = normal (no-skip) return | VERIFIED (structure) |
T as the file-number input is byte-visible (STT I 31) and matches the manual's
MAC example (LDT FILNO / MON 62); the precise user-visible register frame
otherwise lives in the caller-side MON 62 wrapper and the uncarved
MFELL/CALLPROC bridge, so it is inferred where not byte-shown.
Pseudo-code (for an emulator)¶
See 62B-GetBytesInFile.pseudo.c - a pseudo-C
model of the handler for emulator authors. Control flow + the success/error
skip-return split are byte-verified; what RMAXB computes internally is inferred
from the call structure and the manual.
Every instruction in the pseudo-code is translated against the canonical ND-100 instruction semantics reference (RADD/COPY register ops, addressing-mode effective addresses, and skip/branch senses).
Honest caveats¶
What is byte-proven: GOTAB[62B] = 000000 (a level-14 fall-through with no
per-call vector - matches a live read of the running system); the RMAX worker
body at 103767B in 006-S3FS is real code (entry bytes match the disassembly);
and it calls RMAXB (72016B) - the link cell 104033 = 072016B resolves to the
RMAXB FILSYS symbol, so the RMAX -> RMAXB edge is byte-proven.
What is NOT proven: the link from the zero GOTAB slot to the RMAX worker.
Because the vector is zero there is no stub to disassemble and no pointer to
dereference; dispatch drops into the resident MFELL/CALLPROC second-level
path, which lives in an uncarved overlay. So the MON 62 -> RMAX attribution
rests on the RMAX symbol name + the matching byte-count behaviour, not a
followed pointer - hence MISATTRIBUTED in the strict sense. Confirming the link
needs a live trace: issue a real MON 62, single-step the level-14 fall-through
into the resident CALLPROC dispatch, and confirm P lands on RMAX = 103767.
The link cells 003752 (prologue) and 003776 (resident return) match no
FILSYS-SYMBOLS entry; their low addresses suggest resident-monitor routines
outside the file-system segment and are not resolved here. RMAX shares its tail
pointer block with the neighbouring REABT routine (104005B), which is why the
cells it references sit past its own last instruction.
Method: ../../../../../EXTRACTING-RESIDENT-CODE.md - dispatch reality: ../../TASK-05-mismatches.md - master map: ../../MON-CALL-INDEX.md.