5200H - Module Entry Point
This is the entry point for SYS19. It immediately returns, suggesting this module is called through specific entry points rather than from 5200H directly. The actual command processing begins at 5202H.
5200
CP A BF
Compare Register A with itself. This always sets the Z FLAG (A always equals A). This appears to be a NOP-equivalent placeholder.
5201
RET C9
RETURN to caller. This entry point does nothing - actual functionality starts at other addresses.
5202H - Command Dispatcher - Parse CMD Letter
This is the main entry point for file operation commands. It identifies whether the command is LOAD, RUN, MERGE, SAVE, or DELETE by examining the command letter after "CMD". The routine sets up flags and parameters based on the command type.
5202
LD BC,18C8H 01 C8 18
Load Register BC with 18C8H. B=18H (24 decimal) may be a count or flag; C=C8H (RET Z instruction) used for conditional execution control.
5205
POP DE D1
Pop Register DE from the stack to retrieve return address or parameter passed by the calling routine.
5206
CALL subroutine at 638FH to get next character from BASIC command line and convert to uppercase. Returns character in Register A.
5209
If the Z FLAG is set (no character or end of command), JUMP to 521AH to handle LOAD command (default when no letter specified).
[IDENTIFY COMMAND TYPE]
Check the command letter: 'R' for RUN, 'V' for saVe, anything else defaults to LOAD/MERGE.
520B
CP 52H FE 52
Compare Register A with 52H ('R' character). If A equals 52H, the Z FLAG is set (RUN command); otherwise the NZ FLAG is set.
520D
If the Z FLAG is set (letter is 'R'), JUMP to 5215H to set up RUN command parameters.
520F
CP 56H FE 56
Compare Register A with 56H ('V' character). If A equals 56H, the Z FLAG is set (SAVE command); otherwise the NZ FLAG is set.
5211
If the NZ FLAG is set (not 'V' - defaults to LOAD/MERGE), JUMP to 521AH.
[SAVE COMMAND - 'V']
User specified CMD"V" for SAVE. Set up SAVE-specific parameters.
5213
LD B,3EH 06 3E
Load Register B with 3EH (LD A,n instruction opcode). This will be used to modify code for SAVE operation.
[RUN COMMAND - 'R']
User specified CMD"R" for RUN. Set execution flag.
5215
LD C,C9H 0E C9
Load Register C with C9H (RET instruction). This will be stored at 5FCFH to enable immediate execution after loading.
5217
LD D,01H 16 01
Load Register D with 01H. This flag indicates RUN mode (vs. LOAD mode = 00H).
5219
INC HL 23
Increment Register HL to point to the next character in the command string (should be filename quote or space).
[LOAD/MERGE/DELETE COMMAND]
Default path for CMD"L", CMD"M", CMD"D" or just CMD with no letter.
521A
DEC HL 2B
Decrement Register HL to point back to the current position, compensating for the INC HL at 5219H if we jumped here.
521B
Call RST 10H (ROM routine at 0010H) to get next character from command line. Returns character in Register A with CARRY FLAG set if numeric digit.
521C
If the NZ FLAG is set (character found after command letter), JUMP to ROM routine at 1997H for syntax error - should have quote or end of statement here.
[STORE COMMAND FLAGS]
Save the identified command parameters into memory locations for later use.
521F
LD A,D 7A
Load Register A with Register D (command type flag: 00H=LOAD, 01H=RUN).
5220
LD (5315H),A 32 15 53
Store the command type flag at memory location 5315H for later reference during file operations.
5223
LD A,C 79
Load Register A with Register C (execution flag: C8H=CALL Z for conditional, C9H=RET for immediate execution).
5224
LD (5FCFH),A 32 CF 5F
Store the execution control byte at memory location 5FCFH. This location is later executed as code - C9H causes immediate return (RUN), C8H allows conditional execution (LOAD).
5227
LD A,B 78
Load Register A with Register B (instruction opcode: 18H=JR or 3EH=LD A,n depending on SAVE vs LOAD).
5228
LD (5255H),A 32 55 52
Store the operation code at memory location 5255H, modifying the instruction at that address for SAVE vs LOAD behavior.
522BH - Parse Modifier Flags and Update System Configuration
The code now examines the File Control Block (FCB) to determine the file type and applies different patch behavior based on whether this is a disk file or a device (like the printer). IX points to the FCB for the opened file, and IX+0EH contains the device code field.
522B
LD A,(IX+0EH) DD 7E 0E
Load the device code byte from the FCB into register A. This byte indicates what type of device or file this is (disk file, printer, screen, etc.).
522E
AND 07HAND 00000111 E6 07
Mask off the upper bits to isolate the device type field (bits 0-2), which identifies the specific device number.
5230
CP 06H FE 06
Compare with 06H (device 6, which is the printer device).
5232
If the device code is 6 or higher (printer or above), jump ahead to 5240H to handle device files differently. Otherwise, continue to handle disk files.
[DISK FILE PATH] - For regular disk files, we check if the "R" (Read-only) modifier was specified. The DOS override flag at 436CH controls whether read-only protection is enforced.
5234
LD A,(436CH) 3A 6C 43
Load the DOS override control byte from system memory at 436CH. Bit 6 of this byte indicates whether DOS-level overrides are enabled (allowing writes to read-only files).
5237
BIT 6,A CB 77
Test bit 6 to see if DOS override mode is active. When set, this allows the system to bypass read-only protection.
5239
If DOS override is enabled (bit 6 set), jump to 5255H to skip installing the read-only protection patch. The file will be writable even if marked read-only.
DOS override is NOT active, so if the user specified the "R" modifier, we need to install a patch that blocks write operations. We'll set up a RET (C9H) instruction to immediately return from write operations.
523B
LD B,C9H 06 C9
Load register B with C9H, the Z80 opcode for RET (return). This will be used to create a patch that blocks writes.
523D
XOR A AF
Clear register A to 00H. This will be stored in the modifier flag to indicate no special modifier was used.
523E
Jump ahead to 524EH to install the read-only protection patch in the ROM hooks.
[DEVICE FILE PATH] - For device files (printer, screen, etc.), different handling is needed.
5240
If the device code from earlier comparison was NOT exactly 6 (i.e., device 7 or higher), skip patch installation at 5255H. Only device 6 (printer) needs special handling.
This is specifically the printer device (device 6). Check if the "V" (Verify) modifier was specified, which was stored earlier at 5315H.
5242
LD A,(5315H) 3A 15 53
Retrieve the modifier flag byte from 5315H that was set earlier based on user input (00H=none, 01H=R modifier, 02H=V modifier).
5245
OR A B7
Test if the flag is zero (no modifier specified).
5246
If no modifier was specified, skip patch installation and jump to 5255H.
A modifier WAS specified on the printer device. For the printer, the "V" modifier requests character echo verification. We need to adjust the device code in the FCB to enable bi-directional printer mode, then install a JP (Jump) patch instead of RET.
5248
DEC (IX+0EH) DD 35 0E
Decrement the device code in the FCB from 6 to 5, changing the printer from output-only mode to a bi-directional printer device that can receive echo/status characters.
524B
LD B,C3H 06 C3
Load register B with C3H, the Z80 opcode for JP (jump). This will create a patch that redirects to a verification routine rather than blocking the operation entirely.
524D
LD A,C 79
Copy register C (which contains the return address byte C9H from earlier setup) into A. This value will be used as the second modifier flag indicator.
Now install the patch bytes into the ROM hook locations. The code at 6421H and 4312H are RAM locations that shadow ROM routines - they'll be patched with either RET (to block operation) or JP (to redirect to new code).
524E
LD (6421H),A 32 21 64
Store the second patch byte (either 00H for disk files or C9H for device) at memory location 6421H. This becomes part of a patched ROM routine.
5251
LD A,B 78
Load register A with the opcode byte from B (either C9H=RET for read-only files, or C3H=JP for verify mode).
5252
LD (4312H),A 32 12 43
Store the first patch byte at memory location 4312H, completing the patch installation. For read-only files, this creates a RET that prevents writes. For verify mode, this creates a JP to verification code.
5255H - Continue Initialization Based on File Type
All modifier-based patches have been installed (or skipped if not needed). Now determine whether to follow the "Open Existing File" path or the "Create New File" path. The zero flag was set earlier based on whether an existing file was found.
5255
If the zero flag is set (meaning the file does NOT exist or is being created), jump ahead to 526BH for the "Create New File" initialization path.
[OPEN EXISTING FILE PATH] - An existing file was found. Need to set up the file pointers and read the file header to initialize the buffer structure.
5257
Call DOS routine at 1DF8H to perform file positioning or buffer setup for reading the existing file's directory entry and data.
525A
LD DE,(40A4H) ED 5B A4 40
Load DE with the current buffer address from system pointer 40A4H. This points to where the assembled file data begins in memory.
525E
LD HL,(40F9H) 2A F9 40
Load HL with the program pointer from 40F9H. This typically points to the end of the current program area or the next available memory location.
5261
DEC HL 2B
Decrement HL by one byte.
5262
DEC HL 2B
Decrement HL again. These two decrements adjust the pointer back by 2 bytes to account for some header or pointer structure in the file buffer.
5263
Call the file reading subroutine at 54C8H. This likely reads data from the disk file into the buffer area between DE and HL.
5266
Call another file processing routine at 54DFH, probably to finalize the buffer setup or update system pointers after reading.
5269
Jump ahead to 5271H to continue with common initialization code after file opening.
[CREATE NEW FILE PATH] - No existing file was found, so we're creating a new file. Need to initialize an empty buffer structure.
526B
Call DOS routine at 63B9H to allocate or initialize buffer space for the new file.
526E
Call initialization routine at 1B4DH, likely to set up default values in the new file buffer or FCB structures.
5271H - Final File Initialization and Begin Statement Processing
[COMMON PATH] - Both "open existing file" and "create new file" paths merge here. Now perform final initialization steps before beginning to process the BASIC statements to be assembled into the file.
5271
Call DOS routine at 63ADH to perform additional file setup or buffer management.
5274
LD HL,4369H 21 69 43
Load HL with the address 4369H, which points to a system control flags byte.
5277
SET 6,(HL) CB F6
Set bit 6 of the control byte at 4369H. This flag likely indicates that "program input mode" or "file assembly mode" is now active, changing how BASIC interprets incoming lines.
Now set up for reading BASIC program lines. The system will read from the console (or input stream) and parse statements to be added to the file buffer. The pointer at 644EH will be set to point to the statement parsing routine.
5279
LD DE,570DH 11 0D 57
Load DE with the address 570DH, which likely points to a statement parsing routine or processing function.
527C
Call the routine at 4436H, probably to store DE as a function pointer at 644EH or to initialize the statement processing mechanism. This sets up the parser that will be called for each new statement line.
After setting up the parser, get the first input line from the user. The routine at 4436H returns with status in flags and possibly a character in A.
527F
If the zero flag is set (indicating successful initialization or empty input), jump ahead to 5289H to begin normal statement processing.
5281
CP 1CH FE 1C
Compare the character in A with 1CH (ASCII 28, which might be a special control character or end-of-file marker).
5283
If the character is not 1CH, jump to 5E16H to handle an error condition or unexpected input.
5286
If the character WAS 1CH, jump to 5314H to handle end-of-file or completion of statement input.
5289H - Statement Processing Main Loop
This is the core loop that reads BASIC statement lines, parses them, and adds them to the file buffer. Each iteration processes one statement or line number.
5289
Call the routine at 5495H to parse the current statement line. This likely tokenizes the BASIC statement and returns information about its length in BC and/or HL.
528C
PUSH HL E5
Save the HL register on the stack. HL probably contains the address where the parsed statement begins or some related pointer.
528D
ADD HL,BC 09
Add BC to HL. BC likely contains the length of the parsed statement, so this calculates the address of the end of the statement.
528E
LD B,H 44
Copy H into B.
528F
LD C,L 4D
Copy L into C. Now BC contains the end address of the statement.
Calculate how much space remains in the buffer by comparing the buffer start address (40A4H) with the end of this statement.
5290
LD HL,(40A4H) 2A A4 40
Load HL with the buffer start address from system pointer 40A4H.
5293
EX DE,HL EB
Exchange DE and HL. Now DE has the buffer start address, and HL can be used for calculation.
5294
OR A B7
Clear the carry flag before subtraction.
5295
SBC HL,DE ED 52
Subtract DE from HL (HL = HL - DE). This calculates the current buffer usage (how many bytes are already in the buffer).
5297
PUSH HL E5
Save the buffer usage count on the stack.
5298
ADD HL,BC 09
Add BC (the statement end address) to HL (the current usage). This calculates the total buffer space needed after adding this statement.
5299
LD B,H 44
Copy H into B.
529A
LD C,L 4D
Copy L into C. Now BC contains the total space needed.
Check if there's enough stack space remaining. The code compares the stack pointer with a safety margin.
529B
LD HL,FF60H 21 60 FF
Load HL with FF60H (-160 decimal). This is a negative offset that will be used to check for minimum stack space.
529E
ADD HL,SP 39
Add the current stack pointer to HL. This calculates SP - 160, creating a minimum safe stack boundary address.
529F
EX DE,HL EB
Exchange DE and HL. Now DE contains the safe stack boundary, and HL has the buffer address again.
52A0
LD HL,(40FDH) 2A FD 40
Load HL with the string space pointer from 40FDH. This points to the top of the string storage area.
52A3
INC H 24
Increment the high byte of HL by 1, adding 256 bytes to the address. This provides a safety margin in the comparison.
52A4
RST 18H DF
Call ROM routine via RST 18H (restart vector 3). This typically performs a comparison between HL and DE, setting flags based on which is larger. It's checking if there's enough memory space between the stack and string area.
52A5
If no carry (meaning insufficient memory space), jump to 54C5H to handle the "Out of Memory" error condition.
There's enough memory to continue. Now prepare to move the existing buffer contents to make room for the new statement.
52A8
DEC H 25
Decrement the high byte of HL, removing the safety margin added earlier.
52A9
DEC HL 2B
Decrement HL by one more byte. This adjusts the string pointer to its actual position.
52AA
LD (40FDH),DE ED 53 FD 40
Store the adjusted address from DE back to the string space pointer at 40FDH. This moves the string space boundary down to make room for the new statement.
52AE
DEC DE 1B
Decrement DE by 1. This positions DE at the last byte of the destination area for the block move.
52AF
LDDR ED B8
Block move memory from (HL) to (DE), moving backwards, for BC bytes. This shifts the existing file buffer contents down to make room at the top for the new statement. BC still contains the buffer usage count from earlier.
52B1
INC DE 13
Increment DE by 1. After the LDDR, DE points one byte below the new insertion point, so this adjusts it to point at the first byte of the insertion area.
52B2
LD (53DCH),DE ED 53 DC 53
Store the new insertion address from DE into memory location 53DCH. This location is used as a working pointer to track where the next statement data should be copied.
Update the system memory pointers to reflect the new buffer layout.
52B6
POP HL E1
Restore HL from the stack. This recovers the buffer usage count that was saved earlier.
52B7
ADD HL,DE 19
Add DE to HL. This calculates the new end of program area (40F9H pointer value) by adding the insertion point to the buffer size.
52B8
LD (40F9H),HL 22 F9 40
Store the new address in HL to the program end pointer at 40F9H.
52BB
POP BC C1
Restore BC from the stack. This recovers the address of the start of the parsed statement.
52BC
ADD HL,BC 09
Add BC to HL. This calculates the new end of variables area by adding the statement length to the program end.
52BD
LD (40FBH),HL 22 FB 40
Store the new address in HL to the variables end pointer at 40FBH.
Save the buffer start address for later use in the line copying loop.
52C0
LD HL,(40A4H) 2A A4 40
Load HL with the buffer start address from 40A4H again.
52C3
LD (5429H),HL 22 29 54
Store this address at memory location 5429H. This creates a self-modifying code location that will be used as the source address in the line copy operation.
52C6
LD (547FH),HL 22 7F 54
Also store this address at memory location 547FH. This creates another self-modifying code reference, probably used in a different subroutine.
52C9
EX DE,HL EB
Exchange DE and HL. Now DE has the buffer start address, ready to use as the destination for copying the new statement.
52CAH - Process Statement Line Format and Line Number
Now examine the format of the parsed statement line. BASIC program lines in memory begin with a line link pointer (2 bytes), followed by the line number (2 bytes), then the tokenized statement, then a null terminator. The code checks if this is a valid numbered line or an unnumbered direct command.
52CA
LD A,(HL) 7E
Load A with the first byte of the line link pointer (low byte) from the buffer at (HL).
52CB
INC HL 23
Advance HL to point to the second byte of the line link.
52CC
OR (HL) B6
OR A with the second byte of the line link pointer (high byte). If both bytes are 00H, the result will be zero, indicating this line has no forward link (it's the last or only line).
52CD
INC HL 23
Advance HL to point to the line number low byte.
52CE
LD C,(HL) 4E
Load C with the line number low byte.
52CF
INC HL 23
Advance HL to point to the line number high byte.
52D0
LD B,(HL) 46
Load B with the line number high byte. Now BC contains the complete 16-bit line number.
52D1
If the line link was not zero (from the OR operation at 52CCH), jump to 52D6H to process a normal numbered line.
The line link was zero, meaning this is either an unnumbered direct command or special case. Set BC to FFFFH to mark it as having no valid line number.
52D3
LD BC,FFFFH 01 FF FF
Load BC with FFFFH (65535), which serves as a flag value indicating no line number or an invalid/direct command line.
Continue with processing this statement, whether it has a valid line number or not.
52D6
PUSH BC C5
Save the line number (or FFFFH flag) on the stack for later use.
52D7
LD HL,543EH 21 3E 54
Load HL with address 543EH, which points to a buffer finalization subroutine.
52DA
LD (644EH),HL 22 4E 64
Store this address at location 644EH. This updates a function pointer that controls what routine gets called when statement processing completes. The system will now call 543EH when the buffer is full or input ends.
Now check if there's an existing file buffer in memory that needs to be merged with the new lines. Address 4200H contains a marker byte that indicates buffer status.
52DD
LD HL,4200H 21 00 42
Load HL with address 4200H, which contains a file buffer status byte.
52E0
LD A,(HL) 7E
Load A with the status byte from (4200H).
52E1
CP FFH FE FF
Compare with FFH, which indicates no existing file buffer (empty or uninitialized state).
52E3
If the status byte is NOT FFH, there IS an existing buffer, so jump to 535BH to handle merging new lines into the existing file.
[NEW FILE PATH] - The buffer is empty (FFH marker), so this is a completely new file. We'll copy lines directly into the buffer without merge logic.
52E6
LD (5442H),DE ED 53 42 54
Store the current destination address from DE at memory location 5442H. This is a self-modifying code location that will be used as the destination pointer in the line copy loop.
Begin copying bytes from the parsed statement in the parse buffer to the destination buffer. The loop will copy lines byte by byte, checking for certain boundary conditions.
52EA
INC L 2C
Increment the low byte of HL by 1, moving to the next address in the 4200H block.
52EB
If the increment caused L to wrap to 00H (zero flag set), call 54B2H to handle a page boundary crossing in the buffer area. This manages the transition to the next 256-byte block.
52EE
LD C,(HL) 4E
Load C with the byte at the current HL position. This is part of building up a multi-byte value.
52EF
INC L 2C
Increment L to move to the next byte.
52F0
Again check for page boundary crossing and call 54B2H if needed.
52F3
LD A,C 79
Copy C into A for testing.
52F4
OR (HL) B6
OR A with the byte at (HL). This combines two bytes to check if both are zero.
52F5
If both bytes are zero (indicating the end of the line or a null link pointer), jump to 5310H to complete processing of this line batch.
The bytes were not both zero, so continue reading more data from the current line structure.
52F7
INC L 2C
Move to the next byte in the source buffer.
52F8
Check for page boundary crossing.
52FB
LD C,(HL) 4E
Load C with the low byte of the line number or next field.
52FC
INC L 2C
Move to the next byte.
52FD
Check for page boundary crossing.
5300
LD B,(HL) 46
Load B with the high byte. Now BC contains a 16-bit value (likely line number or length).
5301
Call subroutine at 53B4H to process or copy the line data based on the value in BC. This handles the actual data transfer and may check for buffer overflow.
Now copy the statement text byte by byte until we reach the null terminator.
5304
INC L 2C
Move to the next source byte.
5305
Check for page boundary crossing in the source buffer.
5308
LD A,(HL) 7E
Load A with the current byte from the statement text.
5309
OR A B7
Test if A is zero (the null terminator marking the end of the statement).
530A
LD (DE),A 12
Store the byte from A into the destination buffer at (DE). This copies each character of the statement.
530B
INC DE 13
Advance the destination pointer to the next position.
530C
If the byte was not zero, loop back to 5304H to copy the next byte. Continue until we hit the null terminator.
[INNER LOOP END] - The null terminator has been copied. Go back to read the next line from the source buffer.
530E
Jump back to 52E6H to process the next statement line. This continues the main loop until all input lines have been processed.
5310H - Complete Statement Processing and Finalize Buffer
All lines have been copied into the buffer (indicated by encountering a double-zero link pointer). Now finalize the buffer and perform cleanup operations.
5310
POP AF F1
Discard the saved line number (or FFFFH flag) from the stack that was pushed earlier at 52D6H. This value is no longer needed.
5311
Call the buffer finalization routine at 543EH. This performs cleanup operations, updates system pointers, and prepares the buffer for writing to disk.
5314H - Determine Exit Status and Return to DOS
This is the exit point for the file creation/modification command. The code determines whether to return to command level, perform error handling, or continue with additional operations. The modifier flag at 5315H was set earlier based on user input.
5314
LD A,00H 3E 00
Load A with 00H. This is a self-modifying code location - the actual byte (00H here) may have been changed to 01H or 02H earlier depending on which modifier (R or V) was specified.
5316
OR A B7
Test if A is zero (no modifier was used).
5317
If A is zero (no modifier), jump to 1A19H to perform normal DOS return/cleanup and return to the command processor.
A modifier WAS specified (A is non-zero). Need to perform additional processing based on the modifier type.
531A
LD HL,(40A4H) 2A A4 40
Load HL with the buffer start address from 40A4H.
531D
DEC HL 2B
Decrement HL to point one byte before the buffer start. This may point to a header byte or control structure.
531E
DEC A 3D
Decrement A. This distinguishes between modifier value 01H (becomes 00H) and 02H (becomes 01H).
531F
If A became zero (meaning the original value was 01H, indicating the R modifier for read-only), jump to 1D1EH to handle read-only file closure.
The modifier was 02H (V modifier for verify mode on printer output). Need to perform verification operations.
5322
LD DE,(57B8H) ED 5B B8 57
Load DE with a pointer value from 57B8H. This likely contains an address related to the printer verification or error handling.
5326
Call DOS routine at 1B2CH to perform verification checking or compare operations.
5329
LD H,B 60
Copy B into H.
532A
LD L,C 69
Copy C into L. Now HL contains the value that was in BC, likely a comparison result or status code.
532B
DEC HL 2B
Decrement HL to test if it was 0001H (making it 0000H).
532C
If no carry resulted from the decrement (meaning HL was ≥ 0001H), jump to 5331H for error reporting.
532E
If the zero flag is set (HL was exactly 0001H and is now 0000H), verification succeeded - jump to 1D1EH for normal file closure.
5331
If we reach here, verification failed or an error occurred. Jump to 1997H for error reporting (likely "Verify error" or similar message).
5334H - Alternate Entry Point for File Operations
An alternate entry point for file operations, possibly invoked when specific conditions are met or as part of error recovery. The code examines the file control block pointers to determine the current file state.
5334
LD DE,(40A2H) ED 5B A2 40
Load DE with the value from memory location 40A2H. This is typically a File Control Block (FCB) pointer or related system pointer.
5338
LD A,D 7A
Copy the high byte (D) into register A.
5339
AND E A3
AND A with the low byte (E). If both D and E are FFH, the result will be FFH.
533A
INC A 3C
Increment A. If A was FFH, it becomes 00H and sets the zero flag. This tests if the pointer was FFFFH (indicating no file open or invalid state).
533B
If the pointer was FFFFH (invalid/no file), jump to 5350H to handle the no-file case.
A valid file IS open (pointer is not FFFFH). Need to process it appropriately.
533D
Call subroutine at 5D9FH to perform file-related operations, possibly closing or flushing the current file.
5340
LD A,(IX+0EH) DD 7E 0E
Load A with the device code byte from the FCB at offset 0EH. IX still points to the FCB from earlier.
5343
AND 07HAND 00000111 E6 07
Mask to isolate the device type field (bits 0-2).
5345
CP 06H FE 06
Compare with 06H (printer device).
5347
If NOT device 6 (printer), skip ahead to 534CH.
This IS the printer device (6). The earlier code may have decremented the device code to 5 for bi-directional mode, so increment it back to restore the original state.
5349
DEC (IX+0EH) DD 35 0E
Decrement the device code in the FCB. Wait, this seems backwards - perhaps this is restoring a previous modification, or the logic is more complex than initially apparent.
534C
LD A,02H 3E 02
Load A with 02H, setting a status code to indicate successful completion with special handling.
534E
Jump to 5355H to store this status and continue.
[NO FILE PATH] - The file pointer was FFFFH, indicating no file is currently open or an invalid state.
5350
DEC HL 2B
Decrement HL. This adjusts a pointer (possibly pointing just past valid data).
5351
RST 10H D7
Call ROM routine via RST 10H (restart vector 2). This typically performs some comparison or validation check.
5352
If the non-zero flag is set (check failed), jump to 1997H for error reporting.
5355
LD (5315H),A 32 15 53
Store the status code from A into the modifier flag location at 5315H. This updates the self-modifying code byte that was used earlier.
5358
Jump back to 5266H to continue with file finalization or additional processing. This creates a loop or retry mechanism.
535BH - Merge New Lines Into Existing File Buffer
This code path is taken when the file buffer at 4200H is NOT empty (status byte was not FFH). This means there's already file data in memory, and we need to intelligently merge the new input lines with the existing lines, maintaining proper line number order.
535B
DEC (IX+17H) DD 35 17
Decrement the byte at offset 17H in the FCB. This field might control file update behavior or track the number of pending operations.
535E
PUSH DE D5
Save the current destination pointer DE on the stack.
535F
LD (5442H),DE ED 53 42 54
Store DE at the self-modifying code location 5442H for later use in copy operations.
5363
Call subroutine at 54BDH to perform buffer setup or initialization for the merge operation.
Set up to read a line of input from the user/console. E is loaded with a buffer size counter.
5366
LD E,F0H 1E F0
Load E with F0H (240 decimal), setting the maximum line input length counter to 240 characters.
5368
LD HL,(40A7H) 2A A7 40
Load HL with a pointer from 40A7H. This typically points to an input buffer where keyboard input will be stored.
536B
PUSH HL E5
Save the buffer start address on the stack.
[INPUT LOOP START] - Read characters from the console one by one until Enter is pressed or buffer is full.
536C
Call the keyboard input routine at 6119H to read one character from the console. Returns the character in A, with Z flag set if no character available.
536F
If the non-zero flag is set (indicating an error or special condition), jump to 5310H to finalize and exit.
5372
OR A B7
Test if A is zero (no character received yet).
5373
If A is zero, loop back to 536CH to wait for a character. This creates a busy-wait loop.
A character was received in A. Check what kind of character it is.
5375
CP 0DH FE 0D
Compare with 0DH (ASCII 13, the Enter/Return key).
5377
LD (HL),A 77
Store the character into the buffer at (HL) regardless of what it is.
5378
If the character WAS Enter (0DH), jump to 5387H to finish the line and process it.
The character was not Enter. Check if it's a line feed character that should be ignored.
537A
CP 0AH FE 0A
Compare with 0AH (ASCII 10, the Line Feed character).
537C
If NOT line feed, jump to 5383H to accept the character normally.
It IS a line feed character. Check if this is the first character in the buffer (E still equals F0H), in which case ignore it.
537E
LD A,E 7B
Copy E (the remaining buffer space counter) into A.
537F
CP F0H FE F0
Compare with F0H (240), checking if this is the very first character position.
5381
If E equals F0H (buffer is still empty), ignore this line feed and loop back to 536CH to read another character. This skips leading line feeds.
The character is acceptable (not a leading line feed). Store it and continue.
5383
INC HL 23
Advance the buffer pointer to the next position.
5384
DEC E 1D
Decrement the remaining space counter in E.
5385
If E is not zero (buffer not full yet), loop back to 536CH to read the next character.
[INPUT COMPLETE] - Either Enter was pressed or the buffer is full. Null-terminate the line and process it.
5387
XOR A AF
Clear A to 00H (null terminator).
5388
LD (HL),A 77
Store the null terminator at (HL) to mark the end of the input line.
5389
POP HL E1
Restore HL from the stack, pointing it back to the beginning of the input buffer.
538AH - Parse and Process Input Line
The input line has been read and null-terminated. Now parse it to check for line numbers and validate the syntax before adding it to the file buffer.
538A
DEC HL 2B
Decrement HL to point back to the Enter character (0DH) that terminates the line.
538B
RST 10H D7
Call ROM routine via RST 10H to perform a comparison or syntax check on the input line.
538D
DEC A 3D
Decrement A back. These two instructions test the flags without changing A, essentially checking the result of the RST 10H call.
538E
If the zero flag is set (indicating an empty line or special condition), jump back to 5366H to read another line.
5390
If no carry flag (indicating an error condition in the parse), jump to 5DDFH to handle the error.
The line appears valid. Now call the BASIC line parser to tokenize it.
5393
Call the BASIC line tokenizer at 1E5AH. This converts the ASCII text into tokenized BASIC format suitable for storage in the program buffer.
After tokenizing, trim trailing spaces from the line. Work backwards from the end of the line to find the last non-space character.
5396
DEC HL 2B
Move HL back one position to point to the last character before the null terminator.
5397
LD A,20H 3E 20
Load A with 20H (ASCII space character) for comparison.
5399
CP (HL) BE
Compare the space character with the byte at (HL).
539A
If the character is not a space, jump to 53A1H - we've found the end of meaningful content.
[TRIM LOOP] - The last character was a space. Continue scanning backwards to remove all trailing spaces.
539C
DEC HL 2B
Move back another character.
539D
CP (HL) BE
Compare with the space character again.
539E
If this character is also a space, loop back to 539CH to continue trimming. Keep going until we find a non-space.
53A0
INC HL 23
Increment HL by one to point just after the last non-space character.
HL now points to where the null terminator should be placed (right after the last meaningful character). Now process the tokenized line.
53A1
INC HL 23
Move HL forward one position to account for the final character.
53A2
PUSH DE D5
Save the destination buffer pointer DE on the stack.
53A3
Call routine at 1BC0H to finalize the tokenized line format. This likely adds the line link pointer and line number fields.
53A6
POP BC C1
Restore the saved pointer into BC (note: popped as BC, not DE - this swaps the register usage).
53A7
POP DE D1
Restore DE from the stack - this was the original destination pointer from earlier.
53A8
Call the buffer space check and line copy routine at 53B4H. This verifies there's enough space in the buffer for this line and copies the line header.
Now copy the tokenized statement text byte by byte into the destination buffer.
53AB
INC HL 23
Move to the next byte in the source (tokenized line).
53AC
LD A,(HL) 7E
Load the current byte into A.
53AD
OR A B7
Test if A is zero (the null terminator).
53AE
LD (DE),A 12
Store the byte into the destination buffer at (DE).
53AF
INC DE 13
Advance the destination pointer.
53B0
If the byte was not zero, loop back to 53ABH to copy the next byte. Continue until the null terminator is copied.
53B2
Jump back to 535EH to process the next input line. This continues the merge loop.
53B4H - Check Buffer Space and Copy Line Header
This critical subroutine checks if there's enough space remaining in the file buffer to add the new line. If space is available, it copies the line link pointer and line number fields into the buffer. BC contains the line number on entry.
53B4
POP AF F1
Pop the return address from the stack into AF. This is unusual - the routine is manipulating its own return address to implement special control flow.
53B5
EX (SP),HL E3
Exchange HL with the top of stack. This saves HL on the stack and loads a value from the stack into HL.
53B6
PUSH AF F5
Push AF (the saved return address) back onto the stack.
Now check if the new line will fit in the remaining buffer space. The comparison is between the line's expected size and the space available.
53B7
OR A B7
Clear the carry flag before subtraction.
53B8
SBC HL,BC ED 42
Subtract BC from HL with borrow (HL = HL - BC). This calculates the remaining space after adding this line.
53BA
ADD HL,BC 09
Add BC back to restore HL to its original value. The flags from the subtraction are preserved, allowing us to check if space was sufficient.
53BB
If carry is set (meaning HL < BC, insufficient space), jump to 53FEH to handle buffer overflow.
53BD
If zero flag is set (HL exactly equals BC, special case), jump to 53CDH for special handling.
There IS sufficient space. Copy the 4-byte line header (link pointer + line number) into the destination buffer.
53BF
POP AF F1
Restore the return address into AF.
53C0
EX (SP),HL E3
Exchange HL with the top of stack, restoring HL and saving a value.
53C1
EX DE,HL EB
Exchange DE and HL. Now HL points to the destination buffer, and DE has the source pointer.
53C2
PUSH AF F5
Push the return address back onto the stack for eventual return.
Write the 4-byte line header: 2 bytes for line link pointer (both set to H=00H initially), followed by 2 bytes for the line number from BC.
53C3
LD (HL),H 74
Store H (high byte of line link = 00H) at the destination.
53C4
INC HL 23
Move to the next byte.
53C5
LD (HL),H 74
Store H again (low byte of line link = 00H).
53C6
INC HL 23
Move to the line number field.
53C7
LD (HL),C 71
Store the line number low byte from C.
53C8
INC HL 23
Move to the next byte.
53C9
LD (HL),B 70
Store the line number high byte from B.
53CA
INC HL 23
Move HL to point to where the statement text will start.
53CB
EX DE,HL EB
Exchange DE and HL back, restoring the original register arrangement. DE now points to where the statement text should be copied.
53CC
RET C9
Return to the caller with the line header successfully written.
[SPECIAL CASE - EXACT MATCH] - HL exactly equals BC, which might indicate the buffer is exactly full or a boundary condition.
53CD
LD A,B 78
Copy B into A.
53CE
AND C A1
AND A with C. If both B and C are FFH, the result will be FFH.
53CF
INC A 3C
Increment A. If A was FFH, it becomes 00H and sets the zero flag.
53D0
If BC was FFFFH (indicating an unnumbered direct command), jump to 5DE2H for special direct command handling.
BC was not FFFFH. Check the modifier flag to determine how to proceed.
53D3
LD A,(5315H) 3A 15 53
Load the modifier flag from the self-modifying code location at 5315H.
53D6
CP 02H FE 02
Compare with 02H (indicating the V modifier for verify mode).
53D8
If the modifier is 02H (verify mode), jump to 1E4AH for special verify mode processing.
Normal processing continues. Need to scan through the existing buffer to count lines and find the proper insertion point.
53DB
LD HL,0000H 21 00 00
Load HL with 0000H. This is a self-modifying code location - the actual address will be filled in at runtime to point to the start of the buffer being scanned.
[LINE COUNTING LOOP] - Scan through the buffer counting complete lines by looking for null terminators.
53DE
INC HL 23
Skip past the line link low byte.
53DF
INC HL 23
Skip past the line link high byte.
53E0
INC HL 23
Skip past the line number low byte.
53E1
INC HL 23
Skip past the line number high byte. HL now points to the statement text.
53E2
LD A,(HL) 7E
Load the current byte from the statement.
53E3
OR A B7
Test if A is zero (null terminator = end of this line).
53E4
INC HL 23
Move to the next byte.
53E5
If not zero, loop back to 53E2H to continue scanning through this line's statement. Keep going until we find the null terminator.
Found the end of a line. HL now points to the start of the next line (or the end marker). Process this line's information.
53E7
Call subroutine at 53EEH to read the line link pointer and line number from the current position.
53EA
LD H,(HL) 66
Load H with the byte at (HL). This appears to load part of the line link or length field.
53EB
LD L,A 6F
Load L with A (which was returned from the subroutine).
53EC
Jump back to 53B7H to continue the space checking logic with the updated line information.
53EEH - Read Line Link and Number Information
This subroutine reads the line link pointer and line number from the current position in the buffer. It's used during line counting and buffer scanning operations.
53EE
LD (53DCH),HL 22 DC 53
Store the current HL position at memory location 53DCH. This saves the current scan position for later use.
53F1
LD A,(HL) 7E
Load A with the line link pointer low byte.
53F2
INC HL 23
Move to the next byte.
53F3
OR (HL) B6
OR A with the line link pointer high byte. If both bytes are zero, this indicates the end of the line chain.
53F4
INC HL 23
Move to the line number field.
53F5
LD A,(HL) 7E
Load A with the line number low byte (or first byte of line number).
53F6
INC HL 23
Move to the line number high byte.
53F7
RET NZ C0
If the line link pointer was not zero (normal case), return immediately. The line information has been read.
The line link pointer WAS zero (00 00), indicating this is the last line or end of buffer. Handle this special case.
53F8
POP HL E1
Pop a return address from the stack. This skips one level of return, effectively implementing a different return path.
53F9
LD HL,FFFFH 21 FF FF
Load HL with FFFFH, a flag value indicating end of buffer or no more lines.
53FC
Jump to 53B7H to continue processing with the FFFFH flag value.
53FEH - Handle Buffer Overflow - Expand Buffer Space
The new line won't fit in the current buffer space. Need to expand the buffer by making room, similar to what was done earlier in the main processing loop.
53FE
LD HL,(53DCH) 2A DC 53
Load HL with the saved buffer position from 53DCH. This points to where we need to insert the new line.
5401
Call the buffer management routine at 5478H to perform necessary bookkeeping and pointer updates.
5404
LD (547FH),DE ED 53 7F 54
Store DE at the self-modifying code location 547FH.
5408
LD (5442H),DE ED 53 42 54
Store DE at the self-modifying code location 5442H. These update the destination pointers for buffer operations.
540C
Call 53EEH again to re-read the line information at the current position.
540F
PUSH HL E5
Save HL on the stack.
5410
LD H,(HL) 66
Load H with a byte from (HL).
5411
LD L,A 6F
Load L with A. Now HL contains line information.
5412
OR A B7
Clear the carry flag.
5413
SBC HL,BC ED 42
Subtract BC from HL to check available space again.
5415
ADD HL,BC 09
Add BC back, preserving flags.
5416
If still insufficient space (carry set), jump to 541BH to allocate more buffer space.
5418
POP AF F1
Discard the saved HL value.
5419
Jump back to 53B7H to retry the line insertion with the expanded buffer.
Still not enough space after initial expansion. Need to allocate a larger buffer area.
541B
EX DE,HL EB
Exchange DE and HL.
541C
LD (HL),H 74
Store H at (HL).
541D
INC HL 23
Move to next position.
541E
LD (HL),H 74
Store H again (creating zero link pointers).
541F
INC HL 23
Advance position.
5420
LD (HL),E 73
Store E (line number low byte).
5421
INC HL 23
Advance position.
5422
LD (HL),D 72
Store D (line number high byte).
5423
INC HL 23
Move to statement text area.
5424
EX DE,HL EB
Exchange back to restore register arrangement.
5425
POP HL E1
Restore HL from the stack.
5426
INC HL 23
Move HL forward one position.
5427
PUSH BC C5
Save BC (line number) on the stack.
Initialize BC as a counter starting at 5 (the size of a line header: 4 bytes plus 1).
5428
LD BC,0000H 01 00 00
Load BC with 0000H. This is self-modifying code - the actual value will be set at runtime.
542B
INC BC 03
Increment BC to 1.
542C
INC BC 03
Increment BC to 2.
542D
INC BC 03
Increment BC to 3.
542E
INC BC 03
Increment BC to 4.
[STATEMENT COPY LOOP] - Copy the statement text byte by byte, counting bytes as we go.
542F
INC BC 03
Increment the byte counter.
5430
LD A,(HL) 7E
Load A with the current statement byte.
5431
OR A B7
Test if A is zero (null terminator).
5432
LD (DE),A 12
Store the byte at the destination.
5433
INC HL 23
Advance source pointer.
5434
INC DE 13
Advance destination pointer.
5435
If not zero, loop back to 542FH to copy the next byte.
The entire line has been copied. BC now contains the total line length. Update the self-modifying code location and continue.
5437
LD (5429H),BC ED 43 29 54
Store the total line length from BC at the self-modifying code location 5429H.
543B
POP BC C1
Restore the original BC (line number) from the stack.
543C
Jump back to 5404H to continue processing the buffer insertion.
543EH - Finalize Buffer and Write to Disk
This is the main buffer finalization routine that's called when all lines have been added to the file buffer. It performs final cleanup, updates system pointers, and writes the completed buffer to disk.
543E
Call the buffer management routine at 5478H to perform pointer updates and bookkeeping.
5441
LD DE,0000H 11 00 00
Load DE with 0000H. This is self-modifying code - the actual address will be set at runtime to point to the destination for the block move.
5444
LD BC,(53DCH) ED 4B DC 53
Load BC with the buffer position pointer from 53DCH. This contains the size or position information for the block move.
5448
LD HL,(40F9H) 2A F9 40
Load HL with the program end pointer from system memory at 40F9H.
544B
PUSH BC C5
Save BC on the stack.
544C
OR A B7
Clear the carry flag.
544D
SBC HL,BC ED 42
Subtract BC from HL (HL = HL - BC). This calculates how many bytes to move.
544F
LD B,H 44
Copy H into B.
5450
LD C,L 4D
Copy L into C. Now BC contains the byte count for the block move.
5451
POP HL E1
Restore the original BC value into HL (it's now the source address).
5452
LDIR ED B0
Block move BC bytes from (HL) to (DE). This moves the program data to its final location.
5454
LD (40F9H),DE ED 53 F9 40
Store the updated pointer from DE back to the program end pointer at 40F9H.
Now move the variables area if needed.
5458
LD BC,0000H 01 00 00
Load BC with a size value. This is self-modifying code location.
545B
LD A,B 78
Copy B into A.
545C
OR C B1
OR A with C to test if BC is zero.
545D
If BC is zero (no variables area to move), skip the move and jump to 5461H.
545F
LDIR ED B0
Block move the variables area from (HL) to (DE) for BC bytes.
5461
LD (40FBH),DE ED 53 FB 40
Store the updated pointer from DE to the variables end pointer at 40FBH.
Now move the string space if needed.
5465
LD BC,0000H 01 00 00
Load BC with another size value. This is self-modifying code location.
5468
LD A,B 78
Copy B into A.
5469
OR C B1
OR A with C to test if BC is zero.
546A
If BC is zero (no string space to move), skip and jump to 546EH.
546C
LDIR ED B0
Block move the string space from (HL) to (DE) for BC bytes.
546E
LD (40FDH),DE ED 53 FD 40
Store the final pointer from DE to the string space pointer at 40FDH.
All memory areas have been moved. Now perform final cleanup and return to the system.
5472
Call DOS routine at 1AF8H to perform final file operations, possibly closing the file or flushing buffers to disk.
5475
Jump to 64BEH to return to the command processor or perform final system cleanup.
5478H - Buffer Management and Pointer Update Routine
This utility routine manages buffer pointers and performs bookkeeping operations during file buffer manipulation. It's called multiple times during the merge and finalization process.
5478
PUSH HL E5
Save HL on the stack.
5479
PUSH DE D5
Save DE on the stack.
547A
PUSH BC C5
Save BC on the stack. All working registers are preserved.
547B
LD HL,(5442H) 2A 42 54
Load HL with the pointer value from the self-modifying code location at 5442H. This contains the current destination buffer pointer.
547E
LD DE,0000H 11 00 00
Load DE with a value. This is self-modifying code.
5481
OR A B7
Clear the carry flag.
5482
SBC HL,DE ED 52
Subtract DE from HL to calculate an offset or size.
5484
LD (557AH),HL 22 7A 55
Store the result at memory location 557AH. This saves a calculated size or offset value.
5487
LD DE,0000H 11 00 00
Load DE with another value. This is self-modifying code.
548A
LD HL,(5429H) 2A 29 54
Load HL with the pointer from the self-modifying code location at 5429H.
548D
LD A,H 7C
Copy H into A to test if HL is non-zero.
548E
If HL is not zero, call the processing routine at 54F2H to handle additional buffer management tasks.
5491
POP BC C1
Restore BC from the stack.
5492
POP DE D1
Restore DE from the stack.
5493
POP HL E1
Restore HL from the stack. All registers are restored to their original values.
5494
RET C9
Return to the caller.
5495H - Calculate Buffer Sizes and Set Up Pointers
This routine calculates the sizes of different memory areas (program, variables, strings) and sets up self-modifying code locations with these values for use in buffer operations.
5495
LD HL,(40FDH) 2A FD 40
Load HL with the string space pointer from 40FDH.
5498
LD DE,(40FBH) ED 5B FB 40
Load DE with the variables end pointer from 40FBH.
549C
OR A B7
Clear the carry flag.
549D
SBC HL,DE ED 52
Subtract DE from HL (HL = HL - DE). This calculates the size of the string space area.
549F
LD (5466H),HL 22 66 54
Store the string space size at the self-modifying code location 5466H.
54A2
LD B,H 44
Copy H into B.
54A3
LD C,L 4D
Copy L into C. Now BC contains the string space size.
54A4
LD HL,(40F9H) 2A F9 40
Load HL with the program end pointer from 40F9H.
54A7
LD (5488H),HL 22 88 54
Store the program end pointer at the self-modifying code location 5488H.
54AA
EX DE,HL EB
Exchange DE and HL. Now DE has the program end, HL has the variables end.
54AB
OR A B7
Clear the carry flag.
54AC
SBC HL,DE ED 52
Subtract DE from HL. This calculates the size of the variables area.
54AE
LD (5459H),HL 22 59 54
Store the variables area size at the self-modifying code location 5459H.
54B1
RET C9
Return to the caller with all sizes calculated and stored.
54B2H - Handle Page Boundary Crossing During Line Input
This routine is called when the line input buffer crosses a 256-byte page boundary. It checks for buffer overflow and gets another line of input if needed.
54B2
PUSH DE D5
Save the destination pointer DE on the stack.
54B3
LD DE,570DH 11 0D 57
Load DE with address 570DH, which points to an input/parse function.
54B6
Call the routine at 4436H to get more input or check input status.
54B9
If non-zero flag (indicating an error or end condition), jump to 5E16H for error handling.
54BC
POP DE D1
Restore DE from the stack.
Check if we're approaching memory limits. Compare the current position with a safety threshold.
54BD
PUSH HL E5
Save HL on the stack.
54BE
LD HL,(53DCH) 2A DC 53
Load HL with the buffer position from 53DCH.
54C1
DEC H 25
Decrement the high byte by 1 (subtract 256 bytes). This creates a safety margin.
54C2
RST 18H DF
Call ROM routine via RST 18H to compare HL with DE and set appropriate flags.
54C3
POP HL E1
Restore HL from the stack.
54C4
RET NC D0
If no carry (sufficient space remaining), return normally.
54C5
If carry is set (insufficient memory), jump to 197AH to generate an "Out of Memory" error.
54C8H - Read File Data Into Buffer
This routine reads data from an open disk file into the program buffer. It sets up multiple self-modifying code locations with buffer pointers and then calls lower-level routines to perform the actual file I/O.
54C8
LD (53DCH),HL 22 DC 53
Store HL at the self-modifying code location 53DCH.
54CB
LD (547FH),HL 22 7F 54
Store HL at the self-modifying code location 547FH.
54CE
LD (5429H),HL 22 29 54
Store HL at the self-modifying code location 5429H. These three stores set up buffer pointers for subsequent operations.
54D1
EX DE,HL EB
Exchange DE and HL.
54D2
LD (5442H),HL 22 42 54
Store HL at the self-modifying code location 5442H.
54D5
XOR A AF
Clear A to zero. This sets a flag or parameter for the file read operation.
54D6
Call the file processing routine at 54F2H to read data from the file.
54D9
Call 5495H to recalculate buffer sizes after reading data.
54DC
Jump to 543EH to finalize the buffer and complete the file read operation.
54DFH - Post-File-Read Cleanup and Initialization
This routine performs cleanup operations after a file has been read into memory. It initializes various system pointers and prepares to return to the appropriate execution point.
54DF
LD HL,0000H 21 00 00
Load HL with 0000H, clearing it.
54E2
LD (40F0H),HL 22 F0 40
Store 0000H at system pointer 40F0H, probably clearing a current line pointer or execution pointer.
54E5
POP HL E1
Pop a return address from the stack into HL.
54E6
LD (54F0H),HL 22 F0 54
Store this return address at the self-modifying code location 54F0H for later use.
54E9
Call DOS routine at 63B9H to perform buffer or memory management.
54EC
Call routine at 1B8FH for additional initialization or setup.
54EF
JP 0000H C3 00 00
Jump to address 0000H. This is self-modifying code - the actual address was stored earlier at this location. This returns to the saved return point.
54F2H - Main File Data Processing Routine
This complex routine processes the file data after it's been read into memory, handling variables, arrays, and strings. It scans through the program scanning for variable and array definitions and processes each one appropriately.
54F2
LD (5574H),A 32 74 55
Store A at the self-modifying code location 5574H. This saves a flag or parameter value.
54F5
LD (556CH),HL 22 6C 55
Store HL at the self-modifying code location 556CH.
54F8
LD (5565H),DE ED 53 65 55
Store DE at the self-modifying code location 5565H. These stores preserve important pointers.
54FC
LD HL,(40F9H) 2A F9 40
Load HL with the program end pointer from 40F9H.
54FF
LD DE,(40FBH) ED 5B FB 40
Load DE with the variables end pointer from 40FBH.
5503
RST 18H DF
Call ROM routine via RST 18H to compare HL and DE.
5504
If HL equals DE (no variables area), jump to 5527H to skip variable processing.
[VARIABLE PROCESSING LOOP] - Scan through each variable in the variables area.
5506
LD A,(HL) 7E
Load A with the variable type byte at (HL).
5507
AND 0FHAND 00001111 E6 0F
Mask to isolate the variable type field (bits 0-3).
5509
INC HL 23
Move past the type byte.
550A
INC HL 23
Move past the name byte.
550B
BIT 7,(HL) CB 7E
Test bit 7 of the current byte. This bit indicates if this is an array variable.
550D
INC HL 23
Move to the data area.
550E
If bit 7 was clear (simple variable, not array), jump to 551BH to handle it as a simple variable.
This IS an array variable. Arrays need special processing to relocate string pointers.
5510
PUSH AF F5
Save the variable type in AF.
5511
LD A,00H 3E 00
Load A with a parameter value. This is self-modifying code.
5513
Call the array element processing routine at 555BH to handle relocating pointers within the array.
5516
POP AF F1
Restore the variable type into AF.
5517
DEC A 3D
Decrement A to adjust the type value.
5518
DEC A 3D
Decrement A again. This normalizes the array type code.
5519
Jump to 5520H to calculate the variable size and continue.
[SIMPLE VARIABLE PATH] - This is a simple (non-array) variable.
551B
CP 03H FE 03
Compare the type with 03H (string variable type).
551D
If this IS a string variable (type 03H), call 5558H to relocate the string pointer.
Calculate the size of this variable and advance to the next one.
5520
LD C,A 4F
Copy A (the variable type/size indicator) into C.
5521
LD B,00H 06 00
Clear B to zero. Now BC contains the variable data size.
5523
ADD HL,BC 09
Add the variable size to HL, advancing the pointer to the next variable.
5524
Jump back to 54FFH to process the next variable. Continue looping through all variables.
5526
ADD HL,BC 09
Add BC to HL (this line appears unreachable due to the JR above).
5527H - Process String Space Area
After processing all variables, now process the string space area to relocate any string pointers that reference string data.
5527
LD DE,(40FDH) ED 5B FD 40
Load DE with the string space pointer from 40FDH.
552B
RST 18H DF
Call ROM routine via RST 18H to compare HL with DE.
552C
RET Z C8
If HL equals DE (no string space to process), return immediately.
[STRING SPACE PROCESSING LOOP] - Scan through the string space area.
552D
LD A,(HL) 7E
Load A with the string descriptor type byte.
552E
AND 0FHAND 00001111 E6 0F
Mask to isolate the type field.
5530
CP 03H FE 03
Compare with 03H (string type).
5532
INC HL 23
Skip the type byte.
5533
INC HL 23
Skip the name byte.
5534
INC HL 23
Skip another byte.
5535
LD C,(HL) 4E
Load C with the string length low byte.
5536
INC HL 23
Move to the next byte.
5537
LD B,(HL) 46
Load B with the string length high byte. BC now contains the string length.
5538
INC HL 23
Move to the string data pointer.
5539
If the type was not a string (from CP 03H at 5530), jump to 5526H to skip string processing.
This IS a string. Process each character or element in the string.
553B
LD DE,0001H 11 01 00
Load DE with 0001H, setting up a counter or increment value.
[STRING ELEMENT LOOP] - Process each element in this string descriptor.
5540
LD A,(HL) 7E
Load A with the current byte (element count or descriptor).
5541
INC HL 23
Move to the element pointer.
5542
LD C,(HL) 4E
Load C with pointer low byte.
5543
INC HL 23
Move to pointer high byte.
5544
LD B,(HL) 46
Load B with pointer high byte. BC now contains the element pointer.
5545
PUSH AF F5
Save the element count.
5546
INC HL 23
Move past the pointer.
5547
Call ROM routine at 0BAAH to perform pointer relocation or adjustment operations on BC.
554A
POP AF F1
Restore the element count into A.
554B
DEC A 3D
Decrement the element count.
554C
If count is not zero, loop back to 5540H to process the next element.
All elements of this string processed. Continue to next string descriptor.
554F
Call 5558H to relocate the string data pointer itself.
5553
DEC DE 1B
Decrement DE.
5554
LD A,D 7A
Copy D into A.
5555
OR E B3
OR A with E to test if DE is zero.
5556
If DE is not zero, loop back to 554CH to continue processing.
5558
Jump back to 5527H to process the next string descriptor in the string space.
5558H - Relocate String Pointer
This small but critical routine relocates a single string pointer by adding an offset to it. It's called for each string variable and string array element to adjust pointers after the file buffer has been moved in memory.
5558
LD A,(HL) 7E
Load A with the string descriptor byte.
5559
OR A B7
Test if A is zero (empty string or special case).
555A
INC HL 23
Move to the pointer low byte.
555B
LD E,(HL) 5E
Load E with the string pointer low byte.
555C
INC HL 23
Move to the pointer high byte.
555D
LD D,(HL) 56
Load D with the string pointer high byte. DE now contains the old string pointer.
555E
INC HL 23
Move past the pointer.
555F
RET Z C8
If A was zero (empty string), return without relocating - there's no string data to point to.
Need to relocate this pointer. Load the offset and perform the calculation.
5560
LD (5576H),A 32 76 55
Store A at self-modifying code location 5576H for later use.
5563
PUSH HL E5
Save HL on the stack.
5564
LD HL,0000H 21 00 00
Load HL with an offset value. This is self-modifying code - the actual offset was stored here earlier.
5567
SBC HL,DE ED 52
Subtract the old pointer from the offset (HL = offset - old_pointer). This calculates the adjustment needed.
5569
If carry set (offset < old_pointer), jump to 5599H for special handling.
556B
LD HL,0000H 21 00 00
Load HL with another offset. This is self-modifying code.
556E
SBC HL,DE ED 52
Subtract DE from this second offset.
5570
If no carry (second_offset ≥ old_pointer), jump to 5599H.
The pointer is in the valid range for relocation. Add the adjustment offset.
5572
XOR A AF
Clear A to zero and clear carry flag.
5573
OR 00H F6 00
OR with a flag value. This is self-modifying code.
5575
LD A,00H 3E 00
Load A with a value. This is self-modifying code.
5577
If zero flag set, jump to 5580H for special handling.
5579
LD HL,0000H 21 00 00
Load HL with the relocation offset. This is self-modifying code.
557C
ADD HL,DE 19
Add the old pointer to the offset (HL = offset + old_pointer). This calculates the new relocated pointer.
557D
EX DE,HL EB
Exchange DE and HL. Now DE contains the new pointer.
557E
Jump to 5593H to write the new pointer back.
[SPECIAL CASE HANDLING] - Handle cases where the pointer needs different treatment.
5581
If A is not zero, jump to 5587H.
5583
LD D,A 57
Set D to A (zero).
5584
LD E,A 5F
Set E to A (zero). This creates a null pointer (0000H).
5585
Jump to 5593H to write the null pointer.
5588
Call routine at 28BFH to perform complex pointer calculation or string allocation.
558B
POP HL E1
Restore the saved pointer into HL.
558C
PUSH DE D5
Save the result in DE.
558D
LD C,A 4F
Copy A into C (contains a length or count).
558E
LD B,00H 06 00
Clear B. BC now contains the count.
5590
LDIR ED B0
Block move BC bytes from (HL) to (DE). This copies string data to a new location.
5592
POP DE D1
Restore the new pointer into DE.
Write the relocated pointer back to the variable descriptor.
5593
POP HL E1
Restore HL from the stack (points back to the variable descriptor).
5594
PUSH HL E5
Save HL again.
5595
DEC HL 2B
Move HL back to point at the pointer high byte position.
5596
LD (HL),D 72
Write the new pointer high byte from D.
5597
DEC HL 2B
Move to the pointer low byte position.
5598
LD (HL),E 73
Write the new pointer low byte from E. The pointer has been successfully relocated.
5599
POP HL E1
Restore HL from the stack.
559A
XOR A AF
Clear A to zero, setting flags.
559B
RET C9
Return to the caller with the string pointer relocation complete.
559CH - Additional Command Processing Entry Points
This section contains additional entry points for various file-related commands. The code handles command parsing and validation before dispatching to the appropriate handler routines.
559C
RST 08H CF
Call RST 08H (syntax check routine). This checks if the BASIC statement syntax is valid at the current position.
559D
INC L 2C
Increment L by 1. This appears to be data or a token value, not executable code.
559E
CP B6H FE B6
Compare A with B6H (BASIC token for a specific command or operator).
55A0
If not equal, jump to 1997H for syntax error handling.
The syntax is valid. Continue parsing the command parameters.
55A3
PUSH HL E5
Save HL (current parse position) on the stack.
55A4
RST 10H D7
Call RST 10H to perform comparison or validation.
55A5
Call DOS routine at 1B10H to parse the filename or command parameter.
55A8
POP DE D1
Restore the saved parse position into DE.
55A9
POP HL E1
Restore another saved value into HL.
55AA
PUSH BC C5
Save BC on the stack.
55AB
PUSH HL E5
Save HL on the stack.
55AC
Call DOS routine at 1B2CH to perform file operation or comparison.
55AF
If zero flag set (successful), jump to 55B3H.
55B1
LD H,B 60
Copy B into H.
55B2
LD L,C 69
Copy C into L. Transfer BC result into HL.
55B3
EX (SP),HL E3
Exchange HL with the top of stack.
55B4
RST 10H D7
Call RST 10H comparison routine.
55B5
If not zero, loop back to 55B4H. This creates a wait loop.
Processing complete. Close any open files and proceed.
55B7
Call file close routine at 5D9FH to close the current file if open.
55BA
POP HL E1
Restore HL from the stack.
55BB
POP DE D1
Restore DE from the stack.
55BC
Call 54C8H to read the file into the buffer.
55BF
Call 54DFH for post-read cleanup.
55C2
Jump to 5322H to continue processing or return to the command level.
55C5H - Alternative Command Entry Point
This is another entry point for file commands, likely handling a different syntax variant or command type.
55C5
Call DOS routine at 638FH to check the current character or token in the command line.
55C8
If zero flag set (specific character/token found), jump to 55E5H for alternate handling.
55CA
RST 08H CF
Call RST 08H for syntax checking.
55CB
LD B,C 41
Copy C into B. This appears to be a token value (41H = 'A').
55CD
If not zero (syntax error), jump to 1997H for error handling.
Check if there's sufficient stack space for the operation.
55D0
PUSH HL E5
Save HL on the stack.
55D1
LD HL,FE80H 21 80 FE
Load HL with FE80H (-384 decimal), a negative offset for stack checking.
55D4
ADD HL,SP 39
Add the stack pointer to HL (HL = SP - 384). This calculates a minimum safe stack boundary.
55D5
LD (5710H),HL 22 10 57
Store the stack limit at memory location 5710H for later checking.
55D8
LD DE,(40F9H) ED 5B F9 40
Load DE with the program end pointer from 40F9H.
55DC
RST 18H DF
Call RST 18H to compare HL with DE.
55DD
If carry set (insufficient memory), jump to 197AH for "Out of Memory" error.
55E0
POP HL E1
Restore HL from the stack.
55E1
XOR A AF
Clear A to zero.
55E2
Jump to 2B2EH to continue with command processing.
55E5H - Alternate File Buffer Processing
This code path handles an alternate method of processing the file buffer, possibly for a different command variant or when specific flags are set.
55E5
PUSH HL E5
Save HL on the stack.
55E6
LD HL,(40A4H) 2A A4 40
Load HL with the buffer start address from 40A4H.
55E9
DEC HL 2B
Move HL back one byte to point to a marker byte before the buffer.
55EA
LD C,(HL) 4E
Load C with the marker byte value.
55EB
LD (HL),FFH 36 FF
Store FFH at this location, marking the buffer as empty or invalid.
55ED
LD (5710H),HL 22 10 57
Store the buffer marker address at 5710H.
55F0
EX DE,HL EB
Exchange DE and HL.
55F1
LD HL,(40F9H) 2A F9 40
Load HL with the program end pointer.
55F4
DEC H 25
Decrement H (subtract 256), creating a safety margin.
55F5
OR A B7
Clear the carry flag.
55F6
SBC HL,DE ED 52
Subtract DE from HL to check available space.
55F8
PUSH AF F5
Save the flags from the comparison.
55F9
If no carry (sufficient space), jump to 55FEH.
Insufficient space. This appears to be incomplete code or an error condition.
55FB
LD (IX+00H),L DD 75 00
Store L at IX+00H in the FCB (File Control Block). This may update file status.
55FD
LD (DE),A 12
Store A at (DE).
Set up for reading input lines.
55FE
EX DE,HL EB
Exchange DE and HL.
55FF
LD DE,570DH 11 0D 57
Load DE with address 570DH (input/parse function pointer).
5602
Call routine at 4439H to set up the input function and get a line of input.
5605
LD (HL),C 71
Store C (the saved marker byte) back at (HL), restoring the buffer marker.
5606
If non-zero (error condition), jump to 5E16H for error handling.
[INPUT LOOP] - Read and process input lines until complete.
5609
INC H 24
Increment H (add 256 to the address).
560A
LD C,(HL) 4E
Load C with a byte from the input buffer.
560B
POP AF F1
Restore the flags from earlier.
560C
If carry set (from the earlier space check), jump to 5610H.
560E
If not zero, jump back to 55EDH to continue the input loop.
Input processing complete. Finalize and return.
5610
Call DOS routine at 6267H to perform final buffer processing or validation.
5613
LD (IX+11H),11H DD 36 11 00
Store 11H at offset 11H in the FCB. This sets a status or flag byte in the File Control Block.
5617
Call DOS routine at 6397H for additional processing.
561A
If zero flag set, loop back to 5617H. This waits for some operation to complete.
561C
POP HL E1
Restore HL from the stack.
561D
Jump to 2169H to return to the BASIC command interpreter or perform final cleanup.
5620H - NOP Padding Section
This section contains NOP (No Operation) instructions, providing padding to fill unused space in the module. This is common in ROM or fixed-size system modules to ensure proper alignment or to reserve space for future patches or expansion. The SYS19/SYS module ends at 56E7H, with the program entry point specified as 5200H.
5620-56E7
NOP 00 × 200
A series of 200 NOP instructions (00H bytes) padding the remainder of the SYS19/SYS module. This fills the space from 5620H through 56E7H with no-operation placeholders, ensuring the module occupies its allocated memory space.