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

Page Customization

Description:

SYS9/SYS is a DOS overlay module that executes from the shared overlay area at 4D00H-51FFH. This module is the command executor for several important DOS commands:

  • BASIC2 - Activate non-disk BASIC (Model I only)
  • BOOT - Reset the computer
  • CHAIN and DO - Shift keyboard input to come from a disk file
  • CHNON - Alter chaining state (enable/disable chaining temporarily)
  • MDCOPY - MINI-DOS single file copy command
  • PAUSE - Wait for operator input
  • STMT - Execute BASIC statements from DOS

The module also handles logical routine enqueuing/dequeuing and route invocations. This is a mandatory DOS module required for proper system operation.

Variables:

AddressBytesPurpose
4280H2IY register initialization value (used by command dispatcher)
4289H2DOS system flags bytes (controls output modes, write protection, etc.)
42C5H1Saved character during chaining/input operations
428DH1System state flags (MINI-DOS active, special modes)
4058H2Pointer used by '+' command (stack manipulation)
44A0H32Filename parsing buffer / FCB template area
44A3H2Pointer to data area (initialized to 4FF7H)
44A5H1Character counter/position in filename buffer
44A9H1Calculated character count difference
3840H1Keyboard row 6 status (ENTER, CLEAR, BREAK, cursor keys, SPACE)
4978HvariesTarget area for EXX register swap operations
51E0H-51FFH32Temporary buffer for chaining file operations

Disasembly:

4D00H - SYS9 COMMAND DISPATCHER ENTRY POINT

This is the main entry point for SYS9. The code initializes the IY register and then dispatches to various command handlers based on the command code passed in Register A. The dispatcher uses a series of comparisons and conditional jumps to route execution to the appropriate handler routine.

4D00
LD IY,4280H FD 21 80 42
Point Index Register IY to address 4280H. This establishes a base pointer for accessing DOS system data structures. IY is used throughout NEWDOS/80 as a fixed reference point.

[COMMAND DISPATCHER START] The following sequence checks Register A to determine which command was requested. Each comparison checks for a specific command code, and jumps to the appropriate handler if matched.

4D04
CP 2BH FE 2B
Compare Register A against 2BH (ASCII: +). If Register A equals 2BH, the Z FLAG is set; otherwise the NZ FLAG is set. This checks for the '+' command (stack manipulation).
4D06
If the Z FLAG (Zero) has been set (meaning Register A contains 2BH), JUMP to 5048H to handle the '+' command which performs stack manipulation operations.
4D09
CP 4BH FE 4B
Compare Register A against 4BH (ASCII: K). If Register A equals 4BH, the Z FLAG is set; otherwise the NZ FLAG is set. This checks for the 'K' command (Kill/remove stack entry).
4D0B
If the Z FLAG (Zero) has been set (meaning Register A contains 4BH), JUMP to 505FH to handle the 'K' command which removes entries from the stack.
4D0E
CP CBH FE CB
Compare Register A against CBH. If Register A equals CBH, the Z FLAG is set; otherwise the NZ FLAG is set. This is the CHAIN/DO command code.
4D10
If the Z FLAG (Zero) has been set (meaning Register A contains CBH), JUMP to 4E22H to handle the CHAIN/DO command which redirects keyboard input from a disk file.
4D13
CP EBH FE EB
Compare Register A against EBH. If Register A equals EBH, the Z FLAG is set; otherwise the NZ FLAG is set. This is the primary command group indicator.
4D15
If the NZ FLAG (Not Zero) has been set (meaning Register A does NOT equal EBH), JUMP forward to 4D42H to handle as an error (unrecognized command code).

[SUBCOMMAND DISPATCHER] If we reach here, Register A contained EBH, indicating this is one of the EBH-group commands. Register C now contains a subcommand number. The code decrements C repeatedly and tests for zero to dispatch to the appropriate handler.

4D17
DEC C 0D
DECrement Register C by 1. This is the first subcommand check. The Z FLAG will be set if C becomes zero.
4D18
If the Z FLAG has been set (meaning C was 01H before the decrement), JUMP to 4DD9H. This handles subcommand 1 of the EBH group.
4D1B
DEC C 0D
DECrement Register C by 1. This is the second subcommand check.
4D1C
If the Z FLAG has been set (meaning C was 02H originally), JUMP to 4FD7H. This handles subcommand 2, which appears to be the BOOT command handler.
4D1F
DEC C 0D
DECrement Register C by 1. This is the third subcommand check.
4D20
If the Z FLAG has been set (meaning C was 03H originally), JUMP to 4DDCH. This handles subcommand 3.
4D23
DEC C 0D
DECrement Register C by 1. This is the fourth subcommand check.
4D24
If the Z FLAG has been set (meaning C was 04H originally), JUMP to 4EE2H. This handles subcommand 4.
4D27
DEC C 0D
DECrement Register C by 1. This is the fifth subcommand check.
4D28
If the Z FLAG has been set (meaning C was 05H originally), JUMP forward to 4D72H. This handles subcommand 5.
4D2A
DEC C 0D
DECrement Register C by 1. This is the sixth subcommand check.
4D2B
If the Z FLAG has been set (meaning C was 06H originally), JUMP to 4D42H. This treats subcommand 6 as an error (not implemented).
4D2E
DEC C 0D
DECrement Register C by 1. This is the seventh subcommand check.
4D2F
If the Z FLAG has been set (meaning C was 07H originally), JUMP to 5070H. This handles subcommand 7.
4D32
DEC C 0D
DECrement Register C by 1. This is the eighth subcommand check.
4D33
If the Z FLAG has been set (meaning C was 08H originally), JUMP forward to 4D52H. This handles subcommand 8.
4D35
DEC C 0D
DECrement Register C by 1. This is the ninth subcommand check.
4D36
If the Z FLAG has been set (meaning C was 09H originally), JUMP forward to 4D63H. This handles subcommand 9.
4D38
DEC C 0D
DECrement Register C by 1. This is the tenth subcommand check.
4D39
If the Z FLAG has been set (meaning C was 0AH originally), JUMP to 4DC6H. This handles subcommand 10 (0AH).
4D3C
DEC C 0D
DECrement Register C by 1. This is the eleventh subcommand check.
4D3D
If the Z FLAG has been set (meaning C was 0BH originally), JUMP forward to 4DACH. This handles subcommand 11 (0BH).
4D3F
DEC C 0D
DECrement Register C by 1. This is the twelfth and final subcommand check.
4D40
If the Z FLAG has been set (meaning C was 0CH originally), JUMP forward to 4DB1H. This handles subcommand 12 (0CH).

4D42H - ERROR HANDLER FOR UNRECOGNIZED COMMANDS

This section handles unrecognized command codes by setting up an error code and jumping to the error display routine. Two entry points exist: 4D42H for general errors (code 2AH) and 4D46H for specific error code 33H.

4D42
LD A,2AH 3E 2A
Load Register A with 2AH. This is the error code for "general error" or "unrecognized command".
4D44
JUMP forward to 4D4EH to display the error and exit.
4D46
LD A,33H 3E 33
Load Register A with 33H. This is an alternate error code entry point for a specific error condition (error 33H = 51 decimal).
4D48
PUSH AF F5
Save Register Pair AF (specifically Register A containing the error code) onto the stack.
4D49
LD A,46H 3E 46
Load Register A with 46H. This is an SVC (Supervisor Call) function code.
4D4B
RST 28H EF
Execute RST 28H (jump to 0028H), which is the NEWDOS/80 Supervisor Call mechanism. This invokes the DOS service specified by the value in Register A (46H).
4D4C
LD A,2FH 3E 2F
Load Register A with 2FH. This value will be used in the next instruction.
4D4E
OR A B7
OR Register A with itself. This sets the flags based on the value in A but does not change A. The Z FLAG will be set if A=00H, cleared otherwise. This also clears the CARRY FLAG.
4D4F
JUMP to 4409H in SYS0. This is the DOS error handler routine that displays error messages and performs appropriate cleanup based on the current DOS state.

4D52H - SUBCOMMAND 8 HANDLER (PAUSE COMMAND)

This routine handles subcommand 8, which implements the PAUSE command. It displays a message prompting the user, then waits for the user to press ENTER before continuing.

4D52
GOSUB to 4D63H to check system flags and potentially display output preparation message.
4D55
LD HL,4FB2H 21 B2 4F
Point Register Pair HL to address 4FB2H. This address contains the message text "PRESS 'ENTER' WHEN READY TO CONTINUE".
4D58
GOSUB to SYS0 routine at 4467H. This is the message display routine that outputs the null-terminated string pointed to by HL.

[WAIT FOR ENTER KEY LOOP] The following loop continuously scans the keyboard waiting for the user to press the ENTER key (character code 0DH).

4D5B
GOSUB to ROM routine at 0049H. This scans the keyboard and returns the character code in Register A (returns 00H if no key pressed).
4D5E
SUB 0DH D6 0D
SUBtract 0DH (ASCII: ENTER) from Register A. If Register A contained 0DH, the Z FLAG will be set and A becomes 00H. If A was not 0DH, the NZ FLAG will be set.
4D60
If the NZ FLAG (Not Zero) has been set (meaning the user did NOT press ENTER), LOOP BACK to 4D5BH to continue waiting for input.
4D62
RET C9
RETurn to caller. The PAUSE command is complete - the user has pressed ENTER.

4D63H - CHECK SYSTEM FLAGS AND DISPLAY "CHAINING"

This routine checks DOS system flags at 4289H to determine if output-related status messages should be displayed. Specifically, it checks if bit 6 of byte 4289H is set (output in progress) and bit 5 of byte 428AH is clear (prompt display needed), then calls the message display routine.

4D63
LD BC,(4289H) ED 4B 89 42
Load Register Pair BC with the 16-bit value stored at memory location 4289H (low byte) and 428AH (high byte). These are DOS system flag bytes that control various operational modes.
4D67
BIT 6,B CB 70
Test BIT 6 of Register B (which contains the byte from 4289H). The Z FLAG will be set if bit 6 is 0, or NZ FLAG will be set if bit 6 is 1. Bit 6 indicates output/chaining is in progress.
4D69
If the Z FLAG has been set (meaning bit 6 of 4289H is 0, indicating no output in progress), JUMP forward to 4D70H to return immediately without displaying anything.
4D6B
BIT 5,C CB 69
Test BIT 5 of Register C (which contains the byte from 428AH). The Z FLAG will be set if bit 5 is 0, or NZ FLAG will be set if bit 5 is 1.
4D6D
If the Z FLAG has been set (meaning bit 5 of 428AH is 0), GOSUB to 4467H in SYS0 to display the message. HL should point to the message "CHAINING " at 4F98H.
4D70
XOR A AF
XOR Register A with itself, setting Register A to ZERO and clearing all flags (setting the Z FLAG).
4D71
RET C9
RETurn to caller with A=00H and Z FLAG set, indicating successful completion.

4D72H - SUBCOMMAND 5 HANDLER

This routine handles subcommand 5 of the EBH command group. It checks a flag at 44A0H, performs conditional operations based on bit 7, and then sets up either error code 26H or 34H before jumping to the error display routine.

After calling 4D82H to check flags, this tests the result and either loads error code 34H or jumps back to display the error.

4D72
LD A,(44A0H) 3A A0 44
Fetch the byte stored at memory location 44A0H and load it into Register A. This is the first byte of the filename parsing buffer area.
4D75
RLCA 07
Rotate Register A Left Circular (through carry). Bit 7 goes into the CARRY FLAG and into bit 0. This tests bit 7 of the original value.
4D76
LD A,26H 3E 26
Load Register A with 26H. This is error code 26H (display error message via SVC).
4D78
JR NC,4D4EH 30 D4
If the NO CARRY FLAG has been set (meaning bit 7 of the value at 44A0H was 0), JUMP BACK to 4D4EH to display error 26H and exit.
4D7A
GOSUB to 4D82H to check and process filename buffer flags, looking for specific characters (N, Y, or D) that control operation mode.
4D7D
RET Z C8
If the Z FLAG has been set (meaning 4D82H found a valid character match), RETurn to caller immediately with success.
4D7E
LD A,34H 3E 34
Load Register A with 34H. This is error code 34H (parse error or invalid parameter).
4D80
JUMP BACK to 4D4EH to display error code 34H and exit.

4D82H - CHECK FILENAME BUFFER FOR Y/N/D FLAGS

This routine examines the filename buffer at HL, looking for specific control characters (N, Y, or D) that determine operational modes. It modifies DOS system flags at 4289H-428AH based on the character found, and returns with Z FLAG set if a valid character was found.

4D82
LD BC,(4289H) ED 4B 89 42
Load Register Pair BC with the 16-bit value stored at memory locations 4289H-428AH. These are DOS system flag bytes.
4D86
RES 5,C CB A9
RESet (clear to 0) bit 5 of Register C. This clears a flag in the system flags byte at 428AH.
4D88
RES 4,B CB A0
RESet (clear to 0) bit 4 of Register B. This clears a flag in the system flags byte at 4289H.

The routine now fetches a character from the buffer and converts it to uppercase for comparison.

4D8A
LD A,(HL) 7E
Load Register A with the byte stored at the memory location pointed to by HL (the current position in the filename buffer).
4D8B
GOSUB to SYS0 routine at 4548H. This converts lowercase letters to uppercase, leaving other characters unchanged.
4D8E
CP 4EH FE 4E
Compare Register A against 4EH (ASCII: N). If Register A equals 4EH, the Z FLAG is set; otherwise the NZ FLAG is set.
4D90
If the Z FLAG has been set (meaning the character is N), JUMP forward to 4DA1H to complete processing with the flags as currently set (both bits cleared).
4D92
SET 5,C CB E9
SET (set to 1) bit 5 of Register C. This sets a flag in the system flags at 428AH, indicating a different mode.
4D94
CP 59H FE 59
Compare Register A against 59H (ASCII: Y). If Register A equals 59H, the Z FLAG is set; otherwise the NZ FLAG is set.
4D96
If the Z FLAG has been set (meaning the character is Y), JUMP forward to 4DA1H to complete processing with bit 5 of C set.
4D98
CP 44H FE 44
Compare Register A against 44H (ASCII: D). If Register A equals 44H, the Z FLAG is set; otherwise the NZ FLAG is set.
4D9A
RET NZ C0
If the NZ FLAG (Not Zero) has been set (meaning the character is NOT D), RETurn to caller immediately. The NZ FLAG indicates an invalid/unrecognized character.

If we reach here, the character is D. We need to check an additional condition before setting bit 4.

4D9B
BIT 6,B CB 70
Test BIT 6 of Register B (from system flags at 4289H). The Z FLAG will be set if bit 6 is 0, or NZ FLAG will be set if bit 6 is 1.
4D9D
If the Z FLAG has been set (meaning bit 6 of 4289H is 0), JUMP forward to 4DA1H without setting bit 4 of B.
4D9F
SET 4,B CB E0
SET (set to 1) bit 4 of Register B. This sets a flag at 4289H indicating special mode D operation when bit 6 is also set.

[FINALIZE FLAGS AND CHECK FOR END OF LINE] The character has been validated. Now advance to the next character and verify we're at end of line.

4DA1
INC HL 23
INCrement Register Pair HL, moving to the next character position in the buffer.
4DA2
LD A,(HL) 7E
Load Register A with the byte at the memory location pointed to by HL (the next character in the buffer).
4DA3
CP 0DH FE 0D
Compare Register A against 0DH (ASCII: ENTER, carriage return, end of line marker). If Register A equals 0DH, the Z FLAG is set; otherwise the NZ FLAG is set.
4DA5
RET NZ C0
If the NZ FLAG (Not Zero) has been set (meaning there are more characters after the Y/N/D flag), RETurn to caller with NZ indicating an error (extra characters not allowed).
4DA6
LD (4289H),BC ED 43 89 42
Store Register Pair BC into memory locations 4289H-428AH. This writes back the modified system flag bytes.
4DAA
XOR A AF
XOR Register A with itself, setting Register A to ZERO and setting the Z FLAG, clearing all other flags. This indicates successful completion.
4DAB
RET C9
RETurn to caller with Z FLAG set, indicating success.

4DACH - SUBCOMMAND 11 HANDLER ("RUN ONLY" STOPPED MESSAGE)

This routine handles subcommand 11 (0BH) by displaying a message indicating that a "RUN ONLY" program has been stopped, then waits for the user to press R to continue.

4DAC
LD HL,50F4H 21 F4 50
Point Register Pair HL to address 50F4H. This address contains the message text "DOS FATAL ERROR" followed by a carriage return.
4DAF
JUMP forward to 4DB4H to display the message and handle user input.

4DB1H - SUBCOMMAND 12 HANDLER ("RUN ONLY" MESSAGE)

This routine handles subcommand 12 (0CH) by displaying a different "RUN ONLY" related message.

4DB1
LD HL,50E1H 21 E1 50
Point Register Pair HL to address 50E1H. This address contains the message text "'RUN ONLY' STOPPED" followed by a carriage return.

[COMMON MESSAGE DISPLAY AND KEY WAIT] Both subcommands 11 and 12 converge here to display their respective messages and wait for user response.

4DB4
GOSUB to SYS0 routine at 4467H to display the null-terminated message pointed to by HL.
4DB7
LD HL,5104H 21 04 51
Point Register Pair HL to address 5104H. This address contains the message text "!!! KEY 'R' FOR RESET."
4DBA
GOSUB to 4467H in SYS0 to display the second message prompting for the reset key.

[WAIT FOR 'R' KEY LOOP] Wait indefinitely for the user to press the R key.

4DBD
GOSUB to ROM routine at 0049H to scan the keyboard and return the key code in Register A (returns 00H if no key pressed).
4DC0
RES 5,A CB AF
RESet (clear to 0) bit 5 of Register A. This converts lowercase letters to uppercase by clearing the case bit in ASCII encoding.
4DC2
CP 52H FE 52
Compare Register A against 52H (ASCII: R). If Register A equals 52H, the Z FLAG is set; otherwise the NZ FLAG is set.
4DC4
If the NZ FLAG (Not Zero) has been set (meaning the key pressed was NOT R), LOOP BACK to 4DBDH to continue waiting for the correct key.

Once R is pressed, execute a system reset.

4DC6
RST 00H C7
Execute RST 00H (jump to 0000H), which is the Z80 reset vector. This performs a complete system reset, restarting the computer from the ROM bootstrap.

4DC7H - REGISTER SWAP AND SETUP ROUTINE

This routine performs register exchanges and setup operations. It appears to prepare for a special operation by swapping the alternate register set, setting up stack values, and then deciding whether to continue or jump to an error handler based on the value in Register A.

4DC7
EXX D9
EXchange register pairs BC, DE, and HL with their alternate (shadow) counterparts BC', DE', and HL'. This swaps to the alternate register set.
4DC8
LD BC,EB01H 01 01 EB
Load Register Pair BC with the immediate value EB01H. B=EBH, C=01H. This appears to be a command code (EBH) and subcommand (01H) combination.
4DCB
LD DE,4978H 11 78 49
Load Register Pair DE with the immediate address 4978H. This points to a target area for data operations.
4DCE
PUSH BC C5
Save Register Pair BC (containing EB01H) onto the stack.
4DCF
PUSH DE D5
Save Register Pair DE (containing 4978H) onto the stack.
4DD0
EXX D9
EXchange register pairs back to the primary register set (BC, DE, HL). This restores the original registers.
4DD1
OR A B7
OR Register A with itself. This sets flags based on the current value in A without changing it. The Z FLAG is set if A=00H, cleared otherwise.
4DD2
If the NZ FLAG (Not Zero) has been set (meaning Register A is not zero), JUMP to 4982H in SYS0. This is an SVC setup/FCB validation routine.
4DD5
EXX D9
EXchange register pairs to the alternate register set again.
4DD6
PUSH HL E5
Save Register Pair HL from the alternate register set onto the stack.
4DD7
EXX D9
EXchange back to the primary register set.
4DD8
RET C9
RETurn to caller with A=00H.

4DD9H - SUBCOMMAND 1 HANDLER (STACK MANIPULATION)

This routine handles subcommand 1 of the EBH command group. It performs a simple stack manipulation by exchanging and popping values.

4DD9
EX (SP),HL E3
EXchange the value in Register Pair HL with the 16-bit value on top of the stack. HL gets the stack value, and the stack gets the old HL value.
4DDA
POP HL E1
POP (restore) the top value from the stack into Register Pair HL, removing it from the stack and adjusting the stack pointer.
4DDB
RET C9
RETurn to caller.

4DDCH - SUBCOMMAND 3 HANDLER (BUFFER COPY OPERATION)

This routine handles subcommand 3 of the EBH command group. It exchanges DE and HL registers, then copies 32 bytes (20H) from the area pointed to by HL into the filename parsing buffer at 44A0H, sets up a pointer at 44A3H, and performs file parsing/loading operations.

4DDC
EX DE,HL EB
EXchange Register Pairs DE and HL. The source address is now in HL, and the previous HL value is in DE.
4DDD
LD DE,44A0H 11 A0 44
Load Register Pair DE with address 44A0H, pointing to the start of the filename parsing buffer.
4DE0
LD BC,0020H 01 20 00
Load Register Pair BC with 0020H (32 decimal). This is the number of bytes to copy.
4DE3
LDIR ED B0
Load, Increment, and Repeat. This copies BC bytes from (HL) to (DE), incrementing both pointers after each byte. Continues until BC reaches zero. This copies 32 bytes into the filename buffer.

After copying the buffer, set up a pointer and process the file specification.

4DE5
LD HL,4FF7H 21 F7 4F
Point Register Pair HL to address 4FF7H. This appears to be a default or template area.
4DE8
LD (44A3H),HL 22 A3 44
Store Register Pair HL (4FF7H) into memory locations 44A3H-44A4H. This sets up a pointer in the filename buffer structure.
4DEB
POP AF F1
POP (restore) Register Pair AF from the stack. This retrieves a previously saved flag/accumulator value.
4DEC
POP HL E1
POP (restore) Register Pair HL from the stack. This retrieves a previously saved address.
4DED
GOSUB to SYS0 routine at 4C7AH. This calculates the physical disk sector from logical parameters.
4DF0
RET C D8
If the CARRY FLAG has been set (indicating an error in sector calculation), RETurn to caller immediately with the error.
4DF1
If the NZ FLAG (Not Zero) has been set, GOSUB to 4E06H. This performs additional file processing operations.
4DF4
RET NZ C0
If the NZ FLAG (Not Zero) has been set (indicating an error or special condition), RETurn to caller immediately.

4DF5H - SET SYSTEM FLAGS AND RETURN

This section completes the processing from 4DDCH by setting specific bits in the DOS system flags at 4289H-428AH to indicate file operations are active, then clears a state flag and returns.

4DF5
LD HL,4289H 21 89 42
Point Register Pair HL to address 4289H, the first DOS system flags byte.
4DF8
SET 5,(HL) CB EE
SET (set to 1) bit 5 of the byte at memory location pointed to by HL (4289H). This sets a flag indicating a specific operational state.
4DFA
INC HL 23
INCrement Register Pair HL, now pointing to 428AH (the second system flags byte).
4DFB
BIT 6,(HL) CB 76
Test BIT 6 of the byte at memory location pointed to by HL (428AH). The Z FLAG will be set if bit 6 is 0, or NZ FLAG will be set if bit 6 is 1.
4DFD
If the Z FLAG has been set (meaning bit 6 of 428AH is 0), JUMP forward to 4E01H, skipping the next instruction.
4DFF
SET 4,(HL) CB E6
SET (set to 1) bit 4 of the byte at memory location pointed to by HL (428AH). This sets an additional flag when bit 6 was already set.
4E01
XOR A AF
XOR Register A with itself, setting Register A to ZERO and clearing all flags (setting the Z FLAG).
4E02
LD (42C5H),A 32 C5 42
Store the value held in Register A (00H) into memory location 42C5H. This clears the saved character flag used during chaining operations.
4E05
RET C9
RETurn to caller with A=00H and Z FLAG set.

4E06H - FILE VERIFICATION LOOP

This routine performs file verification by reading characters from the filename buffer and comparing them against characters from the current file position. It loops through the filename, checking for match conditions and special markers (80H indicates start of data, 0DH indicates end).

4E06
LD B,H 44
Load Register B with the value from Register H. This saves the high byte of an address.
4E07
LD C,L 4D
Load Register C with the value from Register L. This saves the low byte, so BC now contains a copy of HL.
4E08
LD H,B 60
Load Register H with the value from Register B. This appears redundant but may be for clarity or modified in practice.
4E09
LD L,C 69
Load Register L with the value from Register C. HL is now restored/confirmed to its original value.

[WAIT FOR DATA START MARKER LOOP] The following loop reads characters until it finds the start marker (80H).

4E0A
GOSUB to 4F50H. This reads a character from the filename buffer at 44A0H and performs special processing, returning the character in Register A with Z FLAG set if at certain delimiters.
4E0D
RET NZ C0
If the NZ FLAG (Not Zero) has been set (indicating an error or special condition from the read), RETurn to caller immediately.
4E0E
CP 80H FE 80
Compare Register A against 80H. If Register A equals 80H, the Z FLAG is set; otherwise the NZ FLAG is set. 80H is the data start marker.
4E10
If the NZ FLAG (Not Zero) has been set (meaning the character is NOT 80H), LOOP BACK to 4E0AH to continue reading until we find the start marker.

[CHARACTER COMPARISON LOOP] Now we've found the start marker. Compare characters from the file against the buffer.

4E12
GOSUB to 4F50H to read the next character from the filename buffer.
4E15
RET NZ C0
If the NZ FLAG (Not Zero) has been set (indicating an error), RETurn to caller immediately.
4E16
GOSUB to SYS0 routine at 4548H. This converts lowercase letters to uppercase for case-insensitive comparison.
4E19
CP (HL) BE
Compare Register A against the byte stored at the memory location pointed to by HL. If they are equal, the Z FLAG is set; otherwise the NZ FLAG is set.
4E1A
INC HL 23
INCrement Register Pair HL, moving to the next character in the comparison buffer.
4E1B
If the NZ FLAG (Not Zero) has been set (meaning the characters did NOT match), JUMP BACK to 4E08H to restart the comparison process from the beginning.
4E1D
CP 0DH FE 0D
Compare Register A against 0DH (ASCII: ENTER, carriage return). If Register A equals 0DH, the Z FLAG is set; otherwise the NZ FLAG is set. This checks if we've reached the end of the filename.
4E1F
If the NZ FLAG (Not Zero) has been set (meaning we haven't reached the end yet), LOOP BACK to 4E12H to continue comparing characters.
4E21
RET C9
RETurn to caller. If we reach here, all characters matched successfully and we found the carriage return, so Z FLAG is set indicating success.

4E22H - CHAIN/DO COMMAND HANDLER ENTRY POINT

This is the main entry point for the CHAIN and DO commands (command code CBH). These commands redirect keyboard input to come from a disk file instead of the physical keyboard. The handler sets up chaining mode, opens the specified file, and manages the state flags that control how input is redirected.

4E22
LD A,0AH 3E 0A
Load Register A with 0AH. This value will be stored but immediately overwritten by the next instruction. This may be a vestigial instruction or placeholder.
4E24
LD A,18H 3E 18
Load Register A with 18H (the JR opcode). This value will be used for self-modifying code.
4E26
LD (4E22H),A 32 22 4E
Store the value held in Register A (18H) into memory location 4E22H. This is self-modifying code - it overwrites the first instruction of this routine (changing LD A,0AH to JR offset), so subsequent calls will skip directly past this initialization.

[SET UP CHAINING FLAGS] Initialize the chaining mode flags.

4E29
LD HL,44A1H 21 A1 44
Point Register Pair HL to address 44A1H, which is in the filename parsing buffer area (one byte past the start).
4E2C
SET 5,(HL) CB EE
SET (set to 1) bit 5 of the byte at memory location pointed to by HL (44A1H). This sets a flag indicating chaining mode is being activated.

[CHECK FOR MINI-DOS MODE] The code now checks if the system is in MINI-DOS mode by examining bit 7 of the system flags.

4E2E
LD A,(428DH) 3A 8D 42
Fetch the byte stored at memory location 428DH and load it into Register A. This is a system state flags byte.
4E31
BIT 7,A CB 7F
Test BIT 7 of Register A. The Z FLAG will be set if bit 7 is 0, or NZ FLAG will be set if bit 7 is 1. Bit 7 set indicates MINI-DOS is active.
4E33
If the NZ FLAG (Not Zero) has been set (meaning MINI-DOS is active, bit 7=1), JUMP forward to 4E57H to skip the stack scanning section.

[SCAN STACK FOR BASIC MARKER] If not in MINI-DOS, scan the stack looking for a specific marker pattern that indicates BASIC is active. This searches for the pattern 94H 06H ... 05H E3H which identifies a BASIC context on the stack.

4E35
LD B,0AH 06 0A
Load Register B with 0AH (10 decimal). This is the loop counter for the number of stack entries to scan.
4E37
LD HL,FFFFH 21 FF FF
Point Register Pair HL to address FFFFH. This will be used with ADD to scan backward through the stack.
4E3A
ADD HL,SP 39
ADD the Stack Pointer value to Register Pair HL. This calculates HL = SP - 1, pointing just below the current stack top.

[STACK SCAN LOOP] Search through the stack for the BASIC marker pattern.

4E3B
DEC B 05
DECrement Register B by 1. This counts down the number of stack entries remaining to scan.
4E3C
If the Z FLAG has been set (meaning B reached zero, we've scanned all 10 entries), JUMP forward to 4E7BH. This indicates BASIC was not found on the stack.
4E3E
INC HL 23
INCrement Register Pair HL, moving forward to the next byte in the stack.
4E3F
LD A,(HL) 7E
Load Register A with the byte stored at the memory location pointed to by HL (current stack position).
4E40
CP 94H FE 94
Compare Register A against 94H. If Register A equals 94H, the Z FLAG is set; otherwise the NZ FLAG is set. This is the first byte of the BASIC marker pattern.
4E42
INC HL 23
INCrement Register Pair HL to check the next byte.
4E43
If the NZ FLAG (Not Zero) has been set (meaning the byte was NOT 94H), LOOP BACK to 4E3BH to continue scanning the stack.
4E45
LD A,(HL) 7E
Load Register A with the next byte at (HL). This checks the second byte of the pattern.
4E46
CP 06H FE 06
Compare Register A against 06H. If Register A equals 06H, the Z FLAG is set; otherwise the NZ FLAG is set. This is the second required byte.
4E48
If the NZ FLAG (Not Zero) has been set (meaning the byte was NOT 06H), LOOP BACK to 4E3BH to continue scanning.

Found the 94H 06H pattern. Now skip forward 12 bytes and check for the remaining pattern bytes.

4E4A
LD DE,000CH 11 0C 00
Load Register Pair DE with 000CH (12 decimal). This is the offset to skip forward in the stack structure.
4E4D
ADD HL,DE 19
ADD Register Pair DE to Register Pair HL. HL now points 12 bytes forward from the second pattern byte.
4E4E
LD A,(HL) 7E
Load Register A with the byte at this new position.
4E4F
CP 05H FE 05
Compare Register A against 05H. If Register A equals 05H, the Z FLAG is set; otherwise the NZ FLAG is set.
4E51
DEC HL 2B
DECrement Register Pair HL by 1, moving back one byte to check the preceding byte.
4E52
RET NZ C0
If the NZ FLAG (Not Zero) has been set (meaning the byte was NOT 05H), RETurn to caller. The pattern doesn't match - this is not a BASIC stack frame.
4E53
LD A,(HL) 7E
Load Register A with the byte at the preceding position.
4E54
CP E3H FE E3
Compare Register A against E3H. If Register A equals E3H, the Z FLAG is set; otherwise the NZ FLAG is set. This is the final byte of the BASIC marker pattern.
4E56
RET NZ C0
If the NZ FLAG (Not Zero) has been set (meaning the byte was NOT E3H), RETurn to caller. The complete pattern was not found.

[BASIC MARKER FOUND OR MINI-DOS ACTIVE] If we reach here either: (1) we found the complete BASIC pattern on the stack, or (2) we jumped here from 4E33H because MINI-DOS is active.

4E57H - CHECK KEYBOARD STATE AND BEGIN CHAINING LOOP

This section checks keyboard and system state, then enters the main chaining loop which processes input from the chain file instead of the keyboard.

4E57
LD A,(428DH) 3A 8D 42
Fetch the byte stored at memory location 428DH and load it into Register A. This is the system state flags byte.
4E5A
AND 40H E6 40
AND Register A with 40H (binary: 01000000), masking out all bits except bit 6. The Z FLAG will be set if bit 6 is 0, cleared if bit 6 is 1.
4E5C
If the Z FLAG has been set (meaning bit 6 of 428DH is 0), JUMP forward to 4E66H to skip the keyboard check.

Bit 6 is set, so check the keyboard for the BREAK key.

4E5E
LD A,(3840H) 3A 40 38
Fetch the byte stored at memory location 3840H and load it into Register A. This is keyboard row 6, which includes the BREAK key (bit 6), ENTER (bit 0), CLEAR (bit 1), cursor keys, and SPACE.
4E61
AND 40H E6 40
AND Register A with 40H, testing the BREAK key (bit 6). The Z FLAG will be set if BREAK is NOT pressed (bit 6=0), or NZ FLAG if BREAK IS pressed (bit 6=1 on Model I when key is pressed).
4E63
If the NZ FLAG (Not Zero) has been set (meaning BREAK key IS pressed), JUMP to 4F03H to handle the break/pause condition.

[MAIN CHAINING LOOP START] Process the chaining display message and begin reading from the chain file.

4E66
GOSUB to 4ED3H. This checks if special keyboard/MINI-DOS conditions exist and clears the accumulator if so.
4E69
LD A,(42C5H) 3A C5 42
Fetch the byte stored at memory location 42C5H and load it into Register A. This is the saved character from previous chaining operations (initially 00H).
4E6C
OR A B7
OR Register A with itself. This sets flags based on the value in A. The Z FLAG will be set if A=00H, indicating no saved character.
4E6D
If the NZ FLAG (Not Zero) has been set (meaning there IS a saved character from a previous operation), JUMP forward to 4E90H to use that character instead of reading a new one.
4E6F
GOSUB to 4F50H to read the next character from the chain file buffer.
4E72
If the Z FLAG has been set (indicating a special delimiter or end condition), JUMP forward to 4E90H to process the character.
4E74
CP 1CH FE 1C
Compare Register A against 1CH. If Register A equals 1CH, the Z FLAG is set; otherwise the NZ FLAG is set. 1CH is a special control code (position error - before start of file).
4E76
If the NZ FLAG (Not Zero) has been set (meaning the character is NOT 1CH), JUMP forward to 4EE0H to handle as a regular character or different error.
4E78
GOSUB to 4EC5H. This clears chaining flags and resets the system state, ending the chaining operation.
4E7B
OR 01H F6 01
OR Register A with 01H. This sets bit 0 of Register A and clears the Z FLAG, setting the NZ FLAG.
4E7D
RET C9
RETurn to caller with NZ FLAG set, indicating completion or error condition.

4E7EH - PROCESS FILENAME FLAGS AND HANDLE ERRORS

This routine checks filename buffer flags using the Y/N/D checker at 4D82H, then handles various error conditions and continues chaining operations. It processes saved characters and manages the flow based on system flag states.

4E7E
GOSUB to 4D82H to check the filename buffer for Y/N/D control flags and update system flags at 4289H-428AH accordingly.
4E81
If the NZ FLAG (Not Zero) has been set (meaning 4D82H found an invalid or missing flag), JUMP to 4F2EH to handle as an error.
4E84
LD A,(42C5H) 3A C5 42
Fetch the byte stored at memory location 42C5H and load it into Register A. This retrieves any saved character from previous operations.
4E87
GOSUB to 511BH. This routine checks Register A and system flags, returning to different locations based on the conditions.
4E8A
BIT 5,C CB 69
Test BIT 5 of Register C (which contains system flags from 428AH). The Z FLAG will be set if bit 5 is 0, or NZ FLAG will be set if bit 5 is 1.
4E8C
If the Z FLAG has been set (meaning bit 5 of C is 0), JUMP BACK to 4E7BH to set error flag and return.
4E8E
JUMP BACK to 4E57H to continue the chaining loop from the keyboard check point.

4E90H - PROCESS CHARACTER FROM CHAIN FILE

This section processes a character read from the chain file. It saves the character in multiple registers, clears the saved character flag, and then performs various checks to determine how to handle the character (whether it's a special code requiring file processing, a regular character, or an error condition).

4E90
LD B,A 47
Load Register B with the value from Register A. This saves a copy of the character.
4E91
LD C,A 4F
Load Register C with the value from Register A. This saves another copy of the character in C.
4E92
XOR A AF
XOR Register A with itself, setting Register A to ZERO and setting the Z FLAG.
4E93
LD (42C5H),A 32 C5 42
Store the value held in Register A (00H) into memory location 42C5H. This clears the saved character flag.
4E96
LD A,B 78
Load Register A with the value from Register B. This restores the character to Register A.

[CHECK CHARACTER TYPE] Determine what type of character we received and how to process it.

4E97
SUB 80H D6 80
SUBtract 80H from Register A. If A was 80H, the result is 00H and Z FLAG is set. This checks if the character is the special 80H marker (start of data).
4E99
If the Z FLAG has been set (meaning the character was 80H), JUMP BACK to 4E78H to call 4EC5H, which clears chaining and returns.
4E9B
CP 04H FE 04
Compare Register A against 04H. Since we subtracted 80H, this checks if the original character was 84H. If they are equal, the Z FLAG is set; otherwise the NZ FLAG is set.
4E9D
JR C,4EEEH 38 4F
If the CARRY FLAG has been set (meaning A-80H < 04H, so original character was 80H-83H), JUMP forward to 4EEEH. This handles characters in the 80H-83H range.
4E9F
CP 06H FE 06
Compare Register A against 06H. This checks if the original character was 86H (since we subtracted 80H). If they are equal, the Z FLAG is set; otherwise the NZ FLAG is set.
4EA1
If the CARRY FLAG has been set (meaning A < 06H after subtraction, so original character was 84H or 85H), JUMP to 4F1BH to handle these special command codes.

[READ NEXT CHARACTER FOR COMPOUND COMMAND] Characters 86H and above require reading an additional character parameter.

4EA4
GOSUB to 4F50H to read the next character from the chain file. This character is the parameter for the compound command.
4EA7
LD (42C5H),A 32 C5 42
Store the value held in Register A (the parameter character) into memory location 42C5H. This saves it for later use.
4EAA
If the NZ FLAG (Not Zero) has been set from the CALL 4F50H (indicating normal character read), JUMP forward to 4EB0H to process it.
4EAC
CP 80H FE 80
Compare Register A against 80H. If Register A equals 80H, the Z FLAG is set; otherwise the NZ FLAG is set.
4EAE
JUMP forward to 4EB4H. This always executes, with flags set by the previous CP instruction.
4EB0
CP 1CH FE 1C
Compare Register A against 1CH (position error code). If Register A equals 1CH, the Z FLAG is set; otherwise the NZ FLAG is set.
4EB2
If the NZ FLAG (Not Zero) has been set (meaning the character is NOT 1CH), JUMP forward to 4EE0H to handle as a different error or process normally.
4EB4
If the Z FLAG has been set (from either A=80H at 4EACH or A=1CH at 4EB0H), GOSUB to 4EC5H to clear chaining flags and reset system state.
4EB7
CP 85H FE 85
Compare Register A against 85H. If Register A equals 85H, the Z FLAG is set; otherwise the NZ FLAG is set. This checks for the special 85H code.
4EB9
If the Z FLAG has been set (meaning the character is 85H), JUMP to 4F16H to handle this special code.
4EBC
LD A,B 78
Load Register A with the value from Register B. This restores the original character code from the chain file.
4EBD
CP A BF
Compare Register A with itself. This always sets the Z FLAG and clears the CARRY FLAG. This is used to set known flag states before returning.
4EBE
RET C9
RETurn to caller with Z FLAG set.

4EBFH - DISPLAY "ABORTED" MESSAGE

This short routine displays the "ABORTED" message and then falls through to the chaining cleanup routine.

4EBF
LD HL,4FA2H 21 A2 4F
Point Register Pair HL to address 4FA2H. This address contains the message text "ABORTED" followed by a carriage return.
4EC2
GOSUB to 4F45H. This displays "CHAINING " followed by the message pointed to by HL, then falls through to the cleanup routine at 4EC5H.

4EC5H - CLEAR CHAINING FLAGS AND RESET STATE

This routine clears all chaining-related flags and resets the system to normal keyboard input mode. It clears the chaining active flag, clears buffer flags, and resets write protection flags.

4EC5
LD HL,44A0H 21 A0 44
Point Register Pair HL to address 44A0H, the start of the filename parsing buffer.
4EC8
LD (HL),00H 36 00
Store 00H into the memory location pointed to by HL (44A0H). This clears the first byte of the filename buffer, effectively marking it as empty.
4ECA
LD HL,4289H 21 89 42
Point Register Pair HL to address 4289H, the first DOS system flags byte.
4ECD
RES 5,(HL) CB AE
RESet (clear to 0) bit 5 of the byte at memory location pointed to by HL (4289H). This clears the chaining active flag.
4ECF
INC HL 23
INCrement Register Pair HL, now pointing to 428AH (the second system flags byte).
4ED0
RES 4,(HL) CB A6
RESet (clear to 0) bit 4 of the byte at memory location pointed to by HL (428AH). This clears another system flag related to chaining mode.
4ED2
RET C9
RETurn to caller with chaining flags cleared.

4ED3H - CHECK MINI-DOS AND KEYBOARD CONDITIONS

This routine checks if the system is in a special state where MINI-DOS is active with specific keyboard conditions. If both conditions are met, it clears Register A; otherwise it returns immediately.

4ED3
LD A,(3840H) 3A 40 38
Fetch the byte stored at memory location 3840H and load it into Register A. This is keyboard row 6 status.
4ED6
AND 08HAND 00001000 E6 08
AND Register A with 08H (binary: 00001000), testing bit 3. The Z FLAG will be set if bit 3 is 0, cleared if bit 3 is 1.
4ED8
RET Z C8
If the Z FLAG has been set (meaning bit 3 of the keyboard row is 0), RETurn to caller immediately without modifying A.
4ED9
LD A,(428DH) 3A 8D 42
Fetch the byte stored at memory location 428DH and load it into Register A. This is the system state flags byte.
4EDC
AND 40H E6 40
AND Register A with 40H (binary: 01000000), testing bit 6. The Z FLAG will be set if bit 6 is 0, cleared if bit 6 is 1.
4EDE
RET Z C8
If the Z FLAG has been set (meaning bit 6 of 428DH is 0), RETurn to caller immediately.
4EDF
XOR A AF
XOR Register A with itself, setting Register A to ZERO and setting the Z FLAG. This is reached only if both conditions above were true.

4EE0H - ERROR HANDLER WITH STACK MANIPULATION

This routine handles error conditions by displaying an "ABORTED" message, saving the error code on the stack twice, calling the cleanup routine, and then deciding whether to jump to DOS READY (4030H) or the error display handler (4409H) based on whether Register A is zero.

4EE0
PUSH AF F5
Save Register Pair AF (accumulator and flags) onto the stack. This preserves the error code or character.
4EE1
PUSH AF F5
Save Register Pair AF onto the stack again. This creates a duplicate copy on the stack.
4EE2
GOSUB to 4EBFH. This displays "CHAINING ABORTED" and clears chaining flags by calling through to 4EC5H.
4EE5
POP AF F1
POP (restore) Register Pair AF from the stack. This retrieves one copy of the saved value.
4EE6
POP AF F1
POP (restore) Register Pair AF from the stack again. This retrieves the original value.
4EE7
OR A B7
OR Register A with itself. This sets flags based on the value in A without changing it. The Z FLAG is set if A=00H, cleared otherwise.
4EE8
If the Z FLAG has been set (meaning Register A is 00H), JUMP to SYS0 routine at 4030H. This is the error-already-displayed DOS exit routine.
4EEB
JUMP to SYS0 routine at 4409H. This is the DOS error handler that displays error messages based on the code in Register A.

4EEEH - HANDLE CHARACTERS 80H-83H (OUTPUT TO DISPLAY)

This routine handles special characters in the 80H-83H range read from the chain file. It processes these as commands to output characters to the display, with bit 0 of the character code controlling whether the character should be echoed to the display via ROM routine 0033H.

4EEE
GOSUB to 4F50H to read the next character from the chain file. This is the actual character to be output.
4EF1
If the NZ FLAG (Not Zero) has been set (indicating an error condition from the read), JUMP BACK to 4EE0H to handle the error.
4EF3
PUSH AF F5
Save Register Pair AF (the character just read) onto the stack.
4EF4
BIT 0,B CB 40
Test BIT 0 of Register B (which contains the original 80H-83H command code). The Z FLAG will be set if bit 0 is 0, or NZ FLAG will be set if bit 0 is 1.
4EF6
If the NZ FLAG (Not Zero) has been set (meaning bit 0 of the command was 1, codes 81H or 83H), GOSUB to ROM routine at 0033H. This displays the character in Register A at the cursor position and advances the cursor.
4EF9
POP AF F1
POP (restore) Register Pair AF from the stack, retrieving the character.

[CHECK FOR END OF RECORD] After outputting, check if this was a carriage return (end of record marker).

4EFA
CP 0DH FE 0D
Compare Register A against 0DH (ASCII: ENTER, carriage return). If Register A equals 0DH, the Z FLAG is set; otherwise the NZ FLAG is set.
4EFC
If the NZ FLAG (Not Zero) has been set (meaning the character was NOT a carriage return), LOOP BACK to 4EEEH to read and output another character.

We've reached a carriage return. Check what type of 80H command this was.

4EFE
LD A,B 78
Load Register A with the value from Register B (the original 80H-83H command code).
4EFF
CP 81H FE 81
Compare Register A against 81H. If Register A equals 81H, the Z FLAG is set; otherwise the NZ FLAG is set.
4F01
If the NZ FLAG (Not Zero) has been set (meaning the command was NOT 81H), JUMP forward to 4F13H to continue normal chaining flow.

4F03H - PAUSE HANDLER DURING CHAINING

This routine handles the pause condition when BREAK is pressed during chaining (or when command 81H is processed). It displays a "PAUSE." message and waits for the user to press a key before continuing.

4F03
LD HL,4FAAH 21 AA 4F
Point Register Pair HL to address 4FAAH. This address contains the message text "PAUSE. " (with a trailing space).
4F06
GOSUB to 4F45H. This displays "CHAINING " followed by the pause message.

[WAIT FOR KEY AND CLEAR BREAK] Wait for any keyboard activity and for the BREAK key to be released before continuing.

4F09
GOSUB to 4ED3H. This checks MINI-DOS and keyboard conditions.
4F0C
LD A,(3840H) 3A 40 38
Fetch the byte stored at memory location 3840H and load it into Register A. This reads keyboard row 6 status.
4F0F
AND 01HAND 00000001 E6 01
AND Register A with 01H, testing bit 0 (ENTER key). The Z FLAG will be set if ENTER is NOT pressed (bit 0=0), or NZ FLAG if ENTER IS pressed.
4F11
If the Z FLAG has been set (meaning ENTER is NOT pressed), LOOP BACK to 4F09H to continue waiting.

ENTER has been pressed. Resume chaining.

4F13
JUMP to 4E57H to resume the main chaining loop from the keyboard state check.

4F16H - HANDLE 85H SPECIAL CODE

This routine handles the special 85H code from the chain file. It saves the code in Register C and sets up the original command character for special processing.

4F16
LD C,A 4F
Load Register C with the value from Register A (which is 85H). This saves the special code.
4F17
LD A,B 78
Load Register A with the value from Register B (the original character code from earlier).
4F18
LD (42C5H),A 32 C5 42
Store the value held in Register A into memory location 42C5H. This saves the original character code for later processing.

4F1BH - HANDLE 84H-85H COMMANDS (READ LINE FROM FILE)

This routine handles commands 84H and 85H which read a line of text from the chain file into a buffer. It reads up to 32 (20H) characters or until a carriage return is encountered, storing them in a buffer starting at 4FD7H.

4F1B
LD B,20H 06 20
Load Register B with 20H (32 decimal). This is the maximum number of characters to read.
4F1D
LD HL,4FD7H 21 D7 4F
Point Register Pair HL to address 4FD7H. This is the buffer where the line will be stored.
4F20
PUSH HL E5
Save Register Pair HL (buffer start address) onto the stack for later use.

[READ LINE LOOP] Read characters one at a time until carriage return or buffer full.

4F21
GOSUB to 4F50H to read the next character from the chain file buffer.
4F24
If the NZ FLAG (Not Zero) has been set (indicating an error condition from the read), JUMP BACK to 4EE0H to handle the error.
4F26
CP 0DH FE 0D
Compare Register A against 0DH (ASCII: ENTER, carriage return). If Register A equals 0DH, the Z FLAG is set; otherwise the NZ FLAG is set.
4F28
LD (HL),A 77
Store the value held in Register A (the character just read) into the memory location pointed to by HL (current buffer position).
4F29
INC HL 23
INCrement Register Pair HL, moving to the next buffer position.
4F2A
If the Z FLAG has been set (meaning the character was a carriage return), JUMP forward to 4F32H to complete the line read.
4F2C
DJNZ 4F21H 10 F3
DECrement Register B and Jump if Not Zero to 4F21H. This continues reading characters until either B reaches zero (buffer full) or a carriage return is found.

[BUFFER OVERFLOW ERROR] If we reach here, the buffer is full but no carriage return was found.

4F2E
LD A,01H 3E 01
Load Register A with 01H. This is an error code indicating buffer overflow or line too long.
4F30
JUMP BACK to 4EE0H to display the error and abort chaining.

[LINE READ COMPLETE] Successfully read a complete line ending with carriage return.

4F32
POP HL E1
POP (restore) Register Pair HL from the stack. This retrieves the buffer start address (4FD7H).
4F33
BIT 0,C CB 41
Test BIT 0 of Register C (which contains the command code). The Z FLAG will be set if bit 0 is 0, or NZ FLAG will be set if bit 0 is 1. This distinguishes between 84H (bit 0=0) and 85H (bit 0=1).
4F35
If the NZ FLAG (Not Zero) has been set (meaning the command was 85H with bit 0=1), JUMP to 4E7EH to process filename flags and continue chaining.

[COMMAND 84H PATH - PARSE AND LOAD FILE] The line in the buffer should be a filespec. Parse and attempt to load it.

4F38
LD DE,44A0H 11 A0 44
Load Register Pair DE with address 44A0H, pointing to the filename parsing buffer.
4F3B
GOSUB to SYS0 routine at 443FH. This parses the filespec from (HL) into the FCB template at (DE).
4F3E
If the Z FLAG has been set (meaning the filespec parsed successfully), GOSUB to 4E06H to perform file verification and loading.
4F41
If the NZ FLAG (Not Zero) has been set (indicating an error in parsing or loading), JUMP BACK to 4EE0H to handle the error.
4F43
JUMP BACK to 4F13H to resume the main chaining loop.

4F45H - DISPLAY "CHAINING " PREFIX THEN MESSAGE

This routine displays the "CHAINING " prefix message followed by whatever message is pointed to by HL. It's used to provide context for various chaining-related status messages.

4F45
PUSH HL E5
Save Register Pair HL (pointer to the message to display after "CHAINING ") onto the stack.
4F46
LD HL,4F98H 21 98 4F
Point Register Pair HL to address 4F98H. This address contains the message text "CHAINING " (with trailing space).
4F49
GOSUB to SYS0 routine at 4467H to display the "CHAINING " prefix message.
4F4C
POP HL E1
POP (restore) Register Pair HL from the stack, retrieving the pointer to the second message.
4F4D
JUMP to SYS0 routine at 4467H to display the second message and return from there.

4F50H - READ CHARACTER FROM CHAIN FILE BUFFER

This is the main character input routine for chaining operations. It reads characters from the filename buffer at 44A0H, handling special delimiter sequences ("/.." pattern) and performing automatic buffer refilling when needed. Returns characters in Register A with Z FLAG set for special conditions.

4F50
GOSUB to 4F8CH. This reads a character from the filename buffer at 44A0H and returns it in Register A.
4F53
RET NZ C0
If the NZ FLAG (Not Zero) has been set (indicating a normal character was read), RETurn to caller immediately with the character in A.

[SPECIAL DELIMITER HANDLING] If Z FLAG is set from 4F8CH, we hit end of buffer. Check for the "/.." delimiter pattern.

4F54
PUSH BC C5
Save Register Pair BC onto the stack.
4F55
CP 2FH FE 2F
Compare Register A against 2FH (ASCII: /). If Register A equals 2FH, the Z FLAG is set; otherwise the NZ FLAG is set.
4F57
LD B,A 47
Load Register B with the value from Register A. This saves the first character of the potential delimiter.
4F58
LD A,(44A5H) 3A A5 44
Fetch the byte stored at memory location 44A5H and load it into Register A. This is the character position counter in the filename buffer.
4F5B
LD C,A 4F
Load Register C with the value from Register A. This saves the current position.
4F5C
If the Z FLAG has been set (meaning the first character was /), GOSUB to 4F8CH to read the next character.
4F5F
If the NZ FLAG (Not Zero) has been set (indicating a normal character was read, not end of buffer), JUMP forward to 4F76H. The pattern didn't complete.
4F61
CP 2EH FE 2E
Compare Register A against 2EH (ASCII: .). If Register A equals 2EH, the Z FLAG is set; otherwise the NZ FLAG is set. Checking for "/.."
4F63
If the Z FLAG has been set (meaning the second character was ., so far we have "/."), GOSUB to 4F8CH to read the third character.
4F66
If the NZ FLAG (Not Zero) has been set (not end of buffer), JUMP forward to 4F76H. The pattern didn't complete.
4F68
CP B B8
Compare Register A with Register B (which contains the first character). For the "/.." pattern, this checks if the third character also matches the first.
4F69
If the Z FLAG has been set (meaning all three characters matched so far, like "/.."), GOSUB to 4F8CH to read what follows.
4F6C
If the NZ FLAG (Not Zero) has been set, JUMP forward to 4F76H. The complete pattern wasn't found.

[DELIMITER PATTERN FOUND] We found the complete "/.." delimiter. Check if the following character is a valid hex digit 0-5.

4F6E
SUB 30H D6 30
SUBtract 30H from Register A. This converts ASCII '0'-'9' to binary 0-9. If A was '0', result is 00H and Z FLAG is set.
4F70
CP 06H FE 06
Compare Register A against 06H. If Register A is less than 06H, the CARRY FLAG is set; if greater or equal, NO CARRY FLAG is set.
4F72
SET 7,A CB FF
SET (set to 1) bit 7 of Register A. This converts the value 0-5 into 80H-85H, marking it as a special command code.
4F74
JR C,4F89H 38 13
If the CARRY FLAG has been set (meaning the character after "/.." was '0'-'5'), JUMP forward to 4F89H to set Z FLAG and return the special code (80H-85H).

[PATTERN INVALID - RESTORE POSITION] The "/.." pattern was not followed by a valid digit. Restore the buffer position.

4F76
LD A,(44A5H) 3A A5 44
Fetch the current character position counter from memory location 44A5H and load it into Register A.
4F79
SUB C 91
SUBtract Register C (the saved position from 4F5BH) from Register A. This calculates how many characters we read while checking the pattern.
4F7A
LD (44A9H),A 32 A9 44
Store the value held in Register A (the character count difference) into memory location 44A9H.
4F7D
If the NZ FLAG (Not Zero) has been set (meaning we read some characters), GOSUB to SYS0 routine at 4445H. This adjusts the buffer position.
4F80
If the NZ FLAG (Not Zero) has been set, JUMP forward to 4F8AH to restore BC and return.
4F82
LD A,B 78
Load Register A with the value from Register B (the first character we read).
4F83
CP 86H FE 86
Compare Register A against 86H. This checks if the first character value is less than 86H.
4F85
JR C,4F89H 38 02
If the CARRY FLAG has been set (meaning A < 86H), JUMP forward to 4F89H to set Z FLAG and return.
4F87
AND 7FHAND 01111111 E6 7F
AND Register A with 7FH (binary: 01111111). This clears bit 7, converting codes 80H-FFH to 00H-7FH.
4F89
CP A BF
Compare Register A with itself. This always sets the Z FLAG and clears the CARRY FLAG. This marks the character as special.
4F8A
POP BC C1
POP (restore) Register Pair BC from the stack.
4F8B
RET C9
RETurn to caller with the character in A and flags set appropriately (Z FLAG if special code, NZ FLAG if error or normal).

4F8CH - FETCH NEXT CHARACTER FROM FILENAME BUFFER

This routine fetches the next character from the filename buffer at 44A0H. If it reaches end of buffer (returns 00H), it attempts to refill the buffer by calling ROM input routine 0013H. Returns character in Register A with Z FLAG set if end of buffer.

4F8C
LD DE,44A0H 11 A0 44
Load Register Pair DE with address 44A0H, pointing to the filename parsing buffer.
4F8F
GOSUB to ROM routine at 0013H. This gets the next character from the buffer at (DE), returning it in Register A. Returns Z FLAG if at end of buffer (character is 00H).
4F92
RET NZ C0
If the NZ FLAG (Not Zero) has been set (meaning a non-zero character was read), RETurn to caller immediately with the character.
4F93
OR A B7
OR Register A with itself. Since A is 00H (from the end of buffer), this sets the Z FLAG.
4F94
If the Z FLAG has been set (always true here since A=00H), LOOP BACK to 4F8CH to try reading again. This creates an infinite loop until a non-zero character is obtained.
4F96
CP A BF
Compare Register A with itself. This always sets the Z FLAG. This line is effectively unreachable due to the infinite loop at 4F94H.
4F97
RET C9
RETurn to caller. This is also unreachable.

4F98H - MESSAGE DATA AREA

This section contains all the text messages used by SYS9, stored as null-terminated ASCII strings. Each message ends with either a carriage return (0DH) or a null byte (03H) as a terminator.

4F98
DEFB "CHAINING " 43 48 41 49 4E 49 4E 47 20
Message text: "CHAINING " (with trailing space). Used as a prefix for various chaining status messages.
4FA0
DEFB 03H 03
Message terminator (null byte).
4FA2
DEFB "ABORTED" 41 42 4F 52 54 45 44
Message text: "ABORTED". Displayed when chaining is terminated due to an error or user break.
4FA9
DEFB 0DH 0D
Message terminator (carriage return).
4FAA
DEFB "PAUSE. " 50 41 55 53 45 2E 20
Message text: "PAUSE. " (with trailing space). Displayed when the system pauses during chaining (BREAK pressed or command 81H).
4FB1
DEFB 03H 03
Message terminator (null byte).
4FB2
DEFB "PRESS 'ENTER' WHEN READY TO CONTINUE" 50 52 45 53 53 20 27 45 4E 54 45 52 27 20 57 48 45 4E 20 52 45 41 44 59 20 54 4F 20 43 4F 4E 54 49 4E 55 45
Message text: "PRESS 'ENTER' WHEN READY TO CONTINUE". Displayed by the PAUSE command to prompt the user.
4FD6
DEFB 0DH 0D
Message terminator (carriage return).

4FD7H - BOOT COMMAND HANDLER AND LINE BUFFER

This section serves dual purposes: it's the entry point for the BOOT/reset command (subcommand 2 of EBH group), and it also contains a 32-byte buffer used for reading lines from chain files. The BOOT command initializes registers and performs a system reset sequence.

4FD7
LD DE,51E0H 11 E0 51
Load Register Pair DE with address 51E0H. This is a temporary buffer area used during file operations.
4FDA
LD HL,4DDCH 21 DC 4D
Point Register Pair HL to address 4DDCH. This is the subcommand 3 handler routine address.
4FDD
LD (4483H),HL 22 83 44
Store Register Pair HL into memory locations 4483H-4484H. This sets up a handler address pointer.
4FE0
LD A,44H 3E 44
Load Register A with 44H. This is a parameter value for the following routine.
4FE2
GOSUB to 4DC7H. This performs register swapping and setup operations, preparing for a special operation mode.
4FE5
LD A,00H 3E 00
Load Register A with 00H (zero). This clears the accumulator.
4FE7
LD (4288H),A 32 88 42
Store the value held in Register A (00H) into memory location 4288H. This clears a system flag or state byte.
4FEA
LD HL,(448CH) 2A 8C 44
Load Register Pair HL with the 16-bit value stored at memory locations 448CH-448DH. This appears to be a saved address or counter.
4FED
LD A,(4488H) 3A 88 44
Fetch the byte stored at memory location 4488H and load it into Register A.
4FF0
OR A B7
OR Register A with itself. This sets flags based on the value in A without changing it. The Z FLAG will be set if A=00H.
4FF1
If the NZ FLAG (Not Zero) has been set (meaning the value at 4488H was not zero), JUMP forward to 4FF4H.
4FF3
DEC HL 2B
DECrement Register Pair HL by 1. This adjusts the address/counter when the flag was zero.
4FF4
LD A,H 7C
Load Register A with the value from Register H (high byte of HL).
4FF5
AND L A5
AND Register A with Register L. If both H and L are FFH, the result will be FFH. Otherwise, at least one bit will be 0.
4FF6
INC A 3C
INCrement Register A by 1. If A was FFH, it becomes 00H and Z FLAG is set.

[ENTRY POINT FOR TEMPLATE/STRUCTURE AT 4FF7H] This is also used as a pointer target by code at 4DE8H.

4FF7
If the Z FLAG has been set (meaning HL was FFFFH before incrementing A), JUMP forward to 5026H.
4FF9
LD (51EAH),HL 22 EA 51
Store Register Pair HL into memory locations 51EAH-51EBH. This saves the address in the temporary buffer area.
4FFC
EXX D9
EXchange register pairs BC, DE, and HL with their alternate (shadow) counterparts. This switches to the alternate register set.
4FFD
LD HL,4439H 21 39 44
Point Register Pair HL to address 4439H in the alternate register set. This is a routine address in SYS0.
5000
EXX D9
EXchange back to the primary register set.
5001
XOR A AF
XOR Register A with itself, setting Register A to ZERO and setting the Z FLAG.
5002
GOSUB to 4DC7H again to perform register setup with A=00H.
5005
LD A,00H 3E 00
Load Register A with 00H. This explicitly clears A (redundant after XOR A above).
5007
LD (4288H),A 32 88 42
Store the value held in Register A (00H) into memory location 4288H. This clears the system flag again.

[FILE PROCESSING LOOP] The following code processes files from the buffer.

500A
GOSUB to SYS0 routine at 443FH. This parses a filespec from buffer into FCB template.
500D
RET NZ C0
If the NZ FLAG (Not Zero) has been set (indicating an error in parsing), RETurn to caller immediately.
500E
LD DE,4480H 11 80 44
Load Register Pair DE with address 4480H, another filename buffer area.
5011
GOSUB to SYS0 routine at 4436H. This performs file operations with the parsed filespec.
5014
If the NZ FLAG (Not Zero) has been set (indicating completion or error), JUMP forward to 501FH to check the error code.
5016
LD DE,51E0H 11 E0 51
Load Register Pair DE with address 51E0H, the temporary buffer area.
5019
GOSUB to SYS0 routine at 4439H. This performs additional file processing.
501C
RET NZ C0
If the NZ FLAG (Not Zero) has been set (error), RETurn to caller.
501D
JUMP BACK to 500EH to continue processing files in a loop.

[CHECK ERROR CODE] Determine if the error is position-related (1CH/1DH) or something else.

501F
CP 1CH FE 1C
Compare Register A against 1CH (position error - before start of file). If Register A equals 1CH, the Z FLAG is set; otherwise the NZ FLAG is set.
5021
If the Z FLAG has been set (error is 1CH), JUMP forward to 5026H to complete processing.
5023
CP 1DH FE 1D
Compare Register A against 1DH (position error - past EOF). If Register A equals 1DH, the Z FLAG is set; otherwise the NZ FLAG is set.
5025
RET NZ C0
If the NZ FLAG (Not Zero) has been set (error is NOT 1DH), RETurn to caller with the error.

[FINALIZE BOOT PROCESSING] Save state and prepare for final operations.

5026
LD HL,(448CH) 2A 8C 44
Load Register Pair HL with the 16-bit value stored at memory locations 448CH-448DH.
5029
LD (51ECH),HL 22 EC 51
Store Register Pair HL into memory locations 51ECH-51EDH in the temporary buffer area.
502C
LD A,(4488H) 3A 88 44
Fetch the byte stored at memory location 4488H and load it into Register A.
502F
LD (51E8H),A 32 E8 51
Store the value held in Register A into memory location 51E8H in the temporary buffer.
5032
LD DE,51E0H 11 E0 51
Load Register Pair DE with address 51E0H, pointing to the temporary buffer start.

[WAIT FOR KEY LOOP] Wait for a keypress before continuing.

5035
GOSUB to SYS0 routine at 443FH to parse filespec.
5038
RET NZ C0
If the NZ FLAG (Not Zero) has been set (error), RETurn to caller.
5039
GOSUB to SYS0 routine at 4436H for file operations.
503C
If the Z FLAG has been set (operation not complete), LOOP BACK to 5039H to continue.
503E
CP 1CH FE 1C
Compare Register A against 1CH. If Register A equals 1CH, the Z FLAG is set; otherwise the NZ FLAG is set.
5040
If the Z FLAG has been set (error code is 1CH), JUMP forward to 5045H.
5042
CP 1DH FE 1D
Compare Register A against 1DH. If Register A equals 1DH, the Z FLAG is set; otherwise the NZ FLAG is set.
5044
RET NZ C0
If the NZ FLAG (Not Zero) has been set (error is neither 1CH nor 1DH), RETurn to caller with the error.
5045
JUMP to SYS0 routine at 4428H. This appears to be a completion or finalization routine.

5048H - '+' COMMAND HANDLER (STACK PUSH)

This routine handles the '+' command (2BH) which manipulates the stack by pushing values. It stores the current return address and program counter onto a special stack area pointed to by 4058H.

5048
GOSUB to 50A3H. This validates that HL is in the valid range (>= 5200H) and adjusts HL pointer, returning with Z FLAG set if valid.
504B
RET NZ C0
If the NZ FLAG (Not Zero) has been set (address out of range error), RETurn to caller immediately.
504C
DEC HL 2B
DECrement Register Pair HL by 1, moving to the next stack slot.
504D
LD DE,(4058H) ED 5B 58 40
Load Register Pair DE with the 16-bit value stored at memory locations 4058H-4059H. This is the current stack pointer for the '+' command stack.
5051
LD (HL),D 72
Store the value held in Register D (high byte) into the memory location pointed to by HL.
5052
DEC HL 2B
DECrement Register Pair HL by 1.
5053
LD (HL),E 73
Store the value held in Register E (low byte) into the memory location pointed to by HL.
5054
LD D,H 54
Load Register D with the value from Register H. This copies the high byte of the new pointer.
5055
LD E,L 5D
Load Register E with the value from Register L. DE now contains the updated pointer.
5056
DEC HL 2B
DECrement Register Pair HL by 1.
5057
LD (HL),D 72
Store the value held in Register D into the memory location pointed to by HL.
5058
DEC HL 2B
DECrement Register Pair HL by 1.
5059
LD (HL),E 73
Store the value held in Register E into the memory location pointed to by HL. This completes storing the 4-byte entry.
505A
LD (4058H),HL 22 58 40
Store Register Pair HL into memory locations 4058H-4059H. This updates the stack pointer to point to the new top of stack.
505D
XOR A AF
XOR Register A with itself, setting Register A to ZERO and setting the Z FLAG.
505E
RET C9
RETurn to caller with A=00H and Z FLAG set, indicating success.

505FH - 'K' COMMAND HANDLER (STACK POP/KILL)

This routine handles the 'K' command (4BH) which removes (kills) entries from the '+' command stack. It validates the stack pointer, reads values from the stack, and updates the stack pointer.

505F
GOSUB to 50A3H to validate the stack address range and adjust HL.
5062
If the Z FLAG has been set (meaning HL is in valid range), JUMP forward to 509EH for normal completion.
5064
XOR A AF
XOR Register A with itself, setting Register A to ZERO.
5065
DEC HL 2B
DECrement Register Pair HL by 1.
5066
LD (HL),A 77
Store the value held in Register A (00H) into the memory location pointed to by HL. This clears the byte.
5067
INC HL 23
INCrement Register Pair HL by 1, restoring it to the original value.
5068
LD C,(HL) 4E
Load Register C with the byte stored at the memory location pointed to by HL.
5069
INC HL 23
INCrement Register Pair HL by 1.
506A
LD B,(HL) 46
Load Register B with the byte stored at the memory location pointed to by HL. BC now contains a 16-bit value read from the stack.
506B
EX DE,HL EB
EXchange Register Pairs DE and HL. The stack address is now in DE.
506C
LD (HL),C 71
Store the value held in Register C into the memory location pointed to by HL.
506D
INC HL 23
INCrement Register Pair HL by 1.
506E
LD (HL),B 70
Store the value held in Register B into the memory location pointed to by HL. This writes the value back somewhere.
506F
RET C9
RETurn to caller.

5070H - SUBCOMMAND 7 HANDLER (FILENAME PROCESSING)

This routine handles subcommand 7 of the EBH command group. It processes filename specifications by reading up to 9 characters from the buffer into the temporary area at 51E0H, padding with spaces if necessary, and then calling directory lookup routines.

5070
LD DE,51E0H 11 E0 51
Load Register Pair DE with address 51E0H, pointing to the temporary buffer area.
5073
LD B,09H 06 09
Load Register B with 09H (9 decimal). This is the maximum number of characters to read for a filename (8 characters + 1 for extension).

[CHARACTER READ LOOP] Read up to 9 characters from the filename buffer.

5075
PUSH DE D5
Save Register Pair DE (buffer pointer) onto the stack.
5076
INC HL 23
INCrement Register Pair HL, moving to the next character in the source.
5077
GOSUB to SYS0 routine at 4C7AH. This calculates the physical disk sector from logical parameters and returns with CARRY FLAG set on error.
507A
JR NC,5083H 30 07
If the NO CARRY FLAG has been set (meaning no error in sector calculation), JUMP forward to 5083H to handle as end of data.
507C
LD A,(HL) 7E
Load Register A with the byte stored at the memory location pointed to by HL (the character just read).
507D
LD (DE),A 12
Store the value held in Register A into the memory location pointed to by DE (current position in 51E0H buffer).
507E
INC DE 13
INCrement Register Pair DE, moving to the next buffer position.
507F
DJNZ 5076H 10 F5
DECrement Register B and Jump if Not Zero to 5076H. This continues reading characters until B reaches zero (9 characters read).
5081
LD B,09H 06 09
Load Register B with 09H (9 decimal). This reloads the counter, suggesting we're about to process padding or check the count.

[PADDING WITH SPACES] If we didn't read all 9 characters, pad the remaining positions with spaces.

5083
LD A,B 78
Load Register A with the value from Register B (number of characters remaining unread).
5084
CP 09H FE 09
Compare Register A against 09H. If Register A equals 09H (meaning no characters were read), the Z FLAG is set; otherwise the NZ FLAG is set.
5086
If the Z FLAG has been set (meaning B=09H, no characters were read), JUMP to 4D4CH to display error code 2FH and exit.
5089
LD A,20H 3E 20
Load Register A with 20H (ASCII: SPACE). This is the padding character.
508B
LD (DE),A 12
Store the value held in Register A (space character) into the memory location pointed to by DE.
508C
INC DE 13
INCrement Register Pair DE, moving to the next buffer position.
508D
DJNZ 5089H 10 FA
DECrement Register B and Jump if Not Zero to 5089H. This pads the remaining positions with spaces until all 9 positions are filled.

[CALL DIRECTORY LOOKUP] The filename is now complete in the buffer. Process it with directory routines.

508F
EX (SP),HL E3
EXchange the value in Register Pair HL with the 16-bit value on top of the stack. This swaps the current position with the saved buffer start address.
5090
GOSUB to 50ADH. This performs a directory lookup operation using the filename in the buffer.
5093
LD DE,000AH 11 0A 00
Load Register Pair DE with 000AH (10 decimal). This is an offset value.
5096
ADD HL,DE 19
ADD Register Pair DE to Register Pair HL. This advances HL by 10 bytes, moving to the next directory entry or structure.
5097
POP DE D1
POP (restore) Register Pair DE from the stack. This retrieves the saved buffer pointer from the beginning of the loop.
5098
If the Z FLAG has been set (meaning the lookup completed successfully or reached end), JUMP forward to 509EH.
509A
EX (SP),HL E3
EXchange the value in Register Pair HL with the 16-bit value on top of the stack.
509B
PUSH HL E5
Save Register Pair HL onto the stack.
509C
EX DE,HL EB
EXchange Register Pairs DE and HL.
509D
RET C9
RETurn to caller to continue processing.

[COMPLETION OR ERROR] Either the lookup completed or we need to handle an error.

509E
LD A,18H 3E 18
Load Register A with 18H. This is an error code.
50A0
JUMP to 4D4EH to display the error and exit.

50A3H - VALIDATE STACK ADDRESS RANGE

This routine validates that the address in HL is within the valid range for stack operations (must be >= 5200H). It performs the check and adjusts HL by adding 4, returning with Z FLAG set if the address is valid, or jumping to an error handler if out of range.

50A3
LD A,H 7C
Load Register A with the value from Register H (high byte of the address to validate).
50A4
CP 52H FE 52
Compare Register A against 52H. If Register A is less than 52H, the CARRY FLAG is set; if greater or equal, NO CARRY FLAG is set. This checks if the address is >= 5200H.
50A6
If the CARRY FLAG has been set (meaning the address is less than 5200H, out of valid range), JUMP to 4D4CH to display error code 2FH.
50A9
INC HL 23
INCrement Register Pair HL by 1.
50AA
INC HL 23
INCrement Register Pair HL by 1 again.
50AB
INC HL 23
INCrement Register Pair HL by 1 again.
50AC
INC HL 23
INCrement Register Pair HL by 1 again. HL has now been incremented by 4 total, moving past a 4-byte stack entry.

50ADH - DIRECTORY LOOKUP AND COMPARISON

This routine performs directory lookups by scanning through a linked list structure stored at 4058H. It reads entries, compares filenames, and returns information about matching entries. The routine handles the special stack structure used by the '+' and 'K' commands.

50AD
PUSH HL E5
Save Register Pair HL (current position pointer) onto the stack.
50AE
LD HL,4058H 21 58 40
Point Register Pair HL to address 4058H. This is the base pointer for the stack structure used by '+' and 'K' commands.
50B1
PUSH HL E5
Save Register Pair HL (the 4058H pointer) onto the stack.
50B2
PUSH HL E5
Save Register Pair HL onto the stack again. This creates a duplicate for loop control.

[DIRECTORY SCAN LOOP START] Walk through the linked list of directory entries.

50B3
POP BC C1
POP (restore) Register Pair BC from the stack. BC now contains the pointer we just pushed (4058H initially).
50B4
POP HL E1
POP (restore) Register Pair HL from the stack. This retrieves the base pointer.
50B5
LD B,H 44
Load Register B with the value from Register H.
50B6
LD C,L 4D
Load Register C with the value from Register L. BC now contains a copy of HL.
50B7
LD E,(HL) 5E
Load Register E with the byte stored at the memory location pointed to by HL (low byte of next pointer).
50B8
INC HL 23
INCrement Register Pair HL by 1.
50B9
LD D,(HL) 56
Load Register D with the byte at (HL) (high byte of next pointer). DE now contains the pointer to the next entry in the list.
50BA
LD A,D 7A
Load Register A with the value from Register D (high byte of pointer).
50BB
OR E B3
OR Register A with Register E. If both D and E are zero (pointer is 0000H), the Z FLAG will be set, indicating end of list.
50BC
If the NZ FLAG (Not Zero) has been set (meaning the pointer is NOT null), JUMP forward to 50C0H to process this entry.

[END OF LIST REACHED] The pointer was null, so we've scanned the entire list.

50BE
POP HL E1
POP (restore) Register Pair HL from the stack (the original position pointer saved at 50ADH).
50BF
RET C9
RETurn to caller with Z FLAG set (from the OR at 50BBH), indicating end of list.

[PROCESS DIRECTORY ENTRY] We have a valid pointer in DE. Read the entry and compare filenames.

50C0
EX DE,HL EB
EXchange Register Pairs DE and HL. HL now points to the directory entry to process.
50C1
LD E,(HL) 5E
Load Register E with the byte stored at the memory location pointed to by HL.
50C2
INC HL 23
INCrement Register Pair HL by 1.
50C3
LD D,(HL) 56
Load Register D with the byte at (HL). DE now contains another pointer or data value from the entry.
50C4
INC HL 23
INCrement Register Pair HL by 1, now pointing to the filename data in the entry.
50C5
OR A B7
OR Register A with itself. This sets flags based on A (which still contains D from 50BAH). Clears the CARRY FLAG.
50C6
SBC HL,DE ED 52
SuBtract with Carry Register Pair DE from Register Pair HL. This compares the two addresses. If HL=DE, the Z FLAG is set.
50C8
POP HL E1
POP (restore) Register Pair HL from the stack (the original position pointer).
50C9
If the NZ FLAG (Not Zero) has been set (meaning the comparison showed the addresses were different), JUMP to 4D46H to display error code 33H.

[COMPARE FILENAMES] The addresses matched. Now compare the actual filename data.

50CC
PUSH HL E5
Save Register Pair HL (position pointer) onto the stack again.
50CD
PUSH DE D5
Save Register Pair DE onto the stack.
50CE
PUSH BC C5
Save Register Pair BC onto the stack.
50CF
INC DE 13
INCrement Register Pair DE by 1.
50D0
INC DE 13
INCrement Register Pair DE by 1 again. DE now points 2 bytes past the data value, to the start of the filename in the entry.
50D1
LD B,08H 06 08
Load Register B with 08H (8 decimal). This is the number of characters to compare (standard filename length).

[CHARACTER COMPARISON LOOP] Compare 8 characters of the filename.

50D3
LD A,(DE) 1A
Load Register A with the byte stored at the memory location pointed to by DE (character from directory entry).
50D4
SUB (HL) 96
SUBtract the byte at (HL) from Register A. If they are equal, A becomes 00H and Z FLAG is set; if different, NZ FLAG is set.
50D5
INC DE 13
INCrement Register Pair DE, moving to the next character in the directory entry.
50D6
INC HL 23
INCrement Register Pair HL, moving to the next character in the search filename.
50D7
If the NZ FLAG (Not Zero) has been set (meaning the characters did NOT match), JUMP BACK to 50B3H to continue searching the next entry in the list.
50D9
DJNZ 50D3H 10 F8
DECrement Register B and Jump if Not Zero to 50D3H. This continues comparing characters until all 8 have been checked or a mismatch is found.

[FILENAME MATCH FOUND] All 8 characters matched. Clean up the stack and return success.

50DB
POP DE D1
POP (restore) Register Pair DE from the stack.
50DC
POP HL E1
POP (restore) Register Pair HL from the stack.
50DD
POP BC C1
POP (restore) Register Pair BC from the stack.
50DE
OR 35H F6 35
OR Register A with 35H. Since A was 00H from the successful comparison, this sets A to 35H and clears the Z FLAG, setting the NZ FLAG to indicate a match was found.
50E0
RET C9
RETurn to caller with NZ FLAG set, indicating a matching filename was found in the directory.

50E1H - FINAL MESSAGE DATA AND NOP PADDING

This section contains the remaining message strings used by SYS9, followed by NOP padding to fill out the module to its end address. The messages are for the "RUN ONLY" stopped condition and the fatal error display.

50E1
DEFB "'RUN ONLY' STOPPED" 27 52 55 4E 20 4F 4E 4C 59 27 20 53 54 4F 50 50 45 44
Message text: "'RUN ONLY' STOPPED". Displayed by subcommand 12 when a run-only program has been halted.
50F3
DEFB 03H 03
Message terminator (null byte).
50F4
DEFB "DOS FATAL ERROR" 44 4F 53 20 46 41 54 41 4C 20 45 52 52 4F 52
Message text: "DOS FATAL ERROR". Displayed by subcommand 11 to indicate a critical system error.
5103
DEFB 03H 03
Message terminator (null byte).
5104
DEFB "!!! KEY 'R' FOR RESET." 21 21 21 20 20 20 4B 45 59 20 27 52 27 20 46 4F 52 20 52 45 53 45 54 2E
Message text: "!!! KEY 'R' FOR RESET." (with leading spaces). Prompts the user to press R to reset the system after a fatal error.
5119
DEFB 0DH 0D
Message terminator (carriage return).

511BH - CHECK FLAGS AND CONDITIONAL RETURN

This routine checks the value in Register A and system flags to determine the appropriate return path. If A is non-zero, it jumps to 4E90H. If certain flag conditions are met, it performs a conditional DOS Ready return.

511B
OR A B7
OR Register A with itself. This sets flags based on the value in A without changing it. The Z FLAG will be set if A=00H.
511C
If the NZ FLAG (Not Zero) has been set (meaning Register A is not zero), JUMP to 4E90H to process the character from the chain file.
511F
LD A,B 78
Load Register A with the value from Register B (which contains system flags from earlier).
5120
AND 50H E6 50
AND Register A with 50H (binary: 01010000), masking bits 6 and 4. The Z FLAG will be set if both bits are 0.
5122
CP 40H FE 40
Compare Register A against 40H. If Register A equals 40H (meaning bit 6 is set, bit 4 is clear), the Z FLAG is set; otherwise the NZ FLAG is set.
5124
If the Z FLAG has been set (meaning the flag pattern is 40H), JUMP to SYS0 routine at 402DH. This is the warm start / DOS Ready entry point.
5127
RET C9
RETurn to caller if the special condition was not met.

5128H - NOP PADDING TO MODULE END

This section contains NOP (No OPeration) instructions that pad the module from 5128H to 51DFH, filling the unused space in the SYS9 overlay area. This ensures the module occupies its full allocated memory region from 4D00H to 51FFH.

5128-51DF
NOP (repeated) 00 (repeated 184 times)
No OPeration padding. These 184 bytes (B8H bytes) fill the space from 5128H to 51DFH with NOP instructions (00H). This ensures the module ends at the correct boundary before the temporary buffer area at 51E0H.

51E0H - TEMPORARY BUFFER AREA (NOT SHOWN IN DISASSEMBLY)

The disassembly ends at 51DFH. The memory region from 51E0H to 51FFH (32 bytes) is used as a temporary buffer by various routines in SYS9, particularly for file operations and the BOOT command handler. This buffer is not shown in the disassembly because it contains data, not code.

[END OF SYS9/SYS CODE] The SYS9 module code ends at 51DFH. Memory from 51E0H-51FFH is reserved as a working buffer area used by the routines in this module.