Skip to content

336B Terminal

In progress   MON 336B (222 decimal) · Mnemonic IOMTY · Group: Not grouped in manual

Available from: Background programs (manual compatibility box)

Emulation source: src/handlers/mon_336B_Terminal.c

Description

This I/O multifunction monitor call is used to change the attributes of terminal and terminal access device (TAD) input/output. It is also used to configure NET/One interfaces and SCSI disks.

This monitor call needs a varying number of input and output parameters depending upon function. All parameters are therefore placed in an array.

Notes

  • Version history: the J-version functions/parameters of MON 336 (IOMTY) were completely revised in the K-version - the call now also configures NET/One interfaces and SCSI disks (SCSI connect/report/remove use functions 300B-302B), and all parameters are passed in an array (ND-60230-5-EN SINTRAN III - Release Information - K-version.md:2261-2265, 13194). M-version added function 26B: get protocol ID and MTAD ID from the MTAD data field (ND-860230-7A-EN SINTRAN III - Release Information - M-Version.md:1190-1199). N-version added function 27B: get IP address and TAD information (ND-860230-8-EN SINTRAN III - Release Information - N-version.md:964-988).

Parameters

Name Type Direction Description
FunctionCode INTEGER2 In Function code (more details on page 496).
ArrayLength INTEGER2 In Length of function parameter array (must be greater than or equal number of input/output parameters specified for function).
ParameterArray INTEGER2[] In/Out Function parameter array. (More details are given on page 496.)

Direction: In = the program supplies the value, Out = the call returns it, In/Out = both.

See also

SetBreak, SetEcho

Compatibility

Machines Users Programs
ND-100 and ND-500 All users Background programs

The manual's compatibility box for this call, word for word.

Yes/no fields from the YAML extraction (not in the manual's words):

ND-100 ND-500 User programs RT programs System programs
No No Yes Yes No

Disagreement

The manual box says ND-100 and ND-500, but the yes/no fields say ND-100 = No, ND-500 = No. The manual box is the source.

Examples

From the manual (OCR text, not corrected).

| Instruction | Operand | Comment |
|-------------|---------|---------|
| LDT         | NTERM   | %Load register T with new terminal. |
| SAA         | 0       |  |
| COPY        | SA DL   | %Copy function code 0 to the L register |
| LDA         | 0       | %No translation to uppercase letters. |
| MON         | 336     | %TerminalFunction with function code 0. |
| STA         | ERROR   | %Returns here if errors. |

- **NTERM, ...**
  %Logical device number of a terminal.

- **ERROR, ...**

ndmonlib implementation

In progress Registered MON_STATUS_IN_PROGRESS: partly implemented. The dispatcher calls the handler.

Handler mon_336B_Terminal
Code lines 63 (non-blank, non-comment lines in the file)

Notes from the handler source

src/handlers/mon_336B_Terminal.c line 67

Function codes, written as the raw values the caller passes.
The manual numbers them in OCTAL, so 012B == 10 decimal.

src/handlers/mon_336B_Terminal.c line 85

Function 12B - Set/reset 8-bit unmodified input/output.
"Unmodified means no parity on the most significant bit in byte."

  Word 1 = logical device number
  Word 2 = 8-bit status: 0 = set 8-bit unmodified I/O
                         1 = reset to 7-bit I/O, parity on most significant bit

Minimum function parameter array size is 2 (manual page 506 rules table).

The ND linker issues exactly this at startup: Func=12B, Size=2,
ParamArray=[1, 0] - i.e. "set 8-bit unmodified on the console terminal".

src/handlers/mon_336B_Terminal.c line 108

0 means SET 8-bit unmodified; 1 means reset to 7-bit with parity. Note the
sense is inverted relative to the boolean we keep.

src/handlers/mon_336B_Terminal.c line 148

Every other function is a real terminal/NIU/SCSI attribute operation we
do not model. Return a real SINTRAN error rather than pretending to
succeed - a silent success here would let a caller act on an unchanged
parameter array, which is exactly the failure mode that made 144B MAGTP
so expensive to find.

src/handlers/mon_336B_Terminal.c line 159

Status2 is the 4th ND-500 argument and is an OUT parameter carrying the
standard error code. The caller separately takes its own status from W1
("W1 =: Status1" in the manual's example, which the linker does verbatim at
0xB004C2C7). Only write it when the caller actually passed it.

src/handlers/mon_336B_Terminal.c line 166

W1 = Status1 (ND-860228 line 22542: "W1 =: Status1" on the OK return).
mon_set_success only clears K; without an explicit W1 the linker reads a
stale value (the CALLG target address) as Status1 - the 144B MAGTP / 412B
FSCNT stale-value defect class. Set W1=0 on success so Status1 reads OK.

Emulation research

Source

This section comes from the emulation: block of the call's YAML file in the NDInsight repo. It records what was learned while implementing the call in nd500x; its status is nd500x's, not ndmonlib's.

Status (nd500x) not_implemented
nd500x handler nd500x/src/libmon/handlers/mon_336B_Terminal.c
Last updated 2026-07-17

Note

NOT IMPLEMENTED, and CURRENTLY THE ND LINKER''S BLOCKER. The handler is the auto-generated stub: it logs its three arguments and returns mon_set_error(ctx, -1) - and -1 is not a SINTRAN error code either. It is registered MON_STATUS_NOT_IMPLEMENTED. NOTE FOR WHOEVER IMPLEMENTS IT: the nd500x dispatcher SHORT-CIRCUITS MON_STATUS_NOT_IMPLEMENTED and never calls the handler, so the registry status must be changed at the same time or the new code will never run (commit 5b6bdfd).

Function codes

  • Radix: unknown
  • Note: NOT ESTABLISHED. The manual defers to "more details on page 496" for both FunctionCode and ParameterArray, and that page is not in the scanned set we have. The only observed value is 10 (see observed_calls) whose radix is unknown - if it is octal it is 8 decimal. Do NOT copy 144B MAGTP''s table; that is a different call. Getting the radix wrong is a real bug (see the 144B_DeviceFunction.yaml precedent, where the giveaway was that the table skipped 8 and 9).
  • Codes

Parameter notes

1. ParameterArray

Field Value
Note IO PARAMETER - the manual types it in/out, and the whole design of this call is "a varying number of input and output parameters depending upon function, therefore placed in an array". THE OUT-PARAMETER DEFECT CLASS APPLIES DIRECTLY: a handler that returns SUCCESS without writing the output slots of this array will cause a failure that surfaces tens of thousands of instructions later somewhere unrelated. Confirmed instances of that exact shape: 412B FSCNT (commit 73ac594) and 144B MAGTP function 0 (commit 6ad9c09 - the linker''s DDB tables stayed blank, it walked blank memory as records, computed a bogus 0x40404040 pointer, took a protect violation, and the symptom appeared ~83000 instructions later as a stack overflow). Whatever is implemented here, the array write must be part of the contract.
Verified No

2. FunctionCode / ArrayLength / ParameterArray

Field Value
Note On ND-500 all INTEGER MON parameters are 32-bit words (W BLOCK), not the 16-bit halfwords the manual''s INTEGER2 implies for the ND-100.
Verified Yes

3. ArrayLength

Field Value
Note Manual: must be greater than or equal to the number of input/output parameters specified for the function.
Verified Yes

Observed calls

1. ND linker (linker-b01.dom) @PC=0xB004C2C7

Field Value
Params Arg0: 10
Arg1: 2
Arg2: 1
Arg3: 0
Expectation THIS IS THE CALL THE NEXT IMPLEMENTER NEEDS. The linker issues it immediately after it loads its DDB tables (i.e. right after the 144B MAGTP function-0 Read-Record that commit 6ad9c09 made work). Recorded as "MON 336B (IOMTY) with 4 args = (10, 2, 1, 0)". Because 336B is unimplemented, the linker gets an error and cannot proceed - this is the current end of the ND linker path.
Note FOUR arguments were observed, but the manual documents THREE parameters (FunctionCode, ArrayLength, ParameterArray) and the nd500x registry declares 3. Which of the four observed values maps to which parameter is NOT established - do not assume arg0=FunctionCode=10 without checking the linker''s wrapper, the way the 511B DVIO mapping was established from the caller''s code rather than from arithmetic (commit 2d9b00f).

Return contract

  • Success: Not implemented - never returned.
  • Errors

    1. -1

    Field Value
    Octal None
    Meaning NOT a SINTRAN code. The auto-generated stub''s placeholder. Commit 6b57202 notes 192 such mon_set_error(ctx, -1) calls remain in NOT_IMPLEMENTED stubs and "-1 is not a SINTRAN code either".

Verified

1. The IOMTY worker is REAL SINTRAN L bytes: 14 words at 51745B-51762B in the resident SINTRAN-DATA_commoncode image (byte offset 42954), bounded strictly by the next symbol MBFDI=51763B.

Field Value
Evidence Carve L-VSX-500 336B-Terminal/README.md and 336B-Terminal.ASM. All 14 words are code: seven JPL I resident-worker calls interleaved with seven LDD ,B parameter-descriptor loads - the dispatch entry into the resident I/O multifunction machinery.

2. GOTAB[336B] = 000000 - there is no per-call entry stub.

Field Value
Evidence Carve: commoncode 071571B (1 word, byte offset 59122), GOTAB+336 = 000000, VERIFIED.

3. The linker reaches 336B only after 144B MAGTP function 0 works.

Field Value
Evidence Commit 6ad9c09: "The linker now advances to MON 336B IOMTY, an unimplemented terminal-attribute call."

Unverified

  • THE MON 336B -> IOMTY LINK IS NOT PROVEN. The GOTAB slot is zero and the hop crosses the resident MFELL / CALLPROC bridge, which is NOT PRESENT IN ANY CARVED SEGMENT - the carve marks it "MISATTRIBUTED": the bytes are certainly code, but that they are THIS call''s worker is attribution by symbol name only. Unlike most calls in this group, NO MCTAB slot value has been read for 336B.
  • No function-code table, no parameter-array layout, no error codes. The manual defers to page 496, which we do not have.
  • Which of the four observed argument values is the FunctionCode, and its radix.
  • GUIDANCE ALREADY ON RECORD (docs/MON_CSHARP_SYNC_HANDOFF.md PART D): "336B IOMTY / 144B MAGTP / 244B GDIEN / 53B RSEGM: blocked or low-prio (uncarved dispatch or need a backing store). Implement the safe skeleton + benign no-op for unknown sub-functions; DO NOT FABRICATE DEVICE/ERROR SEMANTICS." Note the tension with the OUT-parameter rule above: a benign no-op that does not write the array is exactly the 144B function-0 bug. Prefer erroring loudly over silently succeeding without writing.

Sources

Doc Note
NDInsight/tools/sintran-segment-carver/versions/L-VSX-500/re/mon-analysis/336B-Terminal/README.md IOMTY worker body 51745B-51762B in commoncode (real code); GOTAB[336B]=0; the dispatch link is MISATTRIBUTED.
nd500x/docs/MON_CSHARP_SYNC_HANDOFF.md PART D - the stub list the linker needs; 336B is called out as blocked/low-prio.
NDInsight/Developer/MON/calls/144B_DeviceFunction.yaml The call the linker makes immediately BEFORE this one; its emulation block explains the DDB-table load.

Updates 2026 07 17

1. Function 12B implemented; Status2 is a 4th OUT arg the YAML omits

Field Value
Status verified
Detail Function codes are OCTAL (ND-860228.2 EN pp504-506). nd500x implements function 12B "set/reset 8-bit unmodified input/output" (word1 = device, word2 = 0 set / 1 reset): this fixed the linker's garbled high-bit console output. The ND-500 CALLG form is FOUR args - Func, Size, ParamArray, Status2 - and Status2 (standard error code, OUT) is NOT in the extracted parameter list; writing it is required (412B/144B OUT-parameter class).
Nd500x commit 558ecc6

Source

SINTRAN III Monitor Calls (ND-860228.2 EN), page 503.