TRS-80 DOS - NEWDOS/80 v2.0 for the Model III - SYS9/SYS Disassembled

Page Customization

Introduction / Summary

SYS9/SYS is one of the NEWDOS/80 v2.0 DOS overlay modules, loaded into the overlay area at 4D00H–51FFH when any of its commands are invoked. SYS9 handles a diverse group of DOS library commands: COPY, DUAL, FORMS, KILL, MASTER, PATCH, RELO, ROUTE, SETCOM, and WP (Write Protect). It also contains handlers for the DOS FATAL ERROR and RUN ONLY STOPPED system messages.

When SYS1/SYS (the command interpreter) identifies one of these commands, it loads SYS9 into the overlay area and transfers control to the entry point at 4D00H. Register A contains a function code identifying which command group to execute, and Register C contains a sub-function number for the EBH dispatch group. Register HL points into the DOS command buffer at the current parse position.

The overlay is organized into several functional areas: the main command dispatch table (4D00H–4D41H), error exit stubs (4D42H–4D4FH), individual command handler routines, shared utility subroutines for option parsing and chaining control, text message strings, and the COPY command's file transfer engine. The ROUTE command at 4E22H contains self-modifying code that adjusts its initial setup value on first execution.

Variable and RAM Location Reference

The following RAM locations, system variables, and self-modifying code addresses are referenced throughout SYS9/SYS.

Variables and Storage:

AddressDescription
4058HTimer interrupt chain head pointer. Points to the first entry in the linked list of user 25ms timer interrupt routines enqueued via 4410H (Model III: 447BH).
4280HStart of PDRIVE storage area. IY is pointed here (4280H) at overlay entry to provide indexed access to PDRIVE parameters and system configuration.
4288HSystem flags byte (within PDRIVE/system storage). Used to track the current file number or operation index during file I/O sequences.
4289HSystem option flags word (2 bytes at 4289H–428AH). Byte at 4289H (Register C in the code) holds option bits including: Bit 5 = chaining Y/N flag. Byte at 428AH (Register B in the code) holds option bits including: Bit 6 = D-option valid flag, Bit 4 = D-option selected flag.
428DHSYSTEM option flags. Bit 7 = flag checked by the ROUTE command to determine stack scanning behavior. Bit 6 = BREAK key enable flag checked during chaining pause operations.
42C5HChaining saved-character byte. When the ROUTE/CHAIN system is reading characters from a chain file, this byte holds the last character read or a state indicator (00H = no saved character, non-zero = saved character or state code).
44A0HStart of a 32-byte (20H bytes) work area used for filespec storage and parameter passing. Byte at 44A0H bit 7 is tested by the MASTER command to check file status. The area from 44A0H–44BFH is loaded from the command buffer during RELO processing.
44A1HSecond byte of the work area. Bit 5 is set by the ROUTE command during initialization to indicate the route is active.
44A3H2-byte pointer within the work area. The RELO command stores a pointer to the default filename extension string (4FF7H) here.
44A5HCurrent byte position counter within the chain file read routine. Tracks how many bytes have been consumed from the current record.
44A9HByte difference value used in chain file positioning. Stores the difference between the starting and current position for record repositioning.
4480HFCB (File Control Block) base area used for file I/O operations. Passed as DE parameter to DOS file position routines.
4483H2-byte pointer storing the address of a routine to call after file operations (set by the COPY file transfer engine at 4FDDH).
4488HFile record length or mode byte. Tested by the COPY routine to determine whether to decrement the record count.
448CH2-byte value holding the current file record count or size. Read by the COPY routine to determine the number of records to transfer.
3840HKeyboard memory-mapped row 6: ENTER, CLEAR, BREAK, UP, DOWN, LEFT, RIGHT, SPACE. Bit 0 = @ key (address row); Bit 3 = UP ARROW key; Bit 6 = RIGHT ARROW key. Various bits tested for BREAK key checking and keyboard pause detection.
51E0HStart of a temporary buffer area within the overlay's unused padding space. Used by the COPY command and the FORMS/PATCH line-input routine to store filespec data and input text. Extends through 51EFH (16 bytes for filespec) or further as needed.
51EAH2-byte value within the 51E0H buffer area. The COPY routine stores the source file's record count here.
51ECH2-byte value within the 51E0H buffer area. The COPY routine stores the destination file's ending record count here.
51E8HByte within the 51E0H buffer area. The COPY routine stores the file record length/mode byte here.

Self-Modifying Code:

AddressDescription
4E22HThe ROUTE command entry point. Initially contains LD A,0AH (3E 0AH). On first execution, the instruction at 4E26H overwrites the immediate operand at 4E22H+1 with 18H, changing the instruction to LD A,18H for all subsequent calls. This implements a one-time initialization: the first ROUTE invocation uses function code 0AH, and all subsequent invocations use 18H.

Major Routine Reference

The following is a summary of the major routines within SYS9/SYS and their entry points.

Command Dispatch and Error Handling

AddressDescription
4D00HMain entry point and command dispatcher. Dispatches to individual command handlers based on function code in Register A and sub-function in Register C.
4D42HError exit: loads error code 2AH (general error) and falls through to the common error exit at 4D4EH.
4D46HError exit with file close: loads error code 33H, pushes it, calls RST 28H with function 46H to close the current file, then loads error code 2FH and exits.
4D4EHCommon error exit: OR A to clear the Z flag and set NZ, then jumps to SYS0 error handler at 4409H.

Shared Utility Routines

AddressDescription
4D63HDisplay pending chaining message. Checks system option flags at 4289H: if bit 6 of B (428AH) is set and bit 5 of C (4289H) is clear, calls 4467H to display a message. Returns with A=0 and Z flag set.
4D82HParse Y/N/D option from command line. Reads a character from (HL), converts to uppercase via 4548H, and sets bits in Register B and C based on whether the character is Y, N, or D. Stores updated flags back to 4289H on success.
4DC7HDOS-CALL / SVC invocation setup. Saves alternate register set, sets BC'=EB01H and DE'=4978H (SVC parameters), then tests Register A and dispatches accordingly.
4EC5HReset chaining state. Clears byte at 44A0H to 00H, resets bit 5 of (4289H) and bit 4 of (428AH), clearing all chaining-active flags.
4ED3HCheck for SHIFT+DOWN ARROW key combination. Reads keyboard row at 3840H, tests bit 3 (UP ARROW), then checks system option flag bit 6 at 428DH. Returns Z if the key combination is not pressed or not enabled.
4F45HDisplay two messages: first the "CHAINING " prefix from 4F98H, then the message pointed to by HL on entry. Used by the ABORTED and PAUSE message display routines.
4F50HRead next character from chain file. Calls the low-level chain read at 4F8CH, then checks for slash-delimited embedded commands (section markers, drive specs). Returns the character in A with Z flag set on success, or NZ on error.
4F8CHLow-level chain file character read. Calls DOS routine 0013H (read next byte from file) with DE pointing to the work area at 44A0H. Skips null bytes (00H). Returns character in A with Z set, or NZ on error.

Command Handlers

AddressDescription
4D72HMASTER command handler. Checks file status bit, then calls the Y/N/D parser. Exits with error if the parse fails.
4DACHDOS FATAL ERROR handler. Points HL to the "DOS FATAL ERROR" message at 50F4H and falls into the reset prompt routine.
4DB1HRUN ONLY STOPPED handler. Points HL to the "'RUN ONLY' STOPPED" message at 50E1H and falls into the reset prompt routine.
4DB4HReset prompt routine. Displays the error message, then displays "!! KEY 'R' FOR RESET." and waits for the R key, then executes RST 00H (system reset).
4DC6HSystem reset (RST 00H). Immediate hardware reset.
4DD9HCOPY command entry (sub-function 1). Pops return address manipulation for stack-based dispatch.
4DDCHRELO command entry (sub-function 3). Copies 32 bytes from command buffer to the 44A0H work area, sets up the default extension pointer, then processes the file operation.
4E06HFilename search/match routine. Scans through a data stream reading bytes via 4F50H looking for an 80H marker byte followed by character matches against the string at (HL).
4E22HROUTE command entry. [SELF-MODIFYING CODE] First call uses function 0AH; subsequent calls use 18H.
4E57HROUTE command main processing. Checks BREAK key, calls chain character reader, and processes the chain file command stream.
4EBFHDisplay "CHAINING ABORTED" message and reset chaining state.
4EE2HChain error handler. Calls the ABORTED display, then exits to either the no-error exit (4030H) or the error exit (4409H) depending on the error state.
4F03HDisplay "CHAINING PAUSE" message and wait for a key release.
4F1BHLine input from chain file. Reads up to 32 characters from the chain file into a buffer at 4FD7H, terminated by 0DH (ENTER).
4FD7HCOPY command file transfer engine. Sets up FCB parameters, opens files, and transfers records between source and destination.
5048HKILL command handler. Validates address range, then manipulates the timer interrupt chain linked list to remove an entry.
505FHWP (Write Protect) command handler (actually the enqueue side - adds to timer chain).
5070HFORMS command handler. Parses up to 9 characters of filename from the command buffer into the 51E0H buffer area.
50A3HAddress range validation. Checks that Register H >= 52H (address must be above the overlay area at 5200H). Returns NZ with HL advanced by 4 if valid.
50ADHTimer interrupt chain search. Walks the linked list at 4058H looking for a matching entry. Returns Z if found, NZ if not found.
511BHROUTE final check. Tests Register A for zero, then examines bits 4 and 6 of Register B to determine exit path.

Text Message Strings

AddressMessage
4F98H"CHAINING " (terminated by 03H at 4FA1H, but note the space at 4FA0H is followed by 03H)
4FA2H"ABORTED" + 0DH
4FAAH"PAUSE. PRESS 'ENTER' WHEN READY TO CONTINUE" + 0DH
50E1H"'RUN ONLY' STOPPED" + 03H
50F4H"DOS FATAL ERROR" + 03H
5104H"!! KEY 'R' FOR RESET." + 0DH

Disassembly

4D00H – SYS9 Main Entry Point and Command Dispatcher

This is the entry point for SYS9/SYS. SYS0 loads this overlay and jumps here with Register A containing a function code that identifies which command group was requested. Register IY is set to 4280H (PDRIVE storage base) for indexed access to system parameters. Register HL points into the DOS command buffer at the current parse position, and Register C contains a sub-function number used by the EBH dispatch group.

4D00
LD IY,4280H FD 21 80 42
Point Index Register IY to 4280H, the base of the PDRIVE storage and system configuration area. This gives all routines in this overlay fast indexed access to system parameters via IY+offset addressing.
4D04
CP 2BH FE 2B
Compare Register A (the function code from SYS1 identifying which command was entered) against 2BH (decimal 43, the code for the CHAIN/DO command group). If Register A equals 2BH, the Z FLAG is set; otherwise the NZ FLAG is set.
4D06
If the Z FLAG has been set (function code is 2BH, meaning the KILL command was requested), JUMP to 5048H to execute the KILL command handler.
4D09
CP 4BH FE 4B
Compare Register A (function code) against 4BH (decimal 75, the code for the WP/KILL-enqueue command group). If Register A equals 4BH, the Z FLAG is set.
4D0B
If the Z FLAG has been set (function code is 4BH), JUMP to 505FH to execute the WP (Write Protect / timer chain enqueue) command handler.
4D0E
CP CBH FE CB
Compare Register A (function code) against CBH (decimal 203, the code for the ROUTE command). If Register A equals CBH, the Z FLAG is set.
4D10
If the Z FLAG has been set (function code is CBH, meaning the ROUTE command was requested), JUMP to 4E22H to execute the ROUTE command handler.
4D13
CP EBH FE EB
Compare Register A (function code) against EBH (decimal 235, the multi-command dispatch group code). If Register A equals EBH, the Z FLAG is set; otherwise we fall through to the error exit below.
4D15
If the NZ FLAG has been set (function code is not EBH, and was not 2BH, 4BH, or CBH either — meaning an unrecognized function code was passed), JUMP to 4D42H which loads error code 2AH (general error) and exits through the error handler.

The function code is EBH. Now Register C contains a sub-function number identifying which specific command within this group was requested. The code uses a series of DEC C / conditional jump pairs to dispatch. Each DEC C decrements the sub-function counter by 1, and a JP Z or JR Z fires when the counter reaches zero, meaning we have found the matching command.

4D17
DEC C 0D
DECrement Register C (the sub-function counter) by 1. If C was 1 on entry, it is now 0 and the Z FLAG is set, indicating sub-function 1 = COPY command.
4D18
If the Z FLAG has been set (sub-function 1), JUMP to 4DD9H to execute the COPY command handler.
4D1B
DEC C 0D
DECrement Register C by 1. If C was 2 on entry, it is now 0 and the Z FLAG is set, indicating sub-function 2 = WP (Write Protect) command.
4D1C
If the Z FLAG has been set (sub-function 2), JUMP to 4FD7H to execute the WP command via the COPY file transfer engine.
4D1F
DEC C 0D
DECrement Register C by 1. If C was 3 on entry, it is now 0 and the Z FLAG is set, indicating sub-function 3 = RELO command.
4D20
If the Z FLAG has been set (sub-function 3), JUMP to 4DDCH to execute the RELO command handler.
4D23
DEC C 0D
DECrement Register C by 1. If C was 4 on entry, it is now 0 and the Z FLAG is set, indicating sub-function 4 = PATCH command.
4D24
If the Z FLAG has been set (sub-function 4), JUMP to 4EE2H to execute the PATCH command handler.
4D27
DEC C 0D
DECrement Register C by 1. If C was 5 on entry, it is now 0 and the Z FLAG is set, indicating sub-function 5 = MASTER command.
4D28
If the Z FLAG has been set (sub-function 5), JUMP to 4D72H to execute the MASTER command handler.
4D2A
DEC C 0D
DECrement Register C by 1. If C was 6 on entry, it is now 0 and the Z FLAG is set, indicating sub-function 6 = unrecognized/error.
4D2B
If the Z FLAG has been set (sub-function 6), JUMP to 4D42H to exit with error code 2AH (general error). Sub-function 6 is not assigned to any command.
4D2E
DEC C 0D
DECrement Register C by 1. If C was 7 on entry, it is now 0 and the Z FLAG is set, indicating sub-function 7 = FORMS command.
4D2F
If the Z FLAG has been set (sub-function 7), JUMP to 5070H to execute the FORMS command handler.
4D32
DEC C 0D
DECrement Register C by 1. If C was 8 on entry, it is now 0 and the Z FLAG is set, indicating sub-function 8 = SETCOM command.
4D33
If the Z FLAG has been set (sub-function 8), JUMP to 4D52H to execute the SETCOM command handler.
4D35
DEC C 0D
DECrement Register C by 1. If C was 9 on entry, it is now 0 and the Z FLAG is set, indicating sub-function 9 = DUAL command.
4D36
If the Z FLAG has been set (sub-function 9), JUMP to 4D63H to execute the DUAL command handler (which is actually the display-pending-chaining-message routine).
4D38
DEC C 0D
DECrement Register C by 1. If C was 10 on entry, it is now 0 and the Z FLAG is set, indicating sub-function 10 = System Reset (RST 00H).
4D39
If the Z FLAG has been set (sub-function 10), JUMP to 4DC6H to execute the system reset handler (RST 00H entry with DOS-CALL setup).
4D3C
DEC C 0D
DECrement Register C by 1. If C was 11 on entry, it is now 0 and the Z FLAG is set, indicating sub-function 11 = DOS FATAL ERROR handler.
4D3D
If the Z FLAG has been set (sub-function 11), JUMP to 4DACH to display "DOS FATAL ERROR" and prompt for system reset.
4D3F
DEC C 0D
DECrement Register C by 1. If C was 12 on entry, it is now 0 and the Z FLAG is set, indicating sub-function 12 = 'RUN ONLY' STOPPED handler.
4D40
If the Z FLAG has been set (sub-function 12), JUMP to 4DB1H to display "'RUN ONLY' STOPPED" and prompt for system reset.

4D42H – Error Exit Stubs

These are short error exit routines used by the dispatcher and individual command handlers. They load an appropriate NEWDOS/80 error code into Register A and jump to the SYS0 error handler at 4409H.

4D42
LD A,2AH 3E 2A
Load Register A with 2AH (decimal 42), the NEWDOS/80 error code for General Error. This is the default error exit for unrecognized function codes or sub-function numbers.
4D44
JUMP unconditionally to 4D4EH, the common error exit that sets the NZ flag and jumps to the SYS0 error handler at 4409H.
4D46
LD A,33H 3E 33
Load Register A with 33H (decimal 51), a NEWDOS/80 error code. This entry point is used when a file operation has failed and the file needs to be closed before reporting the error.
4D48
PUSH AF F5
Save Register A (error code 33H) and the flags onto the stack, preserving the error code while we close the file.
4D49
LD A,46H 3E 46
Load Register A with 46H (decimal 70). This is the SVC function code to be passed to RST 28H. Function 46H is the close file SVC — it closes the file associated with the current FCB.
4D4B
RST 28H EF
Execute RST 28H (the NEWDOS/80 Supervisor Call vector). With Register A = 46H, this invokes the close file SVC to close the currently open file before we report the error. This ensures the file is properly closed even though an error occurred.
4D4C
LD A,2FH 3E 2F
Load Register A with 2FH (decimal 47), a NEWDOS/80 error code indicating a file-related error that occurred after the close attempt. This overwrites the previous error code — the close-then-report pattern ensures a clean state.
4D4E
OR A B7
OR Register A with itself. Since A contains a non-zero error code (2AH, 2FH, or other), this clears the Z flag (sets NZ) and clears the Carry flag. The NZ condition signals to the caller that an error occurred.
4D4F
JUMP to 4409H in SYS0, the DOS error exit routine. This routine displays the error message corresponding to the error code in Register A and returns to the DOS command prompt.

4D52H – SETCOM Command Handler

The SETCOM command (Model III only) sets RS-232 interface parameters. This handler calls the DUAL display routine first, then displays the "PAUSE" prompt message and waits for the user to press ENTER before returning.

4D52
GOSUB to 4D63H to display any pending chaining message. This routine checks the system option flags at 4289H and conditionally displays a notification if chaining state requires it. Returns with A=0 and Z flag set.
4D55
LD HL,4FB2H 21 B2 4F
Point Register Pair HL to 4FB2H, the address of the text string "PRESS 'ENTER' WHEN READY TO CONTINUE" terminated by 0DH. This message will be displayed to the user.
4D58
GOSUB to 4467H in SYS0, the send message to video display routine. HL points to the message string. The routine displays characters until it encounters a 0DH (carriage return) or 03H terminator.

[LOOP START] — Wait for the user to press ENTER. The loop reads the keyboard until the ENTER key (0DH) is detected.

4D5B
GOSUB to ROM routine at 0049H, the scan keyboard routine. This routine checks the keyboard and returns the ASCII code of any key currently pressed in Register A, or 0 if no key is pressed.
4D5E
SUB 0DH D6 0D
SUBtract 0DH (ASCII code for ENTER/carriage return) from Register A (the key code returned by the keyboard scan). If the key pressed was ENTER, the result is zero and the Z FLAG is set.
4D60
If the NZ FLAG has been set (the key pressed was not ENTER, or no key was pressed), JUMP back to 4D5BH to continue scanning the keyboard. [LOOP END]
4D62
RET C9
RETURN to the caller. The SETCOM handler has displayed its message and waited for ENTER. Control returns to SYS0 which will proceed with further SETCOM processing.

4D63H – Display Pending Chaining Message / DUAL Command Handler

This routine checks the system option flags at 4289H–428AH. If bit 6 of the byte at 428AH (the "D-option valid" flag in Register B) is set AND bit 5 of the byte at 4289H (the "chaining Y flag" in Register C) is clear, it calls the message display routine at 4467H to show a pending notification. This routine also serves as the DUAL command handler (sub-function 9). It always returns with Register A = 0 and the Z flag set.

4D63
LD BC,(4289H) ED 4B 89 42
Load Register Pair BC from the 2-byte system option flags at 4289H. Register C receives the byte at 4289H (option byte containing bit 5 = chaining Y/N flag) and Register B receives the byte at 428AH (option byte containing bit 6 = D-option valid flag, bit 4 = D-option selected flag).
4D67
BIT 6,B CB 70
Test bit 6 of Register B (the byte from 428AH). Bit 6 is the D-option valid flag. If this bit is 0, the Z FLAG is set (D-option is not active); if this bit is 1, the NZ FLAG is set (D-option is active).
4D69
If the Z FLAG has been set (bit 6 of B is 0, meaning the D-option is not active), JUMP to 4D70H to skip the message display and return with A=0.
4D6B
BIT 5,C CB 69
Test bit 5 of Register C (the byte from 4289H). Bit 5 is the chaining Y flag. If this bit is 0, the Z FLAG is set (chaining is not set to Y); if this bit is 1, the NZ FLAG is set (chaining is set to Y).
4D6D
If the Z FLAG has been set (bit 5 of C is 0, meaning chaining Y flag is NOT set), GOSUB to 4467H in SYS0 to display the message pointed to by Register HL. HL still points to wherever it was set by the caller. The condition is: D-option is active (bit 6 of B = 1) AND chaining Y is not active (bit 5 of C = 0) — display the message.
4D70
XOR A AF
Set Register A to 0 by XORing it with itself. This also sets the Z FLAG and clears the Carry flag. The routine always returns with A=0 and Z set, indicating no error.
4D71
RET C9
RETURN to the caller with Register A = 0 and Z flag set.

4D72H – MASTER Command Handler

The MASTER command (sub-function 5) manages the master diskette designation. It first checks bit 7 of the byte at 44A0H (the file status/work area byte) to determine the current state. If bit 7 is clear (Carry not set after RLCA), an error is returned. If bit 7 is set, the Y/N/D option parser at 4D82H is called to read the user's option character from the command buffer. On success (Z flag), the routine returns to the caller. On failure (NZ flag), error code 34H (parse error) is returned.

4D72
LD A,(44A0H) 3A A0 44
Fetch the byte at 44A0H (the first byte of the 32-byte work area, which holds file status flags set up by the command interpreter) into Register A. Bit 7 of this byte indicates whether the file/diskette is in a valid state for the MASTER operation.
4D75
RLCA 07
Rotate Register A Left through Carry. This moves bit 7 of A into the Carry flag. If bit 7 was 1 (file status is valid for MASTER), the CARRY FLAG is set. If bit 7 was 0 (file status is not valid), the NO CARRY FLAG is set.
4D76
LD A,26H 3E 26
Load Register A with 26H (decimal 38), a NEWDOS/80 error code. This value is loaded preemptively — it will only be used if the Carry flag is not set (meaning the MASTER operation is not valid in the current state). Note: this LD does not affect flags.
4D78
If the NO CARRY FLAG has been set (bit 7 of 44A0H was 0, meaning the file status is not valid for the MASTER command), JUMP to 4D4EH to exit with error code 26H in Register A.
4D7A
GOSUB to 4D82H, the Y/N/D option parser. This routine reads the next character from the command buffer pointed to by HL, converts it to uppercase, and sets the appropriate flag bits in Registers B and C based on whether the character is Y, N, or D. Returns Z on success (valid option found and command line terminated by 0DH), or NZ on failure.
4D7D
RET Z C8
If the Z FLAG has been set (the Y/N/D parser succeeded — a valid option was found and the remainder of the command line is properly terminated), RETURN to the caller. The MASTER command has been processed successfully.
4D7E
LD A,34H 3E 34
Load Register A with 34H (decimal 52), the NEWDOS/80 error code for Parse Error. The Y/N/D parser returned NZ, meaning the option character was not Y, N, or D, or the command line was not properly terminated.
4D80
JUMP unconditionally to 4D4EH, the common error exit, to report parse error 34H via the SYS0 error handler at 4409H.

4D82H – Parse Y/N/D Option from Command Line

This utility routine parses a single-character option (Y, N, or D) from the command line buffer pointed to by Register HL. It loads the current system option flags from 4289H–428AH, clears the relevant flag bits, reads and converts the character to uppercase, sets the appropriate bits based on the character found, verifies the command line is terminated by 0DH, and stores the updated flags back to 4289H. Returns Z and A=0 on success, or NZ on failure (invalid character or unterminated command).

4D82
LD BC,(4289H) ED 4B 89 42
Load Register Pair BC from the 2-byte system option flags at 4289H. Register C receives the byte at 4289H (contains bit 5 = chaining Y/N flag among others). Register B receives the byte at 428AH (contains bit 6 = D-option valid flag, bit 4 = D-option selected flag).
4D86
RES 5,C CB A9
Clear bit 5 of Register C (the chaining Y flag in the 4289H option byte). This resets the Y flag before we parse the new option, so the flags reflect only the current command's setting.
4D88
RES 4,B CB A0
Clear bit 4 of Register B (the D-option selected flag in the 428AH option byte). This resets the D flag before parsing.
4D8A
LD A,(HL) 7E
Fetch the character at the current command buffer position (pointed to by HL) into Register A. This is the option character the user typed (Y, N, D, or something else).
4D8B
GOSUB to 4548H in SYS0, the convert to uppercase routine. If Register A contains a lowercase letter (61H–7AH), it is converted to uppercase (41H–5AH). Otherwise A is unchanged.
4D8E
CP 4EH FE 4E
Compare Register A (the uppercase option character) against 4EH (ASCII N). If Register A equals 4EH, the Z FLAG is set, meaning the user selected the N (No) option.
4D90
If the Z FLAG has been set (user typed N), JUMP to 4DA1H. For the N option, no additional flag bits need to be set — bit 5 of C and bit 4 of B were already cleared above. The code skips ahead to verify the command line terminator.
4D92
SET 5,C CB E9
Set bit 5 of Register C (the chaining Y flag in the 4289H option byte). This bit is set for both the Y and D options — the Y flag is active whenever the option is not N.
4D94
CP 59H FE 59
Compare Register A (the uppercase option character) against 59H (ASCII Y). If Register A equals 59H, the Z FLAG is set, meaning the user selected the Y (Yes) option.
4D96
If the Z FLAG has been set (user typed Y), JUMP to 4DA1H. For the Y option, bit 5 of C was already set above. The code skips ahead to verify the command line terminator.
4D98
CP 44H FE 44
Compare Register A (the uppercase option character) against 44H (ASCII D). If Register A equals 44H, the Z FLAG is set, meaning the user selected the D (Deferred/Dual) option.
4D9A
RET NZ C0
If the NZ FLAG has been set (the character was not N, Y, or D — it is an invalid option character), RETURN immediately with NZ set. The caller will detect this and report a parse error.

The character is D. Check if the D-option is valid (bit 6 of B must be set for D to be accepted).

4D9B
BIT 6,B CB 70
Test bit 6 of Register B (the D-option valid flag from 428AH). If this bit is 0, the Z FLAG is set (D-option is not valid for this command); if this bit is 1, the NZ FLAG is set (D-option is valid).
4D9D
If the Z FLAG has been set (bit 6 of B is 0, meaning D-option is not valid), JUMP to 4DA1H. The D character is accepted but bit 4 of B is not set — the D-option is treated as a no-op when it is not valid.
4D9F
SET 4,B CB E0
Set bit 4 of Register B (the D-option selected flag in the 428AH option byte). This marks that the user explicitly selected the D option and it is valid for this command.

All three option paths (N, Y, D) converge here. Now verify that the next character in the command buffer is 0DH (ENTER), indicating the option was the last parameter on the command line.

4DA1
INC HL 23
INCrement Register Pair HL by 1, advancing the command buffer pointer past the option character to the next byte.
4DA2
LD A,(HL) 7E
Fetch the next character from the command buffer (pointed to by HL) into Register A. This should be 0DH (carriage return) if the command line is properly terminated.
4DA3
CP 0DH FE 0D
Compare Register A against 0DH (ASCII carriage return / ENTER). If Register A equals 0DH, the Z FLAG is set, confirming the command line is properly terminated after the option character.
4DA5
RET NZ C0
If the NZ FLAG has been set (the next character is not 0DH — there is unexpected text after the option), RETURN with NZ set. The caller will report a parse error.

The command line is properly terminated. Store the updated option flags back to the system variable area and return success.

4DA6
LD (4289H),BC ED 43 89 42
Store Register Pair BC back to the 2-byte system option flags at 4289H. Register C (with updated bit 5 = chaining Y flag) is stored at 4289H, and Register B (with updated bit 4 = D-option selected flag) is stored at 428AH. The system option state now reflects the user's Y/N/D selection.
4DAA
XOR A AF
Set Register A to 0 by XORing it with itself. This sets the Z FLAG and clears the Carry flag, indicating success to the caller.
4DAB
RET C9
RETURN to the caller with A=0 and Z flag set, indicating the Y/N/D option was successfully parsed and the system flags have been updated.

4DACH – DOS FATAL ERROR / 'RUN ONLY' STOPPED / Reset Prompt Handlers

These routines handle unrecoverable system conditions. The DOS FATAL ERROR handler (sub-function 11) and the 'RUN ONLY' STOPPED handler (sub-function 12) each load a pointer to their respective error message string and then fall into the shared reset prompt routine at 4DB4H. The reset prompt displays the error message, displays "!! KEY 'R' FOR RESET.", then waits in a loop for the user to press R. Once R is detected, RST 00H performs a hardware system reset.

4DAC
LD HL,50F4H 21 F4 50
Point Register Pair HL to 50F4H, the address of the text string "DOS FATAL ERROR" (terminated by 03H). This is the DOS FATAL ERROR handler entry point (sub-function 11).
4DAF
JUMP unconditionally to 4DB4H, the shared reset prompt routine, to display the error message and wait for R to reset.
4DB1
LD HL,50E1H 21 E1 50
Point Register Pair HL to 50E1H, the address of the text string "'RUN ONLY' STOPPED" (terminated by 03H). This is the 'RUN ONLY' STOPPED handler entry point (sub-function 12). Falls through to the reset prompt at 4DB4H.
4DB4
GOSUB to 4467H in SYS0, the send message to video display routine. HL points to the error message string ("DOS FATAL ERROR" or "'RUN ONLY' STOPPED"). The routine displays characters until it encounters a 03H or 0DH terminator.
4DB7
LD HL,5104H 21 04 51
Point Register Pair HL to 5104H, the address of the text string "!! KEY 'R' FOR RESET." (terminated by 0DH). This second message tells the user how to recover.
4DBA
GOSUB to 4467H in SYS0 to display the "!! KEY 'R' FOR RESET." message on the video screen.

[LOOP START] — Wait for the user to press the R key. The loop reads the keyboard, masks the case bit, and checks for ASCII R (52H).

4DBD
GOSUB to ROM routine at 0049H, the scan keyboard routine. Returns the ASCII code of any key currently pressed in Register A, or 0 if no key is pressed.
4DC0
RES 5,A CB AF
Clear bit 5 of Register A. This converts lowercase letters to uppercase by clearing the bit that differentiates them (bit 5 is the only difference between uppercase 41H–5AH and lowercase 61H–7AH in ASCII). Specifically, lowercase r (72H) becomes uppercase R (52H).
4DC2
CP 52H FE 52
Compare Register A (the uppercase key code) against 52H (ASCII R). If Register A equals 52H, the Z FLAG is set, meaning the user pressed R or r.
4DC4
If the NZ FLAG has been set (the user did not press R), JUMP back to 4DBDH to continue scanning the keyboard. [LOOP END]

4DC6H – System Reset (RST 00H)

This entry point executes RST 00H, which performs a hardware system reset on the TRS-80 Model III. The CPU jumps to address 0000H in ROM, which reinitializes the system and boots from disk. This is reached after the user presses R in response to a DOS FATAL ERROR or 'RUN ONLY' STOPPED condition. It is also the target of sub-function 10 from the dispatch table.

4DC6
RST 00H C7
Execute RST 00H, which jumps to address 0000H in ROM. On the Model III, this initiates a complete system reset: the ROM bootstrap code re-executes, reinitializing all hardware and loading the operating system from the boot disk. This is a dead-end instruction — execution never continues past this point.

4DC7H – DOS-CALL / SVC Invocation Setup

This routine sets up the alternate register set with SVC (Supervisor Call) parameters and then dispatches based on the value of Register A. It is called by the COPY file transfer engine and other routines that need to invoke DOS services. The alternate registers BC' and DE' are loaded with EB01H and 4978H respectively — these are the SVC function code (EB01H = overlay load with sub-function 01) and the SVC parameter pointer (4978H). If Register A is non-zero, execution jumps to 4982H in SYS0. If Register A is zero, the alternate HL' is pushed and execution returns through the stack.

4DC7
EXX D9
Exchange the primary register set (BC, DE, HL) with the alternate register set (BC', DE', HL'). The alternate registers are now the active set and can be loaded with SVC parameters.
4DC8
LD BC,EB01H 01 01 EB
Load alternate Register Pair BC' with EB01H. This is the SVC overlay identifier: EBH = SYS9 overlay module code, 01H = sub-function code. This tells the DOS SVC system to use SYS9's handler with sub-function 1.
4DCB
LD DE,4978H 11 78 49
Load alternate Register Pair DE' with 4978H, a pointer to a parameter block or routine entry point within the SYS0 resident area. This is used as the SVC's data/routine pointer parameter.
4DCE
PUSH BC C5
Save alternate Register BC' (value EB01H) onto the stack. This pushes the SVC overlay identifier onto the stack where it will be accessible by the DOS-CALL dispatch mechanism.
4DCF
PUSH DE D5
Save alternate Register DE' (value 4978H) onto the stack. This pushes the SVC parameter pointer onto the stack.
4DD0
EXX D9
Exchange back to the primary register set (BC, DE, HL). The alternate registers now hold the SVC parameters (EB01H and 4978H), and the primary registers are restored.
4DD1
OR A B7
OR Register A with itself. This tests whether Register A is zero or non-zero without changing its value. If A is zero, the Z FLAG is set; if A is non-zero, the NZ FLAG is set. The Carry flag is cleared.
4DD2
If the NZ FLAG has been set (Register A is non-zero, indicating a DOS-CALL with a specific function), JUMP to 4982H in SYS0. This is a DOS-CALL entry point that processes the SVC using the parameters previously set up in the alternate registers and on the stack.

Register A is zero. This is the "return via stack" path — push the alternate HL' and return, which transfers control to whatever address was in HL'.

4DD5
EXX D9
Exchange to the alternate register set. HL' (the alternate HL, which was preserved from before the first EXX) is now the active HL.
4DD6
PUSH HL E5
Save alternate Register HL' onto the stack. This places a return address on the stack — when the following EXX/RET executes, the RET will pop this address and jump to it.
4DD7
EXX D9
Exchange back to the primary register set.
4DD8
RET C9
RETURN. This pops the address that was just pushed (the value from HL') and jumps to it. This effectively performs a computed jump to the address that was in the alternate HL register.

4DD9H – COPY Command Entry (Stack Manipulation)

The COPY command entry point (sub-function 1) performs a stack manipulation to redirect the return path. It exchanges the top of the stack with HL, then pops the result into HL. The effect is to replace the current return address with the value in HL (the command buffer pointer), and load the old return address into HL. This sets up HL with the return address from the dispatcher while putting the command buffer pointer where a later RET will find it.

4DD9
EX (SP),HL E3
Exchange the value at the top of the stack with Register Pair HL. HL previously held the command buffer pointer (from the dispatch entry). The top of stack held the return address from the caller. After this instruction, HL contains the old return address and the stack top contains the command buffer pointer.
4DDA
POP HL E1
Pop the value from the top of the stack into Register Pair HL. This loads HL with the command buffer pointer that was just placed on the stack. The stack is now one level shorter, and the original return address has been discarded.
4DDB
RET C9
RETURN. This pops the next value from the stack and jumps to it. The stack now points to the next return address in the chain. This effectively transfers control to the routine that follows the COPY dispatch, with HL pointing to the command buffer.

4DDCH – RELO Command Handler

The RELO command (sub-function 3) relocates or transfers file data. It copies 32 bytes (20H) from the current command buffer position into the 44A0H work area, stores a pointer to the default filename extension string at 44A3H, restores saved registers from the stack, calls 4C7AH in SYS0 for the main relocation processing, and then conditionally calls the filename search routine at 4E06H. On success, it sets the chaining Y flag (bit 5 of 4289H), conditionally sets the D-option flag, clears the saved character byte at 42C5H, and returns.

4DDC
EX DE,HL EB
Exchange Register Pairs DE and HL. HL previously pointed to the current position in the command buffer. After this exchange, DE holds the command buffer pointer (source for the block copy) and HL holds whatever was in DE (not critical here — HL will be set as the destination next).
4DDD
LD DE,44A0H 11 A0 44
Load Register Pair DE with 44A0H, the address of the 32-byte work area. DE is now the destination for the block copy — the command buffer data will be copied here.
4DE0
LD BC,0020H 01 20 00
Load Register Pair BC with 0020H (decimal 32), the number of bytes to copy. This is the size of the work area at 44A0H that will receive the command buffer data.
4DE3
LDIR ED B0
Execute LDIR (block transfer). Copy 32 bytes from the address originally in HL (command buffer position, now the source since EX DE,HL was done and then DE was overwritten — note: the source is actually from the original HL value stored before the EX DE,HL, which means HL was the source from the first EX) to 44A0H. After LDIR, DE points to 44C0H (just past the work area) and HL points 32 bytes past the original source position.
4DE5
LD HL,4FF7H 21 F7 4F
Point Register Pair HL to 4FF7H, the address of a default filename extension string within the overlay area. This string is used when no explicit extension is provided in the filespec.
4DE8
LD (44A3H),HL 22 A3 44
Store the value in Register Pair HL (4FF7H, the default extension string pointer) to memory at 44A3H. This sets up the pointer at 44A3H to reference the default extension string for use during filespec parsing.
4DEB
POP AF F1
Restore Register Pair AF from the stack. This retrieves previously saved flags and the A register value (which may contain a function parameter saved by the caller before the overlay was loaded).
4DEC
POP HL E1
Restore Register Pair HL from the stack. This retrieves a previously saved address (the continuation point or parameter pointer saved by the caller).
4DED
GOSUB to 4C7AH in SYS0. This is a utility routine that performs the main file relocation/positioning work. Returns Carry set on error, Z/NZ indicating the result state.
4DF0
RET C D8
If the CARRY FLAG has been set (the SYS0 routine at 4C7AH returned an error), RETURN immediately to the caller with the error condition propagated. The RELO command aborts.
4DF1
If the NZ FLAG has been set (the SYS0 routine succeeded but indicated additional processing is needed), GOSUB to 4E06H, the filename search/match routine. This scans the chain file data stream looking for a matching filename.
4DF4
RET NZ C0
If the NZ FLAG has been set (the filename search failed — no match was found), RETURN to the caller with the error condition. The RELO command cannot proceed without finding the target file.

The file was found successfully. Now update the system option flags to indicate chaining is active with the Y option, and conditionally set the D-option flag.

4DF5
LD HL,4289H 21 89 42
Point Register Pair HL to 4289H, the address of the first system option flags byte (containing bit 5 = chaining Y flag).
4DF8
SET 5,(HL) CB EE
Set bit 5 of the byte at (HL), which is 4289H. This sets the chaining Y flag, indicating that chaining is now active with the Y option enabled.
4DFA
INC HL 23
INCrement Register Pair HL by 1. HL now points to 428AH, the second system option flags byte (containing bit 6 = D-option valid flag, bit 4 = D-option selected flag).
4DFB
BIT 6,(HL) CB 76
Test bit 6 of the byte at (HL), which is 428AH. Bit 6 is the D-option valid flag. If this bit is 0, the Z FLAG is set (D-option is not valid); if 1, the NZ FLAG is set (D-option is valid).
4DFD
If the Z FLAG has been set (bit 6 of 428AH is 0, meaning D-option is not valid), JUMP to 4E01H to skip setting the D-option selected flag.
4DFF
SET 4,(HL) CB E6
Set bit 4 of the byte at (HL), which is 428AH. This sets the D-option selected flag, indicating the D option is both valid and now active.
4E01
XOR A AF
Set Register A to 0 by XORing it with itself. This sets the Z FLAG and clears the Carry flag.
4E02
LD (42C5H),A 32 C5 42
Store Register A (value 00H) to memory at 42C5H, the chaining saved-character byte. Clearing this to zero resets the chain file read state, indicating no character is currently saved/pending from a previous read operation.
4E05
RET C9
RETURN to the caller. The RELO command has completed successfully: the file data has been relocated, the chaining flags have been updated, and the chain read state has been reset.

4E06H – Filename Search/Match in Chain Data Stream

This routine searches through the chain file data stream for a filename that matches the string pointed to by Register HL. It reads bytes from the chain file via 4F50H, looking for an 80H marker byte that signals the start of a filename entry. When an 80H byte is found, the routine reads subsequent characters, converts them to uppercase via 4548H, and compares them against the corresponding characters in the match string at (HL). If all characters match and the final character is 0DH (indicating the end of the filename), the routine returns Z. If a mismatch is found, it resets HL to the start of the match string and continues scanning. Returns NZ on error or if the data stream ends without finding a match.

4E06
LD B,H 44
Copy Register H into Register B. This saves the high byte of HL (the match string pointer) into B for later restoration when the search needs to restart after a mismatch.
4E07
LD C,L 4D
Copy Register L into Register C. This saves the low byte of HL into C. Together, BC now holds a copy of the original match string pointer.

[LOOP START — Reset HL to start of match string] — On each mismatch, HL is restored from BC so the comparison restarts from the beginning of the match string.

4E08
LD H,B 60
Copy Register B into Register H. This restores the high byte of the match string pointer, resetting HL to point to the start of the match string for a new comparison attempt.
4E09
LD L,C 69
Copy Register C into Register L. HL now points to the start of the match string again.

[INNER LOOP — Scan for 80H marker byte]

4E0A
GOSUB to 4F50H, the read next character from chain file routine. Returns the next character in Register A with Z set on success, or NZ on error (end of file or read error).
4E0D
RET NZ C0
If the NZ FLAG has been set (error reading from the chain file — end of file or read error), RETURN with NZ set. The filename search has failed because the data stream ended without finding a match.
4E0E
CP 80H FE 80
Compare Register A (the character read from the chain file) against 80H. The value 80H is used as a filename entry marker in the chain data stream. If Register A equals 80H, the Z FLAG is set.
4E10
If the NZ FLAG has been set (the character is not 80H — not a filename marker), JUMP back to 4E0AH to continue reading bytes from the chain file, scanning for the next 80H marker.

Found an 80H marker. Now read and compare characters one at a time against the match string.

4E12
GOSUB to 4F50H to read the next character from the chain file following the 80H marker. This is the first (or next) character of the potential filename match.
4E15
RET NZ C0
If the NZ FLAG has been set (error reading from the chain file), RETURN with NZ set. The search has failed.
4E16
GOSUB to 4548H in SYS0, the convert to uppercase routine. Converts the character in Register A to uppercase if it is a lowercase letter.
4E19
CP (HL) BE
Compare Register A (the uppercase character from the chain file) against the byte at (HL) (the current character in the match string). If they are equal, the Z FLAG is set (match continues); if not equal, the NZ FLAG is set (mismatch).
4E1A
INC HL 23
INCrement Register Pair HL by 1, advancing the match string pointer to the next character regardless of whether the comparison matched.
4E1B
If the NZ FLAG has been set (the characters did not match — mismatch detected), JUMP back to 4E08H to reset HL to the start of the match string and continue scanning for the next 80H marker. [MISMATCH — restart search]

The characters matched. Check if this is the end of the filename (0DH terminator).

4E1D
CP 0DH FE 0D
Compare Register A (the matched character) against 0DH (carriage return). If the matched character is 0DH, the Z FLAG is set, meaning we have reached the end of the filename and all characters matched — the search is successful.
4E1F
If the NZ FLAG has been set (the matched character is not 0DH — there are more characters to compare), JUMP back to 4E12H to read and compare the next character from the chain file.
4E21
RET C9
RETURN with the Z FLAG set (from the CP 0DH comparison). The filename in the chain data stream matches the search string. The caller can now proceed knowing the target file was found.

4E22H – ROUTE Command Entry [SELF-MODIFYING CODE]

The ROUTE command manages I/O device routing in NEWDOS/80. This entry point contains self-modifying code: the instruction at 4E22H is initially LD A,0AH, but on first execution, the code at 4E26H overwrites the immediate operand byte at address 4E23H (the byte after the 3EH opcode) with the value 18H. This changes the instruction permanently to LD A,18H for all subsequent calls. The first invocation uses function code 0AH (initial route setup), and all later invocations use 18H (route continuation). After the self-modification, the routine sets the chaining active flag in 44A1H, then checks the system option flag at 428DH bit 7 to decide whether to perform a stack scan or jump directly to the main ROUTE processing loop.

4E22
LD A,0AH 3E 0A
[SELF-MODIFYING CODE — TARGET] Load Register A with 0AH (decimal 10). This is the initial function code used on the first invocation of the ROUTE command. The byte at address 4E23H (the immediate operand 0AH) will be overwritten by the instruction at 4E26H, changing this instruction to LD A,18H for all future calls.
4E24
LD A,18H 3E 18
Load Register A with 18H (decimal 24). This instruction executes immediately after the one above, so Register A is overwritten with 18H. The value 18H is the function code that will be used for all subsequent ROUTE invocations after the self-modification takes effect.
4E26
LD (4E22H),A 32 22 4E
[SELF-MODIFYING CODE — WRITE] Store Register A (value 18H) to memory at 4E22H. This is actually writing to address 4E23H in effect — wait, examining more carefully: the opcode 32H stores A to the address in the next two bytes. The address is 4E22H. But 4E22H contains the opcode 3EH (LD A,n). The byte at 4E22H is the 3EH opcode itself, and 4E23H is the operand. Writing 18H to 4E22H would overwrite the 3EH opcode. However, re-examining: the instruction at 4E22H is 3E 0A. Writing A (which is 18H) to address 4E22H would change the 3EH to 18H. But 18H is the opcode for JR d. This would transform the first instruction from LD A,0AH (3E 0A) into JR 4E2EH (18 0A). On all subsequent calls to 4E22H, the code would jump forward 0AH bytes to 4E2EH, skipping the initial setup entirely and going directly to the LD A,(428DH) instruction. Register A would then contain the byte from 428DH rather than a fixed function code.

[SELF-MODIFYING CODE ANALYSIS]: The first time 4E22H is called, the instructions execute sequentially: LD A,0AH → LD A,18H → LD (4E22H),A. The LD (4E22H),A writes 18H to address 4E22H, changing the byte from 3EH to 18H. On all subsequent calls, 4E22H now contains 18H 0AH, which is JR 4E2EH (jump forward +0AH from the address of the next instruction, 4E24H, giving 4E2EH). This means the LD A,18H and LD (4E22H),A instructions are skipped on subsequent calls, and execution jumps directly to 4E2EH.

4E29
LD HL,44A1H 21 A1 44
Point Register Pair HL to 44A1H, the second byte of the 32-byte work area. Bit 5 of this byte is the route active flag.
4E2C
SET 5,(HL) CB EE
Set bit 5 of the byte at (HL), which is 44A1H. This sets the route active flag, indicating that the ROUTE command's I/O redirection is now engaged.
4E2E
LD A,(428DH) 3A 8D 42
Fetch the system option flags byte at 428DH into Register A. Bit 7 of this byte controls whether the ROUTE command performs a stack scan (bit 7 = 0) or jumps directly to the main processing loop (bit 7 = 1).
4E31
BIT 7,A CB 7F
Test bit 7 of Register A (the byte from 428DH). If bit 7 is 0, the Z FLAG is set (stack scan mode); if bit 7 is 1, the NZ FLAG is set (direct processing mode).
4E33
If the NZ FLAG has been set (bit 7 of 428DH is 1, meaning stack scan is not required), JUMP to 4E57H to go directly to the main ROUTE processing loop.

4E35H – ROUTE Stack Scan for Return Address Validation

When bit 7 of 428DH is 0, the ROUTE command scans the stack looking for a specific return address pattern that indicates the call came from a known DOS-CALL context. The scan examines up to 10 word-sized entries on the stack, looking for the byte pair 94H followed by 06H (which represents a return address within SYS0). If found, it then checks bytes at offset +0CH from that position for the pair E3H/05H. If the full pattern is found, execution continues to the main ROUTE processing at 4E57H. If the pattern is not found after scanning 10 entries, the routine exits with OR 01H (setting NZ and bit 0 of A) at 4E7BH.

4E35
LD B,0AH 06 0A
Load Register B with 0AH (decimal 10). This is the maximum number of stack entries to scan. B serves as a countdown counter for the stack search loop.
4E37
LD HL,FFFFH 21 FF FF
Load Register Pair HL with FFFFH (65535 decimal, which is -1 in two's complement). This will be added to the stack pointer to position HL one byte below the current SP, setting up for stack scanning.
4E3A
ADD HL,SP 39
ADD the Stack Pointer to Register Pair HL. Since HL was FFFFH (-1), the result is SP-1, positioning HL to point one byte below the top of the stack. This is the starting point for the downward scan through stacked return addresses.

[LOOP START — Stack scan loop] Scan up to 10 stack entries looking for the byte pattern 94H followed by 06H.

4E3B
DEC B 05
DECrement Register B (the stack scan counter) by 1. If B reaches 0, the Z FLAG is set, meaning all 10 entries have been scanned without finding the pattern.
4E3C
If the Z FLAG has been set (B reached 0 — all 10 stack entries scanned without a match), JUMP to 4E7BH to exit with a failure indication (OR 01H sets NZ). The ROUTE command cannot validate its call context.
4E3E
INC HL 23
INCrement Register Pair HL by 1, advancing the stack scan pointer to the next byte on the stack.
4E3F
LD A,(HL) 7E
Fetch the byte at the current stack scan position (pointed to by HL) into Register A. This byte is part of a stacked return address.
4E40
CP 94H FE 94
Compare Register A against 94H. This is the first byte of the return address pattern being searched for. If A equals 94H, the Z FLAG is set.
4E42
INC HL 23
INCrement Register Pair HL by 1 to point to the next byte, regardless of whether the comparison matched. This advances past the current byte.
4E43
If the NZ FLAG has been set (the byte was not 94H), JUMP back to 4E3BH to decrement the counter and continue scanning the next stack entry.

Found 94H. Check if the next byte is 06H to confirm the full 2-byte pattern.

4E45
LD A,(HL) 7E
Fetch the next byte from the stack scan position into Register A. HL was incremented past the 94H byte, so this reads the byte that follows it.
4E46
CP 06H FE 06
Compare Register A against 06H. Combined with the previous 94H match, the 2-byte pattern 94H/06H represents the return address 0694H (stored low-byte-first on the stack). If A equals 06H, the Z FLAG is set — the pattern is confirmed.
4E48
If the NZ FLAG has been set (the second byte was not 06H — false match on the first byte), JUMP back to 4E3BH to continue scanning.

Found the 94H/06H pattern (return address 0694H). Now verify a secondary pattern at offset +0CH from the current position.

4E4A
LD DE,000CH 11 0C 00
Load Register Pair DE with 000CH (decimal 12). This is the offset from the current stack position to the secondary verification bytes.
4E4D
ADD HL,DE 19
ADD Register Pair DE (000CH) to HL, advancing the pointer 12 bytes forward from the 06H byte. HL now points to the secondary verification location on the stack.
4E4E
LD A,(HL) 7E
Fetch the byte at the secondary verification position (HL + 0CH from the 06H byte) into Register A.
4E4F
CP 05H FE 05
Compare Register A against 05H. This is the first byte of the secondary pattern. If A equals 05H, the Z FLAG is set.
4E51
DEC HL 2B
DECrement Register Pair HL by 1, moving back one byte to read the byte that precedes the 05H position.
4E52
RET NZ C0
If the NZ FLAG has been set (the byte at offset +0CH was not 05H — secondary pattern does not match), RETURN with NZ set. The stack does not contain the expected call context pattern.
4E53
LD A,(HL) 7E
Fetch the byte at (HL) (the position one byte before the 05H byte) into Register A. This is the second byte of the secondary verification pattern.
4E54
CP E3H FE E3
Compare Register A against E3H. The pair E3H/05H (at this position and the next) forms the second half of the full stack context signature. If A equals E3H, the Z FLAG is set, confirming the full pattern has been found.
4E56
RET NZ C0
If the NZ FLAG has been set (the byte preceding 05H was not E3H — full pattern not confirmed), RETURN with NZ set. The stack scan has failed validation.

The full stack pattern has been verified (94H/06H at one position, E3H/05H at offset +0BH/+0CH). The ROUTE command was called from a recognized DOS-CALL context. Fall through to the main ROUTE processing loop at 4E57H.

4E57H – ROUTE Command Main Processing Loop

This is the main processing loop for the ROUTE command's chain file execution. It first checks for a BREAK key condition, then reads characters from the chain file and dispatches them based on their value. Characters with code 80H trigger a chain reset. Characters 81H–83H are special chain commands (81H–83H after subtracting 80H give 01H–03H). Characters 84H and 85H trigger additional processing. Regular printable characters in the range 01H–7FH are echoed to the display if bit 0 of Register B is set. The loop processes the entire chain file until an error, end-of-file, or explicit stop condition is encountered.

4E57
LD A,(428DH) 3A 8D 42
Fetch the system option flags byte at 428DH into Register A. Bit 6 of this byte is the BREAK key enable flag for chaining operations.
4E5A
AND 40H E6 40
AND Register A with 40H (binary 01000000), isolating bit 6 (the BREAK key enable flag). If bit 6 is 0, the result is zero and the Z FLAG is set (BREAK checking is disabled). If bit 6 is 1, the result is non-zero and the NZ FLAG is set (BREAK checking is enabled).
4E5C
If the Z FLAG has been set (bit 6 of 428DH is 0 — BREAK key checking is disabled), JUMP to 4E66H to skip the BREAK key test and proceed directly to the chain file read.
4E5E
LD A,(3840H) 3A 40 38
Fetch the byte from keyboard memory-mapped address 3840H into Register A. This reads keyboard row 6 which contains: ENTER (bit 0), CLEAR (bit 1), BREAK (bit 2), UP (bit 3), DOWN (bit 4), LEFT (bit 5), RIGHT (bit 6), SPACE (bit 7). Active low — a 0 bit means the key is pressed.
4E61
AND 40H E6 40
AND Register A with 40H (binary 01000000), isolating bit 6 (the RIGHT ARROW key). Active low: if bit 6 is 0, the key IS pressed and the result is zero (Z set). If bit 6 is 1, the key is NOT pressed and the result is non-zero (NZ set). Note: this is actually testing bit 6 which is the RIGHT key in the keyboard matrix.
4E63
If the NZ FLAG has been set (bit 6 is 1 — the key is NOT pressed, meaning this particular key condition indicates a BREAK/pause request), JUMP to 4F03H to display "CHAINING PAUSE" and wait for the user to acknowledge.

No BREAK/pause condition detected. Check for the SHIFT+DOWN ARROW combination and then read the next character from the chain file.

4E66
GOSUB to 4ED3H, the check SHIFT+DOWN ARROW routine. This reads keyboard row 3840H bit 3 (UP ARROW key) and checks system option bit 6 at 428DH. Returns Z if the key combination is not active or not enabled; returns NZ (with A=0) if the combination is detected.
4E69
LD A,(42C5H) 3A C5 42
Fetch the chaining saved-character byte from 42C5H into Register A. If this byte is non-zero, a character was previously read from the chain file but not yet consumed (it was "pushed back"). If zero, no character is pending.
4E6C
OR A B7
OR Register A with itself to test whether the saved character byte is zero or non-zero. If A is 0, the Z FLAG is set (no saved character); if A is non-zero, the NZ FLAG is set (a saved character is pending).
4E6D
If the NZ FLAG has been set (42C5H contains a non-zero saved character), JUMP to 4E90H to process that saved character instead of reading a new one from the chain file.
4E6F
GOSUB to 4F50H, the read next character from chain file routine. Returns the next character in Register A with Z set on success, or NZ with an error code in A on failure.
4E72
If the Z FLAG has been set (character read successfully), JUMP to 4E90H to process the character.

The chain file read returned an error (NZ). Check if it is error 1CH (position before start of file), which is a recoverable condition.

4E74
CP 1CH FE 1C
Compare Register A (the error code from 4F50H) against 1CH (decimal 28), the NEWDOS/80 error code for Position Error — before start of file. If A equals 1CH, the Z FLAG is set.
4E76
If the NZ FLAG has been set (the error is NOT 1CH — it is a different, unrecoverable error), JUMP to 4EE0H, the chain error handler, which displays "CHAINING ABORTED" and exits.

The error is 1CH (before start of file). This means the chain file has been fully consumed. Reset the chaining state and return with NZ.

4E78
GOSUB to 4EC5H, the reset chaining state routine. This clears byte at 44A0H to 00H, resets bit 5 of (4289H) and bit 4 of (428AH), fully deactivating chaining.
4E7B
OR 01H F6 01
OR Register A with 01H. This sets bit 0 of A and clears the Z flag (sets NZ). The result is always non-zero, so the NZ condition signals to the caller that chaining has ended or the stack scan failed.
4E7D
RET C9
RETURN to the caller with NZ set, indicating chaining has terminated (either end of chain file or stack scan failure).

4E7EH – Chain Command Y/N/D Option Processing

This routine is called when the chain file contains a command that requires a Y/N/D option (such as CHNON,Y or CHNON,N). It calls the Y/N/D parser at 4D82H to read the option from the chain data, then calls 511BH for final ROUTE status checking. Based on the result, it either returns with failure or loops back to the main ROUTE processing at 4E57H.

4E7E
GOSUB to 4D82H, the Y/N/D option parser. This reads the next character from the position pointed to by HL, converts it to uppercase, and sets the appropriate system option flag bits. Returns Z on success, NZ on failure.
4E81
If the NZ FLAG has been set (the Y/N/D parser failed — invalid character or unterminated command), JUMP to 4F2EH which loads error code 01H and jumps to the chain error handler at 4EE0H.
4E84
LD A,(42C5H) 3A C5 42
Fetch the chaining saved-character byte from 42C5H into Register A. This value is passed to the 511BH routine for final status checking.
4E87
GOSUB to 511BH, the ROUTE final check routine. This tests whether A is zero, then examines bits 4 and 6 of Register B to determine the proper exit path. Returns Z if the route should be terminated, NZ if it should continue.
4E8A
BIT 5,C CB 69
Test bit 5 of Register C (which still holds the updated option flags from the Y/N/D parser — bit 5 is the chaining Y flag). If bit 5 is 0, the Z FLAG is set (chaining Y is OFF — the user chose N); if bit 5 is 1, the NZ FLAG is set (chaining Y is ON).
4E8C
If the Z FLAG has been set (bit 5 of C is 0 — chaining Y is OFF, meaning the user selected N to stop chaining), JUMP to 4E7BH to exit with OR 01H (NZ set), indicating chaining has been deactivated.
4E8E
JUMP unconditionally to 4E57H to return to the main ROUTE processing loop and continue reading from the chain file. Chaining Y is still ON, so processing continues.

4E90H – Chain Character Dispatcher

This routine receives a character from the chain file (either freshly read or retrieved from the saved-character byte at 42C5H) and dispatches it based on its value. The character is saved in both Registers B and C. After clearing the saved-character byte, it subtracts 80H to classify: 80H (result 0) triggers a chain reset; 81H–83H (result 01H–03H) triggers character echo/pass-through; 84H–85H (result 04H–05H) triggers special command processing; 86H+ triggers line input from the chain file.

4E90
LD B,A 47
Copy Register A (the chain file character or saved character) into Register B. B preserves the original character value throughout the dispatch processing.
4E91
LD C,A 4F
Copy Register A into Register C. C also preserves the character value for later bit testing.
4E92
XOR A AF
Set Register A to 0 by XORing it with itself. This also sets the Z FLAG.
4E93
LD (42C5H),A 32 C5 42
Store Register A (value 00H) to the chaining saved-character byte at 42C5H. This clears any pending saved character, since we are now processing the character that was in A.
4E96
LD A,B 78
Copy Register B (the original character) back into Register A for classification.
4E97
SUB 80H D6 80
SUBtract 80H from Register A. This classifies the character: if the original was 80H, A is now 0 (Z set). If it was 81H–83H, A is 01H–03H. If 84H–85H, A is 04H–05H. If 86H+, A is 06H+. Characters below 80H would result in a borrow (negative result), which sets the Carry flag.
4E99
If the Z FLAG has been set (the character was exactly 80H — the chain section end marker), JUMP to 4E78H to reset the chaining state and return. Character 80H signals the end of a chaining section.
4E9B
CP 04H FE 04
Compare Register A (character minus 80H) against 04H. Characters 81H–83H (A = 01H–03H) are below 04H and will have the CARRY FLAG set. Characters 84H+ (A >= 04H) will have NO CARRY.
4E9D
If the CARRY FLAG has been set (A < 04H, meaning the original character was 81H, 82H, or 83H — printable character pass-through codes), JUMP to 4EEEH to process the character as a display/echo operation.
4E9F
CP 06H FE 06
Compare Register A (character minus 80H) against 06H. Characters 84H–85H (A = 04H–05H) are below 06H and will have the CARRY FLAG set. Characters 86H+ (A >= 06H) will have NO CARRY.
4EA1
If the CARRY FLAG has been set (A is 04H or 05H, meaning the original character was 84H or 85H — special chain commands), JUMP to 4F1BH to process the line input from chain file routine.

The character code is 86H or higher (A >= 06H after subtracting 80H). Read the next character, save it, and check for chain section boundaries.

4EA4
GOSUB to 4F50H, the read next character from chain file. Returns the next character in A with Z on success, NZ on error.
4EA7
LD (42C5H),A 32 C5 42
Store Register A (the character just read, or the error code) to the chaining saved-character byte at 42C5H. This saves the character for processing on the next iteration of the main loop.
4EAA
If the NZ FLAG has been set (error reading from chain file), JUMP to 4EB0H to check if the error is recoverable (1CH) or fatal.
4EAC
CP 80H FE 80
Compare Register A (the successfully read character) against 80H (the chain section end marker). If A equals 80H, the Z FLAG is set.
4EAE
JUMP unconditionally to 4EB4H. If A was 80H, Z is set and the CALL Z at 4EB4H will execute the chaining reset. If A was not 80H, NZ is set and the call is skipped.
4EB0
CP 1CH FE 1C
Compare Register A (the error code) against 1CH (Position Error — before start of file). If A equals 1CH, the Z FLAG is set (recoverable end-of-chain condition).
4EB2
If the NZ FLAG has been set (the error is NOT 1CH — it is a fatal error), JUMP to 4EE0H, the chain error handler.
4EB4
If the Z FLAG has been set (either the character was 80H or the error was 1CH — both indicating end of chain section), GOSUB to 4EC5H to reset the chaining state. This clears the active flags in 44A0H, 4289H, and 428AH.
4EB7
CP 85H FE 85
Compare Register A against 85H. The value 85H is a special chain command code that triggers the CHNON,Y handler at 4F16H. If A equals 85H, the Z FLAG is set.
4EB9
If the Z FLAG has been set (character is 85H — the CHNON continuation command), JUMP to 4F16H to process the chain continuation by saving the current state and starting a new input line.
4EBC
LD A,B 78
Copy Register B (the original character from before the 80H subtraction) back into Register A.
4EBD
CP A BF
Compare Register A with itself. This always sets the Z FLAG and clears the Carry flag. This is a compact way to return with Z set (success/continue), indicating the character has been fully processed.
4EBE
RET C9
RETURN with Z flag set, indicating the chain character has been processed and the caller should continue.

4EBFH – Display "CHAINING ABORTED" Message

This routine displays the "CHAINING ABORTED" message by first calling 4F45H (which displays "CHAINING " as a prefix, then displays the message pointed to by HL). It then falls through to 4EC5H to reset the chaining state flags.

4EBF
LD HL,4FA2H 21 A2 4F
Point Register Pair HL to 4FA2H, the address of the text string "ABORTED" (terminated by 0DH at 4FA9H). This will be displayed as the second part of the message, following the "CHAINING " prefix.
4EC2
GOSUB to 4F45H, the display two-part chaining message routine. This first displays "CHAINING " from the string at 4F98H, then displays the string pointed to by HL ("ABORTED"). The combined output is "CHAINING ABORTED".

4EC5H – Reset Chaining State Flags

This routine clears all chaining-related state flags: it zeroes the byte at 44A0H (the work area status byte), clears bit 5 of (4289H) (the chaining Y flag), and clears bit 4 of (428AH) (the D-option selected flag). This fully deactivates the chaining system.

4EC5
LD HL,44A0H 21 A0 44
Point Register Pair HL to 44A0H, the first byte of the 32-byte work area. This byte holds the chain file status flags.
4EC8
LD (HL),00H 36 00
Store 00H to the byte at (HL), which is 44A0H. This clears all chain file status flags, marking the chain file as inactive.
4ECA
LD HL,4289H 21 89 42
Point Register Pair HL to 4289H, the system option flags byte containing the chaining Y flag at bit 5.
4ECD
RES 5,(HL) CB AE
Clear bit 5 of the byte at (HL), which is 4289H. This resets the chaining Y flag, indicating chaining is no longer active in Y mode.
4ECF
INC HL 23
INCrement Register Pair HL by 1. HL now points to 428AH, the second system option flags byte containing the D-option selected flag at bit 4.
4ED0
RES 4,(HL) CB A6
Clear bit 4 of the byte at (HL), which is 428AH. This resets the D-option selected flag, indicating the D option is no longer active.
4ED2
RET C9
RETURN to the caller. All chaining state flags have been cleared.

4ED3H – Check for SHIFT+DOWN ARROW Key Combination

This utility routine checks whether the SHIFT+DOWN ARROW key combination is currently pressed and whether the system option at 428DH bit 6 enables this check. It reads keyboard row 3840H and tests bit 3 (the UP ARROW key position in the keyboard matrix). If the key is pressed (bit is 0, active low) AND the system option bit 6 at 428DH is set, the routine returns NZ with A=0. Otherwise it returns Z. This key combination is used as a user-initiated pause or intervention during chaining.

4ED3
LD A,(3840H) 3A 40 38
Fetch the byte from keyboard memory-mapped address 3840H into Register A. This reads keyboard row 6: ENTER (bit 0), CLEAR (bit 1), BREAK (bit 2), UP (bit 3), DOWN (bit 4), LEFT (bit 5), RIGHT (bit 6), SPACE (bit 7). Active low — a 0 bit means the key IS pressed.
4ED6
AND 08H E6 08
AND Register A with 08H (binary 00001000), isolating bit 3 (the UP ARROW key). If bit 3 is 0 (key IS pressed, active low), the result is 0 and the Z FLAG is set. If bit 3 is 1 (key is NOT pressed), the result is 08H and the NZ FLAG is set.
4ED8
RET Z C8
If the Z FLAG has been set (bit 3 is 0 — the UP ARROW key IS pressed), RETURN with Z set. Note: despite the routine's name, this returns Z when the key IS detected, which the caller treats as "no action needed." The active-low logic means the AND result is 0 when the key is pressed.

Bit 3 was 1 (key is NOT pressed, result was 08H/NZ). Now check if the system option enables this key check.

4ED9
LD A,(428DH) 3A 8D 42
Fetch the system option flags byte at 428DH into Register A. Bit 6 controls whether the SHIFT+DOWN ARROW check is enabled.
4EDC
AND 40H E6 40
AND Register A with 40H (binary 01000000), isolating bit 6 (the key-check enable flag). If bit 6 is 0, the result is 0 and the Z FLAG is set (check disabled). If bit 6 is 1, the result is 40H and the NZ FLAG is set (check enabled).
4EDE
RET Z C8
If the Z FLAG has been set (bit 6 of 428DH is 0 — the key check is disabled), RETURN with Z set. The caller sees Z and takes no action.

Both conditions are met: the key is not pressed (bit 3 was 1) AND the key check is enabled (bit 6 of 428DH is 1). The NZ result from AND 40H is still active. Fall through with NZ set. The next instruction (XOR A at 4EDFH) sets A=0 but note: the code flow here actually falls through to 4EDFH only when both conditions pass.

4EDF
XOR A AF
Set Register A to 0 by XORing it with itself. This sets the Z FLAG. However, this is actually the start of the chain error path at 4EDFH–4EE0H — when the SHIFT+DOWN check falls through here, it transitions into the error handler. The XOR A provides A=0 as an error code indicating user intervention, and the PUSH AF at 4EE0H saves it.

4EE0H – Chain Error Handler

This is the common error handler for chaining operations. It saves the error code in Register A, calls 4EBFH to display "CHAINING ABORTED" and reset the chaining state, restores the error code, and then dispatches to the appropriate DOS exit: if A is zero, it jumps to the no-error exit at 4030H (error already displayed); if A is non-zero, it jumps to the error exit at 4409H to display the error message. Note that the entry at 4EDFH (XOR A; fall through) and 4EE0H (PUSH AF) form two different entry paths.

4EE0
PUSH AF F5
Save Register A (the error code or chain character) and the flags onto the stack. This preserves the error code while the "CHAINING ABORTED" message is displayed.
4EE1
PUSH AF F5
Save Register AF onto the stack a second time. Two copies are pushed because the CALL to 4EBFH may alter the stack depth, and both POPs at 4EE5H–4EE6H need to restore the original value reliably.
4EE2
GOSUB to 4EBFH, the display "CHAINING ABORTED" routine. This displays the two-part message "CHAINING ABORTED" on the video screen and resets all chaining state flags (clears 44A0H, resets bit 5 of 4289H, resets bit 4 of 428AH).
4EE5
POP AF F1
Restore Register AF from the stack (first of two POPs). This retrieves the saved error code.
4EE6
POP AF F1
Restore Register AF from the stack (second POP). This retrieves the original error code that was pushed at 4EE0H, ensuring A contains the correct error value.
4EE7
OR A B7
OR Register A with itself to test if the error code is zero or non-zero. If A is 0, the Z FLAG is set (no specific error code — the error message was already displayed or this is a user-initiated abort). If A is non-zero, the NZ FLAG is set (a specific error code needs to be displayed).
4EE8
If the Z FLAG has been set (error code is 0 — the error has already been displayed or no error code applies), JUMP to 4030H in SYS0, the error-already-displayed DOS exit. This is a dead-end routine that returns to the DOS command prompt without displaying an additional error message.
4EEB
JUMP to 4409H in SYS0, the DOS error exit. Register A contains the non-zero error code. This routine will display the corresponding NEWDOS/80 error message and return to the DOS command prompt.

4EEEH – Chain Character Echo / Pass-Through Loop

This routine handles characters 81H–83H from the chain dispatch. These characters represent printable text that should be read from the chain file and optionally echoed to the display. The loop reads characters one at a time from the chain file via 4F50H, conditionally displays each character via the ROM display routine at 0033H (if bit 0 of Register B is set), and continues until a 0DH (carriage return) terminator is found. After the line is complete, it checks if the original chain command was 81H and if so, enters the PAUSE handler. Otherwise, it returns to the main ROUTE processing loop at 4E57H.

[LOOP START — Read and echo characters from chain file]

4EEE
GOSUB to 4F50H, the read next character from chain file routine. Returns the next character in Register A with Z set on success, or NZ with an error code in A on failure.
4EF1
If the NZ FLAG has been set (error reading from chain file), JUMP to 4EE0H, the chain error handler, to display "CHAINING ABORTED" and exit.
4EF3
PUSH AF F5
Save Register A (the character just read from the chain file) and the flags onto the stack. This preserves the character while we check whether to display it.
4EF4
BIT 0,B CB 40
Test bit 0 of Register B. Register B holds the original chain command code (81H, 82H, or 83H from before the dispatch). Bit 0 indicates whether to echo characters to the display: if bit 0 is 1 (codes 81H and 83H), characters are echoed; if bit 0 is 0 (code 82H), characters are not echoed.
4EF6
If the NZ FLAG has been set (bit 0 of B is 1 — echo is enabled), GOSUB to ROM routine at 0033H, the display character routine. Register A contains the character to display. This outputs the character to the video screen at the current cursor position and advances the cursor.
4EF9
POP AF F1
Restore Register A (the chain file character) from the stack.
4EFA
CP 0DH FE 0D
Compare Register A (the chain file character) against 0DH (ASCII carriage return / ENTER). If A equals 0DH, the Z FLAG is set, meaning the end of the text line has been reached.
4EFC
If the NZ FLAG has been set (the character was not 0DH — there are more characters in the line), JUMP back to 4EEEH to read and process the next character. [LOOP END]

The 0DH terminator has been found — the text line is complete. Now check if the original chain command was 81H, which requires a PAUSE after display.

4EFE
LD A,B 78
Copy Register B (the original chain command code: 81H, 82H, or 83H) into Register A for comparison.
4EFF
CP 81H FE 81
Compare Register A against 81H. Chain command 81H means "display text and then pause." If A equals 81H, the Z FLAG is set.
4F01
If the NZ FLAG has been set (the command was 82H or 83H — not the pause variant), JUMP to 4F13H to return to the main ROUTE processing loop without pausing.

4F03H – Chaining PAUSE Handler

This routine displays the "CHAINING PAUSE" message (the prefix "CHAINING " followed by "PAUSE. PRESS 'ENTER' WHEN READY TO CONTINUE"), then enters a loop waiting for the user to release a specific key. The loop calls the SHIFT+DOWN ARROW check at 4ED3H and reads keyboard row 3840H testing bit 0 (the @/ENTER key area). When the key condition is met (bit 0 of 3840H becomes non-zero, meaning the key is released), the routine exits to the main ROUTE processing loop at 4E57H.

4F03
LD HL,4FAAH 21 AA 4F
Point Register Pair HL to 4FAAH, the address of the text string "PAUSE. PRESS 'ENTER' WHEN READY TO CONTINUE" (terminated by 0DH). This is the second part of the pause message, after the "CHAINING " prefix.
4F06
GOSUB to 4F45H, the display two-part chaining message routine. This first displays "CHAINING " from the string at 4F98H, then displays the message at HL. The combined output is "CHAINING PAUSE. PRESS 'ENTER' WHEN READY TO CONTINUE".

[LOOP START — Wait for key release] Loop until the ENTER key area shows the key is released (active low, so bit 0 becoming non-zero means release).

4F09
GOSUB to 4ED3H, the check SHIFT+DOWN ARROW routine. This monitors the keyboard for the user intervention key combination during the pause wait.
4F0C
LD A,(3840H) 3A 40 38
Fetch the byte from keyboard memory-mapped address 3840H into Register A. This reads keyboard row 6: ENTER (bit 0), CLEAR (bit 1), BREAK (bit 2), UP (bit 3), DOWN (bit 4), LEFT (bit 5), RIGHT (bit 6), SPACE (bit 7).
4F0F
AND 01H E6 01
AND Register A with 01H (binary 00000001), isolating bit 0 (the ENTER key). Active low: if bit 0 is 0, ENTER IS pressed and the result is 0 (Z set). If bit 0 is 1, ENTER is NOT pressed and the result is 01H (NZ set).
4F11
If the Z FLAG has been set (bit 0 is 0 — ENTER key IS still pressed or no key is pressed), JUMP back to 4F09H to continue waiting. [LOOP END] The loop exits when ENTER is released (bit 0 becomes 1).
4F13
JUMP to 4E57H to return to the main ROUTE processing loop and continue reading from the chain file.

4F16H – CHNON Continuation Processing (Chain Command 85H)

This routine handles chain command code 85H, which signals a CHNON (chain on/off) continuation. It saves the current command code into Register C, saves Register B (the original character) to the chaining saved-character byte at 42C5H, and then falls through to the line input routine at 4F1BH. This preserves the chain state so that after the line input is processed, chaining can continue from where it left off.

4F16
LD C,A 4F
Copy Register A (value 85H, the CHNON continuation command code) into Register C. C preserves this value for later use in determining how to process the completed line input (bit 0 of C is tested at 4F33H).
4F17
LD A,B 78
Copy Register B (the original chain character from before it was classified in the dispatcher at 4E90H) into Register A.
4F18
LD (42C5H),A 32 C5 42
Store Register A (the original character from B) to the chaining saved-character byte at 42C5H. This "pushes back" the character so it can be re-read on the next chain file access. The current character is preserved because the following line-input routine will consume additional characters from the chain file.

4F1BH – Line Input from Chain File into Buffer

This routine reads a line of text from the chain file into a buffer at 4FD7H. It reads up to 32 characters (20H), storing each one and checking for the 0DH (carriage return) terminator. If the line is successfully read (terminated by 0DH within 32 characters), the routine dispatches based on bit 0 of Register C: if bit 0 is set (from CHNON processing at 4F16H), it jumps to the Y/N/D option handler at 4E7EH; if bit 0 is clear, it processes the line as a DOS command by positioning the file and searching for a filename match. If the chain file read fails or the line exceeds 32 characters, the chain error handler at 4EE0H is invoked.

4F1B
LD B,20H 06 20
Load Register B with 20H (decimal 32). This is the maximum number of characters to read from the chain file for this line. B serves as a countdown counter.
4F1D
LD HL,4FD7H 21 D7 4F
Point Register Pair HL to 4FD7H, the address of the line input buffer within the overlay area. Characters read from the chain file will be stored here.
4F20
PUSH HL E5
Save Register Pair HL (the buffer start address 4FD7H) onto the stack. This preserves the buffer start for later use after the read loop completes.

[LOOP START — Read characters from chain file into buffer]

4F21
GOSUB to 4F50H, the read next character from chain file routine. Returns the next character in Register A with Z set on success, or NZ on error.
4F24
If the NZ FLAG has been set (error reading from chain file), JUMP to 4EE0H, the chain error handler.
4F26
CP 0DH FE 0D
Compare Register A (the character read) against 0DH (carriage return / ENTER). If A equals 0DH, the Z FLAG is set, indicating end of line.
4F28
LD (HL),A 77
Store Register A (the character, including the 0DH terminator if present) to the buffer at the position pointed to by HL. Every character read is stored, including the terminator.
4F29
INC HL 23
INCrement Register Pair HL by 1, advancing the buffer write pointer to the next position.
4F2A
If the Z FLAG has been set (the character stored was 0DH — end of line), JUMP to 4F32H to process the completed line.
4F2C
DECrement B and JUMP to 4F21H if B is not zero. This continues the read loop for the next character, up to a maximum of 32 characters. [LOOP END on DJNZ]

The loop counter B reached zero without finding a 0DH terminator — the line exceeds 32 characters. This is an error.

4F2E
LD A,01H 3E 01
Load Register A with 01H. This is a non-zero error indicator passed to the chain error handler. It does not correspond to a specific NEWDOS/80 error code — it simply indicates a chain file format error (line too long).
4F30
JUMP to 4EE0H, the chain error handler, to display "CHAINING ABORTED" and exit with the error code in A.

The line was successfully read (terminated by 0DH within 32 characters). Retrieve the buffer start address and dispatch based on the command type.

4F32
POP HL E1
Restore Register Pair HL from the stack. HL now holds 4FD7H, the start address of the line input buffer containing the text just read from the chain file.
4F33
BIT 0,C CB 41
Test bit 0 of Register C. If the line input was initiated from the CHNON handler at 4F16H, C holds 85H (bit 0 = 1). If initiated from the chain character dispatcher for codes 84H–85H directly at 4F1BH via 4EA1H, C holds the character from 4E91H. Bit 0 determines the processing path.
4F35
If the NZ FLAG has been set (bit 0 of C is 1 — this is a CHNON command requiring Y/N/D option processing), JUMP to 4E7EH to parse the Y/N/D option from the buffered line.

Bit 0 of C is 0. The line contains a DOS command or filename to process. Position the file to the start and search for a matching filename.

4F38
LD DE,44A0H 11 A0 44
Load Register Pair DE with 44A0H, the address of the FCB work area. DE is passed to the DOS file position routine as the FCB pointer.
4F3B
GOSUB to 443FH in SYS0, the position FCB to start of file routine. DE points to the FCB at 44A0H. This resets the file position to the beginning so the filename search can scan from the start.
4F3E
If the Z FLAG has been set (the file position was set successfully), GOSUB to 4E06H, the filename search/match routine. HL points to the line input buffer at 4FD7H containing the name to search for. The routine scans the chain file data for a matching filename entry.
4F41
If the NZ FLAG has been set (either the file positioning failed or the filename search did not find a match), JUMP to 4EE0H, the chain error handler.
4F43
JUMP unconditionally to 4F13H, which jumps to 4E57H to return to the main ROUTE processing loop. The filename was found and the chain file position is now set correctly for continued reading.

4F45H – Display Two-Part Chaining Message

This utility routine displays a two-part message: first the "CHAINING " prefix string from 4F98H, then the message pointed to by HL on entry. It preserves HL across the first display call and then displays the second part. Used by the "CHAINING ABORTED" and "CHAINING PAUSE..." message routines.

4F45
PUSH HL E5
Save Register Pair HL (the pointer to the second part of the message, e.g., "ABORTED" or "PAUSE...") onto the stack. HL is preserved while the "CHAINING " prefix is displayed.
4F46
LD HL,4F98H 21 98 4F
Point Register Pair HL to 4F98H, the address of the text string "CHAINING " (8 characters plus a trailing space, terminated by 03H). This is the prefix that precedes all chaining status messages.
4F49
GOSUB to 4467H in SYS0, the send message to video display routine. HL points to "CHAINING ". The routine displays characters until it encounters a 03H terminator. After the call, "CHAINING " has been displayed on the screen.
4F4C
POP HL E1
Restore Register Pair HL from the stack. HL now points to the second part of the message (e.g., "ABORTED" at 4FA2H or "PAUSE..." at 4FAAH).
4F4D
JUMP to 4467H in SYS0 to display the second part of the message. Since this is a JP (not a CALL), the RET inside 4467H will return directly to the caller of 4F45H. The combined display output is "CHAINING " followed by the message text.

4F50H – Read Next Character from Chain File (High-Level)

This is the high-level chain file character reader. It calls the low-level reader at 4F8CH to get the next byte, then checks if the character is a slash (2FH) which introduces an embedded command sequence. Embedded commands have the format /x.y/n where x is checked against the current position byte at 44A5H, y is a separator (2EH = period), and n is a drive/section number (ASCII digit). If the slash sequence is recognized as an embedded command, the routine processes the position change and returns the adjusted character. If the slash is not followed by a valid command sequence, the routine falls back to normal character return. Register BC is preserved across the call.

4F50
GOSUB to 4F8CH, the low-level chain file character reader. Returns the next non-null character from the chain file in Register A with Z set on success, or NZ with an error code on failure.
4F53
RET NZ C0
If the NZ FLAG has been set (error reading from chain file), RETURN immediately with the error code in A and NZ set. The caller will handle the error.
4F54
PUSH BC C5
Save Register Pair BC onto the stack. BC is preserved across the embedded command parsing that follows, since B and C are used as temporary working registers.
4F55
CP 2FH FE 2F
Compare Register A (the character read) against 2FH (ASCII slash /). The slash character introduces an embedded command sequence in the chain file. If A equals 2FH, the Z FLAG is set.
4F57
LD B,A 47
Copy Register A (the character read) into Register B. B preserves the original character for later comparison and return.
4F58
LD A,(44A5H) 3A A5 44
Fetch the current position byte from 44A5H into Register A. This byte tracks the current position within the chain file record and is used to verify embedded command sequences.
4F5B
LD C,A 4F
Copy Register A (the position byte from 44A5H) into Register C. C preserves the starting position value for later comparison and difference calculation.
4F5C
If the Z FLAG has been set (the character was a slash 2FH), GOSUB to 4F8CH to read the next character from the chain file. This is the first character after the slash. If the character was not a slash, this call is skipped.
4F5F
If the NZ FLAG has been set (either the original character was not a slash, or reading the next character after the slash failed), JUMP to 4F76H to handle the fallback/non-command path.
4F61
CP 2EH FE 2E
Compare Register A (the character after the slash) against 2EH (ASCII period .). In the embedded command format /x.y/n, the period separates the two position components. If A equals 2EH, the Z FLAG is set.
4F63
If the Z FLAG has been set (the character was a period), GOSUB to 4F8CH to read the next character (the second position component). If not a period, this call is skipped.
4F66
If the NZ FLAG has been set (the character was not a period, or reading the next character failed), JUMP to 4F76H for fallback handling.
4F68
CP B B8
Compare Register A (the character after the period) against Register B (which holds the original slash character 2FH, or the first character if it was not a slash). This checks if the embedded command has a matching delimiter. If A equals B, the Z FLAG is set.
4F69
If the Z FLAG has been set (the delimiter matched), GOSUB to 4F8CH to read the next character (the drive/section number digit).
4F6C
If the NZ FLAG has been set (the delimiter did not match, or reading failed), JUMP to 4F76H for fallback handling.

The full embedded command sequence /x./n has been parsed. Register A contains the final digit character. Convert it from ASCII to binary and validate.

4F6E
SUB 30H D6 30
SUBtract 30H (ASCII 0) from Register A, converting the ASCII digit character to its binary value (0–9). For example, ASCII 3 (33H) becomes binary 3.
4F70
CP 06H FE 06
Compare Register A (the binary digit value) against 06H (decimal 6). Valid drive/section numbers are 0–5. If A is less than 6, the CARRY FLAG is set (valid). If A is 6 or greater, the NO CARRY FLAG is set (invalid).
4F72
SET 7,A CB FF
Set bit 7 of Register A. This marks the drive/section number with the high bit set (80H OR'd with the value), creating a tagged value that distinguishes it from ordinary characters. For example, drive 3 becomes 83H.
4F74
If the CARRY FLAG has been set (the digit was valid, 0–5), JUMP to 4F89H to return the tagged character with Z flag set (CP A sets Z). The caller receives a value 80H–85H indicating the embedded drive/section command.

Either the embedded command sequence was not recognized or the digit was invalid. Fall through to the fallback path which restores the file position.

4F76
LD A,(44A5H) 3A A5 44
Fetch the current position byte from 44A5H into Register A. The chain file reader has advanced the position while parsing the failed command sequence.
4F79
SUB C 91
SUBtract Register C (the starting position saved at 4F5BH) from Register A (the current position). The result is the number of bytes consumed during the failed parse attempt.
4F7A
LD (44A9H),A 32 A9 44
Store Register A (the position difference) to 44A9H. This value tells the file repositioning routine how many bytes to back up.
4F7D
If the NZ FLAG has been set (the position difference is non-zero — bytes were consumed), GOSUB to 4445H in SYS0, the position FCB back one record routine. This backs up the file position to undo the failed parse, so the characters can be re-read as normal text.
4F80
If the NZ FLAG has been set (the repositioning failed), JUMP to 4F8AH to pop BC and return with NZ (error).
4F82
LD A,B 78
Copy Register B (the original character that was read before the slash-command parsing began) back into Register A. This restores the original character for return to the caller.
4F83
CP 86H FE 86
Compare Register A (the original character) against 86H. Characters 86H and above are high chain command codes that need their bit 7 cleared before being returned. If A is less than 86H, the CARRY FLAG is set.
4F85
If the CARRY FLAG has been set (A < 86H — the character is a normal character or a low chain command below 86H), JUMP to 4F89H to return the character as-is with Z set.
4F87
AND 7FH E6 7F
AND Register A with 7FH (binary 01111111), clearing bit 7. This strips the high bit from characters 86H and above, converting them to their 7-bit equivalents (06H and above). This ensures only valid ASCII characters are returned to the caller.
4F89
CP A BF
Compare Register A with itself. This always sets the Z FLAG and clears the Carry flag. This is a compact way to set the Z condition indicating success.
4F8A
POP BC C1
Restore Register Pair BC from the stack (saved at 4F54H). BC is restored to its value on entry to 4F50H.
4F8B
RET C9
RETURN to the caller. Register A contains the character (or tagged drive/section number), and the Z flag indicates success (Z) or error (NZ).

4F8CH – Low-Level Chain File Character Reader

This is the low-level routine that reads the next byte from the chain file. It calls the DOS routine at 0013H (read next byte from file) with DE pointing to the work area at 44A0H. If the byte is 00H (null), it skips it and reads again, looping until a non-null byte is found. Returns the character in Register A with Z set on success, or NZ with an error code on failure.

[LOOP START — Read bytes, skipping nulls]

4F8C
LD DE,44A0H 11 A0 44
Load Register Pair DE with 44A0H, the address of the FCB work area. DE is passed to the ROM/DOS read routine as the FCB pointer identifying which file to read from.
4F8F
GOSUB to the ROM/DOS routine at 0013H. This is the read next byte from file routine. DE points to the FCB at 44A0H. On success, Register A contains the byte read and the Z FLAG is set. On error, Register A contains an error code and the NZ FLAG is set.
4F92
RET NZ C0
If the NZ FLAG has been set (error reading from the file — end of file, disk error, etc.), RETURN immediately with the error code in A and NZ set.
4F93
OR A B7
OR Register A with itself to test if the byte read is zero (00H null). If A is 0, the Z FLAG is set; if A is non-zero, the NZ FLAG is set.
4F94
If the Z FLAG has been set (the byte read was 00H — a null byte), JUMP back to 4F8CH to read the next byte. Null bytes are padding and are skipped. [LOOP END]
4F96
CP A BF
Compare Register A with itself. This always sets the Z FLAG and clears the Carry flag. This sets the success condition (Z) for the caller.
4F97
RET C9
RETURN with the non-null character in Register A and Z flag set, indicating a successful read.

4F98H – Text Message Strings

These are the text message strings used by the SYS9 overlay module. Each string is terminated by either 03H (ETX, used by the SYS0 display routine at 4467H as an end-of-message marker) or 0DH (carriage return, which also terminates the display and moves the cursor to the next line).

4F98
DEFM "CHAINING "
9-character string: "CHAINING " (8 letters plus a trailing space). This prefix is displayed before "ABORTED" or "PAUSE..." messages by the two-part display routine at 4F45H.
4FA1
DEFB 03H
End-of-message terminator (ETX) for the "CHAINING " string.
4FA2
DEFM "ABORTED"
7-character string: "ABORTED". Displayed after "CHAINING " when a chain file error occurs or user intervention stops chaining.
4FA9
DEFB 0DH
Carriage return terminator for the "ABORTED" string.
4FAA
DEFM "PAUSE. PRESS 'ENTER' WHEN READY TO CONTINUE"
44-character string: "PAUSE. PRESS 'ENTER' WHEN READY TO CONTINUE". Displayed after "CHAINING " when chain command 81H is encountered or the BREAK/pause condition is detected.
4FD6
DEFB 0DH
Carriage return terminator for the pause message string.

4FD7H – WP / COPY File Transfer Engine Entry

This routine serves as the entry point for the COPY file transfer engine (also used by the WP command's sub-function 2). It sets up the source file by loading its filespec pointer (51E0H), stores the RELO handler address (4DDCH) as a callback pointer at 4483H, invokes the DOS-CALL mechanism via 4DC7H with function code 44H, initializes the file tracking byte at 4288H, reads the source file's record count from 448CH and record length/mode from 4488H, then validates the source file. If the source file is empty (record count = FFFFH after adjustment), it skips directly to copying the destination file information. Otherwise, it saves the source record count and sets up for the record-by-record copy loop.

4FD7
LD DE,51E0H 11 E0 51
Load Register Pair DE with 51E0H, the address of the temporary buffer area in the overlay's padding region. This buffer holds the filespec string for the source file in the COPY operation.
4FDA
LD HL,4DDCH 21 DC 4D
Point Register Pair HL to 4DDCH, the address of the RELO command handler. This address is stored as a callback — after the file operation completes, the system calls back to 4DDCH for post-processing.
4FDD
LD (4483H),HL 22 83 44
Store Register Pair HL (value 4DDCH) to memory at 4483H, the post-file-operation callback pointer. When the DOS file system completes its operation, it calls the routine at the address stored here.
4FE0
LD A,44H 3E 44
Load Register A with 44H (decimal 68). This is the DOS-CALL function code for the file open/setup operation that will be dispatched via 4DC7H.
4FE2
GOSUB to 4DC7H, the DOS-CALL / SVC invocation setup. Register A contains 44H (non-zero), so execution will jump to 4982H in SYS0 for DOS-CALL processing. The alternate registers have been loaded with BC'=EB01H and DE'=4978H.
4FE5
LD A,00H 3E 00
Load Register A with 00H. This value will be stored to 4288H to reset the file number/flags tracker. Note: LD A,00H is used instead of XOR A to avoid affecting the flags from the DOS-CALL return.
4FE7
LD (4288H),A 32 88 42
Store Register A (00H) to memory at 4288H, the system file number/flags tracker. Clearing this to zero resets the file tracking state for the COPY operation.
4FEA
LD HL,(448CH) 2A 8C 44
Load Register Pair HL from memory at 448CH, the source file record count (2 bytes, little-endian). This is the number of records in the source file as reported by the DOS after the file was opened.
4FED
LD A,(4488H) 3A 88 44
Fetch the byte at 4488H into Register A. This is the file record length/mode byte. If A is 0, the file uses fixed-length records; if non-zero, it uses variable-length records or a specific record size.
4FF0
OR A B7
OR Register A with itself to test if the record length/mode byte is zero. If A is 0, the Z FLAG is set (fixed-length mode); if non-zero, the NZ FLAG is set (variable-length mode).
4FF1
If the NZ FLAG has been set (non-zero record mode — variable-length records), JUMP to 4FF4H to skip the record count adjustment.
4FF3
DEC HL 2B
DECrement Register Pair HL (the record count) by 1. In fixed-length record mode, the record count is adjusted down by 1 because the count is 1-based and the copy loop uses 0-based indexing.
4FF4
LD A,H 7C
Copy Register H (high byte of the record count) into Register A.
4FF5
AND L A5
AND Register A (H) with Register L (low byte of the record count). The result is FFH only if both H and L are FFH (i.e., HL = FFFFH). This is a fast test for HL = FFFFH.
4FF6
INC A 3C
INCrement Register A by 1. If A was FFH (from the AND), it wraps to 00H and the Z FLAG is set, confirming HL = FFFFH (empty file). If A was anything else, the NZ FLAG is set (file has records).
4FF7
If the Z FLAG has been set (HL = FFFFH — the source file is empty or invalid), JUMP to 5026H to skip the source file copy and proceed directly to setting up the destination file parameters. Note: address 4FF7H is also referenced as the default filename extension string pointer — the bytes 28H 2DH at this address happen to be the opcode for JR Z, but when read as string data by the RELO command (which stores 4FF7H at 44A3H), they would be interpreted as ASCII characters.
4FF9
LD (51EAH),HL 22 EA 51
Store Register Pair HL (the source file record count) to memory at 51EAH in the temporary buffer area. This saves the source file's ending record number for use during the copy loop.
4FFC
EXX D9
Exchange the primary register set with the alternate register set. The alternate HL' will be loaded with a routine address for the copy loop.
4FFD
LD HL,4439H 21 39 44
Load alternate Register Pair HL' with 4439H, the address of the SYS0 read next record from file routine. This address is stored in HL' for use by the DOS-CALL mechanism's "return via HL'" path at 4DD5H–4DD8H.
5000
EXX D9
Exchange back to the primary register set. HL' now contains 4439H for the upcoming DOS-CALL.
5001
XOR A AF
Set Register A to 0 by XORing it with itself. A=0 selects the "return via HL'" path in the DOS-CALL setup at 4DC7H.
5002
GOSUB to 4DC7H with A=0. This takes the "return via stack" path: it pushes HL' (4439H) onto the stack and returns, effectively calling 4439H (read next record). The SVC parameters EB01H/4978H are also set up in alternate registers and on the stack.
5005
LD A,00H 3E 00
Load Register A with 00H. This resets the file number/flags tracker for the destination file setup.
5007
LD (4288H),A 32 88 42
Store 00H to memory at 4288H, resetting the file tracking state before the destination file is opened.
500A
GOSUB to 443FH in SYS0, the position FCB to start of file routine. This resets the destination file's FCB position to the beginning, preparing for the record-by-record write.
500D
RET NZ C0
If the NZ FLAG has been set (error positioning the file), RETURN with the error condition.

500EH – COPY Main Record Transfer Loop

This is the main copy loop that transfers records from the source file to the destination file. For each iteration, it positions the destination FCB to the current record (via 4436H), reads a record from the source file buffer (via 4439H with the source FCB at 51E0H), and repeats until all records are transferred or an end-of-file condition is reached. When done, it checks for expected end-of-file errors (1CH or 1DH) and proceeds to finalize the destination file.

[LOOP START — Copy records from source to destination]

500E
LD DE,4480H 11 80 44
Load Register Pair DE with 4480H, the address of the destination file FCB. DE is passed to the positioning routine to identify which file to operate on.
5011
GOSUB to 4436H in SYS0, the position FCB to specified record routine. DE points to the destination FCB at 4480H. This positions the file for the next record to be written.
5014
If the NZ FLAG has been set (error positioning the destination file — possibly end of file), JUMP to 501FH to check if it is an expected end-of-file condition.
5016
LD DE,51E0H 11 E0 51
Load Register Pair DE with 51E0H, the address of the source file FCB/buffer in the temporary buffer area.
5019
GOSUB to 4439H in SYS0, the read next record from file routine. DE points to the source FCB at 51E0H. This reads the next record from the source file into the I/O buffer, which can then be written to the destination.
501C
RET NZ C0
If the NZ FLAG has been set (error reading from the source file), RETURN with the error condition propagated to the caller.
501D
JUMP unconditionally back to 500EH to position and write the next record. [LOOP END]

The destination file positioning returned an error. Check if it is an expected end-of-file condition.

501F
CP 1CH FE 1C
Compare Register A (the error code from 4436H) against 1CH (Position Error — before start of file). If A equals 1CH, the Z FLAG is set — this is an expected end condition.
5021
If the Z FLAG has been set (error code is 1CH — expected end of file), JUMP to 5026H to proceed to the destination file finalization.
5023
CP 1DH FE 1DH
Compare Register A against 1DH (Position Error — past end of file). This is also an expected end condition for the copy operation. If A equals 1DH, the Z FLAG is set.
5025
RET NZ C0
If the NZ FLAG has been set (the error is neither 1CH nor 1DH — an unexpected error), RETURN with the error condition. The COPY operation has failed.

5026H – COPY Destination File Finalization

This routine saves the destination file's parameters (record count and record length/mode) from the DOS file control area into the temporary buffer at 51E0H, then positions the destination file's FCB to the start and begins writing records from the start. When all records have been written (detected by a 1CH or 1DH positioning error), it calls the SYS0 file close routine at 4428H.

5026
LD HL,(448CH) 2A 8C 44
Load Register Pair HL from memory at 448CH, the destination file record count (2 bytes). This is the number of records in the destination file after the copy operation.
5029
LD (51ECH),HL 22 EC 51
Store Register Pair HL (the destination record count) to memory at 51ECH in the temporary buffer. This saves the destination file's ending record number.
502C
LD A,(4488H) 3A 88 44
Fetch the file record length/mode byte from 4488H into Register A.
502F
LD (51E8H),A 32 E8 51
Store Register A (the record length/mode) to memory at 51E8H in the temporary buffer. This saves the file's record format for later reference.
5032
LD DE,51E0H 11 E0 51
Load Register Pair DE with 51E0H, the address of the source/destination file FCB in the temporary buffer.
5035
GOSUB to 443FH in SYS0, the position FCB to start of file routine. DE points to the FCB at 51E0H. This resets the file position for the write-back phase.
5038
RET NZ C0
If the NZ FLAG has been set (error positioning the file), RETURN with the error condition.

[LOOP START — Write records to destination file]

5039
GOSUB to 4436H in SYS0, the position FCB to specified record routine. The FCB was set up by the previous 443FH call; this advances to the next record position for writing.
503C
If the Z FLAG has been set (record positioned successfully), JUMP back to 5039H to position the next record. This tight loop writes all remaining records. [LOOP END]
503E
CP 1CH FE 1C
Compare Register A (the error code from 4436H) against 1CH (Position Error — before start of file). If A equals 1CH, the Z FLAG is set (expected end of write).
5040
If the Z FLAG has been set (error 1CH — expected end), JUMP to 5045H to close the file.
5042
CP 1DH FE 1DH
Compare Register A against 1DH (Position Error — past end of file). Also an expected end condition.
5044
RET NZ C0
If the NZ FLAG has been set (unexpected error — neither 1CH nor 1DH), RETURN with the error.
5045
JUMP to 4428H in SYS0, the file close routine. This closes the destination file, flushes any buffered data to disk, and updates the directory entry. Since this is a JP, the RET inside 4428H returns directly to the COPY command's caller.

5048H – KILL Command Handler (Timer Chain Insertion)

The KILL command (function code 2BH) enqueues a timer entry into the system timer interrupt chain at 4058H. It first calls the timer chain search routine at 50A3H to validate Register HL and search for any existing entry matching the caller's filespec. If the search succeeds (Z flag), the entry already exists and the routine returns error 18H. If the search returns NZ (no existing entry found), the routine inserts a new entry by linking it into the chain: the current chain head pointer at 4058H is stored into the new entry's link field, and the new entry's address is written to 4058H, making it the new head of the timer chain.

5048
GOSUB to 50A3H, the timer chain search routine. This validates that Register H is >= 52H and then searches the timer interrupt chain starting at 4058H for an entry matching the caller's 8-byte identifier. Returns Z if a matching entry was found (HL points to the matching entry's link field), or NZ if no match was found (HL points to the last entry's link field).
504B
RET NZ C0
If the NZ FLAG has been set (no matching entry found — this is actually the expected condition for KILL, which needs to insert a new entry), RETURN. Wait — re-examining the logic: KILL wants to ADD an entry. If 50A3H returns NZ, it means no existing duplicate was found, and HL is positioned correctly. But here RET NZ exits. This means: if NZ (search found something unexpected or returned an error), exit. The KILL command only proceeds with insertion when Z is set.

The search returned Z. HL points to the appropriate position in the timer chain. Insert the new entry by updating the chain link pointers.

504C
DEC HL 2B
DECrement Register Pair HL by 1. HL is adjusted back to point to the high byte of the link field in the timer chain entry where the new entry will be inserted.
504D
LD DE,(4058H) ED 5B 58 40
Load Register Pair DE from memory at 4058H, the timer interrupt chain head pointer. DE now holds the address of the current first entry in the timer chain.
5051
LD (HL),D 72
Store Register D (high byte of the old chain head) to the byte at (HL). This writes the high byte of the forward link into the new entry's link field.
5052
DEC HL 2B
DECrement Register Pair HL by 1, moving to the low byte of the link field.
5053
LD (HL),E 73
Store Register E (low byte of the old chain head) to the byte at (HL). The new entry's link field now points to the old chain head, linking the new entry into the chain.
5054
LD D,H 54
Copy Register H into Register D. This starts building the address of the new entry (the link field we just wrote to) in DE.
5055
LD E,L 5D
Copy Register L into Register E. DE now holds the address of the new entry's link field (low byte position).
5056
DEC HL 2B
DECrement Register Pair HL by 1. HL now points two bytes before the link field — this is the start of the new entry's header.
5057
LD (HL),D 72
Store Register D to (HL). This writes the high byte of the entry's own link address into the entry header.
5058
DEC HL 2B
DECrement Register Pair HL by 1.
5059
LD (HL),E 73
Store Register E to (HL). The entry header now contains a self-referencing pointer for the chain management.
505A
LD (4058H),HL 22 58 40
Store Register Pair HL to memory at 4058H, the timer interrupt chain head pointer. The new entry's address is now the head of the chain, completing the insertion.
505D
XOR A AF
Set Register A to 0 by XORing it with itself. This sets the Z FLAG, indicating success.
505E
RET C9
RETURN with A=0 and Z flag set, indicating the KILL command completed successfully — the timer entry has been inserted into the chain.

505FH – WP Command Handler (Timer Chain Removal)

The WP command (function code 4BH) removes a timer entry from the system timer interrupt chain at 4058H. It calls the timer chain search routine at 50A3H to find a matching entry. If a match is found (Z flag set), the entry is already absent or the search indicates an error, so error 18H is returned. If NZ is returned (the entry was found and its position identified), the routine unlinks the entry by copying its forward link pointer back to the predecessor's link field, effectively removing the entry from the chain.

505F
GOSUB to 50A3H, the timer chain search routine. Validates HL and searches the timer chain for a matching entry.
5062
If the Z FLAG has been set (the search did not find a removable entry — either no match or the entry is in an error state), JUMP to 509EH to exit with error code 18H.

The search returned NZ — an entry was found. HL points into the chain where the entry needs to be unlinked. Remove the entry by updating the predecessor's forward link to skip over it.

5064
XOR A AF
Set Register A to 0 by XORing it with itself.
5065
DEC HL 2B
DECrement Register Pair HL by 1, moving back to the high byte of the entry's self-referencing header.
5066
LD (HL),A 77
Store 00H to (HL), clearing the high byte of the entry's header. This marks the entry as removed.
5067
INC HL 23
INCrement Register Pair HL by 1, moving forward to read the entry's forward link pointer.
5068
LD C,(HL) 4E
Load Register C with the byte at (HL) — the low byte of the removed entry's forward link (pointing to the next entry in the chain).
5069
INC HL 23
INCrement Register Pair HL by 1.
506A
LD B,(HL) 46
Load Register B with the byte at (HL) — the high byte of the removed entry's forward link. BC now holds the address of the next entry in the chain after the one being removed.
506B
EX DE,HL EB
Exchange Register Pairs DE and HL. DE (which was set up by the search routine to point to the predecessor's link field) moves to HL, and the current position moves to DE.
506C
LD (HL),C 71
Store Register C (low byte of the next entry's address) to (HL), the predecessor's forward link low byte. This links the predecessor directly to the entry after the removed one.
506D
INC HL 23
INCrement Register Pair HL by 1.
506E
LD (HL),B 70
Store Register B (high byte of the next entry's address) to (HL), completing the predecessor's forward link update. The removed entry is now bypassed in the chain.
506F
RET C9
RETURN. Register A is 0 (from XOR A at 5064H) and Z is set, indicating the WP command completed successfully — the timer entry has been removed from the chain.

5070H – FORMS Command Handler

The FORMS command (sub-function 7) manages printer form specifications. It reads up to 9 filespec/parameter entries from the command line. For each entry, it advances HL past one character, calls the SYS0 filespec parser at 4C7AH, and stores the parsed parameter bytes into a buffer at 51E0H. If the parser returns Carry (successful parse with data), the current character at (HL) is copied to the buffer and the loop continues. When the parser returns No Carry (end of parameters or error), the loop exits. If no parameters were parsed (B still equals 9), an error is returned via 4D4CH. Otherwise, remaining buffer positions are filled with 20H (spaces), and the routine calls the timer chain search at 50ADH to locate and update the FORMS entry.

5070
LD DE,51E0H 11 E0 51
Load Register Pair DE with 51E0H, the address of the temporary buffer in the overlay's padding region. Parsed parameters will be stored here.
5073
LD B,09H 06 09
Load Register B with 09H (decimal 9). This is the maximum number of parameters to parse from the FORMS command line. B serves as a countdown counter.
5075
PUSH DE D5
Save Register Pair DE (the buffer address 51E0H) onto the stack. This preserves the buffer start for later use.

[LOOP START — Parse filespec/parameter entries]

5076
INC HL 23
INCrement Register Pair HL by 1, advancing the command buffer pointer past the delimiter or separator character to the next parameter.
5077
GOSUB to 4C7AH in SYS0, the parse/validate filespec routine. HL points to the current position in the command buffer. The routine parses the next filespec or parameter and returns Carry set if data was found, No Carry if end of parameters.
507A
If the NO CARRY FLAG has been set (no more parameters to parse — end of command line or parse error), JUMP to 5083H to exit the parse loop.
507C
LD A,(HL) 7E
Fetch the current character at the command buffer position (HL) into Register A. This is the parameter byte or delimiter that follows the parsed filespec.
507D
LD (DE),A 12
Store Register A (the parameter byte) to the buffer at the position pointed to by DE (51E0H + offset).
507E
INC DE 13
INCrement Register Pair DE by 1, advancing the buffer write pointer to the next position.
507F
DECrement B and JUMP to 5076H if B is not zero. Continue parsing parameters, up to a maximum of 9. [LOOP END on DJNZ]
5081
LD B,09H 06 09
If we reach here, all 9 parameters were parsed and B reached 0. Reload B with 09H. This value will make the comparison at 5084H succeed (B=09H = 09H), which would falsely trigger the "no parameters" error. However, since we parsed all 9, the JR NC at 507AH would not have been taken, so this path means we parsed exactly 9 parameters. Reloading B=09H ensures the CP check at 5084H falls through correctly — see analysis below.
5083
LD A,B 78
Copy Register B (the remaining parameter count) into Register A. If no parameters were parsed, B is still 09H. If some were parsed, B is less than 09H.
5084
CP 09H FE 09
Compare Register A (B) against 09H. If A equals 09H, the Z FLAG is set (no parameters were parsed — B was never decremented from its initial value of 9, or was reloaded to 9 after parsing all 9).
5086
If the Z FLAG has been set (B equals 09H — either no parameters were parsed or all 9 were parsed with the reload), JUMP to 4D4CH. This loads error code 33H and exits via the error handler. For the case where no parameters were parsed, this is the correct error response. For the 9-parsed case, the reload at 5081H prevents this from triggering because the DJNZ loop at 507FH decrements B to 0 and falls through, then B is reloaded to 09H — but actually, looking at this more carefully: if all 9 are parsed, DJNZ decrements B to 0 and falls through to 5081H. Then B is reloaded to 09H, A=B=09H, CP 09H sets Z, and JP Z takes us to the error. This means parsing exactly 9 parameters is treated as an error, limiting FORMS to 1–8 parameters.

Parameters were parsed (B < 09H, meaning 1–8 parameters). Fill remaining buffer positions with spaces.

5089
LD A,20H 3E 20
Load Register A with 20H (ASCII space). This fill character pads unused positions in the parameter buffer.
508B
LD (DE),A 12
Store Register A (20H space) to the buffer at (DE).
508C
INC DE 13
INCrement Register Pair DE by 1.
508D
DECrement B and JUMP to 5089H if B is not zero. Fill remaining positions with spaces.
508F
EX (SP),HL E3
Exchange the top of the stack with Register Pair HL. The stack held the buffer start address (51E0H from the PUSH DE at 5075H). After this exchange, HL = 51E0H (buffer start) and the stack holds the old HL (command buffer position).
5090
GOSUB to 50ADH, the timer chain search (from chain head) routine. HL points to 51E0H (the buffer with parsed parameters). This searches the timer chain for an entry matching the FORMS identifier and returns with Z/NZ indicating the result.
5093
LD DE,000AH 11 0A 00
Load Register Pair DE with 000AH (decimal 10). This is the offset from the current chain position to the location where the FORMS parameter data should be written.
5096
ADD HL,DE 19
ADD Register Pair DE (000AH) to HL, advancing HL to point to the parameter data area within the timer chain entry.
5097
POP DE D1
Restore Register Pair DE from the stack. DE now holds the old command buffer position (pushed by EX (SP),HL at 508FH).
5098
If the Z FLAG has been set (the timer chain search found no matching entry — there is no FORMS entry to update), JUMP to 509EH to exit with error code 18H.

A matching FORMS entry was found. Prepare to copy the parsed parameters into the entry's data area.

509A
EX (SP),HL E3
Exchange the top of the stack with Register Pair HL. HL gets the buffer start address (51E0H) from the stack, and the current chain entry address goes onto the stack.
509B
PUSH HL E5
Save Register Pair HL (51E0H, the parsed parameter buffer) onto the stack.
509C
EX DE,HL EB
Exchange Register Pairs DE and HL. HL now holds the old command buffer position, DE holds the buffer address. The caller's stack has been set up for return.
509D
RET C9
RETURN. The stack contains the chain entry address, so this RET jumps to the chain entry's parameter area, which will be populated by the caller. The FORMS command parameters have been parsed and the chain entry has been located.
509E
LD A,18H 3E 18
Load Register A with 18H (decimal 24), the NEWDOS/80 error code for a chain/timer entry error (entry not found or already exists, depending on context).
50A0
JUMP to 4D4EH, the common error exit, to report error 18H via the SYS0 error handler at 4409H.

50A3H – Timer Chain Search with HL Validation

This routine validates Register H (must be >= 52H, ensuring the pointer is in a valid memory range above the overlay) and then advances HL by 4 bytes before falling through to the timer chain search at 50ADH. If Register H < 52H, the routine exits with an error via 4D4CH (error code 33H).

50A3
LD A,H 7C
Copy Register H (the high byte of the pointer in HL) into Register A.
50A4
CP 52H FE 52
Compare Register A against 52H. If H < 52H, the CARRY FLAG is set, meaning HL points to memory within or below the overlay area (below 5200H), which is not a valid location for timer chain entries.
50A6
If the CARRY FLAG has been set (H < 52H — invalid memory range), JUMP to 4D4CH to exit with error code 33H. The timer entry pointer must be above the overlay area.
50A9
INC HL 23
INCrement Register Pair HL by 1.
50AA
INC HL 23
INCrement Register Pair HL by 1.
50AB
INC HL 23
INCrement Register Pair HL by 1.
50AC
INC HL 23
INCrement Register Pair HL by 1. HL has been advanced 4 bytes past its original position, now pointing to the identifier/data portion of the timer entry (past the 4-byte link header).

50ADH – Timer Chain Search from Chain Head

This routine searches the timer interrupt chain starting from the head pointer at 4058H, looking for an entry whose 8-byte identifier matches the 8 bytes pointed to by HL on entry. The chain is a singly-linked list: each entry starts with a 2-byte forward link pointer (pointing to the next entry), followed by the entry data. The routine walks the chain, comparing 8 bytes at offset +2 of each entry against the 8 bytes at (HL). Returns NZ with A = OR 35H (non-zero) if a matching entry is found, or Z (from the OR A after LD A,D / OR E returning 0) if the end of the chain is reached (link = 0000H) without finding a match. On error (chain corruption detected by SBC HL,DE ≠ 0), jumps to the file-close error exit at 4D46H.

50AD
PUSH HL E5
Save Register Pair HL (pointer to the 8-byte identifier to search for) onto the stack.
50AE
LD HL,4058H 21 58 40
Point Register Pair HL to 4058H, the timer interrupt chain head pointer. The 2-byte value at this address points to the first entry in the chain.
50B1
PUSH HL E5
Save Register Pair HL (address 4058H) onto the stack. This saves the address of the "predecessor link" (the chain head pointer itself) for potential chain manipulation by the caller.

[LOOP START — Walk the timer chain]

50B3
PUSH HL E5
Save Register Pair HL (current chain position) onto the stack.
50B4
POP BC C1
Restore into Register Pair BC. This is a compact LD BC,HL — BC now holds the current chain position (the address of the link field being examined).
50B5
POP HL E1
Restore Register Pair HL from the stack. HL now holds the address of the previous link field (the predecessor's link pointer).
50B6
LD B,H 44
Copy Register H into Register B. BC is being set to the value of HL (the predecessor link address).
50B7
LD C,L 4D
Copy Register L into Register C. BC now holds the predecessor link address.
50B8
LD E,(HL) 5E
Load Register E with the byte at (HL) — the low byte of the current entry's forward link pointer.
50B9
INC HL 23
INCrement Register Pair HL by 1.
50BA
LD D,(HL) 56
Load Register D with the byte at (HL) — the high byte of the current entry's forward link pointer. DE now holds the address of the next entry in the chain (or 0000H if end of chain).
50BB
LD A,D 7A
Copy Register D (high byte of forward link) into Register A.
50BC
OR E B3
OR Register A with Register E (low byte of forward link). If DE = 0000H (end of chain), the result is 0 and the Z FLAG is set. If DE is non-zero, the NZ FLAG is set (there is another entry to examine).
50BD
If the NZ FLAG has been set (DE is non-zero — there is a next entry), JUMP to 50C0H to examine it.
50BE
POP HL E1
Restore Register Pair HL from the stack (the identifier pointer that was pushed at 50ADH). End of chain reached with no match.
50BF
RET C9
RETURN with the Z FLAG set (from OR E at 50BCH producing 0). This indicates no matching entry was found — the chain has been fully traversed.

DE is non-zero — there is another entry. Follow the link and compare its 8-byte identifier against the search pattern.

50C0
EX DE,HL EB
Exchange Register Pairs DE and HL. HL now points to the next entry in the chain (from the forward link), and DE holds the old position.
50C1
LD E,(HL) 5E
Load Register E with the byte at (HL) — the low byte of this entry's own forward link pointer. This reads the entry's header to get its forward link for the next iteration.
50C2
INC HL 23
INCrement Register Pair HL by 1.
50C3
LD D,(HL) 56
Load Register D with the byte at (HL) — the high byte of this entry's forward link. DE now holds this entry's forward link (address of the next entry).
50C4
INC HL 23
INCrement Register Pair HL by 1. HL now points to byte +2 of the entry, which is the start of the 8-byte identifier data.
50C5
OR A B7
Clear the Carry flag (OR A with itself). This prepares for the SBC HL,DE instruction, which uses the Carry flag.
50C6
SBC HL,DE ED 52
SUBtract with Carry: HL = HL - DE - Carry. Since Carry was cleared, this computes HL - DE. If the entry's forward link (DE) equals the current position + 2 (HL), the result is 0 and Z is set. This is a chain integrity check — if the entry's link points back to itself, the chain is corrupted.
50C8
POP HL E1
Restore Register Pair HL from the stack (the identifier pointer).
50C9
If the NZ FLAG has been set (HL - DE ≠ 0 — the chain integrity check failed, indicating corruption or a valid non-self-referencing entry), JUMP to 4D46H, the file close error exit. This reports error 33H via RST 28H and then error 2FH.

The integrity check passed (HL - DE = 0). Now compare the 8-byte identifier. Push the search pointer and predecessor link, then compare byte by byte.

50CC
PUSH HL E5
Save Register Pair HL (the identifier pointer) onto the stack for restoration after the comparison.
50CD
PUSH DE D5
Save Register Pair DE (the current entry's data pointer at offset +2) onto the stack.
50CE
PUSH BC C5
Save Register Pair BC (the predecessor link address) onto the stack.
50CF
INC DE 13
INCrement Register Pair DE by 1.
50D0
INC DE 13
INCrement Register Pair DE by 1. DE now points to offset +4 of the chain entry (past the 2-byte link and 2-byte header), which is where the 8-byte identifier data starts.
50D1
LD B,08H 06 08
Load Register B with 08H (decimal 8). This is the number of bytes to compare in the identifier match.

[COMPARE LOOP — Match 8 bytes]

50D3
LD A,(DE) 1A
Load Register A with the byte at (DE) — the current byte from the chain entry's identifier.
50D4
SUB (HL) 96
SUBtract the byte at (HL) (the corresponding byte from the search identifier) from Register A. If the bytes match, A = 0 and the Z FLAG is set.
50D5
INC DE 13
INCrement Register Pair DE by 1, advancing to the next byte of the chain entry's identifier.
50D6
INC HL 23
INCrement Register Pair HL by 1, advancing to the next byte of the search identifier.
50D7
If the NZ FLAG has been set (the bytes did not match — mismatch found), JUMP back to 50B3H to advance to the next chain entry and continue searching.
50D9
DECrement B and JUMP to 50D3H if B is not zero. Continue comparing the next byte of the 8-byte identifier. [COMPARE LOOP END]

All 8 bytes matched. Restore the saved registers and return with a match indication.

50DB
POP DE D1
Restore Register Pair DE from the stack (the predecessor link address, originally saved as BC at 50CEH but popped into DE here).
50DC
POP HL E1
Restore Register Pair HL from the stack (the current entry's data pointer at offset +2, saved as DE at 50CDH).
50DD
POP BC C1
Restore Register Pair BC from the stack (the identifier pointer, saved as HL at 50CCH).
50DE
OR 35H F6 35
OR Register A with 35H. Register A was 0 (from the final successful SUB at 50D4H), so A becomes 35H. This sets the NZ FLAG (A is non-zero), which signals to the caller that a matching entry was found.
50E0
RET C9
RETURN with NZ set (A = 35H) and the register state: DE = predecessor link address, HL = matched entry's data pointer at offset +2. The caller can use these to manipulate the chain (insert before, remove, or update the matched entry).

50E1H – Text Message Strings (Error Messages)

These are additional text message strings used by the SYS9 fatal error and reset handlers.

50E1
DEFM "'RUN ONLY' STOPPED"
18-character string: "'RUN ONLY' STOPPED". Displayed when a program running in RUN-ONLY mode is halted. Terminated by 03H at 50F3H.
50F3
DEFB 03H
End-of-message terminator (ETX) for the "'RUN ONLY' STOPPED" string.
50F4
DEFM "DOS FATAL ERROR"
15-character string: "DOS FATAL ERROR". Displayed when an unrecoverable DOS error occurs. Terminated by 03H at 5103H.
5103
DEFB 03H
End-of-message terminator (ETX) for the "DOS FATAL ERROR" string.
5104
DEFM "!! KEY 'R' FOR RESET."
21-character string: "!! KEY 'R' FOR RESET.". Displayed after "DOS FATAL ERROR" or "'RUN ONLY' STOPPED" to instruct the user to press R to reset. Terminated by 0DH at 5119H.
5119
DEFB 0DH
Carriage return terminator for the "!! KEY 'R' FOR RESET." string.

511BH – ROUTE Final Check Routine

This short utility routine is called from the ROUTE command's Y/N/D option processing at 4E87H. It tests whether Register A is zero and whether specific bits of Register B indicate a termination condition. If A is non-zero, execution jumps to the chain character dispatcher at 4E90H for further processing. If A is zero, the routine checks bits 4 and 6 of B: if bit 6 is set and bit 4 is clear (AND 50H = 40H), it signals a clean ROUTE termination by jumping to the no-error exit at 402DH.

511B
OR A B7
OR Register A with itself to test if A is zero or non-zero. If A is 0, the Z FLAG is set; if non-zero, the NZ FLAG is set.
511C
If the NZ FLAG has been set (A is non-zero — there is a character to process), JUMP to 4E90H, the chain character dispatcher, to classify and handle the character.
511F
LD A,B 78
Copy Register B (which contains the system option flags from 428AH as loaded during Y/N/D parsing) into Register A.
5120
AND 50H E6 50
AND Register A with 50H (binary 01010000), isolating bits 4 and 6 of B. Bit 6 is the D-option valid flag, bit 4 is the D-option selected flag. Possible results: 00H (neither set), 10H (bit 4 only), 40H (bit 6 only), 50H (both set).
5122
CP 40H FE 40
Compare Register A against 40H. If the result of AND 50H was exactly 40H (bit 6 set, bit 4 clear — D-option is valid but not selected), the Z FLAG is set. This specific combination indicates a clean ROUTE termination condition.
5124
If the Z FLAG has been set (D-option valid but not selected — clean termination condition), JUMP to 402DH in SYS0, the no-error exit. This cleanly exits the ROUTE command with no error code.
5127
RET C9
RETURN to the caller. The ROUTE termination condition was not met — the caller (at 4E8AH) will check bit 5 of C to decide whether to continue or stop chaining.

5128H–51FFH – NOP Padding and Temporary Buffer Area

The region from 5128H to 51DFH consists of 184 bytes of 00H (NOP) padding. This unused space fills the remainder of the overlay's code area up to the end of the 512-byte overlay boundary. The region from 51E0H to 51FFH (32 bytes) is used as a temporary buffer area by the COPY, WP, and FORMS commands for storing filespecs, parameter data, and intermediate values during file transfer operations. Key locations within this buffer include: 51E0H (filespec/FCB storage), 51E8H (file record length/mode), 51EAH (source file record count), and 51ECH (destination file ending record count).

5128–51DF
DEFS 184,00H
184 bytes of NOP padding (00H fill). This region is unused by the overlay code and fills the space between the last instruction at 5127H and the temporary buffer at 51E0H.
51E0–51FF
DEFS 32
Temporary buffer area (32 bytes). Used as working storage by the COPY file transfer engine, WP command, and FORMS command. Overlaps with the overlay's padding space and extends to the end of the overlay at 51FFH. Key offsets: +00H = filespec/FCB (51E0H), +08H = record length/mode (51E8H), +0AH = source record count (51EAH), +0CH = destination record count (51ECH).