MON 251B (octal) — CopyPage (COPAG)¶
Copies file pages sequentially between two opened files (one may be a magnetic tape or floppy disk with volume). A special call used by the BACKUP-SYSTEM — no high-level-language interface; the X/D register use is tailored for reading magnetic-tape labels. Copying stops at end-of-file, a non-existent page, or a short magnetic-tape record. Both files must be local files.
Status: dispatch head byte-proven as a fall-through (GOTAB[251B] = 000000); worker body is
real SINTRAN L bytes; the exact MON 251 → worker link crosses an uncarved kernel bridge
(CALLPROC/MFELL) — see Honest caveats. All addresses/values are octal.
- Full disassembly:
251B-CopyPage.ASM— the actualCOPAGworker body (MON 251B has no GOTAB entry stub, see below). - Bytes live once in the canonical segment layer:
../../segments-ref/.
Dispatch path¶
flowchart LR
A["User program<br/>MON 251B"] --> B["ENT14 level-14<br/>T = MON number"]
B --> C["GOTAB[251B] = 000000<br/>(fall-through, byte proven)"]
C -.uncarved CALLPROC/MFELL.-> E["COPAG copy worker<br/>006-S3FS :110050B"]
E --> F["per-page copy<br/>via JPL I workers"]
class A blue
class B,C teal
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
GOTAB[251B] is literally 000000, so there is no entry stub to disassemble; the dashed hop
(C ⇢ E) is the resident CALLPROC/MFELL second-level dispatch, which is not present in any
carved segment and cannot be followed statically.
Code location (dispatch path)¶
Every row is a real region you can open. Byte offset = (addr − loadbase) in octal words × 2.
| Role | Segment (full disasm) | Addr range (octal) | Byte offset | Symbol | Verdict |
|---|---|---|---|---|---|
| GOTAB[251] dispatch word | commoncode.asm · .hex | 071504B (1 word) |
59016 | GOTAB+251 = 000000 |
VERIFIED (fall-through) |
| resident CALLPROC/MFELL bridge | — (uncarved) | — | — | CALLPROC |
UNVERIFIED |
| COPAG copy worker body | 006-S3FS.asm · .hex | 110050B–110471B |
51280 | COPAG |
real bytes; link UNVERIFIED |
Verify by hand: grep '^110050 ' ../../segments-ref/006-S3FS/006-S3FS.hex → byte offset 51280;
then dd if=../../../segments/006-S3FS.bin bs=1 skip=51280 count=4 | od -An -tx1 → 22 5e cc 65
(the stored words 021136 146145 = STD I 136 / RADD CLD SL DA, the COPAG prologue).
Confirm the fall-through: dd if=../../../resident/SINTRAN-DATA_commoncode.bin bs=1 skip=59016 count=2 | od -An -tx1
→ 00 00; prove-mon.py 251 reads GOTAB[251] … 000000.
Instruction walkthrough¶
Full listing: 251B-CopyPage.ASM. There is no entry stub (fall-through
dispatch); the body is the COPAG worker.
Prologue (110050–110054) saves D (110050 STD I 136 — D = the buffer address per the MAC
example) and calls resident register-save SPUSH via pointer @110207 = 003752B.
Open source + dest (110055–110074) resolves the two open-file descriptors: 110057 JPL I 131
(@110210) opens/validates one, 110060 JMP I 131 (@110211) is the destination-error return; the
sequence repeats at 110065–110070 for the second file (source-error return 110070 JMP I 122).
First-page fetch (110075–110102) loads the caller 32-bit first-page address (X points at a
double word), shared by both files. Main copy loop (110103–110325) branches on whether each
side is a real file (110110/110134/110162 JAF), transfers one page (110155 JPL I 36 →
@110215), detects missing pages / holes (110126 JAP, 110145 JAF) and stores the missing-page
skip-return values (110133/110161/110204 STD ,B nn), then bumps the page (110321 MIN ,B 17) and
copied counters (110323 MIN ,B 16). Pointer/data tables (110206–110216, 110357–110374,
110463–110471) hold the JPL I/JMP I targets (SPUSH 003752, SPOP 003776 among them).
Parameter / register contract¶
Manual-side names/types are from 251B_CopyPage.yaml
(MAC: LDT FL1NO / LDA (BUFF / COPY SA DD / LDA FL2NO / LDX (PAGE / MON 251).
| Reg / field | Dir | Meaning | Verdict |
|---|---|---|---|
T = SourceFile |
in | source file number (or logical device for tape/floppy) | inferred (manual) |
A = DestFile |
in | destination file number (or logical device) | inferred (manual) |
X = FirstPage |
in | address of a 32-bit word with the first page address | inferred (manual) |
D = DestBuffer |
in | address of a buffer for a short magtape record (−1 = none), saved at 110050 |
VERIFIED saved; meaning inferred |
A&D = FirstPageMiss |
out | missing-page number (double-skip return) | inferred (manual) |
T&X = LastPageMiss |
out | last page number in a hole (double-skip return, directory source) | inferred (manual) |
| error return | out | destination error / source error (EOF = 3) | inferred (manual) |
This post-CALLPROC body works through ,B frame fields, so the precise T/A/X/D mapping is
inferred from the manual and the caller-side MON 251 wrapper, not byte-proven here.
Pseudo-code (for an emulator)¶
See 251B-CopyPage.pseudo.c — a pseudo-C model of the handler for
emulator authors. Control flow and the copy-loop shape are byte-verified; the per-page worker and
tape/hole semantics are inferred from the call structure and the manual. Every instruction is
translated per the canonical
ND-100 Instruction Semantics reference.
Honest caveats¶
What is byte-proven: GOTAB[251B] = 000000 (a fall-through, matching prove-mon.py 251); the
COPAG worker at 110050B is real code (its SPUSH/SPOP prologue/epilogue, its two-file open
sequence, its page-copy loop with missing-page skip returns).
What is NOT proven: the link from the MON number to the COPAG worker. Because GOTAB[251] =
000000 there is no static edge from the level-14 dispatch word into 110050B; the only path
runs through the resident CALLPROC/MFELL second-level dispatch, in an uncarved overlay. So
the MON 251 → COPAG attribution rests on the symbol name (COPAG = COpy PAGe) + the matching
copy behaviour, not a followed pointer — UNVERIFIED in the strict sense. This reconciles into
one story: the body is genuine SINTRAN L bytes (its direct branches all close inside the carve, up to
its pointer tables), but the attachment to MON 251 is runtime-populated. Confirming it needs a live
trace: break at the level-14 MON entry with the number = 251, single-step the resident
fall-through, and confirm P lands on COPAG = 110050B.
Method: ../../../../../EXTRACTING-RESIDENT-CODE.md §9 · dispatch reality: ../../TASK-05-mismatches.md §G · master map: ../../MON-CALL-INDEX.md.