504B OutputString¶
Validated MON 504B (324 decimal) · Mnemonic DVOUTS · Group: File Operations (manual section 2.4)
Available from: All programs (manual compatibility box)
Emulation source: src/handlers/mon_504B_OutputString.c
Description¶
Writes a string to a device, e.g. a terminal or an opened file.
- This is the most efficient way to output strings on the ND-500.
- The maximum string length is 2048 bytes.
- Appendix F contains an ASCII table.
Parameters¶
| Name | Type | Direction | Description |
|---|---|---|---|
DeviceNo |
INTEGER2 | In | Logical device number, e.g. a file number. See appendix B. You may use 1 for your own terminal. Use the SINTRAN III open file number if output to a file. |
NoOfBytes |
INTEGER2 | In | Number of bytes to write (max 2048). |
Buffer |
STRING | In | String to be output. |
Direction: In = the program supplies the value, Out = the call returns it, In/Out = both.
See also¶
OutMessage, OutUpTo8Bytes, Out8Bytes, OutString, OutNumber, OutByte, and InputString
Compatibility¶
| Machines | Users | Programs |
|---|---|---|
| ND-500 | All users | All 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 | Yes | No | No | No |
Examples¶
From the manual (OCR text, not corrected).
INTEGER : DeviceNo, NoOfBytes
BYTES : Buff(0:199)
...
Monitor_Call('OutputString', DeviceNo, NoOfBytes, Buff(0))
INTEGER DeviceNo, NoOfBytes
INTEGER Buff(100)
...
Monitor_Call('OutputString', DeviceNo, NoOfBytes, Buff(1))
DeviceNo, NoOfBytes : LONGINT;
Buff : ARRAY [0..8] OF RECORD...END;
...
OutputString(DeviceNo, NoOfBytes, Buff);
01 DeviceNo COMP.
01 NoOfBytes COMP.
01 Buff.
02 array COMP OCCURS 100 TIMES.
...
MONITOR-CALL "OutputString" USING DeviceNo, NoOfBytes, Buff.
DeviceNo : W BLOCK 1
NoOfBytes : W BLOCK 1
Buff : BY BLOCK 4000B
Status : W BLOCK 1
OutputString : EQU 37B9 + 504B
...
CALLG OutputString, 3, DeviceNo, NoOfBytes, Buff
IF K GO Error
W1 =: Status
...
Error, ...
ndmonlib implementation¶
Validated Registered MON_STATUS_VALIDATED in src/core/mon_registry.c: implemented, tested and working.
| Handler | mon_504B_OutputString |
| Code lines | 118 (non-blank, non-comment lines in the file) |
Notes from the handler source¶
src/handlers/mon_504B_OutputString.c line 54
=========================================================================
DVOUTS core - shared with MON 511B DVIO (see mon_device_io.h).
=========================================================================
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_504B_OutputString.c |
| Last updated | 2026-07-17 |
Architecture note¶
THE DVOUTS BODY IS SHARED, NOT DUPLICATED. mon_dvouts_write() in nd500x/src/libmon/handlers/mon_504B_OutputString.c is the core, exported via mon_device_io.h, and MON 511B DVIO calls the SAME function for its output phase. The carve/NPL side confirms SINTRAN is built the same way: DVIO SHARES ITS OUTPUT BODY WITH NOUTSTR (MON 504) - SUBR DVIO,NOUTSTR,OSTRS,PT5RST at MP-P2-N500.NPL:1688. So 511B == 504B DVOUTS followed by 503B DVINST on the same device.
Parameter notes¶
1. Buffer
| Field | Value |
|---|---|
| Note | arg 2. Taken as a RAW BYTE ADDRESS (arg_addresses[2]) and read byte by byte - NOT a [Length][Pointer] descriptor. Contrast 162B OutString's 2-arg form, which IS a descriptor. Same index (2) in 511B DVIO. |
| Verified | Yes |
2. NoOfBytes
| Field | Value |
|---|---|
| Note | arg 1, a 32-bit word. Max 2048; a larger value is REJECTED with error 124 (174B) - unlike 503B DVINST's MaxNo, which is clamped. Same index (1) in 511B DVIO. |
| Verified | Yes |
3. DeviceNo
| Field | Value |
|---|---|
| Note | arg 0. Routed by class: character device / terminal -> console; mass-storage file -> open-file table (with fflush and position tracking); else error 24. |
| Verified | Yes |
Observed calls¶
1. ND linker (linker-b01.dom), thunk @0xB004ACA7, call @0xB004ACAD
| Field | Value |
|---|---|
| Params | Arg count: 3 |
| Expectation | A bare pass-through thunk: ents $0x20; call $0xF8000144, $0x3, b.0x14, b.0x18, @b.0x1C - with exactly ONE caller that builds its arg block at a fixed +0x150 and calls with ZERO CALLG args. |
| Note | This call site is load-bearing EVIDENCE for 511B: the 511B caller builds its args 0..2 with an instruction sequence BYTE-IDENTICAL to this one's, which is how 511B args 0..2 were proven to be DVOUTS' (DeviceNo, NoOfBytes, @Buffer). |
2. ND linker, via 511B DVIO
| Field | Value |
|---|---|
| Params | Deviceno: 1 Noofbytes: 2 Buffer: 0xB0049430 |
| Expectation | Writes the 2-byte prompt, after which the 503B DVINST phase reads a 12-byte line. |
| Note | Runtime-verified in commit 2d9b00f. |
Return contract¶
- Success: K flag cleared.
-
Errors
Code Octal Meaning 124 174B Illegal parameter (NoOfBytes > 2048, file not open for writing, or short host write) 24 030B No such device name (unsupported device class) 90 132B No file opened with this number 111 157B Missing parameter (fewer than 3 CALLG args)
Verified¶
1. The maximum string length is 2048 bytes.
| Field | Value |
|---|---|
| Evidence | The manual, corroborated from the NPL side: output byte count DNOBY, max 4000B octal = 2048 bytes (MP-P2-N500.NPL, recorded in 511B_DVIO.yaml). |
2. The output path works end to end against a real program.
| Field | Value |
|---|---|
| Evidence | Commit 2d9b00f: through 511B DVIO the linker's prompt is written ("504B DVOUTS wrote 2 bytes") and it proceeds to read its reply. |
3. DVOUTS is the right call to emulate WELL - it is the one real ND-500 programs actually use for output.
| Field | Value |
|---|---|
| Evidence | The manual for both 2B OutByte ("You are advised to use the faster OutputString on the ND-500"), 24B Out8Bytes and 162B OutString ("For performance reasons, it is inadvisable to use this call from the ND-500. Use OutputString instead") all point here, and the traced programs bear it out - 504B and 162B are the output calls actually observed. |
Unverified¶
- Error 124 (174B Illegal parameter) for NoOfBytes > 2048 is a CHOICE, not a read value. The manual states the 2048 limit but not the code returned for exceeding it. (Note 503B's carve DOES byte-verify a 174B illegal-parameter path, which makes 174B plausible here - but that is inference from the sibling call, not proof for this one.)
- The file-output path (writing DVOUTS to an open mass-storage file) is implemented but has NO observed caller; only the terminal path is trace-proven.
- nd500x never blocks on output - there is no output buffer to fill.
Sources¶
| Doc | Note |
|---|---|
| SINTRAN III Monitor Calls (ND-860228.2 EN) | The manual body of this YAML. |
| NDInsight/tools/sintran-segment-carver/versions/L-VSX-500/re/mon-analysis/504B-OutputString/ | Carve folder for this call - NOT mined into this block; the facts above come from the handler, the call sites and the 511B evidence chain. |
Source¶
SINTRAN III Monitor Calls (ND-860228.2 EN), page 383.