Skip to content

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.