TRS-80 - BASIC Utility

Page Customization

Introduction/Summary:

BASIC/CMD is the Disk BASIC extension module for TRS-80 Model III TRSDOS 1.3. This overlay provides all disk file I/O capabilities to BASIC programs, transforming the cassette-based Level II BASIC into a full-featured Disk BASIC environment.

The module occupies memory from 4152H to approximately 64DCH (approximately 8.5KB) and provides a comprehensive set of file handling commands including:

  • File Operations: OPEN, CLOSE, KILL, NAME (rename), LOAD, SAVE, RUN, MERGE
  • Sequential File I/O: INPUT#, PRINT#, LINE INPUT#
  • Random Access File I/O: GET, PUT, FIELD, LSET, RSET, LOC, LOF, EOF
  • Device Control: CMD (output redirection to devices)
  • System Commands: SYSTEM (exit to TRSDOS), FILES (directory listing)

The program entry point is at 614DH, which initializes the Disk BASIC environment. Upon entry, the module:

  1. Saves the current BASIC program pointer and system state
  2. Initializes file control blocks and buffer areas
  3. Copies ROM BASIC vectors to RAM for modification
  4. Prompts for the number of file buffers (if not specified)
  5. Displays the copyright banner: "S-80 Model III Disk BASIC Rev 1.3"
  6. Transfers control to the BASIC READY prompt

The jump table at 4152H-41E2H provides entry points that are called by the BASIC interpreter when disk-related tokens are encountered. Each entry is a 3-byte JP instruction redirecting to the appropriate handler routine.

File Buffer Structure: Each open file requires a 360-byte (168H) buffer area. The module supports up to 15 simultaneous open files, with buffer space allocated at initialization based on user specification. File Control Blocks (FCBs) track file status, current position, record length, and buffer pointers.

Variables:

AddressBytesPurpose
5200H-5202H3File open/close state flags - Byte 0: FFH if file operations active, Byte 1: verify flag, Byte 2: initialization flag
40A0H2BASIC memory top pointer (system variable, preserved/restored)
40A4H2String space pointer / File buffer base address
40A7H2Input buffer pointer for LINE INPUT# operations
40AFH1Variable type flag (1=integer, 2=string, 3=single, 4=double)
40B1H2Program end pointer
40B3H2Array variable pointer
40D3H1Temporary storage for string operations
40D4H2Temporary pointer for string descriptor
40D6H2String temporary pointer
40D8H2Saved HL pointer for array operations
40DCH1Array dimension flag (80H = processing dimensions)
40DFH2Saved HL for OPEN command processing
40ECH2Current line number for error reporting
40F3H2Saved file pointer for sequential operations
40F9H2End of file buffer area pointer
4121H2Variable pointer for DIM operations
4204H2Error handler vector (points to ROM error routine)
4272H2Temporary storage for SYSTEM command HL preservation
4274H2Secondary temporary for CMD "O" operations
426DH1Maximum file number allowed (0-15)
426EH1Verify flag - 'V' (56H) if verify enabled, 0 otherwise
426FH2Saved state for file operations (copied from 5200H)
427AH1SYSTEM command active flag (FFH = returning to DOS)
42AEH1BREAK enable flag (C9H=RET for enabled, C3H=JP for disabled)
442BH1DOS file access mode flags
442FH1ROUTE/DUAL flag (80H=ROUTE, FFH=DUAL, 00H=Neither)
4411H2DOS high memory limit
441FH1DOS version check byte (must be >= 13H for TRSDOS 1.3)
5868H-587BH20Error address lookup table (10 entries × 2 bytes)
59A8H-59BDH22Keyword strings: "LIST", "EDIT", "DELETE", "AUTO" with length prefixes
59BEH-59C7H10String "READY " for display matching
6126H-614CH39DOS error code to BASIC error code translation table
6301H-6319H25String: "Use TRSDOS 1.3 or Later" + CR + NUL
631AH-6328H15String: "How Many Files?" (prompt for file buffer count)
6329H-638EH102Copyright banner: "S-80 Model III Disk BASIC Rev 1.3" + date + copyright
638FH-63A1H19Free bytes display template: "00,000 Free Bytes 00 "
63A2H-63A5H4Disk geometry data copied from DOS
63A6H-63AEH9String: "Variable Files" (file type indicator)
63AFH-63B5H7String: "Files" + CR + NUL (alternate file type indicator)
63B6H1Record length for current file operation
63BCH1Last DOS error code encountered
63BDH1Read/Write direction flag (0=read, non-zero=write)
63BEH-63BFH2Current file's FCB pointer (0000H if no file active)
63C0H-63C1H2Current file buffer base pointer
63E0H-63E1H2Last allocated buffer end pointer
63E2H1EOF flag for current read operation (F1H=EOF, 0=not EOF)
63E3H1Saved file count during nested operations
63E4H1Command type marker (2AH='*' for RUN with files)
63E5H-63E6H2Saved string space pointer during initialization
63E7H-63E8H2Saved file count pointer during initialization
63E9H-63EAH2Saved memory top during initialization
63EBH1Initialization complete flag
63ECH1Memory size specified flag for -M option
63EDH1Files specified flag for -F option
63EEH-63EFH2Saved command line pointer at entry
63F0H-6349H90Command line copy buffer for RUN command parsing
6350H-6367H24Filename buffer for file operations (null-terminated)
64DCH+variesFile buffer area - 360 bytes (168H) per open file, allocated at initialization

Disassembly:

4152H - DISK BASIC JUMP TABLE

This is the primary dispatch table for Disk BASIC commands. When the BASIC interpreter encounters a disk-related token, it calculates the offset into this table and executes the corresponding JP instruction. Each 3-byte entry redirects to the actual command handler. The table contains 32 entry points covering all file I/O and disk system commands.

4152
Jump to CHR$ function handler - Returns a string containing the character with the specified ASCII code.
4155
Jump to DIM statement handler for string arrays with file buffer - Dimensions a string array for use with file operations.
4158
Jump to MKI$ function handler - Converts an integer to a 2-byte string for random file storage.
415B
Jump to DEFUSR statement handler - Defines a USR function entry point for machine language calls.
415E
Jump to MKS$ function handler - Converts a single-precision number to a 4-byte string for random file storage.
4161
Jump to EOF function handler - Returns -1 (true) if end of file reached, 0 (false) otherwise.
4164
Jump to LOC function handler - Returns the current record number for a random access file.
4167
Jump to LOF function handler - Returns the length of file in bytes (number of records × record length).
416A
Jump to MKD$ function handler - Converts a double-precision number to an 8-byte string for random file storage.
416D
Jump to CVI function handler - Converts a 2-byte string from a random file back to an integer.
4170
Jump to CVS function handler - Converts a 4-byte string from a random file back to single-precision.
4173
Jump to CMD statement handler - Redirects output to a device (printer, comm port, or file).
4176
Jump to ROM routine at 3030H - CVD function handler for double-precision conversion from string.
4179
Jump to OPEN statement handler - Opens a file for input, output, random, or extend access.
417C
Jump to FIELD statement handler - Defines field variables for random access file buffer.
417F
Jump to GET statement handler - Reads a record from a random access file into the buffer.
4182
Jump to PUT statement handler - Writes a record from the buffer to a random access file.
4185
Jump to CLOSE statement handler - Closes one or more open files, flushing buffers to disk.
4188
Jump to LOAD statement handler - Loads a BASIC program from disk into memory.
418B
Jump to MERGE statement handler - Merges an ASCII BASIC program with the current program.
418E
Jump to NAME statement handler - Renames a file on disk.
4191
Jump to KILL statement handler - Deletes a file from disk.
4194
Jump to &H / &O handler - Parses hexadecimal (&H) or octal (&O) number constants.
4197
Jump to LSET statement handler - Left-justifies a string in a random file field buffer.
419A
Jump to RSET statement handler - Right-justifies a string in a random file field buffer.
419D
Jump to FILES statement handler - Displays a directory listing of files on disk.
41A0
Jump to SAVE statement handler - Saves the current BASIC program to disk.
41A3
Jump to LINE INPUT statement handler - Reads an entire line from keyboard or file.
41A6
Jump to ERROR statement handler (in SYS0) - Simulates an error condition.
41A9
Jump to USR function handler - Calls a machine language routine defined by DEFUSR.
41AC
Jump to PRINT# output completion handler - Writes buffered output to file.
41AF
Jump to INPUT# statement handler - Reads formatted data from a sequential file.
41B2
Jump to PRINT# statement handler - Writes formatted data to a sequential file.
41B5
Jump to file buffer save routine - Preserves file state for nested operations.
41B8
Jump to file buffer restore routine - Restores file state after nested operations.
41BB
Jump to close all files routine - Closes all open files (used before LOAD/RUN/SYSTEM).
41BE
Jump to clear file buffer pointer - Resets the active file pointer to indicate no file selected.
41C1
Jump to INPUT# item separator check - Processes comma/newline between INPUT# variables.
41C4
Jump to INPUT handler with file check - Gets input from keyboard or file depending on context.
41C7
Jump to RUN statement handler (file version) - Runs a BASIC program from disk.
41CA
Jump to file mode check for LIST - Checks if output should go to file or screen.
41CD
Jump to simple RET (stub entry) - Placeholder for future expansion or compatibility.
41D0
Jump to print character to file handler - Routes character output to file if file active.
41D3
Jump to PRINT# file number check - Validates file number for output operations.
41D6
Jump to MID$ statement handler - Replaces a portion of a string variable.
41D9
Jump to WRITE# statement handler - Writes comma-delimited data to sequential file.
41DC
Jump to check if output to file active - Returns status of current file output redirection.
41DF
Jump to SYSTEM statement handler - Exits BASIC and returns to TRSDOS Ready prompt.
41E2
Jump to SYSTEM (alternate entry) - Same as 41DFH, possibly for different token.

5200H - FILE STATE FLAGS AND ARRAY DIMENSION HANDLER

This section contains three flag bytes at 5200H-5202H that track file operation states, followed by the array dimension handler for disk file operations. The routine at 5203H processes DIM statements for arrays that will be used with random access files. It validates the number of dimensions and stores array bounds.

5200
NOP 00
File operation active flag - Set to FFH when file operations are in progress, 00H otherwise. Used to track state across LOAD/RUN operations.
5201
NOP 00
Verify flag storage - Stores verify mode (from 442BH bit 2) during file operations.
5202
NOP 00
Initialization flag - Non-zero if special initialization routine at 3042H should be called.

The following routine handles array dimensioning for file buffer variables. Entry: HL points to BASIC text after DIM token. The routine checks if array dimensions are valid (1-3 dimensions supported) and creates the array descriptor.

5203
LD A,(40AFH) 3A AF 40
Load Register A with the variable type flag from 40AFH. This indicates the type of variable being dimensioned: 1=integer, 2=string, 3=single precision, 4=double precision.
5206
DEC A 3D
Decrement Register A by 1, converting type 1-4 to 0-3.
5207
DEC A 3D
Decrement Register A again, now type becomes -1 to 2.
5208
DEC A 3D
Decrement Register A again. If original type was 3 (single precision), A is now 0; types 1-2 are now negative (sign flag set).
5209
OR A B7
OR Register A with itself to set flags. Z flag set if A=0 (single precision), M flag set if A is negative (integer or string).
520A
SCF 37
Set Carry Flag to 1. This flag will be used to indicate a special array type if we jump.
520B
If Z flag is set (type was single precision = 3), JUMP to 526CH to handle single-precision array with carry set indicating special mode.
520D
LD C,(HL) 4E
Load Register C with the low byte of the first dimension bound from the array descriptor pointed to by HL.
520E
INC HL 23
Increment HL to point to the high byte of the first dimension.
520F
LD B,(HL) 46
Load Register B with the high byte of the first dimension bound. BC now contains the first dimension size.
5210
PUSH BC C5
Save the first dimension bound onto the stack for later use.
5211
If M flag (Minus/Sign) is set from the OR at 5209H (meaning type was integer=1 or string=2), JUMP to 522BH to handle 1-dimensional array.
5214
INC HL 23
Increment HL to point to the next dimension in the array descriptor.
5215
LD C,(HL) 4E
Load Register C with the low byte of the second dimension bound.
5216
INC HL 23
Increment HL to point to the high byte of the second dimension.
5217
LD B,(HL) 46
Load Register B with the high byte of the second dimension bound. BC now contains the second dimension size.
5218
PUSH BC C5
Save the second dimension bound onto the stack.
5219
If Parity/Overflow flag is clear (odd parity - type was 4, double precision), JUMP to 522BH. The original type=4 after three decrements = 1, OR 1 = PO flag clear.
521C
INC HL 23
Increment HL to point to a possible third dimension.
521D
If Carry is set (from 520AH, indicating special array handling), JUMP to 5222H to continue reading third dimension.
521F
LD HL,411DH 21 1D 41
Load HL with address 411DH - a default array descriptor location in the BASIC workspace, used when no third dimension specified.
5222
LD C,(HL) 4E
Load Register C with the low byte of the third dimension (or default).
5223
INC HL 23
Increment HL to point to high byte.
5224
LD B,(HL) 46
Load Register B with the high byte of the third dimension. BC now contains the third dimension size.
5225
INC HL 23
Increment HL past this dimension entry.
5226
PUSH BC C5
Save the third dimension bound onto the stack.
5227
LD C,(HL) 4E
Load Register C with the low byte of a possible fourth dimension.
5228
INC HL 23
Increment HL to point to high byte.
5229
LD B,(HL) 46
Load Register B with the high byte of the fourth dimension.
522A
PUSH BC C5
Save the fourth dimension bound onto the stack.
522B
If Carry flag is set, JUMP to 5276H to process the accumulated dimension values on the stack.
522E
RST 08H CF
Call the SYNCHR routine via RST 08H to verify the next character in BASIC text matches the expected token.
522F
CP (HL) BE
(Token byte BEH follows RST 08H) - Check for token BEH (specific BASIC keyword token).
5230
LD A,80H 3E 80
Load Register A with 80H - the array processing active flag to indicate we're in the middle of dimensioning.
5232
LD (40DCH),A 32 DC 40
Store the array flag (80H) into 40DCH (array dimension processing flag) to indicate active array processing.
5235
OR (HL) B6
OR Register A with the byte at HL, combining the flag with the current token/value.
5236
LD B,A 47
Copy the combined value from A to Register B for use as a parameter.
5237
JUMP to ROM routine at 2612H to continue array dimensioning with the calculated parameters in B.

523AH - DIM STATEMENT DISK HANDLER

This is the main entry point for the DIM statement when disk file support is active. It calls the dimension processor at 522EH, then checks the variable type and sets up the array descriptor pointer. Entry: HL points to BASIC text. Exit: Array is dimensioned, HL points past the dimension specification.

523A
GOSUB to 522EH to process the dimension specification via RST 08H synchronization.
523D
LD A,(40AFH) 3A AF 40
Load Register A with the variable type flag from 40AFH after dimension processing.
5240
OR A B7
OR Register A with itself to set the Zero flag based on the type value.
5241
PUSH AF F5
Save AF (type and flags) onto the stack for later comparison.
5242
LD (40F3H),HL 22 F3 40
Store HL (current BASIC text pointer) into 40F3H (saved file pointer) to preserve position.
5245
EX DE,HL EB
Exchange DE and HL. DE now has the text pointer, HL will be used for array descriptor.
5246
LD A,(HL) 7E
Load Register A with the byte at HL (array descriptor low byte).
5247
INC HL 23
Increment HL to point to high byte.
5248
LD H,(HL) 66
Load Register H with the high byte of the array pointer.
5249
LD L,A 6F
Load Register L with the low byte (from A). HL now points to the array descriptor.
524A
OR H B4
OR Register A (low byte) with H (high byte) to check if the pointer is zero (null array).
524B
If Z flag is set (pointer is 0000H - undefined array), JUMP to 5363H to handle the "Undefined array" error.
524E
LD A,(HL) 7E
Load Register A with the first byte of the array descriptor.
524F
CP 28H FE 28
Compare Register A with 28H (ASCII ( open parenthesis). This checks if we're at an array element reference.
5251
If NZ flag is set (not an open parenthesis), JUMP to 529FH - this is a simple variable, not an array.
5253
RST 10H D7
Call CHRGET via RST 10H to get the next character from BASIC text, advancing past the '('.
5254
LD (40D8H),HL 22 D8 40
Store the current HL pointer into 40D8H for later restoration during array indexing.
5257
JUMP unconditionally to 525BH to continue processing the array subscripts.

[LOOP START] - The following code loops through each array subscript, separated by commas.

5259
RST 08H CF
Call SYNCHR via RST 08H to verify expected character.
525A
INC L 2C
(Token byte 2CH follows RST 08H) - Verify comma (2CH = ASCII ,) between subscripts.
525B
LD C,04H 0E 04
Load Register C with 04H - parameter indicating 4-byte floating point value expected for subscript.
525D
GOSUB to ROM routine at 1963H to evaluate the subscript expression.
5260
LD A,80H 3E 80
Load Register A with 80H - the array processing flag.
5262
LD (40DCH),A 32 DC 40
Store the flag into 40DCH to indicate array processing is active.
5265
GOSUB to ROM routine at 260DH to process the evaluated subscript value.
5268
EX DE,HL EB
Exchange DE and HL to swap array pointer and text pointer.
5269
SCF 37
Set the Carry Flag to indicate subscript processing continues.
526A
[LOOP] - JUMP back to 5203H to process the next subscript or complete array access.
526C
If No Carry flag is set, JUMP to ROM routine at 2423H - single precision array with simple subscript.
526F
PUSH DE D5
Save DE (text pointer) onto the stack.
5270
EX DE,HL EB
Exchange DE and HL.
5271
GOSUB to ROM routine at 2888H to allocate string space for the array element.
5274
POP DE D1
Restore DE (text pointer) from the stack.
5275
XOR A AF
Clear Register A to 0 and clear flags (Z flag set).

5276H - ARRAY SUBSCRIPT PROCESSING AND STORAGE

This section processes accumulated array subscripts from the stack and stores dimension bounds into the array descriptor. It handles the closing parenthesis verification and stores subscript values into the appropriate memory locations. Entry: Stack contains dimension values, HL points to array descriptor, DE points to BASIC text.

5276
PUSH HL E5
Save HL (array descriptor pointer) onto the stack.
5277
PUSH AF F5
Save AF (flags including Z from XOR A at 5275H) onto the stack.
5278
EX DE,HL EB
Exchange DE and HL. HL now points to BASIC text, DE points to array descriptor.
5279
LD A,(HL) 7E
Load Register A with the current character from BASIC text.
527A
CP 29H FE 29
Compare Register A with 29H (ASCII ) closing parenthesis). If equal, Z flag is set.
527C
If NZ flag is set (not a closing parenthesis), JUMP back to 5259H to expect and process another comma-separated subscript.
527E
LD HL,(40F3H) 2A F3 40
Load HL with the saved BASIC text pointer from 40F3H (saved at 5242H).
5281
RST 08H CF
Call SYNCHR via RST 08H to verify expected token.
5282
(Token byte 28H follows RST 08H) - Verify opening parenthesis (28H). If found (Z set), JUMP to 5269H.
5284
LD HL,(40D8H) 2A D8 40
Load HL with the saved array index pointer from 40D8H (saved at 5254H).
5287
GOSUB to ROM routine at 260DH to continue processing the array element.
528A
EX (SP),HL E3
Exchange HL with the value on top of stack. HL gets previous value, stack gets current HL.
528B
GOSUB to ROM routine at 1F2BH for additional array processing.
528E
LD A,(HL) 7E
Load Register A with the byte at current HL position.
528F
CP 29H FE 29
Compare Register A with 29H (ASCII )) to check for closing parenthesis.
5291
If Z flag is set (found closing parenthesis), JUMP to 529AH to finish subscript processing.
5293
RST 08H CF
Call SYNCHR via RST 08H to verify expected token.
5294
INC L 2C
(Token byte 2CH follows RST 08H) - Verify comma separator between subscripts.
5295
EX (SP),HL E3
Exchange HL with stack top, rotating pointers.
5296
RST 08H CF
Call SYNCHR via RST 08H again.
5297
INC L 2C
(Token byte 2CH follows RST 08H) - Verify another comma.
5298
[LOOP] - JUMP back to 5287H to continue processing subscripts.
529A
RST 10H D7
Call CHRGET via RST 10H to advance past the closing parenthesis.
529B
EX (SP),HL E3
Exchange HL with stack top to restore proper pointer.
529C
RST 08H CF
Call SYNCHR via RST 08H.
529D
ADD HL,HL 29
(Token byte 29H follows RST 08H) - Verify closing parenthesis token.
529E
LD A,D5H 3E D5
Load Register A with D5H - a marker value for completed array subscript processing.
529F
RST 08H CF
Call SYNCHR via RST 08H to verify next token.
52A0
RST 08H CF
Call SYNCHR again - this is part of inline token verification.
52A1
PUSH DE D5
(Token byte D5H follows RST 08H) - Verify token, then save DE onto stack.
52A2
GOSUB to ROM routine at 2337H for expression evaluation.
52A5
DEC HL 2B
Decrement HL to back up one character in BASIC text.
52A6
RST 10H D7
Call CHRGET via RST 10H to re-fetch current character.
52A7
If NZ flag is set (unexpected character), JUMP to ROM error handler at 1997H for Syntax Error.
52AA
RST 20H E7
Call GETYP via RST 20H to determine the result type.
52AB
If Z flag is set (string type), JUMP to 52DCH to handle string assignment.
52AD
POP DE D1
Restore DE from the stack.
52AE
POP AF F1
Restore AF from the stack (flags saved earlier).
52AF
If Z flag is set, JUMP to 52F0H to finalize array element.
52B1
If No Carry flag is set, JUMP to 52CFH for different array type handling.
52B3
POP HL E1
Restore HL (array descriptor pointer) from the stack.
52B4
POP BC C1
Restore BC (dimension value) from the stack.
52B5
LD (HL),B 70
Store high byte of dimension (B) into array descriptor at HL.
52B6
DEC HL 2B
Decrement HL to point to previous byte.
52B7
LD (HL),C 71
Store low byte of dimension (C) into array descriptor.
52B8
If M flag (Minus/Sign) is set, JUMP to 52AEH to continue processing dimensions.
52BB
DEC HL 2B
Decrement HL for next dimension entry.
52BC
POP BC C1
Restore next BC (dimension value) from the stack.
52BD
LD (HL),B 70
Store high byte of this dimension.
52BE
DEC HL 2B
Decrement HL.
52BF
LD (HL),C 71
Store low byte of this dimension.
52C0
If Parity/Overflow flag is clear, JUMP to 52AEH.
52C3
DEC HL 2B
Decrement HL for third dimension entry.
52C4
POP BC C1
Restore BC (third dimension value) from the stack.
52C5
LD (HL),B 70
Store high byte of third dimension.
52C6
DEC HL 2B
Decrement HL.
52C7
LD (HL),C 71
Store low byte of third dimension.
52C8
DEC HL 2B
Decrement HL for fourth dimension entry.
52C9
POP BC C1
Restore BC (fourth dimension value) from the stack.
52CA
LD (HL),B 70
Store high byte of fourth dimension.
52CB
DEC HL 2B
Decrement HL.
52CC
LD (HL),C 71
Store low byte of fourth dimension.
52CD
JUMP to 52AEH to continue processing.
52CF
PUSH DE D5
Save DE onto the stack.
52D0
PUSH AF F5
Save AF onto the stack.
52D1
RST 20H E7
Call GETYP via RST 20H to get result type.
52D2
LD DE,40D3H 11 D3 40
Load DE with address 40D3H (temporary storage for string operations).
52D5
If Z flag is set (string type), GOSUB to ROM routine at 2888H for string allocation.
52D8
POP AF F1
Restore AF from the stack.
52D9
JUMP to ROM routine at 281AH to complete the operation.
52DC
LD HL,(40B3H) 2A B3 40
Load HL with the array variable pointer from 40B3H.
52DF
EX DE,HL EB
Exchange DE and HL.
52E0
LD HL,(4121H) 2A 21 41
Load HL with the variable pointer for DIM from 4121H.
52E3
RST 18H DF
Call CPDEHL via RST 18H to compare DE with HL.
52E4
If Carry is set (DE < HL), JUMP to 52EBH.
52E6
GOSUB to ROM routine at 2843H for string handling.
52E9
JUMP to 52ADH to continue.
52EB
POP DE D1
Restore DE from the stack.
52EC
LD HL,40D3H 21 D3 40
Load HL with address 40D3H (temporary string storage).
52EF
PUSH HL E5
Save HL onto the stack.
52F0
GOSUB to ROM routine at 29F5H for final array element processing.
52F3
LD A,(HL) 7E
Load Register A with the byte at HL.
52F4
LD (40B3H),HL 22 B3 40
Store HL into 40B3H (array variable pointer).
52F7
POP HL E1
Restore HL from the stack.
52F8
LD (HL),A 77
Store the value in A at the address pointed to by HL.
52F9
INC HL 23
Increment HL.
52FA
LD (HL),C 71
Store C at the address pointed to by HL.
52FB
INC HL 23
Increment HL.
52FC
LD (HL),B 70
Store B at the address pointed to by HL.
52FD
JUMP to 52AEH to continue processing.

52FFH - DEFUSR STATEMENT HANDLER

Handles the DEFUSR statement which defines the entry address for a USR machine language function. Syntax: DEFUSR[n]=address where n is 0-9. The address is stored in a lookup table at 5868H.

52FF
CP C1H FE C1
Compare Register A with C1H. This checks for a specific token following DEFUSR.
5301
If Z flag is set (token matches), JUMP to 5354H for alternate DEFUSR handling.
5303
GOSUB to 522EH to synchronize with BASIC text via RST 08H.
5306
GOSUB to ROM routine at 2828H to get the address expression value.
5309
EX DE,HL EB
Exchange DE and HL. DE now has the text pointer, HL has the address value.
530A
LD (HL),E 73
Store low byte of address (E) at the USR table entry.
530B
INC HL 23
Increment HL to point to high byte location.
530C
LD (HL),D 72
Store high byte of address (D) at the USR table entry.
530D
EX DE,HL EB
Exchange DE and HL back. HL now has the text pointer.
530E
LD A,(HL) 7E
Load Register A with the current character from BASIC text.
530F
CP 28H FE 28
Compare Register A with 28H (ASCII (). Check if there's a following parameter.
5311
If NZ flag is set (no open parenthesis), JUMP to ROM at 1F05H to complete the statement.
5314
RST 10H D7
Call CHRGET via RST 10H to advance past the '('.
5315
GOSUB to ROM routine at 260DH to evaluate parameter expression.
5318
LD A,(HL) 7E
Load Register A with current character.
5319
CP 29H FE 29
Compare Register A with 29H (ASCII )) checking for closing parenthesis.
531B
If Z flag is set (found ')'), JUMP to ROM at 1F05H to finish the statement.
531E
RST 08H CF
Call SYNCHR via RST 08H.
531F
INC L 2C
(Token byte 2CH follows RST 08H) - Verify comma separator.
5320
[LOOP] - JUMP back to 5315H to process next parameter.

5322H - USR FUNCTION HANDLER

Handles the USR function call which invokes a machine language routine previously defined with DEFUSR. Entry: HL points to text after USR token, optional digit 0-9 specifies which USR slot. Exit: Returns result from machine language routine in the numeric accumulator.

5322
POP AF F1
Restore AF from the stack (caller's return info).
5323
GOSUB to 5342H to parse the optional USR number (0-9) and get the address table entry.
5326
PUSH DE D5
Save DE (pointer to USR address table entry) onto the stack.
5327
GOSUB to ROM routine at 252CH to evaluate the argument expression.
532A
EX (SP),HL E3
Exchange HL with stack top. HL gets USR table pointer, stack gets text pointer.
532B
LD C,(HL) 4E
Load Register C with the low byte of the USR address.
532C
INC HL 23
Increment HL to point to high byte.
532D
LD B,(HL) 46
Load Register B with the high byte of the USR address. BC now contains the USR entry point.
532E
LD HL,26E7H 21 E7 26
Load HL with address 26E7H - the return address for after the USR call completes.
5331
PUSH HL E5
Push the return address onto the stack.
5332
PUSH BC C5
Push the USR address onto the stack (will be used as call target via RET).
5333
LD A,(40AFH) 3A AF 40
Load Register A with the variable type flag from 40AFH.
5336
PUSH AF F5
Save the type flag onto the stack for the USR routine to access.
5337
CP 03H FE 03
Compare Register A with 03H (single precision type).
5339
If Z flag is set (single precision), GOSUB to ROM routine at 29DAH to prepare the single-precision value in registers.
533C
POP AF F1
Restore AF (type flag) from the stack. This will be available to the USR routine.
533D
EX DE,HL EB
Exchange DE and HL. Sets up registers for USR routine parameter passing.
533E
LD HL,4121H 21 21 41
Load HL with address 4121H - pointer to variable storage area for USR to return value.
5341
RET C9
RETurn - This pops the USR address from stack and jumps to the user's machine language routine. When USR routine executes RET, control returns to 26E7H.

5342H - USR NUMBER PARSER

Parses the optional digit (0-9) after USR to determine which USR slot to use. If no digit follows, defaults to USR0. Returns pointer to the 2-byte address entry in the USR table at 5868H. Entry: HL points to BASIC text. Exit: DE = pointer to USR table entry, HL = updated text pointer.

5342
RST 10H D7
Call CHRGET via RST 10H to get the next character (possibly a digit 0-9).
5343
LD BC,0000H 01 00 00
Load BC with 0000H - default offset (USR0) if no digit follows.
5346
If No Carry (character is not a digit 0-9), JUMP to 534DH to use default USR0.
5348
SUB 30H D6 30
Subtract 30H (ASCII '0') from A to convert digit character to numeric value 0-9.
534A
RLCA 07
Rotate A left (multiply by 2) since each USR entry is 2 bytes.
534B
LD C,A 4F
Load Register C with the calculated offset (0, 2, 4, 6, ... 18 for USR0-USR9).
534C
RST 10H D7
Call CHRGET via RST 10H to advance past the digit.
534D
EX DE,HL EB
Exchange DE and HL. DE now has the text pointer.
534E
LD HL,5868H 21 68 58
Load HL with 5868H - base address of the USR address table (10 entries × 2 bytes).
5351
ADD HL,BC 09
Add BC (offset 0-18) to HL to point to the specific USR entry.
5352
EX DE,HL EB
Exchange DE and HL. DE now has pointer to USR entry, HL has text pointer.
5353
RET C9
RETurn to caller with DE = USR table entry pointer, HL = text pointer.

5354H - ALTERNATE DEFUSR HANDLER

Alternate entry for DEFUSR when preceded by token C1H. Parses the USR number and stores the address value into the USR table.

5354
GOSUB to 5342H to parse the USR number and get table entry pointer in DE.
5357
PUSH DE D5
Save DE (USR table entry pointer) onto the stack.
5358
RST 08H CF
Call SYNCHR via RST 08H to verify next token.
5359
PUSH DE D5
(Token byte D5H follows RST 08H) - Verify token D5H (likely '=' assignment).
535A
GOSUB to ROM routine at 2B02H to evaluate the address expression.
535D
EX (SP),HL E3
Exchange HL with stack top. HL gets USR table pointer, stack gets text pointer.
535E
LD (HL),E 73
Store low byte of address (E) into the USR table entry.
535F
INC HL 23
Increment HL to point to high byte location.
5360
LD (HL),D 72
Store high byte of address (D) into the USR table entry.
5361
POP HL E1
Restore HL (text pointer) from the stack.
5362
RET C9
RETurn to caller - DEFUSR statement complete.

5363H - UNDEFINED ARRAY ERROR HANDLER

Generates error code 2EH (Undefined array) when an array is referenced that hasn't been dimensioned. Jumps to the standard BASIC error handler.

5363
LD E,2EH 1E 2E
Load Register E with error code 2EH - "Undefined array" error number.
5365
JUMP to ROM error handler at 19A2H to display error message and return to READY.

5368H - CMD Statement Pre-Check Routine

This routine is called before processing CMD statements that require a file number. It checks if the next token is the USING keyword (token CEH) and if so, returns immediately with Z flag set. Otherwise, it validates that the current variable contains a valid file number and jumps to the file number validation routine at 5A46H.

5368
PUSH HL E5
Save HL (current BASIC line pointer) on stack
5369
RST 10H D7
Call CHRGET - get next character from BASIC line, skip spaces
536A
CP CEH FE CE
Compare with CEH (USING keyword token). If match, Z flag is set
536C
POP HL E1
Restore HL (BASIC line pointer)
536D
LD A,(HL) 7E
Load Register A with byte at current BASIC line position
536E
RET Z C8
If Z flag set (USING keyword found), RETURN - let caller handle PRINT USING

Not USING keyword - this is a PRINT# or CMD requiring a file number. Continue to validate.

536F
LD C,02H 0E 02
Load Register C with 02H (file access mode = output)
5371
JUMP to 5A46H to validate file number and set up for output

5374H - CMD Statement Main Handler (Device Dispatcher)

This is the main entry point for the CMD statement. It evaluates a string expression to get the device/option code, then dispatches to the appropriate handler based on the first character. CMD supports: D (DOS directory), L (LOAD command string), P (PRINT# position), J (JKL system), Z (ZONE settings), C (cassette options), O (file rename), X (DOS exit), B (BREAK on/off), E (video enable), T (tape operations), R (cassette read), S (SYSTEM), A (SYSTEM with carry), & (debug/special), and I (immediate DOS command).

5374
Call ROM routine to skip spaces and set up expression evaluation
5377
PUSH HL E5
Save HL (BASIC line pointer after expression) on stack
5378
Call ROM routine to evaluate string expression - returns string descriptor in HL
537B
LD A,(HL) 7E
Load Register A with string length from descriptor
537C
OR A B7
Test if string length is zero
537D
If string empty (Z set), JUMP to Illegal Function Call error at 1E4AH

String is not empty. Get pointer to actual string data from descriptor bytes 2-3.

5380
INC HL 23
Point to low byte of string address in descriptor
5381
LD E,(HL) 5E
Load Register E with low byte of string data address
5382
INC HL 23
Point to high byte of string address
5383
LD D,(HL) 56
Load Register D with high byte of string data address. DE now points to string
5384
LD A,(DE) 1A
Load Register A with first character of CMD string (the command letter)

Now dispatch based on the command letter. Each letter has a specific handler.

5385
CP 44H FE 44
Compare with D (44H) - DOS directory listing command
5387
If D, JUMP to 541AH - CMD "D" handler (directory with options)
538A
CP 4CH FE 4C
Compare with L (4CH) - LOAD command handler
538C
If L, JUMP to 54F3H - CMD "L" handler (load program via string)
538F
CP 50H FE 50
Compare with P (50H) - PRINT# position handler
5391
If P, JUMP to 552DH - CMD "P" handler (set print position)
5394
CP 4AH FE 4A
Compare with J (4AH) - JKL system command
5396
If J, JUMP to 557CH - CMD "J" handler (execute JKL system routine)
5399
CP 5AH FE 5A
Compare with Z (5AH) - ZONE settings (ROUTE/DUAL)
539B
If Z, JUMP to 559FH - CMD "Z" handler (zone/route/dual settings)
539E
CP 43H FE 43
Compare with C (43H) - Cassette options (R/S)
53A0
If C, JUMP to 55F4H - CMD "C" handler (cassette read/save options)
53A3
CP 4FH FE 4F
Compare with O (4FH) - File rename operation
53A5
If O, JUMP to 5610H - CMD "O" handler (rename old file to new)
53A8
CP 58H FE 58
Compare with X (58H) - DOS exit command
53AA
If X, JUMP to 5594H - CMD "X" handler (exit to TRSDOS)
53AD
CP 42H FE 42
Compare with B (42H) - BREAK on/off command
53AF
If B, JUMP to 564BH - CMD "B" handler (enable/disable BREAK key)
53B2
CP 45H FE 45
Compare with E (45H) - Video enable command
53B4
If E, JUMP (relative) to 5410H - CMD "E" handler (video output control)
53B6
CP 54H FE 54
Compare with T (54H) - Tape operations
53B8
If T, JUMP (relative) to 53DAH - CMD "T" handler (tape motor control)
53BA
CP 52H FE 52
Compare with R (52H) - Cassette read mode
53BC
If R, JUMP (relative) to 53D5H - CMD "R" handler (cassette read)
53BE
CP 53H FE 53
Compare with S (53H) - SYSTEM command
53C0
If S, JUMP to 59C9H - CMD "S" handler (SYSTEM command)
53C3
CP 41H FE 41
Compare with A (41H) - SYSTEM with carry set
53C5
SCF 37
Set Carry Flag (will be passed to SYSTEM handler as mode indicator)
53C6
If A, JUMP to 59C9H - CMD "A" handler (SYSTEM with special flag)
53C9
CP 26H FE 26
Compare with & (26H) - Debug/special command
53CB
If &, JUMP to 5487H - CMD "&" handler (special debug/poke operations)
53CE
CP 49H FE 49
Compare with I (49H) - Immediate DOS command
53D0
If I, JUMP (relative) to 53E0H - CMD "I" handler (immediate DOS command)

No valid command letter matched - this is an invalid CMD option.

53D2
JUMP to Illegal Function Call error at 1E4AH

53D5H - CMD "R" Handler (Cassette Read Mode)

This handler activates cassette read mode by calling the ROM cassette initialization routine at 0298H. After setup, it re-enables interrupts and returns to BASIC.

53D5
Call ROM cassette read initialization routine at 0298H
53D8
JUMP (relative) to 53DDH - common exit (restore HL, enable interrupts, return)

53DAH - CMD "T" Handler (Tape Motor Control)

This handler controls the cassette tape motor by calling the ROM routine at 02A1H. This allows BASIC programs to start/stop the tape motor programmatically.

53DA
Call ROM tape motor control routine at 02A1H
53DD
POP HL E1
Restore HL (BASIC line pointer saved at 5377H)
53DE
EI FB
Enable interrupts (cassette routines may have disabled them)
53DF
RET C9
RETURN to BASIC interpreter

53E0H - CMD "I" Handler (Immediate DOS Command)

This handler executes an immediate TRSDOS command from a string. It expects the syntax CMD "I,command" where "command" is the DOS command string. The routine copies the command to the DOS command buffer at 4225H and calls the $COMDOS routine at 4299H to execute it.

53E0
POP HL E1
Restore HL (BASIC line pointer)
53E1
RST 08H CF
SYNCHR - verify next character matches inline byte
53E2
DEFB 2CH 2C
Inline byte: require , (comma) separator
53E3
Call ROM routine to skip spaces and prepare for expression
53E6
PUSH HL E5
Save HL (BASIC line pointer after comma) on stack
53E7
Call ROM routine to evaluate string expression - get DOS command string
53EA
LD A,(HL) 7E
Load Register A with string length from descriptor
53EB
OR A B7
Test if string length is zero
53EC
If string empty, JUMP to Illegal Function Call error

String has content. Extract address and length for copying to DOS buffer.

53EF
INC HL 23
Point to low byte of string address
53F0
LD E,(HL) 5E
Load Register E with low byte of string address
53F1
INC HL 23
Point to high byte of string address
53F2
LD D,(HL) 56
Load Register D with high byte. DE now points to command string
53F3
LD C,A 4F
Copy string length to Register C
53F4
LD B,00H 06 00
Clear Register B - BC now holds string length (0-255)
53F6
INC BC 03
Increment BC to include terminating CR in copy count
53F7
LD L,A 6F
Load Register L with string length
53F8
LD H,00H 26 00
Clear Register H - HL now holds string length
53FA
ADD HL,DE 19
Add string base to length - HL points past end of string
53FB
LD A,(HL) 7E
Load Register A with byte after string (save it)
53FC
PUSH AF F5
Save original byte on stack (will restore after command execution)
53FD
LD (HL),0DH 36 0D
Store 0DH (CR) as terminator after string
53FF
PUSH HL E5
Save terminator position on stack
5400
EX DE,HL EB
Exchange: HL = source string address, DE = terminator position
5401
LD DE,4225H 11 25 42
Load DE with DOS command line buffer address (4225H)
5404
PUSH DE D5
Save buffer address on stack (for COMDOS call)
5405
LDIR ED B0
Block copy: copy BC bytes from (HL) to (DE) - command string to DOS buffer
5407
POP HL E1
Restore HL = 4225H (DOS command buffer address)
5408
Call $COMDOS at 4299H - execute DOS command, returns to BASIC READY on completion

After DOS command completes, restore the original byte we overwrote with CR.

540B
POP HL E1
Restore HL = position where we put CR terminator
540C
POP AF F1
Restore original byte in Register A
540D
LD (HL),A 77
Restore original byte after string (remove our CR)
540E
POP HL E1
Restore HL (BASIC line pointer)
540F
RET C9
RETURN to BASIC interpreter

5410H - CMD "E" Handler (Video Enable Control)

This handler controls video output by calling DOS function at 4409H. It reads the last DOS error code from 63BCH, ORs it with C0H (setting bits 6 and 7), and passes this value to the video control routine. This enables or configures video display output.

5410
LD A,(63BCH) 3A BC 63
Load Register A with last DOS error code from 63BCH
5413
OR C0H F6 C0
OR with C0H - set bits 6 and 7 (video enable flags)
5415
Call DOS video control routine at 4409H
5418
POP HL E1
Restore HL (BASIC line pointer)
5419
RET C9
RETURN to BASIC interpreter

541AH - CMD "D" Handler (DOS Directory with Options)

This handler processes the CMD "D" command which displays a directory listing with optional filtering. The rest of the CMD string contains filter options that are passed to the DOS directory display routine at 4419H. The format is CMD "D:filter" where filter specifies what files to list.

541A
EX DE,HL EB
Exchange DE and HL - HL now points to CMD string data
541B
INC HL 23
Skip past the 'D' character to point to filter options
541C
SYNCHR: Verify next char
541D
DEFB 3AH 3A
Expected: ':' (colon)
541E
LD A,(HL) 7E
Get character from HL
541F
LD (4271H),A 32 71 42
Store to 4271H
5425
POP HL E1
Restore HL (BASIC line pointer)
5426
RET C9
RETURN to BASIC interpreter

5427H - LINE INPUT Statement Handler

This is the entry point for the LINE INPUT statement. It handles both LINE INPUT# (file input) and LINE INPUT (keyboard input). The statement reads an entire line of text into a string variable without parsing. If a # symbol follows, it redirects to the LINE INPUT# handler at 5AC9H.

5427
RST 08H CF
SYNCHR - verify next character matches inline byte
5428
DEFB 89H 89
Inline byte: require INPUT token (89H) after LINE keyword
5429
Call ROM routine to handle LINE INPUT prompt string if present
542C
LD A,(HL) 7E
Load Register A with current character from BASIC line
542D
CP 23H FE 23
Compare with # (23H) - check for file number prefix
542F
If # found, JUMP to 5AC9H - LINE INPUT# file handler

No # symbol - this is keyboard LINE INPUT. Get variable to store result.

5432
Call ROM routine to get/create string variable - returns address in DE
5435
Call ROM routine to verify it's a string variable (error if not)
5438
Call ROM routine to finalize variable setup
543B
PUSH DE D5
Save DE (variable address) on stack
543C
PUSH HL E5
Save HL (BASIC line pointer) on stack
543D
Call ROM keyboard input routine - read line from keyboard
5440
POP DE D1
Restore DE (now holds BASIC line pointer)
5441
POP BC C1
Restore BC (now holds variable address)
5442
If Carry set (BREAK pressed), JUMP to BREAK handler at 1DBEH

Input completed successfully. Copy input line to string variable.

5445
PUSH BC C5
Save BC (variable address) on stack
5446
PUSH DE D5
Save DE (BASIC line pointer) on stack
5447
LD B,00H 06 00
Clear Register B (string processing flag = 0)
5449
Call ROM routine to process input buffer into string
544C
POP HL E1
Restore HL (BASIC line pointer)
544D
XOR A AF
Clear Register A (success indicator = 0)
544E
JUMP to ROM routine at 1F32H to complete string assignment and continue execution

5451H - Clear File Buffer Pointer Routine

This utility routine clears the current FCB (File Control Block) pointer at 63BEH to indicate no file is currently active. It's called when closing files or when file operations complete.

5451
PUSH HL E5
Save HL on stack
5452
LD L,A 6F
Load Register L with A (which is 0 from caller)
5453
LD H,A 67
Load Register H with A (also 0) - HL = 0000H
5454
LD (63BEH),HL 22 BE 63
Store 0000H at 63BEH - clear current FCB pointer (no file active)
5457
POP HL E1
Restore HL
5458
RET C9
RETURN to caller

5459H - PRINT# File Number Check Routine

This routine validates the file number for PRINT# statements. It expects A to contain '#' (23H) when called. If '#' is present, it advances to get the file number and validates it for output. If not '#', it returns to normal PRINT handling.

5459
PUSH HL E5
Save HL (BASIC line pointer) on stack
545A
CP 23H FE 23
Compare Register A with # (23H)
545C
If not '#', JUMP to ROM PRINT continuation at 26E7H

'#' found - this is PRINT# (output to file). Check for USING keyword.

545F
RST 10H D7
CHRGET - get next character after '#'
5460
CP CEH FE CE
Compare with USING token (CEH)
5462
POP HL E1
Restore HL (BASIC line pointer)
5463
LD A,(HL) 7E
Reload Register A with current character
5464
RET Z C8
If USING keyword found (Z set), RETURN - caller handles PRINT# USING

Not USING - this is plain PRINT#. Set up file for output.

5465
POP BC C1
Pop return address into BC (discard - we'll jump elsewhere)
5466
Call file number validation routine at 5A44H
5469
PUSH HL E5
Save HL (BASIC line pointer after file number)
546A
LD HL,(40A7H) 2A A7 40
Load HL with input buffer pointer from 40A7H
546D
DEC HL 2B
Decrement to point to last valid position
546E
JUMP to ROM routine at 21EBH to continue PRINT# processing

5471H - Check if Output to File Active

This routine checks whether output is currently being directed to a file (vs console). It examines the FCB pointer at 63BEH - if it's zero, no file output is active. If non-zero, it checks if the return address indicates we're coming from the right place in the PRINT routines and redirects accordingly.

5471
PUSH HL E5
Save HL on stack
5472
LD HL,(63BEH) 2A BE 63
Load HL with current FCB pointer from 63BEH
5475
LD A,H 7C
Load Register A with high byte of FCB pointer
5476
OR L B5
OR with low byte - test if FCB pointer is zero
5477
POP HL E1
Restore HL
5478
RET Z C8
If FCB pointer is zero (no file active), RETURN - normal output

File output is active. Check where we came from and redirect.

5479
EX (SP),HL E3
Exchange HL with top of stack - get return address into HL
547A
PUSH DE D5
Save DE on stack
547B
LD DE,2B2EH 11 2E 2B
Load DE with ROM address 2B2EH (PRINT routine boundary)
547E
RST 18H DF
CPDEHL - compare DE with HL (return address)
547F
POP DE D1
Restore DE
5480
POP HL E1
Restore HL (original value)
5481
If return address >= 2B2EH, JUMP to 2B4AH (alternate PRINT path)
5484
Otherwise JUMP to 2282H (standard PRINT path with file output)

5487H - CMD "&" Handler (Debug/Special Operations)

This handler processes the CMD "&" command which provides special debug and memory poke operations. The format is CMD "&&" (double ampersand required). It then calls a data table interpreter at 563FH with a pointer to the operation table at 549BH. This allows direct memory manipulation and system control.

5487
POP HL E1
Restore HL (BASIC line pointer)
5488
LD A,(HL) 7E
Load Register A with current character (should be '&')
5489
CP 26H FE 26
Compare with & (26H) - verify double ampersand
548B
If not '&', JUMP to Illegal Function Call error
548E
RST 10H D7
CHRGET - get next character (skip second '&')
548F
If not end of statement (NZ), JUMP to Illegal Function Call error

Valid CMD "&&" - execute debug table operations.

5492
PUSH HL E5
Save HL (BASIC line pointer) on stack
5493
LD HL,549BH 21 9B 54
Load HL with address of operation table at 549BH
5496
Call table interpreter routine at 563FH
5499
POP HL E1
Restore HL (BASIC line pointer)
549A
RET C9
RETURN to BASIC interpreter

549BH - CMD "&" Operation Data Table

This is a data table used by the CMD "&" debug handler. It contains encoded operations for memory manipulation, system control, and special functions. The data is interpreted by the routine at 563FH. Each entry specifies a memory address and operation to perform. The table is XOR-encoded with 55H for obfuscation.

Data table: 88 bytes of encoded debug operation definitions from 549BH to 54F2H. Format is interpreted by routine at 563FH - XOR 55H decoding applied to each byte.

549B
DEFB 35H,01H,3DH,3CH,26H,75H 35 01 3D 3C 26 75
Encoded operation entry 1
54A1
DEFB 17H,34H,26H,3CH,36H,75H 17 34 26 3C 36 75
Encoded operation entry 2
54A7
DEFB 3CH,26H,75H,16H,1AH,05H 3C 26 75 16 1A 05
Encoded operation entry 3
54ADH
DEFB 0CH,07H,1CH,12H,1DH,01H 0C 07 1C 12 1D 01
Encoded operation entry 4
54B3H
DEFB 10H,11H,75H,37H,2CH,75H 10 11 75 37 2C 75
Encoded operation entry 5
54B9H
DEFB 01H,14H,1BH,11H,0CH,75H 01 14 1B 11 0C 75
Encoded operation entry 6
54BFH
DEFB 16H,1AH,07H,05H,1AH,07H 16 1A 07 05 1A 07
Encoded operation entry 7
54C5H
DEFB 14H,01H,1CH,1AH,1BH,79H 14 01 1C 1A 1B 79
Encoded operation entry 8
54CBH
DEFB 75H,64H,6CH,6DH,65H,58H 75 64 6C 6D 65 58
Encoded operation entry 9 (contains "dlme" text?)
54D1H
DEFB 01H,1FH,58H,05H,27H,3AH 01 1F 58 05 27 3A
Encoded operation entry 10
54D7H
DEFB 21H,30H,36H,21H,3CH,3AH 21 30 36 21 3C 3A
Encoded operation entry 11
54DDH
DEFB 3BH,75H,3DH,34H,26H,75H 3B 75 3D 34 26 75
Encoded operation entry 12
54E3H
DEFB 16H,19H,10H,14H,07H,10H 16 19 10 14 07 10
Encoded operation entry 13
54E9H
DEFB 11H,75H,18H,30H,38H,3AH 11 75 18 30 38 3A
Encoded operation entry 14
54EFH
DEFB 27H,2CH,58H,01H 27 2C 58 01
Encoded operation entry 15 (final entry marker)

54F3H - CMD "L" Handler (LOAD Program from String)

This handler processes the CMD "L,filename" command which loads a program file. The filename is taken from a BASIC string expression following the comma. The routine copies the filename to the DOS command buffer at 4465H (with CR terminator) and calls the DOS $LOAD routine at 4430H.

54F3
POP HL E1
Restore HL (originally points to CMD string - but we discard this)
54F4
RST 08H CF
SYNCHR - verify next character matches inline byte
54F5
DEFB 2CH 2C
Inline byte: require , (comma) separator after 'L'
54F6
Call ROM routine to skip spaces and prepare for expression
54F9
PUSH HL E5
Save HL (BASIC line pointer after comma) on stack
54FA
Call ROM routine to evaluate string expression - get filename string
54FD
LD A,(HL) 7E
Load Register A with string length from descriptor
54FE
OR A B7
Test if string length is zero
54FF
If Carry set (error condition), JUMP to Illegal Function Call

Get string address and calculate position for CR terminator.

5502
INC HL 23
Point to low byte of string address
5503
LD E,(HL) 5E
Load Register E with low byte of string address
5504
INC HL 23
Point to high byte of string address
5505
LD D,(HL) 56
Load Register D with high byte. DE = filename string address
5506
LD L,A 6F
Load Register L with string length
5507
LD H,00H 26 00
Clear Register H - HL = string length
5509
ADD HL,DE 19
Add base to length - HL points past end of filename string
550A
LD A,(HL) 7E
Load Register A with byte after filename (save for restoration)
550B
PUSH AF F5
Save original byte on stack
550C
LD (HL),0DH 36 0D
Store 0DH (CR) as filename terminator
550E
PUSH HL E5
Save terminator position on stack
550F
EX DE,HL EB
Exchange: HL = source filename, DE = terminator position
5510
LD DE,4465H 11 65 44
Load DE with DOS command buffer address at 4465H

[LOOP START] Copy filename character by character to DOS buffer until CR found.

5513
LD A,(HL) 7E
[LOOP] Load Register A with character from source filename
5514
LD (DE),A 12
Store character to DOS command buffer
5515
CP 0DH FE 0D
Compare with CR (0DH) - end of filename?
5517
If CR (Z set), JUMP to 551DH - done copying [LOOP END]
5519
INC HL 23
Advance source pointer
551A
INC DE 13
Advance destination pointer
551B
JUMP back to 5513H - continue copying [LOOP]

Filename copied. Now call DOS to load the program.

551D
LD DE,4465H 11 65 44
Load DE with DOS command buffer address (filename location)
5520
Call DOS $LOAD routine at 4430H to load program file
5523
If NZ (DOS error), JUMP to error handler at 6113H

Load successful. Restore the byte we overwrote with CR.

5526
POP HL E1
Restore HL = terminator position
5527
POP AF F1
Restore original byte in Register A
5528
LD (HL),A 77
Restore original byte (remove our CR terminator)
5529
POP HL E1
Restore HL (BASIC line pointer)
552A
RET C9
RETURN to BASIC interpreter
552B
Alternate entry - JUMP to 5529H (cleanup and return)

552DH - CMD "P" Handler (PRINT# Position)

This handler processes the CMD "P,expression" command which sets the print position for subsequent PRINT# output. It evaluates a string expression and stores the position information in a string variable descriptor, then formats the memory size value in a specific format for display purposes.

552D
POP HL E1
Restore HL (discard CMD string pointer)
552E
RST 08H CF
SYNCHR - verify next character matches inline byte
552F
DEFB 2CH 2C
Inline byte: require , (comma) separator
5530
Call ROM routine to get string variable address in DE
5533
Call ROM routine to finalize variable setup
5536
PUSH HL E5
Save HL (BASIC line pointer) on stack
5537
LD A,(DE) 1A
Load Register A with string length from variable descriptor
5538
OR A B7
Test if string length is zero
5539
If string empty (Z set), JUMP to 5544H - create new string space

Existing string - get its address from descriptor.

553B
PUSH DE D5
Save DE (variable descriptor address) on stack
553C
EX DE,HL EB
Exchange: HL = descriptor address
553D
INC HL 23
Point to low byte of string address
553E
LD E,(HL) 5E
Load Register E with low byte of string address
553F
INC HL 23
Point to high byte of string address
5540
LD D,(HL) 56
Load Register D with high byte. DE = string data address
5541
POP HL E1
Restore HL (was DE = descriptor address)
5542
JUMP to 554FH - continue with string setup

Empty string - allocate 3 bytes of string space.

5544
PUSH DE D5
Save DE (variable descriptor address) on stack
5545
LD A,03H 3E 03
Load Register A with 03H (need 3 bytes for position string)
5547
Call ROM routine to allocate A bytes of string space
554A
LD HL,(40D4H) 2A D4 40
Load HL with string descriptor pointer from 40D4H
554D
POP DE D1
Restore DE (variable descriptor address)
554E
EX DE,HL EB
Exchange: HL = variable descriptor, DE = new string space

Set up string descriptor: length=3, address=DE.

554F
LD (HL),03H 36 03
Store 03H as string length in descriptor
5551
INC HL 23
Point to low byte of address in descriptor
5552
LD (HL),E 73
Store low byte of string address
5553
INC HL 23
Point to high byte of address in descriptor
5554
LD (HL),D 72
Store high byte of string address
5555
EX DE,HL EB
Exchange: HL = string data area

Read memory size from port F8H and format as 2-digit number with prefix.

5556
IN A,(F8H) DB F8
Read port F8H - memory configuration/size register
5558
CP C8H FE C8
Compare with C8H (200 decimal) - 48K+?
555A
LD B,32H 06 32
Load Register B with 2 (32H) - first digit for >=200
555C
LD C,C8H 0E C8
Load Register C with C8H (200) - subtractor for >=200
555E
If A >= 200 (NC), JUMP to 556CH - use '2' prefix
5560
CP 64H FE 64
Compare with 64H (100 decimal) - 32K-48K range?
5562
LD B,31H 06 31
Load Register B with 1 (31H) - first digit for 100-199
5564
LD C,64H 0E 64
Load Register C with 64H (100) - subtractor for 100-199
5566
If A >= 100 (NC), JUMP to 556CH - use '1' prefix
5568
LD B,20H 06 20
Load Register B with (20H space) - first digit for <100
556A
LD C,00H 0E 00
Load Register C with 00H - no subtraction needed

Store first character and calculate remaining 2-digit number.

556C
LD (HL),B 70
Store first character (hundreds digit or space) in string
556D
INC HL 23
Advance to next position in string
556E
SUB C 91
Subtract C from A - remove hundreds
556F
LD (HL),2FH 36 2F
Store 2FH ('0'-1) - will be incremented to get tens digit

[LOOP START] Divide by 10 to get tens digit.

5571
INC (HL) 34
[LOOP] Increment tens digit character
5572
SUB 0AH D6 0A
Subtract 10 from A
5574
If still >= 0 (NC), JUMP back to 5571H - keep counting tens [LOOP]

Remainder is units digit. Convert to ASCII.

5576
ADD 3AH C6 3A
Add 3AH to remainder (compensates for extra SUB 0AH, converts to '0'-'9')
5578
INC HL 23
Advance to units position in string
5579
LD (HL),A 77
Store units digit character
557A
POP HL E1
Restore HL (BASIC line pointer)
557B
RET C9
RETURN to BASIC interpreter

557CH - CMD "J" Handler (JKL System)

Executes the TRSDOS JKL system routine. The JKL system provides keyboard macro capabilities in TRSDOS.

The JKL system allows users to define keyboard macros. This handler preserves the return address around the DOS call to ensure proper continuation of BASIC command processing.

557C
POP HL E1
Restore return address from CMD parser
557D
LD (4272H),HL 22 72 42
Save return address to temporary storage
5580
Call DOS JKL system routine
5583
LD HL,(4272H) 2A 72 42
Restore return address
5586
RET C9
Return to BASIC

5594H - CMD "X" Handler (Exit to TRSDOS)

Exits BASIC and returns to TRSDOS operating system prompt.

The EXIT command terminates BASIC and returns control to TRSDOS. The code after the CALL at 5598H is never executed since the DOS exit routine transfers control directly to the operating system. However, it's included for consistency with other handlers.

5594
POP HL E1
Restore return address from CMD parser
5595
LD (4272H),HL 22 72 42
Save return address to temporary storage
5598
Call DOS exit routine (does not return)
559B
LD HL,(4272H) 2A 72 42
Restore return address (never executed)
559E
RET C9
Return (never executed)

559FH - CMD "Z" Handler (ZONE N/F - ROUTE/DUAL Settings)

Controls printer output routing: ZONE "N" enables ROUTE mode (duplicate output to printer), ZONE "F" disables it. The "Z" command syntax is: CMD "Z","N" or CMD "Z","F"

559F
POP HL E1
Restore return address from CMD parser
55A0
SYNCHR: Verify next char is comma
55A1
DEFB 2CH 2C
Expected character: comma
55A2
SYNCHR: Verify next char is quote
55A3
DEFB 22H 22
Expected character: quote
55A4
LD (4FCFH),HL 22 CF 4F
Save HL (parser position) to temporary storage
55A7
DEC HL 2B
Back up to quote character
55A8
CHRGET: Get next character (skip quote)
55A9
INC HL 23
Move to character after quote
55AA
CP 4EH FE 4E
Is it 'N' (eNable ROUTE/DUAL)?
55AC
If not 'N', check for 'F'

55ADH - Enable ROUTE/DUAL Mode (CMD "Z","N")

Enables printer output duplication - all screen output is also sent to the printer.

The DUAL mode works by redirecting both output vectors to a special handler at 4CE1H that duplicates all output to both the screen and printer. The original vectors are saved so they can be restored when DUAL mode is disabled.

55AD
PUSH HL E5
Save parser position
55AE
LD A,(442FH) 3A 2F 44
Get current ROUTE/DUAL flag
55B1
OR A B7
Check if already enabled (FFH)
55B2
If already on, skip to exit
55B4
DEC A 3D
Set A = FFH (enable flag)
55B5
LD (442FH),A 32 2F 44
Enable ROUTE/DUAL mode
55B8
LD HL,(401EH) 2A 1E 40
Get primary output vector
55BB
LD (4CE7H),HL 22 E7 4C
Save original primary vector
55BE
LD HL,(4026H) 2A 26 40
Get secondary output vector
55C1
LD (4CF8H),HL 22 F8 4C
Save original secondary vector
55C4
LD HL,4CE1H 21 E1 4C
Point to DUAL output handler routine
55C7
LD (401EH),HL 22 1E 40
Set primary output vector to DUAL handler
55CA
LD (4026H),HL 22 26 40
Set secondary output vector to DUAL handler

55CDH - ZONE Command Exit Handler

Common exit point for ZONE command - checks for closing quote and returns.

55CD
POP HL E1
Restore parser position
55CE
LD A,(HL) 7E
Get current character
55CF
CP 22H FE 22
Is it closing quote?
55D1
RET NZ C0
Return if not (syntax error will follow)
55D2
INC HL 23
Skip past closing quote
55D3
RET C9
Return to command processor

55D4H - Check for 'F' (Disable ROUTE/DUAL)

Handles CMD "Z","F" to disable printer output duplication.

Disabling DUAL mode restores the original output vectors from their saved locations. This returns output routing to normal screen-only operation. The ROUTE/DUAL flag at 442FH is set to 00H to indicate disabled state.

55D4
CP 46H FE 46
Is it 'F' (disable)?
55D6
If not 'F', syntax error
55D9
SYNCHR: Verify next char
55DA
DEFB 46H 46
Expected character: 'F'
55DB
PUSH HL E5
Save parser position
55DC
LD A,(442FH) 3A 2F 44
Get current ROUTE/DUAL flag
55DF
OR A B7
Check if enabled (00H = off)
55E0
If already off, skip to exit
55E2
LD HL,(4CE7H) 2A E7 4C
Get saved primary output vector
55E5
LD (401EH),HL 22 1E 40
Restore original primary vector
55E8
LD HL,(4CF8H) 2A F8 4C
Get saved secondary output vector
55EB
LD (4026H),HL 22 26 40
Restore original secondary vector
55EE
XOR A AF
Set A = 00H (disable flag)
55EF
LD (442FH),A 32 2F 44
Disable ROUTE/DUAL mode
55F2
Jump to exit handler

55F4H - CMD "C" Handler (Cassette R/S Options)

Controls cassette tape operations: CMD "C" (read mode, E=02) or CMD "C","R" (read mode, E=02) or CMD "C","S" (write mode, E=00). This sets up the cassette system for either reading or writing.

NOTE: There's a bug in this code. When "R" is specified, E should be 02H (read mode), but the code path leaves E=01H. However, at 5602H it jumps to 560AH which calls 4281H. The cassette control routine at 4281H may handle E=01H as read mode, or this might be a minor bug that doesn't affect functionality. The correct values should be: E=02H for read, E=00H for write.

55F4
POP HL E1
Restore return address from CMD parser
55F5
LD A,(HL) 7E
Get next character from command line
55F6
CP 2CH FE 2C
Is it a comma?
55F8
LD E,02H 1E 02
Default mode = 02H (Read mode)
55FA
If no comma, use default read mode
55FC
INC HL 23
Skip past comma
55FD
DEC E 1D
E = 01H (intermediate value)
55FE
LD A,(HL) 7E
Get option character
55FF
INC HL 23
Move to next position
5600
CP 52H FE 52
Is it 'R' (Read)?
5602
If 'R', E=01H is incorrect; jump to call
5604
DEC E 1D
E = 00H (Write mode for 'S')
5605
CP 53H FE 53
Is it 'S' (Save/Write)?
5607
If not 'S', syntax error

560AH - Execute Cassette Control

Calls the DOS cassette control routine with the mode in register E.

560A
PUSH HL E5
Save parser position
560B
Call cassette control (E = mode)
560E
POP HL E1
Restore parser position
560F
RET C9
Return to BASIC

5610H - CMD "O" Handler (Rename File)

Renames a disk file. Syntax: CMD "O", oldname$, newname$ - The "O" command provides file renaming capability from BASIC.

The rename operation requires two string parameters. The DOS routine at 4284H expects the old filename pointer at 4272H and the new filename pointer at 4274H. Both filenames must be valid strings; empty strings cause a Type Mismatch error.

5610
POP HL E1
Restore return address from CMD parser
5611
SYNCHR: Verify next char is comma
5612
DEFB 2CH 2C
Expected character: comma
5613
Evaluate expression (old filename)
5616
LD A,(40AFH) 3A AF 40
Get variable type flag
5619
CP 02H FE 02
Is it a string (type 2)?
561B
If not string, "Type Mismatch" error
561E
PUSH HL E5
Save parser position
561F
EX DE,HL EB
DE = parser position, HL = string descriptor
5620
LD E,(HL) 5E
E = string length
5621
INC HL 23
Point to address low byte
5622
LD D,(HL) 56
D = string address low byte
5623
POP HL E1
Restore parser position
5624
LD (4272H),DE ED 53 72 42
Save old filename pointer to 4272H
5628
SYNCHR: Verify next char is comma
5629
DEFB 2CH 2C
Expected character: comma
562A
Evaluate expression (new filename)
562D
Get string address in DE, length in A
5630
PUSH HL E5
Save parser position
5631
LD A,(DE) 1A
Get first character of new filename
5632
OR A B7
Check if null (empty string)
5633
If empty, "Type Mismatch" error
5636
LD (4274H),DE ED 53 74 42
Save new filename pointer to 4274H
563A
Call DOS rename file routine
563D
POP HL E1
Restore parser position
563E
RET C9
Return to BASIC

563FH - XOR-Encoded Table Interpreter

Processes XOR 55H encoded command tables. Used by CMD "&" handler to interpret encoded operation data. This routine reads a count byte, then XOR-decodes and outputs each subsequent byte.

This routine is used to decode the CMD "&" operation data table at 549BH-54F2H. Each byte in the table is XOR'd with 55H to produce the actual character to output. This simple encoding may have been used to avoid conflicts with special characters or control codes in the source file.

563F
LD B,(HL) 46
B = byte count from table
5640
INC HL 23
Point to next data byte [LOOP START]
5641
LD A,(HL) 7E
Get encoded byte [LOOP]
5642
XOR 55H EE 55
Decode by XOR with 55H
5644
Output character in A to current device
5647
INC HL 23
Point to next encoded byte
5648
Repeat for all B bytes [LOOP END]
564A
RET C9
Return to caller

564BH - CMD "B" Handler (BREAK ON/OFF)

Controls CTRL+C break handling. CMD "B","N" enables breaks (stores C9H=RET at 42AEH). CMD "B","F" disables breaks (stores C3H=JP at 42AEH). This uses self-modifying code to enable/disable the break check.

564B
POP HL E1
Restore return address from CMD parser
564C
SYNCHR: Verify next char is comma
564D
DEFB 2CH 2C
Expected character: comma
564E
SYNCHR: Verify next char is quote
564F
DEFB 22H 22
Expected character: quote
5650
LD (4FCFH),HL 22 CF 4F
Save parser position
5653
DEC HL 2B
Back up to quote
5654
CHRGET: Get next char (skip quote)
5655
INC HL 23
Move to character after quote
5656
CP 4EH FE 4E
Is it 'N' (eNable breaks)?
5658
If not 'N', check for 'F'
565A
LD A,C9H 3E C9
A = C9H (RET opcode - enables breaks)
565C
Jump to store break enable byte

565DH - Check for 'F' (Disable Breaks)

565D
CP 46H FE 46
Is it 'F' (disable breaks)?
565F
If not 'F', syntax error
5662
SYNCHR: Verify next char is 'F'
5663
DEFB 46H 46
Expected character: 'F'
5664
LD A,C3H 3E C3
A = C3H (JP opcode - disables breaks)

5666H - Store Break Control Byte and Exit

The BREAK control mechanism uses self-modifying code. Location 42AEH contains either RET (C9H) which allows breaks, or JP (C3H) which bypasses the break check. When breaks are disabled, the break handler immediately jumps past the break detection code. This is an efficient way to enable/disable a feature without conditionals in the time-critical break check routine.

5666
LD (42AEH),A 32 AE 42
Store opcode at break check location
5669
LD A,(HL) 7E
Get current character
566A
CP 22H FE 22
Is it closing quote?
566C
RET NZ C0
Return if not (error will follow)
566D
INC HL 23
Skip past closing quote
566E
RET C9
Return to BASIC

566FH - NAME Statement Handler

Implements the NAME statement for renaming files. Syntax: NAME oldname$ AS newname$. This provides an alternative syntax to CMD "O" for file renaming.

The NAME statement closes all files before attempting the rename operation. This ensures that neither the old nor new filename is currently in use by an open file buffer. The actual rename processing is handled by the DOS routine at 427EH.

566F
PUSH BC C5
Save registers
5670
PUSH DE D5
Save registers
5671
PUSH HL E5
Save parser position
5672
Close all open files
5675
POP HL E1
Restore parser position
5676
POP DE D1
Restore registers
5677
POP BC C1
Restore registers
5678
Jump to DOS NAME handler

567BH - FILES Statement Handler

Implements the FILES statement for displaying disk directory. Syntax: FILES [filespec$] - If no filespec is provided, displays all files. This provides directory listing capability from BASIC programs.

567B
CHRGET: Get next character from command
567C
Evaluate expression (optional filespec)
567F
GETYP: Check variable type
5680
LD A,01H 3E 01
A = 01H (numeric type flag)
5682
PUSH AF F5
Save type indicator
5683
If string (Z=1), jump to process filespec
5685
POP AF F1
Restore type (numeric)
5686
Convert numeric to integer in HL
5689
OR A B7
Check if result is zero
568A
If zero, "Type Mismatch" error
568D
PUSH AF F5
Save numeric value (now type=numeric confirmed)
568E
SYNCHR: Verify next char is comma
568F
DEFB 2CH 2C
Expected character: comma
5690
Evaluate string expression (filespec)
5693
Get string address in DE

5696H - Process FILES Command Parameters

This is a complex routine that appears to handle multiple parameter formats for the FILES command. The exact behavior continues in the next section starting at 56C8H. The routine manages string allocation and type checking for the directory listing parameters.

5696
SYNCHR: Verify next char is comma
5697
DEFB 2CH 2C
Expected character: comma
5698
PUSH HL E5
Save parser position
5699
LD HL,(4121H) 2A 21 41
Get variable pointer
569C
EX (SP),HL E3
Save var ptr, restore parser pos
569D
Evaluate string expression
56A0
SYNCHR: Verify next char
56A1
DEFB 29H 29
Expected character: ')' (close paren)
56A2
PUSH HL E5
Save parser position
56A3
Allocate string space
56A6
EX DE,HL EB
DE = allocated space address
56A7
POP BC C1
BC = parser position
56A8
POP HL E1
HL = variable pointer
56A9
POP AF F1
A = type flag (01H=numeric, other=string)
56AA
PUSH BC C5
Save parser position
56AB
LD BC,26E7H 01 E7 26
Return address for completion
56AE
PUSH BC C5
Push return address
56AF
LD BC,27F8H 01 F8 27
Secondary return address
56B2
PUSH BC C5
Push secondary return
56B3
PUSH AF F5
Save type flag again
56B4
PUSH DE D5
Save destination pointer
56B5
String manipulation routine
56B8
POP DE D1
Restore destination pointer
56B9
POP AF F1
Restore type flag
56BA
LD B,A 47
B = type flag
56BB
DEC A 3D
Adjust for zero-based index
56BC
LD C,A 4F
C = adjusted type
56BD
CP (HL) BE
Compare with actual type
56BE
LD A,00H 3E 00
Prepare return value = 0
56C0
RET NC D0
Return if type mismatch
56C1
LD A,(HL) 7E
Get actual string length
56C2
OR A B7
Check if zero length
56C3
RET Z C8
Return if empty string
56C4
LD A,(DE) 1A
Get first char of destination
56C5
OR A B7
Check if null
56C6
LD A,B 78
A = original type flag
56C7
RET Z C8
Return if destination empty

56C8H - FILES Handler String Comparison Loop

Continuation of FILES statement handler - performs string comparison and manipulation for directory filtering.

56C8
LD A,(HL) 7E
Get length byte from source string
56C9
INC HL 23
Point to low address byte
56CA
LD B,(HL) 46
B = address low byte
56CB
INC HL 23
Point to high address byte
56CC
LD H,(HL) 66
H = address high byte
56CD
LD L,B 68
HL = string address
56CE
LD B,00H 06 00
B = 00H (prepare for 16-bit add)
56D0
ADD HL,BC 09
HL = string start + length offset
56D1
SUB C 91
A = remaining length
56D2
LD B,A 47
B = remaining length
56D3
PUSH BC C5
Save remaining length
56D4
PUSH DE D5
Save destination pointer
56D5
EX (SP),HL E3
HL=dest, save source on stack
56D6
LD C,(HL) 4E
C = dest string length
56D7
INC HL 23
Point to address low byte
56D8
LD E,(HL) 5E
E = address low byte
56D9
INC HL 23
Point to address high byte
56DA
LD D,(HL) 56
DE = destination string address
56DB
POP HL E1
HL = source string address
56DC
PUSH HL E5
Save source address again
56DD
PUSH DE D5
Save dest address
56DE
PUSH BC C5
Save dest length

56DFH - Character-by-Character Comparison Loop

Compares source and destination strings character by character.

56DF
LD A,(DE) 1A
Get char from destination [LOOP START]
56E0
CP (HL) BE
Compare with source char
56E1
If different, handle mismatch
56E3
INC DE 13
Next dest character [MATCH PATH]
56E4
DEC C 0D
Decrement dest length counter
56E5
If dest exhausted, complete match
56E7
INC HL 23
Next source character
56E8
DEC B 05
Decrement source length counter
56E9
Continue if source not exhausted [LOOP]
56EB
POP DE D1
Clean up stack (dest length)
56EC
POP DE D1
Clean up stack (dest address)
56ED
POP BC C1
Clean up stack (source address)
56EE
POP DE D1
Clean up stack (remaining length)
56EF
XOR A AF
A = 0 (no match found)
56F0
RET C9
Return with no match

56F1H - Complete Match Found

Destination string completely matched against source - return position in source.

56F1
POP HL E1
HL = dest length (discard)
56F2
POP DE D1
DE = dest address (discard)
56F3
POP DE D1
DE = source address (discard)
56F4
POP BC C1
BC = remaining length
56F5
LD A,B 78
A = remaining source length
56F6
SUB H 94
Calculate match position
56F7
ADD A,C 81
Adjust with matched length
56F8
INC A 3C
Make 1-based position
56F9
RET C9
Return position in A

56FAH - Character Mismatch - Try Next Position

Characters didn't match - advance source position and retry.

This is a substring search routine used by the FILES statement to filter directory listings. It searches for a match of the destination string within the source string, returning the 1-based position if found, or 0 if not found. The algorithm tries every possible starting position in the source string.

56FA
POP BC C1
BC = dest length (discard)
56FB
POP DE D1
DE = dest address (restore)
56FC
POP HL E1
HL = source address
56FD
INC HL 23
Advance to next source position
56FE
DEC B 05
Decrement remaining source length
56FF
If source exhausted, no match
5701
Retry comparison at new position [LOOP END]

5703H - &H/&O Number Parser (Hexadecimal and Octal Literals)

Parses hexadecimal (&H) and octal (&O) number literals. Returns 16-bit value in DE. Used by BASIC to support &H and &O number formats.

The parser recognizes three formats: &H for hexadecimal (base 16), &O for octal (base 8), and a bare & followed by digits which defaults to octal. This provides compatibility with various BASIC dialects.

5703
LD DE,0000H 11 00 00
Initialize result to 0
5706
CHRGET: Get next character after '&'
5707
CP 4FH FE 4F
Is it 'O' (octal)?
5709
If 'O', process octal number
570B
CP 48H FE 48
Is it 'H' (hexadecimal)?
570D
If neither H nor O, treat as octal

570FH - Hexadecimal Number Parser (&H)

Parses up to 5 hexadecimal digits (supports 0-9, A-F). Result accumulated in HL, then moved to DE.

570F
LD B,05H 06 05
Max 5 hex digits (20 bits, but we use 16)
5711
INC HL 23
Move to next character [HEX LOOP START]
5712
LD A,(HL) 7E
Get next character [HEX LOOP]
5713
Check if character is letter (A-Z)
5716
EX DE,HL EB
Save parser pos in DE, result in HL
5717
If letter (carry clear), handle A-F
5719
CP 3AH FE 3A
Is it >= ':' (after '9')?
571B
If >= ':', invalid hex [ERROR PATH]
571D
SUB 30H D6 30
Convert '0'-'9' to 0-9
571F
If < '0', invalid hex [ERROR PATH]
5721
Jump to shift and add digit

5723H - Process Hex Letter (A-F)

5723
CP 47H FE 47
Is it >= 'G'?
5725
If >= 'G', invalid hex [ERROR PATH]
5727
SUB 37H D6 37
Convert 'A'-'F' to 10-15 (41H-37H=0AH)

5729H - Shift and Add Hex Digit

5729
ADD HL,HL 29
Multiply result by 16 (shift left 4 bits)
572A
ADD HL,HL 29
Shift 2
572B
ADD HL,HL 29
Shift 3
572C
ADD HL,HL 29
Shift 4 (×16 complete)
572D
OR L B5
Combine digit with result
572E
LD L,A 6F
Store in low byte
572F
DEC B 05
Decrement digit counter
5730
If 5 digits processed, finish [SUCCESS PATH]
5733
EX DE,HL EB
Restore parser pos to HL, result to DE
5734
Get next hex digit [HEX LOOP END]

5736H - Prepare for Octal Parse (No 'O' Specified)

5736
DEC HL 2B
Back up to character after '&'

5737H - Octal Number Parser (&O or bare &)

Parses octal digits (0-7). Result accumulated in HL, then moved to DE.

5737
CHRGET: Get next character [OCTAL LOOP START]
5738
EX DE,HL EB
DE=parser pos, HL=result
5739
If carry clear (not digit), finish [LOOP]
573B
CP 38H FE 38
Is it >= '8'?
573D
If >= '8', syntax error (invalid octal)
5740
LD BC,07B2H 01 B2 07
BC = return address after conversion
5743
PUSH BC C5
Push return address
5744
ADD HL,HL 29
Multiply by 8 (shift left 3 bits)
5745
RET C D8
If overflow, return [ERROR PATH]
5746
ADD HL,HL 29
Shift 2
5747
RET C D8
If overflow, return [ERROR PATH]
5748
ADD HL,HL 29
Shift 3 (×8 complete)
5749
RET C D8
If overflow, return [ERROR PATH]
574A
POP BC C1
Remove return address (no overflow)
574B
LD B,00H 06 00
B = 0 for 16-bit add
574D
SUB 30H D6 30
Convert '0'-'7' to 0-7
574F
LD C,A 4F
C = digit value
5750
ADD HL,BC 09
Add digit to result
5751
EX DE,HL EB
HL=parser pos, DE=result
5752
Get next octal digit [OCTAL LOOP END]

5754H - Finalize Number and Return

Common exit point for both hex and octal parsers. Converts result and returns.

The number parsers support hexadecimal (&H) and octal (&O or bare &) literals in BASIC expressions. Hexadecimal numbers can be up to 5 digits (though only 4 digits = 16 bits are typically used), and octal numbers can be any length until overflow. Invalid digits for the selected base cause appropriate errors. The final result is converted to BASIC's internal floating-point format before returning.

5754
Convert HL to floating point
5757
EX DE,HL EB
HL = parser position
5758
RET C9
Return to caller

5759H - MID$ Statement Handler

Implements the MID$ statement for modifying a substring within a string variable. Syntax: MID$(string$, position [, length]) = replacement$. This allows in-place modification of strings.

The MID$ statement requires careful handling because it modifies strings in place. The code checks whether the string is in the string space (above memory top) or in the program area, as different handling is needed for each case. Strings in program space are literals and should not normally be modified.

5759
INC HL 23
Skip past MID$ token
575A
SYNCHR: Verify next char is '('
575B
DEFB 28H 28
Expected character: '(' (open paren)
575C
Evaluate expression (string variable)
575F
Get string descriptor
5762
PUSH HL E5
Save parser position
5763
PUSH DE D5
Save string descriptor pointer
5764
EX DE,HL EB
HL = string descriptor pointer
5765
INC HL 23
Skip length byte
5766
LD E,(HL) 5E
E = string address low byte
5767
INC HL 23
Point to high byte
5768
LD D,(HL) 56
DE = string address
5769
LD HL,(40A0H) 2A A0 40
HL = memory top pointer
576C
CPDEHL: Compare DE with HL
576D
If string in string space, OK
576F
POP HL E1
Restore string descriptor
5770
PUSH HL E5
Save it again
5771
Check string in program area
5774
POP HL E1
Restore string descriptor
5775
PUSH HL E5
Save it again
5776
String assignment check

5779H - Parse Position, Length Parameters, and Replacement String

5779
POP HL E1
Restore string descriptor
577A
EX (SP),HL E3
HL=parser pos, save descriptor
577B
SYNCHR: Verify next char is comma
577C
DEFB 2CH 2C
Expected character: comma
577D
Evaluate integer expression (position)
5780
OR A B7
Check if position is zero
5781
If zero, "Type Mismatch" error
5784
PUSH AF F5
Save position
5785
LD A,(HL) 7E
Get next character
5786
Parse optional length parameter
5789
PUSH DE D5
Save length (in E)
578A
SYNCHR: Verify next char
578B
DEFB D5H D5
Expected character: D5H (PUSH DE opcode as delimiter)
578C
Evaluate string expression (replacement)
578F
PUSH HL E5
Save parser position
5790
Allocate string space
5793
EX DE,HL EB
DE = allocated space
5794
POP HL E1
Restore parser position
5795
POP BC C1
BC = previous stack entry
5796
POP AF F1
A = position parameter
5797
LD B,A 47
B = position
5798
EX (SP),HL E3
HL=string descriptor, save parser
5799
PUSH HL E5
Save descriptor again
579A
LD HL,26E7H 21 E7 26
Return address for completion
579D
EX (SP),HL E3
Push return addr, restore descriptor
579E
LD A,C 79
A = length (from earlier)
579F
OR A B7
Check if zero
57A0
RET Z C8
If no characters to replace, done
57A1
LD A,(HL) 7E
A = target string length
57A2
SUB B 90
A = length - position
57A3
If position beyond string, error
57A6
INC A 3C
Adjust for inclusive range
57A7
CP C B9
Compare with requested length
57A8
If less available, use available
57AA
LD A,C 79
Use requested length

57ABH - Perform String Replacement

Copies replacement characters into the target string at the specified position.

57AB
LD C,B 48
C = position
57AC
DEC C 0D
Make 0-based offset
57AD
LD B,00H 06 00
B = 0 for 16-bit add
57AF
PUSH DE D5
Save replacement string pointer
57B0
INC HL 23
Skip target length byte
57B1
LD E,(HL) 5E
E = target address low
57B2
INC HL 23
Point to high byte
57B3
LD H,(HL) 66
H = target address high
57B4
LD L,E 6B
HL = target string start
57B5
ADD HL,BC 09
HL = target position to replace
57B6
LD B,A 47
B = number of chars to replace
57B7
POP DE D1
DE = replacement string pointer
57B8
EX DE,HL EB
HL=replacement, DE=target
57B9
LD C,(HL) 4E
C = replacement string length
57BA
INC HL 23
Point to address low
57BB
LD A,(HL) 7E
A = address low byte
57BC
INC HL 23
Point to high byte
57BD
LD H,(HL) 66
H = address high byte
57BE
LD L,A 6F
HL = replacement string address
57BF
EX DE,HL EB
HL=target, DE=replacement source
57C0
LD A,C 79
A = replacement length
57C1
OR A B7
Check if zero
57C2
RET Z C8
If no replacement chars, done

57C3H - Character Copy Loop

The MID$ statement replaces up to the specified number of characters in the target string with characters from the replacement string. If the replacement string is longer than the specified length or available space, it's truncated. If the replacement string is shorter, only those characters are replaced.

57C3
LD A,(DE) 1A
Get char from replacement [LOOP START]
57C4
LD (HL),A 77
Store in target [LOOP]
57C5
INC DE 13
Next replacement char
57C6
INC HL 23
Next target position
57C7
DEC C 0D
Decrement replacement counter
57C8
RET Z C8
If done with replacement, return
57C9
Continue if target space remains [LOOP END]
57CB
RET C9
Return to caller

57CCH - Parse Optional Length Parameter

Helper routine to parse the optional length parameter in MID$ statement. Sets E to FFH if no length specified, otherwise evaluates the length expression.

57CC
LD E,FFH 1E FF
Default length = FFH (maximum)
57CE
CP 29H FE 29
Is next char ')' (no length)?
57D0
If ')', use default length
57D2
SYNCHR: Verify comma
57D3
DEFB 2CH 2C
Expected character: comma
57D4
Evaluate integer expression (length)

57D7H - Verify Closing Parenthesis

57D7
SYNCHR: Verify ')'
57D8
DEFB 29H 29
Expected character: ')' (close paren)
57D9
RET C9
Return to caller

57DAH - INPUT# Statement Handler

Reads data from a file using INPUT# statement. Checks if a file is open and routes to appropriate input handler.

57DA
PUSH HL E5
Save parser position
57DB
LD HL,(63BEH) 2A BE 63
Get current FCB pointer
57DE
LD A,H 7C
Check if file open
57DF
OR L B5
Is FCB pointer zero?
57E0
POP HL E1
Restore parser position
57E1
If no file, use regular INPUT
57E4
POP AF F1
Remove return address (change flow)
57E5
PUSH BC C5
Save BC
57E6
PUSH DE D5
Save DE
57E7
LD B,F0H 06 F0
B = 240 chars max per read
57E9
LD D,7FH 16 7F
D = 7FH (mask for high bit clear)
57EB
LD HL,(40A7H) 2A A7 40
HL = input buffer pointer

57EEH - Read Characters from File Loop

Reads characters from file into input buffer, processing special characters.

57EE
Read character from file [LOOP START]
57F1
LD E,A 5F
Save character in E [LOOP]
57F2
SUB 80H D6 80
Test high bit
57F4
SBC A,A 9F
A = FFH if high bit was set, 00H if clear
57F5
OR D B2
Combine with mask (7FH)
57F6
LD D,A 57
Update mask
57F7
LD A,E 7B
Restore character
57F8
AND D A2
Apply mask (clear high bit if needed)
57F9
LD (HL),A 77
Store in input buffer
57FA
CP 0DH FE 0D
Is it CR (carriage return)?
57FC
If CR, finish line
57FE
CP 0AH FE 0A
Is it LF (line feed)?
5800
If not LF, store and continue
5802
LD A,B 78
Check if first character
5803
CP F0H FE F0
Is counter still at F0H?
5805
If first char is LF, skip it [LOOP]

5807H - Continue Reading Characters

5807
INC HL 23
Advance buffer pointer
5808
Continue if space remains [LOOP END]

580AH - Terminate Input Line

580A
XOR A AF
A = 00H (null terminator)
580B
LD (HL),A 77
Terminate string
580C
POP DE D1
Restore DE
580D
POP BC C1
Restore BC
580E
LD HL,(40A7H) 2A A7 40
HL = input buffer start
5811
DEC HL 2B
Back up one position
5812
RET C9
Return to caller

5813H - INPUT# Separator Check

Checks for field separators (comma, colon) when reading from a file with INPUT#.

The INPUT# handler reads up to 240 characters (F0H) from a file, stopping at CR (0DH). It masks the high bit of characters and skips leading LF characters. The data is placed in the input buffer at 40A7H and null-terminated.

5813
PUSH HL E5
Save position
5814
LD HL,(63BEH) 2A BE 63
Get current FCB pointer
5817
LD A,H 7C
Check if file open
5818
OR L B5
Is FCB pointer zero?
5819
POP HL E1
Restore position
581A
LD A,C 79
A = separator character
581B
RET Z C8
If no file, return (use keyboard)
581C
POP AF F1
Remove return address
581D
LD A,C 79
A = separator again
581E
POP BC C1
Restore BC
581F
Jump to file character output routine

5822H - INPUT with File Check

Checks whether INPUT should read from a file or keyboard, and routes accordingly.

5822
INC SP 33
Remove two bytes from stack
5823
INC SP 33
(Clean up stack)
5824
EX (SP),HL E3
HL=top of stack, save original HL
5825
PUSH DE D5
Save DE
5826
LD DE,0387H 11 87 03
DE = comparison value
5829
CPDEHL: Compare DE with HL
582A
POP DE D1
Restore DE
582B
EX (SP),HL E3
Restore stack, get HL back
582C
If not file input, use normal INPUT
582E
PUSH HL E5
Save HL
582F
LD HL,(63BEH) 2A BE 63
Get current FCB pointer
5832
LD A,H 7C
Check if file open
5833
OR L B5
Is FCB pointer zero?
5834
POP HL E1
Restore HL
5835
If no file, keyboard input
5838
PUSH HL E5
Save HL again
5839
Read character from file
583C
If no carry, normal return
583F
PUSH BC C5
Save BC
5840
PUSH DE D5
Save DE
5841
PUSH HL E5
Save HL
5842
Complete PRINT# output
5845
POP HL E1
Restore HL
5846
POP DE D1
Restore DE
5847
POP BC C1
Restore BC
5848
LD A,(63E2H) 3A E2 63
Get EOF flag
584B
OR A B7
Check if EOF
584C
LD HL,1D1EH 21 1E 1D
HL = error handler address
584F
EX (SP),HL E3
Replace return with error handler
5850
If EOF, trigger INPUT PAST END error
5853
EX (SP),HL E3
Restore original return address
5854
PUSH BC C5
Save BC
5855
PUSH DE D5
Save DE
5856
LD HL,1929H 21 29 19
HL = string handling routine
5859
Process string
585C
POP DE D1
Restore DE
585D
POP BC C1
Restore BC
585E
LD A,0DH 3E 0D
A = CR character
5860
POP HL E1
Restore HL
5861
RET C9
Return to caller

5862H - Use Normal Keyboard INPUT

This section provides complex logic to determine whether INPUT should read from a file or the keyboard. It checks the FCB pointer at 63BEH to determine if a file is currently open for input operations. The code handles EOF conditions and routes to appropriate error handlers.

5862
LD (40A9H),A 32 A9 40
Store character
5865
Jump to keyboard INPUT handler

5868H - USR Function Address Table

Table of 10 addresses for USR(0) through USR(9) functions. All initialized to 1E4AH (Type Mismatch error handler). Users can POKE new addresses to redirect USR functions to custom machine language routines.

5868
DEFW 1E4AH 4A 1E
USR(0) default address - Type Mismatch error
586A
DEFW 1E4AH 4A 1E
USR(1) default address
586C
DEFW 1E4AH 4A 1E
USR(2) default address
586E
DEFW 1E4AH 4A 1E
USR(3) default address
5870
DEFW 1E4AH 4A 1E
USR(4) default address
5872
DEFW 1E4AH 4A 1E
USR(5) default address
5874
DEFW 1E4AH 4A 1E
USR(6) default address
5876
DEFW 1E4AH 4A 1E
USR(7) default address
5878
DEFW 1E4AH 4A 1E
USR(8) default address
587A
DEFW 1E4AH 4A 1E
USR(9) default address

587CH - INPUT Statement Entry Point (No File)

Main entry point for INPUT statement when no file is open. Checks if this is a special editing command (LIST, EDIT, AUTO, DELETE) or regular INPUT.

This routine detects special editing keys: LF (line feed), '[', '.', and ',' all trigger line number input for editing commands. ESC cancels input. ^Z (1AH) is used for special commands. Regular characters go through the normal INPUT buffer processing.

587C
POP HL E1
Get return address from stack
587D
PUSH HL E5
Put it back (peek at return)
587E
LD DE,1A7EH 11 7E 1A
DE = comparison address
5881
CPDEHL: Compare return address
5882
If not special case, normal INPUT
5885
LD A,0EH 3E 0E
A = 0EH (shift out control code)
5887
Output shift-out character
588A
Get character from keyboard
588D
CP 0AH FE 0A
Is it line feed?
588F
If LF, get line number
5891
CP 5BH FE 5B
Is it '[' key?
5893
If '[', get line number
5895
CP 2EH FE 2E
Is it '.' (period)?
5897
If period, get line number
5899
CP 2CH FE 2C
Is it ',' (comma)?
589B
If comma, get line number
589D
LD HL,(40A4H) 2A A4 40
HL = string space pointer
58A0
CP 1BH FE 1B
Is it ESC key?
58A2
If ESC, handle cancel
58A4
LD DE,FFFFH 11 FF FF
DE = -1 (default increment)
58A7
CP 1AH FE 1A
Is it ^Z (Ctrl-Z)?
58A9
If ^Z, process editing command
58AB
PUSH BC C5
Save BC
58AC
LD HL,5938H 21 38 59
HL = command processing routine
58AF
PUSH HL E5
Push return address
58B0
LD HL,(40A7H) 2A A7 40
HL = input buffer pointer
58B3
PUSH HL E5
Save buffer pointer
58B4
LD B,F0H 06 F0
B = 240 chars max input
58B6
LD C,B 48
C = same (F0H)
58B7
Jump to keyboard input routine

58BBH - Get Current Line Number for Editing

Retrieves the current line number from system variable for use in LIST, EDIT, AUTO commands.

58BB
LD DE,(40ECH) ED 5B EC 40
DE = current line number

58BFH - Process Editing Command

Processes special editing commands like AUTO, EDIT, LIST, DELETE. Parses optional line number and validates the command.

58BF
PUSH AF F5
Save command character
58C0
Get line number from input
58C3
POP DE D1
D = command character
58C4
NOP 00
(Padding or remnant)
58C5
LD A,D 7A
A = command character
58C6
If no carry (valid number), continue
58C8
CP 2EH FE 2E
Was command '.' (period)?
58CA
If period, handle special case
58CC
CP 2CH FE 2C
Was command ',' (comma)?
58CE
If comma, handle special case
58D0
CP 0AH FE 0A
Was it line feed?
58D2
If not LF, check for '['
58D4
LD A,(HL) 7E
Get low byte of line number
58D5
INC HL 23
Point to high byte
58D6
OR (HL) B6
OR with high byte (test if zero)
58D7
DEC HL 2B
Restore pointer
58D8
If line number nonzero, cancel
58DA
Continue processing

58DCH - Check for Carry Flag from Line Number Parse

58DC
If zero result, handle specially

58DEH - Check for '[' Key

58DE
CP 5BH FE 5B
Is it '[' key?
58E0
If not '[', finish

58E2H - Validate String Space Pointer

Checks if string space pointer has moved during command processing.

58E2
LD HL,(40A4H) 2A A4 40
Get current string space pointer
58E5
OR A B7
Clear carry for subtraction
58E6
SBC HL,BC ED 42
HL = current - saved
58E8
If unchanged, continue
58EA
ADD HL,BC 09
Restore HL [LOOP START]
58EB
PUSH BC C5
Save BC [LOOP]
58EC
POP DE D1
DE = BC
58ED
PUSH HL E5
Save HL
58EE
POP BC C1
BC = HL
58EF
LD A,(HL) 7E
Get low byte of address
58F0
INC HL 23
Point to high byte
58F1
LD H,(HL) 66
H = high byte
58F2
LD L,A 6F
HL = string address
58F3
CPDEHL: Compare with saved
58F4
If not match, keep searching [LOOP END]

58F6H - Transfer Parsed Values

58F6
PUSH BC C5
Save BC
58F7
POP HL E1
HL = BC

58F8H - Setup Command Parameters

Prepares registers for command execution - BC contains line number, DE contains next line pointer.

58F8
NOP 00
(Padding or alignment)
58F9
POP BC C1
Restore BC (original value)
58FA
PUSH HL E5
Save HL
58FB
POP BC C1
BC = HL (line number)
58FC
INC HL 23
Skip past length byte
58FD
INC HL 23
Skip past another byte
58FE
LD E,(HL) 5E
E = low byte of next pointer
58FF
INC HL 23
Point to high byte
5900
LD D,(HL) 56
DE = next line pointer
5901
CP 2CH FE 2C
Is command ','?
5903
If comma, handle renumber?
5906
PUSH DE D5
Save next line pointer
5907
PUSH BC C5
Save line number
5908
LD A,0FH 3E 0F
A = 0FH (shift in control code)
590A
Output shift-in character
590D
LD A,1DH 3E 1D
A = 1DH (cursor right)
590F
Move cursor right
5912
LD HL,(4020H) 2A 20 40
HL = cursor position pointer
5915
LD DE,FFC0H 11 C0 FF
DE = -64 (back one line on screen)
5918
ADD HL,DE 19
HL = cursor position - 64
5919
LD A,H 7C
Get high byte of position
591A
CP 3CH FE 3C
Compare with screen start (3C00H)
591C
If below screen, skip READY check
591E
LD B,0AH 06 0A
B = 10 (length of "READY ")
5920
LD DE,59BEH 11 BE 59
DE = "READY" string address

5923H - Compare Screen with "READY" String

Checks if "READY" appears on screen at the cursor position.

5923
LD A,(DE) 1A
Get char from READY string [LOOP START]
5924
CP (HL) BE
Compare with screen [LOOP]
5925
If mismatch, skip erase
5927
INC DE 13
Next char in READY
5928
INC HL 23
Next screen position
5929
Continue for all 10 chars [LOOP END]
592B
LD A,1BH 3E 1B
A = 1BH (ESC - erase to end of line)
592D
Erase "READY" from screen

5930H - Restore Cursor and Execute Command

5930
LD A,1EH 3E 1E
A = 1EH (cursor home)
5932
Move cursor to home position
5935
Jump to command executor

This section handles the interactive editing features. It detects "READY" on the screen and erases it before executing LIST, EDIT, AUTO, or DELETE commands. The cursor positioning code ensures clean display output. The routine at 2B33H handles the actual command execution based on the parsed parameters in BC (line number) and DE (next line pointer).

5938H - Command Keyword Detection (LIST/EDIT/DELETE/AUTO)

Identifies which editing command (LIST, EDIT, DELETE, AUTO) was entered and sets up parameters for execution.

5938
PUSH AF F5
Save flags
5939
If carry set, skip keyword check
593B
PUSH HL E5
Save input pointer
593C
LD A,(HL) 7E
Get first character of command
593D
LD HL,59A8H 21 A8 59
Point to "LIST" keyword
5940
CP 4CH FE 4C
Is it 'L' (LIST)?
5942
If 'L', process LIST
5944
LD HL,59ADH 21 AD 59
Point to "EDIT" keyword
5947
CP 45H FE 45
Is it 'E' (EDIT)?
5949
If 'E', process EDIT
594B
LD HL,59B9H 21 B9 59
Point to "AUTO" keyword
594E
CP 41H FE 41
Is it 'A' (AUTO)?
5950
If 'A', process AUTO
5952
LD HL,59B2H 21 B2 59
Point to "DELETE" keyword
5955
CP 44H FE 44
Is it 'D' (DELETE)?
5957
If not 'D', not a keyword

5959H - Process Recognized Keyword

Keyword was recognized - extract length and setup for comparison.

5959
LD A,(HL) 7E
Get keyword length byte
595A
LD (5992H),A 32 92 59
Store length for LDIR
595D
DEC A 3D
Length - 1
595E
LD (5975H),A 32 75 59
Store for ADD instruction **SELF-MODIFY**
5961
INC HL 23
Skip past length byte
5962
LD (598FH),HL 22 8F 59
Store keyword text address **SELF-MODIFY**
5965
POP HL E1
Restore input pointer
5966
PUSH HL E5
Save it again
5967
CHRGET: Get next character
5968
If digit, continue
596A
CP 2EH FE 2E
Is it '.' (period)?
596C
If not period, exit

596EH - Validate Complete Keyword Match

This routine uses SELF-MODIFYING CODE at three locations: 5975H (ADD nn), 598FH (LD HL,nnnn), and 5992H (LD C,nn). It expands abbreviated keywords (L, E, D, A) to their full forms (LIST, EDIT, DELETE, AUTO) by copying the full keyword text into the input buffer. The LDDR backwards copy prevents overwriting source data when the destination overlaps.

596E
Check for end of keyword
5971
If at end, not valid keyword
5973
LD A,B 78
A = B (start position)
5974
ADD 00H C6 00
Add keyword length **SELF-MODIFIED at 5975H**
5976
CP C B9
Compare with end position
5977
If beyond end, syntax error
597A
POP HL E1
Restore input pointer
597B
PUSH HL E5
Save it again
597C
PUSH DE D5
Save DE
597D
LD E,B 58
E = start position
597E
LD B,A 47
B = end position
597F
SUB E 93
A = bytes to move
5980
PUSH BC C5
Save count
5981
LD B,00H 06 00
B = 0 for 16-bit add
5983
LD C,E 4B
BC = start offset
5984
ADD HL,BC 09
HL = source + offset
5985
ADD A,L 85
Calculate destination low
5986
LD E,A 5F
E = dest low byte
5987
LD A,H 7C
Get source high byte
5988
ADC 00H CE 00
Add carry to high byte
598A
LD D,A 57
DE = destination address
598B
LDDR ED B8
Copy backwards (overlap safe)
598D
EX DE,HL EB
HL = destination
598E
LD HL,0000H 21 00 00
HL = keyword source **SELF-MODIFIED at 598FH**
5991
LD C,00H 0E 00
C = keyword length **SELF-MODIFIED at 5992H**
5993
LDIR ED B0
Copy keyword into input buffer
5995
POP BC C1
Restore BC
5996
POP DE D1
Restore DE

5997H - Exit Keyword Processing

5997
POP HL E1
Restore input pointer

5998H - Jump to Command Processor

5998
Jump to ROM command executor

599BH - Check for End of Keyword

Verifies that keyword is followed by valid delimiter (=, (, or CR).

599B
CHRGET: Get next character [LOOP START]
599C
CP 3DH FE 3D
Is it '=' (assignment)? [LOOP]
599E
RET Z C8
If '=', valid end (Z set)
599F
CP 28H FE 28
Is it '(' (function call)?
59A1
RET Z C8
If '(', valid end (Z set)
59A2
CP 0DH FE 0D
Is it CR (end of line)?
59A4
If not CR, keep checking [LOOP END]
59A6
OR A B7
Clear Z flag (not valid delimiter)
59A7
RET C9
Return (Z clear = not at end)

59A8H - Keyword String Table (DATA)

Length-prefixed keyword strings for LIST, EDIT, DELETE, and AUTO commands.

59A8
DEFB 04H 04
"LIST" keyword length
59A9
DEFM "LIST" 4C 49 53 54
"LIST" keyword text
59AD
DEFB 04H 04
"EDIT" keyword length
59AE
DEFM "EDIT" 45 44 49 54
"EDIT" keyword text
59B2
DEFB 06H 06
"DELETE" keyword length
59B3
DEFM "DELETE" 44 45 4C 45 54 45
"DELETE" keyword text
59B9
DEFB 04H 04
"AUTO" keyword length
59BA
DEFM "AUTO" 41 55 54 4F
"AUTO" keyword text

59BEH - "READY" String (DATA)

10-byte string displayed at BASIC ready prompt: "READY" followed by 5 spaces.

The "READY" string is exactly 10 bytes to fill a line on the TRS-80 screen. It's used by the code at 5923H to detect and erase the READY prompt when executing editing commands.

59BE
DEFM "READY " 52 45 41 44 59 20 20 20 20 20
READY prompt string (10 bytes)

59C8H - End of READY String / Code Boundary

59C8
RET C9
Return (boundary marker)

59C9H - SYSTEM Statement Handler

Exits BASIC and returns to TRSDOS operating system. Closes all files and restores DOS environment before exit.

The SYSTEM statement performs a clean exit from BASIC. It sets the SYSTEM active flag to prevent re-entry, restores the original DOS state saved at initialization (5200H), sets up an error handler, closes all files to flush buffers and release resources, then transfers control back to TRSDOS. The carry flag determines which DOS entry point to use.

59C9
PUSH AF F5
Save flags
59CA
LD A,FFH 3E FF
A = FFH (SYSTEM active flag)
59CC
LD (427AH),A 32 7A 42
Set SYSTEM active flag
59CF
LD HL,(5200H) 2A 00 52
Get original state from 5200H
59D2
LD (426FH),HL 22 6F 42
Restore saved state to 426FH
59D5
LD HL,4030H 21 30 40
HL = error handler address
59D8
LD (4204H),HL 22 04 42
Set error handler vector
59DB
Close all open files
59DE
POP AF F1
Restore flags
59DF
If no carry, exit via DOS vector
59E2
Exit to TRSDOS (warm boot)

59E5H - Check File Open and Process

Validates that a file is open and processes file operations. Used by various file I/O statements.

59E5
LD HL,(63BEH) 2A BE 63
Get current FCB pointer
59E8
LD A,H 7C
Check if file open
59E9
OR L B5
Is FCB pointer zero?
59EA
RET Z C8
If no file open, return
59EB
INC HL 23
Point to FCB+1 (mode byte)
59EC
LD A,(HL) 7E
Get file mode
59ED
POP HL E1
Get return address
59EE
PUSH DE D5
Save DE
59EF
PUSH AF F5
Save file mode
59F0
LD DE,2130H 11 30 21
DE = comparison value
59F3
CPDEHL: Compare return address
59F4
POP DE D1
D = file mode
59F5
LD A,D 7A
A = file mode
59F6
POP DE D1
Restore DE
59F7
If carry, jump to handler
59FA
Jump to alternate handler

59FDH - File Buffer Save Routine

Saves the current file FCB pointer and buffer pointer for later restoration.

59FD
LD HL,(63BEH) 2A BE 63
Get current FCB pointer
5A00
LD (40F3H),HL 22 F3 40
Save FCB pointer to 40F3H
5A03
LD HL,6250H 21 50 62
HL = default buffer address
5A06
LD (HL),00H 36 00
Initialize buffer (clear first byte)
5A08
LD (63C0H),HL 22 C0 63
Set current buffer pointer
5A0B
RET C9
Return to caller

5A0CH - File Buffer Restore Routine

Restores previously saved FCB and buffer pointers.

5A0C
LD HL,(40F3H) 2A F3 40
Get saved FCB pointer
5A0F
LD (63BEH),HL 22 BE 63
Restore current FCB pointer
5A12
LD HL,(63E0H) 2A E0 63
Get last allocated buffer end
5A15
LD (63C0H),HL 22 C0 63
Restore current buffer pointer
5A18
RET C9
Return to caller

5A19H - LIST File Mode Check

Checks if a file is open for LIST output. If file is open, redirects to file output instead of screen.

This routine intercepts LIST commands when a file is open. Instead of displaying to the screen, it redirects the LIST output to the open file by removing the normal return address and jumping to a file-specific LIST handler.

5A19
LD HL,(63BEH) 2A BE 63
Get current FCB pointer
5A1C
LD A,H 7C
Check if file open
5A1D
OR L B5
Is FCB pointer zero?
5A1E
RET Z C8
If no file, return (use screen)
5A1F
POP HL E1
Remove return address
5A20
Jump to file LIST handler

5A23H - Memory Calculation Routine

Converts floating point value to integer and performs memory-related calculation. Used by file buffer allocation routines.

This routine multiplies the input value by 192 (C0H), which is the size of file buffer structures. This is used to calculate memory requirements for file buffers. The result is converted to a format suitable for memory allocation.

5A23
Convert FP to integer in HL
5A26
LD A,C0H 3E C0
A = C0H (192 decimal)
5A28
Multiply HL by A
5A2B
OR A B7
Clear carry
5A2C
LD B,06H 06 06
B = 6
5A2E
LD C,00H 0E 00
C = 0
5A30
Jump to conversion routine

5A33H - Open File for Output Helper

Opens a file for output and saves the DOS state.

5A33
DOS: Open file for output
5A36
Jump to common save routine

5A38H - Open File for Input Helper

Opens a file for input and saves the DOS state.

5A38
DOS: Open file for input

5A3BH - Save DOS State After File Open

Common routine to save DOS state after opening a file.

5A3B
PUSH HL E5
Save HL register
5A3C
LD HL,(5200H) 2A 00 52
Get original state from 5200H
5A3F
LD (426FH),HL 22 6F 42
Save state to 426FH
5A42
POP HL E1
Restore HL
5A43
RET C9
Return to caller

5A44H - File # Validation Helper (Expects '#')

Sets C=1 and falls through to check for '#' character.

5A44
LD C,01H 0E 01
C = 1 (file number expected flag)

5A46H - File # Validation (Called from 5371H)

Checks if next character is '#', returns if not. Used by PRINT#, INPUT#, etc.

5A46
CP 23H FE 23
Is it '#' character?
5A48
RET NZ C0
If not '#', return
5A49
PUSH BC C5
Save BC
5A4A
Parse file number
5A4D
POP DE D1
D = saved C (expected flag)
5A4E
CP E BB
Compare file # with expected
5A4F
If mismatch, error
5A52
SYNCHR: Verify comma follows
5A53
DEFB 2CH 2C
Expected character: comma
5A54
LD (63BEH),BC ED 43 BE 63
Store file control block pointer
5A58
RET C9
Return to caller

5A59H - File # Parser

Parses file number after '#' character, validates range, and returns FCB pointer in BC.

The file number table at 63C0H contains 16 word pointers (32 bytes total) to FCB structures. Each file number (0-15) has a 2-byte pointer. The routine multiplies the file number by 2 (two ADD HL,DE) to index into this table. The FCB's first byte is the status: 00H=closed, non-zero=open.

5A59
DEC HL 2B
Back up to '#' character
5A5A
CHRGET: Get next char (skip '#')
5A5B
CP 23H FE 23
Is it '#'?
5A5D
If '#', handle special case
5A60
Evaluate expression (file number)
5A63
Convert to integer in A
5A66
LD E,A 5F
E = file number
5A67
LD A,(426DH) 3A 6D 42
Get maximum file number allowed
5A6A
CP E BB
Compare max with requested
5A6B
If requested > max, error
5A6E
LD D,00H 16 00
D = 0 (DE = file number)
5A70
PUSH HL E5
Save parser position
5A71
LD HL,63C0H 21 C0 63
HL = file pointer table base
5A74
ADD HL,DE 19
Add file number (×1)
5A75
ADD HL,DE 19
Add again (×2 for word pointers)
5A76
LD C,(HL) 4E
C = FCB pointer low byte
5A77
INC HL 23
Point to high byte
5A78
LD B,(HL) 46
BC = FCB pointer
5A79
LD A,(BC) 0A
Get first byte of FCB (status)
5A7A
OR A B7
Check if file is open (0=closed)
5A7B
POP HL E1
Restore parser position
5A7C
RET C9
Return (Z set if closed)

5A7DH - MKD$ Function Handler

Converts double-precision floating point to 8-byte string representation.

5A7D
LD A,02H 3E 02
A = 2 (MKD$ type code)
5A7F
LD BC,043EH 01 3E 04
BC = double-precision size params

5A80H - CVI Function Handler

Converts 2-byte string to integer value.

5A80
LD BC,083EH 01 3E 08
BC = integer conversion params

5A83H - CVS Function Handler (and common MKx$ processing)

Converts 4-byte string to single-precision value. Also serves as common code for MKI$/MKS$/MKD$.

5A83
PUSH AF F5
Save type code
5A84
Get string parameter
5A87
POP AF F1
Restore type code
5A88
Convert string to numeric
5A8B
LD HL,(40D4H) 2A D4 40
Get string descriptor pointer
5A8E
Release string space
5A91
Return with converted value

5A96H - CHR$ Function Handler (Disk Version)

Extended CHR$ function supporting additional parameters for disk BASIC.

5A96
LD A,01H 3E 01
A = 1 (CHR$ type)
5A98
LD BC,033EH 01 3E 03
BC = single byte params

5A99H - MKI$ Function Handler

Converts integer to 2-byte string representation.

5A99
LD BC,073EH 01 3E 07
BC = integer size params

5A9CH - MKS$ Function Handler (and common CVx processing)

Converts single-precision to 4-byte string. Also common code for CVI/CVS/CVD functions.

The MKI$/MKS$/MKD$ functions convert numeric values to binary string representations, while CVI/CVS/CVD convert binary strings back to numbers. These are used for binary file I/O. The type codes are: 1=integer (2 bytes), 2=single (4 bytes), 3=double (8 bytes). The string length must be exact for the type being converted.

5A9C
PUSH AF F5
Save type code
5A9D
Allocate string space
5AA0
POP AF F1
Restore type code
5AA1
CP (HL) BE
Compare type with string length
5AA2
If type >= length, Type Mismatch
5AA5
INC A 3C
Adjust type code
5AA6
INC HL 23
Skip length byte
5AA7
LD C,(HL) 4E
C = string address low
5AA8
INC HL 23
Point to high byte
5AA9
LD H,(HL) 66
H = string address high
5AAA
LD L,C 69
HL = string data address
5AAB
LD (40AFH),A 32 AF 40
Store type in variable type flag
5AAE
Complete conversion and return

5AB3H - WRITE# Statement Handler

Implements WRITE# for formatted output to sequential files. Automatically adds delimiters (commas) between fields and quotes around strings. Syntax: WRITE# filenumber, expression [, expression...]

WRITE# uses specific delimiters: strings are enclosed in quotes (22H) and fields are separated by commas (2CH). Numeric values use space (20H) delimiter. This differs from PRINT# which doesn't add quotes or commas automatically.

5AB3
LD DE,(63BEH) ED 5B BE 63
Get current FCB pointer
5AB7
LD A,D 7A
Check if file open
5AB8
OR E B3
Is FCB pointer zero?
5AB9
RET Z C8
If no file, return (use PRINT)
5ABA
POP AF F1
Remove return address (change flow)
5ABB
GETYP: Get variable type
5ABC
LD BC,2243H 01 43 22
BC = delimiters: B=22H (quote), C=43H
5ABF
LD DE,2C20H 11 20 2C
DE = delimiters: D=20H (space), E=2CH (comma)
5AC2
If not string (Z=0), numeric output
5AC5
LD E,D 5A
E = D = 20H (space delimiter for string)
5AC6
Jump to WRITE output routine

5AC9H - LINE INPUT# Statement Handler

Reads an entire line from a file into a string variable. Syntax: LINE INPUT# filenumber, string$. Unlike regular INPUT#, this reads the complete line including commas and quotes as literal characters.

5AC9
Validate '#' character present
5ACC
Evaluate expression (file number)
5ACF
Get string address in DE
5AD2
LD BC,2169H 01 69 21
BC = return address
5AD5
PUSH BC C5
Push return address
5AD6
PUSH DE D5
Save string descriptor
5AD7
LD BC,1F31H 01 31 1F
BC = parameters for line input
5ADA
XOR A AF
A = 0
5ADB
LD D,A 57
D = 0 (quote state)
5ADC
LD E,A 5F
E = 0 (delimiter state)

5ADDH - WRITE# Main Processing Loop

Core routine for reading and processing file data for WRITE# or LINE INPUT#. Handles quotes, delimiters, and special characters.

5ADD
PUSH AF F5
Save A register
5ADE
PUSH BC C5
Save delimiters (B=quote, C=field)
5ADF
PUSH HL E5
Save parser position
5AE0
Read character from file [LOOP START]
5AE3
If carry (EOF), error [ERROR PATH]
5AE6
CP 20H FE 20
Is it space? [LOOP]
5AE8
If not space, process normally
5AEA
INC D 14
Test D (quote state flag)
5AEB
DEC D 15
Restore D (sets Z if was 0)
5AEC
If in quotes (D≠0), skip space [LOOP]

5AEEH - Check for Quote Character

5AEE
CP 22H FE 22
Is it quote (")?
5AF0
If not quote, continue processing
5AF2
LD B,A 47
B = quote character (save it)
5AF3
LD A,E 7B
A = delimiter state
5AF4
CP 2CH FE 2C
Was last delimiter comma?
5AF6
LD A,B 78
Restore A = quote
5AF7
If not after comma, process normally
5AF9
LD D,B 50
D = quote (mark in-quote state)
5AFA
LD E,B 58
E = quote (delimiter state)
5AFB
Read next character (skip opening quote)
5AFE
If EOF, finish [ERROR PATH]

5B00H - Character Processing Main Logic

5B00
LD HL,(40A7H) 2A A7 40
HL = input buffer pointer
5B03
LD B,FFH 06 FF
B = max chars remaining (255)
5B05
LD C,A 4F
C = current character
5B06
LD A,D 7A
A = quote state
5B07
CP 22H FE 22
Are we in quoted string?
5B09
LD A,C 79
Restore A = current char
5B0A
If in quotes, store character
5B0C
CP 0DH FE 0D
Is it CR (end of line)?
5B0E
PUSH HL E5
Save buffer pointer
5B0F
If CR, finalize input
5B11
POP HL E1
Restore buffer pointer
5B12
CP 0AH FE 0A
Is it LF (line feed)?
5B14
If not LF, store character
5B16
LD C,A 4F
C = LF character
5B17
LD A,E 7B
A = last delimiter
5B18
CP 2CH FE 2C
Was last delimiter comma?
5B1A
LD A,C 79
Restore A = LF
5B1B
If not after comma, write char to buffer
5B1E
Read next character
5B21
If EOF, finish [ERROR PATH]
5B23
CP 0DH FE 0D
Is next char CR?
5B25
If not CR, continue
5B27
LD A,E 7B
A = last delimiter
5B28
CP 20H FE 20
Was it space?
5B2A
If space, read more
5B2C
CP 2CH FE 2C
Was it comma?
5B2E
LD A,0DH 3E 0D
A = CR
5B30
If comma, read more

5B32H - Check for Delimiter Match

5B32
OR A B7
Check if char is zero
5B33
If zero, read next
5B35
CP D BA
Does it match quote state?
5B36
If closing quote, finish field
5B38
CP E BB
Does it match delimiter?
5B39
If delimiter, finish field
5B3B
Store character in buffer

5B3EH - Read Next Character

5B3E
Read next character from file
5B41
If no EOF, continue loop [LOOP END]

5B43H - Field Complete - Process Terminator

5B43
PUSH HL E5
Save buffer pointer
5B44
CP 22H FE 22
Is terminator a quote?
5B46
If quote, skip trailing spaces
5B48
CP 20H FE 20
Is terminator a space?
5B4A
If not space, finalize

5B4CH - Skip Trailing Spaces/Quotes

5B4C
Read next character [SKIP LOOP START]
5B4F
If EOF, finalize [SKIP LOOP]
5B51
CP 20H FE 20
Is it space?
5B53
If space, keep skipping [SKIP LOOP END]
5B55
CP 2CH FE 2C
Is it comma?
5B57
If comma, finalize
5B59
CP 0DH FE 0D
Is it CR?
5B5B
If not CR, check for LF

5B5DH - Handle End of Line (CR Found)

5B5D
Read next character
5B60
If EOF, finalize
5B62
CP 0AH FE 0A
Is it LF?
5B64
If LF after CR, finalize

5B66H - Decrement Record Counter

5B66
LD HL,(63BEH) 2A BE 63
Get FCB pointer
5B69
LD BC,0007H 01 07 00
Offset to record counter
5B6C
ADD HL,BC 09
HL = FCB + 7 (record counter)
5B6D
Decrement and check counter
5B70
Jump to finalize

5B72H - Decrement Record Counter and Check for Refill

Decrements the record counter at (HL). If counter reaches FFH, reads next record from file. Returns Z flag set if counter is zero.

The record counter at FCB+7 tracks how many characters remain in the current buffer. When it reaches FFH (255), the buffer is exhausted and a new record must be read from disk. This automatic buffering makes sequential file access efficient.

5B72
DEC (HL) 35
Decrement record counter
5B73
LD A,(HL) 7E
Get new counter value
5B74
OR A B7
Check if zero
5B75
RET Z C8
If zero, return (Z set)
5B76
CP FFH FE FF
Did it wrap to FFH?
5B78
RET NZ C0
If not FFH, return
5B79
PUSH HL E5
Save counter address
5B7A
PUSH DE D5
Save DE
5B7B
LD BC,FFFBH 01 FB FF
BC = -5 (back to FCB start)
5B7E
ADD HL,BC 09
HL = FCB + 7 - 5 = FCB + 2
5B7F
EX DE,HL EB
DE = FCB + 2
5B80
DOS: Read next record
5B83
If error (NZ), translate DOS error
5B86
POP DE D1
Restore DE
5B87
POP HL E1
Restore counter address
5B88
LD (HL),FFH 36 FF
Reset counter to FFH (full buffer)
5B8A
RET C9
Return to caller

5B8BH - Finalize Field Input

Terminates the input buffer, processes the field data, and returns to caller.

5B8B
POP HL E1
Restore buffer pointer
5B8C
LD (HL),00H 36 00
Null-terminate buffer
5B8E
LD HL,(40A7H) 2A A7 40
Get input buffer start
5B91
DEC HL 2B
Back up one position
5B92
LD A,E 7B
A = last delimiter
5B93
SUB 20H D6 20
Check if space (20H)
5B95
If space, special handling
5B97
LD B,00H 06 00
B = 0
5B99
Process input data
5B9C
POP HL E1
Restore HL from stack
5B9D
RET C9
Return to caller

5B9EH - Space Delimiter Special Handling

5B9E
CHRGET: Get next character
5B9F
Process numeric input
5BA2
POP HL E1
Restore HL
5BA3
RET C9
Return to caller

5BA4H - Store Character in Input Buffer

Stores character in buffer if non-zero and space remains. Auto-exits if buffer full.

5BA4
OR A B7
Check if character is zero
5BA5
RET Z C8
If zero, don't store
5BA6
LD (HL),A 77
Store character in buffer
5BA7
INC HL 23
Advance buffer pointer
5BA8
DEC B 05
Decrement chars remaining
5BA9
RET NZ C0
If space remains, return
5BAA
POP BC C1
Clean stack (remove return addr)
5BAB
Buffer full - finalize input

5BADH - LOAD/RUN/MERGE Common Entry

Common initialization for LOAD, RUN, and MERGE statements. Sets up parameters and jumps to main OPEN processing.

5BAD
LD D,01H 16 01
D = 01H (LOAD/RUN mode)
5BAF
XOR A AF
A = 0
5BB0
Jump to OPEN processing routine

5BB3H - RUN Statement (File Version)

Loads and executes a BASIC program from disk. Syntax: RUN "filename"

The RUN statement accepts optional ",R" parameter to start execution. The RUN mode flag at 5200H is set to FFH to distinguish from LOAD. After loading completes, execution transfers to the newly loaded program.

5BB3
RET C D8
If carry set, return
5BB4
POP AF F1
Remove return address (change flow)
5BB5
LD A,FFH 3E FF
A = FFH (RUN flag)
5BB7
LD (5200H),A 32 00 52
Set RUN mode flag
5BBA
OR AFH F6 AF
Set flags
5BBC
PUSH AF F5
Save flags
5BBD
Call LOAD common routine
5BC0
LD A,(426DH) 3A 6D 42
Get max file number
5BC3
LD (63E3H),A 32 E3 63
Save to file count storage
5BC6
DEC HL 2B
Back up parser
5BC7
CHRGET: Get next char
5BC8
If end of statement, execute
5BCA
SYNCHR: Verify comma
5BCB
DEFB 2CH 2C
Expected character: comma
5BCC
SYNCHR: Verify 'R'
5BCD
DEFB 52H 52
Expected character: 'R'
5BCE
If not 'R', syntax error

5BD1H - RUN Statement Execution (Continued)

Completes RUN statement by clearing file number, setting EOF flag, and executing the loaded program.

5BD1
POP AF F1
Restore flags
5BD2
XOR A AF
A = 0
5BD3
LD (426DH),A 32 6D 42
Clear max file number (no files)
5BD6
OR F1H F6 F1
A = F1H (EOF flag value)

5BD8H - LOAD Common Completion

Common exit point for LOAD and RUN. Sets up EOF flag, initializes buffer, and completes the load operation.

5BD8
LD (63E2H),A 32 E2 63
Set EOF flag to A (F1H)
5BDB
LD HL,6250H 21 50 62
HL = default buffer address
5BDE
LD (HL),00H 36 00
Initialize buffer (clear first byte)
5BE0
LD (63C0H),HL 22 C0 63
Set current buffer pointer
5BE3
Process program in memory
5BE6
LD A,(63E3H) 3A E3 63
Get saved file count
5BE9
LD (426DH),A 32 6D 42
Restore max file number
5BEC
LD HL,(63E0H) 2A E0 63
Get last buffer end pointer
5BEF
LD (63C0H),HL 22 C0 63
Restore current buffer pointer
5BF2
LD (63BEH),HL 22 BE 63
Restore current FCB pointer
5BF5
Read character from file
5BF8
If EOF, finish [ERROR PATH]
5BFB
INC A 3C
Increment character
5BFC
If not FFH, continue

5BFEH - Load Program Into Memory

Main program loading loop - reads file data into memory until EOF or memory full.

5BFE
LD HL,(40A4H) 2A A4 40
HL = string space pointer [LOAD LOOP START]
5C01
EX DE,HL EB
DE = string space
5C02
LD HL,(40A0H) 2A A0 40
HL = memory top [LOAD LOOP]
5C05
LD BC,FFAAH 01 AA FF
BC = -86 (safety margin)
5C08
ADD HL,BC 09
HL = memory top - 86
5C09
CPDEHL: Compare string space with limit
5C0A
EX DE,HL EB
HL = string space
5C0B
If out of memory, finish [ERROR PATH]
5C0D
Read character from file
5C10
LD (HL),A 77
Store character in memory
5C11
INC HL 23
Advance memory pointer
5C12
If no EOF, continue loading [LOAD LOOP END]
5C14
Finalize program in memory
5C17
INC HL 23
Skip terminator byte
5C18
INC HL 23
Skip second terminator
5C19
LD (40F9H),HL 22 F9 40
Save end of file buffer
5C1C
LD HL,426DH 21 6D 42
HL = max file number address
5C1F
LD A,(HL) 7E
Get current max file number
5C20
LD (63E3H),A 32 E3 63
Save to file count storage
5C23
LD (HL),00H 36 00
Clear max file number
5C25
Link program lines
5C28
LD A,(63E3H) 3A E3 63
Get saved file count
5C2B
LD (426DH),A 32 6D 42
Restore max file number
5C2E
LD A,(63E2H) 3A E2 63
Get EOF flag
5C31
OR A B7
Check if set
5C32
If not EOF, normal return
5C35
If EOF, execute loaded program

The LOAD routine reads the program file byte-by-byte into the string space area, checking memory limits. After loading, it processes the program lines (1AF8H), links them properly (1B5DH), and if this is RUN (EOF flag = F1H), executes the program at 1D1EH.

5C38H - PRINT# Output Completion

Finalizes PRINT# statement output. Closes file if requested and cleans up.

5C38
Finalize PRINT output
5C3B
Close file helper
5C3E
POP HL E1
Get return address
5C3F
PUSH DE D5
Save DE
5C40
LD DE,1A1FH 11 1F 1A
DE = comparison address
5C43
CPDEHL: Compare return address
5C44
POP DE D1
Restore DE
5C45
PUSH HL E5
Push return address back
5C46
If match, cleanup file
5C49
Return to main interpreter

5C4CH - Out of Memory During LOAD

5C4C
Process partial program
5C4F
Trigger Out of Memory error

5C52H - MERGE Statement Handler

Merges program from disk with current program in memory. Syntax: MERGE "filename"

5C52
POP BC C1
Remove return address
5C53
Call LOAD common routine
5C56
DEC HL 2B
Back up parser
5C57
CHRGET: Get next char
5C58
If end of statement, merge
5C5A
Complete PRINT# if needed
5C5D
Syntax error

5C60H - Execute MERGE Operation

5C60
XOR A AF
A = 0 (clear EOF flag)
5C61
LD (63E2H),A 32 E2 63
Clear EOF flag (not RUN)
5C64
Read first character
5C67
If EOF immediately, finish
5C6A
INC A 3C
Check for FFH marker
5C6B
If FFH (binary), error

5C6EH - MERGE/LOAD Record Processing

5C6E
LD HL,(63BEH) 2A BE 63
Get FCB pointer
5C71
LD BC,0007H 01 07 00
Offset to record counter
5C74
ADD HL,BC 09
HL = FCB + 7
5C75
Decrement record counter
5C78
Return to interpreter

5C7BH - PRINT# Statement Handler

Outputs formatted data to a file. Syntax: PRINT# filenumber, expression [; expression...]

5C7B
RET C D8
If carry set, return
5C7C
POP AF F1
Remove return address
5C7D
PUSH HL E5
Save parser position
5C7E
LD HL,(63BEH) 2A BE 63
Get FCB pointer
5C81
LD A,H 7C
Check if file open
5C82
OR L B5
Is FCB pointer zero?
5C83
LD DE,0084H 11 84 00
DE = error code (Bad File Mode)
5C86
If file open, error
5C89
POP HL E1
Restore parser position
5C8A
File cleanup routine
5C8D
Jump to PRINT handler

5C90H - SAVE Statement Handler

Saves current BASIC program to disk. Syntax: SAVE "filename" [,A]

5C90
LD D,02H 16 02
D = 02H (SAVE mode)
5C92
Call file open routine
5C95
DEC HL 2B
Back up parser
5C96
CHRGET: Get next char
5C97
If end of statement, save ASCII
5C99
SYNCHR: Verify comma
5C9A
DEFB 2CH 2C
Expected character: comma
5C9B
SYNCHR: Verify 'A'
5C9C
DEFB 41H 41
Expected character: 'A' (ASCII)
5C9D
Jump to ASCII save handler

5CA0H - Save Program in Binary Format

Saves program as tokenized binary format (default for SAVE without ,A option).

SAVE writes the program in tokenized binary format by default. The FFH marker at the start indicates binary format. The ",A" option (handled at 2B2EH) saves in ASCII format instead. Binary saves are smaller and faster but not human-readable.

5CA0
LD A,FFH 3E FF
A = FFH (binary marker)
5CA2
Write marker to file
5CA5
LD DE,(40F9H) ED 5B F9 40
DE = end of file buffer
5CA9
LD HL,(40A4H) 2A A4 40
HL = string space pointer (program start)
5CAC
CPDEHL: Compare pointers [SAVE LOOP START]
5CAD
If all written, finish [SAVE LOOP END]
5CAF
LD A,(HL) 7E
Get byte from program [SAVE LOOP]
5CB0
INC HL 23
Advance program pointer
5CB1
PUSH DE D5
Save end pointer
5CB2
Write byte to file
5CB5
POP DE D1
Restore end pointer
5CB6
Continue saving [LOOP]

5CB8H - CLOSE Statement Handler

Closes one or all open files. Syntax: CLOSE [#filenumber] or CLOSE (closes all files)

5CB8
LD BC,5E14H 01 14 5E
BC = file close routine address
5CBB
LD A,(426DH) 3A 6D 42
A = max file number
5CBE
If specific file, jump to handler

5CC0H - Close All Files Loop

Iterates through all file numbers and closes each open file.

5CC0
PUSH HL E5
Save parser position [CLOSE ALL LOOP START]
5CC1
PUSH BC C5
Save close routine address
5CC2
PUSH AF F5
Save file number counter [CLOSE ALL LOOP]
5CC3
LD DE,5CC9H 11 C9 5C
DE = return address
5CC6
PUSH DE D5
Push return address
5CC7
PUSH BC C5
Push close routine address
5CC8
RET C9
Call close routine (RET to BC)
5CC9
POP AF F1
Restore file number
5CCA
POP BC C1
Restore close routine
5CCB
DEC A 3D
Decrement file counter
5CCC
If more files, continue [CLOSE ALL LOOP END]
5CCF
POP HL E1
Restore parser position
5CD0
RET C9
Return to caller

5CD1H - Check for Additional Files to Close

5CD1
POP BC C1
Remove BC from stack
5CD2
POP HL E1
Get parser position
5CD3
LD A,(HL) 7E
Get next character
5CD4
CP 2CH FE 2C
Is it comma?
5CD6
RET NZ C0
If not comma, done
5CD7
CHRGET: Skip comma

5CD8H - Close Specific File Number

5CD8
PUSH BC C5
Save close routine address
5CD9
LD A,(HL) 7E
Get next character
5CDA
CP 23H FE 23
Is it '#'?
5CDC
If '#', skip it
5CDF
Get file number in A
5CE2
EX (SP),HL E3
HL = close routine, save parser
5CE3
PUSH HL E5
Push close routine as return
5CE4
LD DE,5CD1H 11 D1 5C
DE = continuation address
5CE7
PUSH DE D5
Push continuation address
5CE8
JP (HL) E9
Jump to close routine

5CE9H - Close All Files Routine

Emergency close all files. Called by SYSTEM, errors, and program termination.

5CE9
PUSH DE D5
Save DE
5CEA
PUSH BC C5
Save BC
5CEB
XOR A AF
A = 0 (close all marker)
5CEC
Call CLOSE handler
5CEF
POP BC C1
Restore BC
5CF0
POP DE D1
Restore DE
5CF1
XOR A AF
A = 0 (clear flags)
5CF2
RET C9
Return to caller

5CF3H - FIELD Statement Handler

Defines field structure for random access files. Syntax: FIELD #n, width AS stringvar [, width AS stringvar...]

5CF3
Parse file number
5CF6
If file not open, error
5CF9
SUB 03H D6 03
Check file mode (must be random=3)
5CFB
If not random access, error
5CFE
EX DE,HL EB
DE = parser position
5CFF
LD HL,000BH 21 0B 00
HL = offset 11 (record length)
5D02
ADD HL,BC 09
HL = FCB + 11
5D03
LD A,(HL) 7E
Get record length
5D04
LD (63B6H),A 32 B6 63
Save to record length variable
5D07
XOR A AF
A = 0 (field position)
5D08
EX DE,HL EB
HL = parser, DE = FCB+11
5D09
LD DE,0034H 11 34 00
DE = offset 52 (buffer start)

5D0CH - FIELD Definition Loop

Processes each field definition in the FIELD statement.

5D0C
EX DE,HL EB
Swap DE/HL [FIELD LOOP START]
5D0D
ADD HL,BC 09
HL = FCB + offset [FIELD LOOP]
5D0E
LD B,A 47
B = current position
5D0F
EX DE,HL EB
Restore HL = parser
5D10
LD A,(HL) 7E
Get next character
5D11
CP 2CH FE 2C
Is it comma?
5D13
RET NZ C0
If not comma, done [FIELD LOOP END]
5D14
PUSH DE D5
Save buffer address
5D15
PUSH BC C5
Save position
5D16
Get field width in A
5D19
PUSH AF F5
Save width
5D1A
SYNCHR: Verify 'A'
5D1B
DEFB 41H 41
Expected: 'A' (AS keyword)
5D1C
SYNCHR: Verify 'S'
5D1D
DEFB 53H 53
Expected: 'S'
5D1E
Evaluate string variable
5D21
Get string descriptor address
5D24
POP AF F1
Restore width
5D25
POP BC C1
Restore position
5D26
EX (SP),HL E3
HL = buffer addr, save parser
5D27
LD C,A 4F
C = width
5D28
ADD A,B 80
A = position + width
5D29
If no overflow, continue
5D2B
If overflow, error

5D2EH - Validate Field Width

5D2E
LD B,A 47
B = new position
5D2F
LD A,(63B6H) 3A B6 63
A = record length
5D32
CP B B8
Compare with new position
5D33
If within record, OK
5D35
OR A B7
Check if record length is zero
5D36
If nonzero and overflow, error

5D39H - Store Field Descriptor

The FIELD statement maps string variables to sections of a random access file's record buffer. Each field has a width (in bytes) and a string variable name. The statement stores width and buffer address in the string descriptor (3 bytes: length, addr_low, addr_high). The field position is tracked and validated against the record length (63B6H) to prevent buffer overflow.

5D39
LD A,B 78
A = new position
5D3A
OR A B7
Check if zero
5D3B
EX DE,HL EB
DE = buffer address
5D3C
LD (HL),C 71
Store width in descriptor
5D3D
INC HL 23
Next byte
5D3E
LD (HL),E 73
Store buffer address low
5D3F
INC HL 23
Next byte
5D40
LD (HL),D 72
Store buffer address high
5D41
LD B,00H 06 00
B = 0 for BC
5D43
POP HL E1
Restore parser position
5D44
If more fields, continue loop
5D46
LD A,C 79
A = width
5D47
OR A B7
Check if zero
5D48
RET NZ C0
If nonzero, return
5D49
Process next field

5D4BH - RSET Statement Handler

Right-justify string in field. Syntax: RSET stringvar = expression. Pads left side with spaces.

5D4B
OR 37H F6 37
Set bit 5 and others (RSET flag)

5D4DH - LSET Statement Handler

Left-justify string in field. Syntax: LSET stringvar = expression. Pads right side with spaces. RSET falls through to here.

5D4D
PUSH AF F5
Save LSET/RSET flag
5D4E
Evaluate left side (string variable)
5D51
Get string descriptor in DE
5D54
PUSH DE D5
Save descriptor address
5D55
SYNCHR: Verify '='
5D56
DEFB D5H D5
Expected character: '=' (equals sign, actually D5H is unusual...)
5D57
Evaluate right side (string expression)
5D5A
POP BC C1
BC = destination descriptor
5D5B
EX (SP),HL E3
HL = LSET/RSET flag, save parser
5D5C
PUSH HL E5
Save flag again
5D5D
PUSH BC C5
Save destination descriptor
5D5E
Get source string address in HL
5D61
LD B,(HL) 46
B = source string length
5D62
EX (SP),HL E3
HL = dest descriptor, save source
5D63
LD A,(HL) 7E
A = destination length
5D64
LD C,A 4F
C = destination length
5D65
PUSH BC C5
Save lengths (B=src, C=dst)
5D66
PUSH HL E5
Save dest descriptor
5D67
PUSH AF F5
Save dest length
5D68
INC HL 23
Point to address bytes
5D69
LD E,(HL) 5E
E = dest address low
5D6A
INC HL 23
Next byte
5D6B
LD D,(HL) 56
DE = destination buffer address
5D6C
OR A B7
Check if dest length is zero
5D6D
If zero length, cleanup and exit
5D6F
LD HL,(40A4H) 2A A4 40
HL = string space pointer
5D72
CPDEHL: Is dest in string space?
5D73
If not in string space, skip check
5D75
LD HL,(40F9H) 2A F9 40
HL = end of file buffer
5D78
CPDEHL: Is dest below file buffer?
5D79
If in safe area, proceed

NOTE: The SYNCHR at 5D56H uses D5H as the expected character. This is unusual - D5H is not the '=' character (which is 3DH). This appears to be an error or the bytes may be misaligned. The hex should be verified against the actual file.

5D7BH - Garbage Collection for Field Assignment

If destination is a temporary string, performs garbage collection to make room.

5D7B
LD E,C 59
E = destination length
5D7C
LD D,00H 16 00
DE = dest length (16-bit)
5D7E
LD HL,(40A0H) 2A A0 40
HL = memory top
5D81
ADD HL,DE 19
HL = top + length
5D82
EX DE,HL EB
DE = required top
5D83
LD HL,(40D6H) 2A D6 40
HL = temp string pointer
5D86
Perform garbage collection
5D89
If carry (error), handle it
5D8B
POP AF F1
Restore dest length
5D8C
LD A,C 79
A = dest length
5D8D
Allocate string space
5D90
POP HL E1
Restore dest descriptor address
5D91
POP BC C1
Restore lengths
5D92
EX (SP),HL E3
HL = source string, save dest desc
5D93
PUSH DE D5
Save new address
5D94
PUSH BC C5
Save lengths
5D95
Get source string again
5D98
POP BC C1
Restore lengths
5D99
POP DE D1
Restore new address
5D9A
EX (SP),HL E3
HL = dest descriptor
5D9B
PUSH BC C5
Save lengths
5D9C
PUSH HL E5
Save dest descriptor
5D9D
INC HL 23
Point to address
5D9E
LD (HL),E 73
Store new address low
5D9F
INC HL 23
Next byte
5DA0
LD (HL),D 72
Store new address high
5DA1
PUSH AF F5
Save A

5DA2H - Get Source and Destination Pointers

5DA2
POP AF F1
Restore A
5DA3
POP HL E1
HL = dest descriptor
5DA4
INC HL 23
Point to address
5DA5
LD E,(HL) 5E
E = dest address low
5DA6
INC HL 23
Next byte
5DA7
LD D,(HL) 56
DE = dest buffer address
5DA8
POP BC C1
BC = lengths (B=src, C=dst)
5DA9
POP HL E1
HL = source descriptor
5DAA
PUSH DE D5
Save dest address
5DAB
INC HL 23
Point to source address
5DAC
LD E,(HL) 5E
E = source address low
5DAD
INC HL 23
Next byte
5DAE
LD D,(HL) 56
DE = source address
5DAF
EX DE,HL EB
HL = source address
5DB0
POP DE D1
DE = dest address
5DB1
LD A,C 79
A = dest length
5DB2
CP B B8
Compare dest with source length
5DB3
If dest >= source, use dest length
5DB5
LD B,A 47
B = dest length (truncate source)

5DB6H - Calculate Padding and Perform Copy

5DB6
SUB B 90
A = dest length - copy length
5DB7
LD C,A 4F
C = padding length
5DB8
POP AF F1
Restore LSET/RSET flag
5DB9
If RSET (NC), pad left with spaces
5DBC
INC B 04
Test B
5DBD
DEC B 05
Restore B (set Z if was 0)
5DBE
If no chars to copy, skip

5DC0H - String Copy Loop

5DC0
LD A,(HL) 7E
Get source character [COPY LOOP START]
5DC1
LD (DE),A 12
Store to destination [COPY LOOP]
5DC2
INC HL 23
Next source
5DC3
INC DE 13
Next destination
5DC4
Continue copy [COPY LOOP END]

5DC6H - Zero-Length Field Cleanup

5DC6
POP BC C1
Clean stack (5 values)
5DC7
POP BC C1
Clean stack
5DC8
POP BC C1
Clean stack
5DC9
POP BC C1
Clean stack
5DCA
POP BC C1
Clean stack

5DCBH - Pad Right Side (LSET)

5DCB
If LSET (C set), pad right with spaces
5DCE
POP HL E1
Restore parser position
5DCF
RET C9
Return to caller

5DD0H - Fill with Spaces Subroutine

Fills C bytes at (DE) with spaces (20H). Used for padding in LSET/RSET.

5DD0
LD A,20H 3E 20
A = space character
5DD2
INC C 0C
Test C [PAD LOOP START]
5DD3
DEC C 0D
Restore C (set Z if was 0) [PAD LOOP]
5DD4
RET Z C8
If no padding needed, return
5DD5
LD (DE),A 12
Store space
5DD6
INC DE 13
Next position
5DD7
Continue padding [PAD LOOP END]

5DD9H - String Allocation Error Handler

5DD9
POP AF F1
Clean stack
5DDA
POP HL E1
Clean stack
5DDB
POP BC C1
Clean stack
5DDC
EX (SP),HL E3
Get source descriptor
5DDD
EX DE,HL EB
DE = source descriptor
5DDE
If error not zero, skip conversion
5DE0
PUSH BC C5
Save BC
5DE1
LD A,B 78
A = source length
5DE2
Convert to string type
5DE5
Process string
5DE8
POP BC C1
Restore BC

5DE9H - Continue Error Recovery

5DE9
EX (SP),HL E3
Restore stack state
5DEA
PUSH BC C5
Save BC
5DEB
PUSH HL E5
Save HL
5DEC
PUSH AF F5
Save AF
5DED
Jump back to retry allocation

5DEFH - EOF Function Handler

Tests if end-of-file reached for a file. Syntax: EOF(filenumber). Returns -1 (true) if at EOF, 0 (false) otherwise.

5DEF
Get file number and validate
5DF2
CP 02H FE 02
Is it output mode (02H)?
5DF4
If output, error (can't EOF on output)
5DF7
LD HL,000FH 21 0F 00
HL = offset 15 (current record high)
5DFA
ADD HL,BC 09
HL = FCB + 15
5DFB
LD A,(HL) 7E
A = current record high byte
5DFC
DEC HL 2B
HL = FCB + 14
5DFD
LD E,(HL) 5E
E = current record low byte
5DFE
DEC HL 2B
HL = FCB + 13
5DFF
CP (HL) BE
Compare current high with last high
5E00
If different, not at EOF
5E02
DEC HL 2B
HL = FCB + 12
5E03
LD A,E 7B
A = current low byte
5E04
CP (HL) BE
Compare current low with last low
5E05
If different, not at EOF
5E07
DEC HL 2B
HL = FCB + 11 (record length)
5E08
DEC HL 2B
HL = FCB + 10 (buffer position)
5E09
LD A,(HL) 7E
A = buffer position
5E0A
DEC HL 2B
HL = FCB + 9
5E0B
DEC HL 2B
HL = FCB + 8
5E0C
DEC HL 2B
HL = FCB + 7 (chars remaining)
5E0D
SUB (HL) 96
A = position - remaining

5E0EH - Return EOF Status

EOF checks if the current record number equals the last record number AND if the buffer position equals or exceeds the characters remaining. This indicates all data has been read. The function returns -1 (true) if at EOF, 0 (false) otherwise.

5E0E
SUB 01H D6 01
Set carry if A was 0
5E10
SBC A,A 9F
A = FFH if carry, 00H if no carry
5E11
Convert to floating point and return

5E14H - File Close Helper

Internal file close routine. Validates file number and closes the file via DOS.

5E14
Get file number in A, FCB in BC
5E17
RET Z C8
If file not open (Z), return
5E18
CP 01H FE 01
Is it input mode?
5E1A
If input, skip flush
5E1C
PUSH BC C5
Save FCB pointer
5E1D
XOR A AF
A = 0 (clear flag)
5E1E
LD (BC),A 02
Clear FCB status byte
5E1F
INC BC 03
BC = FCB + 1
5E20
INC BC 03
BC = FCB + 2
5E21
LD D,B 50
D = B
5E22
LD E,C 59
DE = FCB + 2
5E23
DOS: Close file
5E26
If error, translate DOS error
5E29
POP BC C1
Restore FCB pointer

5E2AH - Clear File Buffer

5E2A
LD D,34H 16 34
D = 52 (buffer size to clear)
5E2C
XOR A AF
A = 0 [CLEAR LOOP START]
5E2D
LD (BC),A 02
Clear byte in FCB [CLEAR LOOP]
5E2E
INC BC 03
Next byte
5E2F
DEC D 15
Decrement counter
5E30
Continue clearing [CLEAR LOOP END]
5E32
RET C9
Return to caller

5E33H - LOC Function Handler

Returns current record number for random access file. Syntax: LOC(filenumber)

5E33
Get file number and FCB
5E36
If file not open, error
5E39
SCF 37
Set carry flag
5E3A
LD HL,000CH 21 0C 00
HL = offset 12 (last record low)
5E3D
PUSH AF F5
Save flags
5E3E
ADD HL,BC 09
HL = FCB + 12
5E3F
LD E,(HL) 5E
E = last record low byte
5E40
INC HL 23
HL = FCB + 13
5E41
LD D,(HL) 56
DE = last record number
5E42
LD HL,000BH 21 0B 00
HL = offset 11 (record length)
5E45
ADD HL,BC 09
HL = FCB + 11
5E46
LD A,(HL) 7E
A = record length
5E47
LD (5E69H),A 32 69 5E
Store to self-modify location **SELF-MODIFY**
5E4A
LD HL,000AH 21 0A 00
HL = offset 10 (buffer position)
5E4D
POP AF F1
Restore flags
5E4E
If no carry, use offset 10
5E50
LD HL,0007H 21 07 00
HL = offset 7 (chars remaining)

5E53H - Calculate Record Position (LOC/LOF Common)

Calculates record number based on byte position. Uses self-modifying code for record length.

5E53
ADD HL,BC 09
HL = FCB + offset
5E54
LD A,(HL) 7E
A = position or chars remaining
5E55
LD (5E70H),A 32 70 5E
Store to self-modify location **SELF-MODIFY**
5E58
LD A,(5E69H) 3A 69 5E
Get record length **SELF-MODIFIED**
5E5B
OR A B7
Check if zero
5E5C
If nonzero, calculate normally
5E5E
LD A,(5E70H) 3A 70 5E
Get position **SELF-MODIFIED**
5E61
OR A B7
Check if zero
5E62
If both zero, return 0
5E64
INC DE 13
Increment record number
5E65
Return result

5E67H - Divide by Record Length

LOC uses self-modifying code at 5E69H and 5E70H to store the record length and position for calculation. The routine multiplies the record number by record length and adds the position to get the total byte position, then returns this as a floating point number.

5E67
EX DE,HL EB
HL = last record number
5E68
LD A,00H 3E 00
A = record length **SELF-MODIFIED at 5E69H**
5E6A
DOS: Calculate sector (HL = HL * A)
5E6D
LD H,A 67
H = result high
5E6E
LD D,L 55
D = result low
5E6F
LD L,00H 2E 00
L = 0
5E70
LD A,00H 3E 00
A = position **SELF-MODIFIED at 5E70H**
5E72
Multiply by position
5E75
LD E,L 5D
E = result low byte
5E76
ADD A,D 82
Add carries
5E77
LD D,A 57
DE = total records

5E78H - Convert to Floating Point

5E78
EX DE,HL EB
HL = record number
5E79
Convert HL to floating point and return

5E7CH - LOF Function Handler

Returns length of file (total number of records). Syntax: LOF(filenumber)

LOF reuses most of LOC's code, but uses offset 14 (file length) instead of offset 12 (current record). Both functions share the calculation routine at 5E53H which handles the self-modifying record length division.

5E7C
Get file number and FCB
5E7F
If file not open, error
5E82
LD HL,000EH 21 0E 00
HL = offset 14 (file length low)
5E85
OR A B7
Clear carry
5E86
Jump to common calculation routine

5E88H - Character Output to File Entry (Stack Cleanup)

Prepares for character output to file by cleaning up stack.

5E88
POP HL E1
Get return address

5E89H - Character Output to File Routine *** CRITICAL ***

Core routine for writing characters to sequential files. Called by PRINT#, WRITE#, SAVE, and all output statements. Manages output buffer and writes to disk when full.

*** CRITICAL ROUTINE *** This is one of the most important routines in the entire file system. It is called by every file output operation. Understanding this routine is essential to understanding how file output works.

5E89
PUSH HL E5
Save HL (return address from stack)
5E8A
PUSH AF F5
Save character to write
5E8B
LD HL,(63BEH) 2A BE 63
HL = current FCB pointer
5E8E
LD A,(HL) 7E
A = file mode (FCB+0)
5E8F
CP 01H FE 01
Is it input mode (01H)?
5E91
If input mode, error (can't write)
5E94
POP AF F1
Restore character to write
5E95
PUSH DE D5
Save DE
5E96
PUSH BC C5
Save BC
5E97
INC HL 23
HL = FCB+1 (mode details)
5E98
LD B,00H 06 00
B = 0 (for 16-bit math)
5E9A
PUSH AF F5
Save character again
5E9B
LD D,(HL) 56
D = mode byte value
5E9C
CP 0DH FE 0D
Is character CR (carriage return)?
5E9E
LD (HL),B 70
Clear mode byte temporarily
5E9F
If CR, skip position update
5EA1
ADD E0H C6 E0
Add E0H (adjust position?)
5EA3
LD A,D 7A
A = mode byte
5EA4
ADC A,B 88
Add carry to mode byte
5EA5
LD (HL),A 77
Restore mode byte

5EA6H - Call DOS Write Routine

5EA6
INC HL 23
HL = FCB+2
5EA7
EX DE,HL EB
DE = FCB+2, HL = mode byte val
5EA8
POP AF F1
Restore character to write
5EA9
PUSH AF F5
Save it again
5EAA
PUSH DE D5
Save FCB+2
5EAB
ROM: Character output to file
5EAE
POP DE D1
Restore FCB+2
5EAF
If error (NZ), handle it [ERROR PATH]

5EB1H - Success Path - Restore and Return

5EB1
POP AF F1
Clean stack (character) [SUCCESS PATH]
5EB2
POP BC C1
Restore BC
5EB3
POP DE D1
Restore DE
5EB4
POP HL E1
Restore return address
5EB5
RET C9
Return to caller [SUCCESS]

5EB6H - Error Path - Check DOS Error Code

The character output routine at 5E89H is the bottleneck for all file output. It calls ROM routine at 001BH which manages the actual character buffering and disk writes. The mode byte at FCB+1 is temporarily cleared and restored - this may be for DOS compatibility. CR (0DH) is handled specially without updating the position counter.

5EB6
LD C,A 4F
C = error code from DOS [ERROR PATH]
5EB7
LD A,(DE) 1A
A = error status byte
5EB8
OR A B7
Check sign bit
5EB9
LD A,C 79
Restore error code
5EBA
If negative (M), translate DOS error
5EBD
Otherwise, treat as success

5EBFH - PUT Statement Handler

Writes a record to a random access file. Syntax: PUT #filenumber [, recordnumber]

5EBF
OR AFH F6 AF
Set flags (mark as PUT)
5EC1
LD (63BDH),A 32 BD 63
Store operation flag (write=FFH)
5EC4
XOR A AF
A = 0
5EC5
LD (5F01H),A 32 01 5F
Clear record increment flag **SELF-MODIFY**
5EC8
Parse file number
5ECB
CP 03H FE 03
Is file mode random (03H)?
5ECD
If not random, error
5ED0
PUSH BC C5
Save FCB pointer
5ED1
PUSH HL E5
Save parser position
5ED2
LD HL,000CH 21 0C 00
HL = offset 12 (record number)
5ED5
ADD HL,BC 09
HL = FCB+12
5ED6
LD E,(HL) 5E
E = current record low
5ED7
INC HL 23
HL = FCB+13
5ED8
LD D,(HL) 56
DE = current record number
5ED9
INC DE 13
DE = next record (default)
5EDA
POP HL E1
Restore parser position
5EDB
LD A,(HL) 7E
Get next character
5EDC
CP 2CH FE 2C
Is it comma?
5EDE
If comma, get explicit record#
5EE0
LD A,FFH 3E FF
A = FFH (auto-increment flag)
5EE2
LD (5F01H),A 32 01 5F
Set auto-increment **SELF-MODIFY**
5EE5
Continue with default record

5EE7H - GET/PUT with Explicit Record Number

5EE7
Get integer value (record number)

5EEAH - Validate Syntax and Record Number

5EEA
DEC HL 2B
Back up parser
5EEB
CHRGET: Get next char
5EEC
If not end, syntax error
5EEF
EX (SP),HL E3
HL = FCB, save parser on stack
5EF0
PUSH HL E5
Save FCB again
5EF1
LD A,E 7B
A = record low byte
5EF2
OR D B2
OR with high byte
5EF3
If record 0, error
5EF6
DEC DE 1B
DE = record - 1 (0-based)
5EF7
LD B,D 42
BC = record number - 1
5EF8
LD C,E 4B
BC = 0-based record
5EF9
EX DE,HL EB
HL = record - 1
5EFA
INC DE 13
DE = FCB + 1
5EFB
INC DE 13
DE = FCB + 2
5EFC
LD HL,0032H 21 32 00
HL = 50 (offset to buffer)
5EFF
ADD HL,DE 19
HL = FCB + 52 (buffer start)
5F00
LD A,00H 3E 00
A = auto-increment flag **SELF-MODIFIED at 5F01H**
5F02
OR A B7
Check auto-increment flag
5F03
If auto-increment, skip DOS position

5F05H - Position to Specific Record

5F05
PUSH HL E5
Save buffer address
5F06
DOS: Position to record in BC
5F09
POP HL E1
Restore buffer address
5F0A
If success (Z), continue
5F0C
CP 1CH FE 1C
Is error code 1CH?
5F0E
If 1CH, handle specially
5F10
CP 1DH FE 1D
Is error code 1DH?
5F12
If not 1CH or 1DH, DOS error

5F15H - Handle Record Not Found (Create New)

5F15
LD A,(63BDH) 3A BD 63
A = operation flag
5F18
OR A B7
Check if PUT (FFH) or GET (00H)
5F19
If GET (0), clear buffer and return
5F1B
DOS: Write new record
5F1E
If error, translate DOS error
5F21
POP AF F1
Clean stack
5F22
POP HL E1
Restore parser
5F23
RET C9
Return to caller

5F24H - Read or Write Record

5F24
LD A,(63BDH) 3A BD 63
A = operation flag
5F27
OR A B7
Check if write or read
5F28
If PUT (NZ), write record
5F2A
DOS: Read record (GET)
5F2D
If success (Z), finish
5F2F
LD B,A 47
B = error code
5F30
AND FEH E6 FE
Mask off low bit
5F32
CP 1CH FE 1C
Is it 1CH or 1DH?
5F34
LD A,B 78
Restore full error code
5F35
If other error, translate
5F38
LD A,(426EH) 3A 6E 42
A = verify flag
5F3B
OR A B7
Check if verify enabled
5F3C
LD A,B 78
Restore error code
5F3D
If verify on, report error
5F40
Else clear buffer and continue

5F42H - GET Success - Return

5F42
POP BC C1
Clean stack
5F43
POP HL E1
Restore parser
5F44
RET C9
Return to caller

5F45H - Clear Record Buffer

Clears the record buffer to zeros. Used when GET fails or for new records.

5F45
POP HL E1
HL = FCB pointer
5F46
LD DE,0034H 11 34 00
DE = 52 (offset to buffer)
5F49
ADD HL,DE 19
HL = buffer start
5F4A
LD B,00H 06 00
B = 256 (buffer size)
5F4C
XOR A AF
A = 0
5F4D
LD (HL),A 77
Clear byte [CLEAR LOOP START]
5F4E
INC HL 23
Next byte [CLEAR LOOP]
5F4F
Continue for 256 bytes [CLEAR LOOP END]
5F51
POP HL E1
Restore parser
5F52
RET C9
Return to caller

PUT/GET use self-modifying code at 5F01H to store the auto-increment flag. The operation flag at 63BDH distinguishes PUT (FFH) from GET (00H). The verify flag at 426EH controls whether read errors on non-existent records are reported or silently ignored by zeroing the buffer.

5F53H - Read Character from File *** CRITICAL ***

Core routine for reading characters from sequential files. Called by INPUT#, LINE INPUT#, LOAD, MERGE, and all input statements. Manages input buffer and reads from disk when exhausted.

*** CRITICAL ROUTINE *** This is the mirror of 5E89H for input operations. Every file read operation calls this routine. Understanding this is essential to understanding file input.

The character read routine at 5F53H calls ROM routine 0013H which manages the actual buffer and disk reads. Error codes 1CH and 1DH are treated as EOF conditions and return with carry set. The routine at 5F7BH may retry the read under certain conditions (Z flag set from ROM call).

5F53
PUSH BC C5
Save BC
5F54
PUSH HL E5
Save HL
5F55
LD HL,(63BEH) 2A BE 63
HL = current FCB pointer
5F58
PUSH DE D5
Save DE
5F59
EX DE,HL EB
DE = FCB pointer
5F5A
INC DE 13
DE = FCB + 1
5F5B
INC DE 13
DE = FCB + 2
5F5C
PUSH DE D5
Save FCB+2 address
5F5D
ROM: Read character from file
5F60
POP DE D1
Restore FCB+2 address
5F61
PUSH AF F5
Save character and flags
5F62
LD A,(DE) 1A
A = error status byte
5F63
OR A B7
Check sign bit
5F64
If positive (P), no error
5F67
POP AF F1
Restore character/flags [ERROR PATH]
5F68
If Z (EOF), set carry and return
5F6A
CP 1CH FE 1C
Is error code 1CH?
5F6C
If 1CH, set carry
5F6E
CP 1DH FE 1D
Is error code 1DH?
5F70
If not 1C/1D, translate DOS error

5F73H - Set EOF Flag and Return

5F73
SCF 37
Set carry flag (EOF/error)
5F74
LD B,B7H 06 B7
B = B7H (flag value)

5F75H - Restore and Return with Carry

5F75
POP DE D1
Restore DE
5F76
POP HL E1
Restore HL
5F77
POP BC C1
Restore BC
5F78
RET C9
Return (carry=EOF/error)

5F7AH - Success Path - Character Read OK

5F7A
POP AF F1
Restore character (carry clear)
5F7B
If Z set, retry read?
5F7D
Return with character (no carry)

5F7FH - Filename Parser *** IMPORTANT ***

Parses filename string, converts to uppercase, validates with DOS. Result stored at 6350H. Called by OPEN, LOAD, SAVE, KILL.

*** IMPORTANT ROUTINE *** Called by all file operations that need filenames.

5F7F
PUSH BC C5
Save BC
5F80
Evaluate string expression
5F83
PUSH HL E5
Save parser position
5F84
Get string descriptor
5F87
LD A,(HL) 7E
A = string length
5F88
OR A B7
Check if zero
5F89
If empty, error
5F8C
CP 18H FE 18
Is length >= 24?
5F8E
If >= 24, too long error
5F91
INC HL 23
Point to address low
5F92
LD C,(HL) 4E
C = address low
5F93
INC HL 23
Point to address high
5F94
LD B,(HL) 46
BC = source string address
5F95
LD HL,6350H 21 50 63
HL = filename buffer destination
5F98
LD E,A 5F
E = length (counter)

5F99H - Filename Copy and Uppercase Conversion Loop

5F99
LD A,(BC) 0A
Get char from source [LOOP START]
5F9A
CP 61H FE 61
Is it < 'a'? [LOOP]
5F9C
If < 'a', skip conversion
5F9E
CP 7BH FE 7B
Is it >= '{'?
5FA0
If >= '{', skip conversion
5FA2
XOR 20H EE 20
Convert lowercase to uppercase
5FA4
LD (HL),A 77
Store char to buffer
5FA5
INC HL 23
Next destination
5FA6
INC BC 03
Next source
5FA7
DEC E 1D
Decrement counter
5FA8
Continue until done [LOOP END]
5FAA
LD (HL),E 73
Null-terminate (E=0)
5FAB
POP HL E1
Restore parser
5FAC
POP DE D1
Restore DE
5FAD
LD B,D 42
BC = DE
5FAE
LD C,E 4B
Restore BC

5FAFH - Validate Filename with DOS

The filename parser converts lowercase (61H-7AH) to uppercase by XORing with 20H. Maximum filename is 23 characters (18H-1). Result stored at 6350H and validated through DOS call 441CH.

5FAF
PUSH BC C5
Save BC
5FB0
PUSH HL E5
Save HL
5FB1
LD HL,6350H 21 50 63
HL = filename buffer
5FB4
INC DE 13
DE = FCB + 3
5FB5
INC DE 13
DE = FCB + 4
5FB6
DOS: Parse/validate filename
5FB9
If error (NZ), bad filename
5FBC
OR A B7
Check return code
5FBD
If non-zero, bad filename
5FC0
POP HL E1
Restore parser
5FC1
POP BC C1
Restore BC
5FC2
RET C9
Return to caller [SUCCESS]

5FC3H - OPEN Statement Handler *** CRITICAL ***

Main entry for OPEN statement. Syntax: OPEN "mode", #filenumber, "filename" [, recordlength]

*** CRITICAL ROUTINE *** Heart of the file system. All file operations start here.

5FC3
LD BC,2169H 01 69 21
BC = return address
5FC6
PUSH BC C5
Push return address
5FC7
Evaluate mode expression
5FCA
PUSH HL E5
Save parser
5FCB
Get string descriptor
5FCE
LD A,(HL) 7E
A = mode string length
5FCF
OR A B7
Check if empty
5FD0
If empty, bad file mode error
5FD3
INC HL 23
Point to address
5FD4
LD C,(HL) 4E
C = address low
5FD5
INC HL 23
Point to address high
5FD6
LD B,(HL) 46
BC = mode string address
5FD7
LD A,(BC) 0A
Get first char of mode
5FD8
AND DFH E6 DF
Convert to uppercase
5FDA
LD D,02H 16 02
D = 02H (output mode)
5FDC
CP 4FH FE 4F
Is it 'O'?
5FDE
If 'O', use mode 02H
5FE0
LD D,01H 16 01
D = 01H (input mode)
5FE2
CP 49H FE 49
Is it 'I'?
5FE4
If 'I', use mode 01H
5FE6
LD D,04H 16 04
D = 04H (extend mode)
5FE8
CP 45H FE 45
Is it 'E'?
5FEA
If 'E', use mode 04H
5FEC
LD D,03H 16 03
D = 03H (random mode)
5FEE
CP 52H FE 52
Is it 'R'?
5FF0
If not I/O/E/R, error

5FF3H - Parse File Number and Filename

5FF3
POP HL E1
Restore parser
5FF4
SYNCHR: Verify comma
5FF5
DEFB 2CH 2C
Expected: comma
5FF6
PUSH DE D5
Save mode in D
5FF7
CP 23H FE 23
Is next char '#'?
5FF9
If '#', skip it
5FFC
Get file number in E
5FFF
SYNCHR: Verify comma
6000
DEFB 2CH 2C
Expected: comma
6001
LD A,E 7B
A = file number
6002
OR A B7
Check if zero
6003
If zero, out of range error
6006
CP D5H FE D5
Compare with D5H (unused?)

6007H - Common Entry Point (used by LOAD/RUN/MERGE)

NOP placeholder - may be modified at runtime

6007
NOP 00
(Entry marker - may be modified)

6008H - Get FCB and Parse Filename

6008
Get file# in A, FCB ptr in BC
600B
If file already open, error
600E
PUSH BC C5
Save FCB pointer
600F
Parse filename to 6350H
6012
LD B,00H 06 00
B = 0 (default record length)
6014
POP DE D1
DE = FCB pointer
6015
POP AF F1
A = file mode
6016
PUSH AF F5
Save mode again
6017
PUSH DE D5
Save FCB pointer
6018
CP 03H FE 03
Is mode random?
601A
If not random, skip rec len
601C
DEC HL 2B
Back up parser
601D
CHRGET: Get next
601E
If end, use default
6020
SYNCHR: Verify comma
6021
DEFB 2CH 2C
Expected: comma
6022
Get record length in E
6025
LD B,E 43
B = record length

6026H - Save State and Call DOS

6026
LD (40DFH),HL 22 DF 40
Save parser position
6029
POP HL E1
HL = FCB pointer
602A
LD A,(442BH) 3A 2B 44
A = DOS flags
602D
AND F9H E6 F9
Clear bits 1 and 2
602F
LD C,A 4F
C = modified flags
6030
LD A,(5200H) 3A 00 52
A = RUN/LOAD flag
6033
OR A B7
Check if set
6034
LD A,C 79
Restore flags
6035
If not RUN/LOAD, skip
6037
OR 04H F6 04
Set bit 2 (RUN/LOAD mode)
6039
LD (442BH),A 32 2B 44
Store modified DOS flags
603C
POP AF F1
A = file mode
603D
PUSH AF F5
Save mode again
603E
PUSH HL E5
Save FCB pointer
603F
LD (63BEH),HL 22 BE 63
Set current FCB pointer
6042
EX DE,HL EB
DE = FCB pointer
6043
INC DE 13
DE = FCB + 1
6044
INC DE 13
DE = FCB + 2
6045
LD HL,0032H 21 32 00
HL = 50 (buffer offset)
6048
ADD HL,DE 19
HL = buffer start address
6049
LD C,A 4F
C = file mode
604A
LD A,B 78
A = record length
604B
OR A B7
Check if zero
604C
If zero, use default
604E
LD A,(426EH) 3A 6E 42
A = verify flag
6051
OR A B7
Check if verify enabled
6052
If verify off with rec len, error
6055
INC H 24
Adjust buffer address (verify)

6056H - Call DOS Open Based on Mode

OPEN determines file mode from first character: I=input(01H), O=output(02H), R=random(03H), E=extend(04H). Extend mode converts to output after positioning to end. Mode byte stored at FCB+0. Parser position saved at 40DFH. RUN/LOAD flag at 5200H modifies DOS behavior for program loading.

6056
LD A,C 79
A = file mode
6057
CP 04H FE 04
Is it extend mode?
6059
If not extend, check others
605B
Save state
605E
If error, translate DOS error
6061
POP HL E1
Clean stack
6062
POP AF F1
Clean stack
6063
LD A,02H 3E 02
A = 02H (extend→output)
6065
PUSH AF F5
Save mode
6066
PUSH HL E5
Save HL
6067
DOS: Open random access
606A
Continue to finalize
606C
CP 01H FE 01
Is it input mode?
606E
If input, open for read
6070
CP 03H FE 03
Is it random mode?
6072
If not random, must be output
6074
Save state
6077
If success, finalize
6079
DOS: Open for output
607C
Continue to finalize
607E
DOS: Open for input
6081
PUSH AF F5
Save result
6082
LD A,(5200H) 3A 00 52
A = RUN/LOAD flag
6085
OR A B7
Check if RUN or LOAD
6086
If not RUN/LOAD, skip
6088
XOR A AF
A = 0
6089
LD (5200H),A 32 00 52
Clear RUN/LOAD flag
608C
LD A,(442BH) 3A 2B 44
A = DOS flags
608F
RRA 1F
Rotate right
6090
RRA 1F
Rotate right again
6091
SBC A,A 9F
A = FFH if carry, 00H otherwise
6092
LD (5201H),A 32 01 52
Store flag at 5201H
6095
POP AF F1
Restore DOS result
6096
If DOS error (NZ), translate
6099
POP HL E1
HL = FCB pointer
609A
POP AF F1
A = file mode
609B
LD (HL),A 77
Store mode at FCB+0
609C
INC HL 23
HL = FCB+1
609D
LD (HL),00H 36 00
Clear FCB+1
609F
LD HL,(40DFH) 2A DF 40
Restore parser position
60A2
RET C9
Return to caller [SUCCESS]

60A3H - File Cleanup Routine

Cleans up after file operations. Clears buffers and resets flags.

60A3
PUSH AF F5
Save AF
60A4
XOR A AF
A = 0
60A5
LD (5200H),A 32 00 52
Clear RUN/LOAD flag
60A8
LD A,(5201H) 3A 01 52
A = file buffer flag
60AB
OR A B7
Check if set
60AC
If not set, skip cleanup
60AE
LD HL,(40A4H) 2A A4 40
HL = string space start
60B1
LD BC,044CH 01 4C 04
BC = 1100 (clear size)
60B4
LD (HL),00H 36 00
Clear byte [CLEAR LOOP]
60B6
INC HL 23
Next byte
60B7
DEC BC 0B
Decrement counter
60B8
LD A,B 78
A = high byte
60B9
OR C B1
OR with low byte
60BA
Continue clearing [END LOOP]
60BC
LD (5201H),A 32 01 52
Clear flag (A=0)
60BF
Process program
60C2
LD HL,54D2H 21 D2 54
HL = address (table?)
60C5
Process table
60C8
Return to command level
60CB
POP AF F1
Restore AF
60CC
RET C9
Return to caller

60CDH - KILL Statement Handler (continued)

Deletes a file from disk. Syntax: KILL "filename"

KILL statement uses DOS call 442CH to delete the file. The filename is parsed through 5F7FH and stored at 6350H. The three NOPs at 60D0H-60D2H may be placeholders for future modification.

60CD
PUSH BC C5
Save BC
60CE
PUSH DE D5
Save DE
60CF
PUSH HL E5
Save HL
60D0
NOP 00
(Placeholder 1)
60D1
NOP 00
(Placeholder 2)
60D2
NOP 00
(Placeholder 3)
60D3
POP HL E1
Restore HL
60D4
POP DE D1
Restore DE
60D5
POP BC C1
Restore BC
60D6
XOR A AF
A = 0 (file # 0 = get ptr)
60D7
Get file info (Z if closed)
60DA
Parse filename to 6350H
60DD
PUSH HL E5
Save parser
60DE
LD HL,(63C0H) 2A C0 63
HL = file pointer table base
60E1
EX DE,HL EB
DE = table base
60E2
INC DE 13
DE = table + 1
60E3
INC DE 13
DE = table + 2
60E4
LD B,00H 06 00
B = 0
60E6
Save state
60E9
If error, translate DOS error
60EC
DOS: Delete file ($KILL)
60EF
If error, translate DOS error
60F2
LD HL,(63C0H) 2A C0 63
Get table base pointer
60F5
LD (HL),00H 36 00
Clear first byte
60F7
POP HL E1
Restore parser
60F8
RET C9
Return to caller [SUCCESS]

60F9H-6110H - Error Code Jump Table (DATA)

Error entry points. Each loads specific error code and jumps to error handler at 19A2H.

Error Code Jump Table:

60F9HLD E,6CHError 6CH - Bad File Mode
60FBHLD BC,681EHError 68H - unused?
60FEHLD BC,661EHFile Number Out of Range (error 66H)
6101HLD BC,7C1EHError 7CH
6104HLD BC,6E1EHError 6EH
6107HLD BC,801EHError 80H
610AHLD BC,7E1EHError 7EH
610DHLD BC,641EHError 64H
6110HJP 19A2HJump to error display routine

6113H - DOS Error Translation *** CRITICAL ***

Translates DOS error codes to BASIC error numbers using table at 6126H.

*** CRITICAL ROUTINE *** All DOS errors pass through here for translation to user-friendly BASIC errors.

6113
LD B,00H 06 00
B = 0 (for 16-bit math)
6115
LD HL,6126H 21 26 61
HL = error translation table
6118
CP 27H FE 27
Is DOS error >= 27H?
611A
If < 27H, use as index
611C
LD A,01H 3E 01
A = 01H (default for unknown)
611E
LD C,A 4F
BC = error index
611F
ADD HL,BC 09
HL = table + index
6120
LD E,(HL) 5E
E = BASIC error code
6121
LD (63BCH),A 32 BC 63
Save DOS error code
6124
Jump to error display

6126H-614CH - DOS to BASIC Error Code Lookup Table (DATA)

39-byte table mapping DOS errors (00H-26H) to BASIC error numbers.

The error translation table converts DOS-specific error codes into user-friendly BASIC error messages. Error 72H is the most common (general I/O error). Error 66H indicates bad file number. Errors 1CH-1FH (EOF conditions) all map to error 66H.

Error Translation Table (6126H-614CH) - 39 bytes:

IndexBytesBASIC Error
00-0672 72 72 72 72 72 72Error 72H (I/O error) - repeated
0780Error 80H (file error)
08-0E72 72 72 72 72 72Error 72H - repeated
0F88Error 88H (different I/O)
1066Error 66H (bad file number)
11-1272 72Error 72H
1380Error 80H
14-1872 72 72 72 6AError 72H, then 6AH
198AError 8AH (write error)
1A86Error 86H
1B7AError 7AH
1C-1F66 66 66 66Error 66H (repeated)
2080Error 80H
21-2466 66 66 66Error 66H (repeated)
258AError 8AH
2666Error 66H
27+xxDefaults to Index 01 - Error 72H

614DH - PROGRAM ENTRY POINT *** CRITICAL ***

Main initialization when BASIC/CMD loads. Saves state, sets up file system, displays copyright.

*** PROGRAM ENTRY POINT *** This is where execution starts when BASIC/CMD is loaded. Critical initialization code.

614D
LD (63EEH),HL 22 EE 63
Save HL (entry parameter)
6150
LD A,(HL) 7E
Get first byte
6151
LD (63E4H),A 32 E4 63
Save entry byte
6154
LD HL,(40A4H) 2A A4 40
HL = string space base
6157
LD (63E5H),HL 22 E5 63
Save string space pointer
615A
LD HL,(426DH) 2A 6D 42
HL = max file number
615D
LD (63E7H),HL 22 E7 63
Save max file number
6160
LD HL,(40A0H) 2A A0 40
HL = memory top (MEMSIZ)
6163
LD (63E9H),HL 22 E9 63
Save memory top
6166
XOR A AF
A = 0
6167
LD (427AH),A 32 7A 42
Clear SYSTEM flag
616A
LD HL,022EH 21 2E 02
HL = 022EH (offset?)
616D
LD (4204H),HL 22 04 42
Store at 4204H
6170
LD DE,4080H 11 80 40
DE = 4080H (destination)
6173
LD HL,18F7H 21 F7 18
HL = 18F7H (ROM source)
6176
LD BC,0027H 01 27 00
BC = 39 bytes to copy
6179
LDIR ED B0
Copy ROM data to RAM
617B
LD HL,(63E7H) 2A E7 63
Restore max file number
617E
LD (426DH),HL 22 6D 42
Store to 426DH
6181
LD HL,(4411H) 2A 11 44
HL = DOS memory top
6184
LD (40A0H),HL 22 A0 40
Set new memory top (MEMSIZ)
6187
LD SP,HL F9
Set stack pointer

6188H - Self-Modify Entry Point (First Run) **SELF-MODIFY**

6188
LD HL,614DH 21 4D 61
HL = entry point address
618B
LD (HL),3AH 36 3A
Modify: LD A,(nnnn) **SELF-MODIFY**
618D
INC HL 23
Next byte
618E
LD (HL),B 70
Store address low **SELF-MODIFY**
618F
INC HL 23
Next byte
6190
LD (HL),2CH 36 2C
Store comma **SELF-MODIFY**
6192
INC HL 23
Next byte
6193
LD (40A7H),HL 22 A7 40
Save to input buffer ptr
6196
LD HL,63EBH 21 EB 63
HL = 63EBH (flag location)
6199
LD (HL),00H 36 00
Clear initialization flag

619BH - Continue Initialization

619B
Clear all variables
619E
Initialize interpreter
61A1
XOR A AF
A = 0
61A2
LD (619EH),A 32 9E 61
Self-modify CALL **SELF-MODIFY**
61A5
LD (619FH),A 32 9F 61
Self-modify next byte **SELF-MODIFY**
61A8
LD (61A0H),A 32 A0 61
Self-modify third byte **SELF-MODIFY**
61AB
LD A,(441FH) 3A 1F 44
A = DOS version number
61AE
CP 13H FE 13
Is DOS >= 1.3?
61B0
If >= 1.3, continue

61B2H - DOS Version Too Old - Exit with Error

61B2
LD HL,6301H 21 01 63
HL = "Use TRSDOS 1.3 or Later"
61B5
Print string
61B8
SCF 37
Set carry (error flag)
61B9
Exit to SYSTEM (TRSDOS)

61BCH - Check for Re-entry ('*' Parameter)

61BC
LD A,(63E4H) 3A E4 63
A = entry parameter byte
61BF
CP 2AH FE 2A
Is it '*' (re-entry)?
61C1
If not '*', normal entry
61C4
LD A,(426DH) 3A 6D 42
A = current max file#
61C7
Allocate file buffers
61CA
LD BC,1A18H 01 18 1A
BC = return address
61CD
LD HL,(63E9H) 2A E9 63
HL = saved memory top
61D0
LD (40A0H),HL 22 A0 40
Restore memory top
61D3
LD HL,(63E5H) 2A E5 63
HL = saved string space
61D6
LD (40A4H),HL 22 A4 40
Restore string space
61D9
LD HL,(426FH) 2A 6F 42
HL = saved state
61DC
LD (5200H),HL 22 00 52
Restore state to 5200H
61DF
Return to BASIC

61E2H - Normal Entry Path

The entry point performs critical initialization. On first run (6188H-6199H), it self-modifies code at 614DH. The '*' parameter (2AH) triggers re-entry path at 61BCH which restores saved state. DOS version check at 61ABH requires TRSDOS 1.3 or later. The entry point copies 39 bytes from ROM (18F7H) to RAM (4080H) using LDIR.

61E2
PUSH AF F5
Save entry byte
61E3
LD A,(5202H) 3A 02 52
A = display flag
61E6
OR A B7
Check if set
61E7
If set, call display routine
61EA
POP AF F1
Restore entry byte
61EB
CP 20H FE 20
Is it space or higher?
61ED
If >= space, process command

61F0H - Prompt "How Many Files"

Prompts user for number of files (0-15) and optional verify mode.

61F0
LD HL,631AH 21 1A 63
HL = "How Many Files"
61F3
Print string
61F6
Get input line
61F9
If error, re-prompt
61FB
XOR A AF
A = 0
61FC
LD (426EH),A 32 6E 42
Clear verify flag
61FF
CHRGET: Get first char
6200
OR A B7
Check if zero (empty)
6201
LD A,03H 3E 03
A = 3 (default files)
6203
If empty, use default
6205
LD A,(HL) 7E
Get character
6206
Parse integer to DE
6209
CP 56H FE 56
Is it 'V'?
620B
If not 'V', skip
620D
LD (426EH),A 32 6E 42
Set verify flag (56H)
6210
CHRGET: Skip 'V'
6211
OR A B7
Check if end
6212
If not end, syntax error
6215
LD A,D 7A
A = high byte
6216
OR A B7
Check if > 255
6217
If > 255, re-prompt
6219
LD A,E 7B
A = file count
621A
CP 10H FE 10
Is it >= 16?
621C
If >= 16, re-prompt

621EH - Store File Count and Allocate

621E
LD (426DH),A 32 6D 42
Store max file number
6221
PUSH AF F5
Save file count
6222
PUSH BC C5
Save BC
6223
PUSH DE D5
Save DE
6224
PUSH HL E5
Save HL
6225
LD L,A 6F
L = file count
6226
LD H,00H 26 00
HL = file count
6228
Multiply by buffer size
622B
LD DE,0004H 11 04 00
DE = 4
622E
ADD HL,DE 19
HL = total + 4
622F
LD DE,63A2H 11 A2 63
DE = 63A2H
6232
LD BC,0002H 01 02 00
BC = 2
6235
LDIR ED B0
Copy 2 bytes
6237
POP HL E1
Restore HL
6238
POP DE D1
Restore DE
6239
POP BC C1
Restore BC
623A
POP AF F1
Restore file count

623BH - Allocate File Buffer Array *** IMPORTANT ***

Creates file pointer table at 63C0H, allocates FCB+buffer space starting at 64DCH.

*** IMPORTANT ROUTINE *** Sets up the entire file buffer structure. Each file gets 360 bytes (168H).

623B
INC A 3C
A = file count + 1
623C
LD HL,64DCH 21 DC 64
HL = buffer area base
623F
LD DE,63C0H 11 C0 63
DE = file pointer table
6242
LD (63E0H),HL 22 E0 63
Save buffer end pointer
6245
LD (HL),00H 36 00
Clear FCB status [ALLOC LOOP]
6247
EX DE,HL EB
HL = table, DE = buffer
6248
LD (HL),E 73
Store buffer ptr low
6249
INC HL 23
Next table byte
624A
LD (HL),D 72
Store buffer ptr high
624B
INC HL 23
Next table entry
624C
EX DE,HL EB
HL = buffer, DE = table
624D
LD BC,0168H 01 68 01
BC = 360 bytes per file
6250
ADD HL,BC 09
HL = next buffer location
6251
LD B,A 47
B = counter
6252
LD A,(426EH) 3A 6E 42
A = verify flag
6255
OR A B7
Check if verify enabled
6256
If not verify, skip
6258
INC H 24
Add 256 for verify buffer
6259
LD A,B 78
Restore counter
625A
DEC A 3D
Decrement counter
625B
Continue for all files [END LOOP]
625D
LD A,(63E4H) 3A E4 63
A = entry parameter
6260
CP 2AH FE 2A
Is it '*' (re-entry)?
6262
RET Z C8
If re-entry, return
6263
LD (HL),00H 36 00
Null-terminate table
6265
INC HL 23
HL = string space base
6266
LD (40A4H),HL 22 A4 40
Set string space pointer

6269H - Prompt for Memory Size

Prompts "Memory Size?" and allocates memory for BASIC.

6269
LD HL,0105H 21 05 01
HL = 0105H (data offset?)
626C
Print "Memory Size?"
626F
Get input line
6272
If error, re-prompt
6274
CHRGET: Get char
6275
OR A B7
Check if empty
6276
If not empty, parse value
6278
LD HL,(4411H) 2A 11 44
HL = DOS memory top
627B
LD DE,FFFAH 11 FA FF
DE = -6
627E
Compare/subtract
627F
If carry, use DE
6281
EX DE,HL EB
HL = DOS top - 6
6282
Set memory size
6285
Continue
6287
Parse integer to DE
628A
OR A B7
Check if end
628B
If not end, syntax error
628E
Validate and set size

6291H - Display Copyright and Return to BASIC

6291
Display copyright banner
6294
Return to command level

6297H - Validate Memory Size

6297
DEC DE 1B
DE = size - 1
6298
LD HL,(4411H) 2A 11 44
HL = DOS memory top
629B
Compare
629C
EX DE,HL EB
HL = requested size
629D
If too large, re-prompt

629FH - Set Memory Size and Allocate

629F
POP IX DD E1
IX = return address
62A1
DEC HL 2B
HL = size - 1
62A2
EX DE,HL EB
DE = size
62A3
LD HL,(40A4H) 2A A4 40
HL = string space base
62A6
LD BC,012CH 01 2C 01
BC = 300 (minimum space)
62A9
ADD HL,BC 09
HL = base + 300
62AA
EX DE,HL EB
HL = size, DE = min
62AB
Compare
62AC
If < min, "Out of Memory"
62AF
LD DE,FFCEH 11 CE FF
DE = -50
62B2
LD (40B1H),HL 22 B1 40
Save actual top
62B5
ADD HL,DE 19
HL = top - 50
62B6
LD (40A0H),HL 22 A0 40
Set MEMSIZ (memory top)
62B9
Process program
62BC
LD HL,0000H 21 00 00
HL = 0
62BF
Convert to string
62C2
Process string
62C5
PUSH HL E5
Save HL
62C6
LD DE,0005H 11 05 00
DE = 5
62C9
ADD HL,DE 19
HL = string + 5
62CA
LD A,(HL) 7E
Get digit
62CB
SUB 06H D6 06
Subtract 6
62CD
CP 30H FE 30
Is it >= '0'?
62CF
If >= '0', OK
62D1
DEC HL 2B
Back up
62D2
DEC (HL) 35
Decrement previous digit
62D3
INC HL 23
Forward
62D4
ADD 0AH C6 0A
Add 10
62D6
LD (HL),A 77
Store digit
62D7
POP HL E1
Restore HL
62D8
LD DE,638FH 11 8F 63
DE = display buffer
62DB
LD BC,0006H 01 06 00
BC = 6 bytes
62DE
LDIR ED B0
Copy to buffer
62E0
Process program
62E3
JP (IX) DD E9
Return via IX

62E5H - Display Copyright Banner **SELF-MODIFY**

Displays TRS-80 Model III Disk BASIC copyright. Self-modifies to run only once.

The copyright display routine uses self-modifying code. On first run, 62E6H contains 3EH (LD A,01H). After running once, it modifies itself to 3EH 00H (LD A,00H), so subsequent calls return immediately at 62EBH.

62E5
LD A,01H 3E 01
A = 1 (first run flag)
62E7
DEC A 3D
A = 0 **SELF-MODIFIED**
62E8
LD (62E6H),A 32 E6 62
Modify LD A,01H → LD A,00H
62EB
RET NZ C0
If not first run, return
62EC
LD HL,6329H 21 29 63
HL = copyright string
62EF
Print copyright
62F2
LD HL,63A6H 21 A6 63
HL = "Memory" string
62F5
LD A,(426EH) 3A 6E 42
A = verify flag
62F8
OR A B7
Check if verify enabled
62F9
If verify, skip
62FB
LD HL,63AFH 21 AF 63
HL = alt string
62FE
Print and return

6301H - String Data and System Variables

Text strings, buffers, and system variables used by BASIC/CMD.

6301H - Error Message: "Use TRSDOS 1.3 or Later"

6301
DEFM "Use TRSDOS 1.3 or Later" 55 73 65...
Version error message
6318
DEFB 0DH 0D
CR (carriage return)
6319
DEFB 00H 00
Null terminator

631AH - Prompt: "How Many Files"

631A
DEFM "How Many Files" 48 6F 77...
File count prompt
6328
DEFB 00H 00
Null terminator

6329H - Copyright Banner

6329
DEFM "TRS-80 Model III Disk BASIC Rev 1.3" 54 52 53...
Product name and version
634C
DEFB 0DH 0D
CR (carriage return)
634D
DEFM "(c) (p) 1980 by Tandy Corp. All Rights Reserved." 28 63 29...
Copyright notice
637C
DEFB 0DH 0D
CR (carriage return)
637D
DEFM "Created 5-Jul-80" 43 72 65...
Creation date
638E
DEFB 0DH 0D
CR (carriage return)

638FH - Memory Size Display Buffer

The memory display buffer at 638FH is a template. Actual memory size digits are filled in at runtime at positions 638FH-6394H before display.

638F
DEFM "00,000 Free Bytes 00 " 30 30 2C...
Memory display template (15 bytes)
63A4
DEFB 00H 00
Null terminator

63A6H - Verify Mode Message: "Variable Files"

Alternate message displayed when verify mode is disabled would be at a different location (not shown in verify path).

63A6
DEFM "Variable Files" 56 61 72...
Verify mode enabled message
63B4
DEFB 0DH 0D
CR (carriage return)
63B5
DEFB 00H 00
Null terminator

63B6H - System Variables and Buffers

Runtime variables used by file system and initialization code.

63B6
DEFW 0000H 00 00
Record Length Storage (2 bytes)
63B8
DEFB 00H,00H,00H,00H 00 00 00 00
Reserved/padding (4 bytes)
63BC
DEFB 00H 00
Last DOS error code
63BD
DEFB 00H 00
PUT/GET flag (FFH=write, 00H=read)
63BE
DEFW 0000H 00 00
Current File Control Block pointer

63C0H - File Pointer Table (32 bytes)

The file pointer table at 63C0H stores pointers to FCB+buffer structures for up to 16 files (0-15). Each entry is 2 bytes. File #0 is reserved. Actual number of entries used is determined by "How Many Files" prompt response.

63C0
DEFW 0000H 00 00
File #0 buffer pointer
63C2
DEFW 0000H 00 00
File #1 buffer pointer
63C4
DEFW 0000H 00 00
File #2 buffer pointer
63C6
DEFW 0000H 00 00
File #3 buffer pointer
63C8
DEFW 0000H 00 00
File #4 buffer pointer
63CA
DEFW 0000H 00 00
File #5 buffer pointer
63CC
DEFW 0000H 00 00
File #6 buffer pointer
63CE
DEFW 0000H 00 00
File #7 buffer pointer
63D0
DEFW 0000H 00 00
File #8 buffer pointer
63D2
DEFW 0000H 00 00
File #9 buffer pointer
63D4
DEFW 0000H 00 00
File #10 buffer pointer
63D6
DEFW 0000H 00 00
File #11 buffer pointer
63D8
DEFW 0000H 00 00
File #12 buffer pointer
63DA
DEFW 0000H 00 00
File #13 buffer pointer
63DC
DEFW 0000H 00 00
File #14 buffer pointer
63DE
DEFW 0000H 00 00
File #15 buffer pointer

63E0H - Last Allocated Buffer End

63E0
DEFW 0000H 00 00
End address of last allocated buffer
63E2
DEFB 00H,00H 00 00
Reserved/padding (2 bytes)

63E4H - Entry Parameter Byte

63E4
DEFB 00H 00
Entry parameter (2AH='*' for re-entry)

63E5H - Saved String Space Pointer

63E5
DEFW 0000H 00 00
Saved string space base pointer

63E7H - Saved Max File Number

63E7
DEFW 0000H 00 00
Saved maximum file number (0-15)

63E9H - Saved Memory Top

63E9
DEFW 0000H 00 00
Saved memory top (MEMSIZ)

63EBH - Initialization Flag

63EB
DEFB 00H 00
Initialization complete flag

63ECH - Command Line Flags

63EC
DEFB 00H 00
File count specified flag (-F)
63ED
DEFB 00H 00
Memory size specified flag (-M)

63EEH - Saved Entry HL Register

63EE
DEFW 0000H 00 00
Saved HL from entry point

63F0H - Temporary Filename Buffer (16 bytes)

63F0
DEFB 00H,00H,00H,00H 00 00 00 00
Temp buffer bytes 0-3
63F4
DEFB 00H,00H,00H,00H 00 00 00 00
Temp buffer bytes 4-7
63F8
DEFB 00H,00H,00H,00H 00 00 00 00
Temp buffer bytes 8-11
63FC
DEFB 00H,00H,00H,00H 00 00 00 00
Temp buffer bytes 12-15

The temporary buffer at 63F0H (16 bytes) is used during command line processing to build quoted filenames from command parameters before execution.

6400H - Reserved Area (9 bytes)

6400
DEFB 00H,00H,00H,00H 00 00 00 00
Reserved bytes 0-3
6404
DEFB 00H,00H,00H,00H 00 00 00 00
Reserved bytes 4-7
6408
DEFB 00H 00
Reserved byte 8

6409H - Command Line Processing

Processes command line parameters passed to BASIC/CMD.

6409
LD HL,64DCH 21 DC 64
HL = buffer base
640C
LD (40A4H),HL 22 A4 40
Set string space
640F
LD HL,(63EEH) 2A EE 63
HL = entry parameter
6412
DEC HL 2B
Back up [PARSE LOOP]
6413
CHRGET: Get char
6414
CP 20H FE 20
Is it space?
6416
If < space, end of params
6419
CP 5BH FE 5B
Is it >= '['?
641B
If >= '[', end of params
641E
CP 2DH FE 2D
Is it '-' (option)?
6420
If '-', process option
6422
EX DE,HL EB
DE = source
6423
LD HL,63F0H 21 F0 63
HL = temp buffer
6426
LD (HL),22H 36 22
Store quote
6428
INC HL 23
Next byte
6429
LD A,(DE) 1A
Get char [COPY LOOP]
642A
CP 21H FE 21
Is it < '!'?
642C
If < '!', end of filename
642E
LD (HL),A 77
Copy char
642F
INC HL 23
Next dest
6430
INC DE 13
Next source
6431
Continue copy [END LOOP]
6433
LD (HL),00H 36 00
Null-terminate
6435
EX DE,HL EB
HL = source position
6436
Continue parsing

6438H - Process Option Flags (-M or -F)

6438
CHRGET: Get option char
6439
CP 4DH FE 4D
Is it 'M' (memory)?
643B
PUSH AF F5
Save flag
643C
If 'M', continue
643E
CP 46H FE 46
Is it 'F' (files)?
6440
If not M or F, syntax error
6443
CHRGET: Skip option char
6444
SYNCHR: Verify '='
6445
DEFB 3DH 3D
Expected: '='
6446
Get value???
6449
INC SP 33
Adjust stack
644A
LD (63ECH),A 32 EC 63
Store flag at 63ECH
644D
XOR A AF
A = 0
644E
LD (426EH),A 32 6E 42
Clear verify flag
6450
LD A,(HL) 7E
Get next char
6451
Parse integer to DE
6454
CP 56H FE 56
Is it 'V' (verify)?
6456
If not 'V', skip
6458
LD (426EH),A 32 6E 42
Set verify flag (56H)
645B
INC HL 23
Skip 'V'
645C
LD A,D 7A
A = high byte
645D
OR A B7
Check if > 255
645E
If > 255, re-prompt
6461
LD A,E 7B
A = value
6462
CP 10H FE 10
Is it >= 16?
6464
If >= 16, re-prompt
6467
PUSH AF F5
Save value
6468
LD A,2AH 3E 2A
A = '*' (re-entry marker)
646A
LD (63E4H),A 32 E4 63
Set re-entry flag
646D
POP AF F1
Restore value
646E
PUSH HL E5
Save HL
646F
Allocate files
6472
LD (HL),00H 36 00
Null-terminate
6474
INC HL 23
Next byte
6475
LD (40A4H),HL 22 A4 40
Set string space
6478
POP HL E1
Restore HL
6479
Continue parsing

647CH - Process Memory Option (-M)

647C
LD (63EDH),A 32 ED 63
Store flag at 63EDH
647F
Parse memory size to DE
6482
OR A B7
Check if end
6483
If end, syntax error
6486
PUSH HL E5
Save HL
6487
POP IY FD E1
IY = saved HL
6489
LD HL,C9AFH 21 AF C9
HL = XOR A / RET
648C
LD (5CE9H),HL 22 E9 5C
Patch routine
648F
Validate memory size
6492
LD HL,C5D5H 21 D5 C5
HL = PUSH DE / PUSH BC
6495
LD (5CE9H),HL 22 E9 5C
Restore routine
6498
PUSH IY FD E5
Push IY
649A
POP HL E1
HL = IY
649B
Continue parsing

649EH - Finalize Command Line Processing

649E
LD A,(63ECH) 3A EC 63
A = file count flag
64A1
OR A B7
Check if set
64A2
If set, skip default
64A4
LD A,2AH 3E 2A
A = '*'
64A6
LD (63E4H),A 32 E4 63
Set re-entry flag
64A9
LD A,03H 3E 03
A = 3 (default files)
64AB
Allocate files
64AE
LD (HL),00H 36 00
Null-terminate
64B0
INC HL 23
Next byte
64B1
LD (40A4H),HL 22 A4 40
Set string space
64B4
LD A,(63EDH) 3A ED 63
A = memory flag
64B7
OR A B7
Check if set
64B8
If set, skip default
64BA
LD HL,(4411H) 2A 11 44
HL = DOS memory top
64BD
LD DE,FFFAH 11 FA FF
DE = -6
64C0
Compare
64C1
If carry, use DE
64C3
EX DE,HL EB
Use default
64C4
Set memory size
64C7
LD HL,63F0H 21 F0 63
HL = temp buffer
64CA
LD A,(HL) 7E
Get first char
64CB
OR A B7
Check if empty
64CC
If empty, finish
64CF
Display copyright
64D2
LD HL,1A19H 21 19 1A
HL = return address
64D5
PUSH HL E5
Push return
64D6
LD HL,63F0H 21 F0 63
HL = filename buffer
64D9
Execute RUN command

64DCH - File Buffer Area (END OF CODE)

Dynamic file buffer area. Each file allocated gets 360 bytes (168H).

File Buffer Structure:

Base Address: 64DCH

Size per file: 360 bytes (168H) in normal mode, 616 bytes (268H) in verify mode (adds 256-byte verify buffer)

Maximum allocation: 16 files × 360 bytes = 5,760 bytes. Actual allocation determined by "How Many Files" prompt (0-15)

Buffer Layout per file:

Offset 00H-31H: FCB (File Control Block) - 50 bytes

Offset 32H-131H: Record buffer - 256 bytes

Offset 132H-167H: Additional workspace - 54 bytes

File pointer table at 63C0H contains 2-byte pointers to each FCB.

Table is null-terminated when buffer list ends.