Skip to content

MON 56B (octal) - SetUserParam (PASET)

Sets the 5 user parameters of a background program (termination-handling information). GetUserParam (MON 57B) reads them back. Background programs only.

Status: GOTAB dispatch head byte-proven as fall-through (GOTAB[56B] = 000000, no per-call stub); the MPASE worker body is real SINTRAN L bytes in the second-level monitor segment 025-S3IRPIT (a SYMBOL-2-LIST symbol). It is a shared set/get body: MPASE=102363B (this call) clears the SSK skip flag for the SET direction, the twin MPAGE=102365B (GetUserParam, MON 57B) sets it for GET; both copy 5 words between the user array and the USPAR system array via MOVUS. The code closes at 102406B (indirect return), bounded by the next symbol RERRP=102413B. The exact MON 56 -> worker link crosses an uncarved kernel bridge (see Honest caveats). All addresses/values are octal.

  • Full disassembly: 56B-SetUserParam.ASM - the actual code (the shared MPASE/MPAGE worker; 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 56B"] --> B["ENT14 level-14<br/>T = MON number"]
    B --> C["GOTAB[56B] = 000000<br/>(byte-proven: fall-through)"]
    C -.uncarved MFELL / CALLPROC.-> E["MPASE set-param worker<br/>025-S3IRPIT :102363B (SSK=0)"]
    E --> F["get array; MST PIE;<br/>MOVUS 5 words user->system"]
    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 025-S3IRPIT (load base 32000B) it is (addr - 32000B) x 2.

Role Segment (full disasm) Addr range (octal) Byte offset Symbol Verdict
GOTAB[56] dispatch word commoncode.asm - .hex 071311B (1 word) 58770 GOTAB+56 = 000000 VERIFIED (fall-through)
resident MFELL/CALLPROC bridge - (uncarved) - - MFELL/CALLPROC UNVERIFIED
MPASE/MPAGE worker body 025-S3IRPIT.asm - .hex 102363B-102406B (code) + 102407B-102412B (link cells) 41446 MPASE (SSK=0) / MPAGE=102365B (SSK=1) real bytes = CODE; body link MISATTRIBUTED

The window is bounded strictly by the next symbol RERRP=102413B (the MON 207B read-error-parameters handler). Words 102363B-102406B are code and 102407B-102412B are a pointer table (link cells) - one of them, 102410B, is the USPAR=145445B constant loaded by the copy setup; they are data.

Verify by hand: grep '^102363 ' ../../segments-ref/025-S3IRPIT/025-S3IRPIT.hex -> byte offset 41446; then dd if=../../../segments/025-S3IRPIT.bin bs=1 skip=41446 count=2 2>/dev/null | od -An -tx1 -> f8 10 (the stored word = octal 174020, a genuine BSET ZRO SSK instruction, the MPASE set entry). The GOTAB slot itself: grep '^71311 ' ../../segments-ref/SINTRAN-DATA_commoncode/SINTRAN-DATA_commoncode.hex -> 71311 000000 000 000 58770; then dd if=../../../resident/SINTRAN-DATA_commoncode.bin bs=1 skip=58770 count=2 2>/dev/null | od -An -tx1 -> 00 00 (= 000000, fall-through). prove-mon.py 56 reads the same GOTAB zero.


Instruction walkthrough

Full listing: 56B-SetUserParam.ASM. The body is the shared MPASE/MPAGE worker (there is no F16xx stub because GOTAB[56] = 0).

Entry split (102363-102366) - 102363 BSET ZRO SSK is the SET entry (MPASE, this call), clearing the skip flag; 102365 BSET ONE SSK is the GET entry (MPAGE, MON 57B), setting it; both fall through to 102366 JPL I 21 -> [102407], the resident prologue that fetches the user-array address.

Monitor entry + direction fork (102367-102401) - 102367 SAA 4 / 102370 MST PIE enter the monitor level; 102371 BSKP ONE SSK forks on the direction. The GET side (102373-102375) puts the USPAR constant in D and the user array in T; the SET side (102377-102401, this call) puts the user array in D and USPAR in T.

5-word copy + return (102402-102406) - 102402 SAX 5 sets the count, 102403 LDA ,B 17 loads the page selector, 102404 JPL I 5 -> [102411] calls MOVUS to copy the 5 words between the user segment and the system segment; 102405 STZ ,B 12 clears the returned status (A = 0) and 102406 JMP I 4 -> [102412] returns indirectly.


Parameter / register contract

Manual-side names/types are from 56B_SetUserParam.yaml.

Reg / field Dir Meaning Verdict
user array (5 words) in the 5 user parameters, 16-bit on ND-100 (PASET(APAR)) inferred (manual)
entry point in 102363B = set (this call); 102365B = get (shared body, SSK split) VERIFIED (bytes)
SSK internal set (0) / get (1) direction selector (BSKP ONE SSK at 102371) VERIFIED (bytes)
B+20 (D0) internal user-array pointer used as one side of the MOVUS copy VERIFIED (bytes); meaning inferred
USPAR=145445B internal system-side parameter array (the other MOVUS side) VERIFIED (bytes)
A out status word cleared to 0 on success (102405 STZ ,B 12) VERIFIED (bytes); meaning inferred

Pseudo-code (for an emulator)

See 56B-SetUserParam.pseudo.c - a pseudo-C model for emulator authors. The control flow (the SSK set/get split, the monitor entry, the direction of the 5-word MOVUS copy and the zeroed return status) is byte-verified; the user-array layout is inferred from the manual and the monitor-call source shape.

Every instruction in the pseudo-code is translated against the canonical ND-100 instruction semantics reference (BSET ZRO/ONE SSK clear/set skip flag, JPL I indirect call, SAA set A, MST PIE mask-set, BSKP ONE SSK skip-if-set, RADD CLD SA DD copy idiom, LDA/LDT ,B frame loads, SAX set X, JMP I indirect return).


Honest caveats

What is byte-proven: GOTAB[56B] = 000000 (level-14 fall-through; prove-mon.py 56 reads commoncode file byte 0xe592 = 00 00); the MPASE worker body at 102363B in 025-S3IRPIT is real code (first word 174020B = BSET ZRO SSK matches the disassembly); and it is a set/get user-parameter routine (monitor entry, SSK-selected copy direction, MOVUS 5-word transfer keyed on the USPAR constant), consistent with SetUserParam and its MPAGE GET twin.

Which segment and why: MPASE=102363B is a SYMBOL-2-LIST symbol, so it lives in the second-level monitor overlay 025-S3IRPIT, with its GET twin MPAGE=102365B two words later. The window 102363B-102412B is bounded strictly by the next symbol RERRP=102413B (a different handler): 102363-102406 are code and 102407-102412 are the JPL I/JMP I link-cell table (one cell is the USPAR=145445B constant).

What is NOT proven: the link from the zero GOTAB slot to the MPASE 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 - hence MISATTRIBUTED in the strict sense: the attribution rests on the MPASE symbol name + matching behaviour + the MPAGE GET twin, not a followed pointer. The JPL I/JMP I link cells (102407..102412) are a pointer table whose runtime targets are not resolved here. Confirming the dispatch link needs a live trace of a real MON 56.

Method: ../../../../../EXTRACTING-RESIDENT-CODE.md - dispatch reality: ../../TASK-05-mismatches.md - master map: ../../MON-CALL-INDEX.md.