120B WriteToFile¶
Validated MON 120B (80 decimal) · Mnemonic WFILE · Group: File Operations (manual section 2.4)
Available from: not known - no compatibility box captured from the manual
Emulation source: src/handlers/mon_120B_WriteToFile.c
Description¶
Writes any number of bytes to a file. The read operation must start at the beginning of a block. The file must be opened for random write access.
- The standard block size is 512 bytes. You can change this with SetBlockSize. The first block is number 0.
- You may use access code D for direct transfer. Then the block size must be a multiple of the page size. The number of bytes to transfer must be a multiple of the block size. The data must be fixed contiguously in memory.
- Peripheral files are always written to sequentially.
- Data transfer across segment or RT common limits is illegal as this would be likely to result in inconsistent data.
Parameters¶
| Name | Type | Direction | Description |
|---|---|---|---|
FileNo |
INTEGER2 | In | File number. See OpenFile. |
ReturnFlag |
INTEGER2 | In | Wait flag. 0=suspend until complete, non-zero=continue (use AwaitFileTransfer to check). |
Buff |
BYTES | In | Buffer containing data to be transferred. |
BlockNo |
INTEGER2 | In | Block number to start writing from. Use -1 to write to the next block. |
NoOfBytes |
LONGINT | In | Number of bytes to be written. |
Direction: In = the program supplies the value, Out = the call returns it, In/Out = both.
See also¶
SetStartBlock, SetBlockSize, WriteDiskPage, WriteBlock, and ReadFromFile
Compatibility¶
| ND-100 | ND-500 | User programs | RT programs | System programs |
|---|---|---|---|---|
| Yes | Yes | Yes | Yes | No |
From the YAML extraction; this call's page in the manual had no compatibility box that was captured.
Examples¶
From the manual (OCR text, not corrected).
INTEGER : FileNo, ReturnFlag, BlockNo
BYTES : Buff(0:511)
INTEGER4 : NoOfBytes
...
ON ROUTINEERROR DO
IF ErrCode > 0 THEN ...
ENDON
Monitor_Call('WriteToFile', FileNo, ReturnFlag, Buff(0), BlockNo, NoOfBytes)
INTEGER FileNo, ReturnFlag, BlockNo
INTEGER Buff(256)
INTEGER*4 NoOfBytes
...
Monitor_Call('WriteToFile', FileNo, ReturnFlag, Buff(1),
BlockNo, NoOfBytes)
C IF (ErrCode .NE. 0) THEN ...
FileNo, ReturnFlag, BlockNo : INTEGER;
NoOfBytes : LONGINT;
Buff : ARRAY [0..15] OF RECORD...END;
...
WriteToFile(FileNo, ReturnFlag, Buff, BlockNo, NoOfBytes);
IF ErrCode <> 0 THEN ...
01 FileNo COMP. 01 ReturnFlag COMP.
01 Buff.
02 array COMP OCCURS 256 TIMES.
01 BlockNo COMP. 01 NoOfBytes COMP PIC S9(10).
01 ErrCode COMP.
...
MONITOR-CALL "WriteToFile" USING FileNo, ReturnFlag, Buff,
BlockNo, NoOfBytes.
CALL "CbError" USING ErrCode.
IF ErrCode NOT = 0 GO ...
FileNo : W BLOCK 1
ReturnFlag : W BLOCK 1
Buff : W BLOCK 256
BlockNo : W BLOCK 1
NoOfBytes : W BLOCK 1
ErrCode : W BLOCK 1
WriteToFile : EQU 3789 + 120B
...
CALLG WriteToFile, 5, FileNo, ReturnFlag, Buff, BlockNo, NoOfBytes
IF K GO ERROR
...
ERROR : W1 =: ErrCode %ErrorCode in W1 register.
LDA (PAR %Load register A with address of parameter list.
MON 120 %Monitor call WriteToFile.
JAF ERROR %Do error handling if register A is non-zero.
ERROR, ... %Error number in register A.
...
PAR, FILNO %File number returned from earlier open.
FLAG %Wait flag.
BUFF %Buffer containing data to be written.
BLKNO %Block number where writing is started.
COUNT %Number of words to transfer.
...
FILNO, ...
FLAG, ...
BUFF, 0
*+1000/ %Make a buffer of 512 words, 4 blocks.
BLKNO ...
COUNT, 0
1000 %Transfer 512 words.
ND-100 and ND-500 All users Background programs
ndmonlib implementation¶
Validated Registered MON_STATUS_VALIDATED in src/core/mon_registry.c: implemented, tested and working.
| Handler | mon_120B_WriteToFile |
| Code lines | 116 (non-blank, non-comment lines in the file) |
Notes from the handler source¶
src/handlers/mon_120B_WriteToFile.c line 79
Check file is not mapped as segment (per SINTRAN docs:
"You may not use WriteToFile on a file which is connected as a segment")
src/handlers/mon_120B_WriteToFile.c line 88
Check access mode allows random writing
Valid modes: ACCESS_RAND_RDWR (2), ACCESS_RAND_RDWR_CTG (6),
ACCESS_RAND_RDWR_RT (8), ACCESS_RAND_EXTEND (9)
src/handlers/mon_120B_WriteToFile.c line 121
Position the file.
BlockNo is a SIGNED halfword: -1 means "write to the next block", i.e.
carry on from wherever the previous transfer left off, without seeking.
This is how sequential streaming through WFILE works. Callers sign-extend
it to a word (PLANC emits H WCONV), so -1 arrives here as 0xFFFFFFFF;
treating it as an unsigned block index seeks past the end and fails every
write.
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) | implemented |
| nd500x handler | nd500x/src/libmon/handlers/mon_120B_WriteToFile.c |
| Last updated | 2026-07-17 |
Parameter notes¶
1. BlockNo
| Field | Value |
|---|---|
| Note | As in 117B RFILE: the manual field says "Use -1 to write to the next block", and the trap is the SIGN. BlockNo is a SIGNED halfword that callers sign-extend to a word (PLANC emits H WCONV), so -1 arrives as 0xFFFFFFFF. Read unsigned it seeks past the end and every write fails. -1 must mean "resume at the recorded position, do not seek by block". |
| Verified | Yes |
2. all INTEGER parameters
| Field | Value |
|---|---|
| Note | On ND-500 every INTEGER parameter is a 32-bit WORD ('W BLOCK' in the manual's assembly_500 examples), so nd500x reads all of them with word accessors. |
| Verified | Yes |
Return contract¶
- Success: K flag cleared; data flushed to the host file; file position advanced.
-
Errors
Code Octal Meaning 85 125B Not open for random write 87 127B File number out of range 90 132B No file opened with this number 97 141B Transfer error (short host write) 99 143B No such block (seek failed) 89 131B No more buffer space 124 174B Illegal parameter (file connected as segment; negative BlockNo other than -1; size over the cap)
Verified¶
| Claim | Evidence |
|---|---|
| WriteToFile is illegal on a file connected as a segment. | The manual states it; the handler enforces it (entry->mapped_as_segment -> 174B). |
| Writing past the recorded end extends the file. | The handler advances object_entry.bytes_in_file when the new position exceeds it, which is what 62B RMAX then reports. |
Unverified¶
- ReturnFlag (the wait flag) is read and logged but has no effect - every write is synchronous and flushed. The non-zero "continue, then use AwaitFileTransfer" path is not modelled.
- "The write operation must start at the beginning of a block" is not enforced.
- Access code D (direct transfer) block-size/page-size constraints are not enforced.
- "Peripheral files are always written sequentially" is not modelled.
- nd500x caps a single write at 65536 bytes (MAX_WRITE_SIZE) and returns 174B above it. That cap is an emulator invention, not a documented SINTRAN limit.
- Unlike 117B RFILE, this handler does NOT write a transferred-count back to NoOfBytes. Whether the real WFILE does a count write-back on a short write has not been carved - the 117B success path (006-S3FS worker 102130B, 102433-102470) was carved but the WFILE counterpart was not.
- WFILE's return contract has NOT been audited against the carve. The completeness matrix records it as MATCH from a manual-based reading only.
Sources¶
| Doc | Note |
|---|---|
| SINTRAN III Monitor Calls (ND-860228.2 EN) | The manual page this YAML was extracted from. |
| nd500x/docs/MON_COMPLETENESS_MATRIX.md | Row 120B WFILE - "MATCH (prior)", manual-based. |
Source¶
SINTRAN III Monitor Calls (ND-860228.2 EN), page 569.