MON 336B (octal) - Terminal (IOMTY)¶
The I/O multifunction monitor call: changes the attributes of terminal and terminal-access-device (TAD) input/output, and configures NET/One interfaces and SCSI disks. It needs a varying number of input/output parameters depending on the function code, so all parameters are passed in an array (a FunctionCode, an ArrayLength and a ParameterArray). Available to all users; background programs.
Status: GOTAB dispatch head byte-proven as fall-through (GOTAB[336B] =
000000, no per-call stub); the IOMTY worker body is real SINTRAN L bytes in the
resident SINTRAN-DATA_commoncode image (a SYMBOL-1-LIST symbol). The worker is
real executable code - an alternating sequence of resident-worker calls (JPL I)
and parameter-descriptor loads (LDD ,B ...), the dispatch entry into the
resident I/O multifunction machinery (it closes at 51762B, bounded by the next
symbol MBFDI=51763B). The exact MON 336 -> worker link crosses an uncarved
kernel bridge (see Honest caveats). All addresses/values are
octal.
- Full disassembly:
336B-Terminal.ASM- the actual code (the IOMTY 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 336B"] --> B["ENT14 level-14<br/>T = MON number"]
B --> C["GOTAB[336B] = 000000<br/>(byte-proven: fall-through)"]
C -.uncarved MFELL / CALLPROC.-> E["IOMTY I/O-multifunction worker<br/>commoncode :51745B"]
E --> F["resident-worker calls +<br/>parameter-array descriptor loads"]
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.
Code location (dispatch path)¶
Every row is a real region you can open. Byte offset = (addr - loadbase) in
octal words x 2; for commoncode (load base 0) the byte offset is the octal
address x 2 (decimal).
| Role | Segment (full disasm) | Addr range (octal) | Byte offset | Symbol | Verdict |
|---|---|---|---|---|---|
| GOTAB[336] dispatch word | commoncode.asm - .hex | 071571B (1 word) |
59122 | GOTAB+336 = 000000 |
VERIFIED (fall-through) |
| resident MFELL/CALLPROC bridge | - (uncarved) | - | - | MFELL/CALLPROC |
UNVERIFIED |
| IOMTY worker body | commoncode.asm - .hex | 51745B-51762B (14 words) |
42954 | IOMTY |
real bytes = CODE; body link MISATTRIBUTED |
The window is bounded strictly to the next symbol MBFDI=51763B (14 words). All
14 words are code (seven JPL I resident-worker calls interleaved with seven
LDD ,B parameter-descriptor loads). The JPL I link cells (052021/052023) lie
past this window in the following region.
Verify by hand: grep '^51745 ' ../../segments-ref/SINTRAN-DATA_commoncode/SINTRAN-DATA_commoncode.hex
-> byte offset 42954; then
dd if=../../../resident/SINTRAN-DATA_commoncode.bin bs=1 skip=42954 count=2 2>/dev/null | od -An -tx1
-> ba 2c (the stored word = octal 135054, a genuine JPL I 54 instruction,
confirming the region is code). The GOTAB slot itself:
grep '^71571 ' ../../segments-ref/SINTRAN-DATA_commoncode/SINTRAN-DATA_commoncode.hex
-> 71571 000000 000 000 59122; then
dd if=../../../resident/SINTRAN-DATA_commoncode.bin bs=1 skip=59122 count=2 2>/dev/null | od -An -tx1
-> 00 00 (= 000000, fall-through). prove-mon.py 336 reads the same GOTAB zero.
Instruction walkthrough¶
Full listing: 336B-Terminal.ASM. The body is the IOMTY
worker (there is no F16xx stub because GOTAB[336] = 0).
Dispatch body (51745-51762) - the worker is a tight, regular sequence: each
odd word calls a resident I/O worker through a link cell
(51745 JPL I 54 -> [052021], 51747 JPL I 52 -> [052021],
51751 JPL I 52 -> [052023], ...), and each even word loads a double-word
parameter descriptor from the caller's B-frame parameter array
(51746 LDD ,B -115, 51750 LDD ,B -125, 51752 LDD ,B -133, ...). Seven
resident-worker calls interleave with seven descriptor loads across the 14 words -
the classic shape of an I/O multifunction dispatcher that walks a parameter array
and hands each descriptor to a resident sub-worker. The concrete sub-function
chosen by the function code lives past the uncarved CALLPROC.
Parameter / register contract¶
Manual-side names/types are from 336B_TERMINAL.yaml.
| Reg / field | Dir | Meaning | Verdict |
|---|---|---|---|
FunctionCode |
in | function code selecting the I/O sub-function (MAC COPY SA DL, function 0) |
inferred (manual) |
ArrayLength |
in | length of the parameter array (>= parameters for the function) | inferred (manual) |
ParameterArray |
in/out | the function parameter array (the LDD ,B descriptors read it) |
inferred (manual); descriptor loads VERIFIED |
T (MAC example) |
in | logical device number of the terminal (LDT NTERM) |
inferred (manual) |
A |
in/out | translation flag on entry; error number on return (MON 336 / STA ERROR) |
inferred (manual) |
The worker's LDD ,B parameter-array reads and JPL I resident-worker calls are
VERIFIED from bytes, but the mapping onto the user-visible
FunctionCode/ArrayLength/ParameterArray contract lives in the caller-side MON 336
wrapper and the uncarved CALLPROC frame, so the contract is inferred, not
byte-proven here.
Pseudo-code (for an emulator)¶
See 336B-Terminal.pseudo.c - a pseudo-C model of
the handler for emulator authors. The control flow (the seven resident-worker
calls interleaved with the seven parameter-descriptor loads) is byte-verified; the
register/field semantics and which I/O sub-function the function code selects are
inferred from the manual and the code shape.
Every instruction in the pseudo-code is translated against the canonical
ND-100 instruction semantics reference
(LDD ,B load-double with A in the low word, JPL I indirect call via a link
cell, addressing-mode effective addresses).
Honest caveats¶
What is byte-proven: GOTAB[336B] = 000000 (level-14 dispatch, a fall-through
with no per-call vector; prove-mon.py 336 reads commoncode file byte
0xe6f2 = 00 00); the IOMTY worker body at 51745B in SINTRAN-DATA_commoncode
is real code (first word 135054B = JPL I 54 matches the disassembly); and it is
an I/O multifunction dispatcher (seven resident-worker calls interleaved with
seven parameter-array descriptor loads), consistent with the Terminal I/O
multifunction call.
Which segment and why: IOMTY=51745B is a SYMBOL-1-LIST symbol, so it lives
in the resident SINTRAN-DATA_commoncode image (the always-resident kernel code),
appropriate for a terminal / TAD / SCSI I/O primitive. The window 51745B-51762B
is bounded strictly by the next symbol MBFDI=51763B (14 words), all code.
What is NOT proven: the link from the zero GOTAB slot to the IOMTY 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 336 -> IOMTY
attribution rests on the IOMTY symbol name (terminal I/O multifunction) + the
matching dispatcher behaviour, not a followed pointer - hence MISATTRIBUTED in
the strict sense. The worker's JPL I indirections target the link cells
052021/052023, which lie past the carved window and are not resolved here; this
window is the named dispatch entry into a larger resident I/O module, not a fully
self-contained subroutine. Confirming the dispatch link needs a live trace: issue
a real MON 336, single-step the level-14 fall-through into the resident
CALLPROC, and confirm P lands on IOMTY = 51745.
Method: ../../../../../EXTRACTING-RESIDENT-CODE.md - dispatch reality: ../../TASK-05-mismatches.md - master map: ../../MON-CALL-INDEX.md.