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!
[LOOP] DECrement B and JUMP if Not Zero - continue checking fields.
44E8
INC HL 23
Skip to day field (if hours rolled over to next day).
44E9
INC (HL) 34
INCrement the day counter (rollover from 23:59:59 to next day).
44EA
RET C9
RETURN to caller.
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.
If NZ FLAG (previous state non-zero), skip the store.
4532
LD (4580H),A 32 80 45
Store 0 into keyboard buffer flag at 4580H.
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).
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
AND L A5
Data byte A5H (appears at entry - may be signature check).
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
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-40E5
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 (306 bytes, all 00H). Addresses 50A9H-51DAH.
Program Entry Point
The DOS bootstrap loader jumps here after loading SYS0/SYS from disk.
ENTRY
ORG 4D00H
PROGRAM ENTRY = 4D00H - Boot initialization starts at 4D00H.