SYS0/SYS is the core resident module of NEWDOS/80 v2.0 for the TRS-80 Model I. Loaded by the bootstrap routine from Track 0, Granules 1-3 (sectors 05-19), this module occupies memory from 4000H to 4CFFH and remains permanently resident throughout DOS operation, except for the DOS initialization routines in the overlay area which are overlaid when no longer needed. It provides the fundamental operating system services including disk I/O, file management, interrupt handling, and the command interface.
SYS0/SYS handles DOS initialization, disk I/O, clock interrupts, load of other system modules, keyboard intercept, etc.
SYS0/SYS resides in all the non-data areas from 4000H to 4CFFH and is located on Track 0 gran 1 of the DOS DISK and runs for 3 grans - sectors 05-19.
SYS0/SYS is actually comprised of a bunch of random snippets of code and so you will note Object Code load blocks being identified.
For lack of anywhere better to put this information, RST 28H is used heavily in NEWDOS/80 to call the various system files and the routines inside of them. A RST 28H call requires, at the very least, that Register A contain a value which is comprised of 3 binary parts: xxx yy zzz. zzz is the sector of the directory (less 2) to check for the system file. yy is the number of the system file in that directory sector. xxx is the function being called within that SYS file. The SYS file breakdown is:
Sector Read (4630H) - Reads 256-byte sectors with retry capability
Sector Write (463CH) - Writes sectors with optional verify
Directory Operations (492FH-496FH) - Search, read, and update directory entries
Extent Management (4875H-48F2H) - Handles file allocation via granule-based extents
Error Recovery - 3-retry mechanism for failed disk operations
Supervisor Call Interface (RST 28H)
The SVC mechanism uses a function code in Register A with the format xxx yy zzz:
zzz (bits 0-2): Directory sector minus 2
yy (bits 3-4): System file number within that sector
xxx (bits 5-7): Function number within the SYS file
This allows access to 8 directory sectors × 3 files × 8 functions = 192 possible system calls.
Device Driver Chain (4ADBH)
Installable device drivers are linked in a chain structure:
Each entry contains: device code (2 bytes), flags, handler address, next link
Drivers are searched sequentially until a matching device code is found
The chain terminates with marker byte C0H
Allows runtime extension of I/O capabilities
Interrupt Handler (45F2H)
The interrupt service routine handles:
Timer Ticks - Increments system clock at 4040H
Time Updates - Cascades seconds→minutes→hours→date via callback at 44CDH
Keyboard Scanning - Processes keyboard input during interrupts
Disk Motor Timeout - Manages drive motor shutoff timing
Variables:
Address
Size
Description
4040H
1
Timer tick counter
4041H-4043H
3
Date storage (Year, Month, Day)
4044H-4046H
3
Time storage (Hours, Minutes, Seconds)
4049H
2
High memory pointer
4369H
1
Driver status flags (bit 6 = output in progress)
4370H
1
Disk parameter from boot sector
4380H
-
IY base pointer - DOS system area
439FH
1
Maximum drive number
43ABH
1
Warm boot signature (A5H when booted)
43ACH
6
Date/time backup for warm restart
43DCH
2
Cached driver address
Error Codes
Code
Meaning
11H
Disk read error
12H
Disk write error
1CH
Position error (before start)
1DH
Position error (past EOF)
22H
Invalid module type
24H
Memory write error
25H
Access denied
27H
System disk error
2AH
General error
2BH
SVC error
2CH
Directory full
2DH
File not found
2EH
Device not ready
34H
Parse error
Some Common Calls:
Directory Entry Search
This routine scans the disk directory for a file specification or attempts to locate the next entry after a successful search. It is a fundamental component of commands like DIR, PURGE, and KILL.
Routine:
Directory Entry Search
Address:
495EH (Common entry point for file search)
Description:
Searches the disk directory for a file entry matching the name provided in the FCB pointed to by IX. Upon completion, it leaves the directory entry information available in a work buffer. This is used to implement DIR, PURGE, and KILL commands. If found, returns A=00H and updates the FCB. If not found, returns an error code in A.
Variable
Entry
Exit
Description
IX
Required: Pointer to the File Control Block (FCB) containing the target file name.
Modified: The FCB pointed to by IX is updated with the directory entry information.
File Control Block pointer.
HL
Required (For iteration): Must point to the start of the current directory sector buffer.
Modified: Used internally; its final value is not typically relied upon by the caller.
Directory buffer pointer.
A
N/A
Set: A=00H on success (file found), A=XXH (error code) if not found.
Status/Error register.
Flags
N/A
Set: Z FLAG set on success (A=00H), NZ FLAG set on error.
Status flags (Z, C, etc.).
Sector Read Primitive
This routine is the lowest-level logical I/O function, responsible for reading a 256-byte sector from the disk controller into a specified memory buffer. High-level routines like file search, file read, and GAT access rely on this primitive.
Routine:
Sector Read Primitive
Address:
4630H (SectorRead)
Description:
Reads a single 256-byte sector from the specified track and sector into a memory buffer. This routine includes the standard 3-retry mechanism for disk I/O errors and reports the result via the Carry flag.
Function
Reads the sector identified by the Track, Sector, and Drive into the buffer pointed to by BC. Returns success/failure via the Carry flag and the status code in A.
Variable
Entry
Exit
Description
A
Required: Disk Drive number (01H-04H).
Modified: Contains the disk status/error code on exit.
Drive number/Status register.
HL
Required: Track number (00H-23H).
Modified: Preserved after the call (but may be volatile).
Track number register.
DE
Required: Sector number (01H-1AH).
Modified: Preserved after the call (but may be volatile).
Sector number register.
BC
Required: Starting address of the 256-byte memory buffer where the sector data is stored.
Modified: Used internally, usually preserved across the call.
Buffer address register.
Flags
N/A
Set: C FLAG clear on success (read OK), C FLAG set on error (read failed after retries).
Status flags (Z, C, etc.).
Character Output Handler
Routine:
Character Output Handler
Address:
4BC2H (CharOut_Main)
Description:
The primary low-level routine responsible for displaying a single 8-bit ASCII character to the currently active console device (e.g., screen or printer). This routine is essential for all text output.
Function
Accepts an ASCII character in A and routes it to the currently active console device.
Variable
Entry
Exit
Description
A
Required: The 8-bit ASCII character to be displayed.
Modified: Contents are passed through and modified.
Character input/output register.
Flags
N/A
Modified: Flags are changed by the routine's operations.
Status flags (Z, C, etc.).
Hex to ASCII Conversion (8-bit)
Routine:
Hex to ASCII Conversion (8-bit)
Address:
4068H (HexToAscii8)
Description:
Converts an 8-bit binary value into its 2-character hexadecimal ASCII string equivalent.
Function
Converts the 8-bit value in A into its 2-character ASCII hexadecimal equivalent, storing the result at the address pointed to by HL.
Variable
Entry
Exit
Description
A
Required: The 8-bit binary value to convert.
Modified: Holds the last converted ASCII character.
8-bit value input register.
HL
Required: Pointer to the destination memory buffer where the ASCII string (2 bytes) will be stored.
Modified: Incremented by 2; points past the stored string.
Output buffer address pointer.
B, C
N/A
Modified: Used as scratchpad and modified.
General purpose registers (used for loop/scratchpad).
Flags
N/A
Modified: Flags are changed by the routine's operations.
Status flags (Z, C, etc.).
FCB Open/Close Primitive
This is the high-level Disk SVC routine used to perform file opening and closing operations. SYS4 (ATTRIB) uses this to open files for reading/modifying attributes, and SYS5 (DEBUG) may call it indirectly when loading or saving blocks.
Routine:
File Control Block Open/Close Primitive
Address:
46D8H (Common entry point, often dispatched via RST 28H with A=01H or A=02H)
Description:
Handles the high-level logic for opening a file (locating the directory entry, reading the GAT, and preparing the FCB for I/O) or closing a file (writing updated GAT/Directory data, if necessary).
Function
Executes the file system operation specified by A on the file defined by the FCB at IX, typically managing GAT and Directory information.
Variable
Entry
Exit
Description
A
Required: Function Code (e.g., A=01H for OPEN, A=02H for CLOSE).
Set: A=00H on success; A=XXH (error code) if the operation failed.
Function code/Status register.
IX
Required: Pointer to the File Control Block (FCB) defining the file name and I/O state.
Modified: FCB fields (like GAT cluster, record pointer) are updated on entry and exit.
File Control Block pointer.
Flags
N/A
Set: Z FLAG set on success (A=00H), NZ FLAG set on error. C FLAG may be used for status.
Status flags (Z, C, etc.).
String Compare
This is a low-level memory utility essential for parsing command line arguments and comparing strings (like file names, extensions, or command keywords). SYS4 uses it to compare input strings for attributes (SET, RESET), and SYS5 uses it heavily for command parsing (D, M, R, etc.).
Routine:
String Compare (HL vs. DE)
Address:
43BCH (Common entry point for a general-purpose string compare utility)
Description:
Compares two strings in memory, character by character, until a mismatch is found or a specified length is reached. Used widely for DOS command parsing and file operations. Compares BC bytes starting at HL with bytes starting at DE. Returns the result of the comparison via the Z80 Flag Register.
Variable
Entry
Exit
Description
HL
Required: Pointer to the first string.
Modified: Incremented during comparison; points past the last byte compared.
Pointer to String 1.
DE
Required: Pointer to the second string.
Modified: Incremented during comparison; points past the last byte compared.
Pointer to String 2.
BC
Required: The maximum number of bytes to compare.
Modified: Decremented during comparison; returns number of bytes remaining.
Length counter.
Flags
N/A
Set: Z FLAG set if the strings are identical for the length specified. C FLAG and sign flags set based on the first differing character (A-B).
Status flags (Z, C, etc.).
DOS Error Handler/Return Vector
While not a standard function, this is the guaranteed exit point that all commands eventually use to return control to the main DOS prompt after completing execution or encountering an error. All SYS files will eventually jump or call back to this address.
Routine:
DOS Error and Exit Handler (Vector)
Address:
400FH (DOS Jump Table Entry Point)
Description:
This is the primary vector used by overlay files (SYS1-SYS5) to return control to the resident DOS kernel, either upon successful command completion or following an error. It handles setting up the prompt and waiting for the next command. Receives control from an executing DOS command, processes any potential error code in A, re-initializes the DOS environment, displays the command prompt, and awaits the next user input.
Variable
Entry
Exit
Description
A
Optional: If returning with an error, A should contain the error code (non-zero). If successful, it's often 00H or ignored.
Modified: Contents are typically cleared or used for internal status.
Error code/Status register.
All Registers
N/A
Restored/Cleared: All registers are usually modified or ignored as the routine re-initializes DOS state.
All general-purpose registers.
Flags
N/A
Modified: Flags are changed as DOS state is reset.
Status flags (Z, C, etc.).
Memory Move/Block Copy
This routine is the backbone of any large data operation, like moving file contents, copying sectors, or shifting buffers. It is heavily utilized by disk utilities like SYS6 (BACKUP) and SYS7 (FORMAT) for block-level data manipulation.
Routine:
Memory Block Copy (HL to DE)
Address:
43B7H (Common entry point for a general-purpose memory copy utility)
Function:
Copies BC bytes from the memory location starting at HL to the location starting at DE. Note: This is a non-overlapping copy (for overlapping moves, a different routine or technique is usually required). This is a faster alternative to LDIR when registers are already set up.
Variable
Entry
Exit
Description
HL
Required: Pointer to the source memory block (start of data to be copied).
Modified: Incremented during copy; points past the last byte copied.
Source memory pointer.
DE
Required: Pointer to the destination memory block (where data is written).
Modified: Incremented during copy; points past the last byte written.
Destination memory pointer.
BC
Required: The number of bytes to copy (the length of the block).
Modified: Decremented until zero (loop counter).
Length counter.
Flags
N/A
Modified: Flags are changed by the routine's operations.
Status flags (Z, C, etc.).
Set/Change Disk Drive
All disk commands (BACKUP, FORMAT, COPY, DIR, etc.) must first communicate the target drive number to the resident kernel so that subsequent disk I/O calls (like the Sector Read/Write Primitives) operate on the correct physical drive.
Routine:
Set Current Disk Drive
Address:
4B67H (Common entry point for setting the active drive)
Description:
Sets the internal DOS variables to specify which disk drive (0-3 or 1-4) is the currently active one for all subsequent disk I/O operations. This must be called before using disk primitives. Updates the resident DOS kernel's state variables to designate the drive specified in A as the current working drive. Returns status via the Carry flag.
Variable
Entry
Exit
Description
A
Required: The desired physical drive number (typically 00H for Drive 0, 01H for Drive 1, etc.).
Modified: Typically preserved, or may contain an internal status code.
Drive number/Status register.
C
N/A
Modified: Often used as scratchpad or holds a register value.
General purpose register.
Flags
N/A
Set: C FLAG is often cleared on success, set on error (e.g., if the drive is invalid/not mounted).
Status flags (Z, C, etc.).
Disassembly
400CH - DOS Jump Table Entry Points
This is the beginning of the DOS communication region. These jump vectors allow programs to access DOS services at fixed addresses regardless of internal code changes between versions.
JUMP to device driver chain handler. After displaying ready prompt, process any pending driver requests.
4036H-403DH - NO CODE
The disassembly I had did not have any code showing in this region. Just skipped right over it.
403EH - System Variables and Counters
This area contains system variables used by the DOS. The NOPs represent zero-initialized storage locations. At runtime, these hold timer counts, cursor positions, and state flags.
403E
NOP 00
Reserved byte (system variable storage).
403F
NOP 00
Reserved byte.
4040
NOP 00
Timer tick counter - incremented by interrupt handler at 4610H.
4041
NOP 00
Date/time storage: Year (low byte).
4042
NOP 00
Date/time storage: Month.
4043
NOP 00
Date/time storage: Day.
4044
NOP 00
Time storage: Hours.
4045
NOP 00
Time storage: Minutes.
4046
NOP 00
Time storage: Seconds.
4047
NOP 00
Reserved.
4048
LD D,D 52
Data byte 52H ('R' in ASCII) - part of version string or identifier.
4049
RST 38H FF
High memory pointer (low byte) - set during boot to top of available RAM.
404A
RST 38H FF
High memory pointer (high byte).
404B
NOP 00
Reserved byte.
404C
NOP 00
Reserved byte.
404D
NOP 00
Reserved byte.
404E
NOP 00
Reserved byte.
404F
NOP 00
Reserved byte.
4050
NOP 00
Reserved byte.
4051
NOP 00
Reserved byte.
4052
NOP 00
Reserved byte.
4053H - Disk Interrupt Handler Hook (unpatched)
This small routine is called during disk operations to handle FDC interrupts. It checks if carry flag is set (indicating a disk event) and calls the appropriate handler.
4053
NOP 00
NO OPERATION (Unpatched Code)
4054
NOP 00
NO OPERATION (Unpatched Code)
4055
NOP 00
NO OPERATION (Unpatched Code)
4056
NOP 00
NO OPERATION (Unpatched Code)
4057
NOP 00
NO OPERATION (Unpatched Code)
4058
NOP 00
NO OPERATION (Unpatched Code)
4059
NOP 00
NO OPERATION (Unpatched Code)
Patched
PATCH PURPOSE: This patch adds critical FDC (Floppy Disk Controller) interrupt handling that was absent in the original release. Without this code, disk interrupts could cause the FDC status register to overflow with unread status bytes, leading to missed interrupts and disk I/O errors. The patch checks if a drive is currently selected (via RLCA moving bit 7 to carry), and if so, calls 47E8H to read and clear the FDC status register, preventing status accumulation and ensuring reliable disk operations.
4053
PUSH AF F5
Save Register A and Flags onto the stack (preserve caller's state). (Patched Code)
4054
RLCA 07
Rotate Register A left through carry. This shifts bit 7 into the Carry flag to test drive select status. (Patched Code)
If CARRY FLAG is set (drive active), GOSUB to 47E8H to read FDC status register. (Patched Code)
4058
POP AF F1
Restore Register A and Flags from the stack. (Patched Code)
4059
RET C9
RETURN to caller. (Patched Code)
405AH - Nothing!
405A
NOP 00
Reserved byte.
405B
NOP 00
Reserved byte.
405C
NOP 00
Reserved byte.
405DH-4062H - NO CODE
The disassembly I had did not have any code showing in this region. Just skipped right over it.
4063H - Hex to ASCII Conversion Routine
This routine converts a 16-bit value in DE to a 4-character hexadecimal ASCII string stored at the address in HL. It processes the high byte (D) first, then the low byte (E).
4063
LD A,D 7A
Load Register A with the high byte of the value to convert (from Register D).
The disassembly I had did not have any code showing in this region. Just skipped right over it.
4368H - DOS System Variables and FCB Storage
This area contains DOS system variables, drive parameter blocks, and FCB (File Control Block) templates. Many values are initialized at boot time from the disk's boot sector.
4368
AND L A5
Data byte A5H - DOS signature/marker byte.
4369
LD B,B 40
Data byte 40H - system flag.
436A
NOP 00
Reserved storage.
436B
NOP 00
Reserved storage.
436C
NOP 00
System option flags (low) - loaded from boot sector.
436D
NOP 00
System option flags (high).
436E
NOP 00
Extended system flags (low).
436F
NOP 00
Extended system flags (high).
4370
LD E,D 5A
Data byte 5AH - disk parameter loaded from 42A8H.
4371
LD DE,0323H 11 23 03
Drive parameter block pointer (initialized at boot).
Drive 0 FCB+05: Sector position (FFH = uninitialized).
4386
LD BC,0100H 01 00 01
Drive 1 parameter block.
4389
NOP 00
Drive 1 status.
438A
NOP 00
Drive 1 reserved.
438B
NOP 00
Drive 1 reserved.
438C
NOP 00
Drive 1 reserved.
438D
RST 38H FF
Drive 1 FCB buffer (uninitialized).
438E
NOP 00
Drive 1 FCB.
438F
RST 38H FF
Drive 1 FCB (uninitialized).
4390
LD BC,0100H 01 00 01
Drive 2 parameter block.
4393
NOP 00
Drive 2 status.
4394
NOP 00
Drive 2 reserved.
4395
NOP 00
Drive 2 reserved.
4396
NOP 00
Drive 2 reserved.
4397
RST 38H FF
Drive 2 FCB (uninitialized).
4398
NOP 00
Drive 2 FCB.
4399
LD (HL),C 71
Data byte 71H - pointer reference.
439A
LD B,E 43
Data byte 43H - high byte of 4371H pointer.
439B
NOP 00
Reserved.
439C
NOP 00
Reserved.
439D
NOP 00
Reserved.
439E
NOP 00
Reserved.
439F
INC B 04
Data byte 04H - max drive number (loaded from 42A0H).
43A0
LD BC,0100H 01 00 01
Drive 3 parameter block (or system param loaded from 42A2H/42A3H).
43A3
NOP 00
Reserved.
43A4
LD BC,0000H 01 00 00
Additional parameters.
43A7
DEC C 0D
Data byte.
43A8
DEC C 0D
Data byte.
43A9H-43B1H - High Memory Pointer
Contains the high memory pointer determined at boot time, and warm boot signature area.
43A9
NOP 00 00
High memory address (2 bytes) - set during RAM detection.
43AB
NOP 00
Warm boot signature - set to A5H after first boot.
43AC
NOP 00 00 00 00 00 00
Date/time backup (6 bytes) - saved during boot for warm restart.
43B2H - Device Driver Chain and System Buffers
Device driver chain storage and additional system FCB templates for drives.
43B2
NOP 00
Device driver chain area start.
43B3
NOP 00
Driver chain link.
43B4
NOP 00
Driver flags.
43B5
RST 38H FF
Driver address (uninitialized).
43B6
RST 38H FF
Driver address high.
43B7-43B9
DB 00 00 00
NO OPERATION (Unpatched Code)
Patched
43B7-43B9
DB FCH,4CH,00H FC 4C 00
Driver callback pointer: 4CFCH (delay routine) + flags. Used by device driver chain for timing/delay callbacks during I/O operations. (Patched Code)
43BA
NOP 00
Reserved.
43BB
NOP 00
Reserved.
43BC
RST 38H FF
FCB template (uninitialized).
43BD
RST 38H FF
FCB template.
43BE
NOP 00
FCB reserved.
43BF
NOP 00
FCB reserved.
43C0
NOP 00
FCB reserved.
43C1
NOP 00
FCB reserved.
43C2
NOP 00
FCB reserved.
43C3
RST 38H FF
FCB extent (uninitialized).
43C4
RST 38H FF
FCB extent.
43C5
NOP 00
FCB reserved.
43C6
NOP 00
FCB reserved.
43C7
NOP 00
FCB reserved.
43C8
NOP 00
FCB reserved.
43C9
NOP 00
FCB reserved.
43CA
RST 38H FF
FCB extent.
43CB
RST 38H FF
FCB extent.
43CC
NOP 00
FCB reserved.
43CD
NOP 00
FCB reserved.
43CE
ADD A,B 80
Data byte 80H - driver load buffer reference.
43CF
JR Z,43D1H 28 00
Data bytes.
43D1
NOP 00
Reserved.
43D2
LD B,D 42
Data byte 42H - buffer page reference.
43D3
NOP 00
Reserved.
43D4
NOP 00
Reserved.
43D5
RST 38H FF
Uninitialized marker.
43D6
NOP 00
Reserved.
43D7
NOP 00
Reserved.
43D8
NOP 00
Device state - cleared during driver setup.
43D9
NOP 00
Reserved.
43DA
LD B,B 40
Data byte 40H.
43DB
NOP 00
Reserved.
43DC
NOP 00 00
Driver address storage (2 bytes) - written by 4BFFH.
43DE
RST 38H FF
Uninitialized marker.
43DF
RST 38H FF
Uninitialized marker.
43E0H-43FFH - No Code
The disassembly I had did not have any code showing in this region. Just skipped right over it.
4400H - DOS Ready / Warm Start Handler
This is the warm start entry point (jumped to from 402DH). It resets the system state and displays the DOS Ready prompt. Various SVC functions are called via RST 28H.
4400
LD A,23H 3E 23
Load Register A with SVC function 23H (Clear screen or reset display).
4402
RST 28H EF
Execute Supervisor Call - clears screen and initializes display.
4403
NOP 00
Padding (SVCs can have parameter bytes after them).
4404
NOP 00
Padding.
4405
LD A,63H 3E 63
Load Register A with SVC function 63H (Display "READY" message).
4407
RST 28H EF
Execute Supervisor Call - displays the DOS Ready prompt.
4408
RET Z C8
If Z FLAG is set (no error), RETURN. Otherwise fall through to error handling.
4409
PUSH AF F5
Save Register A (error code) onto the stack.
440A
LD A,26H 3E 26
Load Register A with SVC function 26H (Display error message).
440C
RST 28H EF
Execute Supervisor Call - displays the error message for the code pushed earlier.
This area contains the default FCB template and sector buffer space. Boot sector data is read into this area at 4480H.
4480
ADD A,D 82
Data byte 82H - FCB status flags.
4481
JR NZ,4483H 20 00
Data bytes - FCB flags/conditional.
4483
NOP 00
FCB reserved.
4484
LD B,D 42
Data byte 42H - buffer page reference.
4485
NOP 00
FCB reserved.
4486
NOP 00
FCB reserved.
4487
RST 38H FF
FCB buffer (uninitialized).
4488
NOP 00
FCB reserved.
4489
NOP 00
FCB reserved.
448A
LD (BC),A 02
Data byte.
448B
NOP 00
FCB reserved.
448C
RST 38H FF
FCB extent (uninitialized).
448D
RST 38H FF
FCB extent.
448E
RST 38H FF
FCB extent.
448F
RST 38H FF
FCB extent.
4490
RST 38H FF
FCB extent.
4491
RST 38H FF
FCB extent.
4492
RST 38H FF
FCB extent.
4493
RST 38H FF
FCB extent.
4494
RST 38H FF
FCB extent.
4495
RST 38H FF
FCB extent.
4496
RST 38H FF
FCB extent.
4497
RST 38H FF
FCB extent.
4498
RST 38H FF
FCB extent.
4499
RST 38H FF
FCB extent.
449A
RST 38H FF
FCB extent.
449B
RST 38H FF
FCB extent.
449C
RST 38H FF
FCB extent.
449D
RST 38H FF
FCB extent.
449E
RST 38H FF
FCB extent.
449F
RST 38H FF
FCB extent (end of 32-byte FCB).
44A0
NOP 00
Reserved.
44A1
NOP 00
Reserved.
44A2
JR Z,44A5H 28 01
Conditional jump (data/code).
44A4
LD HL,3C35H 21 35 3C
Load HL with 3C35H - video RAM position for date display.
44A7H - Display Date Routine
This routine displays the current date by converting the binary values at 4041H-4043H to ASCII and writing them to video RAM at 3C35H (second row of screen).
44A7
LD DE,4043H 11 43 40
Point DE to day counter at 4043H (the date storage area, starting with day).
44AA
LD B,3AH 06 3A
Load Register B with 3AH (ASCII colon ':'). This is the separator character.
44AC
LD C,03H 0E 03
Load Register C with 3 - we have 3 fields to convert (DD/MM/YY or MM/DD/YY).
[LOOP START] - Convert each date component (day, month, year) to two ASCII digits.
44AE
LD (HL),2FH 36 2F
Store '/' (2FH) at current position. This gets incremented to become the first digit.
44B0
LD A,(DE) 1A
Fetch the current date component (day/month/year) from the address in DE.
44B1
INC (HL) 34
[INNER LOOP] INCrement the tens digit character at (HL).
44B2
SUB 0AH D6 0A
SUBtract 10 from A. Each subtraction represents one "tens" digit.
JUMP to the shared conversion loop (reuses code at 44ACH).
44C9H - Timer Callback Table
This is the timer callback table used by the interrupt handler. Contains pointers to routines called on timer ticks.
44C9
EX DE,HL EB
Data byte EBH - callback table entry or opcode.
44CA
LD B,H 44
Data byte 44H - high byte of callback address.
44CB
JR Z,44CEH 28 01
Jump over next byte if Z flag set (or data bytes).
44CDH - Increment Time Counter
This routine increments the system time. It handles rollover from seconds→minutes→hours and uses the limit values at 407CH. Called by the interrupt handler.
44CD
LD HL,4041H 21 41 40
Point HL to the time storage area starting at 4041H (year, but we work on seconds first).
44D0
PUSH HL E5
Save HL onto the stack for later restoration.
44D1
LD DE,43ACH 11 AC 43
Point DE to backup/restore area at 43ACH.
44D4
LD BC,0006H 01 06 00
Set BC to 6 bytes (year, month, day, hour, minute, second).
44D7
LDIR ED B0
Block copy: backup current date/time from (HL) to (DE), 6 bytes.
44D9
LD DE,407CH 11 7C 40
Point DE to time limits table at 407CH (59, 59, 23 for sec, min, hour).
44DC
POP HL E1
Restore HL (points to 4041H, but we need seconds at 4046H).
44DD
LD B,03H 06 03
Load B with 3 - three time fields to potentially increment (sec, min, hour).
[LOOP START] - Try to increment each time field, checking for rollover.
44DF
INC (HL) 34
INCrement the current time field (seconds first).
44E0
LD A,(DE) 1A
Fetch the maximum value for this field from the limits table.
44E1
SUB (HL) 96
SUBtract current value from max. If result is negative (carry), we haven't exceeded limit.
44E2
RET NC D0
If NO CARRY (current ≤ max), no rollover needed - RETURN.
44E3
LD (HL),C 71
Reset this field to C (which is 0 from the LDIR operation) - rollover!
GOSUB to routine at 4853H to perform character conversion or processing.
450A
LD A,C 79
Load Register A with the value in Register C (converted character).
450B
SUB 20H D6 20
SUBtract 20H (32 decimal - space character) from Register A.
450D
CP 60H FE 60
Compare Register A against 60H (96 decimal). If A < 60H, the CARRY FLAG is set.
450F
LD A,C 79
Load Register A with the original character from Register C.
4510
JP C,047DH DA 7D 04
If the CARRY FLAG has been set (character is in valid range), JUMP to 047DH for output.
4513
JP 0458H C3 58 04
JUMP to ROM routine at 0458H for character handling.
4516H - Keyboard BREAK Check
This routine checks for special key combinations and handles the BREAK key. Used by the keyboard scanner during disk operations and other interruptible processes.
4516
LD A,(4369H) 3A 69 43
Fetch system flags from 4369H to check current operating mode.
DECrement A (if we reach here, A was 0, so now A = FFH).
453E
LD (4573H),A 32 73 45
Store A (now FFH) into memory location at 4573H.
4541
LD (HL),00H 36 00
Clear the keyboard state storage at (HL) by storing 0.
4543H - Keyboard Scan Loop
This section scans the keyboard matrix by reading each row (at memory-mapped addresses 3801H-3880H) and comparing with previous state to detect key presses.
4543
LD L,36H 2E 36
Load L with 36H. Combined with H=40H from context, HL points to keyboard shadow buffer at 4036H.
4545
LD BC,3801H 01 01 38
Load BC with 3801H - the first keyboard row address (@ A B C D E F G).
4548
LD D,FFH 16 FF
Load D with FFH - used as key code counter/index, starts at -1.
[KEYBOARD SCAN LOOP] - Read each keyboard row and detect changes.
454A
LD A,(BC) 0A
Read the current keyboard row from the memory-mapped address in BC.
454B
LD E,A 5F
Copy current row state to E.
454C
XOR (HL) AE
XOR with previous state in shadow buffer - result shows changed keys.
454D
LD (HL),E 73
Update shadow buffer with current state.
454E
AND E A3
AND with current state - isolates newly pressed keys (not released).
If Z FLAG (no valid key), JUMP to cleanup at 4589H.
Performs keyboard character filtering and case conversion, checking for special key combinations and applying appropriate transformations to the input character.
4571
LD A,H 7C
Load Register A with the value from Register H.
4572
CP FFH FE FF
Compare Register A against FFH. If Register A equals FFH, the Z FLAG is set; otherwise the NZ FLAG is set.
4574
LD (4573H),A 32 73 45
Store the value held in Register A into memory location 4573H. [SELF-MODIFYING CODE] This modifies the immediate operand of the CP instruction at 4572H.
If the Z FLAG has been set (result is zero), LOOP BACK to 456DH to continue keyboard scanning.
457F
LD A,FFH 3E FF
Load Register A with FFH (all bits set).
4581
LD (4537H),A 32 37 45
Store the value held in Register A into memory location 4537H. [SELF-MODIFYING CODE] This modifies code in an earlier routine.
4584
LD A,02H 3E 02
Load Register A with 02H.
4586
LD (4580H),A 32 80 45
Store the value held in Register A into memory location 4580H. [SELF-MODIFYING CODE] This modifies the immediate value of the LD A,00H instruction at 4577H, changing it to LD A,02H.
If the Z FLAG has been set (character is 1FH), JUMP to 45B0H to clear Register A and return.
4593
RET C9
RETURN to caller with processed character in Register A.
4594H - Character Case Conversion Handler
This routine handles character case conversion, checking for alphabetic characters and applying uppercase conversion or toggling case based on shift key state. It includes self-modifying code to enable/disable the case toggle feature.
4594
AND DFH E6 DF
AND Register A with DFH (11011111 binary). This clears bit 5, which converts lowercase letters to uppercase (since ASCII lowercase and uppercase differ only in bit 5).
4596
SUB 41H D6 41
SUBtract 41H (ASCII A) from Register A. This normalizes the character to check if it's in the A-Z range.
4598
CP 1AH FE 1A
Compare Register A against 1AH (26 decimal). If Register A < 1AH, the CARRY FLAG will be set. If Register A >= 1AH, the NO CARRY FLAG will be set. This tests if the normalized value is within the alphabetic range (0-25 = A-Z).
459A
LD A,C 79
Load Register A with the value from Register C (restoring the original character).
If the CARRY FLAG has been set (character is alphabetic A-Z), JUMP to 45B2H to apply case toggle.
[NON-ALPHABETIC PATH] - Character is not A-Z, check if it's a space character.
459D
CP 20H FE 20
Compare Register A against 20H (ASCII space character). If Register A equals 20H, the Z FLAG is set; otherwise the NZ FLAG is set.
459F
RET NZ C0
If the NZ FLAG has been set (not a space), RETURN to caller with character unchanged.
[SPACE KEY HANDLER] - Check shift key state and toggle case conversion mode.
45A0
LD HL,387FH 21 7F 38
Point Register Pair HL to 387FH (keyboard row 7, first half - SHIFT key status).
45A3
LD A,(HL) 7E
Fetch the shift key status byte from 387FH.
45A4
INC HL 23
INCrement HL to point to 3880H (keyboard row 7, second half).
45A5
AND (HL) A6
AND with the value at 3880H to combine both shift key status bytes.
45A6
RRCA 0F
Rotate Register A right through carry. This moves bit 0 into the CARRY FLAG to test the shift key state.
45A7
LD A,C 79
Load Register A with C (restoring the space character).
45A8
RET NC D0
If the NO CARRY FLAG has been set (shift not pressed), RETURN with space character unchanged.
[SHIFT+SPACE DETECTED] - Toggle the case conversion mode by modifying code.
45A9
LD HL,45B4H 21 B4 45
Point Register Pair HL to 45B4H (the RET instruction that may be toggled).
45AC
LD A,(HL) 7E
Fetch the current instruction byte at 45B4H.
45AD
XOR C9H EE C9
XOR with C9H (RET opcode). [SELF-MODIFYING CODE] This toggles the instruction between RET (C9H) and another value, effectively enabling/disabling the case toggle feature.
45AF
LD (HL),A 77
Store the modified instruction byte back to 45B4H.
45B0
XOR A AF
Set Register A to ZERO and clear all flags.
45B1
RET C9
RETURN to caller with zero in Register A (suppressing the space character output).
45B2
XOR 20H EE 20
XOR Register A with 20H (00100000 binary). This toggles bit 5, which swaps the case of alphabetic characters (uppercase becomes lowercase and vice versa).
45B4
RET C9
RETURN to caller with case-toggled character in Register A. [MODIFIABLE INSTRUCTION] This byte is modified by the code at 45ADH-45AFH.
45B5H - Lowercase to Uppercase Conversion
This standalone routine converts lowercase letters (a-z) to uppercase (A-Z) by testing the character range and subtracting 20H if it's a lowercase letter.
45B5
CP 61H FE 61
Compare Register A against 61H (ASCII a). If Register A < 61H, the CARRY FLAG will be set. If Register A >= 61H, the NO CARRY FLAG will be set.
45B7
RET C D8
If the CARRY FLAG has been set (character is less than a), RETURN with character unchanged.
45B8
CP 7BH FE 7B
Compare Register A against 7BH (ASCII {, one past z). If Register A < 7BH, the CARRY FLAG will be set. If Register A >= 7BH, the NO CARRY FLAG will be set.
45BA
RET NC D0
If the NO CARRY FLAG has been set (character is 7BH or greater), RETURN with character unchanged.
[LOWERCASE DETECTED] - Character is in range a-z, convert to uppercase.
45BB
SUB 20H D6 20
SUBtract 20H from Register A. This converts lowercase to uppercase (since ASCII lowercase = uppercase + 20H).
45BD
RET C9
RETURN to caller with uppercase character in Register A.
45BE
NOP 00
Instruction set to either NOP or RET, so when called during interrupt handler will Check System Flags or return immediately [MODIFIABLE INSTRUCTION].
45BFH - Check System Flags
This routine checks system flags to determine operating mode and whether certain features are enabled.
45BF
LD HL,4369H 21 69 43
Point HL to system flags byte at 4369H.
45C2
LD A,(HL) 7E
Fetch the system flags.
45C3
AND 6CH E6 6C
Mask with 6CH (bits 2, 3, 5, 6). Tests specific condition flags.
This routine performs keyboard scanning and system state verification during interrupt or system operations. It invokes a DOS supervisor call to clean up the stack by removing two return addresses (unwinding nested call chains), then checks specific keyboard rows for break conditions or special key sequences. The routine also validates whether certain system locations have been patched, allowing for hook detection and alternate code paths. This is typically called during interrupt handling or system state transitions.
45CE
LD A,E3H 3E E3
Load Register A with E3H. This is the function code for RST 28H Supervisor Call: • SVC function E3H = SYS1/SYS, Function 7 (Directory Sector 05H, file position 0, function 7) • Binary breakdown: 111 00 011 (function 7, file 0, directory sector 3+2=5) • Function 7 executes the "Double POP and Exit" routine at 4D78H in SYS1
45D0
LD C,04H 0E 04
Load Register C with 04H. This dispatch counter parameter tells the SYS1 overlay which specific function to execute. With C=04H, the SYS1 dispatcher at 4D00H will decrement C four times through its dispatch chain to reach function 7.
45D2
RST 28H EF
Execute Supervisor Call. This invokes the DOS system service dispatcher which: • Loads the SYS1/SYS overlay module into memory at 4D00H-51FFH • Dispatches to function 7 based on the C=04H countdown mechanism • Function 7 (at 4D78H) executes: POP AF, POP AF, then JR 4D8BH • This removes two return addresses from the stack, effectively unwinding nested call chains • Then performs standard exit processing (checking DOS-CALL and MINI-DOS states)
After the SVC call completes and the stack has been cleaned up by removing two return addresses, check keyboard input to detect special key combinations or break conditions.
45D3
LD A,(3810H) 3A 10 38
Fetch the current state of keyboard row 4 from memory address 3810H. This row contains keys: 01234567. Each bit represents one key (active LOW on Model I - pressed key = 0 bit).
45D6
CP 0EH FE 0E
Compare Register A against 0EH (00001110 binary). If Register A equals 0EH, the Z FLAG is set; otherwise the NZ FLAG is set. This checks for a specific key combination: bit 0 set (key 0 not pressed), bits 1-3 clear (keys 123 pressed), bit 4 set (key 4 not pressed).
JUMP (unconditional relative jump) to 45E8H to continue keyboard checking with row 1. This skips over the alternate patch-detection path.
[ALTERNATE PATH - PATCH DETECTION] The following code at 45DAH is reached by falling through from earlier code (not shown in this section). This performs a system integrity check by detecting whether a routine has been hooked or patched by third-party software.
45DA
LD A,(45BEH) 3A BE 45
Fetch the byte stored at memory address 45BEH into Register A. This location is being checked to determine if a system routine has been patched or hooked by user software or extensions.
45DD
SUB C9H D6 C9
SUBtract C9H from Register A. C9H is the Z80 opcode for the RET instruction. If 45BEH contains C9H (indicating an unpatched RET), Register A becomes 00H and the Z FLAG is set; otherwise NZ FLAG is set, indicating the location has been modified (hooked) to contain different code, such as a JP instruction to a user extension.
If the Z FLAG has been set (meaning memory location 45BEH contains a RET instruction C9H, indicating the routine is unpatched and using standard DOS code), JUMP to 440DH for standard processing.
[PATCHED PATH - HOOK HANDLER] If we reach here, location 45BEH does NOT contain RET (C9H), meaning a routine has been hooked or patched by third-party software (such as a disk accelerator, debugging tool, or system extension). Restore all CPU registers to their pre-call state and transfer control to continue execution through the hooked code path.
45E2
POP AF F1
Restore Register Pair AF from the stack (recovers the Accumulator and Flags to their pre-call state).
45E3
POP BC C1
Restore Register Pair BC from the stack.
45E4
POP DE D1
Restore Register Pair DE from the stack.
45E5
POP HL E1
Restore Register Pair HL from the stack. All CPU registers have now been completely restored to their state before the hook was called, allowing the patched routine to execute with the correct context.
JUMP (relative) to 460AH with all registers restored, transferring control to continue execution after the patched routine completes.
[KEYBOARD CHECK CONTINUATION] This is the target of the jump from 45D8H. Continue checking for break conditions or special key combinations in keyboard row 1.
45E8
LD A,(3802H) 3A 02 38
Fetch the current state of keyboard row 1 from memory address 3802H. This row contains keys: HIJKLMNO. Each bit represents one key (active LOW).
45EB
CP 1CH FE 1C
Compare Register A against 1CH (00011100 binary). If Register A equals 1CH, the Z FLAG is set; otherwise the NZ FLAG is set. This checks for specific keys: bits 0-1 set (keys HI not pressed), bits 2-4 clear (keys JKL pressed), bits 5-7 set (keys MNO not pressed).
45ED
LD A,D 7A
Load Register A with the value held in Register D. This preserves or retrieves a status value from Register D for return to the caller. The flags from the previous comparison are preserved.
45EE
RET C9
RETurn to the calling routine. Register A now contains the value from Register D, and the CPU flags reflect the keyboard comparison results (Z or NZ based on whether the key pattern matched).
[ADDITIONAL ENTRY POINT] The following code at 45EFH provides an alternate entry point for a different SVC function related to memory debugging. Note that A5H has triple significance as both a SVC code, the warm boot signature, and a memory display function.
45EF
LD A,A5H 3E A5
Load Register A with A5H. This is a SVC function code with multiple meanings: • SVC function A5H = SYS3/SYS, Function 5 (Directory Sector 07H, file position 0, function 5) • Binary breakdown: 101 00 101 (function 5, file 0, directory sector 5+2=7) • Function 5 executes the DEBUG/DUMP memory display routine at 515FH in SYS3 • A5H also serves as the warm boot signature stored at 43ABH to indicate system initialization
45F1
RST 28H EF
Execute Supervisor Call. Invokes DOS system service function A5H which: • Loads the SYS3/SYS overlay module into memory at 4D00H-51DFH • Dispatches to the DEBUG/DUMP function at 515FH • Displays memory contents on screen starting at 3C00H (video RAM) or 4000H (user RAM) • BREAK key toggles between video RAM and user RAM display • Non-printable characters (<20H or >upper limit at 4290H) are shown as periods • Displays until the memory region wraps (H AND 3FH = 0), then returns
45F2H - Interrupt Service Routine Entry
This is the main interrupt service routine. It's jumped to from 4012H when hardware interrupts occur. It handles disk and timer interrupts.
45F2
PUSH AF F5
Save Register A and Flags onto the stack (preserve interrupted program's state).
45F3
PUSH HL E5
Save HL onto the stack.
45F4
PUSH DE D5
Save DE onto the stack.
45F5
PUSH BC C5
Save BC onto the stack.
45F6
LD A,(37ECH) 3A EC 37
Read the Floppy Disk Controller Status, and do absolutely nothing with it! (Unpatched Code)
45F9
LD A,(37E0H) 3A E0 37
Read the drive select latch at 37E0H to check which drive caused interrupt (Unpatched Code)
45FC
RLCA 07
Rotate left - moves drive select bits into position for testing (Unpatched Code)
Patched
PATCH PURPOSE: This patch fixes two issues: (1) It removes a wasteful read of the FDC status register at 37ECH whose result was immediately discarded, consuming precious interrupt cycles. (2) It integrates the new disk interrupt handler at 4053H into the ISR flow. The original code would read the FDC status but never act on it, potentially causing the controller to hang waiting for acknowledgment. The patched version properly delegates to 4053H which conditionally reads the status only when needed, improving interrupt latency and disk reliability.
45F6
LD A,(37E0H) 3A E0 37
Read the drive select latch at 37E0H to check which drive caused interrupt. (Patched Code)
45F9
RLCA 07
Rotate left - moves drive select bits into position for testing. (Patched Code)
GOSUB to additional interrupt processing (or return stub if disabled).
4603
POP BC C1
Restore BC from the stack.
4604
POP DE D1
Restore DE from the stack.
4605
POP HL E1
Restore HL from the stack.
4606
POP AF F1
Restore A and Flags from the stack.
4607
EI FB
Enable Interrupts - allow further interrupts to occur.
4608
RET C9
RETURN from interrupt to the interrupted program.
4609H - Exit/Return Handler
This routine is called to return from DOS operations. It pushes AF and performs SVC 27H which handles the actual return.
4609
PUSH AF F5
Save Register A (usually contains error/status code) onto the stack.
460A
LD A,27H 3E 27
Load A with SVC function 27H (return from SVC handler).
460C
RST 28H EF
Execute Supervisor Call to perform the return.
460D
LD (HL),B 70
This may be part of the return data or a no-op in this context.
460E
INC HL 23
Increment HL (part of return sequence).
460F
JP (HL) E9
JUMP to address in HL - returns to the calling program.
4610H - Timer Tick Handler
This routine handles timer interrupts. It increments the tick counter and potentially updates the system time. Called from the interrupt service routine when carry is set.
4610
LD HL,4040H 21 40 40
Point HL to timer tick counter at 4040H.
4613
INC (HL) 34
INCrement the tick counter.
4614
LD HL,4537H 21 37 45
Point HL to keyboard repeat delay counter at 4537H.
This routine initiates a disk sector read operation. It sets up the FDC command byte and falls through to the main disk I/O routine.
4630
LD A,88H 3E 88
Load A with 88H - FDC Read Sector command (80H + flags for head load, verify).
1771 FDC Command: 88H (1000 1000)
Function Description
Bit 7
Bit 6
Bit 5
Bit 4
Bit 3
Bit 2
Bit 1
Bit 0
Summary of Bits
1
0
0
m
b
E
0
0
Command=Read Sector Bit 7-5: Read Command (100) m: 1=Multiple Records, 0=Single Record b: 1=IBM format, 0=Non-IBM Format E: 1=Enable HLD, HLT, and 10ms Delay, 0=Assume Head Already Engaged, no Delay Remainder: Unused (00)
Load A with A9H - FDC Write Sector command with flags
1771 FDC Command: A9H (1010 1001)
Function Description
Bit 7
Bit 6
Bit 5
Bit 4
Bit 3
Bit 2
Bit 1
Bit 0
Summary of Bits
1
0
1
m
b
E
a1
a0
Command=Write Sector Bit 7-5: Write Command (101) m: 1=Multiple Records, 0=Single Record b: 1=IBM format, 0=Non-IBM Format E: 1=Enable HLD, HLT, and 10ms Delay, 0=Assume Head Already Engaged, no Delay a1, a0: Data Address Mark Select (00=Normal, 01=Deleted)
Command=Write Sector Bit 7-5: Write Command (101) m: 1=Multiple Records, 0=Single Record b: 1=IBM format, 0=Non-IBM Format E: 1=Enable HLD, HLT, and 10ms Delay, 0=Assume Head Already Engaged, no Delay a1, a0: Data Address Mark Select (00=Normal, 01=Deleted)
4642H - Disk I/O Setup and Execute
This is the main disk I/O entry point. It stores the command, sets up parameters based on command type (read vs write), then executes the FDC operation.
4642
LD (46C4H),A 32 C4 46
Store the FDC command byte at 46C4H for later use.
4645
AND 20HAND 00100000E6 20
Test bit 5 - this distinguishes read (bit 5=0) from write (bit 5=1) operations.
GOSUB to execute FDC command at 4747H (perform seek).
46B6
POP AF F1
Restore track/sector into AF.
46B7
POP BC C1
Restore BC.
46B8
PUSH BC C5
Save BC again (will need for retry loop).
46B9
LD (37EDH),A 32 ED 37
Store track number to FDC track register at 37EDH.
46BC
PUSH DE D5
Save DE (buffer pointer).
46BD
LD DE,37EFH 11 EF 37
Point DE to FDC data register at 37EFH.
46C0
LD HL,37ECH 21 EC 37
Point HL to FDC command/status register at 37ECH.
46C3
LD (HL),00H 36 00
Write 00H to command register - NOP/prepare before actual command.
46C5H - FDC Data Transfer Loop
This is the critical data transfer loop. It issues the read/write command and performs byte-by-byte transfer with the FDC, checking DRQ (Data Request) status.
If Z FLAG (drive ready), go back to check for more data.
4717H - FDC Operation Complete
The FDC operation has completed. Now we check the status register for errors and clean up.
4717
LD A,(HL) 7E
Fetch final FDC status into A.
4718
LD (HL),0D0H 36 D0
Write D0H to FDC command register - Force Interrupt command to reset state.
1771 FDC Command: D0H (1101 0000)
Function Description
Bit 7
Bit 6
Bit 5
Bit 4
Bit 3
Bit 2
Bit 1
Bit 0
Summary of Bits
1
1
0
1
I3
I2
I1
I0
Command=Force Interrupt Bit 7-4: Command Code (1101) I3: 1=Interrupt Immediately 0=No Interrupt Immediately I2: 1=Interrupt on the next Index Pulse 0=No Interrupt on the next Index Pulse I1: 1=Interrupt the next time Ready goes to Not Ready 0=No Interrupt the next time Ready goes to Not Ready I0: 1=Interrupt the next time Not Ready goes to Ready 0=No Interrupt the next time Not Ready goes to Ready
471A
INC HL 23
Point HL to FDC track register.
471B
POP BC C1
Restore BC (was pushed with track number).
471C
LD (HL),B 70
Store track number to track register.
471D
POP HL E1
Restore HL.
471E
POP DE D1
Restore DE.
471F
POP BC C1
Restore BC.
4720
EI FB
Enable Interrupts - critical section is over.
4721
AND FCH E6 FC
Mask FDC status with FCH - isolate error bits (ignore BUSY and INDEX).
This is the main file open routine. It searches the directory for a matching filename and sets up the FCB (File Control Block) for subsequent operations.
Retrieves the current file position information from the FCB.
4968
LD C,(IX+05H) DD 4E 05
Fetch FCB+05H (sector within record) to C.
496B
LD L,(IX+0AH) DD 6E 0A
Fetch FCB+0AH (record number low) to L.
496E
LD H,(IX+0BH) DD 66 0B
Fetch FCB+0BH (record number high) to H.
4971
LD A,H 7C
Load A with record high byte.
4972
CP (IX+0DH) DD BE 0D
Compare with FCB+0DH (EOF high).
4975
RET NZ C0
If NZ FLAG (not at EOF), RETURN.
4976
LD A,L 7D
Load A with record low byte.
4977
CP (IX+0CH) DD BE 0C
Compare with FCB+0CH (EOF low).
497A
RET NZ C0
If NZ FLAG (not at EOF), RETURN.
497B
LD A,C 79
Load A with sector offset.
497C
CP (IX+08H) DD BE 08
Compare with FCB+08H (EOF sector offset).
497F
RET C9
RETURN - Z flag set if at exact EOF.
4980H - SVC Setup / File Operation Prologue
This routine sets up the environment for file operations. It saves all registers, sets up IX to point to the FCB (File Control Block), and initializes IY to the DOS system area.
4980
LD A,(DE) 1A
Fetch first byte of FCB (File Control Block) from address in DE.
PATCH PURPOSE: This patch corrects a critical file positioning bug in the backspace operation. The original code had two different jump targets: 4BA1H (which stored the position immediately without setting the position-changed flag at bit 6 of FCB+01H) and 4B90H (which set the flag first). This inconsistency meant that backing up across a sector boundary could fail to flush a dirty buffer, causing data corruption. The patch standardizes both paths to jump to 4B80H, which properly sets bit 6 (position changed flag) before any position updates, ensuring the buffer management system knows to flush modified data before seeking to a new position.
Main character output handler for the display. This is called via the JP at 400CH. Handles display output with integrated keyboard and printer support.
This is the main entry point for the DOS. At boot, control transfers here. The routine determines available RAM by writing complement patterns, initializes system variables, loads configuration from the disk boot sector, and eventually displays the DOS Ready prompt.
4D00
A5
Data byte A5H
4D01
IM1 ED 56
Set Interrupt Mode 1 - interrupts call address 0038H.
4D03
LD HL,FFFFH 21 FF FF
Point HL to top of memory (FFFFH).
[RAM SIZE DETECTION LOOP] - Scan down from FFFFH to find actual RAM. Writes complement of byte, reads back, decrements if it doesn't match.
When a boot error occurs (disk read failure or invalid signature), this handler displays an error message and attempts to continue with alternate drives.
4DD1
LD A,27H 3E 27
Load A with error code 27H (system disk error).
4DD3
PUSH AF F5
Save error code onto the stack.
4DD4
LD A,46H 3E 46
Load A with SVC function 46H (display system message).
4DD6
RST 28H EF
Execute Supervisor Call to display the error message.
4DD7H - Drive Initialization Loop
Initializes drive parameter blocks by copying boot sector data for each configured drive.
Parses 3 two-digit fields (YY/MM/DD or HH:MM:SS) from ASCII input at (HL), stores binary values at (DE) counting down. Validates each field against min/max limits on stack.
This area contains encoded message strings and control data. The bytes represent packed text with high bit set for end-of-string markers and special characters.
4FA8-4FAA
DB 1CH,1FH,03H 1C 1F 03
Control codes: cursor home (1CH), clear (1FH), position (03H).
4FAB-4FD6
DB BF B4 80 BF 20 BE 83 83 BD 20 BF 80 80 BF 20 BF 83 83 BD 20 BE 83 83 BD 20 BE 83 83 8D 20 80 80 B8 87 20 BE 83 83 BD 20 BE 83 83 BD
Banner graphics - box drawing characters (high bit set).
4FD7-40E6
DEFM " APPARAT, INC." + 0AH
4FE7-5012
BF 82 AD BF 20 BF 83 83 B3 20 BF 9E AD BF 20 BF 80 80 BF 20 BF 80 80 BF 20 B2 83 83 BD 20 A0 9E 81 80 20 BE 83 83 BD 20 BF 80 80 BF
8-byte area where boot parameters from 42F8H are copied during initialization.
505B
DB 00H,00H,00H,00H 00 00 00 00
Boot parameter storage (8 bytes, initialized to zero).
505F
DB 00H,00H,00H,00H 00 00 00 00
Boot parameters continued.
5063H - Date Input Prompt
Prompt string displayed when requesting date entry during boot.
5063
DB "DATE?" 44 41 54 45 3F
Text: "DATE?"
5068
DB 20H,20H 20 20
Two spaces.
506A
DB "(MM/DD/YY)" 28 4D 4D 2F 44 44 2F 59 59 29
Format hint: "(MM/DD/YY)"
5074
DB 20H,03H 20 03
Space + control code (cursor position).
5076H - Time Input Prompt
Prompt string displayed when requesting time entry during boot.
5076
DB "TIME?" 54 49 4D 45 3F
Text: "TIME?"
507B
DB 20H,20H 20 20
Two spaces.
507D
DB "(HH:MM:SS)" 28 48 48 3A 4D 4D 3A 53 53 29
Format hint: "(HH:MM:SS)"
5087
DB 20H,03H 20 03
Space + control code.
5089H - Date Display Format
Format string for displaying current date on screen.
5089
DB "MM/DD/YY" 4D 4D 2F 44 44 2F 59 59
Date format: "MM/DD/YY"
5091
DB 20H,20H 20 20
Trailing spaces.
5093H - Time Display Format
Format string for displaying current time on screen.
5093
DB "HH:MM:SS" 48 48 3A 4D 4D 3A 53 53
Time format: "HH:MM:SS"
509B
DB 0DH 0D
Carriage return (end of string).
509CH - Date/Time Validation Tables
Validation limits for date and time input parsing. Each field has (minimum, range) pairs. Used by the parser at 4F6FH to validate user input.
509C
DB 01H,0CH 01 0C
Month limits: min=1, range=12 (valid: 1-12).
509E
DB 01H,1FH 01 1F
Day limits: min=1, range=31 (valid: 1-31).
50A0
DB 00H,64H 00 64
Year limits: min=0, range=100 (valid: 00-99).
50A2
DB 00H,18H 00 18
Hour limits: min=0, range=24 (valid: 0-23).
50A4
DB 00H,3CH 00 3C
Minute limits: min=0, range=60 (valid: 0-59).
50A6
DB 00H,3CH 00 3C
Second limits: min=0, range=60 (valid: 0-59).
50A8
DB 00H 00
Table terminator or padding.
50A9H - Reserved Buffer Space
Reserved buffer area initialized to zeros. Used as temporary storage during boot operations and later available for overlay programs. This space extends to the end of the SYS0 module.
50A9
DS 306 00...
Reserved buffer area (306 bytes, initialized to 00H).
Program Entry Point
The DOS bootstrap loader jumps here after loading SYS0/SYS from disk.
ENTRY
ORG 4D00H
PROGRAM ENTRY = 4D00H - Boot / cold start entry point