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

Page Customization

SYS20/SYS - BASIC Disk Statement Executor

SYS20/SYS is the primary resident module during BASIC program execution, handling a comprehensive set of disk-related BASIC statements and functions. This module provides the core infrastructure for file operations, memory management, and BASIC statement execution while programs are running.

Primary Functions:

  • CMD Statement Processing: Handles CMD"=" assignments and CMD"F" file operations with sophisticated function dispatching
  • Memory Management: RAM testing, buffer allocation, stack validation, and workspace initialization
  • File Operations: FRE() function, CLOSE/OPEN validation, KILL statement, FILE statement, SYSTEM statement
  • String Functions: INKEY$ implementation with comprehensive input character handling
  • Error Handling: Integrated error checking and DOS error translation throughout all operations

Module Architecture:

The module is structured around several key functional areas:

  • Entry Points (5200H-5202H): Module validation and call dispatcher entry
  • CMD"=" Processor (5203H-529AH): Assignment statement handler with memory testing and stack management
  • Memory Test Routines (529BH-52E1H): RAM verification using pattern testing (A5H pattern) with comprehensive validation
  • CMD"==" Dispatcher (52E2H-5314H): Function table lookup and execution for file-related commands
  • FRE() function (5315H-5323H)
  • CLOSE validation (5326H-5341H)
  • OPEN validation (5342H-535BH)
  • KILL statement (535EH-5364H)
  • FILE statement (5367H-536DH)
  • SYSTEM statement (5370H-537EH)
  • String function handlers (LEN, ASC, STR,VAL,LEFT, VAL, LEFT,VAL,LEFT, RIGHT,CHR, CHR ,CHR) (5381H-53B3H)
  • File Operations (5383H-55F9H): CLOSE, OPEN validation, KILL, FILE, SYSTEM implementations
  • INKEY$ Handler (55FAH-56ADH): Character input processing with quote handling and delimiter recognition
  • INPUT# processing (with detailed state machine explanation) (560EH-56ACH)
  • Reserved space (58 NOPs) (56AEH-56E7H)

Technical Highlights:

  • Self-Modifying Code: Multiple locations used for temporary storage and dynamic code generation
  • Stack Management: Sophisticated SP preservation and workspace allocation at 70FCH
  • Memory Protection: Comprehensive bounds checking against MEMSIZ (40FDH) and buffer limits
  • Pattern-Based Testing: Uses A5H pattern with XOR verification for RAM validation (64 bytes tested)
  • Function Dispatch Tables: CMD"F" uses indexed table lookup at 5952H for command routing

Variables:

AddressBytesPurpose
5271H-5273H3Self-modifying: LD HL,0000H instruction - stores calculated buffer size
5272H-5273H2Storage: Available memory size (calculated workspace)
5275H-5276H2Storage: Buffer base address
5278H-5279H2Storage: Original buffer pointer (for restoration)
528FH-5290H2Self-modifying: LD SP,0000H instruction - stores stack pointer for restoration
5290H-5291H2Storage: Saved stack pointer value
52C8H-52CAH3Self-modifying: LD HL,0000H instruction - stores test buffer address
52C9H-52CAH2Storage: RAM test workspace pointer (64-byte test area)
5716H1Error flag: Set to 01H when INKEY$ input error detected (used at 568FH)
5952H+VariableCMD"F" function dispatch table: byte count, function string, jump address triples
56AEH-56E7H58Reserved/padding: NOP instructions for future expansion or alignment

Key System Variables Used:

AddressBytesPurpose
40A7H2BASIC work pointer - current position in BASIC text being processed
40B1H2STREND - end of string storage area
40FDH2MEMSIZ - highest usable memory address (used for bounds checking)
4318H1System state flag (related to BASIC execution state)
436AH1I/O flag byte (bit 7 set during operations to prevent recursion)

Disassembly:

5200H - Module Entry Point

Entry point for SYS20 module. The CP A instruction sets Z flag if A=0 (module validation check), then immediately returns. This is a standard module signature pattern used by NEWDOS/80 to verify module presence.

5200
CP A BF
Compare Register A with itself. This always sets the Z FLAG (indicating equal), and is used as a module signature/validation check. When called as a validation test, the Z FLAG return confirms the module is present and valid.
5201
RET C9
Return to caller with Z FLAG set, confirming module validation.

5202H - CMD"=" Assignment Statement Processor

Handles CMD"=" assignments that evaluate expressions and potentially store results in memory. This sophisticated routine performs memory bounds checking, RAM testing, and workspace management. The routine validates that sufficient memory exists, tests RAM integrity using pattern verification, and manages stack allocation for expression evaluation.

5202
POP BC C1
Pop return address from the stack into BC. This is the address to return to after processing the CMD"=" statement. The return address is saved because the routine will manipulate the stack extensively.
5203
LD D,H 54
Copy Register H to Register D. This begins saving the current HL register (which points to the BASIC text) to the DE register pair for later use.
5204
LD E,L 5D
Copy Register L to Register E, completing the transfer of HL to DE. DE now points to the current position in the BASIC statement text (saved for later reference).
5205
INC HL 23
Increment HL to point to the next character in the BASIC statement after CMD"=".
5206
LD A,(HL) 7E
Load Register A with the character at HL (the character immediately following the '=' sign).
5207
CP 3DH FE 3D
Compare the character to = (3DH). This checks if the statement is CMD"==" (double equals), which has special handling.
5209
If the Z FLAG is set (character is '='), JUMP to 52E2H to handle CMD"==" which processes CMD"F" function calls (FILE, KILL, SYSTEM operations).

[STANDARD CMD"=" PATH] The following code handles regular CMD"=" assignments (single equals). First, it sets a recursion guard flag, then calls the BASIC expression evaluator to parse and evaluate what comes after the '='.

520C
LD HL,436AH 21 6A 43
Load HL with address 436AH, which is the I/O operation flag byte. This flag prevents recursive calls during I/O operations.
520F
SET 7,(HL) CB FE
Set bit 7 at address 436AH. This marks that an I/O operation is in progress, preventing re-entry into this routine (recursion guard).
5211
PUSH HL E5
Push HL (436AH) onto the stack, preserving the flag address for later cleanup.
5212
EX DE,HL EB
Exchange DE and HL. HL now points back to the '=' character in the BASIC text (saved earlier at 5203H-5204H), while DE holds 436AH.
5213
Call ROM routine 4419H to evaluate the BASIC expression following the '=' sign. This is the main BASIC expression evaluator. Upon return, the result type is in Register A (00H=numeric, FFH=string) and the result value is in the appropriate registers or string descriptor.
5216
POP HL E1
Pop HL, restoring the address 436AH (the I/O flag byte location).
5217
RES 7,(HL) CB BE
Clear bit 7 at 436AH, removing the recursion guard flag now that expression evaluation is complete.
5219
POP HL E1
Pop HL, which retrieves the return address (the BC value pushed at 5202H, but note that CALL 4419H has modified the stack, so this is actually retrieving what's now on top of stack after the expression evaluation).
521A
If the C FLAG is set (indicating an error occurred during expression evaluation), JUMP to 5DEEH (BASIC/CMD error handler).
521D
RET Z C8
If the Z FLAG is set (indicating the expression result was numeric with value 0), Return immediately. Zero values are silently ignored for CMD"=" statements.
521E
CP 38H FE 38
Compare Register A (result type) to 38H. This is checking for a specific result type code that indicates the expression should be processed further (not a simple string or numeric).
5220
If Register A is not 38H, JUMP to 5E16H (BASIC/CMD error handler - Type Mismatch or improper result type).

[MEMORY VALIDATION SEQUENCE] The expression result is valid (type 38H). Now begins an extensive memory management sequence: save current stack, calculate workspace requirements, verify available memory, test RAM integrity, and set up temporary workspace at 70FCH.

5223
PUSH HL E5
Push HL (return address) back onto the stack to preserve it during the memory operations.
5224
LD (5290H),SP ED 73 90 52
Store the current Stack Pointer (SP) at memory location 5290H (self-modifying code location at 528FH). This saves the stack pointer so it can be restored later. The value is stored as the operand of a "LD SP,nnnn" instruction.
5228
LD HL,FF40H 21 40 FF
Load HL with FF40H (which is -192 decimal in signed 16-bit). This is the amount of stack space that will be allocated for the workspace.
522B
ADD HL,SP 39
Add SP to HL. This calculates SP - 192 bytes, which will be the bottom of the workspace area. HL now points to where the 192-byte workspace would begin.
522F
LD (52C9H),HL 22 C9 52
Store HL at 52C9H (self-modifying code at 52C8H). This saves the workspace base address as the operand of a "LD HL,nnnn" instruction for later use in RAM testing.
5233
LD BC,(5278H) ED 4B 78 52
Load BC with the value stored at 5278H, which is the original buffer pointer (saved during initialization or a previous operation).
5236
OR A B7
Clear the C FLAG by performing OR A (which also updates other flags based on Register A, but the key effect here is C=0 for the upcoming subtraction).
5237
SBC HL,BC ED 42
Subtract BC from HL (with borrow, but C FLAG is clear). This calculates the available workspace size = (SP - 192) - buffer_pointer. HL now contains how much space is available between the buffer and the proposed workspace.
5239
LD (5272H),HL 22 72 52
Store HL at 5272H, saving the calculated available memory size. This is stored as the operand of a "LD HL,nnnn" instruction at 5271H for potential later use.
523C
PUSH HL E5
Push HL (available memory size) onto the stack for later comparison.
523D
LD DE,(40FDH) ED 5B FD 40
Load DE with the value at 40FDH, which is MEMSIZ - the highest usable memory address in the system. This is used as an upper bound for memory allocation.
5241
OR A B7
Clear the C FLAG for the next subtraction.
5242
SBC HL,DE ED 52
Subtract DE (MEMSIZ) from HL (available memory). If the result is negative (C FLAG set), it means the workspace would extend beyond MEMSIZ, indicating insufficient memory.
5244
POP DE D1
Pop DE, restoring the available memory size (pushed at 523CH). DE now holds the calculated workspace size for use in subsequent checks.
5245
If the C FLAG is set (workspace exceeds MEMSIZ), JUMP to ROM routine 197AH, which generates an "Out of Memory" error (OM ERROR).
5248
LD HL,(5275H) 2A 75 52
Load HL with the value at 5275H, which is the buffer base address (where the data buffer starts in memory).
524B
PUSH HL E5
Push HL (buffer base) onto the stack for safekeeping during the next calculation.
524C
ADD HL,BC 09
Add BC (original buffer pointer from 5278H) to HL (buffer base). This calculates the end address of the buffer.
524D
DEC HL 2B
Decrement HL to point to the last byte of the buffer (end address - 1).
524E
OR A B7
Clear the C FLAG for the subtraction.
524F
SBC HL,DE ED 52
Subtract DE (workspace size) from HL (buffer end). This checks if the buffer end + workspace would fit within available memory. If result is not negative (NC FLAG), there's insufficient space.
5251
If the NC FLAG is set (no borrow, meaning buffer end + workspace exceeds available space), JUMP to 197AH for "Out of Memory" error.

[MEMORY ALLOCATION AND COPY] Memory bounds are validated. Now prepare to copy data to the workspace. This involves calculating the copy length, moving data from the buffer to temporary storage at 5271H area, then to final workspace at 70FCH.

5254
POP HL E1
Pop HL, restoring the buffer base address (pushed at 524BH).
5255
PUSH HL E5
Push HL (buffer base) back onto the stack - it's needed again shortly.
5256
PUSH DE D5
Push DE (workspace size) onto the stack.
5257
EX DE,HL EB
Exchange DE and HL. DE now holds buffer base address, HL holds workspace size.
5258
OR A B7
Clear the C FLAG.
5259
SBC HL,DE ED 52
Subtract DE (buffer base) from HL (workspace size). HL now contains workspace_size - buffer_base, which is the offset from buffer base.
525B
LD DE,5271H 11 71 52
Load DE with 5271H, which is a temporary staging area in the SYS20 module itself (location of self-modifying code).
525E
ADD HL,DE 19
Add DE to HL. This calculates the destination address for copying: 5271H + (workspace_size - buffer_base).
525F
POP DE D1
Pop DE, restoring the workspace size (pushed at 5256H). This will be used as the byte count for the copy operation.
5260
Call ROM routine 4416H to perform memory allocation or setup. This prepares the system for the block move operation.
5263
EX (SP),HL E3
Exchange HL with the value on top of stack. This puts the source address (buffer base, which was pushed at 5255H) into HL, and saves the destination address to the stack.
5264
LDIR ED B0
Block copy: Copy BC bytes from (HL) to (DE), incrementing both pointers. This copies the buffer data to the temporary staging area. BC was set by the CALL to 4416H.
5266
POP HL E1
Pop HL, which retrieves the destination address saved at 5263H.
5267
LD SP,70FCH 31 FC 70
Set the Stack Pointer to 70FCH. This establishes a temporary stack workspace at a high memory location (70FCH is safely above normal BASIC memory areas).
526A
PUSH HL E5
Push HL (destination address) onto the new stack.
526B
Call 529AH - this is the RAM test routine. It fills 64 bytes starting at the workspace address with pattern A5H, then verifies the pattern with XOR testing. This ensures the allocated memory is functional.
526E
LD HL,4318H 21 18 43
Load HL with 4318H, which is a system state flag address related to BASIC execution state.
5271
JUMP to ROM routine 4419H. This appears to be finalizing the CMD"=" operation or setting up for execution. The code at 5271H-527AH contains self-modifying data that was used during the memory operations.

5271H - Self-Modifying Code Area / Staging Data

This section contains a mix of executable instructions and data storage used during the CMD"=" memory operations. The instructions here are modified at runtime to hold calculated values (workspace sizes, addresses, pointers). Some instructions are actual code that executes in special circumstances, while others are purely data storage disguised as instructions.

5271
LD HL,0000H 21 00 00
Self-modifying instruction: The operand (0000H) is replaced at runtime at 5239H with the calculated available memory size. This stores workspace sizing information.
5274
LD DE,5200H 11 00 52
Load DE with 5200H (the module entry point). This instruction may be part of a copy or initialization sequence, or may be modified at runtime.
5277
LD BC,1F00H 01 00 1F
Load BC with 1F00H (7936 bytes). This could be a buffer size or data transfer count for operations.
527A
LDIR ED B0
Block copy: Copy BC bytes from (HL) to (DE). This instruction is positioned to potentially copy data as part of cleanup or initialization, though it may be bypassed by jumps.
527C
JUMP to 527FH - cleanup/restoration routine after CMD"=" processing.

527FH - Cleanup and Stack Restoration

Restoration routine that executes after CMD"=" processing. Restores the original stack pointer, performs final RAM verification, and returns control to BASIC. This ensures the system state is properly restored after the temporary workspace operations.

527F
LD SP,42FCH 31 FC 42
Set the Stack Pointer to 42FCH. This appears to be another temporary stack location used during cleanup operations.
5282
PUSH AF F5
Push AF onto the stack, preserving the accumulator and flags for later restoration.
5283
Call 52A4H - memory test verification routine. This performs a final RAM integrity check to ensure the memory operations didn't corrupt anything. Returns with Z FLAG set if memory test passed, NZ FLAG if failed.
5286
LD A,23H 3E 23
Load Register A with 23H. This is an error code that will be used if the memory test failed.
5288
If the NZ FLAG is set (memory test failed), JUMP to ROM routine 4409H with error code 23H in Register A. This generates a memory error.
528B
Call ROM routine 4416H - performs memory finalization or pointer adjustments after successful operation.
528E
POP AF F1
Pop AF, restoring the accumulator and flags that were saved at 5282H.
528F
LD SP,0000H 31 00 00
Self-modifying instruction: The operand (0000H) is replaced at runtime at 5224H with the saved Stack Pointer value from before the CMD"=" operation. This restores the original stack position.
5292
POP HL E1
Pop HL from the restored stack, retrieving the return address for the CMD"=" statement.
5293
If the C FLAG is set (indicating an error), JUMP to 5DEEH (BASIC/CMD error handler).
5296
If the NZ FLAG is set (indicating type mismatch or other non-zero result), JUMP to 5E16H (error handler).
5299
RET C9
Return to BASIC. The CMD"=" statement has been successfully processed and the system state has been restored.

529AH - RAM Pattern Fill Test

Fills 64 bytes of RAM with the test pattern A5H (10100101 binary). This pattern is chosen because it alternates bits in a way that helps detect stuck bits, addressing problems, or other RAM failures. The pattern is written to the workspace area calculated earlier.

529A
LD HL,(52C9H) 2A C9 52
Load HL from address 52C9H, which contains the workspace base address (stored earlier at 522FH during CMD"=" processing). This is where the 64-byte test area begins.
529D
LD B,40H 06 40
Load Register B with 40H (64 decimal), the number of bytes to fill with the test pattern.
529F
LD (HL),A5H 36 A5
[LOOP START] Store the byte A5H (10100101 binary) at address (HL). This is the test pattern used for RAM verification.
52A1
INC HL 23
Increment HL to point to the next byte in the test area.
52A2
Decrement B and JUMP to 529FH if not zero. This loops 64 times, filling 64 consecutive bytes with A5H. [LOOP END]

52A4H - RAM Test Verification Routine

Comprehensive RAM test that verifies memory integrity using XOR pattern testing. Tests two regions: the workspace area (64 bytes at 52C9H) and string storage (from 40B1H/STREND up to 7100H). The test XORs existing memory with new data, writes it back, then verifies. This catches most RAM failures including stuck bits, addressing errors, and data corruption.

52A4
LD DE,7100H 11 00 71
Load DE with 7100H, the upper limit for the memory test. This is treated as the top of the testable string storage area.
52A7
LD BC,(52C9H) ED 4B C9 52
Load BC with the value at 52C9H, which is the workspace base address filled with A5H pattern (from 529AH routine).
52AB
PUSH BC C5
Push BC (workspace address) onto the stack for later use in the workspace pattern verification.
52AC
Call 52C8H - XOR test routine. This performs the XOR-based memory test from HL up to DE (7100H), testing for RAM integrity.
52AF
EX DE,HL EB
Exchange DE and HL. HL now contains 7100H (or the end point of the test), preparing for the next test region.
52B0
LD BC,0040H 01 40 00
Load BC with 0040H (64 decimal), representing the size of the workspace test area.
52B3
ADD HL,BC 09
Add BC to HL. This calculates 7100H + 64 = 7140H, the upper boundary for the second test region.
52B4
EX DE,HL EB
Exchange DE and HL. DE now holds 7140H (upper limit for second test), HL is ready for setting the lower limit.
52B5
LD BC,(40B1H) ED 4B B1 40
Load BC with the value at 40B1H, which is STREND - the end of string storage area in BASIC. This is the lower boundary for testing string space.
52B8
INC BC 03
Increment BC to point to the byte after STREND, the start of free string space to test.
52B9
Call 52D7H - entry point into the XOR test loop. Tests memory from BC (after STREND) up to DE (7140H), verifying the string storage area.
52BC
POP HL E1
Pop HL, restoring the workspace base address (pushed at 52ABH). Now verify the A5H pattern in the 64-byte workspace.
52BD
LD B,40H 06 40
Load Register B with 40H (64 decimal), the number of bytes in the workspace pattern to verify.
52C0
LD A,(HL) 7E
[VERIFICATION LOOP] Load Register A with the byte at (HL) - one byte from the 64-byte test area that was filled with A5H.
52C1
XOR A5H EE A5
XOR Register A with A5H. If the memory correctly stored A5H, the result will be 00H and the Z FLAG will be set. Any other result indicates a RAM error.
52C3
INC HL 23
Increment HL to point to the next byte in the test area.
52C4
RET NZ C0
If the NZ FLAG is set (XOR result was not zero, meaning memory corruption), Return immediately with NZ condition, signaling RAM failure to the caller (52A4H caller at 5283H).
52C5
Decrement B and JUMP to 52C0H if not zero. Continue verifying all 64 bytes. If loop completes without early return, all bytes were correct.
52C7
RET C9
Return with Z FLAG set (from the successful XOR comparisons), indicating RAM test passed. The caller at 5283H checks this flag to determine success/failure.

52C8H - XOR Memory Test Loop

Core XOR-based memory test engine. This routine reads 64-byte blocks from a source (DE), XORs each byte with the corresponding byte at the destination (HL), writes the result back to (HL), and continues until reaching the upper boundary. The XOR test is particularly effective at detecting stuck bits because any bit that can't change from 0→1 or 1→0 will fail the XOR verification.

52C8
LD HL,0000H 21 00 00
Self-modifying instruction: The operand is replaced at runtime by the caller with the starting address for the memory test. After being called, HL contains the test region's base address.
52CB
LD A,40H 3E 40
Load Register A with 40H (64 decimal), the block size for each test iteration. Each pass tests 64 bytes.
52CD
EX AF,AF' 08
Swap AF with shadow register AF'. This preserves the block counter (40H) in A' while freeing A for the XOR operations. The shadow A' register will track how many bytes remain in the current 64-byte block.
52CD
LD A,(DE) 1A
[TEST LOOP - BYTE LEVEL] Load Register A with a byte from the source data at (DE). This is the test pattern byte.
52CF
XOR (HL) AE
XOR Register A with the byte at (HL). This creates a new pattern: source XOR destination. If memory is working correctly, this value will be written to (HL) and later verified.
52D0
LD (HL),A 77
Store the XOR result back to (HL). This modifies the memory with the test pattern, which will be read back in subsequent tests to verify the write succeeded.
52D1
INC DE 13
Increment DE to point to the next source byte.
52D2
INC HL 23
Increment HL to point to the next test byte.
52D3
LD A,D 7A
Load Register A with Register D (high byte of source pointer). This prepares to check if we've reached the upper boundary.
52D4
CP B B8
Compare Register A (high byte of DE) to Register B. Register B holds the high byte of the upper limit (from caller). If equal, we're approaching the boundary.
52D5
If the Z FLAG is set (high bytes match), JUMP to 52DDH to check the low byte for exact boundary match. This is the first stage of a 16-bit comparison.
52D7
EX AF,AF' 08
[BLOCK COUNTER CHECK] Swap back to AF' to access the block counter (was loaded with 40H at 52CBH and preserved in A').
52D8
DEC A 3D
Decrement the block counter in Register A. One byte of the 64-byte block has been processed.
52D9
If the NZ FLAG is set (counter is not zero), JUMP back to 52CDH to process the next byte in the 64-byte block. Continue testing bytes within this block.
52DB
JUMP to 52C8H to start a new 64-byte block. The block counter will be reset to 40H, and testing continues with the next 64 bytes. [BLOCK LOOP]
52DD
LD A,E 7B
[BOUNDARY CHECK - LOW BYTE] Load Register A with Register E (low byte of source pointer DE). Now check if the exact upper boundary has been reached.
52DE
CP C B9
Compare Register A (low byte of DE) to Register C (low byte of upper limit from caller). This completes the 16-bit boundary comparison started at 52D4H.
52DF
If the NZ FLAG is set (low bytes don't match, haven't reached exact boundary), JUMP to 52D7H to continue the block counter check and keep testing. The boundary hasn't been reached yet.
52E1
RET C9
Return to caller. The exact upper boundary has been reached (both high and low bytes of DE matched BC), so the memory test region is complete.

52E2H - CMD"==" Function Dispatcher

Handles CMD"==" statements which are followed by a function letter (F, S, K, etc.). This dispatcher uses a function table at 5952H to look up and execute the appropriate handler routine. The table format is: byte_count, function_character(s), address_low, address_high, repeated for each function.

52E2
INC HL 23
Increment HL to point past the second = sign. HL now points to the function letter (F, S, K, etc.) that follows "==".
52E3
LD A,(DE) 1A
Load Register A with the byte at (DE). Note that DE was set to point to the character after CMD at 5203H-5204H, so this retrieves a character from the original command position.
52E4
CP 53H FE 53
Compare Register A to S (53H). The 'S' function has special handling and jumps directly to a DOS routine.
52E6
If the Z FLAG is set (character is 'S'), JUMP to ROM routine 4405H. This appears to handle a system or special function directly through ROM BASIC.
52E9
CP 46H FE 46
Compare Register A to F (46H). Most CMD"F" functions start with 'F' and use the dispatch table.
52EB
If the NZ FLAG is set (character is not 'F'), JUMP to 5302H to generate a "Syntax Error" (unrecognized function letter).

[TABLE LOOKUP SEQUENCE] The character is 'F', so use the dispatch table at 5952H. Table format: each entry is [byte_count][function_chars...][addr_low][addr_high]. The code loops through entries, comparing the function string from the BASIC command with each table entry until a match is found.

52ED
LD DE,5952H 11 52 59
Load DE with 5952H, the address of the CMD"F" function dispatch table. This table contains entries for FILE, KILL, etc.
52F0
DEC C 0D
Decrement Register C. C appears to contain a character count or comparison length (set by earlier code). This adjusts the count for the comparison loop.
52F1
PUSH HL E5
[TABLE ENTRY LOOP] Push HL (pointer to function name in BASIC text) onto the stack. This preserves the position for retrying if the current table entry doesn't match.
52F2
LD A,(DE) 1A
Load Register A with the byte count from the table entry at (DE). This is the length of the function name string in this table entry.
52F3
CP C B9
Compare the table entry's byte count to Register C (adjusted function name length from BASIC command). If they don't match, this isn't the right entry.
52F4
LD B,A 47
Load Register B with Register A (byte count). B will be used as a loop counter for character-by-character comparison.
52F5
INC DE 13
Increment DE to point to the first character of the function name in the table entry.
52F6
If the Z FLAG is set (byte counts match), JUMP to 5305H to perform character-by-character comparison. This table entry is a potential match.

[SKIP TO NEXT ENTRY] Byte counts didn't match, so skip over this table entry (function name + address) to reach the next entry.

52F8
POP HL E1
Pop HL, restoring the BASIC text pointer (pushed at 52F1H). Discard this restoration since we're skipping this entry.
52F9
INC DE 13
[SKIP LOOP] Increment DE to skip over one character of the function name in this table entry.
52FA
Decrement B and JUMP to 52F9H if not zero. Continue skipping B bytes (the function name length). This moves DE past the entire function name.
52FC
INC DE 13
Increment DE to skip past the low byte of the jump address (next byte after function name).
52FD
INC DE 13
Increment DE to skip past the high byte of the jump address. DE now points to the next table entry.
52FE
LD A,(DE) 1A
Load Register A with the byte count of the next table entry (or 00H if end of table).
52FF
OR A B7
Set flags based on Register A. If A is 00H, the Z FLAG will be set, indicating end of table (no more entries to check).
5300
If the NZ FLAG is set (not end of table), JUMP to 52F1H to try matching the next table entry. Continue searching through the table.
5302
[END OF TABLE / NO MATCH] No matching function found in the table. JUMP to ROM routine 1E4AH, which generates a "Syntax Error" (SN ERROR).

[CHARACTER-BY-CHARACTER COMPARISON] Byte counts matched at 52F6H. Now compare each character of the function name from BASIC with the table entry's function name.

5305
LD A,(DE) 1A
Load Register A with a character from the table entry's function name at (DE).
5306
CP (HL) BE
Compare Register A with the character from the BASIC text at (HL). If they match, Z FLAG will be set.
5307
LD (DE),A 12
Store Register A back to (DE). This appears to be redundant since we just loaded from there, but may be related to memory timing or verification.
5308
INC HL 23
Increment HL to point to the next character in the BASIC text.
5309
If the NZ FLAG is set (characters didn't match), JUMP to 52F8H to skip to the next table entry. This table entry is not a match.
530B
INC DE 13
Increment DE to point to the next character in the table entry's function name.
530C
Decrement B and JUMP to 5305H if not zero. Continue comparing characters. B was loaded with the byte count at 52F4H.

[MATCH FOUND - EXECUTE] All characters matched! DE now points to the low byte of the jump address. Load the address and jump to the handler routine for this function.

530E
EX DE,HL EB
Exchange DE and HL. HL now points to the jump address (low byte) in the table entry, and DE points to the next character position in BASIC text (not used).
530F
LD E,(HL) 5E
Load Register E with the low byte of the jump address from the table.
5310
INC HL 23
Increment HL to point to the high byte of the jump address.
5311
LD D,(HL) 56
Load Register D with the high byte of the jump address. DE now contains the complete handler address for the matched function.
5312
INC HL 23
Increment HL past the jump address, though this value is not used subsequently.
5313
EX DE,HL EB
Exchange DE and HL. HL now contains the handler routine address to jump to.
5314
JP (HL) E9
JUMP to the address in HL, executing the handler routine for the matched CMD"F" function (FILE, KILL, SYSTEM, etc.). Control transfers to the function-specific code.

5315H - FRE() Function Handler

Returns the amount of free memory available to BASIC programs. This is accessed via CMD"="FRE, and calculates available memory by subtracting the string storage end (STREND) from the stack pointer, then returns this value as a numeric result to BASIC.

5315
LD HL,0000H 21 00 00
Load HL with 0000H, initializing HL for the calculation. HL will be used to build the result.
5318
ADD HL,SP 39
Add the current Stack Pointer (SP) to HL. HL now contains the stack pointer value, which represents the top boundary of available memory.
5319
LD DE,(40B1H) ED 5B B1 40
Load DE with the value at 40B1H, which is STREND - the end of string storage area. This is the bottom boundary of available memory.
531D
OR A B7
Clear the C FLAG for the subtraction.
531E
SBC HL,DE ED 52
Subtract DE (STREND) from HL (SP). HL now contains the free memory size = SP - STREND, which is the amount of memory available between string storage and the stack.
5320
LD (40F6H),HL 22 F6 40
Store the calculated free memory value at 40F6H, which is BASIC's numeric result storage location. This makes the value available to BASIC as a function return.
5323
JUMP to ROM routine 1F8CH, which completes the numeric function return, making the FRE() value available to the BASIC expression evaluator.

5326H - CLOSE Validation Handler

Validates that all files are properly closed before allowing certain operations. Checks the FCB (File Control Block) table to ensure no files have the "open" status bit set. If any files are open, generates an error.

5326
LD A,(40AFH) 3A AF 40
Load Register A with the byte at 40AFH, which is the current device/file type flag used by BASIC to track I/O state.
5329
OR A B7
Set flags based on Register A. If A is 00H, the Z FLAG will be set.
532A
If the NZ FLAG is set (device flag is non-zero, indicating an active device), JUMP to 5DE5H (BASIC/CMD error handler with specific error code).
532D
Load Register A with the byte at 5F89H, which contains the maximum number of files (FCB table size) configured for the system.
5330
LD B,A 47
Copy Register A to Register B. B will be used as a loop counter to check each FCB entry.
5331
Load HL with the value at 64C5H, which is the FCB size in bytes (typically 012DH = 301 bytes per FCB).
5334
LD DE,66BEH 11 BE 66
Load DE with 66BEH, the FCB table base address. DE will point to each FCB entry as we loop through them.
5337
LD A,(DE) 1A
[FCB CHECK LOOP] Load Register A with the first byte of the FCB at (DE), which is the file status flags byte. Bit 7 indicates if the file is open.
5338
RLCA 07
Rotate Register A left, moving bit 7 into the C FLAG. If the file is open, C FLAG will be set.
5339
If the C FLAG is set (file is open), JUMP to 5DE5H to generate an error. Cannot proceed with operation if any files are open.
533C
EX DE,HL EB
Exchange DE and HL. HL now points to the current FCB, DE holds the FCB size.
533D
ADD HL,DE 19
Add DE (FCB size) to HL. HL now points to the next FCB entry in the table.
533E
EX DE,HL EB
Exchange DE and HL back. DE now points to the next FCB, HL holds the FCB size again for the next iteration.
533F
Decrement B and JUMP to 5337H if not zero. Check the next FCB. Loop continues until all FCBs have been checked. [LOOP END]
5341
RET C9
Return to caller. All FCBs have been checked and none are open. It's safe to proceed with the requested operation.

5342H - OPEN Validation Handler

Validates that at least one file is open before allowing certain operations. This is the inverse of the CLOSE validation - it scans the FCB table looking for any file with the "open" status bit set. If no files are open, generates an error.

5342
LD A,(40AFH) 3A AF 40
Load Register A with the byte at 40AFH, the current device/file type flag.
5345
OR A B7
Set flags based on Register A.
5346
If the NZ FLAG is set (device flag non-zero), JUMP to 5DE5H for error.
5349
Load Register A with the maximum number of files from 5F89H.
534C
LD B,A 47
Copy to Register B for loop counter.
534D
Load HL with the FCB size from 64C5H.
5350
LD DE,66BEH 11 BE 66
Load DE with 66BEH, the FCB table base.
5353
LD A,(DE) 1A
[FCB CHECK LOOP] Load Register A with the file status flags byte from the current FCB.
5354
RLCA 07
Rotate left, moving bit 7 (open flag) into C FLAG.
5355
RET C D8
If the C FLAG is set (file is open), Return immediately. Found at least one open file, so operation can proceed.
5356
EX DE,HL EB
Exchange DE and HL to add FCB size.
5357
ADD HL,DE 19
Add FCB size to move to next FCB entry.
5358
EX DE,HL EB
Exchange back, DE points to next FCB.
5359
Decrement B and JUMP to 5353H if not zero. Check next FCB. [LOOP END]
535B
No open files found. JUMP to 5DE5H to generate an error - operation requires at least one open file.

535EH - KILL Statement Handler

Executes the BASIC KILL statement to delete a file from disk. Validates that no files are open (calls 5326H), then calls the DOS DELETE function via SYS0 entry point 4D06H to perform the actual file deletion.

535E
Call 5326H to validate that all files are closed. KILL cannot operate with open files. Returns if all files closed, or jumps to error handler if any files are open.
5361
Call 5F5DH (BASIC/CMD file specification parser). Parses the filename following the KILL statement and prepares it for DOS operations. Returns with filename in proper format.
5364
JUMP to SYS0 routine 4D06H, which is the DOS DELETE function. Deletes the specified file from disk. Upon return to BASIC, the file has been removed or an error has been generated.

5367H - FILE Statement Handler

Executes the BASIC FILE statement which displays a disk directory listing. Validates that no files are open, parses any optional filespec, then calls the DOS directory listing function.

5367
Call 5326H to ensure all files are closed before displaying directory.
536A
Call 5EA2H (BASIC/CMD filespec parser with optional parameters). Parses any drive specifier or wildcard pattern following FILE statement. Returns with filespec prepared.
536D
JUMP to SYS0 routine 4D09H, which is the DOS directory listing function. Displays the disk directory to the screen with the specified filespec filter.

5370H - SYSTEM Statement Handler

Executes the BASIC SYSTEM statement which exits BASIC and returns to the DOS command prompt. Validates all files are closed, ensures proper string termination, then calls the DOS system exit routine.

5370
Call 5326H to validate all files are closed before exiting BASIC.
5373
LD A,(HL) 7E
Load Register A with the character at HL (current position in BASIC text). This checks what follows the SYSTEM statement.
5374
CP 3AH FE 3A
Compare to : (3AH, statement separator). Checks if SYSTEM is followed by another statement on the same line.
5376
If Z FLAG is set (colon found), JUMP to 5E16H for error - cannot have statements after SYSTEM.
5379
CP 00H FE 00
Compare to 00H (end of line marker in tokenized BASIC).
537B
If NZ FLAG is set (not end of line), JUMP to 5E16H for syntax error.
537E
JUMP to SYS0 routine 4D0CH, the DOS system exit function. Returns control to DOS, terminating the BASIC program and interpreter.

5381H - Additional String Function Handlers

Collection of handlers for various string and numeric functions accessible through CMD"F" operations. These provide bridges between disk BASIC operations and ROM BASIC function implementations.

5381
LD HL,420DH 21 0D 42
Load HL with 420DH, a string descriptor or buffer address.
5384
JUMP to ROM routine 0E6CH (string comparison).
5387
[FRE Alternate Entry] Call setup routine.
538A
JUMP to FRE() implementation.
538C
[LEN Handler] Call setup.
538F
JUMP to ROM LEN function.
5392
[ASC Handler] Call setup.
5395
JUMP to ROM ASC function.
5398
[STR$ Handler] Call setup.
539B
JUMP to ROM STR$ function.
539E
[VAL Handler] Call setup.
53A1
JUMP to ROM VAL function.
53A4
[LEFT$ Handler] Call setup.
53A7
JUMP to ROM LEFT$ function.
53AA
[RIGHT$ Handler] Call setup.
53AD
JUMP to ROM RIGHT$ function.
53B0
[CHR$ Handler] Call setup.
53B3
JUMP to ROM CHR$ function.

55FAH - INKEY$ and INPUT# Functions

Keyboard input and file input processing routines. INKEY$ provides non-blocking keyboard reads, while INPUT# handles complex file parsing with quote and delimiter handling.

55FA
[INKEY$ Entry] Check for keypress.
55FD
If no key, return empty string.
55FF
LD B,00H 06 00
Setup for single character string.
5601
Create string from character.
5604
POP HL E1
Cleanup stack.
5605
XOR A AF
Set success flag.
5606
Return to BASIC.
5609
POP AF F1
[No Key Path] Stack cleanup.
560A
POP AF F1
More cleanup.
560B
Return empty string.
560E
[INPUT# Entry] Parse file spec.
5611
Additional parsing.
5614
LD BC,2169H 01 69 21
Setup return address.
5617
PUSH BC C5
Push return point.
5618
PUSH HL E5
Save text pointer.
5619
PUSH DE D5
Save DE register.
561A
XOR A AF
Initialize state flags.
561B
LD D,A 57
D = state machine byte.
561C
Process input characters.
561F
Final cleanup.

5621H - INPUT# Character Processing and Helper Routines

Main character processing loop for INPUT# with state machine handling of quotes, delimiters, and special characters. The loop at 5621H-56ACH reads file input character by character, managing a 255-byte buffer and tracking parsing state in Register D.

Due to the complexity and length of the INPUT# character processing loop (5621H-56ACH), this section implements a sophisticated state machine using Register D bit flags to track: bit 0 (skip spaces), bit 1 (inside quotes), bit 2 (space mode), and bit 3 (quote detected). The loop handles CR-LF sequences, comma delimiters, quoted strings with embedded quotes, and proper buffer management with overflow protection.

5621-56AC
[Complex Loop] ...
INPUT# Character Processing: Implements complete INPUT# parsing with quote handling, delimiter recognition (comma, CR, LF), space skipping, buffer management (255 bytes max), and error handling. Uses Register D as state flags and calls 6119H to read characters. Terminates input on delimiters or end-of-line, stores result in BASIC work buffer at 40A7H, and returns to BASIC with parsed values ready for variable assignment.

56AEH - Reserved Space

Module padding providing expansion space for future functionality.

56AE-56E7
NOP (x58) 00...
Reserved area: 58 bytes of NOP instructions providing expansion space. Ensures stable addressing for any function dispatch tables or data structures that follow in higher memory.