511B DeviceInputOutput¶
In progress MON 511B (329 decimal) · Mnemonic DVIO · Group: Not grouped in manual
Available from: not known - no compatibility box captured from the manual
Emulation source: src/handlers/mon_511B_DVIO.c
Description¶
ND-500 device I/O monitor call: outputs a prompt string to a terminal-class device and then reads an input string in a single combined operation. DVIO shares its output body with NOUTSTR (MON 504) and continues into the instring path, i.e. DVIO = combined OutString + InString. Intended for ND subsystems only.
Notes¶
- Internal-use ND-500 level-12 monitor call; not intended for user programs.
- Handler SUBR DVIO,NOUTSTR,OSTRS,PT5RST at MP-P2-N500.NPL:1688; the output body is shared with NOUTSTR (MON 504).
- Dispatched via the ND-500 level-12 GOSW table (L12MIN=500..L12MAX=523), slot index = 511B - 500B = 11 (octal 13); entered with X = current ND-500 message (N5MESSAGE) and B = ND-500 CPU datafield.
- UNVERIFIED - the values below are message-field offsets read by the handler, not a confirmed CALLG caller signature. Output datafield TODF, output byte count DNOBY (max 4000B octal = 2048 bytes); input phase reads 11DMA (max input bytes) and 11MXBRK (max chars before break).
- Write-back: AD =: X.11NOCHRET (number of returned bytes), 100000 =: X.NUMPAR (write-back mask) at MP-P2-N500.NPL:1900-1901.
Parameters¶
| Name | Type | Direction | Description |
|---|---|---|---|
OutputByteCount |
INTEGER | In | UNVERIFIED - message field DNOBY, number of prompt bytes to output (max 4000B octal = 2048 bytes). Message offset, not a confirmed CALLG parameter. |
MaxInputBytes |
INTEGER | In | UNVERIFIED - message field 11DMA, maximum number of input bytes to read. Message offset, not a confirmed CALLG parameter. |
ReturnedBytes |
INTEGER | Out | UNVERIFIED - number of returned input bytes, written back to message field 11NOCHRET. Message offset, not a confirmed CALLG parameter. |
Direction: In = the program supplies the value, Out = the call returns it, In/Out = both.
See also¶
Compatibility¶
| ND-100 | ND-500 | User programs | RT programs | System programs |
|---|---|---|---|---|
| No | Yes | No | No | Yes |
From the YAML extraction; this call's page in the manual had no compatibility box that was captured.
ndmonlib implementation¶
In progress Registered MON_STATUS_IN_PROGRESS: partly implemented. The dispatcher calls the handler.
| Handler | mon_511B_DVIO |
| Code lines | 52 (non-blank, non-comment lines in the file) |
Notes from the handler source¶
src/handlers/mon_511B_DVIO.c line 143
---- Input phase: read the reply (503B DVINST core) ------------------- *
Strategy/table arguments live at indices 4..13 for BOTH calls, so the
core reads them from ctx directly. Only DevNo/MaxNo/retcount/buffer move.
If the device has no input the core requests a wait: the MON is left
UNCOMMITTED, the CPU rewinds to the CALLG and re-dispatches on resume.
The prompt is re-written on that retry, which is correct - SINTRAN's DVIO
re-prompts when the line is not yet available.
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) | verified |
| nd500x handler | nd500x/src/libmon/handlers/mon_511B_DVIO.c |
| Last updated | 2026-07-17 |
Summary¶
THE FUSED PROMPT-THEN-READ CALL: 511B writes a prompt to a device and then reads a line back from it. 511B == 504B DVOUTS followed by 503B DVINST on the same device. nd500x implements it by DELEGATING to the shared DVOUTS and DVINST cores (mon_device_io.h) rather than duplicating them - which mirrors SINTRAN itself, where the output body is shared with NOUTSTR (MON 504) and the input phase is named XNINSTR, literally 503B DVINST's body.
Callg argument map¶
- Radix: decimal
- Note: ESTABLISHED FROM EVIDENCE (2026-07-16), NOT GUESSED - and NOT derivable by arithmetic. The obvious 3 + (14 - 1 shared DeviceNo) = 16 predicts the COUNT but NOT the ORDER: DVINST's MaxNo and returned-count are RELOCATED TO THE END (14, 15) so that indices 1..2 can carry the output phase. A mapping built on that arithmetic would have put MaxNo at arg 1 and CLOBBERED THE OUTPUT BYTE COUNT. This is why it was not guessed.
- Derivation: In linker-b01.dom.asm each of 503B/504B/511B has exactly ONE call site, and each is a bare pass-through thunk (ents; call MON; ifkret; ret). Nothing runs between the ents and the call, so the thunk's b.0x14.. slots ARE its incoming arguments. Each thunk has exactly ONE caller, which calls it with ZERO CALLG args after building the argument block at the top of its own frame (a fixed +0x150 from the thunk's view). Laying the 503B caller (@0xB004754F) and the 511B caller (@0xB00474A1..0xB0047535) side by side yields the mapping.
-
Call sites
- B004AC8A: ents $0x4C / B004AC90: call $0xF8000143,$0xE -> 503B DVINST (14 args)
- B004ACA7: ents $0x20 / B004ACAD: call $0xF8000144,$0x3 -> 504B DVOUTS (3 args)
- B004ACB9: ents $0x54 / B004ACBF: call $0xF8000149,$0x10 -> 511B DVIO (16 args)
- Args
1. 0
Field Value Name DeviceNo Io I Note 1 = own terminal. Output phase; same as 504B arg 0. All three callers take arg0 from the same b.0x58. 2. 1
Field Value Name NoOfBytes Io I Note Bytes to write. Output phase; same as 504B arg 1. 3. 2
Field Value Name OutputBuffer Io I Note Address of the prompt. Output phase; same as 504B arg 2. 4. 3
Field Value Name InputBuffer Io O Note Address of the input buffer. Input phase; same INDEX as 503B arg 3. 5. 4
Field Value Name BreakStrat Io I Note Observed 7. Written by "w move $0x7,b.0x100" at B004745C. 6. 5
Field Value Name EchoStrat Io I Note Observed -1. 7. 6..9
Field Value Name break/echo table words or string field Io I Note SEMANTICS UNPROVEN - see unverified. Passed through to the DVINST core unchanged. 8. 10..13
Field Value Name table words Io I Note Read from the table at 0xB0052F04; observed -1, 0, 0, 3. 9. 14
Field Value Name MaxNo Io I Note Maximum bytes to read. Observed 12. NOTE: this is arg 1 in 503B - the lists are NOT a shared prefix. 10. 15
Field Value Name ReturnedByteCount Io O Note *** OUT PARAMETER - MUST BE WRITTEN. *** Written by NOBODY before the call and read immediately after it (B0047539: w move b.0x1A0,b.0xA8). Exactly the shape of the MON 412B FSCNT bug: if the handler leaves it alone, the caller silently keeps a stale count. This is arg 2 in 503B.
Observed calls¶
1. ND linker (linker-b01.dom), thunk @0xB004ACB9, call @0xB004ACBF, caller @0xB00474A1
| Field | Value |
|---|---|
| Params | Deviceno: 1 Noofbytes: 2 Outputbuffer: 0xB0049430 Maxno: 12 Inputbuffer: 0xB0001C2E |
| Expectation | Write the 2-byte prompt, then read a line. Runtime-verified: "504B DVOUTS wrote 2 bytes; 503B DVINST read 12 bytes; EXIT -> SUCCESS". MaxNo = 12 arrives via arg[14] exactly as mapped and consumes a 12-byte line. |
| Note | Commit 2d9b00f. |
Return contract¶
- Success: K flag cleared; prompt written, line in InputBuffer, count in arg 15.
-
Errors
Code Octal Meaning 111 157B Missing parameter (fewer than 16 CALLG args) 124 174B Illegal parameter (propagated from the DVOUTS/DVINST cores) 24 030B No such device name (propagated from the cores)
Verified¶
1. The argument mapping above is real. Three INDEPENDENT confirmations.
| Field | Value |
|---|---|
| Evidence | (1) 511B args 0..2 are built by an instruction sequence BYTE-IDENTICAL to the 504B DVOUTS caller's (same "w move $0xB0053068,b.0x114" / "by2 laddr @b.0x114+" / "w2 =: b.0x16C"), and all three callers take arg0 from the same b.0x58 - so args 0..2 ARE DVOUTS' (DeviceNo, NoOfBytes, @Buffer). (2) arg4 is written "w move $0x7,b.0x100" at B004745C, and the live probe observed arg[4] == 7. (3) args 10..13 are read from the table at 0xB0052F04, whose bytes in the loaded image are FF FF FF FF | 00 00 00 00 | 00 00 00 00 | 00 00 00 03, and the live probe observed arg[10..13] == -1, 0, 0, 3. |
2. The MON number decode: 0xF8000149 = 0x149 = 329 decimal = 511 octal, with 16 args.
| Field | Value |
|---|---|
| Evidence | Matches the emulator's "Unimplemented MON ? (UNKNOWN) with 16 args" report exactly. Commit 5b6bdfd. The originally reported PC B004ACD7 is merely the FOLLOWING ifkret, which made the call look like garbage - a decode trap worth remembering. |
3. Implemented and working end to end against the real linker.
| Field | Value |
|---|---|
| Evidence | Commit 2d9b00f. Tests: 8 new 511B assertions in test_mon_calls.c covering prompt-then-read, the OUT-parameter write (the 412B guard), buffer separation, and suspend-on-empty leaving the count untouched. |
4. On an empty device the input phase requests a WAIT: the MON is left UNCOMMITTED, the CPU rewinds to the CALLG and re-dispatches on resume. The PROMPT IS RE-WRITTEN on that retry - which is correct: SINTRAN's DVIO re-prompts when the line is not yet available.
| Field | Value |
|---|---|
| Evidence | mon_511B_DVIO.c; shares the 503B/1B STOP_WAIT_INPUT model (commits 26f665d, 7819a36). |
Unverified¶
- THE PRECISE SEMANTICS OF ARGS 6..9. DO NOT STATE THEM AS FACT. The caller fills b.0x104.. via an "h smove" from a [len][ptr] descriptor at 0xB0052854 / 0xB005285C, so they are NOT plainly a 128-bit break table in the linker's usage. nd500x does not need to resolve this: it passes indices 4..13 through to the SAME DVINST core, which is exactly what the linker's own DVINST call site does with the identical values from the identical frame slots.
- The argument map is derived from ONE program's call sites (the ND linker). It is strong evidence for how 511B is called, not a manual-sourced signature.
Discrepancies¶
1. This YAML's parameters list gives THREE fields (OutputByteCount / DNOBY, MaxInputBytes / 11DMA, ReturnedBytes / 11NOCHRET), reverse-engineered from SINTRAN III NPL source MP-P2-N500.NPL as ND-500 MESSAGE-BUFFER OFFSETS - each already self-labelled "UNVERIFIED ... Message offset, not a confirmed CALLG parameter".
| Field | Value |
|---|---|
| Is | Real callers pass SIXTEEN CALLG arguments, mapped above from evidence. The two models are NOT in conflict - they describe DIFFERENT LAYERS. The NPL/carve model is the level-12 driver / ND-500 message-buffer view; the map above is the CALLG argument-list view a MON emulator must implement. Take the ARG SHAPE from the call sites and the SEMANTICS from the carve/NPL. The two views corroborate each other: DNOBY's max 4000B octal = 2048 bytes is the same limit the DVOUTS core enforces, and 11NOCHRET (the write-back at MP-P2-N500.NPL:1900-1901) is the same OUT parameter as CALLG arg 15. |
| Evidence | Call sites in ND-archive/500/nd-linker/linker-b01.dom.asm (B004ACB9/B004ACBF, caller B00474A1); handler header nd500x/src/libmon/handlers/mon_511B_DVIO.c; commits 5b6bdfd and 2d9b00f. |
2. Recorded for a long time: "the linker's command loop polls an in-memory datafield, no MON call, carver-blocked" - i.e. the linker's interactive input was believed unreachable through MON emulation.
| Field | Value |
|---|---|
| Is | WRONG for the command path. The linker's own disassembly shows it uses three terminal calls: 503B DVINST (input), 504B DVOUTS (output) and 511B DVIO (fused). 511B was simply UNIMPLEMENTED, and its "Unimplemented MON ? (UNKNOWN) with 16 args" report was not recognised as 511B. (The separate startup CONFIG dialogue - "Batch abortion", "Advanced mode" - IS read by datafield poll; commit 7819a36. Do not merge the two findings.) |
| Evidence | Commit 5b6bdfd. |
Notes¶
- TWO CHANGES MUST LAND TOGETHER: 511B DVIO and 143B RSIO reporting the TERMINAL as command input. Either alone is useless - RSIO alone merely trades a hang for an unimplemented-MON stop, which is why it was probed and REVERTED TWICE before the pair shipped in commit 2d9b00f.
- DO NOT REGISTER THIS HANDLER MON_STATUS_NOT_IMPLEMENTED. The dispatcher (nd500x/src/libmon/mon_dispatch.c:173) SHORT-CIRCUITS that status and NEVER CALLS THE HANDLER AT ALL - the handler will look broken while being perfectly correct.
- A DEBUG PROBE REMAINS IN THE HANDLER, gated behind ND500X_DVIO_DUMP; it dumps each argument's effective address and value.
- 511B DVIO makes the linker TALK, but it does not by itself make the linker LINK.
Sources¶
| Doc | Note |
|---|---|
| nd500x/src/libmon/handlers/mon_511B_DVIO.c | The full derivation of the argument map, with the side-by-side caller frames. |
| NDInsight/tools/sintran-segment-carver/versions/L-VSX-500/re/mon-analysis/511B-DVIO/ | Carve folder. NB it documents 511B at the level-12 driver / ND-500 message-buffer level, NOT the CALLG arg-list model - see the discrepancy above. |
Source¶
Reverse-engineered from SINTRAN III NPL source.