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

Page Customization

NEWDOS/80 v2.0 - SYS6/SYS: FORMAT, COPY, and BACKUP Commands

SYS6/SYS is the disk utility overlay for NEWDOS/80, providing the FORMAT, COPY, and BACKUP commands. It loads at address 4D00H and extends through 6FF9H (approximately 9KB). This overlay handles all low-level disk formatting operations, disk-to-disk copying, and backup functions with support for multi-disk operations when source and destination are on the same physical drive.

Command Entry Points

The module entry point at 4D00H examines the command code in Register A and dispatches to the appropriate handler:

  • 68H ('h') → 6F4BH: File transfer/copy operation
  • 28H ('(') → 65FAH: FORMAT command with system initialization
  • 48H ('H') → 4D1EH: FORMAT command (standard entry)
  • Other → 5208H: COPY and BACKUP commands

FORMAT Command (4D1EH, 65FAH)

The FORMAT command prepares blank diskettes for use with NEWDOS/80. Key features include:

  • Track Formatting: Low-level format using the WD1771/1791 controller's format command, writing sector headers and data areas with proper CRC values
  • Sector Interleave: Configurable sector interleave pattern stored in a table at 6485H, optimized for the system's read/write timing
  • Boot Sector Creation: Writes the boot loader code from template at 64BAH to track 0, sector 0
  • Directory Initialization: Creates the Granule Allocation Table (GAT) and Hash Index Table (HIT) on tracks 1-2
  • System Disk Option: When the $ option is specified, copies system files to make a bootable diskette
  • Multi-Format Support: Supports single/double density, single/double sided, and various track counts (35, 40, 77, 80)

COPY Command (5208H with bit 3 of 5996H set)

The COPY command duplicates files or entire diskettes:

  • File Copy Mode: Copies individual files from source to destination disk
  • Disk Copy Mode: Creates an exact duplicate of an entire diskette
  • Same-Drive Operation: Supports copying when source and destination are the same physical drive, prompting for disk swaps
  • Track Buffering: Reads multiple tracks into memory before writing, minimizing disk swaps (buffer at 5D16H, size calculated at 5273H-528EH based on available memory)
  • Verification: Optional verify pass reads back written data and compares against source (routine at 5400H-544EH)

BACKUP Command (5208H with bit 2 of 5996H set)

The BACKUP command creates archival copies with additional features:

  • Granule-Based Copying: Only copies allocated granules, skipping empty space for faster backups
  • Directory Synchronization: Copies the directory structure and updates destination GAT/HIT
  • Space Management: Tracks remaining granules at 5B21H, handles disk-full conditions gracefully

Memory Organization

SYS6 uses an extensive work area from 593BH-5B60H:

  • 593BH-5941H: Control flags and status bytes
  • 5942H-595FH: Three 10-byte drive parameter blocks (primary, source, destination)
  • 5960H-5977H: Filename buffers for source and destination
  • 5994H-5997H: Option flags parsed from command line
  • 59D3H-5AD7H: Message strings for user prompts and errors
  • 5AE5H-5B16H: Source disk control block (DCB)
  • 5B17H-5B48H: Destination disk control block
  • 5D12H-5D14H: Track buffer pointers

Multi-Disk Operation

When source and destination are on the same drive (indicated by bit 7 of 593BH), the code implements a sophisticated disk-swapping system:

  • Disk Detection: Verifies correct disk is mounted by checking disk name/date at 67C3H-6886H
  • User Prompts: Displays "PRESS ENTER WHEN [disk] MOUNTED ON DRIVE n" messages
  • Buffer Management: Swaps buffer contents when switching between disks (routine at 5626H)
  • Batch Operations: Accumulates multiple tracks in memory to minimize disk swaps

Error Handling

The module includes comprehensive error handling:

  • Error Handler Entry: 521AH receives errors and displays appropriate messages
  • Retry Logic: User prompted with "REPLY C (CANCEL), R (RETRY) OR P (PROCEED)" for recoverable errors
  • Disk Full Handling: Detects full destination disk (errors 1AH/1BH) and offers options
  • Verification Failures: Reports comparison errors (3AH) and verification failures (31H) with track/sector information
  • Wrong Disk Detection: Error 33H when incorrect disk detected during multi-disk operation

Low-Level Disk I/O

SYS6 performs direct disk controller access for formatting:

  • Controller Interface: Writes directly to FDC registers at 37ECH-37EFH
  • Format Timing: Critical timing loops for writing sector headers and gaps (6AB2H-6B90H)
  • Density Selection: Handles FM (single density) and MFM (double density) encoding
  • Side Selection: Controls head selection for double-sided drives via bit 5 of drive control byte

Boot Sector Structure

The boot sector template at 64BAH contains:

  • Boot Code: Initial loader that reads DOS into memory
  • Disk Parameters: Track count, sector count, density flags at offset EFH
  • Signature Byte: A5H at offset EFH indicates valid boot sector
  • System Filename: "BOOT/SYS" pointer for loading the operating system

Option Flags

Command-line options are parsed into flags at 5994H-5997H:

  • 5994H Bit 0: $ (system disk) option
  • 5994H Bit 1: Skip boot sector flag
  • 5994H Bit 6: QUERY option - prompt before each operation
  • 5995H Bit 7: Abort on error flag
  • 5996H Bit 2: BACKUP command active
  • 5996H Bit 3: COPY command active
  • 5996H Bit 7: Multi-disk mode active

Key Subroutines

AddressFunction
521AHMain error handler entry point
5273HCalculate track batch size based on available memory
529DHRead track loop - reads source tracks into buffer
5324HWrite track batch to destination disk
5400HPost-write verification loop
546DHWrite single sector to disk
5578HInitialize source drive parameters
557DHInitialize destination drive parameters
5646HFlush all drive buffers
57C8HDisk read operation
57D4HDisk write operation
585AHError display with retry prompt
5881HDisplay message string
6959HFormat track with sector interleave
67C3HVerify correct disk is mounted

Dependencies

SYS6 calls numerous routines in the resident DOS (SYS0):

  • 4424H: Open file for read
  • 4428H: Close file
  • 4467H: Display message string
  • 4776H: Select drive and verify ready
  • 47ECHVerify disk is mounted
  • 4CB4H: Calculate granule from track/sector
  • 4CC5H: Parse filename from command line
  • 4CD9H: Skip whitespace in command buffer
  • 4CEDH: Allocate buffer space

Self-Modifying Code

SYS6 uses self-modifying code extensively for efficiency:

  • 5314H: Track counter incremented during batch operations
  • 531AH: Batch size limit set during initialization
  • 53D7H: Disk full flag toggled during copy operations
  • 53ECH: Write counter for verification phase
  • 57EBH: Disk command byte (80H=read, 40H=write, 20H=verify)
  • 6C63H: Side selection toggle for double-sided formatting

Variables:

REFERENCED DOS WORK AREA VARIABLES (in SYS0 area):

4049HHIGH$ pointer (BASIC high memory limit)
430CHDOS configuration byte
4311HDOS status word
4317HDOS error code
4369HDOS status flags byte
436AHDOS mode flags
436BHDOS control byte
436CHDOS control byte 2
4399HDOS buffer pointer
4930HDrive parameter update flag

SELF-MODIFYING CODE LOCATIONS:

5314HTrack counter (modified by code at 5313H, 5316H, 53F5H)
531AHBatch size limit (set at 528EH, tested at 5319H)
53D7HDisk full flag (set at 53CEH, tested at 53D6H)
53ECHWrite counter (modified at 53EBH, 53EEH, tested at 53FBH)
544FHBuffer end pointer (modified at 5454H, loaded at 5411H)
5401HGranule count save (set at 5336H, loaded at 5400H)
57EBHDisk operation command flag (80H=read, 40H=write, 20H=verify)

BUFFER POINTERS:

5D10HSector data pointer
5D12HTrack buffer start pointer
5D14HTrack buffer end pointer
5D16HTrack buffer relocation base

SYS6 CONTROL/STATUS VARIABLES (593BH-5941H):

593BHMulti-disk operation mode flag (bit 7 = multi-disk active)
593CH-593DHSaved HIGH$ pointer (2 bytes)
593EH-593FHCurrent drive parameter block pointer (2 bytes)
5940HOperation status byte 1
5941HOperation status byte 2

PRIMARY DRIVE PARAMETER BLOCK (5942H-594BH, 10 bytes):

5942HDrive number (FFH = uninitialized)
5943HDrive status flags
5944H-5945H(reserved)
5946H-5947HPointer 1 (5999H)
5948H-5949HPointer 2 (5999H)
594AH-594BHDCB pointer (5A51H)

SOURCE DRIVE PARAMETER BLOCK (594CH-5955H, 10 bytes):

594CHSource drive number (FFH = uninitialized)
594DHSource drive status flags
594EH-594FHSource buffer pointer (5AE5H)
5950H-5951HPointer 1 (59B7H)
5952H-5953HPointer 2 (59A3H)
5954H-5955HSource DCB pointer (5A3CH)

DESTINATION DRIVE PARAMETER BLOCK (5956H-595FH, 10 bytes):

5956HDestination drive number (FFH = uninitialized)
5957HDestination drive status flags
5958H-5959HDestination DCB pointer (5B17H)
595AH-595BHPointer 1 (59C5H)
595CH-595DHPointer 2 (59ADH)
595EH-595FHDestination info pointer (5A44H)

FILENAME BUFFER (5960H-5977H):

5960H-5967HSource filename (8 bytes, space-padded)
5968H-596FHSource extension area
5970H-5977HDestination filename (8 bytes, space-padded)

DISK OPERATION PARAMETERS (5978H-5982H):

5978H-5979HParameter block 1 pointer
597AH-597BHParameter block 2 pointer
597CHSector size indicator
597DHSector size indicator 2
597EHTrack layout byte (82H)
597FH-5980HReserved
5981H-5982HParameter block 3 pointer

BOOT SECTOR TEMPLATE (5983H-5994H):

5983H-598AH"BOOTNAME" - default boot filename template
598BH-5993HDefault format parameters ":2:/4:/:" with terminators

OPTION FLAGS (5994H-5997H):

5994HOption flags byte 1:
Bit 0: $ option (system disk)
Bit 1: Skip boot sector flag
Bit 2: (unused)
Bit 3: (unused)
Bit 4: (unused)
Bit 5: (unused)
Bit 6: QUERY option (40H)
Bit 7: (unused)
5995HOption flags byte 2:
Bit 0: (unused)
Bit 1: (unused)
Bit 2: (unused)
Bit 3: (unused)
Bit 4: (unused)
Bit 5: (unused)
Bit 6: (unused)
Bit 7: Abort on error flag
5996HOption flags byte 3:
Bit 0: (unused)
Bit 1: (unused)
Bit 2: BACKUP option (04H)
Bit 3: COPY option (08H)
Bit 4: (unused)
Bit 5: Set during FORMAT init
Bit 6: (unused)
Bit 7: (unused)
5997HOption flags byte 4

WORK AREA (5998H-59D2H):

5998H-59B6HGeneral work area (zeroed on init)
59B7H-59B8HFormat parameter pointer
59B9H-59BBHAdditional parameters
59BCHConfiguration byte
59BDH-59BEHReserved
59BFH-59C0HReserved
59C1H-59C2HReserved
59C3H-59C4HProgram end address
59C5H-59C6HParameter storage
59C7H-59C8HParameter storage
59C9HReserved
59CAH-59CBHParameter storage
59CCH-59CDHParameter storage
59CEH-59CFHParameter storage
59D0HReserved
59D1H-59D2HHigh memory limit

MESSAGE STRINGS:

59D3H"ERROR WHILE " + 03H
59EEH"PRESS \"ENTER\" WHEN " + 03H
5A02H" DISKETTE MOUNTED ON DRIVE 0" + 0DH
5A1DHDrive number ASCII (modified at runtime)
5A1FH"DONE" + 0DH
5A24H"SOURCE & DEST SAME FILE" + 0DH
5A3CH"SOURCE " + 03H
5A44H"DESTINATION " + 03H
5A51H"** SYSTEM **" + 03H
5A5FH"SECTOR " + 03H
5A67H"READING " + 03H
5A70H"WRITING " + 03H
5A79H"VERIFYING " + 03H
5A84H"CPR" + 00H (Cancel/Proceed/Retry codes)
5A88H"REPLY C (CANCEL), R (RETRY) OR P (PROCEED)" + 0DH
5AB3H"NY" + 00H (No/Yes codes)
5AB6H" (Y OR N) " + 03H
5AC2H"DISKETTE/GAT OVERFLOW" + 0DH
5AD8H"DISK FULL - " + 03H

SOURCE DISK CONTROL AREA (5AE5H-5B16H):

5AE5H-5AE7HSource file control bytes
5AE8H-5AE9HSource sector buffer pointer
5AEBH-5AECHSource disk identifier
5AEDHSource disk type byte
5AEEHReserved
5AEFH-5AF0HSource track number (16-bit)
5AF1H-5AF2HSource disk total granule count
5AF3H-5AF4HReserved
5AF5H-5B16HSource disk sector buffer (32 bytes)

DESTINATION DISK CONTROL AREA (5B17H-5B48H):

5B17HDestination DCB status byte (bit 7 = initialized)
5B18HDestination DCB flags
5B19HReserved
5B1AH-5B1BHDestination buffer pointer
5B1CHReserved
5B1DH-5B1EHDestination disk identifier
5B1FHDestination disk type byte
5B20HReserved
5B21H-5B22HRemaining granule count
5B23H-5B24HDestination total granule count
5B25HReserved
5B26HReserved
5B27H-5B48HDestination disk sector buffer (32 bytes)

THIRD CONTROL AREA (5B49H-5B56H):

5B49H-5B56HThird parameter block (used for three-disk operations)

BUFFER SWAP CONTROL LIST (5B57H-5B5FH):

5B57HEntry type (02H = process this entry)
5B58HByte count for swap
5B59H-5B5AHBuffer 1 pointer (5B64H)
5B5BHEntry type
5B5CHByte count
5B5DH-5B5EHBuffer 2 pointer (5BA3H)
5B5FHEntry type (end marker)

Disassembly

4D00H - SYS6 Entry Point and Function Dispatcher

SYS6 is entered with the function code in Register A. This dispatcher examines the function code and routes execution to the appropriate handler. SYS6 handles the FORMAT, COPY, and BACKUP commands among others. The IY register is set to point to the DOS work area at 4380H.

4D00
LD IY,4380H FD218043
Point Index Register IY to 4380H.
NOTE: 4380H is the base address of the DOS work area. Many subsequent instructions will use IY+offset to access DOS variables.
4D04
LD (IY+97H),97H FD369700
Store 97H at address 4417H (4380H+97H).
NOTE: This sets a marker/flag indicating SYS6 has been entered.
4D08
CP 68H FE68
Compare the function code in Register A against 68H. If equal, the Z FLAG is set.
4D0A
If function code = 68H, JUMP to 6F4BH to handle that function.
4D0D
SET 3,(IY+E9H) FDCBE9DE
Set bit 3 of the byte at 4469H (4380H+E9H).
NOTE: This is a status flag indicating a SYS6 operation is in progress.
4D11
CP 28H FE28
Compare the function code in Register A against 28H.
4D13
If function code = 28H, JUMP to 65FAH to handle that function.
4D16
CP 48H FE48
Compare the function code in Register A against 48H.
4D18
If function code = 48H (FORMAT command), JUMP to 4D1EH to begin FORMAT processing.
4D1B
For all other function codes, JUMP to 5208H (default handler - likely COPY/BACKUP).

4D1EH - FORMAT Command Handler Entry

This section begins processing the FORMAT command (function code 48H). It first checks bit 6 of 436AH to determine if special handling is needed, then saves the high memory pointer and calls subroutines to parse the command line and set up for formatting.

4D1E
LD A,(436AH) 3A6A43
Fetch the system status byte from 436AH into Register A.
NOTE: Bit 6 of this byte indicates a special condition (possibly batch mode or protected state).
4D21
BIT 6,A CB77
Test bit 6 of Register A. If set, the Z FLAG is cleared (NZ).
4D23
If bit 6 is set, skip the initialization and JUMP to 4D32H.
4D25
PUSH HL E5
Save HL (command line pointer) onto the stack.
4D26
LD HL,5996H 219659
Point HL to 5996H (FORMAT options flags area).
4D29
SET 5,(HL) CBEE
Set bit 5 at 5996H to indicate a specific FORMAT mode/option.
4D2B
LD HL,(4049H) 2A4940
Fetch the HIGH$ pointer from 4049H into HL.
NOTE: 4049H contains the highest usable memory address.
4D2E
LD (593CH),HL 223C59
Store the HIGH$ pointer at 593CH for later restoration.
4D31
POP HL E1
Restore HL (command line pointer) from the stack.
4D32
PUSH HL E5
Save HL (command line pointer) onto the stack.
4D33
GOSUB to 6ECBH to parse and validate the drive specification from the command line.
4D36
If the Carry FLAG is clear (no valid drive found or error), JUMP to 4D98H for alternate processing.
4D39
POP DE D1
Pop the saved command line pointer into DE (discarding it from stack).
4D3A
LD (5AEBH),A 32EB5A
Store the drive number (from parsing) at 5AEBH.
4D3D
LD (594CH),A 324C59
Store the drive number at 594CH (source drive for FORMAT).
4D40
LD (5956H),A 325659
Store the drive number at 5956H (destination drive - same for FORMAT).
4D43
PUSH HL E5
Save HL (updated command line pointer after drive spec).
4D44
LD DE,64A6H 11A664
Point DE to 64A6H (a message or parameter table address).
4D47
GOSUB to 63A3H to process/display information.
4D4A
GOSUB to 6FE5H (skip spaces in command line).
4D4D
GOSUB to 6392H to parse additional parameters.
4D50
If Carry is clear (parsing issue), JUMP to 4D8BH for error handling.
4D53
GOSUB to 63A0H for further parameter processing.
4D56
EX (SP),HL E3
Exchange HL with the value on top of stack (swap current HL with saved pointer).
4D57
LD HL,6E0CH 210C6E
Point HL to the message at 6E0CH.
4D5A
GOSUB to 4467H to display the message pointed to by HL.
NOTE: 4467H is the DOS message display routine (vectors to 44CFH).
4D5D
POP HL E1
Restore HL from the stack.
4D5E
GOSUB to 6FB8H for further processing.
4D61
LD B,20H 0620
LET Register B = 20H (32 decimal) as a parameter for the next call.
4D63
GOSUB to 4EA7H (option parsing routine).
4D66
LD HL,5994H 219459
Point HL to 5994H (FORMAT options byte).
4D69
LD A,(HL) 7E
Fetch the options byte from 5994H into Register A.
4D6A
AND F9H E6F9
Mask off bits 1 and 2 (keep bits 0, 3-7). Tests for specific option flags.
4D6C
INC HL 23
Advance HL to point to 5995H.
4D6D
If any of the tested bits were set (NZ), skip to 4D72H.
4D6F
LD A,(HL) 7E
Fetch the byte at 5995H into Register A.
4D70
AND 01HAND 00000001 E601
Test bit 0 only.
4D72
If bit 0 at 5995H is set, skip to 4D79H.
4D74
DEC HL 2B
Move HL back to point to 5994H.
4D75
LD A,(HL) 7E
Fetch the options byte from 5994H.
4D76
OR 40H F640
Set bit 6 in the options byte.
4D78
LD (HL),A 77
Store the modified options byte back to 5994H.
4D79
GOSUB to 5C96H (likely validates format parameters).
4D7C
LD HL,59B7H 21B759
Point HL to the buffer at 59B7H.
4D7F
GOSUB to 6713H.
4D82
GOSUB to 6710H.
4D85
GOSUB to 4DF3H (FORMAT execution subroutine).
4D88
JUMP to 6291H to complete the FORMAT operation and exit.

4D8BH - FORMAT Error/Alternate Path Handler

This section handles cases where the initial parameter parsing encountered an issue. It sets up default values in the control area and re-parses the drive specification.

4D8B
LD HL,5940H 214059
Point HL to 5940H (FORMAT control block).
4D8E
LD (HL),06H 3606
Store 06H at 5940H (default sector count or parameter).
4D90
INC HL 23
Advance HL to 5941H.
4D91
LD (HL),01H 3601
Store 01H at 5941H (default track count or parameter).
4D93
POP HL E1
Restore HL (command line pointer) from the stack.
4D94
GOSUB to 6EC4H to re-parse drive specification.
4D97
PUSH HL E5
Save the updated command line pointer.

4D98H - Check for Dollar Sign Prefix

This section checks if the current character on the command line is a dollar sign ($), which indicates a special filename format in NEWDOS/80. If found, a flag is set and the pointer is advanced.

4D98
POP HL E1
Restore HL (command line pointer) from the stack.
4D99
LD A,(HL) 7E
Fetch the current character from the command line into Register A.
4D9A
CP 24H FE24
Compare against 24H (ASCII $).
4D9C
If NOT a dollar sign, skip ahead to 4DA6H.
4D9E
PUSH HL E5
Save HL onto the stack.
4D9F
LD HL,5940H 214059
Point HL to the control block at 5940H.
4DA2
SET 0,(HL) CBC6
Set bit 0 at 5940H to indicate the $ prefix was found.
4DA4
POP HL E1
Restore HL (command line pointer).
4DA5
INC HL 23
Advance HL past the $ character.

4DA6H - Copy Filename to Buffer and Set Up Parsing

This section copies up to 80 characters from the command line to a working buffer, then begins parsing for special characters like colon (:), period (.), and slash (/) which indicate drive or extension separators.

4DA6
LD DE,4D3EH 113E4D
Load DE with the return address 4D3EH.
NOTE: This will be pushed onto the stack as a return point.
4DA9
PUSH DE D5
Push the return address onto the stack.
4DAA
LD BC,0050H 015000
LET BC = 0050H (80 decimal) - maximum characters to copy.
4DAD
LDIR EDB0
Block copy BC bytes from (HL) to (DE), incrementing both pointers.
NOTE: This copies the command line to the working buffer.
4DAF
POP HL E1
Pop the return address into HL (now HL = 4D3EH, pointing to copied data).
4DB0
LD DE,5AE5H 11E55A
Point DE to 5AE5H (filename parsing buffer).
4DB3
GOSUB to 4E8DH to parse the filename.
4DB6
GOSUB to 6FE5H to skip any leading spaces.
4DB9
LD A,(HL) 7E
Fetch the current character from the command line.
4DBA
CP 3AH FE3A
Compare against 3AH (ASCII : colon - drive separator).
4DBC
If it's a colon, JUMP to 4DC6H to handle drive specification.
4DBE
CP 2EH FE2E
Compare against 2EH (ASCII . period - extension separator).
4DC0
If it's a period, JUMP to 4DC6H.
4DC2
CP 2FH FE2F
Compare against 2FH (ASCII / slash - extension separator).
4DC4
If NOT a slash, skip separator processing and JUMP to 4DDEH.

4DC6H - Handle Filename Separator Characters

When a separator character (colon, period, or slash) is found, this section scans back through the parsed filename buffer to insert the separator at the correct position.

4DC6
LD C,A 4F
Save the separator character in Register C.
4DC7
LD B,00H 0600
LET B = 0 as a position counter.
4DC9
LD DE,5AE5H 11E55A
Point DE to the start of the filename buffer at 5AE5H.
4DCC
LD A,(DE) 1A
[LOOP START] Fetch the character at the current buffer position.
4DCD
CP 03H FE03
Compare against 03H (end-of-text marker).
4DCF
If end of text, exit loop and JUMP to 4DDEH.
4DD1
CP C B9
Compare the buffer character against the separator we're looking for.
4DD2
If it matches, JUMP to 4DD8H to perform the insertion.
4DD4
INC DE 13
Advance the buffer pointer.
4DD5
INC B 04
Increment the position counter.
4DD6
[LOOP] Continue scanning the buffer.
4DD8
DEC HL 2B
[COPY LOOP START] Back up the command line pointer.
4DD9
DEC DE 1B
Back up the buffer pointer.
4DDA
LD A,(DE) 1A
Fetch the character from the buffer.
4DDB
LD (HL),A 77
Store it into the command line (inserting it).
4DDC
[LOOP] Repeat B times to copy all characters back.

4DDEH - Set Parsing Flags and Continue

After handling any separators, this section sets flags at 5996H and 5997H to indicate the parsing state, then calls the option parsing routine with parameter 08H.

4DDE
GOSUB to 4E8AH (alternate filename parsing entry).
4DE1
PUSH HL E5
Save HL (command line pointer).
4DE2
LD HL,5996H 219659
Point HL to 5996H (options flags).
4DE5
SET 2,(HL) CBD6
Set bit 2 at 5996H.
4DE7
INC HL 23
Advance HL to 5997H.
4DE8
SET 3,(HL) CBDE
Set bit 3 at 5997H.
4DEA
POP HL E1
Restore HL (command line pointer).
4DEB
LD B,08H 0608
LET B = 08H as parameter for option parsing.
4DED
GOSUB to 4EA7H to parse command options.
4DF0
JUMP to 6377H to continue processing.

4DF3H - FORMAT Execution Setup Subroutine

This subroutine sets up the sector data for the FORMAT operation. It initializes a block of memory with sector header information.

4DF3
GOSUB to 6424H to initialize format parameters.
4DF6
LD BC,000AH 010A00
LET BC = 000AH (10 bytes to copy).
4DF9
LD A,00H 3E00
LET A = 00H (initial value).
4DFB
RLCA 07
Rotate A left (A = 00H, no effect first time).
4DFC
RLCA 07
Rotate A left again.
4DFD
RLCA 07
Rotate A left again.
4DFE
RLCA 07
Rotate A left again (multiply by 16).
4DFF
ADD A,C 81
Add C to A (A = A + 0AH = 0AH).
4E00
EX DE,HL EB
Exchange DE and HL.
4E01
LD HL,59C5H 21C559
Point HL to the source buffer at 59C5H.
4E04
LDIR EDB0
Block copy 10 bytes from 59C5H to the destination.
4E06
LD H,D 62
Copy D to H (set up HL from DE).
4E07
LD L,A 6F
Copy A to L.
4E08
LD C,06H 0E06
LET C = 06H (6 more bytes to copy).
4E0A
LDIR EDB0
Block copy 6 bytes.
4E0C
LD L,C 69
LET L = C (which is now 0 after LDIR).
4E0D
LD B,01H 0601
LET B = 01H (1 byte to copy).
4E0F
LD DE,6EB5H 11B56E
Point DE to 6EB5H (format template data).
4E12
LDIR EDB0
Block copy 1 byte.
4E14
LD DE,0100H 110001
LET DE = 0100H (256 - sector size indicator).
4E17
LD A,(594CH) 3A4C59
Fetch the source drive number from 594CH.
4E1A
OR A B7
Test if drive number is zero.
4E1B
LD B,A 47
Save drive number in B.
4E1C
If drive is not zero, skip ahead to 4E22H.
4E1E
LD A,E 7B
Load A with E (low byte of 0100H = 00H).
4E1F
OR 03H F603
Set bits 0 and 1 in A.
4E21
LD E,A 5F
Store modified value back in E.
4E22
LD A,(5956H) 3A5659
Fetch the destination drive number from 5956H.
4E25
OR A B7
Test if destination drive is zero.
4E26
If not zero, skip ahead to 4E2CH.
4E28
SET 0,E CBC3
Set bit 0 of E.
4E2A
SET 2,E CBD3
Set bit 2 of E.
4E2C
CP B B8
Compare destination drive (A) with source drive (B).
4E2D
If drives are different, JUMP to 4E3DH.
4E2F
LD A,E 7B
Load A with E.
4E30
OR 06H F606
Set bits 1 and 2 (same drive flag).
4E32
LD E,A 5F
Store back in E.
4E33
LD A,(436AH) 3A6A43
Fetch the system status byte from 436AH.
4E36
BIT 6,A CB77
Test bit 6 (special mode flag).
4E38
LD A,15H 3E15
Load A with error code 15H (just in case).
4E3A
If bit 6 is set, JUMP to 521AH (error exit).

4E3DH - Continue FORMAT Parameter Setup

This section continues setting up FORMAT parameters based on various option flags. It checks for double-sided format options and adjusts the sector configuration accordingly.

4E3D
LD A,(5995H) 3A9559
Fetch the options byte from 5995H.
4E40
BIT 7,A CB7F
Test bit 7 (double-sided flag).
4E42
If not double-sided, skip to 4E4DH.
4E44
LD A,E 7B
Load A with E (current flags).
4E45
CP 06H FE06
Compare against 06H.
4E47
If A >= 06H, JUMP to 5208H (error or alternate path).
4E4A
LD DE,0700H 110007
LET DE = 0700H (7 sectors, side 0).
4E4D
LD A,E 7B
Load A with E.
4E4E
CP 03H FE03
Compare against 03H.
4E50
LD B,80H 0680
LET B = 80H (bit mask).
4E52
LD HL,5A3CH 213C5A
Point HL to 5A3CH (configuration area).
4E55
If E = 03H, GOSUB to 4E68H to prompt user.
4E58
LD A,E 7B
Load A with E again.
4E59
CP 05H FE05
Compare against 05H.
4E5B
LD B,40H 0640
LET B = 40H (bit mask).
4E5D
LD HL,5A44H 21445A
Point HL to 5A44H.
4E60
If E = 05H, GOSUB to 4E68H to prompt user.
4E63
LD (5940H),DE ED534059
Store DE (sector configuration) at 5940H.
4E67
RET C9
Return to caller.

4E68H - User Prompt Subroutine

This subroutine displays a prompt message to the user and waits for a response. It's used to confirm operations like formatting when certain conditions are met.

4E68
DEC A 3D
Decrement A.
4E69
OR D B2
OR A with D.
4E6A
LD C,A 4F
Save result in C.
4E6B
LD A,(5997H) 3A9759
Fetch the options byte from 5997H.
4E6E
AND B A0
AND with the bit mask in B.
4E6F
RET NZ C0
If the bit is set, return (skip prompt).
4E70
PUSH HL E5
Save HL.
4E71
LD HL,6E23H 21236E
Point HL to the prompt message at 6E23H.
4E74
GOSUB to 4467H to display the message.
4E77
POP HL E1
Restore HL (points to additional message).
4E78
GOSUB to 4467H to display the second message.
4E7B
LD HL,6E33H 21336E
Point HL to the query message at 6E33H (likely "Y/N?").
4E7E
GOSUB to 58DEH to get user response.
4E81
RET Z C8
If Z FLAG set (user said Yes), return.
4E82
LD E,00H 1E00
LET E = 00H (clear operation flag).
4E84
LD D,C 51
LET D = C (restore saved value).
4E85
RET C9
Return to caller.

4E86H - Combine D and C into D

4E86
LD A,D 7A
Load A with D.
4E87
OR C B1
OR A with C.
4E88
LD D,A 57
Store result in D.
4E89
RET C9
Return to caller.

4E8AH - Filename Parse Entry Point (Alternate)

This is an alternate entry point for filename parsing that uses a different destination buffer.

4E8A
LD DE,5B17H 11175B
Point DE to the alternate filename buffer at 5B17H.
4E8D
LD B,20H 0620
LET B = 20H (32 characters maximum for filename).
4E8F
PUSH DE D5
Save DE (destination buffer pointer).
4E90
[LOOP START] GOSUB to 4CD5H to check for valid filename character.
NOTE: 4CD5H is a SYS0 routine that validates filename characters.
4E93
If Carry is clear (invalid character), exit loop to 4EA0H.
4E95
LD A,(HL) 7E
Fetch the valid character from the command line.
4E96
LD (DE),A 12
Store it in the destination buffer.
4E97
INC DE 13
Advance the destination pointer.
4E98
INC HL 23
Advance the source pointer.
4E99
[LOOP] Repeat for up to 32 characters.
4E9B
LD A,30H 3E30
LET A = 30H (error code: filename too long).
4E9D
JUMP to 521AH to report the error.
4EA0
LD A,03H 3E03
LET A = 03H (end-of-text marker).
4EA2
LD (DE),A 12
Store the end marker in the buffer.
4EA3
POP DE D1
Restore DE (start of buffer).
4EA4
RET Z C8
If Z FLAG set (ended on valid terminator), return.
4EA5
DEC HL 2B
Back up HL to point to the terminating character.
4EA6
RET C9
Return to caller.

4EA7H - Main Option Parsing Routine

This is the main option parsing routine for FORMAT/COPY/BACKUP commands. Register B contains a mode flag on entry. It scans the command line for option keywords and sets appropriate flags in the option bytes at 5994H-5997H.

4EA7
GOSUB to 6EC0H to scan for the next option on the command line.
4EAA
If NZ (option found), JUMP to 4F1DH to process it.
4EAD
LD HL,5997H 219759
Point HL to options byte at 5997H.
4EB0
LD A,(HL) 7E
Fetch the options byte.
4EB1
AND 0CH E60C
Test bits 2 and 3.
4EB3
If either bit is set, skip to 4ECAH.
4EB5
LD A,(5995H) 3A9559
Fetch the options byte from 5995H.
4EB8
AND 80H E680
Test bit 7 (double-sided flag).
4EBA
PUSH HL E5
Save HL.
4EBB
LD HL,6E46H 21466E
Point HL to a message at 6E46H.
4EBE
If bit 7 was clear, GOSUB to 58DEH to prompt user.
4EC1
POP HL E1
Restore HL (points to 5997H).
4EC2
SET 3,(HL) CBDE
Set bit 3 at 5997H.
4EC4
If user said Yes (Z set), skip to 4ECAH.
4EC6
LD A,(HL) 7E
Fetch the byte at 5997H.
4EC7
XOR 0CH EE0C
Toggle bits 2 and 3.
4EC9
LD (HL),A 77
Store the modified byte back.

4ECAH - Option Flag Validation

This section loads the option flag words from 5994H-5997H and validates the combination of options. It checks for conflicting or incompatible options and adjusts flags as needed.

4ECA
LD DE,(5996H) ED5B9659
Load DE with the word at 5996H-5997H (options bytes 2-3).
4ECE
LD HL,(5994H) 2A9459
Load HL with the word at 5994H-5995H (options bytes 0-1).
4ED1
LD A,D 7A
Load A with D (5997H).
4ED2
AND 02H E602
Test bit 1 of 5997H.
4ED4
If clear, skip to 4EDAH.
4ED6
LD A,L 7D
Load A with L (5994H).
4ED7
OR 42H F642
Set bits 1 and 6.
4ED9
LD L,A 6F
Store back in L.
4EDA
LD A,E 7B
Load A with E (5996H).
4EDB
AND 13H E613
Test bits 0, 1, and 4 of 5996H.
4EDD
If any are set, skip to 4EE2H.
4EDF
LD A,D 7A
Load A with D (5997H).
4EE0
AND 30H E630
Test bits 4 and 5 of 5997H.
4EE2
If any bits set, skip to 4EE7H.
4EE4
LD A,H 7C
Load A with H (5995H).
4EE5
AND 08HAND 00001000 E608
Test bit 3 of 5995H.
4EE7
If no bits set, skip to 4EEDH.
4EE9
BIT 3,E CB5B
Test bit 3 of E (5996H).
4EEB
If clear, JUMP to 4F49H (error: conflicting options).
4EED
LD A,H 7C
Load A with H (5995H).
4EEE
AND 06H E606
Test bits 1 and 2 of 5995H.
4EF0
If both clear, skip to 4EFAH.
4EF2
BIT 2,D CB52
Test bit 2 of D (5997H).
4EF4
If set, skip to 4EFAH.
4EF6
BIT 3,E CB5B
Test bit 3 of E (5996H).
4EF8
If clear, JUMP to 4F49H (error).
4EFA
BIT 3,E CB5B
Test bit 3 of E (5996H).
4EFC
If clear, skip to 4F0CH.
4EFE
BIT 3,D CB5A
Test bit 3 of D (5997H).
4F00
If clear, skip to 4F0CH.
4F02
LD A,L 7D
Load A with L (5994H).
4F03
AND 0DH E60D
Test bits 0, 2, and 3 of 5994H.
4F05
If any set, JUMP to 4F49H (error).
4F07
LD A,H 7C
Load A with H (5995H).
4F08
AND 36H E636
Test bits 1, 2, 4, and 5 of 5995H.
4F0A
If any set, JUMP to 4F49H (error).
4F0C
LD A,H 7C
Load A with H (5995H).
4F0D
AND 41H E641
Test bits 0 and 6 of 5995H.
4F0F
If both clear, skip to 4F15H.
4F11
BIT 3,E CB5B
Test bit 3 of E (5996H).
4F13
If clear, JUMP to 4F49H (error).
4F15
LD (5994H),HL 229459
Store the validated options back to 5994H-5995H.
4F18
LD (5996H),DE ED539659
Store the validated options back to 5996H-5997H.
4F1C
RET C9
Return to caller with validated options.

4F1DH - Process Option Keyword

When an option keyword is found on the command line, this section looks it up in a table at 505CH to determine what flags to set. It matches the keyword and extracts the corresponding flag values.

4F1D
PUSH BC C5
Save BC (contains mode flag in B).
4F1E
EX DE,HL EB
Exchange DE and HL (DE now has command line pointer).
4F1F
LD HL,505CH 215C50
Point HL to the option keyword table at 505CH.
4F22
PUSH DE D5
Save DE (command line pointer).
4F23
LD A,(DE) 1A
[COMPARE LOOP] Fetch character from command line.
4F24
CP (HL) BE
Compare against table entry.
4F25
If no match, JUMP to 4F4CH to try next entry.
4F27
INC DE 13
Advance command line pointer.
4F28
INC HL 23
Advance table pointer.
4F29
[LOOP] Continue comparing characters.
4F2B
INC HL 23
[SKIP TO END OF ENTRY] Advance past current character.
4F2C
BIT 7,(HL) CB7E
Test bit 7 (end-of-keyword marker).
4F2E
If not end, keep skipping.
4F30
LD A,(HL) 7E
Fetch the flag byte (has bit 7 set).
4F31
BIT 2,A CB57
Test bit 2 of the flag byte.
4F33
INC HL 23
Advance to next byte.
4F34
If bit 2 clear, skip extra bytes.
4F36
INC HL 23
Skip 4 extra bytes if bit 2 was set.
4F37
INC HL 23
Continue skipping.
4F38
INC HL 23
Continue skipping.
4F39
INC HL 23
Continue skipping.
4F3A
BIT 4,A CB67
Test bit 4 of the flag byte.
4F3C
If clear, skip.
4F3E
INC HL 23
Skip 2 extra bytes if bit 4 was set.
4F3F
INC HL 23
Continue skipping.
4F40
POP DE D1
Discard saved command line pointer.
4F41
INC HL 23
Advance to next entry.
4F42
LD A,(HL) 7E
Fetch next table byte.
4F43
OR A B7
Test if end of table (00H).
4F44
If not end, continue with next entry.
4F46
End of table reached without match - JUMP to 5214H (unknown option error).

4F49H - Option Error Exit

This is the error exit point for conflicting or invalid option combinations. It jumps to the error handler at 5218H.

4F49
JUMP to 5218H to report option conflict error.

4F4CH - Skip to Next Option Table Entry

When an option keyword doesn't match, this section skips to the next entry in the option table by finding the end-of-keyword marker (bit 7 set).

4F4C
BIT 7,(HL) CB7E
Test bit 7 of current table byte (end-of-keyword marker).
4F4E
If not end marker, JUMP back to skip more bytes.
4F50
POP AF F1
Pop saved value (discard the saved DE as AF).
4F51
LD A,B 78
Load A with B (mode flag).
4F52
AND (HL) A6
AND mode flag with the table's validity mask.
4F53
If zero (option not valid for this mode), JUMP to error.
4F55
LD B,(HL) 46
Load B with the flag byte from table.
4F56
INC HL 23
Advance to next byte (option flag value).
4F57
LD C,(HL) 4E
Load C with the option flag value.
4F58
INC HL 23
Advance past flag value.
4F59
PUSH DE D5
Save DE.
4F5A
LD A,B 78
Load A with B (flag byte).
4F5B
AND 03H E603
Extract bits 0-1 (option byte index: 0-3).
4F5D
LD E,A 5F
Store in E.
4F5E
LD D,00H 1600
Clear D (DE now = offset 0-3).
4F60
PUSH HL E5
Save HL (table pointer).
4F61
LD HL,5994H 219459
Point HL to options base at 5994H.
4F64
PUSH HL E5
Save base address.
4F65
ADD HL,DE 19
Add offset to get target option byte.
4F66
LD A,(HL) 7E
Fetch current option byte value.
4F67
OR C B1
OR in the new flag bits from C.
4F68
LD (HL),A 77
Store updated option byte.
4F69
POP DE D1
Restore base address into DE.
4F6A
POP HL E1
Restore table pointer.
4F6B
BIT 2,B CB50
Test bit 2 of flag byte (extended data present?).
4F6D
If clear, skip extended processing.
4F6F
LD C,04H 0E04
LET C = 4 (4 bytes of extended data).
4F71
LD A,(DE) 1A
[MASK LOOP] Fetch byte from options area.
4F72
AND (HL) A6
AND with mask from table.
4F73
INC DE 13
Advance options pointer.
4F74
INC HL 23
Advance table pointer.
4F75
If result non-zero (conflict), JUMP to error.
4F77
DEC C 0D
Decrement counter.
4F78
[LOOP] Continue for all 4 bytes.
4F7A
LD E,(HL) 5E
Fetch low byte of handler address.
4F7B
INC HL 23
Advance to high byte.
4F7C
LD D,(HL) 56
Fetch high byte of handler address.
4F7D
LD (4F85H),DE ED53854F
Store handler address at 4F85H (self-modifying code!).
4F81
POP HL E1
Restore HL.
4F82
BIT 4,B CB60
Test bit 4 of flag byte (call handler?).
4F84
CALL NZ,0000H C40000
If set, CALL the handler (address was patched at 4F85H).
NOTE: The 0000H is a placeholder - the actual address was stored by the previous instruction!
4F87
POP BC C1
Restore BC.
4F88
JUMP back to 4EA7H to process more options.

4F8BH - Option Handler Entry Points

These are entry points for specific option handlers. Each sets up DE with a destination buffer address and calls a common processing routine.

4F8B
LD DE,5970H 117059
Point DE to buffer at 5970H.
4F8E
JUMP to common handler at 4F98H.
4F90
LD DE,5968H 116859
Point DE to buffer at 5968H.
4F93
JUMP to common handler at 4F98H.
4F95
LD DE,5983H 118359
Point DE to buffer at 5983H.
4F98
GOSUB to 6F8FH to process the option value.
4F9B
If Z FLAG set (error), JUMP to 4F49H.
4F9D
RET C9
Return to caller.

4F9EH - Numeric Option Parser (2-6)

This subroutine parses a single-digit numeric option value (2-6) and stores it at 64AFH.

4F9E
LD A,(HL) 7E
Fetch character from command line.
4F9F
SUB 32H D632
Subtract 32H (ASCII '2') to convert digit.
4FA1
CP 05H FE05
Check if result is 0-4 (original digit was '2'-'6').
4FA3
INC HL 23
Advance past the digit.
4FA4
If out of range, JUMP to error at 4FCBH.
4FA6
ADD 02H C602
Add 2 back to get original value (2-6).
4FA8
LD (64AFH),A 32AF64
Store the value at 64AFH.
4FAB
RET C9
Return to caller.

4FACH - Copy Name to DCB Buffer

This subroutine copies a name (up to 32 characters) from the command line to the DCB buffer at 4480H, terminated by 0DH (carriage return).

4FAC
LD DE,4480H 118044
Point DE to the DCB name buffer at 4480H.
4FAF
LD B,20H 0620
LET B = 32 (maximum characters).
4FB1
LD A,0DH 3E0D
[COPY LOOP] Load A with 0DH (terminator).
4FB3
LD (DE),A 12
Store terminator (will be overwritten if more chars).
4FB4
GOSUB to 4CD5H to check for valid filename character.
4FB7
RET Z C8
If end of name (Z set), return.
4FB8
DEC HL 2B
Back up command line pointer.
4FB9
RET NC D0
If Carry clear (invalid char), return.
4FBA
INC HL 23
Restore command line pointer.
4FBB
LD A,(HL) 7E
Fetch the valid character.
4FBC
LD (DE),A 12
Store it in the buffer.
4FBD
INC DE 13
Advance buffer pointer.
4FBE
INC HL 23
Advance command line pointer.
4FBF
[LOOP] Continue for up to 32 characters.
4FC1
If 32 chars exceeded, JUMP to error.

4FC3H - Parse Numeric Value to 64ACH

4FC3
GOSUB to 6EE7H to parse a numeric value.
4FC6
LD (64ACH),A 32AC64
Store the parsed value at 64ACH.
4FC9
OR A B7
Test if value is zero.
4FCA
RET NZ C0
If non-zero, return successfully.
4FCB
If zero (invalid), JUMP to error.

4FCEH - Parse Numeric Value to 68ABH

4FCE
GOSUB to 6EE2H to parse a numeric value.
4FD1
LD (68ABH),A 32AB68
Store the parsed value at 68ABH.
4FD4
JUMP to 4FC9H to validate and return.

4FD6H - Parse Numeric Value to 68ACH

4FD6
GOSUB to 6EE2H to parse a numeric value.
4FD9
LD (68ACH),A 32AC68
Store the parsed value at 68ACH.
4FDC
RET C9
Return to caller.

4FDDH - Parse and Store 16-bit Value at 5978H

4FDD
GOSUB to 5025H to parse a 16-bit value into DE.
4FE0
LD (5978H),DE ED537859
Store the value at 5978H.
4FE4
RET C9
Return to caller.

4FE5H - Parse and Store 16-bit Value at 5981H

4FE5
GOSUB to 5025H to parse a 16-bit value into DE.
4FE8
LD (5981H),DE ED538159
Store the value at 5981H.
4FEC
RET C9
Return to caller.

4FEDH - Parse and Store 16-bit Value at 597AH

4FED
GOSUB to 5025H to parse a 16-bit value into DE.
4FF0
LD (597AH),DE ED537A59
Store the value at 597AH.
4FF4
RET C9
Return to caller.

4FF5H - Parse Retry Count Option

4FF5
LD DE,63D6H 11D663
Point DE to parameter storage at 63D6H.
4FF8
GOSUB to 5002H to parse and validate.
4FFB
LD (4DFAH),A 32FA4D
Store the value at 4DFAH.
NOTE: This is a self-modifying write into the code area!
4FFE
RET C9
Return to caller.

4FFFH - Parse Option with Range Check

4FFF
LD DE,63CAH 11CA63
Point DE to parameter storage at 63CAH.
5002
PUSH DE D5
Save destination address.
5003
GOSUB to 6EE7H to parse numeric value.
5006
CP 0AH FE0A
Compare against 0AH (10 decimal).
5008
If >= 10, JUMP to error (value out of range).
500A
POP DE D1
Restore destination address.
500B
LD (DE),A 12
Store the validated value.
500C
RET C9
Return to caller.

500DH - Parse 3-Character Hex/Alphanumeric String

This subroutine parses up to 3 hexadecimal or alphanumeric characters from the command line and stores them at 624CH. Valid characters are 0-9 and A-Z.

500D
LD DE,624CH 114C62
Point DE to the destination buffer at 624CH.
5010
LD B,03H 0603
LET B = 3 (maximum characters to parse).
5012
LD A,(HL) 7E
[PARSE LOOP] Fetch character from command line.
5013
SUB 30H D630
Subtract 30H (ASCII '0') to convert digit.
5015
CP 0AH FE0A
Check if it was a digit 0-9.
5017
If Carry (was 0-9), JUMP to store it.
5019
SUB 11H D611
Subtract 11H more to check for A-Z (17 = 'A'-'0'-10).
501B
CP 1AH FE1A
Check if result is 0-25 (was A-Z).
501D
RET NC D0
If not a valid character, return.
501E
LD A,(HL) 7E
Fetch the original character again.
501F
LD (DE),A 12
Store it in the destination buffer.
5020
INC DE 13
Advance destination pointer.
5021
INC HL 23
Advance source pointer.
5022
[LOOP] Continue for up to 3 characters.
5024
RET C9
Return to caller.

5025H - Parse 16-bit Hexadecimal Value

This subroutine parses a 16-bit hexadecimal value from the command line and returns it in DE. It also calculates a CRC-like checksum of the input.

5025
LD DE,5960H 116059
Point DE to the temporary buffer at 5960H.
5028
GOSUB to 6F8FH to copy input to buffer.
502B
PUSH HL E5
Save HL (command line pointer).
502C
EX DE,HL EB
Exchange DE and HL (HL now points to buffer).
502D
LD DE,FFFFH 11FFFF
Initialize DE to FFFFH (starting CRC value).
5030
LD B,08H 0608
LET B = 8 (process 8 characters maximum).
5032
PUSH BC C5
[CRC LOOP] Save loop counter.
5033
LD A,E 7B
Load A with E (low byte of CRC).
5034
AND 07HAND 00000111 E607
Mask to get bits 0-2.
5036
LD C,A 4F
Save in C.
5037
LD A,E 7B
Load E again.
5038
RLCA 07
Rotate left 4 times (multiply by 16).
5039
RLCA 07
Continue rotation.
503A
RLCA 07
Continue rotation.
503B
XOR C A9
XOR with saved low bits.
503C
RLCA 07
One more rotation.
503D
LD C,A 4F
Save intermediate result.
503E
AND 0F0HAND 11110000 E6F0
Mask high nibble.
5040
LD B,A 47
Save in B.
5041
LD A,C 79
Get intermediate result.
5042
RLCA 07
Rotate left once more.
5043
AND 1FHAND 00011111 E61F
Mask to 5 bits.
5045
XOR B A8
XOR with high nibble.
5046
XOR D AA
XOR with D (high byte of CRC).
5047
LD E,A 5F
Store new low byte of CRC.
5048
LD A,C 79
Get intermediate result again.
5049
AND 0FHAND 00001111 E60F
Mask low nibble.
504B
LD B,A 47
Save in B.
504C
LD A,C 79
Get intermediate result.
504D
RLCA 07
Rotate left 4 times.
504E
RLCA 07
Continue rotation.
504F
RLCA 07
Continue rotation.
5050
RLCA 07
Continue rotation.
5051
XOR B A8
XOR with saved low nibble.
5052
POP BC C1
Restore loop counter.
5053
DEC HL 2B
Point to previous buffer byte.
5054
XOR (HL) AE
XOR with input byte.
5055
LD D,A 57
Store new high byte of CRC.
5056
LD (HL),20H 3620
Replace input byte with space (20H).
5058
[LOOP] Continue for all 8 bytes.
505A
POP HL E1
Restore command line pointer.
505B
RET C9
Return with result in DE.

505CH - Option Keyword Table (DATA)

Option keyword lookup table for FORMAT, COPY, and BACKUP commands. Each entry contains the keyword (some prefixed with 'O' for parser use), a flag/terminator byte, and parameter bytes defining option behavior, conflicts, and handlers. Prefix bytes before keywords belong to the previous entry's parameters.

505C
DEFM "CFWO" 43 46 57 4F
CFWO - Check File With Operator.
5060
DEFB A1H,40H A1 40
Flag A1H, param 40H.
5062
DEFM "DDGA=" 44 44 47 41 3D
DDGA= - Destination Directory Granule Allocation.
5067
DEFB F5H,02H,00H,00H,00H,0AH,9EH F5 02 00 00 00 0A 9E
Flag F5H, type 02H, handler at 9E0AH.
506E
DEFB 4FH 4F
'O' prefix byte.
506F
DEFM "ODPW=" 4F 44 50 57 3D
ODPW= - Old Destination Password.
5074
DEFB B5H,01H,C0H,00H,00H,00H B5 01 C0 00 00 00
Flag B5H, type 01H, mask C0H.
507A
DEFB EDH,4FH ED 4F
Prefix bytes (EDH + 'O').
507C
DEFM "NDPW=" 4E 44 50 57 3D
NDPW= - New Destination Password.
5081
DEFB B5H,20H,02H,00H,00H,00H B5 20 02 00 00 00
Flag B5H, sets bit 5, type 02H.
5087
DEFB E5H,4FH E5 4F
Prefix bytes (E5H + 'O').
5089
DEFM "DDSL=" 44 44 53 4C 3D
DDSL= - Destination Directory Starting Lump.
508E
DEFB F5H,04H,00H,00H,00H,0AH F5 04 00 00 00 0A
Flag F5H, type 04H.
5094
DEFB C3H,4FH C3 4F
Prefix bytes (C3H + 'O').
5096
DEFM "SPDN=" 53 50 44 4E 3D
SPDN= - Source PDrive Number (0-9).
509B
DEFB BBH,80H,FFH BB 80 FF
Flag BBH, sets bit 7, mask FFH.
509E
DEFB 4FH 4F
'O' prefix byte.
509F
DEFM "DPDN=" 44 50 44 4E 3D
DPDN= - Destination PDrive Number (0-9).
50A4
DEFB FBH,40H FB 40
Flag FBH, sets bit 6.
50A6
DEFB F5H,4FH F5 4F
Prefix bytes (F5H + 'O').
50A8
DEFM "PFST=" 50 46 53 54 3D
PFST= - Partial Format Starting Track.
50AD
DEFB D7H,02H,B9H,86H,00H,00H D7 02 B9 86 00 00
Flag D7H, type 02H, handler at 86B9H.
50B3
DEFB D6H,4FH D6 4F
Prefix bytes (D6H + 'O').
50B5
DEFM "PFTC=" 50 46 54 43 3D
PFTC= - Partial Format Track Count.
50BA
DEFB D3H,01H D3 01
Flag D3H, type 01H.
50BC
DEFB CEH,4FH CE 4F
Prefix bytes (CEH + 'O').
50BE
DEFM "NDN=" 4E 44 4E 3D
NDN= - New Destination Name.
50C2
DEFB B4H,04H,0AH,00H,00H,00H B4 04 0A 00 00 00
Flag B4H, type 04H.
50C8
DEFB 95H,4FH 95 4F
Prefix bytes (95H + 'O').
50CA
DEFM "ODN=" 4F 44 4E 3D
ODN= - Old Destination Name (verify match).
50CE
DEFB F4H,10H,C0H,00H,00H,02H F4 10 C0 00 00 02
Flag F4H, sets bit 4, mask C0H.
50D4
DEFB 8BH,4FH 8B 4F
Prefix bytes (8BH + 'O').
50D6
DEFM "DDND" 44 44 4E 44
DDND - Display Destination Name and Date.
50DA
DEFB E4H,20H,C0H,80H,00H,02H E4 20 C0 80 00 02
Flag E4H, sets bit 5, mask C0H.
50E0
DEFM "NDMW" 4E 44 4D 57
NDMW - No Diskette Mount Waits.
50E4
DEFB E5H,80H,20H,00H,00H,00H E5 80 20 00 00 00
Flag E5H, sets bit 7, mask 20H.
50EA
DEFM "SPW=" 53 50 57 3D
SPW= - Source Password.
50EE
DEFB B2H,40H B2 40
Flag B2H, sets bit 6.
50F0
DEFB DDH,4FH DD 4F
Prefix bytes (DDH + 'O').
50F2
DEFM "NFMT" 4E 46 4D 54
NFMT - No Format. Dest must be pre-formatted.
50F6
DEFB A7H,08H,00H,06H,00H,04H A7 08 00 06 00 04
Flag A7H, sets bit 3. Conflicts with FMT.
50FC
DEFM "XLF=" 58 4C 46 3D
XLF= - Exclusion List File.
5100
DEFB B7H,20H,00H,00H,00H,10H B7 20 00 00 00 10
Flag B7H, sets bit 5. Conflicts with ILF.
5106
DEFB ACH,4FH AC 4F
Prefix bytes (ACH + 'O').
5108
DEFM "ILF=" 49 4C 46 3D
ILF= - Include List File.
510C
DEFB B7H,10H,00H,00H,00H,20H B7 10 00 00 00 20
Flag B7H, sets bit 4. Conflicts with XLF.
5112
DEFB ACH,4FH AC 4F
Prefix bytes (ACH + 'O').
5114
DEFM "KDN" 4B 44 4E
KDN - Keep Destination Name.
5117
DEFB E4H,08H,C6H,00H,00H,02H E4 08 C6 00 00 02
Flag E4H, sets bit 3. Conflicts with NDN, BDU.
511D
DEFM "SN=" 53 4E 3D
SN= - Source Name (verify match).
5120
DEFB B2H,80H B2 80
Flag B2H, sets bit 7.
5122
DEFB 90H,4FH 90 4F
Prefix bytes (90H + 'O').
5124
DEFM "KDD" 4B 44 44
KDD - Keep Destination Date.
5127
DEFB E4H,01H,C2H,10H,00H,02H E4 01 C2 10 00 02
Flag E4H, sets bit 0. Conflicts with USD, BDU.
512D
DEFM "USD" 55 53 44
USD - Use Source Date.
5130
DEFB A5H,10H,03H,00H,00H,00H A5 10 03 00 00 00
Flag A5H, sets bit 4. Conflicts with KDD, BDU.
5136
DEFM "BDU" 42 44 55
BDU - Bypass Directory Update.
5139
DEFB E4H,02H,0CH,30H,08H,00H E4 02 0C 30 08 00
Flag E4H, sets bit 1. Conflicts with KDN, NDN, NDPW, USD.
513F
DEFM "UBB" 55 42 42
UBB - Use Big Buffer (obsolete in v2).
5142
DEFB A2H,20H A2 20
Flag A2H, sets bit 5.
5144
DEFB 43H 43
Prefix byte ('C').
5145
DEFM "CBF" 43 42 46
CBF - Copy By File (format 6 mode).
5148
DEFB A6H,08H,02H,00H,00H,00H A6 08 02 00 00 00
Flag A6H, sets bit 3.
514D
DEFM "UPD" 55 50 44
UPD - Copy Updated files only.
5150
DEFB A2H,01H A2 01
Flag A2H, sets bit 0.
5152
DEFB 55H 55
Prefix byte ('U').
5153
DEFM "USR" 55 53 52
USR - Copy User files only.
5156
DEFB A2H,10H A2 10
Flag A2H, sets bit 4.
5158
DEFM "DFO" 44 46 4F
DFO - (internal option).
515B
DEFB A5H,08H,00H,00H,00H,04H A5 08 00 00 00 04
Flag A5H, sets bit 3.
5161
DEFB 04H 04
Prefix byte.
5162
DEFM "RWF" 52 57 46
RWF - (internal option).
5165
DEFB C6H,80H,09H,06H,00H,02H C6 80 09 06 00 02
Flag C6H, sets bit 7.
516B
DEFM "FMT" 46 4D 54
FMT - Format destination disk before copy.
516E
DEFB A7H,04H,00H,08H,00H,08H A7 04 00 08 00 08
Flag A7H, sets bit 2. Conflicts with NFMT.
5174
DEFM "/" 2F
/ext - Copy files with specified extension only.
5175
DEFB B2H,02H,0DH B2 02 0D
Flag B2H, type 02H, max 13 chars.
5178
DEFB 50H 50
Prefix byte ('P').
5179
DEFM "Y" 59
Y - Yes to all prompts.
517A
DEFB E4H,40H,B9H,01H,00H,00H E4 40 B9 01 00 00
Flag E4H, sets bit 6.
5180
DEFM "N" 4E
N - No to format prompt.
5181
DEFB E4H,80H,79H,01H,00H,02H E4 80 79 01 00 02
Flag E4H, sets bit 7.
5187
DEFB 00H 00
End of table - NUL terminator.

5186H-51FFH - NO CODE PRESENT


5200H - Error Exit Points

This section contains multiple error exit entry points. Each loads a specific error code into Register A and jumps to the common error handler at 521AH. The error codes correspond to NEWDOS/80 error numbers.

5200
LD A,20H 3E20
Load error code 20H (32 decimal: "DISK SPACE FULL").
5202
JUMP to common error handler.
5204
LD A,3CH 3E3C
Load error code 3CH (60 decimal).
5206
JUMP to common error handler.
5208
LD A,2AH 3E2A
Load error code 2AH (42 decimal: "PARAMETER ERROR").
520A
JUMP to common error handler.
520C
LD A,2CH 3E2C
Load error code 2CH (44 decimal).
520E
JUMP to common error handler.
5210
LD A,(HL) 7E
Fetch character from command line.
5211
CP 0DH FE0D
Compare against 0DH (carriage return - end of line).
5213
RET Z C8
If end of line, return (no error).
5214
LD A,34H 3E34
Load error code 34H (52 decimal: "ILLEGAL PARAMETER").
5216
JUMP to common error handler.
5218
LD A,2FH 3E2F
Load error code 2FH (47 decimal: "CONFLICTING PARAMETERS").

521AH - Common Error Handler Entry

This is the common error handler for SYS6. It saves the error code, calls cleanup routines, then invokes the DOS error display mechanism. The handler restores system state before reporting the error.

521A
PUSH AF F5
Save the error code on the stack.
521B
GOSUB to 5881H to perform cleanup operations.
521E
POP AF F1
Restore the error code into A.
521F
LD HL,4409H 210944
Point HL to 4409H (DOS error handler entry point).
5222
PUSH HL E5
Push the error handler address onto the stack (return address).
5223
PUSH AF F5
Push the error code again.
5224
GOSUB to 5582H for additional cleanup.
5227
LD A,(593BH) 3A3B59
Fetch the status byte from 593BH.
522A
BIT 7,A CB7F
Test bit 7 (special mode flag).
522C
If clear, skip to 5235H.
522E
LD B,05H 06 05
Load Register B with 05H, the retry count for the multi-disk flush operation.
5230
Call subroutine at 5646H to flush all drive buffers. This ensures pending disk operations are completed before error exit.
5233
If the flush failed (NZ), JUMP to 523CH to handle the flush error.
5235
LD HL,4369H 21 69 43
Load HL with 4369H, the address of the DOS status flags byte.
5238
RES 3,(HL) CB 9E
Reset bit 3 of the DOS status flags to clear the "operation in progress" flag.
523A
POP AF F1
Restore the error code from the stack (was pushed at 5223H).
523B
RET C9
RETURN to caller with error code in Register A.

523CH - Flush Error Handler

This code handles the case where the buffer flush at 5230H failed. It displays an error message and then loops back to retry the error exit sequence.

523C
PUSH AF F5
Save the flush error code on the stack.
523D
LD A,46H 3E 46
Load Register A with 46H ('F'), the code for a file/flush error message.
523F
RST 18H DF
Call RST 18H to compare or process the error type.
5240
LD HL,5AC2H 21 C2 5A
Load HL with 5AC2H, the address of an error message string.
5243
Call subroutine at 5881H to display the error message to the user.
5246
Call the DOS print message routine at 4467H to output the message.
5249
LD HL,4030H 21 30 40
Load HL with 4030H, a return address or continuation point.
524C
JUMP back to 5222H to retry the error exit sequence.

524EH - Format Buffer Initialization

This routine initializes the format buffer by loading the current buffer pointers and preparing for the track data relocation.

524E
LD HL,(5D14H) 2A 14 5D
Load HL with the buffer end pointer from 5D14H. This marks where the track buffer data currently ends.
5251
LD DE,(5D12H) ED 5B 12 5D
Load DE with the buffer start pointer from 5D12H. This marks where the track buffer data begins.
5255
OR A B7
Clear the Carry flag to prepare for a 16-bit subtraction. This ensures SBC HL,DE will calculate the true difference without borrowing.
5256
SBC HL,DE ED 52
Subtract DE from HL: HL = (5D14H) - (5D12H). This calculates the size of the data block that needs to be relocated. The result in HL is the byte count.
5258
LD B,H 44
Copy the high byte of the block size to Register B. BC will hold the byte count for the LDIR instruction.
5259
LD C,L 4D
Copy the low byte of the block size to Register C. Now BC = block size for the upcoming block move.
525A
PUSH DE D5
Save the original start pointer (5D12H contents) on the stack. This will be the source address for the LDIR block copy.
525B
LD HL,5D16H 21 16 5D
Load HL with 5D16H, the new destination address for the track buffer data. This is where the data will be relocated to.
525E
LD (5D12H),HL 22 12 5D
Update the start pointer at 5D12H to point to the new location (5D16H). The buffer's base address is now updated.
5261
PUSH HL E5
Save the new start address (5D16H) on the stack for later use.
5262
EX DE,HL EB
Exchange DE and HL. Now DE = 5D16H (destination) and HL is free for the source address.
5263
LDIR ED B0
Block copy: Move BC bytes from (HL) to (DE), incrementing both pointers. This relocates the track buffer data from its old location to 5D16H.
5265
LD (5D14H),DE ED 53 14 5D
Update the end pointer at 5D14H to the new end position after the block move. DE now points past the last byte copied.
5269
Call the format preparation subroutine at 5578H. This initializes additional format parameters.
526C
POP HL E1
Restore the new buffer start address (5D16H) from the stack into HL.
526D
Call the format status check subroutine at 56A6H. This checks if the format operation should continue. Returns Z flag if complete.
5270
If the Z flag is set (format complete or no more work), JUMP to 552DH to finalize the format operation.

Format is not complete - display status and calculate how many tracks can be formatted with available memory.

5273
LD HL,627BH 21 7B 62
Load HL with the address of a status message at 627BH to display formatting progress.
5276
Call the message display subroutine at 587EH to show the formatting status to the user.
5279
LD HL,(593CH) 2A 3C 59
Load HL with the memory limit stored at 593CH. This is the high memory boundary for the format buffer.
527C
LD DE,(5D14H) ED 5B 14 5D
Load DE with the current end pointer from 5D14H (where track data ends).
5280
OR A B7
Clear the Carry flag for subtraction.
5281
SBC HL,DE ED 52
Calculate HL = memory limit - current position. This gives the available memory remaining for track formatting.
5283
LD DE,0102H 11 02 01
Load DE with 0102H (258 bytes). This is the size of one track entry in the format table (256 bytes of sector data + 2 bytes overhead).
5286
LD A,FFH 3E FF
Initialize Register A to FFH (-1). The following loop will count how many tracks can fit.

[LOOP START] - Count how many track entries (258 bytes each) can fit in the remaining memory.

5288
INC A 3C
Increment the track counter in Register A. First iteration makes it 00H.
5289
OR A B7
Clear the Carry flag for the next subtraction.
528A
SBC HL,DE ED 52
Subtract one track entry size (258 bytes) from the remaining memory in HL.
528C
If no borrow (memory still available), [LOOP] back to 5288H to count another track. Continue until we run out of space.

[LOOP END] - Register A now contains the number of tracks that can be formatted in one batch.

528E
LD (531AH),A 32 1A 53
Store the track batch count in the self-modifying code location at 531AH. This will be used as the loop limit.
5291
LD HL,594CH 21 4C 59
Load HL with address 594CH, which holds the source drive number for the format operation.
5294
Call subroutine at 5538H to set up the drive for the format operation based on the drive number at (HL).
5297
XOR A AF
Clear Register A to zero. This initializes the track counter for the upcoming format loop.
5298
LD HL,(5D14H) 2A 14 5D
Load HL with the current track table end pointer from 5D14H. New track entries will be added here.
529B
JUMP forward to 5316H to enter the main track formatting loop at the loop test point.

529DH - Main Track Formatting Loop

[MAIN LOOP START] - This loop reads each track from the source disk and stores it in the track buffer. Each iteration handles one track.

529D
PUSH HL E5
Save the current track table pointer on the stack. HL points to where this track's data will be stored.
529E
INC HL 23
Increment HL past the first byte of the track entry (track number marker).
529F
INC HL 23
Increment HL again past the second byte (status byte). HL now points to the sector data area.
52A0
LD (5AE8H),HL 22 E8 5A
Store this address at 5AE8H as the destination buffer for the upcoming disk read operation.
52A3
LD A,80H 3E 80
Load Register A with 80H (128), the read sector command flag for the disk operation.
52A5
LD (57EBH),A 32 EB 57
Store the command flag at 57EBH. This location controls the disk I/O operation type.
52A8
Call the disk read subroutine at 57C8H to read the current track's sectors from disk. Returns status in A.
52AB
If Z flag set (successful read), JUMP to 52CFH to continue with the next step.
52AD
CP 06H FE 06
Compare the error code with 06H (Record Not Found). This error is expected for unformatted tracks.
52AF
If Record Not Found error, JUMP to 52D0H to handle the unformatted track case.
52B1
CP 1CH FE 1C
Compare with error code 1CH (End of Data on track).
52B3
If End of Data, JUMP to 52B9H to check if this is a COPY operation that needs special handling.
52B5
CP 1DH FE 1D
Compare with error code 1DH (End of Track encountered).
52B7
If NOT End of Track error, JUMP to 52CAH to handle the error and possibly retry.

Error 1CH or 1DH occurred - check if COPY option is set which requires special end-of-track handling.

52B9
LD HL,0000H 21 00 00
Load HL with 0000H. This will be used to signal end-of-disk if COPY mode confirms completion.
52BC
LD A,(5996H) 3A 96 59
Load the option flags byte 3 from 5996H to check the COPY option status.
52BF
AND 08HAND 00001000 E6 08
Mask with bit 3 to test the COPY option flag. Z flag set if COPY is NOT active.
52C1
If COPY option IS active (NZ), CALL 56A2H to verify this is a valid end-of-disk condition.
52C4
If confirmed as end-of-disk (Z set), JUMP to 549CH to finish the copy operation.
52C7
POP HL E1
Restore the track table pointer from the stack.
52C8
[LOOP] - Jump back to retry reading this track from the beginning.

Disk error occurred that wasn't an expected end condition - attempt error recovery.

52CA
Call the error handler at 585AH. This displays the error and asks user to retry or abort.
52CD
If user chose to retry (NZ), JUMP back to 52A8H to attempt the disk read again.

Read succeeded (or user chose to skip) - store the track entry in the buffer.

52CF
XOR A AF
Clear Register A to zero. This indicates a successful read with no error code.

52D0H - Store Track Entry in Buffer

At this point, either the track was read successfully (A=00) or a "Record Not Found" error occurred (A=06), indicating an unformatted track. The code stores the track marker and status in the track table.

52D0
POP HL E1
Restore the track table pointer from the stack. HL points to the start of this track's entry.
52D1
LD (HL),FFH 36 FF
Store FFH as the track marker byte. This indicates a valid track entry in the format buffer.
52D3
INC HL 23
Advance to the status byte position in the track entry.
52D4
LD (HL),A 77
Store the read status in Register A (00=success, 06=not formatted). This records whether the track had readable data.
52D5
INC HL 23
Advance HL to point past the status byte, to the sector data area of this track entry.
52D6
Call subroutine at 571BH to update the track number and advance to the next track position on disk.
52D9
PUSH HL E5
Save the current position (pointing into sector data) on the stack.
52DA
EX DE,HL EB
Move the sector data pointer to DE. This will be the destination for any boot sector copy.
52DB
LD A,(5996H) 3A 96 59
Load the option flags byte 3 from 5996H to check format options.
52DE
AND 0CH E6 0C
Mask with bits 2-3 (COPY and BACKUP options). Z flag set if neither option is active.
52E0
If COPY or BACKUP option is set (NZ), skip the boot sector logic and JUMP to 5311H.

FORMAT only (no COPY/BACKUP) - check if this is track 0 and if we need to copy the boot sector template.

52E2
LD A,(5994H) 3A 94 59
Load the option flags byte 1 from 5994H.
52E5
BIT 1,A CB 4F
Test bit 1 - the "skip boot sector" option. Z flag set if boot sector should be included.
52E7
If skip boot sector flag is set (NZ), JUMP to 5311H to bypass boot sector copying.
52E9
LD HL,(5AEFH) 2A EF 5A
Load HL with the current track number from 5AEFH (stored as 16-bit value).
52EC
DEC HL 2B
Decrement to get track-1 (so track 0 becomes FFFFH when checked, but track 1 becomes 0000H).
52ED
LD A,H 7C
Load the high byte of (track-1) into A.
52EE
OR A B7
Test if high byte is non-zero. If track was 0, H would be FFH after DEC, so this would be NZ.
52EF
If high byte non-zero, this is not track 0 or 1, JUMP to 5311H to skip boot sector copy.
52F1
LD A,L 7D
Load the low byte of (track-1) into A.
52F2
CP 02H FE 02
Compare with 02H. If track was 0, L=FFH (NC). If track was 1, L=00H (C). If track was 2, L=01H (C).
52F4
If L >= 02H (No Carry), JUMP to 52FEH. This happens for track 0 (L=FFH), or tracks 3+.

Track 1 or 2 - copy the directory boot sector template from 64BAH.

52F6
LD HL,64BAH 21 BA 64
Load HL with 64BAH, the address of the directory boot sector template.
52F9
Call subroutine at 5C80H to set up BC with the sector size (256 bytes) for the copy operation.
52FC
JUMP to 530FH to perform the LDIR copy of the boot sector template.

Check if this is track 0 and if the track data contains a valid boot sector signature.

52FE
If L != 02H after earlier compare (meaning not track 0), JUMP to 5311H to skip.
5300
LD HL,00EFH 21 EF 00
Load HL with offset 00EFH (239). This is the location of the boot sector signature within the sector.
5303
ADD HL,DE 19
Add the sector data base address (DE) to get the absolute address of the signature byte.
5304
LD A,(HL) 7E
Load the byte at the signature position.
5305
CP A5H FE A5
Compare with A5H, the NEWDOS/80 boot sector signature. Z flag set if valid signature found.
5307
If signature invalid (NZ), JUMP to 5311H - don't copy the boot sector overlay.

Valid NEWDOS/80 boot sector found - copy the 16-byte boot overlay from 6EB5H.

5309
LD HL,6EB5H 21 B5 6E
Load HL with 6EB5H, the address of the boot sector overlay data (16 bytes).
530C
LD BC,0010H 01 00 10
Load BC with 0010H (16), the number of bytes to copy from the overlay.
530F
LDIR ED B0
Block copy BC bytes from (HL) to (DE). Copy the boot sector template or overlay to the track buffer.
5311
POP HL E1
Restore the sector data pointer from the stack.
5312
INC H 24
Increment H to advance HL by 256 bytes, moving to the next track entry in the buffer.
5313
LD A,00H 3E 00
Load A with 00H. Note: This is self-modifying code - the immediate value at 5314H is updated at runtime.
5315
INC A 3C
Increment the track counter in A.
5316
LD (5314H),A 32 14 53
Store the updated track counter back to 5314H (the immediate value in the LD A,nn instruction above).
5319
CP 0AH FE 0A
Compare track counter with 0AH. Note: The 0AH at 531AH is also self-modifying - set at 528EH to the batch size.
531B
If counter < batch limit (Carry set), [LOOP] back to 529DH to process the next track.

[BATCH COMPLETE] - All tracks in this batch have been read. Now write them to the destination disk.

531E
Call the batch write subroutine at 5324H to write all buffered tracks to the destination disk.
5321
JUMP back to 5291H to set up and process the next batch of tracks.

5324H - Write Track Batch to Destination

This subroutine writes all the tracks that were read into the buffer to the destination disk. It handles COPY/BACKUP modes which may write to a different drive.

5324
Call subroutine at 5535H to switch to the destination drive for writing.
5327
LD A,(5314H) 3A 14 53
Load the track counter from 5314H (number of tracks that were read in this batch).
532A
OR A B7
Test if the track counter is zero. Z flag set if no tracks were read.
532B
RET Z C8
If no tracks to write (Z), RETURN immediately - nothing to do.
532C
LD HL,(5D14H) 2A 14 5D
Load HL with the current buffer end pointer from 5D14H. This points past the last track entry.
532F
LD (544FH),HL 22 4F 54
Store this end pointer at 544FH for later reference during the write loop.
5332
LD DE,(5B21H) ED 5B 21 5B
Load DE with the remaining granule count from 5B21H (used for space tracking in COPY/BACKUP).
5336
LD (5401H),DE ED 53 01 54
Store this value at 5401H for use in the write operation tracking.
533A
XOR A AF
Clear Register A to zero.
533B
LD (53ECH),A 32 EC 53
Initialize the write status flag at 53ECH to zero (no writes performed yet).
533E
PUSH HL E5
Save the current buffer pointer on the stack.
533F
LD A,(5996H) 3A 96 59
Load the option flags byte 3 from 5996H to check COPY/BACKUP settings.
5342
AND 0CH E6 0C
Mask with bits 2-3 (COPY=08H and BACKUP=04H options). Z if neither set.
5344
If pure FORMAT (no COPY/BACKUP), JUMP to 53D5H to perform a simple write.
5347
AND 08HAND 00001000 E6 08
Test bit 3 specifically - the COPY option. Z if this is BACKUP (not COPY).
5349
If BACKUP mode (bit 3 clear), JUMP to 5360H to handle BACKUP-specific logic.

COPY mode - verify source and destination tracks match before writing.

534B
LD A,(HL) 7E
Load the track marker byte from the current buffer entry.
534C
CP (IX+07H) DD BE 07
Compare with the destination track number at IX+07H. Checks if source and destination tracks are aligned.
534F
If tracks match (Z), JUMP to 5360H to proceed with the write.

Track mismatch in COPY - need to seek to correct track on destination before writing.

5351
PUSH AF F5
Save the source track number (from the buffer entry) on the stack.
5352
Call subroutine at 53FBH to finalize any pending write operations.
5355
POP AF F1
Restore the source track number to Register A.
5356
LD IX,5B17H DD 21 17 5B
Load IX with 5B17H, the address of the destination drive control block.
535A
Call subroutine at 56B9H to seek to the specified track on the destination drive.
535D
POP HL E1
Restore the buffer pointer from the stack.
535E
JUMP back to 532FH to retry the write with the destination now on the correct track.

5360H - COPY/BACKUP Granule Allocation Check

This section handles space allocation for COPY and BACKUP operations. It checks if there's room on the destination disk before writing.

5360
LD HL,(5B21H) 2A 21 5B
Load HL with the remaining granule count from 5B21H for the destination disk.
5363
LD A,H 7C
Load the high byte of the granule count into Register A.
5364
OR L B5
OR with the low byte. Z flag set if remaining granules = 0000H (disk full or newly formatted).
5365
If granules remaining (NZ), JUMP to 53D5H to proceed with the write operation.

No granules allocated yet - need to request allocation from destination disk's directory.

5367
XOR A AF
Clear Register A to zero.
5368
LD (53D7H),A 32 D7 53
Store zero at 53D7H (the self-modifying location in the write loop). This initializes the retry flag.
536B
LD A,(5996H) 3A 96 59
Load the option flags byte 3 from 5996H.
536E
BIT 3,A CB 5F
Test bit 3 - the COPY option flag. Z if BACKUP mode, NZ if COPY mode.
5370
PUSH HL E5
Save the granule count (0000H) on the stack.
5371
LD HL,(5AF1H) 2A F1 5A
Load HL with the source disk's total granules from 5AF1H (for BACKUP mode default).
5374
LD A,(5AEDH) 3A ED 5A
Load Register A with the source disk type byte from 5AEDH.
5377
If BACKUP mode (Z flag from bit test at 536E), JUMP to 537FH to use source disk values.

COPY mode - use destination disk's granule parameters instead of source.

5379
LD HL,(5B23H) 2A 23 5B
Load HL with the destination disk's total granules from 5B23H.
537C
LD A,(5B1FH) 3A 1F 5B
Load Register A with the destination disk type byte from 5B1FH.
537F
OR A B7
Test the disk type byte. Z if zero (standard single-density disk).
5380
If non-zero disk type (NZ), JUMP to 5383H to skip the decrement.
5382
DEC HL 2B
Decrement the granule count by 1. For standard disks, adjust for system granule reservation.
5383
LD A,H 7C
Load high byte of the granule count into A.
5384
AND L A5
AND high and low bytes together. Result is FFH only if both bytes are FFH.
5385
INC A 3C
Increment A. If HL was FFFFH (no granules available), A becomes 00H and Z flag is set.
5386
If no granules available (Z), JUMP to 53D1H to skip allocation and continue.
5388
LD (5B21H),HL 22 21 5B
Store the granule count at 5B21H as the number of granules to allocate for this operation.
538B
LD HL,436BH 21 6B 43
Load HL with 436BH, the address of the DOS control byte in the work area.
538E
SET 1,(HL) CB CE
Set bit 1 of the control byte to enable special allocation mode for the upcoming disk operation.
5390
Call the disk allocation subroutine at 57CEH to request granules from the destination disk.
5393
RES 1,(HL) CB 8E
Reset bit 1 of the control byte to restore normal operation mode.
5395
If allocation failed or no space (Z), JUMP to 53D1H to handle the error condition.

Allocation returned an error - check if it's a recoverable condition.

5397
PUSH AF F5
Save the error code on the stack.
5398
LD HL,5995H 21 95 59
Load HL with address 5995H (option flags byte 2).
539B
BIT 7,(HL) CB 7E
Test bit 7 - the "abort on error" flag. NZ if abort is requested.
539D
If abort flag set (NZ), JUMP to 53ADH to display error and abort.
539F
LD HL,5996H 21 96 59
Load HL with address 5996H (option flags byte 3).
53A2
BIT 2,(HL) CB 56
Test bit 2 - the BACKUP flag. NZ if BACKUP mode is active.
53A4
If BACKUP mode (NZ), JUMP to the error handler at 521EH. BACKUP errors are more serious.
53A7
SUB 1AH D6 1A
Subtract 1AH (26) from the error code. Adjusts error code for comparison.
53A9
CP 02H FE 02
Compare adjusted error with 02H. Checks if error is 1AH or 1BH (disk full conditions).
53AB
If error 1AH or 1BH (Carry set), JUMP to 53B3H to handle disk full gracefully.
53AD
Call error display subroutine at 5868H to show the disk error to the user.
53B0
JUMP to the error handler at 521EH to abort the operation.

Disk full condition - finalize the partial copy and prepare to complete.

53B3
Call subroutine at 56DDH to get the directory entry address for the file being written.
53B6
INC HL 23
Advance to the first data field in the directory entry.
53B7
INC HL 23
Advance to the second data field.
53B8
INC HL 23
Advance to the third field - the file attributes byte.
53B9
XOR A AF
Clear Register A to zero.
53BA
LD (HL),A 77
Clear the file attributes byte to indicate the file is incomplete or needs attention.
53BB
LD DE,0011H 11 11 00
Load DE with 0011H (17), the offset to the granule allocation area of the directory entry.
53BE
ADD HL,DE 19
Add offset to HL to point to the first granule pointer in the directory entry.
53BF
LD (HL),A 77
Clear the first granule pointer (set to 00H indicating no allocation yet).
53C0
INC HL 23
Advance to the next byte in the directory entry.
53C1
LD (HL),A 77
Clear the second byte of the granule allocation.
53C2
Call subroutine at 5711H to write the updated directory entry back to disk.
53C5
POP HL E1
Discard the saved error code from the stack (was pushed at 5397H).
53C6
LD HL,5AD8H 21 D8 5A
Load HL with 5AD8H, the address of a "disk full" message.
53C9
Call subroutine at 586FH to display the disk full notification to the user.
53CC
LD A,FFH 3E FF
Load Register A with FFH to set the "disk full encountered" flag.
53CE
LD (53D7H),A 32 D7 53
Store FFH at 53D7H (the self-modifying location) to flag that disk is full.
53D1
POP HL E1
Restore the granule count value from the stack (pushed at 5370H).
53D2
LD (5B21H),HL 22 21 5B
Store the granule count back at 5B21H.

53D5H - Write Track to Destination Disk

This is the actual track write section. It processes each track in the buffer and writes it to the destination disk.

53D5
POP HL E1
Restore the track buffer pointer from the stack (pushed at 533EH). HL points to current track entry.
53D6
LD A,00H 3E 00
Load A with 00H. Note: This is self-modifying code at 53D7H - updated to FFH when disk is full.
53D8
OR A B7
Test the disk full flag. Z if no disk full condition, NZ if disk is full.
53D9
If disk not full (Z), JUMP to 53DFH to proceed with writing.
53DB
Call subroutine at 585EH to display a status message (disk full warning during write).
53DE
DEC A 3D
Decrement A. If A was 01H (from skip), Z flag will be set.
53DF
If Z flag set (write needed), CALL 546DH to perform the actual sector write operation.
53E2
INC HL 23
Advance HL past the track marker byte.
53E3
If the write was successful or skipped (Z), JUMP to 53E6H to skip storing status.
53E5
LD (HL),A 77
Store the write status/error code in the track entry's status byte.
53E6
INC HL 23
Advance HL past the status byte.
53E7
INC H 24
Increment H to advance HL by 256 bytes, moving to the next track entry in the buffer.
53E8
Call subroutine at 571BH to update the track counter and position for the next track.
53EB
LD A,00H 3E 00
Load A with 00H. Note: This is self-modifying code at 53ECH - the write counter.
53ED
INC A 3C
Increment the write counter.
53EE
LD (53ECH),A 32 EC 53
Store the updated write counter back at 53ECH.
53F1
LD A,(5314H) 3A 14 53
Load the remaining track count from 5314H (how many tracks left to write in this batch).
53F4
DEC A 3D
Decrement the remaining track count.
53F5
LD (5314H),A 32 14 53
Store the updated count back at 5314H.
53F8
If tracks remaining (NZ), [LOOP] back to 533EH to write the next track.

53FBH - Finalize Write Batch

This subroutine is called when a write batch is complete or when switching tracks during COPY. It ensures all pending operations are completed.

53FB
LD A,(53ECH) 3A EC 53
Load the write counter from 53ECH (number of tracks successfully written).
53FE
OR A B7
Test if any tracks were written. Z flag set if counter is zero.
53FF
RET Z C8
If no tracks were written (Z), RETURN immediately - nothing to finalize.

5400H - Post-Write Verification Loop

After writing tracks to the destination disk, this code performs verification by reading back the data to ensure it was written correctly. This is part of the FORMAT/COPY/BACKUP verification phase.

5400
LD HL,0000H 21 00 00
Load HL with 0000H. Note: This is self-modifying code at 5401H - updated with granule count at 5336H.
5403
LD (5B21H),HL 22 21 5B
Store the granule count at 5B21H to restore the original value for the next batch.
5406
LD HL,(5D10H) 2A 10 5D
Load HL with the sector data pointer from 5D10H for the verification read.
5409
LD (5B1AH),HL 22 1A 5B
Store this pointer at 5B1AH for the disk I/O routine to use as the buffer address.
540C
LD A,20H 3E 20
Load Register A with 20H, the verify/read-after-write command flag.
540E
LD (57EBH),A 32 EB 57
Store the command flag at 57EBH to set the operation mode to verify.
5411
LD HL,(544FH) 2A 4F 54
Load HL with the track buffer end pointer from 544FH (saved at 532FH).
5414
INC HL 23
Advance to the status byte of the current track entry.
5415
LD A,(HL) 7E
Load the track status byte into Register A.
5416
INC A 3C
Increment A. If status was FFH (end marker), A becomes 00H and Z flag is set.
5417
If end marker found (Z), CALL 585EH to display appropriate status message.
541A
If end marker found (Z), JUMP to 544EH to finish this verification batch.
541C
Call the disk read subroutine at 57C8H to read back the track for verification.
541F
If read error (NZ), JUMP to 5422H to keep the error code.
5421
XOR A AF
Clear Register A to zero on successful read.
5422
If read was successful (Z), JUMP to 5428H to compare with original status.
5424
CP 06H FE 06
Compare error code with 06H (Record Not Found). This is expected for unformatted tracks.
5426
If NOT Record Not Found (NZ), JUMP to 5430H to handle the error.
5428
CP (HL) BE
Compare the read status with the original write status stored in the track entry.
5429
If statuses match (Z), JUMP to 5440H to continue verification.

Status mismatch - the track didn't verify correctly. Update granule count and flag error.

542B
Call subroutine at 5492H to decrement the remaining granule count (one track failed).
542E
LD A,31H 3E 31
Load Register A with 31H, the error code for "verification failed".
5430
DEC HL 2B
Move HL back to point to the track marker byte.
5431
Call the error handler at 585AH to display the error and ask user to retry or abort.
5434
If user chose to skip (Z), JUMP to 544EH to finish this batch.
5436
Call subroutine at 546DH to re-write the track and retry the operation.
5439
If re-write failed (NZ), JUMP to 544EH to finish this batch.
543B
Call subroutine at 5492H to decrement the granule count after the retry.
543E
[LOOP] - Jump back to 5406H to verify the re-written track.

Track verified successfully - compare the sector data with the original to ensure data integrity.

5440
LD B,00H 06 00
Load B with 00H (256 iterations for the comparison loop).
5442
LD DE,(5D10H) ED 5B 10 5D
Load DE with the sector data pointer from 5D10H (where we read the verification data).
5446
INC HL 23
Advance HL to the next byte in the original track data.
5447
LD A,(DE) 1A
Load the byte from the verification buffer (data read back from disk).
5448
CP (HL) BE
Compare with the original data in the track buffer.
5449
INC DE 13
Advance DE to the next byte in the verification buffer.
544A
If bytes don't match (NZ), JUMP to 5461H to handle the data mismatch error.
544C
[LOOP] - Decrement B and loop back to 5446H until all 256 bytes are compared.

All 256 bytes verified successfully - advance to the next track entry.

544E
LD HL,0000H 21 00 00
Load HL with 0000H. Note: This is self-modifying code at 544FH - updated with buffer pointer.
5451
INC HL 23
Advance HL past the track marker byte.
5452
INC HL 23
Advance HL past the status byte.
5453
INC H 24
Increment H to advance HL by 256 bytes, moving to the next track entry.
5454
LD (544FH),HL 22 4F 54
Store the updated buffer pointer at 544FH for the next iteration.
5457
Call subroutine at 571BH to update track numbers and advance to the next track position.
545A
LD HL,53ECH 21 EC 53
Load HL with address 53ECH, the write counter location.
545D
DEC (HL) 35
Decrement the write counter (number of tracks remaining to verify).
545E
If tracks remaining (NZ), [LOOP] back to 5406H to verify the next track.
5460
RET C9
All tracks verified - RETURN to caller.

Data mismatch found during verification - handle the compare error.

5461
Call subroutine at 5492H to decrement the granule count (verification failed).
5464
LD A,3AH 3E 3A
Load Register A with 3AH, the error code for "compare error" (data mismatch).
5466
Call the error handler at 585AH to display the compare error.
5469
If user chose to skip (Z), JUMP to 544EH to continue with the next track.
546B
[LOOP] - Jump back to 5406H to retry verification of this track.

546DH - Write Sector to Disk

This subroutine writes a sector (track) from the buffer to the destination disk. It handles error recovery and sets up the proper write command.

546D
PUSH HL E5
Save the current track entry pointer on the stack.
546E
INC HL 23
Advance HL to the status byte of the track entry.
546F
LD A,(HL) 7E
Load the track status byte into Register A.
5470
CP 06H FE 06
Compare with 06H (Record Not Found). Check if this track was originally unformatted.
5472
INC HL 23
Advance HL to the sector data area.
5473
If track was formatted (status != 06H), JUMP to 5479H to proceed with write.

Track was unformatted (status 06H) - set a flag to indicate format-only operation.

5475
SET 0,(IX+00H) DD CB 00 C6
Set bit 0 of the drive control byte at IX+00H. This flags the track as needing format, not copy.
5479
Call subroutine at 5C8EH to set up the sector buffer address and size for the write.
547C
LD A,40H 3E 40
Load Register A with 40H, the write sector command flag.
547E
LD (57EBH),A 32 EB 57
Store the write command at 57EBH to set the disk operation to write mode.
5481
Call the disk write subroutine at 57CEH to perform the actual sector write.
5484
RES 0,(IX+00H) DD CB 00 86
Reset bit 0 of the drive control byte to restore normal operation mode.
5488
POP HL E1
Restore the track entry pointer from the stack.
5489
RET Z C8
If write was successful (Z), RETURN to caller.

Write error occurred - call error handler and potentially retry.

548A
Call the error handler at 585AH to display the write error.
548D
If user chose to retry (NZ), [LOOP] back to 546DH to attempt the write again.
548F
OR FFH F6 FF
OR A with FFH to set A to FFH and clear the Z flag. This indicates the write was skipped.
5491
RET C9
RETURN with NZ flag indicating the write was not completed successfully.

5492H - Decrement Granule Count

This small utility subroutine decrements the remaining granule count when a track operation fails or is skipped.

5492
PUSH HL E5
Save the current HL value on the stack.
5493
LD HL,(5B21H) 2A 21 5B
Load HL with the remaining granule count from 5B21H.
5496
DEC HL 2B
Decrement the granule count by one (one track/granule failed).
5497
LD (5B21H),HL 22 21 5B
Store the updated granule count back at 5B21H.
549A
POP HL E1
Restore the original HL value from the stack.
549B
RET C9
RETURN to caller.

549CH - End of Copy/Backup Operation

This code is reached when the end of the source disk is detected during a COPY operation. It writes any remaining buffered tracks to the destination, then finalizes the operation based on mode.

549C
POP HL E1
Remove the track entry pointer from the stack (was pushed at 529DH when error detected end of disk).
549D
Call the batch write subroutine at 5324H to write any remaining buffered tracks to the destination disk.
54A0
LD A,(5996H) 3A 96 59
Load the option flags byte 3 from 5996H to check the operation mode.
54A3
BIT 3,A CB 5F
Test bit 3 - the COPY option flag. NZ if COPY mode, Z if BACKUP mode.
54A5
If COPY mode (NZ), JUMP to 552DH to display completion message and finish.
54A8
BIT 2,A CB 57
Test bit 2 - the BACKUP option flag. NZ if BACKUP mode, Z if FORMAT mode.
54AA
If FORMAT mode (Z), JUMP to 54D4H to continue with format-specific completion.

BACKUP mode completion - copy the directory from source to destination.

54AC
LD A,05H 3E 05
Load Register A with 05H, the operation code for directory copy.
54AE
Call subroutine at 568DH to set up for the directory copy operation.
54B1
Call subroutine at 5535H to switch to the destination drive.
54B4
LD HL,(5AF1H) 2A F1 5A
Load HL with the source disk's total granule count from 5AF1H.
54B7
LD (5B23H),HL 22 23 5B
Store this count at 5B23H as the destination's granule count (making them match for BACKUP).
54BA
LD A,(5AEDH) 3A ED 5A
Load the source disk type byte from 5AEDH.
54BD
LD (5B1FH),A 32 1F 5B
Store at 5B1FH as the destination's disk type (copying disk format parameters).
54C0
LD DE,5B17H 11 17 5B
Load DE with 5B17H, the address of the destination drive control block.
54C3
Call the DOS file close routine at 4428H to finalize the destination file.
54C6
LD HL,4317H 21 17 43
Load HL with 4317H, the address of the DOS error status byte.
54C9
LD (HL),05H 36 05
Store 05H as the operation code in the status byte.
54CB
If file close failed (NZ), JUMP to the error handler at 521AH.
54CE
LD HL,402DH 21 2D 40
Load HL with 402DH, the address of a completion message or return point.
54D1
JUMP to 5222H to complete the operation and return to DOS.
54D4
JUMP to 501CH to continue with FORMAT-specific completion (directory initialization).

54D7H - Drive Parameter Check Utility

This utility subroutine checks drive parameters for double-sided disk handling and side selection.

54D7
LD D,(IX+04H) DD 56 04
Load Register D with the track number from the drive control block at IX+04H.
54DA
LD C,(IX+06H) DD 4E 06
Load Register C with the side/sector value from IX+06H.
54DD
LD A,(IX+02H) DD 7E 02
Load Register A with the drive configuration byte from IX+02H.
54E0
AND 1CH E6 1C
Mask with 1CH to isolate bits 2-4 (disk type/density bits).
54E2
CP 08H FE 08
Compare with 08H to check if this is a double-sided disk configuration.
54E4
RET NZ C0
If NOT double-sided (NZ), RETURN - no side selection needed.

Double-sided disk - toggle the side selection bit.

54E5
LD A,C 79
Load the side/sector value into Register A.
54E6
XOR 20H EE 20
XOR with 20H to toggle bit 5 (the side selection bit).
54E8
LD (IX+06H),A DD 77 06
Store the updated side/sector value back at IX+06H.
54EB
RET C9
RETURN to caller with side selection updated.

54ECH - Store Sector and Track Parameters

This utility stores sector and track values into the drive control block.

54EC
LD (IX+06H),C DD 71 06
Store Register C as the sector number at IX+06H in the drive control block.
54EF
LD (IX+07H),E DD 73 07
Store Register E as the track number at IX+07H in the drive control block.
54F2
RET C9
RETURN to caller.

54F3H - Copy Drive Parameters from Work Area

This subroutine copies drive configuration parameters from the appropriate work area based on the option flags.

54F3
LD A,C 79
Load Register A with the value from Register C (the option flags).
54F4
AND 0CH E6 0C
Mask with 0CH to isolate bits 2-3 (COPY/BACKUP flags).
54F6
LD BC,0010H 01 00 10
Load BC with 0010H (16), the number of bytes to copy for the drive control block.
54F9
LD DE,42D0H 11 D0 42
Load DE with 42D0H, the destination address in the DOS work area.
54FC
LD HL,5983H 21 83 59
Load HL with 5983H, the source address for COPY/BACKUP mode parameters.
54FF
If COPY or BACKUP mode (NZ), JUMP to 5508H to perform the copy.

FORMAT mode - use different source parameters.

5501
LD HL,598BH 21 8B 59
Load HL with 598BH, the source address for FORMAT mode parameters.
5504
LD E,D8H 1E D8
Load E with D8H, changing destination to 42D8H for FORMAT mode.
5506
LD C,08H 0E 08
Load C with 08H (8 bytes), the reduced size for FORMAT mode copy.
5508
LDIR ED B0
Block copy BC bytes from (HL) to (DE). Copy the drive parameters to the work area.
550A
LD HL,(59D1H) 2A D1 59
Load HL with the high memory limit from 59D1H.
550D
LD DE,(59C3H) ED 5B C3 59
Load DE with the program end address from 59C3H.
5511
OR A B7
Clear the Carry flag for subtraction.
5512
SBC HL,DE ED 52
Calculate HL = high memory - program end (available memory).
5514
EX DE,HL EB
Exchange DE and HL. Now DE = available memory, HL = program end.
5515
If borrow (no available memory), JUMP to 5528H to skip memory allocation.
5517
If exactly zero available (Z), JUMP to 5528H to skip.

Memory is available - set up the hash table or directory buffer.

5519
LD HL,(59C3H) 2A C3 59
Load HL with the program end address from 59C3H.
551C
LD A,(59BCH) 3A BC 59
Load Register A with a configuration byte from 59BCH.
551F
Call the DOS memory allocation routine at 4CB4H to set up the buffer.
5522
LD H,42H 26 42
Load H with 42H, setting up the high byte of the work area address.
5524
LD C,A 4F
Copy the returned value from the allocation to Register C.
5525
Call subroutine at 5762H to complete the buffer setup.
5528
Call the DOS directory access routine at 491FH to initialize directory handling.
552B
If directory access failed (NZ), JUMP to 54CBH to handle the error.
552D
LD HL,5A1FH 21 1F 5A
Load HL with 5A1FH, the address of the operation complete message.
5530
Call the DOS print message routine at 4467H to display the completion message.
5533
JUMP to 54CEH to finish the operation and return to DOS.

5535H - Set Up Destination Drive

This subroutine configures the system to use the destination drive for write operations.

5535
LD HL,5956H 21 56 59
Load HL with 5956H, the address of the destination drive number storage.
5538
Call subroutine at 5585H to set up drive-specific parameters from (HL).
553B
INC HL 23
Advance HL past the drive number.
553C
INC HL 23
Advance to the drive control block pointer location.
553D
LD E,(HL) 5E
Load the low byte of the drive control block address into E.
553E
INC HL 23
Advance to the high byte.
553F
LD D,(HL) 56
Load the high byte of the control block address into D.
5540
PUSH DE D5
Push the control block address onto the stack.
5541
POP IX DD E1
Pop the control block address into IX for indexed addressing.
5543
LD A,(DE) 1A
Load the first byte of the control block (drive status) into A.
5544
BIT 7,A CB 7F
Test bit 7 - the drive ready/initialized flag. NZ if drive is ready.
5546
RET NZ C0
If drive already initialized (NZ), RETURN - no further setup needed.

Drive not initialized - perform drive selection and initialization.

5547
LD B,00H 06 00
Load B with 00H, parameter for drive access routine.
5549
LD A,17H 3E 17
Load Register A with 17H, the offset for secondary drive control block.
554B
CP E BB
Compare with E (low byte of control block address). Check if this is the destination drive block.
554C
If destination drive block (Z), JUMP to 5556H to use secondary access routine.
554E
Call the primary drive access routine at 4424H.
5551
If successful (Z), JUMP to 5570H to store the sector number.
5553
If failed (NZ), JUMP to the error handler at 521AH.
5556
Call the secondary drive access routine at 4420H.
5559
If failed (NZ), JUMP to 5553H to handle the error.

Drive access successful - verify source and destination match for COPY operation.

555B
LD DE,(5AEBH) ED 5B EB 5A
Load DE with the source disk identifier from 5AEBH.
555F
LD HL,(5B1DH) 2A 1D 5B
Load HL with the destination disk identifier from 5B1DH.
5562
RST 18H DF
Call the compare HL,DE routine via RST 18H. Z if disks match.
5563
If disks don't match (NZ), JUMP to 5570H - this is expected for COPY to different disk.

Source and destination match - display warning about copying to same disk.

5565
LD HL,5A24H 21 24 5A
Load HL with 5A24H, the address of a warning message about same disk.
5568
LD A,(5940H) 3A 40 59
Load the operation status byte from 5940H.
556B
CP 06H FE 06
Compare with 06H (threshold for warning display).
556D
If below threshold (Carry), JUMP to 5243H to display the warning.
5570
LD HL,(593EH) 2A 3E 59
Load HL with the sector storage address from 593EH.
5573
LD A,(IX+06H) DD 7E 06
Load the current sector number from the drive control block at IX+06H.
5576
LD (HL),A 77
Store the sector number at the address in HL.
5577
RET C9
RETURN to caller with drive set up.

5578H - Drive Setup Entry Points

These are multiple entry points for the drive setup routine, each loading a different drive parameter address into HL before falling through to the common setup code at 5585H.

5578
LD HL,594CH 21 4C 59
Load HL with 594CH, the address of the source drive parameters.
557B
JUMP to 5585H to continue with the common setup code.
557D
LD HL,5956H 21 56 59
Load HL with 5956H, the address of the destination drive parameters.
5580
JUMP to 5585H to continue with the common setup code.
5582
LD HL,5942H 21 42 59
Load HL with 5942H, the address of the primary operation drive parameters.
5585
LD (593EH),HL 22 3E 59
Store the parameter address at 593EH as the current drive parameter pointer.
5588
LD A,FFH 3E FF
Load Register A with FFH to set a flag value.
558A
LD (4930H),A 32 30 49
Store FFH at 4930H in the DOS work area, marking drive parameters as updated.
558D
LD A,(HL) 7E
Load the first byte of the drive parameters (drive number) into A.
558E
INC A 3C
Increment A. If drive was FFH (uninitialized), A becomes 00H and Z flag is set.
558F
RET Z C8
If drive uninitialized (Z), RETURN immediately - no setup needed.

Drive is initialized - save registers and check for disk change.

5590
PUSH HL E5
Save the drive parameter pointer on the stack.
5591
PUSH DE D5
Save DE on the stack.
5592
PUSH BC C5
Save BC on the stack.
5593
LD A,(593BH) 3A 3B 59
Load the operation mode flags from 593BH.
5596
BIT 7,A CB 7F
Test bit 7 - the multi-disk operation flag. NZ if multi-disk mode active.
5598
LD B,00H 06 00
Load B with 00H, the default flag value for single-disk mode.
559A
If multi-disk mode (NZ), CALL 5658H to handle disk change detection.
559D
LD C,(HL) 4E
Load the drive number from the parameter block into C.
559E
INC HL 23
Advance to the next byte in the parameter block.
559F
LD B,(HL) 46
Load the drive status flags into B.
55A0
LD DE,0007H 11 07 00
Load DE with 0007H, the offset to the drive control block pointer.
55A3
ADD HL,DE 19
Add offset to HL to point to the control block address location.
55A4
LD E,(HL) 5E
Load the low byte of the drive control block address into E.
55A5
INC HL 23
Advance to the high byte.
55A6
LD D,(HL) 56
Load the high byte of the control block address into D.
55A7
LD HL,5940H 21 40 59
Load HL with 5940H, the address of the operation status bytes.
55AA
LD A,(HL) 7E
Load the first status byte into A.
55AB
AND B A0
AND with the drive status flags. Tests if status matches expected pattern.
55AC
LD A,(HL) 7E
Load the first status byte again (reload for next operation).
55AD
INC HL 23
Advance to the second status byte at 5941H.
55AE
If status check passed (Z), JUMP to 55B5H to continue with drive access.

Status mismatch - update the second status byte to reflect current state.

55B0
XOR B A8
XOR with the drive status flags to find different bits.
55B1
XOR FFH EE FF
Invert all bits to create a mask of matching bits.
55B3
AND (HL) A6
AND with the second status byte to preserve only matching bits.
55B4
LD (HL),A 77
Store the updated status byte.
55B5
LD A,C 79
Load the drive number into Register A.
55B6
Call the DOS drive select routine at 4776H to activate the drive.
55B9
If drive select failed (NZ), JUMP to the error handler at 521AH.
55BC
PUSH HL E5
Save the status pointer on the stack.
55BD
LD A,(HL) 7E
Load the current status byte.
55BE
AND B A0
AND with drive flags to test if disk is present.
55BF
If disk present (NZ), JUMP to 55ECH to proceed with disk access.

No disk present - prompt user to insert disk.

55C1
LD HL,59EEH 21 EE 59
Load HL with 59EEH, the address of the "Insert disk" prompt message.
55C4
Call the DOS print message routine at 4467H to display the insert disk prompt.
55C7
LD H,D 62
Copy high byte of control block address to H.
55C8
LD L,E 6B
Copy low byte of control block address to L. HL now points to control block.
55C9
Call 4467H again to display the disk name from the control block.
55CC
LD A,C 79
Load the drive number into A.
55CD
ADD 30H C6 30
Add 30H to convert to ASCII digit ('0'=30H, '1'=31H, etc.).
55CF
LD (5A1DH),A 32 1D 5A
Store the ASCII drive number in the message template at 5A1DH.
55D2
LD HL,5A02H 21 02 5A
Load HL with 5A02H, the address of the "in drive N" message template.
55D5
Call 4467H to display the complete "in drive N" message.

Wait for user to press ENTER after inserting the disk.

55D8
PUSH BC C5
Save BC on the stack.
55D9
LD BC,8000H 01 00 80
Load BC with 8000H, a parameter for the key wait routine.
55DC
PUSH DE D5
Save DE on the stack.
55DD
Call the DOS keyboard input routine at 4CEDH to wait for a keypress.
55E0
POP DE D1
Restore DE from the stack.
55E1
POP BC C1
Restore BC from the stack.
55E2
Call subroutine at 572BH to check for BREAK key.
55E5
CP 0DH FE 0D
Compare with 0DH (ENTER key). Z if ENTER was pressed.
55E7
If not ENTER (NZ), [LOOP] back to 55E2H to keep waiting.
55E9
Call subroutine at 5881H to clear the prompt message from the screen.
55EC
LD A,C 79
Load the drive number into A.
55ED
Call the DOS disk verify routine at 47ECH to check the disk is readable.
55F0
If disk not ready (NZ), [LOOP] back to 55C1H to prompt again.
55F2
POP HL E1
Restore the status pointer from the stack.
55F3
LD A,(HL) 7E
Load the current status byte.
55F4
OR B B0
OR with the drive flags to mark disk as present.
55F5
LD (HL),A 77
Store the updated status byte.
55F6
LD HL,5B57H 21 57 5B
Load HL with 5B57H, the address of the disk parameter list.
55F9
JUMP to 563BH to continue with disk parameter processing.

55FBH - Disk Parameter Processing Loop

This code processes disk parameters, handling different disk types and swapping buffers as needed for multi-disk operations.

55FB
PUSH HL E5
Save the current parameter list pointer on the stack.
55FC
If Z flag set (from previous test), JUMP to 560DH to skip error check.
55FE
LD A,(4317H) 3A 17 43
Load the DOS error code from 4317H.
5601
CP C B9
Compare with the current drive number in C.
5602
If error matches this drive (Z), JUMP to 560DH to handle it.
5604
BIT 5,(HL) CB 6E
Test bit 5 of the current parameter byte - the "skip on error" flag.
5606
If skip flag not set (Z), JUMP to 5637H to continue normally.
5608
LD A,33H 3E 33
Load Register A with 33H, the error code for "wrong disk in drive".
560A
JUMP to the error handler at 521AH to report the error.
560D
LD A,(430CH) 3A 0C 43
Load the DOS configuration byte from 430CH.
5610
XOR (HL) AE
XOR with the current parameter byte to find differences.
5611
AND 20HAND 00100000 E6 20
Mask with 20H to test only bit 5 (buffer swap needed).
5613
If bit 5 matches (Z), JUMP to 5637H - no buffer swap needed.

Buffer swap needed - exchange buffer contents between source and destination.

5615
XOR (HL) AE
XOR again to restore original bits and toggle bit 5.
5616
LD (HL),A 77
Store the updated parameter byte with bit 5 toggled.
5617
INC HL 23
Advance to the buffer pointer location.
5618
LD A,(HL) 7E
Load the low byte of the buffer address.
5619
INC HL 23
Advance to the high byte.
561A
LD H,(HL) 66
Load the high byte of the buffer address into H.
561B
LD L,A 6F
Load the low byte into L. HL now points to the buffer.
561C
JUMP to 562FH to continue with the buffer swap.

[LOOP] - Buffer swap loop: exchange bytes between two buffers.

561E
LD A,(HL) 7E
Load the byte count from the current position.
561F
OR A B7
Test if byte count is zero. Z flag set if done.
5620
LD B,A 47
Copy byte count to B for the swap loop.
5621
INC HL 23
Advance past the byte count.
5622
EX DE,HL EB
Exchange DE and HL for the swap operation.
5623
If byte count zero (Z), JUMP to 562FH to check for next block.
5625
EX DE,HL EB
Exchange back for the swap.
5626
LD C,(HL) 4E
Load byte from first buffer into C.
5627
LD A,(DE) 1A
Load byte from second buffer into A.
5628
LD (HL),A 77
Store second buffer byte into first buffer.
5629
LD A,C 79
Get first buffer byte from C.
562A
LD (DE),A 12
Store first buffer byte into second buffer. Swap complete for this byte.
562B
INC HL 23
Advance first buffer pointer.
562C
INC DE 13
Advance second buffer pointer.
562D
[LOOP] - Decrement B and loop back to 5626H until all bytes swapped.
562F
LD E,(HL) 5E
Load low byte of next block pointer.
5630
INC HL 23
Advance to high byte.
5631
LD D,(HL) 56
Load high byte of next block pointer.
5632
INC HL 23
Advance past the pointer.
5633
LD A,D 7A
Load high byte into A.
5634
OR E B3
OR with low byte. Z if pointer is 0000H (end of list).
5635
If more blocks (NZ), [LOOP] back to 561EH to process next block.
5637
POP HL E1
Restore the parameter list pointer from the stack.
5638
INC HL 23
Advance to next parameter entry.
5639
INC HL 23
Advance past the entry.
563A
INC HL 23
Advance to the entry type byte.
563B
LD A,(HL) 7E
Load the entry type byte.
563C
CP 02H FE 02
Compare with 02H. Entries with type >= 02H need processing.
563E
LD C,A 4F
Copy entry type to C for later use.
563F
INC HL 23
Advance to the next entry.
5640
If type >= 02H (No Carry), [LOOP] back to 55FBH to process this entry.

Entry type < 02H - done processing, restore registers and return.

5642
POP BC C1
Restore BC from the stack.
5643
POP DE D1
Restore DE from the stack.
5644
POP HL E1
Restore the original drive parameter pointer from the stack.
5645
RET C9
RETURN to caller with drive set up.

5646H - Flush All Drive Buffers

This subroutine iterates through all three drive parameter blocks (at 5942H, 594CH, and 5956H) and flushes any pending buffer data for drives that are currently active. It is called from the error handler at 5230H before exiting to ensure no data is lost. Register B on entry contains a retry count (typically 5).

5646
LD HL,5942H 21 42 59
Load Register HL with the address of the drive parameter block table (5942H). This table contains status information for up to 3 drives, with each entry being 10 (0AH) bytes.
5649
LD C,03H 0E 03
Load Register C with 3, the number of drive entries to process. This serves as a loop counter for iterating through all possible drives (drives 0, 1, and 2).

[LOOP START] - Begin iterating through each drive parameter block.

564B
LD A,(HL) 7E
Load Register A with the drive status byte from the current drive parameter block. A value of FFH indicates the drive slot is unused/inactive.
564C
INC A 3C
Increment Register A. This is a clever test: if the drive status was FFH (inactive/unused), incrementing it produces 00H and sets the Z FLAG. Any other value means the drive is active.
564D
If the NZ FLAG is set (meaning the drive is active - status was not FFH), CALL the buffer flush subroutine at 5658H to write any pending data to disk for this drive.
5650
LD DE,000AH 11 0A 00
Load Register DE with 10 (0AH), the size of each drive parameter block entry in bytes.
5653
ADD HL,DE 19
Add DE to HL, advancing the pointer to the next drive parameter block (from 5942H to 594CH to 5956H).
5654
DEC C 0D
Decrement the drive counter in Register C.
5655
If the NZ FLAG is set (more drives to check), JUMP back to 564BH to process the next drive. [LOOP]
5657
RET C9
Return to the caller. All drive buffers have been flushed.

5658H - Flush Single Drive Buffer

This subroutine flushes the buffer for a single drive. On entry, HL points to the drive parameter block and A contains the drive status byte. Register B (from the caller) contains a retry/error handling flag. This routine interfaces with the DOS buffer management system to write any dirty sectors back to disk.

5658
LD A,(HL) 7E
Load Register A with the drive number from the first byte of the drive parameter block pointed to by HL.
5659
PUSH HL E5
Save the drive parameter block pointer onto the stack for later restoration.
565A
PUSH DE D5
Save Register DE onto the stack.
565B
CALL the SYS0 buffer lookup routine at 4776H. This routine searches for a buffer associated with the drive number in A. Returns with HL pointing to the buffer control block, and B containing buffer flags. Z FLAG set if no buffer found.
565E
If the NZ FLAG is set (buffer found), JUMP to 5684H to check for errors. This is taken if the buffer lookup succeeded.

Buffer was found. Now determine whether it's a read buffer or write buffer by checking bit 0 of the flags in B, and copy the appropriate data.

5660
LD DE,0004H 11 04 00
Load Register DE with 4, the offset to the read buffer pointer within the buffer control block.
5663
BIT 0,B CB 40
Test bit 0 of Register B (buffer flags). If set, this is a write buffer; if clear, it's a read buffer.
5665
If the Z FLAG is set (bit 0 clear, read buffer), JUMP to 5669H to skip the offset adjustment.
5667
INC DE 13
Increment DE to 5 (write buffer offset is 2 bytes higher).
5668
INC DE 13
Increment DE to 6. For write buffers, the pointer is at offset 6 instead of 4.
5669
ADD HL,DE 19
Add the offset in DE to HL, pointing to the buffer address pointer within the control block.
566A
LD E,(HL) 5E
Load the low byte of the buffer address into Register E.
566B
INC HL 23
Increment HL to point to the high byte.
566C
LD D,(HL) 56
Load the high byte of the buffer address into Register D. DE now contains the buffer address.
566D
LD HL,(4399H) 2A 99 43
Load Register HL with the contents of system buffer pointer at 4399H (SYS0 data area). This is the destination/source for the copy operation.
5670
BIT 1,B CB 48
Test bit 1 of Register B (buffer flags). This determines the direction of the copy.
5672
If the NZ FLAG is set (bit 1 set), JUMP to 5675H keeping HL as source. Otherwise swap source/destination.
5674
EX DE,HL EB
Exchange DE and HL, swapping the source and destination addresses for the copy.
5675
PUSH BC C5
Save the buffer flags (B) and any counter value (C) onto the stack.
5676
LD BC,000AH 01 0A 00
Load Register BC with 10, the number of bytes to copy. This copies the drive parameter/status information.
5679
LDIR ED B0
Block copy 10 bytes from the source (HL) to the destination (DE). This synchronizes the buffer data with the drive parameters.
567B
POP BC C1
Restore the buffer flags and counter from the stack.
567C
CALL the SYS0 buffer release routine at 4773H to mark the buffer as flushed/released.
567F
If the NZ FLAG is set (error occurred during release), JUMP to 5684H to handle the error.

[SUCCESS PATH] - Buffer flush completed successfully.

5681
POP DE D1
Restore Register DE from the stack.
5682
POP HL E1
Restore the drive parameter block pointer from the stack.
5683
RET C9
Return to the caller with Z FLAG set (success).

[ERROR PATH] - Check if errors should be suppressed or reported.

5684
BIT 2,B CB 50
Test bit 2 of Register B. If set, this indicates errors should be suppressed (silent mode).
5686
If the NZ FLAG is set (suppress errors), JUMP to 5681H to restore registers and return without error.
5688
JUMP to the main error handler at 521AH to report the disk error to the user.

568BH - Initialize Primary Drive with Retry

This subroutine initializes the primary (system) drive with error code 04H and sets up for operation with error retry enabled.

568B
LD A,04H 3E 04
Load Register A with error code 04H (disk not ready or initialization error).
568D
LD C,FFH 0E FF
Load Register C with FFH, indicating "use default drive" or "all drives" mode.
568F
PUSH AF F5
Save the error code and flags onto the stack.
5690
CALL the primary drive setup routine at 5582H to initialize the drive specified in C.
5693
POP AF F1
Restore the error code and flags from the stack.
5694
OR A B7
Test Register A by ORing it with itself. This sets flags based on the error code.
5695
RET Z C8
If the Z FLAG is set (A=0, no error), RETURN immediately.
5696
OR E0H F6 E0
OR Register A with E0H, setting the upper bits to indicate a specific error type. This converts the error code to a DOS error format.
5698
RST 28H EF
Execute RST 28H, the DOS error signaling routine. This sets up the error condition for the system.
5699
INC HL 23
Increment HL (part of multi-byte operation following RST 28H or entry point for 56A2H).
569A
INC HL 23
Increment HL again.
569B
INC HL 23
Increment HL a third time, advancing past a 3-byte structure.
569C
LD DE,(5D14H) ED 5B 14 5D
Load Register DE with the current buffer pointer from 5D14H.
56A0
RST 18H DF
Execute RST 18H, the DOS compare/dispatch routine.
56A1
RET C9
Return to the caller.

56A2H - Verify End-of-Disk Condition (COPY Mode)

This subroutine checks for the end-of-disk condition during COPY operations. It loops until bit 5 of a status byte is set, indicating the disk operation is complete.

56A2
CALL the subroutine at 5699H to advance the pointer and load the current buffer position.
56A5
RET Z C8
If the Z FLAG is set (operation complete), RETURN to the caller.
56A6
BIT 5,(HL) CB 6E
Test bit 5 of the byte pointed to by HL. This is the end-of-disk flag in the status byte.
56A8
If the Z FLAG is set (bit 5 clear, not at end of disk), JUMP back to 56A2H to continue checking. [LOOP]

End-of-disk detected. Save the current position and set up for the next operation.

56AA
LD (52BAH),HL 22 BA 52
Store HL (current position pointer) at 52BAH for later reference.
56AD
INC HL 23
Increment HL to point to the next byte in the structure.
56AE
LD C,(HL) 4E
Load Register C with the sector count or parameter from the next byte.
56AF
INC HL 23
Increment HL again.
56B0
LD A,(HL) 7E
Load Register A with the next byte (track or head number).
56B1
LD (52D2H),A 32 D2 52
Store this value at 52D2H (track/head storage location).
56B4
LD IX,5AE5H DD 21 E5 5A
Load Index Register IX with 5AE5H, the address of the filename/FCB buffer.
56B8
LD A,C 79
Copy the sector count from Register C to Register A.
56B9
LD (4F56H),A 32 56 4F
Store the sector count at 4F56H (sector counter in the disk I/O area).
56BC
CALL the disk seek routine at 56F4H to position the head at the required track.
56BF
XOR A AF
Clear Register A to zero.
56C0
LD (4F5EH),A 32 5E 4F
Store zero at 4F5EH (clearing a status or counter byte).
56C3
INC HL 23
Increment HL to point to the next parameter.
56C4
CALL the subroutine at 4E21H (parameter setup routine).
56C7
EX DE,HL EB
Exchange DE and HL, moving the calculated address to HL.
56C8
LD A,E 7B
Load Register A with the low byte of the address (now in E after exchange).
56C9
ADD 10H C6 10
Add 16 (10H) to Register A, calculating an offset.
56CB
LD E,A 5F
Store the result back in Register E.
56CC
CALL the subroutine at 4F2EH (disk I/O execution).
56CF
If the NZ FLAG is set (error occurred), JUMP to 56FEH to handle the error.
56D1
OR FFH F6 FF
OR Register A with FFH, setting A to FFH and clearing the Z FLAG.
56D3
RET C9
Return with NZ FLAG set (A=FFH indicates success with end-of-disk reached).

56D4H - Calculate Sector Address

This subroutine calculates the absolute sector address from a logical sector number. It uses the disk geometry parameters from the IY register base.

56D4
LD L,A 6F
Load the low byte of HL with Register A (the logical sector number).
56D5
LD H,00H 26 00
Clear the high byte of HL, making HL = the sector number as a 16-bit value.
56D7
LD A,(IY+8EH) FD 7E 8E
Load Register A with the byte at IY+8EH (offset 142 from IY base 4380H = 440EH). This contains disk geometry information.
56DA
JUMP to the SYS0 sector calculation routine at 4C94H to complete the address computation.

56DDH - Get Directory Entry Address

This subroutine retrieves the address of a directory entry. It calls the SYS0 directory lookup routine.

56DD
CALL the SYS0 directory entry lookup routine at 494BH. This routine locates the directory entry for the current file.
56E0
JUMP to 56FDH to check the result and handle any errors.

56E2H - Seek to Specified Sector

This subroutine seeks to a specified sector, handling track changes as needed. On entry, A contains the target sector number.

56E2
PUSH AF F5
Save Register A (target sector) and flags onto the stack.
56E3
AND 1FHAND 00011111 E6 1F
Mask Register A with 1FH (00011111 binary), extracting the sector number within the track (0-31).
56E5
INC A 3C
Increment to convert from 0-based to 1-based sector numbering.
56E6
INC A 3C
Increment again (sectors are numbered starting at 2, not 0 or 1).
56E7
LD HL,570EH 21 0E 57
Load HL with address 570EH, which contains the current sector number.
56EA
CP (HL) BE
Compare Register A with the current sector number at (HL). Sets Z FLAG if they match.
56EB
If the NZ FLAG is set (different sector), CALL 570DH to update the sector counter.
56EE
POP AF F1
Restore the original sector value and flags from the stack.
56EF
CALL the SYS0 seek routine at 492FH to position the disk head.
56F2
JUMP to 56FDH to check the result.

56F4H - Seek to Track

This is a simpler seek routine that positions the head to a track without sector positioning.

56F4
CALL the SYS0 track seek routine at 4936H.
56F7
JUMP to 56FDH to check the result.

56F9H - Home Drive Head

This routine homes the drive head (seeks to track 0).

56F9
XOR A AF
Clear Register A to zero (track 0).
56FA
CALL the SYS0 seek-to-track routine at 490AH with track 0 in A.
56FD
RET Z C8
If the Z FLAG is set (operation successful), RETURN to the caller.
56FE
JUMP to the main error handler at 521AH if an error occurred.

5701H - Read Disk Sector

This subroutine reads a sector from the disk.

5701
CALL the SYS0 read sector routine at 4922H.
5704
JUMP to 56FDH to check the result and handle any errors.

5706H - Initialize Sector Counter

This routine initializes the sector counter from the system value.

5706
LD A,(4930H) 3A 30 49
Load Register A with the default sector count from 4930H (SYS0 area).
5709
LD (570EH),A 32 0E 57
Store this value at 570EH as the current sector counter.
570C
RET C9
Return to the caller.

570DH - Update Sector Counter

This subroutine updates the sector counter, potentially triggering a track seek if necessary.

570D
LD A,FFH 3E FF
Load Register A with FFH (-1 or 255).
570E
DATA 3C
Self-modifying code location: This byte (3CH = INC A) is modified at runtime to store the current sector number. When executed, it increments A.
570F
INC A 3C
Increment Register A again.
5710
RET Z C8
If the Z FLAG is set (A wrapped to 0), RETURN - no track change needed.
5711
LD A,FFH 3E FF
Load Register A with FFH to reset the sector counter.
5713
LD (570EH),A 32 0E 57
Store FFH at the sector counter location (570EH).
5716
CALL the SYS0 step-in routine at 491FH to move to the next track.
5719
JUMP to 56FDH to check the result.

571BH - Toggle Track Progress Indicator

This subroutine toggles an asterisk (*) character on the screen to indicate track processing progress. It displays at position 3C3FH (top-right corner of the video display, column 63 of row 0).

571B
LD A,(3C3FH) 3A 3F 3C
Load Register A with the character currently displayed at screen position 3C3FH (video RAM, top-right area).
571E
CP 2AH FE 2A
Compare Register A with 2AH (ASCII code for * asterisk). Sets Z FLAG if currently showing asterisk.
5720
LD A,2AH 3E 2A
Load Register A with 2AH (asterisk character), preparing to display it.
5722
If the NZ FLAG is set (not currently showing asterisk), JUMP to 5726H to display the asterisk.
5724
LD A,20H 3E 20
Load Register A with 20H (ASCII space). If asterisk was already showing, we'll display a space to toggle it off.
5726
LD (3C3FH),A 32 3F 3C
Store Register A at screen position 3C3FH, toggling the progress indicator between asterisk and space.
5729
JUMP to 5733H to continue with the BREAK key check.

572BH - Check for BREAK Key with Delay

This subroutine checks for the BREAK key while providing a small delay. It allows the user to cancel long-running operations like FORMAT or COPY. Returns the key code in A.

572B
PUSH DE D5
Save Register DE onto the stack.
572C
CALL the ROM keyboard scan routine at 002BH. This routine scans the keyboard and returns any pressed key in A.
572F
CALL the SYS0 key processing routine at 45B5H to handle special key combinations.
5732
POP DE D1
Restore Register DE from the stack.

Fall through to check for BREAK key and special conditions.

5733
PUSH AF F5
Save the key code and flags onto the stack.
5734
LD A,(5995H) 3A 95 59
Load Register A with the option flags from 5995H. Bit 7 indicates "no user interaction" mode.
5737
BIT 7,A CB 7F
Test bit 7 of the option flags. If set, BREAK checking is disabled.
5739
If the NZ FLAG is set (no-interaction mode), JUMP to 574FH to skip BREAK check.

Check if BREAK+UP or BREAK+DOWN is pressed (keyboard row 3840H).

573B
LD A,(3840H) 3A 40 38
Load Register A from keyboard memory 3840H (row 6: ENTER, CLEAR, BREAK, UP, DOWN, LEFT, RIGHT, SPACE).
573E
AND 48HAND 01001000 E6 48
Mask with 48H (01001000 binary), isolating bits 3 (UP arrow) and 6 (BREAK key).
5740
If the Z FLAG is set (neither BREAK+UP nor BREAK+DOWN pressed), JUMP to 574FH to exit normally.

[BREAK DETECTED] - Wait for key release and check for retry/cancel.

5742
LD A,(3840H) 3A 40 38
Load Register A from keyboard row 3840H again.
5745
AND 09H E6 09
Mask with 09H (00001001 binary), isolating bits 0 (ENTER) and 3 (UP).
5747
If the Z FLAG is set (waiting for ENTER or UP release), LOOP back to 5742H. [WAIT LOOP]
5749
RRCA 0F
Rotate Register A right through carry. This moves bit 0 (ENTER status) into the Carry flag.
574A
LD A,39H 3E 39
Load Register A with error code 39H ("Operator Break" error).
574C
If the NC FLAG is set (Carry clear, ENTER was pressed = cancel), JUMP to error handler at 521AH with the break error.
574F
POP AF F1
Restore the original key code and flags from the stack.
5750
RET C9
Return to the caller with the key code in A.

5751H - Check Free Space and Allocate Sectors

This subroutine manages sector allocation for the disk bitmap. It checks if there's room for more sectors and handles bitmap manipulation. Called during FORMAT and COPY operations to track used/free sectors.

5751
LD A,L 7D
Load Register A with the low byte of HL (current bitmap position).
5752
CP 60H FE 60
Compare Register A with 60H (96 decimal). Check if we've reached the end of the bitmap area.
5754
POP BC C1
Restore Register BC from the stack.
5755
POP DE D1
Restore Register DE from the stack.
5756
POP HL E1
Restore Register HL from the stack.
5757
RET NC D0
If the NC FLAG is set (position >= 60H, at end), RETURN to caller - no more space.
5758
LD A,(59C6H) 3A C6 59
Load Register A with the maximum track number from 59C6H.
575B
CP 61H FE 61
Compare with 61H (97 decimal) to check disk capacity limit.
575D
RET NC D0
If the NC FLAG is set (max track >= 97, exceeds limit), RETURN.
575E
LD A,L 7D
Load Register A with the low byte of HL again.
575F
ADD 60H C6 60
Add 60H to Register A, calculating the absolute bitmap position.
5761
LD L,A 6F
Store the result back in Register L.
5762
PUSH HL E5
Save the updated bitmap pointer onto the stack.
5763
PUSH DE D5
Save Register DE onto the stack.
5764
PUSH BC C5
Save Register BC onto the stack.

[SECTOR ALLOCATION LOOP] - Process the bitmap to mark sectors.

5765
LD A,L 7D
Load Register A with the current bitmap byte position.
5766
CP C0H FE C0
Compare with C0H (192 decimal), checking if we've passed the bitmap area.
5768
If the NC FLAG is set (past bitmap), CALL 5240H to handle overflow/wrap.
576B
INC C 0C
Increment the bit counter in Register C.
576C
LD B,C 41
Copy the bit counter to Register B for the rotation loop.
576D
LD A,7FH 3E 7F
Load Register A with 7FH (01111111 binary), a mask with bit 7 clear.

Rotate the mask to position the correct bit.

576F
RLCA 07
Rotate Register A left. This shifts the zero bit into position.
5770
Decrement B and JUMP back to 576FH if not zero. [ROTATE LOOP]
5772
AND (HL) A6
AND the rotated mask with the bitmap byte at (HL), clearing the target bit to mark the sector as used.
5773
LD (HL),A 77
Store the updated bitmap byte back to memory.
5774
DEC DE 1B
Decrement the sector counter in DE.
5775
LD A,D 7A
Load Register A with the high byte of DE.
5776
OR E B3
OR with the low byte to test if DE has reached zero.
5777
If the Z FLAG is set (DE=0, all sectors marked), JUMP to 5751H to finish up.
5779
LD A,(59CAH) 3A CA 59
Load Register A with the sectors-per-track value from 59CAH.
577C
CP C B9
Compare with the current bit position in C.
577D
If the NZ FLAG is set (more sectors in this track), JUMP back to 576BH to process next sector.
577F
LD C,00H 0E 00
Reset the bit counter to 0 for the new track.
5781
INC L 2C
Increment L to move to the next bitmap byte (next track).
5782
JUMP back to 5765H to continue processing. [LOOP]

5784H - Reserved/Padding Area

This area contains NOP instructions, likely reserved space or padding for alignment.

5784
NOP 00
No operation (padding byte).
5785
NOP 00
No operation (padding byte).
5786
NOP 00
No operation (padding byte).
5787
NOP 00
No operation (padding byte).
5788
NOP 00
No operation (padding byte).
5789
NOP 00
No operation (padding byte).

578AH - Initialize Verify Operation

This subroutine initializes the verify operation, setting up pointers and counters for verifying disk data. It's typically called after a FORMAT or COPY to verify the written data.

578A
LD A,20H 3E 20
Load Register A with 20H (32 decimal, space character or flag value).
578C
LD (57EBH),A 32 EB 57
Store this value at 57EBH (self-modifying code location - modifies the LD B,00H at 57EA to LD B,20H).
578F
LD (5B21H),DE ED 53 21 5B
Store Register DE at 5B21H (starting sector address for verify).
5793
LD HL,4200H 21 00 42
Load Register HL with 4200H, the address of the verify buffer area.
5796
LD (5B1AH),HL 22 1A 5B
Store HL at 5B1AH (verify buffer pointer).
5799
LD HL,(59CFH) 2A CF 59
Load Register HL with the total sector count from 59CFH.
579C
OR A B7
Clear the Carry flag by ORing A with itself.
579D
SBC HL,DE ED 52
Subtract DE (starting sector) from HL (total sectors) to get the number of sectors to verify.
579F
RET C D8
If the Carry FLAG is set (start > total, invalid range), RETURN immediately.
57A0
RET Z C8
If the Z FLAG is set (start = total, nothing to verify), RETURN immediately.
57A1
PUSH HL E5
Save the sector count onto the stack.
57A2
LD HL,5A79H 21 79 5A
Load HL with address 5A79H, pointing to the "VERIFYING" message string.
57A5
CALL the message display routine at 587EH to show "VERIFYING" status.
57A8
LD HL,FFFFH 21 FF FF
Load Register HL with FFFFH (-1), used as an initialization value.
57AB
LD (5B23H),HL 22 23 5B
Store FFFFH at 5B23H (previous sector marker, -1 means none).
57AE
SET 1,(IX+00H) DD CB 00 CE
Set bit 1 of the byte at IX+0 (FCB flags), indicating verify mode is active.
57B2
POP HL E1
Restore the sector count from the stack.

[VERIFY LOOP] - Read and verify each sector.

57B3
CALL the disk read subroutine at 57C8H to read a sector.
57B6
If the Z FLAG is set (read successful), JUMP to 57BAH to continue.
57B8
CP 06H FE 06
Compare the error code with 06H (sector not found / end of data).
57BA
If the NZ FLAG is set (error other than 06H), CALL the error handler with retry prompt at 585AH.
57BD
If the NZ FLAG is set (user chose retry), JUMP back to 57B3H to retry the read. [RETRY LOOP]
57BF
DEC HL 2B
Decrement the remaining sector count.
57C0
CALL the progress indicator toggle routine at 571BH.
57C3
LD A,H 7C
Load Register A with the high byte of the sector count.
57C4
OR L B5
OR with the low byte to test if count has reached zero.
57C5
If the NZ FLAG is set (more sectors to verify), JUMP back to 57B3H. [MAIN LOOP]
57C7
RET C9
Return - all sectors verified successfully.

57C8H - Disk Read Subroutine

This subroutine reads a sector from disk using the FCB pointed to by IX. It's a wrapper that sets up the DE register and calls the SYS0 read routine.

57C8
PUSH IX DD E5
Push the IX register (FCB pointer) onto the stack.
57CA
POP DE D1
Pop the value into DE, effectively copying IX to DE.
57CB
JUMP to the SYS0 sector read routine at 4436H with the FCB address in DE.

57CEH - Disk Write Subroutine

This subroutine writes a sector to disk using the FCB pointed to by IX. Similar to the read routine, it's a wrapper for the SYS0 write function.

57CE
PUSH IX DD E5
Push the IX register (FCB pointer) onto the stack.
57D0
POP DE D1
Pop the value into DE, copying IX to DE.
57D1
JUMP to the sector write routine at 5CE4H with the FCB address in DE.

57D4H - Disk Write with Verify

This subroutine writes a sector and optionally verifies it. Uses IX as the FCB pointer.

57D4
PUSH IX DD E5
Push the IX register (FCB pointer) onto the stack.
57D6
POP DE D1
Pop the value into DE, copying IX to DE.
57D7
JUMP to the SYS0 write-with-verify routine at 443CH.

57DAH - Display Error Status

This subroutine displays an error status message on the screen, showing the error type and the affected file/sector. It saves all registers before displaying and restores them after.

57DA
PUSH HL E5
Save Register HL onto the stack.
57DB
PUSH DE D5
Save Register DE onto the stack.
57DC
PUSH BC C5
Save Register BC onto the stack.
57DD
PUSH AF F5
Save Register AF (accumulator and flags) onto the stack.
57DE
CALL the carriage return output routine at 5881H to start on a new line.
57E1
LD HL,59D3H 21 D3 59
Load HL with address 59D3H, pointing to the "ERROR WHILE " message string.
57E4
CALL the SYS0 string display routine at 4467H to print "ERROR WHILE ".
57E7
LD HL,5A67H 21 67 5A
Load HL with address 5A67H, pointing to "READING" message (default operation type).
57EA
LD B,00H 06 00
Load Register B with 00H. NOTE: This is self-modifying code - the 00H at 57EBH can be changed to 20H to select different messages.
57EC
BIT 6,B CB 70
Test bit 6 of Register B. If set, use "WRITING" message.
57EE
If the Z FLAG is set (bit 6 clear), JUMP to 57F3H to keep "READING" message.
57F0
LD HL,5A70H 21 70 5A
Load HL with address 5A70H, pointing to "WRITING" message string.
57F3
BIT 5,B CB 68
Test bit 5 of Register B. If set, use "VERIFYING" message.
57F5
If the Z FLAG is set (bit 5 clear), JUMP to 57FAH to use current message.
57F7
LD HL,5A79H 21 79 5A
Load HL with address 5A79H, pointing to "VERIFYING" message string.
57FA
CALL the SYS0 string display routine at 4467H to print the operation type.
57FD
LD HL,5A44H 21 44 5A
Load HL with address 5A44H, pointing to "DESTINATION" message.
5800
LD DE,(5B21H) ED 5B 21 5B
Load Register DE with the current sector number from 5B21H.
5804
BIT 7,B CB 78
Test bit 7 of Register B. If set, this is a source (not destination) operation.
5806
If the Z FLAG is set (bit 7 clear, destination), JUMP to 580FH.
5808
LD HL,5A3CH 21 3C 5A
Load HL with address 5A3CH, pointing to "SOURCE" message.
580B
LD DE,(5AEFH) ED 5B EF 5A
Load Register DE with the source sector number from 5AEFH.
580F
CALL the string display routine to print "SOURCE" or "DESTINATION".
5812
LD HL,5A5FH 21 5F 5A
Load HL with address 5A5FH, pointing to "SECTOR" message.
5815
CALL the string display routine to print "SECTOR".
5818
CALL the decimal number display routine at 5909H to print the sector number in DE.
581B
CALL the carriage return routine to move to the next line.
581E
LD A,(5996H) 3A 96 59
Load Register A with the option flags from 5996H.
5821
BIT 2,A CB 57
Test bit 2 of the option flags. If set, suppress detailed error info.
5823
If the NZ FLAG is set (suppress details), JUMP to 521EH to skip remaining output.
5826
CALL the disk error display routine at 5868H to show the detailed error message.

Continue the error display by showing the filename and prompting for retry.

5829
POP BC C1
Restore Register BC from the stack (saved at 57DCH). BC contains the sector/error count.
582A
LD HL,(593EH) 2A 3E 59
Load Register HL with the current drive pointer from 593EH.
582D
LD A,(4317H) 3A 17 43
Load Register A with the current drive number from SYS0 location 4317H.
5830
LD C,A 4F
Copy the drive number to Register C for later use.
5831
PUSH HL E5
Save the drive pointer onto the stack.
5832
PUSH BC C5
Save BC (with drive number in C) onto the stack.
5833
CALL the primary drive setup routine at 5582H to ensure the drive is properly selected.
5836
LD A,B 78
Load Register A with Register B (contains error flags from the drive setup).
5837
CALL the error prompt display routine at 584AH to show retry/cancel options.
583A
POP BC C1
Restore BC (with drive number) from the stack.
583B
POP DE D1
Restore DE (the drive pointer that was in HL) from the stack.
583C
PUSH AF F5
Save the user response (from 584AH) onto the stack.
583D
LD A,C 79
Load Register A with the drive number from C.
583E
CALL the drive initialization routine at 568DH to reset the drive to its original state.
5841
EX DE,HL EB
Exchange DE and HL, putting the drive pointer back in HL.
5842
CALL the common drive setup routine at 5585H to finalize drive selection.
5845
POP AF F1
Restore the user response from the stack.
5846
POP BC C1
Restore Register BC from the stack (originally saved at 57DCH).
5847
POP DE D1
Restore Register DE from the stack (originally saved at 57DBH).
5848
POP HL E1
Restore Register HL from the stack (originally saved at 57DAH).
5849
RET C9
Return to the caller with the user response flags set (Z=retry, NZ=cancel).

584AH - Display Retry/Cancel Prompt

This subroutine displays a retry/cancel prompt after an error. It checks if user interaction is allowed and either prompts the user or automatically cancels. Register A on entry contains error flags; Register B contains operation flags.

584A
LD HL,5995H 21 95 59
Load HL with address 5995H, the option flags location.
584D
BIT 7,(HL) CB 7E
Test bit 7 of the option flags. If set, user interaction is disabled (batch mode).
584F
If the NZ FLAG is set (no interaction mode), JUMP to the error handler at 521AH to abort.
5852
OR 0C0HOR 11000000 F6 C0
OR Register A with C0H (11000000 binary), setting the high bits to indicate error type.
5854
CALL the SYS0 error display routine at 4409H to show the error code.
5857
JUMP to 58C8H to display the retry/cancel prompt and get user response.

585AH - Error Handler with Retry Prompt

This is the main error handler that displays the error, prompts for retry, and optionally updates the error counter. Called when a disk error occurs during read/write/verify operations.

585A
CALL the error status display routine at 57DAH to show the error details.
585D
RET NZ C0
If the NZ FLAG is set (user chose cancel or error handler returned with error), RETURN immediately.

User chose to retry. Increment the error counter at IX+0AH/0BH (16-bit counter).

585E
INC (IX+0AH) DD 34 0A
Increment the low byte of the error counter at IX+0AH (FCB offset 10).
5861
If the NZ FLAG is set (no overflow), JUMP to 5866H to skip high byte increment.
5863
INC (IX+0BH) DD 34 0B
Increment the high byte of the error counter at IX+0BH (FCB offset 11) on overflow.
5866
XOR A AF
Clear Register A to zero, setting the Z FLAG to indicate retry.
5867
RET C9
Return with Z FLAG set (indicating user chose retry).

5868H - Display Disk Error Message

This subroutine displays a detailed disk error message including the filename. The error code is expected in a self-modifying location (5869H). Returns NZ if an error was displayed.

5868
XOR A AF
Clear Register A to zero.
5869
OR 00H F6 00
Self-modifying code: The 00H at 586AH is replaced with the actual error code. OR sets flags based on the error code.
586B
RET Z C8
If the Z FLAG is set (error code is 0, no error), RETURN immediately.
586C
LD HL,59E0H 21 E0 59
Load HL with address 59E0H, pointing to the "WITHIN FILE" message string.
586F
CALL the SYS0 string display routine at 4467H to print "WITHIN FILE".
5872
CALL the directory entry lookup routine at 56DDH to get the filename address.
5875
CALL the filename display routine at 58A0H to print the filename.
5878
CALL the carriage return routine to move to the next line.
587B
OR FFH F6 FF
OR Register A with FFH, setting it to FFH and clearing the Z FLAG to indicate an error was displayed.
587D
RET C9
Return with NZ FLAG set.

587EH - Message Display Subroutine

This is a general-purpose message display routine that prints a string pointed to by HL, followed by a carriage return.

587E
CALL the SYS0 string display routine at 4467H to print the message string pointed to by HL.

Fall through to output a carriage return.

5881H - Output Carriage Return

This subroutine outputs a carriage return character (0DH) to move the cursor to the beginning of the next line.

5881
LD A,0DH 3E 0D
Load Register A with 0DH (ASCII carriage return).
5883
JUMP to the character output routine at 58BDH to display the carriage return.

5886H - Display String with Control Characters Filtered

This subroutine displays B characters from the string at HL, converting control characters (below 20H) and high characters (80H and above) to spaces. Used for safe display of directory entries and user input.

5886
LD A,(HL) 7E
Load Register A with the character at the current position (HL).
5887
CP 20H FE 20
Compare Register A with 20H (space). Check if it's a control character.
5889
INC HL 23
Increment HL to point to the next character.
588A
If the Carry FLAG is set (character < 20H, control char), JUMP to 5890H to replace with space.
588C
CP 80H FE 80
Compare Register A with 80H. Check if it's a high character.
588E
If the Carry FLAG is set (character < 80H, normal printable), JUMP to 5892H to display it.
5890
LD A,20H 3E 20
Load Register A with 20H (space) to replace invalid characters.
5892
CALL the character output routine to display the character.
5895
Decrement B and JUMP back to 5886H if not zero to process the next character. [LOOP]
5897
RET C9
Return after displaying all characters.

5898H - Display B Spaces

This subroutine displays B space characters. Used for padding output and alignment.

5898
LD A,20H 3E 20
Load Register A with 20H (ASCII space).
589A
CALL the character output routine to display a space.
589D
Decrement B and JUMP back to 5898H if not zero. [LOOP]
589F
RET C9
Return after displaying all spaces.

58A0H - Display Filename from Directory Entry

This subroutine displays a filename in the format "FILENAME/EXT" from a directory entry. On entry, HL points to the directory entry. The filename is at offset +5 (8 characters) and extension at offset +13 (3 characters).

58A0
LD A,L 7D
Load Register A with the low byte of HL (directory entry pointer).
58A1
ADD 05H C6 05
Add 5 to Register A, calculating the offset to the filename within the directory entry.
58A3
LD L,A 6F
Store the result back in Register L. HL now points to the filename.
58A4
LD B,08H 06 08
Load Register B with 8, the length of the filename portion.
58A6
CALL the display non-space characters routine at 58B3H to print the filename.

Now display the extension with a "/" separator if present.

58A9
LD A,(HL) 7E
Load Register A with the first character of the extension.
58AA
CP 20H FE 20
Compare with 20H (space). Check if extension exists.
58AC
LD B,03H 06 03
Load Register B with 3, the length of the extension.
58AE
LD A,2FH 3E 2F
Load Register A with 2FH (ASCII "/" slash) for the separator.
58B0
If the NZ FLAG is set (extension exists, not space), CALL the output routine to print "/".

Fall through to display the extension characters.

58B3H - Display Non-Space Characters from String

This subroutine displays characters from the string at HL, skipping trailing spaces. B contains the maximum number of characters to check. Used for compact filename display.

58B3
LD A,(HL) 7E
Load Register A with the character at the current position.
58B4
CP 20H FE 20
Compare with 20H (space).
58B6
INC HL 23
Increment HL to the next character position.
58B7
If the NZ FLAG is set (not a space), CALL the output routine to display the character.
58BA
Decrement B and JUMP back to 58B3H if not zero. [LOOP]
58BC
RET C9
Return after processing all characters.

58BDH - Character Output Routine

This is the low-level character output routine. It saves DE, calls the ROM display routine, and restores DE. Character to output is in Register A.

58BD
PUSH DE D5
Save Register DE onto the stack (ROM routine may modify it).
58BE
PUSH AF F5
Save Register AF (character and flags) onto the stack.
58BF
CALL the ROM character output routine at 0033H to display the character in A.
58C2
POP AF F1
Restore Register AF from the stack.
58C3
POP DE D1
Restore Register DE from the stack.
58C4
RET C9
Return to the caller.

58C5H - Display String and Prompt

This routine displays a string and then shows the retry/cancel prompt. Used for error messages that require user response.

58C5
CALL the SYS0 string display routine at 4467H to print the message at HL.

Fall through to display the retry/cancel prompt.

58C8H - Retry/Cancel Prompt Handler

This subroutine displays the "REPLY C (CANCEL), R (RETRY) OR P (PROCEED)" prompt and waits for user input. Returns Z flag set if user chose Retry, NZ if Cancel or Proceed.

58C8
LD A,(5995H) 3A 95 59
Load Register A with the option flags from 5995H.
58CB
BIT 7,A CB 7F
Test bit 7 of the option flags. If set, no user interaction is allowed.
58CD
If the NZ FLAG is set (no-interaction mode), JUMP to 5249H to handle automatically.
58D0
LD HL,5A84H 21 84 5A
Load HL with address 5A84H, pointing to the "CPR" (Cancel/Proceed/Retry) prompt options.
58D3
CALL the menu prompt handler at 58E4H to display options and get user choice.
58D6
CP 01H FE 01
Compare the user's choice with 01H (Retry option index).
58D8
RET NC D0
If the NC FLAG is set (choice >= 1, Retry or Proceed), RETURN with appropriate flags.
58D9
LD A,39H 3E 39
Load Register A with error code 39H ("Operator Break/Cancel").
58DB
JUMP to the main error handler at 521AH with the cancel error.

58DEH - Yes/No Prompt Handler

This subroutine displays a yes/no prompt and returns the user's choice. Used for confirmation dialogs.

58DE
CALL the string display routine to print the prompt message at HL.
58E1
LD HL,5AB3H 21 B3 5A
Load HL with address 5AB3H, pointing to the "NY" (No/Yes) option string.

Fall through to the menu handler.

58E4H - Menu Prompt Handler

This is the general menu prompt handler. HL points to a null-terminated string of valid option characters. It displays the prompt, waits for a valid key, and returns the index of the chosen option in A (0-based).

58E4
PUSH BC C5
Save Register BC onto the stack.
58E5
PUSH HL E5
Save the option string pointer onto the stack.

Find the end of the option string to display the full prompt.

58E6
LD A,(HL) 7E
Load Register A with the character at the current position.
58E7
OR A B7
Test if A is zero (null terminator).
58E8
INC HL 23
Increment HL to the next character.
58E9
If the NZ FLAG is set (not at end), LOOP back to continue scanning. [SCAN LOOP]
58EB
CALL the string display routine. HL now points past the null, to the prompt text.

[INPUT LOOP] - Wait for a valid key press.

58EE
CALL the keyboard check routine at 572BH to get a key press.
58F1
POP HL E1
Restore the option string pointer from the stack.
58F2
LD C,FFH 0E FF
Initialize the option index counter to FFH (-1, will be incremented to 0).
58F4
PUSH HL E5
Save the option string pointer again for the next iteration.

Search for the pressed key in the option string.

58F5
INC (HL) 34
Temporarily increment the byte at HL (used as a check mechanism).
58F6
INC C 0C
Increment the option index counter.
58F7
DEC (HL) 35
Restore the original value at HL.
58F8
If the Z FLAG is set (byte was 0, end of options without match), LOOP back to wait for another key.
58FA
CP (HL) BE
Compare the pressed key (in A) with the current option character.
58FB
INC HL 23
Increment HL to the next option character.
58FC
If the NZ FLAG is set (no match), LOOP to check the next option.

Match found! Display the selected character and return.

58FE
CALL the character output routine to echo the selected option.
5901
CALL the carriage return routine to move to the next line.
5904
LD A,C 79
Load Register A with the option index from C.
5905
OR A B7
Set flags based on the option index (Z if index=0).
5906
POP HL E1
Clean up the stack (discard saved option pointer).
5907
POP BC C1
Restore Register BC from the stack.
5908
RET C9
Return with the option index in A and flags set accordingly.

5909H - Display Decimal Number

This subroutine displays the 16-bit number in DE as a decimal value. It uses a powers-of-10 table at 5933H to perform the conversion. Leading zeros are suppressed.

5909
LD BC,0400H 01 00 04
Load Register BC with 0400H. B=04 (4 digits to process for 10000s, 1000s, 100s, 10s), C=00 (leading zero flag).
590C
LD HL,5933H 21 33 59
Load HL with address 5933H, the powers-of-10 table (10000, 1000, 100, 10).

[DIGIT LOOP] - Process each decimal digit position.

590F
PUSH BC C5
Save the digit counter and leading zero flag.
5910
LD C,(HL) 4E
Load Register C with the low byte of the current power of 10.
5911
INC HL 23
Increment HL.
5912
LD B,(HL) 46
Load Register B with the high byte of the current power of 10. BC now contains the divisor.
5913
INC HL 23
Increment HL to point to the next power of 10.
5914
EX DE,HL EB
Exchange DE and HL. HL now contains the number, DE points to the table.
5915
LD A,2FH 3E 2F
Load Register A with 2FH (ASCII '0' minus 1). This will be incremented for each subtraction.

[SUBTRACTION LOOP] - Count how many times we can subtract the power of 10.

5917
INC A 3C
Increment the digit counter in A.
5918
ADD HL,BC 09
Add BC to HL. Wait - this should be SBC! Actually this adds the negative (BC contains negative value in two's complement context). Actually looking at the table, the values are stored normally. Let me reconsider...
5919
If the Carry FLAG is set (result positive, subtraction succeeded), LOOP back to subtract again.
591B
SBC HL,BC ED 42
Subtract BC from HL with borrow to restore the previous value (undo one extra subtraction).
591D
POP BC C1
Restore the digit counter and leading zero flag.
591E
EX DE,HL EB
Exchange back. DE contains the remainder, HL points to the table.
591F
CP 30H FE 30
Compare the digit with 30H (ASCII '0'). Check if this is a zero digit.
5921
If the NZ FLAG is set (non-zero digit), JUMP to 5927H to display it.
5923
INC C 0C
Increment C (test if we've displayed any non-zero digit yet).
5924
DEC C 0D
Decrement C back. If C was 0, Z flag is set (leading zero, suppress).
5925
If the Z FLAG is set (leading zero), JUMP to 592BH to skip displaying this digit.
5927
INC C 0C
Increment C to indicate we've displayed a non-zero digit (no more leading zero suppression).
5928
CALL the character output routine to display the digit.
592B
Decrement B (digit counter) and LOOP back if more digits to process. [LOOP]

Display the final (units) digit.

592D
LD A,E 7B
Load Register A with the remainder (units digit) from E.
592E
ADD 30H C6 30
Add 30H to convert to ASCII.
5930
JUMP to the character output routine to display the final digit and return.

5933H - Powers of 10 Table (DATA)

This table contains the powers of 10 used by the decimal display routine. Each entry is a 16-bit value stored in little-endian format. The values represent: -10000, -1000, -100, -10 (stored as two's complement negatives for the subtraction algorithm).

5933
DATA F0 D8
-10000 (D8F0H = -10000 in two's complement, or equivalently 55536 unsigned).
5935
DATA 18 FC
-1000 (FC18H = -1000 in two's complement).
5937
DATA 9C FF
-100 (FF9CH = -100 in two's complement).
5939
DATA F6 FF
-10 (FFF6H = -10 in two's complement).

593BH - System Variables and Buffers

This area contains system variables, flags, and buffer pointers used throughout the SYS6 FORMAT/COPY utility. Values shown are initial/default values; many are modified during operation.

593B
DATA 00
593BH: Reserved/scratch byte.
593C
DATA FF 6F
593CH-593DH: High memory pointer (default 6FFFH). Stores the top of available memory for buffers.
593E
DATA 42 59
593EH-593FH: Current drive parameter pointer (default points to 5942H).
5940
DATA 00 07
5940H-5941H: Option flags word. Bit 0: $ option present. Other bits control various FORMAT/COPY modes.

5942H - Drive Parameter Block Table

This table contains three 10-byte drive parameter blocks, one for each possible drive (0, 1, 2). Each block stores the drive status and buffer pointers. A value of FFH in the first byte indicates the drive slot is unused.

5942
DATA 00 01 00 00
Drive 0 Parameter Block (5942H-594BH): Status byte, flags, and pointers. 00H = active drive 0.
5946
DATA 99 59 99 59
Buffer pointers for drive 0 (pointing to 5999H).
594A
DATA 51 5A
Additional pointer/data for drive 0.
594C
DATA FF 02 E5 5A
Drive 1 Parameter Block (594CH-5955H): FFH in first byte = inactive/unused by default.
5950
DATA B7 59 A3 59
Buffer pointers for drive 1.
5954
DATA 3C 5A
Additional pointer/data for drive 1.
5956
DATA FF 04 17 5B
Drive 2 Parameter Block (5956H-595FH): FFH in first byte = inactive/unused by default.
595A
DATA C5 59 AD 59
Buffer pointers for drive 2.
595E
DATA 44 5A
Additional pointer/data for drive 2.

5960H - Filename Buffer Area

This area is used as a buffer for filename storage and manipulation during COPY operations. Initially filled with spaces (20H).

5960
DATA 20 20 20 20 20 20 20 20
Filename buffer (24 bytes of spaces): Used for temporary filename storage during file operations.
5968
DATA 20 20 20 20 20 20 20 20
Continuation of filename buffer.
5970
DATA 20 20 20 20 20 20 20 20
Continuation of filename buffer.

5978H - Disk Geometry Parameters

This area stores disk geometry and format parameters. These values are set during FORMAT initialization and used throughout disk operations.

5978
DATA 00 00 00 00
5978H-597BH: Reserved/padding bytes.
597C
DATA 08 08
597CH-597DH: Sectors per track values (default 8 for single density).
597E
DATA 82 00 00
597EH-5980H: Disk type flags and parameters. 82H indicates double-sided capability.
5981
DATA E0
5981H: Directory track/format flags.

5982H - Boot Sector Template

This is the boot sector name template that gets written to track 0 during FORMAT. Contains "BOOTNAME" followed by disk parameters.

5982
DATA 42 4E 4F 54 4E 41 4D 45 44
Boot sector name: ASCII "BNOTNAMED" - default disk name template.
598B
DATA 32 3A 2F 34 3A 2F 3A 3A 0D 00
Date template: ASCII "2:/4:/::" followed by CR and null - date format string.

5994H - Operation Mode Flags

These bytes control the operation mode of the FORMAT/COPY utility. They are set based on command line options and modified during execution.

5994
DATA 00
5994H: Primary mode flags. Bit 0: verify after write, Bit 6: no boot sector.
5995
DATA 00
5995H: User interaction flags. Bit 7: suppress user prompts (batch mode).
5996
DATA 00
5996H: Error handling flags. Bit 2: suppress detailed errors, Bit 5: continue on error.
5997
DATA 00
5997H: Additional option flags.

5999H - Scratch/Buffer Area

This large area (5999H-59D2H) serves as a scratch buffer and temporary storage area. It is used for sector data during read/write operations.

5999
DATA 00 00 00 ... (58 bytes)
Scratch buffer area: 58 bytes of working space for disk operations. Initialized to zeros.

59D3H - Message Strings

This area contains the ASCII message strings displayed by the FORMAT/COPY utility. Each string is terminated with a control character (03H) or null. The disassembler shows these as instructions but they are actually string data.

59D3
DATA "ERROR WHILE " 45 52 52 4F 52 20 57 48 49 4C 45 20 03
"ERROR WHILE " - Prefix for error messages during read/write/verify operations.
59E0
DATA "WITHIN FILE " 57 49 54 48 49 4E 20 46 49 4C 45 20 20 03
"WITHIN FILE " - Shown when an error occurs within a specific file.
59EE
DATA "PRESS \"ENTER\" WHEN " 50 52 45 53 53 20 22 45 4E 54 45 52 22 20 57 48 45 4E 20 03
"PRESS \"ENTER\" WHEN " - Prompt prefix for disk change requests.
5A02
DATA " DISKETTE MOUNTED ON DRIVE 0" 20 44 49 53 4B 45 54 54 45 20 4D 4F 55 4E 54 45 44 20 4F 4E 20 44 52 49 56 45 20 30 0D
" DISKETTE MOUNTED ON DRIVE 0" - Continuation of disk mount prompt.
5A1F
DATA "DONE" 44 4F 4E 45 0D
"DONE" - Success message after operation completes.
5A24
DATA "SOURCE & DEST SAME FILE" 53 4F 55 52 43 45 20 26 20 44 45 53 54 20 53 41 4D 45 20 46 49 4C 45 0D
"SOURCE & DEST SAME FILE" - Error when trying to copy a file onto itself.
5A3C
DATA "SOURCE " 53 4F 55 52 43 45 20 03
"SOURCE " - Label for source disk/file in COPY operations.
5A44
DATA "DESTINATION " 44 45 53 54 49 4E 41 54 49 4F 4E 20 03
"DESTINATION " - Label for destination disk/file in COPY operations.
5A51
DATA "** SYSTEM **" 2A 2A 20 53 59 53 54 45 4D 20 2A 2A 20 03
"** SYSTEM **" - Indicates a system file or disk.
5A5F
DATA "SECTOR " 53 45 43 54 4F 52 20 03
"SECTOR " - Prefix for sector number in error messages.
5A67
DATA "READING " 52 45 41 44 49 4E 47 20 03
"READING " - Operation type for error messages.
5A70
DATA "WRITING " 57 52 49 54 49 4E 47 20 03
"WRITING " - Operation type for error messages.
5A79
DATA "VERIFYING " 56 45 52 49 46 59 49 4E 47 20 03
"VERIFYING " - Operation type for verify phase.
5A84
DATA "CPR" 43 50 52 00
"CPR" - Menu options: Cancel, Proceed, Retry (null-terminated).
5A88
DATA "REPLY C (CANCEL), R (RETRY) OR P (PROCEED)" 52 45 50 4C 59 20 43 20 28 43 41 4E 43 45 4C 29 2C 20 52 20 28 52 45 54 52 59 29 20 4F 52 20 50 20 28 50 52 4F 43 45 45 44 29 0D
"REPLY C (CANCEL), R (RETRY) OR P (PROCEED)" - Retry/cancel prompt text.
5AB3
DATA "NY" 4E 59 00
"NY" - Menu options: No, Yes (null-terminated).
5AB6
DATA " (Y OR N) " 20 20 28 59 20 4F 52 20 4E 29 20 03
" (Y OR N) " - Yes/No prompt suffix.
5AC2
DATA "DISKETTE/GAT OVERFLOW" 44 49 53 4B 45 54 54 45 2F 47 41 54 20 4F 56 45 52 46 4C 4F 57 0D
"DISKETTE/GAT OVERFLOW" - Error when disk or Granule Allocation Table is full.
5AD8
DATA "DISK FULL - " 44 49 53 4B 20 46 55 4C 4C 20 2D 20 03
"DISK FULL - " - Error when destination disk runs out of space.

5AE5H - File Control Block (FCB) Template

This area contains the File Control Block used for disk I/O operations. It stores the current filename, extension, drive number, and sector information.

5AE5
DATA 82 20 00 00 42 00 00 FF 00 00
FCB Header: Drive/status (82H), flags, and initial parameters.
5AEF
DATA 00 00 00 00
5AEFH-5AF2H: Source sector pointer (used in COPY operations).

5AF3H - Sector Buffer Control Area

This area contains control structures for the sector buffer management. It tracks buffer allocation, dirty flags, and sector addresses.

This area contains an FFH-filled buffer used for sector data during COPY/BACKUP operations. The FFH bytes serve as uninitialized/available buffer space.

5AF3
DATA 5E 01 00 1F FF FF ...
Buffer control block: Pointers and status flags for sector buffering.
5AFF
DATA FF FF FF FF FF FF ...
Buffer pool: FFH-filled area used for sector data operation buffers (extends to ~5B50H).

5B17H - Destination File Control Block (FCB)

This is the second File Control Block used during COPY operations to track the destination file. It follows the same structure as the FCB at 5AE5H.

5B17
DATA 82 60 00 00 00 00 00 FF 00 00 00 00
Destination FCB: Status byte (82H=active), drive (60H), and file parameters. FF at offset 7 indicates no current sector loaded.
5B23
DATA FF FF 00 1F FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
5B23H-5B48H: Extended buffer space (38 bytes) for FCB operations and sector buffering.

5B49H - Third File Control Block (FCB)

A third FCB structure used for intermediate file operations during multi-file copy or backup operations.

5B49
DATA 82 60 00 00 42 00 00 FF 00 00 00 00 FF FF
Third FCB: Status (82H), drive (60H), file type (42H='B'), and parameters.

5B57H - Option Handler Dispatch Table

This table maps option codes to their handler routines. Each entry contains: option code, parameter bytes, and either inline code or a jump to the handler. The table is processed by the option parser at 55FBH to handle FORMAT/COPY command-line options.

5B57
DATA 02 00 64 5B
Option entry 02: Points to handler at 5B64H.
5B5B
DATA 04 00 A3 5B
Option entry 04: Points to handler at 5BA3H.
5B5F
DATA 05 00 E1 5B
Option entry 05: Points to handler at 5BE1H.
5B63
DATA 00
Table terminator: Zero marks end of dispatch table.

5B64H - Option Handler: DD (Double Density) Parameter

This handler processes double-density format parameters. The structure contains SYS0 function references and parameter values used during FORMAT operations.

5B64
DATA 3D 46 01 A8 41
Parameter block: 3DH marker, reference to 4641H (GAT handling), parameter 41A8H.
5B69
DATA 46 01 A9 37
Continuation: Additional parameters (4601H, 37A9H).
5B6D
DATA 47 03
Parameter 47H: Option flag with count 03H.
5B6F
JUMP to 5C0BH to execute the DD option handler.

5B72H - Option Handler: Stepping Rate Parameter

This handler processes disk stepping rate parameters for the FDC (Floppy Disk Controller).

5B72
DATA 37 48 01 0D 77
Parameter block: 37H marker, reference to 4801H, stepping parameter 770DH.
5B77
DATA 48 03
Parameter 48H: Option flag with count 03H.
5B79
JUMP to 5C3EH to execute the stepping rate handler.

5B7CH - Option Handler: Verify Parameter

This handler processes the verify flag for FORMAT/COPY operations.

5B7C
DATA 92 48 03
Parameter block: 92H marker, reference to 4803H (verify function).
5B7F
JUMP to 5C43H to execute the verify option handler.

5B82H - Option Handler: Head Load/Sectors Per Track

This handler processes head load timing and sectors-per-track parameters.

5B82
DATA EE 48 01 00 F4
Parameter block: EEH marker, reference to 4801H, parameter F400H.
5B87
DATA 48 01 01 38
Continuation: Parameter 4801H, value 3801H.
5B8B
DATA 49 03
Parameter 49H: Option flag with count 03H.
5B8D
JUMP to 5C1EH to execute the head load option handler.

5B90H - Option Handler: Track/Cylinder Parameters

This handler processes track count and cylinder configuration parameters.

5B90
DATA 88 4C 01 03 B3
Parameter block: 88H marker, reference to 4C01H, parameter B303H.
5B95
DATA 4C 01 03 7F
Continuation: Parameter 4C01H, value 7F03H.
5B99
DATA 4A 01 21 EB 56
Parameter 4AH: Points to 56EBH handler.
5B9E
DATA 01 CD 00 00 00
Additional parameters: Call vector and padding.

5BA3H - Option Handler: Buffer/Memory Parameters

This handler processes buffer size and memory allocation parameters for COPY operations.

5BA3
DATA B2 4E 01 50 D0
Parameter block: B2H marker, reference to 4E01H, buffer parameter D050H.
5BA8
DATA 4E 03 00 00 00
Continuation: Parameter 4E03H with padding.
5BAD
DATA 20 4E 01 AF 68
Parameter 20H: Reference to 4E01H, value 68AFH.
5BB2
DATA 4F 01 00 7B
Parameter 4FH: Value 7B00H.
5BB6
DATA 4F 01 1A AF
Continuation: Parameter 4F01H, value AF1AH.
5BBA
DATA 4F 01 00 0A
Continuation: Parameter 4F01H, value 0A00H.
5BBE
DATA 50 01 00 61
Parameter 50H: Value 6100H.
5BC2
DATA 50 03
Parameter 50H: Option flag with count 03H.

5BC4H - Inline Option Code: Name Validation

This inline code validates disk name parameters during FORMAT operations.

5BC4
LD A,1AH 3E 1A
Load 1AH (end-of-file marker) into Register A for comparison.
5BC6
OR A B7
Set flags based on A (always non-zero here).
5BC7
SUB 50H D6 50
Subtract 50H ('P') from A to check range.
5BC9
DATA 03
Parameter byte: Count or flag value.
5BCA
JUMP to 5C5BH to continue name validation.

5BCDH - Option Handler: Directory Parameters

This handler processes directory entry count and allocation parameters.

5BCD
DATA 12 51 01 1A 55
Parameter block: 12H marker, reference to 5101H, parameter 551AH.
5BD2
DATA 51 04
Parameter 51H: Option flag with count 04H.
5BD4
LD HL,5CEFH 21 EF 5C
Load HL with address 5CEFH (directory parameter handler).
5BD7
RET C9
RETURN to caller with HL pointing to handler.

5BD8H - Option Handler: System Configuration

This handler processes system configuration parameters and memory mapping options.

5BD8
RST 28H EF
Call RST 28H - DOS function dispatcher.
5BD9
DATA 4D 03
Function 4DH: System configuration with count 03H.
5BDB
CALL 5C71H to process system memory parameters.
5BDE
DATA 00 00 00
Padding: Three null bytes for alignment.

5BE1H - Option Handler: Disk Geometry Parameters

This handler processes disk geometry parameters including sector size, track count, and side configuration.

5BE1
DATA 61 4E 01 0D 6C
Parameter block: 61H marker, reference to 4E01H, parameter 6C0DH.
5BE6
DATA 4E 01 00 CE
Continuation: Parameter 4E01H, value CE00H.
5BEA
DATA 4E 01 18 EF
Continuation: Parameter 4E01H, value EF18H.
5BEE
DATA 4E 02 35 56
Parameter 4EH: Reference to 5635H handler.
5BF2
DATA DA 4E 01 2F 8B
Parameter DAH: Reference to 4E01H, value 8B2FH.
5BF7
DATA 4E 01 18 72
Continuation: Parameter 4E01H, value 7218H.
5BFB
DATA 4E 03
Parameter 4EH: Option flag with count 03H.
5BFD
JUMP to 5C69H to execute geometry parameter handler.

5C00H - Sector Size Configuration Data

This area contains configuration data for sector size settings. The values are used by the FORMAT command to set up disk parameters.

5C00
DATA 32 50 01 00 40 4E 01 13 00 00 00
Sector configuration block: Sector size parameters (256 bytes = 0100H at 5C03H), track parameters.

5C0BH - DD Option Handler: Double Density Processing

This routine handles the double-density option for FORMAT operations. It checks the current density setting and adjusts format parameters accordingly.

5C0B
EI FB
Enable interrupts to allow system operations during format setup.
5C0C
POP BC C1
Restore BC (contains option parsing state).
5C0D
If NZ FLAG (not zero), JUMP to 5C19H to check error code.
5C0F
LD A,(46C4H) 3A C4 46
Load drive configuration byte from 46C4H (current drive parameters).
5C12
AND 20HAND 00100000 E6 20
Mask with 20H to isolate double-density flag (bit 5).
5C14
If double-density is enabled, JUMP to 5C1CH to return success.
5C16
ADD 06H C6 06
Add 06H to A to create error code for single-density only drive.
5C18
RET C9
RETURN with error code in A.
5C19
CP 06H FE 06
Compare A with 06H (density not supported error).
5C1B
RET NZ C0
If not error 06H, RETURN with current error code.
5C1C
XOR A AF
Clear Register A (set to zero for success).
5C1D
RET C9
RETURN with A=0 indicating success.

5C1EH - Head Load Option Handler

This routine processes head load timing parameters for the FDC. It calculates the appropriate head load value based on drive capabilities and user settings.

5C1E
PUSH BC C5
Save BC (option parsing context) to the stack.
5C1F
PUSH HL E5
Save HL (parameter pointer) to the stack.
5C20
LD L,A 6F
Copy A (user-specified value) to L.
5C21
LD H,00H 26 00
Clear H to make HL = 00xxH (value in L only).
5C23
LD A,05H 3E 05
Load 05H into A (function code for head load calculation).
5C25
CALL 4CB4H (SYS0) - Calculate head load timing value.
5C28
LD H,A 67
Copy result to H (calculated head load value).
5C29
LD A,L 7D
Retrieve original user value from L.
5C2A
LD L,H 6C
Move calculated value from H to L.
5C2B
EX (SP),HL E3
Exchange HL with top of stack (swap with saved HL).
5C2C
INC A 3C
Increment A (adjust user value).
5C2D
INC A 3C
Increment A again (add 2 to original value).
5C2E
CP L BD
Compare adjusted user value with calculated value.
5C2F
If values differ, CALL 490AH (SYS0) to set head load parameter.
5C32
POP HL E1
Restore HL from the stack.
5C33
POP BC C1
Restore BC from the stack.
5C34
RET NZ C0
If NZ FLAG (error occurred), RETURN with error.
5C35
LD A,30H 3E 30
Load 30H ('0') into A for display offset calculation.
5C37
CALL 4C92H (SYS0) - Convert value to display format.
5C3A
LD A,L 7D
Load converted value from L into A.
5C3B
JUMP to 4947H (SYS0) to store the head load parameter.

5C3EH - Stepping Rate Option Handler

This routine handles the stepping rate parameter for the FDC. It validates the stepping rate and configures the controller accordingly.

5C3E
EX AF,AF' 08
Exchange AF with alternate AF' (save current flags).
5C3F
DEC A 3D
Decrement A (adjust stepping rate value).
5C40
If NZ FLAG (value not zero), JUMP to 4838H (SYS0) to set stepping rate.

5C43H - Verify Option Handler

This routine handles the verify flag for FORMAT operations. When verify is enabled, each track is read back after writing to confirm data integrity.

5C43
POP AF F1
Discard return address from stack (unwinding call chain).
5C44
POP AF F1
Discard another return address from stack.
5C45
POP AF F1
Discard third return address from stack.
5C46
LD A,(48BBH) 3A BB 48
Load format status byte from 48BBH.
5C49
OR A B7
Test if status byte is zero.
5C4A
If NZ FLAG (status non-zero), JUMP to 48B8H (SYS0) error handler.
5C4D
LD A,(IX+07H) DD 7E 07
Load format parameter byte from FCB offset 07H.
5C50
LD (486AH),A 32 6A 48
Store format parameter to 486AH (format control variable).
5C53
LD A,64H 3E 64
Load 64H (100 decimal) - verify retry count.
5C55
CALL 49DDH (SYS0) - Initialize verify operation.
5C58
JUMP to 4813H (SYS0) to continue format with verify.

5C5BH - Name Validation Handler

This routine validates disk name parameters by scanning the input buffer for valid characters. Names can be up to 80 characters.

5C5B
LD B,50H 06 50
Load 50H (80 decimal) into B as maximum name length counter.
5C5D
LD A,(HL) 7E
[LOOP START] Load character from name buffer into A.
5C5E
OR A B7
Test if character is null (end of name).
5C5F
If Z FLAG (null terminator), JUMP to 50FEH - name complete.
5C62
INC HL 23
Advance to next character in name buffer.
5C63
Decrement B and [LOOP] back to 5C5DH if not zero.
5C65
LD A,1AH 3E 1A
Load 1AH (EOF marker) - name too long error.
5C67
OR A B7
Set NZ flag to indicate error condition.
5C68
RET C9
RETURN with error (A=1AH, NZ flag set).

5C69H - Geometry Parameter Handler

This routine processes disk geometry parameters and updates the format configuration accordingly.

5C69
DEC E 1D
Decrement E (geometry parameter counter).
5C6A
If NZ FLAG (more parameters), JUMP to 4E62H (SYS0) to process next.
5C6D
INC HL 23
Advance HL past current parameter.
5C6E
JUMP to 4E95H (SYS0) to finalize geometry setup.

5C71H - System Memory Parameter Handler

This routine reads system memory configuration values and stores them in the format parameter block.

5C71
INC HL 23
Advance HL to parameter storage location.
5C72
LD A,(4046H) 3A 46 40
Load high memory pointer high byte from 4046H.
5C75
LD (HL),A 77
Store high byte to parameter block.
5C76
INC HL 23
Advance to next storage location.
5C77
LD A,(4044H) 3A 44 40
Load high memory pointer low byte from 4044H.
5C7A
LD (HL),A 77
Store low byte to parameter block.
5C7B
DEC HL 2B
Move back to first byte.
5C7C
DEC HL 2B
Move back to parameter start.
5C7D
JUMP to 4E1FH (SYS0) to continue parameter processing.

5C80H - Set Up Sector Size (Returns BC=256)

This routine sets up the sector size parameter. For standard TRS-80 disks, this returns BC=0100H (256 bytes per sector).

5C80
LD BC,0100H 01 00 01
Load BC with 0100H (256 decimal) - standard sector size.
5C83
OR A B7
Test A register and set flags.
5C84
RET NZ C0
If NZ FLAG (A non-zero), RETURN with BC=256.
5C85
INC DE 13
Advance DE to sector size field in parameter block.
5C86
INC DE 13
Advance DE again (2-byte offset).
5C87
LD A,(DE) 1A
Load sector size code from parameter block.
5C88
LD (64BCH),A 32 BC 64
Store sector size code to 64BCH (format parameter table).
5C8B
DEC DE 1B
Move DE back to original position.
5C8C
DEC DE 1B
Move DE back (restore original pointer).
5C8D
RET C9
RETURN with sector size configured.

5C8EH - Set Up Sector Buffer Address

This routine stores the sector buffer address and sets the FCB flag to indicate the buffer is configured.

5C8E
LD (5B1AH),HL 22 1A 5B
Store HL (buffer address) to 5B1AH (destination FCB buffer pointer).
5C91
SET 6,(IX+01H) DD CB 01 F6
Set bit 6 of FCB+01H to indicate buffer is allocated.
5C95
RET C9
RETURN to caller.

5C96H - FORMAT Initialization

This routine initializes FORMAT operation parameters by reading source and destination drive configurations and checking for compatibility. It sets up the option dispatch table pointers for double-sided disk operations.

5C96
CALL 63B3H to initialize format parameter tables.
5C99
LD A,(59BEH) 3A BE 59
Load source drive configuration byte from 59BEH.
5C9C
LD B,A 47
Copy source config to B for later comparison.
5C9D
LD A,(59B9H) 3A B9 59
Load source drive flags from 59B9H.
5CA0
LD C,A 4F
Copy source flags to C.
5CA1
LD A,(59CCH) 3A CC 59
Load destination drive configuration byte from 59CCH.
5CA4
LD D,A 57
Copy destination config to D.
5CA5
LD A,(59C7H) 3A C7 59
Load destination drive flags from 59C7H.
5CA8
LD E,A 5F
Copy destination flags to E. Now BC=source, DE=destination.
5CA9
LD A,C 79
Load source flags into A.
5CAA
AND E A3
AND with destination flags to find common capabilities.
5CAB
BIT 5,A CB 6F
Test bit 5 (double-sided capability) in both drives.
5CAD
If Z FLAG (not both double-sided), JUMP to 5CB5H.
5CAF
LD A,B 78
Load source configuration into A.
5CB0
XOR D AA
XOR with destination configuration to find differences.
5CB1
RRCA 0F
Rotate right to move bit 0 to Carry flag.
5CB2
If Carry (configurations differ), JUMP to 6747H - incompatible drives error.
5CB5
LD A,B 78
Load source configuration back into A.
5CB6
BIT 5,C CB 69
Test bit 5 of source flags (double-sided source).
5CB8
If NZ FLAG (source is double-sided), JUMP to 5CBEH.
5CBA
BIT 5,E CB 6B
Test bit 5 of destination flags (double-sided dest).
5CBC
RET Z C8
If Z FLAG (destination single-sided), RETURN - no double-sided setup needed.
5CBD
LD A,D 7A
Load destination configuration into A.
5CBE
RRCA 0F
Rotate right to test bit 0.
5CBF
RET C D8
If Carry (bit 0 set), RETURN - already configured.

The following code sets up dispatch table pointers for double-sided disk operations by redirecting option handlers to the appropriate routines.

5CC0
LD HL,5B5BH 21 5B 5B
Load HL with address 5B5BH (option entry 04 pointer).
5CC3
LD (55F7H),HL 22 F7 55
Store to 55F7H - redirect option handler entry.
5CC6
LD HL,5BB1H 21 B1 5B
Load HL with address 5BB1H (buffer parameter entry).
5CC9
LD (5B5DH),HL 22 5D 5B
Store to 5B5DH - update option table pointer.
5CCC
LD HL,5C00H 21 00 5C
Load HL with address 5C00H (sector config data).
5CCF
LD (5B61H),HL 22 61 5B
Store to 5B61H - update sector config pointer.
5CD2
XOR A AF
Clear Register A to zero.
5CD3
LD (617FH),A 32 7F 61
Store zero to 617FH (clear side flag).
5CD6
LD H,A 67
Copy zero to H.
5CD7
LD L,A 6F
Copy zero to L. HL now = 0000H.
5CD8
LD (61BFH),HL 22 BF 61
Store zero to 61BFH (clear track counter).
5CDB
LD (5BB5H),HL 22 B5 5B
Store zero to 5BB5H (clear option parameter).
5CDE
LD A,18H 3E 18
Load 18H (24 decimal) - default sector count.
5CE0
LD (612DH),A 32 2D 61
Store to 612DH (sectors per track parameter).
5CE3
RET C9
RETURN with double-sided parameters configured.

5CE4H - DOS Configuration Check

This routine checks the DOS configuration flags and sets FCB parameters based on system capabilities.

5CE4
LD A,(430CH) 3A 0C 43
Load DOS configuration byte from 430CH.
5CE7
BIT 5,A CB 6F
Test bit 5 (extended disk support flag).
5CE9
If Z FLAG (not extended), JUMP to 5CEFH.
5CEB
SET 5,(IX+02H) DD CB 02 EE
Set bit 5 of FCB+02H to enable extended mode.
5CEF
JUMP to 4439H (SYS0) to continue configuration.

5CF2H - Extended Mode Sector Count Check

This routine checks if extended disk mode is active and returns the appropriate sector count multiplier.

5CF2
BIT 5,(IX+02H) DD CB 02 6E
Test bit 5 of FCB+02H (extended mode flag).
5CF6
If Z FLAG (not extended mode), JUMP to 5CFCH.
5CF8
BIT 0,(IX+07H) DD CB 07 46
Test bit 0 of FCB+07H (sector size indicator).
5CFC
If Z FLAG (standard sectors), JUMP to 4CB2H (SYS0).
5CFF
LD A,03H 3E 03
Load 03H into A (extended sector count multiplier).
5D01
JUMP to 4CB4H (SYS0) with multiplier in A.

5D04H - Scratch Area / Reserved Space

This area contains 13 bytes of zeros used as scratch space or reserved for future use. Some bytes may be modified during FORMAT operations.

5D04
DATA 00 00 00 00 00 00 00 00 00 00 00 00 00
5D04H-5D10H: 13 bytes of scratch/reserved space.

5D11H - PDRIVE/AUTO Processing Variables

This area contains variables for processing PDRIVE (physical drive) and AUTO configuration parameters during FORMAT with system disk creation.

5D11
DATA 42
5D11H: Default parameter value (42H = 'B').
5D12
DATA 16 5D
5D12H: Pointer to AUTO command buffer (initially 5D16H).
5D14
DATA 16 5D
5D14H: Secondary pointer to AUTO command buffer.

5D16H - FORMAT System Disk Initialization

This routine handles the initialization for creating a system disk during FORMAT. It clears FCB flags, checks for PDRIVE/AUTO options, and sets up the source drive for file copying.

5D16
CALL 6643H to initialize system file parameters.
5D19
LD HL,5AE5H 21 E5 5A
Load HL with address of primary FCB at 5AE5H.
5D1C
RES 1,(HL) CB 8E
Clear bit 1 of FCB status (reset file open flag).
5D1E
LD HL,5B17H 21 17 5B
Load HL with address of secondary FCB at 5B17H.
5D21
RES 1,(HL) CB 8E
Clear bit 1 of secondary FCB status.
5D23
LD A,(5997H) 3A 97 59
Load option flags from 5997H.
5D26
AND 30H E6 30
Mask with 30H to isolate PDRIVE/AUTO bits (bits 4-5).
5D28
If Z FLAG (no PDRIVE/AUTO), JUMP to 5D86H to skip special handling.
5D2A
CALL 568BH to set up primary drive for reading.
5D2D
LD HL,6491H 21 91 64
Load HL with address of input buffer at 6491H.
5D30
LD DE,4480H 11 80 44
Load DE with address of command line buffer at 4480H.
5D33
LD A,(448CH) 3A 8C 44
Load command line length from 448CH.
5D36
CP 0BH FE 0B
Compare with 0BH (11) - minimum valid length.
5D38
If NC (length >= 11), JUMP to 5D65H - invalid parameter.

The following loop reads the AUTO/PDRIVE command string from the terminal, validating each character.

5D3A
LD B,0DH 06 0D
[LOOP START] Load B with 0DH (13) - max parameter length.
5D3C
CALL 5D71H to read next character from input.
5D3F
If Z FLAG (carriage return), [LOOP] back to 5D3AH for new line.
5D41
CP 20H FE 20
Compare with 20H (space character).
5D43
If Z FLAG (space), [LOOP] back to 5D3AH to skip whitespace.
5D45
CP 3BH FE 3B
Compare with 3BH (semicolon - comment marker).
5D47
If NZ FLAG (not semicolon), JUMP to 5D53H to store character.

Handle comment - skip to end of line.

5D49
[SKIP COMMENT LOOP] Read next character.
5D4C
If NZ FLAG (not carriage return), [LOOP] back to 5D49H.
5D4E
JUMP back to 5D3AH for next line.

Store valid characters and validate filename format.

5D50
[CHARACTER LOOP] Read next character.
5D53
LD (HL),A 77
Store character in buffer.
5D54
INC HL 23
Advance buffer pointer.
5D55
If Z FLAG (end of line), [LOOP] back to 5D3AH.
5D57
SUB 2FH D6 2F
Subtract 2FH ('/' - 1) to normalize for digit check.
5D59
CP 0BH FE 0B
Compare with 0BH (check if digit 0-9 or ':').
5D5B
If Carry (valid digit/colon), JUMP to 5D63H.
5D5D
SUB 12H D6 12
Subtract 12H to check for letter A-Z.
5D5F
CP 1AH FE 1A
Compare with 1AH (26 letters).
5D61
If NC (invalid character), JUMP to 5D65H - error.
5D63
Decrement B and [LOOP] back to 5D50H if not zero.

Error handler - invalid AUTO/PDRIVE parameter.

5D65
LD A,01H 3E 01
Load 01H into A - error code 1 (invalid parameter).
5D67
PUSH AF F5
Save error code to stack.
5D68
LD HL,6283H 21 83 62
Load HL with address of error message at 6283H.
5D6B
CALL 4467H (SYS0) to display error message.
5D6E
JUMP to 521BH - error exit handler.

5D71H - Read Character from Input

This subroutine reads a single character from the input stream, handling special cases like BREAK key and end-of-file. Returns Z flag set if carriage return (end of line).

5D71
CALL 0013H (ROM) - Read character from input device.
5D74
If NZ FLAG (special condition), JUMP to 5D7DH.
5D76
AND 7FHAND 01111111 E6 7F
Mask off high bit (convert to 7-bit ASCII).
5D78
If Z FLAG (null character), [LOOP] back to read another.
5D7A
CP 0DH FE 0D
Compare with 0DH (carriage return).
5D7C
RET C9
RETURN with Z flag indicating if CR was received.

Handle special input condition (EOF or BREAK).

5D7D
CP 1CH FE 1C
Compare with 1CH (end-of-file marker).
5D7F
If NZ FLAG (not EOF), JUMP to 5D67H - error handler.
5D81
LD A,0DH 3E 0D
Load 0DH (carriage return) into A.
5D83
LD (HL),A 77
Store CR in buffer to terminate string.
5D84
INC HL 23
Advance buffer pointer.
5D85
LD (HL),A 77
Store second CR (double-terminate).

5D86H - Continue FORMAT Drive Setup

This routine continues the FORMAT drive setup by initializing the source drive parameters and calculating buffer space.

5D86
CALL 5578H to set up source drive for FORMAT.
5D89
CALL 6162H to read disk parameters from source.
5D8C
CALL 6178H to calculate sectors per track.
5D8F
LD (597CH),A 32 7C 59
Store sectors per track to 597CH.
5D92
LD A,C 79
Load track count from C.
5D93
LD (59C0H),A 32 C0 59
Store track count to 59C0H.
5D96
LD HL,(593CH) 2A 3C 59
Load high memory limit from 593CH.
5D99
LD DE,FFE8H 11 E8 FF
Load DE with FFE8H (-24 decimal) adjustment.
5D9C
ADD HL,DE 19
Subtract 24 from high memory to create safety margin.
5D9D
LD (61DBH),HL 22 DB 61
Store adjusted limit to 61DBH (buffer ceiling).
5DA0
LD A,(5997H) 3A 97 59
Load option flags from 5997H.
5DA3
AND 30H E6 30
Mask with 30H to isolate PDRIVE/AUTO bits.
5DA5
If Z FLAG (no special options), JUMP to 5E0FH.
5DA7
AND 10H E6 10
Mask with 10H to isolate PDRIVE bit only.
5DA9
LD C,A 4F
Copy PDRIVE flag to C.
5DAA
If Z FLAG (AUTO only), JUMP to 5DB5H.

Clear the track table for PDRIVE operation.

5DAC
XOR A AF
Clear A to zero.
5DAD
LD B,A 47
Copy zero to B (will wrap to 256 iterations).
5DAE
LD HL,6291H 21 91 62
Load HL with address of track table at 6291H.
5DB1
LD (HL),A 77
[LOOP START] Store zero to track table entry.
5DB2
INC HL 23
Advance to next entry.
5DB3
Decrement B and [LOOP] back if not zero (256 iterations).

5DB5H - Process AUTO/PDRIVE File List

This routine processes the file list for AUTO command or PDRIVE configuration, opening each file specified in the input buffer.

5DB5
LD HL,6491H 21 91 64
Load HL with address of input buffer at 6491H.
5DB8
LD A,(HL) 7E
[FILE LOOP] Load current character from buffer.
5DB9
CP 0DH FE 0D
Compare with 0DH (carriage return).
5DBB
If Z FLAG (end of list), JUMP to 5E07H.
5DBD
LD DE,447FH 11 7F 44
Load DE with address of filename buffer at 447FH.

Copy filename from input buffer to filename buffer.

5DC0
INC DE 13
[COPY LOOP] Advance destination pointer.
5DC1
LD A,(HL) 7E
Load character from source.
5DC2
CP 0DH FE 0D
Compare with 0DH (carriage return).
5DC4
LD (DE),A 12
Store character to destination.
5DC5
INC HL 23
Advance source pointer.
5DC6
If NZ FLAG (not CR), [LOOP] back to 5DC0H.

Append drive number to filename.

5DC8
EX DE,HL EB
Exchange DE and HL (HL now points to end of filename).
5DC9
LD (HL),3AH 36 3A
Store 3AH (':') as drive separator.
5DCB
INC HL 23
Advance to drive number position.
5DCC
LD A,(594CH) 3A 4C 59
Load source drive number from 594CH.
5DCF
LD B,64H 06 64
Load B with 64H (100) for decimal conversion.
5DD1
CALL 61CBH to convert hundreds digit.
5DD4
LD B,0AH 06 0A
Load B with 0AH (10) for decimal conversion.
5DD6
CALL 61CBH to convert tens digit.
5DD9
ADD 30H C6 30
Add 30H ('0') to convert units to ASCII.
5DDB
LD (HL),A 77
Store units digit.
5DDC
INC HL 23
Advance pointer.
5DDD
LD (HL),0DH 36 0D
Store 0DH (CR) to terminate filename.
5DDF
EX DE,HL EB
Exchange DE and HL (restore pointers).
5DE0
LD DE,4480H 11 80 44
Load DE with filename buffer address again.
5DE3
CALL 4424H (SYS0) - Open file by name.
5DE6
If Z FLAG (success), JUMP to 5DF1H.
5DE8
CP 18H FE 18
Compare error code with 18H (file not found).
5DEA
If Z FLAG (not found), [LOOP] back to try next file.
5DEC
CP 19H FE 19
Compare with 19H (end of directory).
5DEE
If NZ FLAG (other error), JUMP to 521AH - error handler.

5DF1H - Record File Track in Table

This routine records the track number of an opened file in the track table for later copying during system disk creation.

5DF1
LD A,(4F56H) 3A 56 4F
Load current track number from 4F56H.
5DF4
PUSH HL E5
Save HL (input buffer pointer) to stack.
5DF5
LD HL,6291H 21 91 62
Load HL with address of track table at 6291H.
5DF8
LD E,A 5F
Copy track number to E.
5DF9
LD D,00H 16 00
Clear D for 16-bit offset.
5DFB
ADD HL,DE 19
Add track number as offset to table base.
5DFC
LD A,C 79
Load PDRIVE flag from C.
5DFD
OR A B7
Test if PDRIVE mode.
5DFE
If Z FLAG (AUTO mode), JUMP to 5E03H.
5E00
LD A,(4D6EH) 3A 6E 4D
Load PDRIVE parameter from 4D6EH.
5E03
LD (HL),A 77
Store track marker in table.
5E04
POP HL E1
Restore input buffer pointer from stack.
5E05
JUMP back to 5DB8H to process next file.

5E07H - Finish AUTO/PDRIVE Processing

This routine completes the AUTO/PDRIVE file list processing and returns to normal FORMAT operation.

5E07
LD A,05H 3E 05
Load 05H into A (function code).
5E09
CALL 568DH to flush drive buffers.
5E0C
CALL 5578H to reset source drive setup.

5E0FH - Initialize AUTO Command Pointers

This routine initializes the AUTO command buffer pointers for system disk operations.

5E0F
LD HL,6491H 21 91 64
Load HL with address of input buffer at 6491H.
5E12
LD (5D12H),HL 22 12 5D
Store to 5D12H (AUTO command pointer 1).
5E15
LD (5D14H),HL 22 14 5D
Store to 5D14H (AUTO command pointer 2).
5E18
LD C,00H 0E 00
Load C with 00H (initial track counter).
5E1A
CALL 619DH to initialize track buffer.
5E1D
If NZ FLAG (error), JUMP to 5EAAH.
5E20
CALL 61F6H to read directory sector.
5E23
LD A,(5996H) 3A 96 59
Load option flags from 5996H.
5E26
If NZ FLAG (read error), JUMP to 5E32H.
5E28
BIT 0,A CB 47
Test bit 0 of option flags.
5E2A
If Z FLAG (bit 0 clear), JUMP to 5E32H.
5E2C
INC HL 23
Advance HL to check directory entry.
5E2D
BIT 5,(HL) CB 6E
Test bit 5 of directory entry (system flag).
5E2F
DEC HL 2B
Move back to start of entry.
5E30
If Z FLAG (not system), JUMP to 5EAAH.
5E32
BIT 4,A CB 67
Test bit 4 of option flags.
5E34
If Z FLAG (bit 4 clear), JUMP to 5E3EH.

5E36H - Check Directory Entry Flags

This code checks directory entry flags to determine if the entry should be processed during FORMAT/COPY operations.

5E36
BIT 6,(HL) CB 76
Test bit 6 of directory entry (invisible/hidden flag).
5E38
If NZ FLAG (hidden file), JUMP to 5EAAH to skip.
5E3A
BIT 3,(HL) CB 5E
Test bit 3 of directory entry (system file flag).
5E3C
If NZ FLAG (system file), JUMP to 5EAAH to skip.
5E3E
BIT 1,A CB 4F
Test bit 1 of option flags (extension filter active).
5E40
If Z FLAG (no filter), JUMP to 5E5BH.

Compare file extension with filter pattern.

5E42
PUSH HL E5
Save directory entry pointer to stack.
5E43
PUSH DE D5
Save DE to stack.
5E44
PUSH BC C5
Save BC to stack.
5E45
LD DE,000DH 11 0D 00
Load DE with 0DH (13) - offset to file extension.
5E48
ADD HL,DE 19
Add offset to point to extension field.
5E49
LD DE,624CH 11 4C 62
Load DE with address of extension filter pattern at 624CH.
5E4C
LD B,03H 06 03
Load B with 03H - extension length (3 characters).
5E4E
LD A,(DE) 1A
[COMPARE LOOP] Load filter character.
5E4F
CP (HL) BE
Compare with file extension character.
5E50
INC DE 13
Advance filter pointer.
5E51
INC HL 23
Advance extension pointer.
5E52
If NZ FLAG (mismatch), JUMP to 5E56H.
5E54
Decrement B and [LOOP] if not zero.
5E56
POP BC C1
Restore BC from stack.
5E57
POP DE D1
Restore DE from stack.
5E58
POP HL E1
Restore directory entry pointer from stack.
5E59
If NZ FLAG (extension mismatch), JUMP to 5EAAH to skip file.

5E5BH - Process Valid Directory Entry

This routine processes a valid directory entry that passed all filters, checking for additional conditions like password protection.

5E5B
LD D,(HL) 56
Load directory entry status byte into D.
5E5C
BIT 6,D CB 72
Test bit 6 (password protected flag).
5E5E
If NZ FLAG (protected), CALL 61EAH to handle password.
5E61
If NZ FLAG (password failed), JUMP to 5EAAH.
5E63
LD A,(5995H) 3A 95 59
Load additional option flags from 5995H.
5E66
BIT 6,A CB 77
Test bit 6 (confirmation prompt flag).
5E68
If Z FLAG (no prompt), JUMP to 5E87H.

Display confirmation prompt for this file.

5E6A
PUSH DE D5
Save DE to stack.
5E6B
PUSH BC C5
Save BC to stack.
5E6C
CALL 58A0H to display filename.
5E6F
LD HL,625CH 21 5C 62
Load HL with address of confirmation prompt at 625CH.
5E72
CALL 58E4H to display prompt and get response.
5E75
POP BC C1
Restore BC from stack.
5E76
POP DE D1
Restore DE from stack.
5E77
If NZ FLAG (response not default), JUMP to 5E81H.
5E79
LD HL,6D5EH 21 5E 6D
Load HL with address of skip message at 6D5EH.
5E7C
CALL 4467H (SYS0) to display message.
5E7F
JUMP back to 5E0FH to restart with next file.
5E81
DEC A 3D
Decrement A (check response code).
5E82
If Z FLAG (response = 1, proceed), JUMP to 5EB3H.
5E84
DEC A 3D
Decrement A again.
5E85
If Z FLAG (response = 2, skip), JUMP to 5EAAH.

5E87H - Store Directory Entry in Track List

This routine stores the directory entry information in the track list for later processing during FORMAT/COPY operations.

5E87
LD HL,(5D14H) 2A 14 5D
Load HL with track list pointer from 5D14H.
5E8A
LD (HL),80H 36 80
Store 80H as entry marker (indicates valid entry).
5E8C
BIT 6,D CB 72
Test bit 6 of directory status (password protected).
5E8E
If Z FLAG (not protected), JUMP to 5EA2H.
5E90
LD A,(5997H) 3A 97 59
Load option flags from 5997H.
5E93
BIT 3,A CB 5F
Test bit 3 (preserve password flag).
5E95
If NZ FLAG (preserve), JUMP to 5EA2H.
5E97
LD A,C 79
Load track number into A.
5E98
CP 80H FE 80
Compare with 80H (128).
5E9A
If NC (track >= 128), JUMP to 5EA2H.
5E9C
AND 18H E6 18
Mask with 18H to check track range.
5E9E
If NZ FLAG (not in range), JUMP to 5EA2H.
5EA0
SET 6,(HL) CB F6
Set bit 6 of track entry marker (flag for processing).
5EA2
INC HL 23
Advance track list pointer.
5EA3
LD (HL),C 71
Store track number low byte.
5EA4
INC HL 23
Advance pointer.
5EA5
LD (HL),B 70
Store track number high byte.
5EA6
INC HL 23
Advance pointer.
5EA7
LD (5D14H),HL 22 14 5D
Update track list pointer at 5D14H.

5EAAH - Advance to Next Directory Entry

This routine advances to the next directory entry and checks if there are more entries to process.

5EAA
LD HL,597CH 21 7C 59
Load HL with address of sectors per track counter at 597CH.
5EAD
CALL 61BAH to advance sector counter.
5EB0
If NC (more sectors), JUMP back to 5E1AH to continue.

5EB3H - Begin Track Processing

This routine begins processing the collected track list, reading and copying data from source to destination.

5EB3
CALL 6190H to reset track position.
5EB6
CALL 5699H to check end-of-disk condition.
5EB9
If Z FLAG (end of disk), JUMP to 552DH to finish.
5EBC
PUSH HL E5
[TRACK LOOP] Save current position to stack.
5EBD
CALL 61D6H to get next track entry.
5EC0
If Carry (entry found), JUMP to 5ECEH.
5EC2
CALL 5EE4H to process track data.
5EC5
CALL 5578H to set up source drive.
5EC8
CALL 6190H to reset position.
5ECB
POP HL E1
Restore position from stack.
5ECC
[LOOP] back to 5EBCH for next track.

5ECEH - Copy Track Entry Data

This routine copies the track entry data to the destination buffer.

5ECE
INC HL 23
Advance past entry marker.
5ECF
LD A,(HL) 7E
Load track number from entry.
5ED0
CALL 56EFH to seek to specified track.
5ED3
LD BC,0018H 01 18 00
Load BC with 0018H (24 bytes) - entry data length.
5ED6
LDIR ED B0
Copy BC bytes from (HL) to (DE).
5ED8
POP HL E1
Restore saved position from stack.
5ED9
SET 4,(HL) CB E6
Set bit 4 of entry marker (processed flag).
5EDB
CALL 5699H to check end condition.
5EDE
If NZ FLAG (more data), [LOOP] back to 5EBCH.
5EE0
LD HL,60BFH 21 BF 60
Load HL with address 60BFH (continuation point).
5EE3
PUSH HL E5
Push return address to stack (will return to 60BFH).

5EE4H - Set Up Destination Drive Parameters

This routine sets up the destination drive parameters by reading disk geometry and calculating sector counts.

5EE4
CALL 557DH to select destination drive.
5EE7
CALL 6162H to read disk parameters.
5EEA
CALL 6178H to calculate sectors per track.
5EED
LD (597DH),A 32 7D 59
Store destination sectors per track to 597DH.
5EF0
LD A,C 79
Load track count from C.
5EF1
LD (59CEH),A 32 CE 59
Store destination track count to 59CEH.
5EF4
LD A,(5997H) 3A 97 59
Load option flags from 5997H.
5EF7
BIT 3,A CB 5F
Test bit 3 (special processing flag).
5EF9
If Z FLAG (no special), JUMP to 5F92H.

5EFCH - Special Track Processing Mode

This routine handles special track processing mode for disk copy operations.

5EFC
LD C,00H 0E 00
Load C with 00H (start from track 0).
5EFE
CALL 619DH to initialize track buffer.
5F01
If NZ FLAG (error), JUMP to 5F89H.
5F04
LD (5F1EH),HL 22 1E 5F
Store HL to 5F1EH (self-modifying code location).
5F07
CALL 6190H to reset position.
5F0A
[SCAN LOOP] Check end-of-disk condition.
5F0D
If Z FLAG (end), JUMP to 5F89H.
5F0F
BIT 4,(HL) CB 66
Test bit 4 (processed flag).
5F11
If Z FLAG (not processed), [LOOP] back to 5F0AH.
5F13
CALL 61D6H to get track entry.
5F16
BIT 5,(HL) CB 6E
Test bit 5 of entry.
5F18
If NZ FLAG (skip this), [LOOP] back to 5F0AH.
5F1A
PUSH HL E5
Save position to stack.
5F1B
LD B,05H 06 05
Load B with 05H (loop count).
5F1D
LD HL,0000H 21 00 00
Load HL with 0000H (this location may be modified at 5F1EH).
5F20
PUSH HL E5
Save HL to stack.
5F21
PUSH DE D5
Save DE to stack.
5F22
INC HL 23
[INCREMENT LOOP] Increment HL.
5F23
INC DE 13
Increment DE.
5F24
Decrement B and [LOOP] if not zero.
5F26
LD B,0BH 06 0B
Load B with 0BH (11) - filename length.
5F28
CALL 6254H to compare filenames.
5F2B
POP HL E1
Restore HL from stack.
5F2C
POP DE D1
Restore DE from stack.
5F2D
If Z FLAG (match), JUMP to 5F32H.
5F2F
POP HL E1
Restore position from stack.
5F30
JUMP back to 5F0AH for next entry.

5F32H - Process Matching File Entry

This routine processes a matching file entry found in the destination directory.

5F32
PUSH DE D5
Save DE to stack.
5F33
PUSH BC C5
Save BC to stack.
5F34
LD BC,0003H 01 03 00
Load BC with 0003H (offset to file attributes).
5F37
ADD HL,BC 09
Add offset to HL (point to attributes).
5F38
EX DE,HL EB
Exchange DE and HL.
5F39
ADD HL,BC 09
Add offset to original pointer.
5F3A
LD A,(DE) 1A
Load source attribute byte.
5F3B
LD (HL),A 77
Store to destination attribute.
5F3C
INC HL 23
Advance HL.
5F3D
PUSH AF F5
Save attribute byte.
5F3E
INC DE 13
Advance DE.
5F3F
LD A,(DE) 1A
Load next source byte.
5F40
LD (HL),A 77
Store to destination.
5F41
LD BC,0010H 01 10 00
Load BC with 0010H (offset to granule info).
5F44
ADD HL,BC 09
Add offset to HL.
5F45
EX DE,HL EB
Exchange DE and HL.
5F46
ADD HL,BC 09
Add offset to original pointer.
5F47
LD A,(HL) 7E
Load source granule info.
5F48
LD (DE),A 12
Store to destination.
5F49
INC DE 13
Advance DE.
5F4A
INC HL 23
Advance HL.
5F4B
LD A,(HL) 7E
Load next source byte.
5F4C
LD (DE),A 12
Store to destination.
5F4D
DEC DE 1B
Move DE back.
5F4E
EX DE,HL EB
Exchange DE and HL.
5F4F
POP AF F1
Restore attribute byte from stack.
5F50
CALL 6209H to update directory entry.
5F53
POP BC C1
Restore BC from stack.
5F54
POP DE D1
Restore DE from stack.
5F55
POP HL E1
Restore position from stack.
5F56
SET 5,(HL) CB EE
Set bit 5 of entry marker (completed flag).
5F58
INC HL 23
Advance to track number.
5F59
INC HL 23
Advance past track number.
5F5A
LD (HL),C 71
Store new track value.
5F5B
LD A,C 79
Load track value into A.
5F5C
LD (5B1EH),A 32 1E 5B
Store to 5B1EH (current track variable).
5F5F
CALL 5711H to write directory entry.
5F62
LD A,(4317H) 3A 17 43
Load DOS status from 4317H.
5F65
CP 05H FE 05
Compare with 05H (specific status).
5F67
If NZ FLAG (different status), JUMP to 5608H.
5F6A
INC DE 13
Advance DE to check next byte.
5F6B
LD A,(DE) 1A
Load byte from (DE).
5F6C
BIT 6,A CB 77
Test bit 6 (extended attribute).
5F6E
DEC DE 1B
Move DE back.
5F6F
If NZ FLAG (extended), JUMP to 5F89H.

5F71H - Handle Extended File Attributes

This routine handles files with extended attributes by writing additional directory information.

5F71
LD HL,436BH 21 6B 43
Load HL with address of DOS flag byte at 436BH.
5F74
SET 2,(HL) CB D6
Set bit 2 (enable extended write).
5F76
PUSH HL E5
Save flag address to stack.
5F77
EX DE,HL EB
Exchange DE and HL.
5F78
LD DE,5B17H 11 17 5B
Load DE with address of secondary FCB at 5B17H.
5F7B
CALL 60A9H to write extended data.
5F7E
If NZ FLAG (error), JUMP to 521AH error handler.
5F81
POP HL E1
Restore flag address from stack.
5F82
RES 2,(HL) CB 96
Clear bit 2 (disable extended write).
5F84
LD A,05H 3E 05
Load 05H into A (restore status).
5F86
LD (4317H),A 32 17 43
Store to 4317H (DOS status).

5F89H - Continue Track List Processing

This routine continues processing the track list and loops until all entries are handled.

5F89
LD HL,597DH 21 7D 59
Load HL with address of destination sectors per track.
5F8C
CALL 61BAH to advance sector counter.
5F8F
If NC (more sectors), JUMP back to 5EFEH.

5F92H - Standard Track Processing

This routine handles standard (non-special) track processing for normal COPY operations.

5F92
LD A,(5995H) 3A 95 59
Load additional option flags from 5995H.
5F95
BIT 3,A CB 5F
Test bit 3 (special mode flag).
5F97
RET NZ C0
If NZ FLAG (special mode), RETURN.
5F98
CALL 56F9H to reset FDC parameters.
5F9B
LD DE,6391H 11 91 63
Load DE with address of directory buffer at 6391H.
5F9E
CALL 6172H to set buffer address.
5FA1
CALL 6162H to read disk parameters.
5FA4
CALL 6190H to reset track position.
5FA7
[DIRECTORY LOOP] Check end-of-disk condition.
5FAA
If Z FLAG (end), JUMP to 6092H to finish.
5FAD
BIT 4,(HL) CB 66
Test bit 4 (processed flag).
5FAF
If Z FLAG (not processed), [LOOP] back to 5FA7H.
5FB1
RES 4,(HL) CB A6
Clear bit 4 (processed flag).
5FB3
PUSH HL E5
Save position to stack.
5FB4
BIT 5,(HL) CB 6E
Test bit 5 (completed flag).
5FB6
INC HL 23
Advance past marker byte.
5FB7
If NZ FLAG (completed), JUMP to 6083H.
5FBA
CALL 61EAH to validate entry.
5FBD
If NZ FLAG (invalid), JUMP to 6083H.
5FC0
LD A,(HL) 7E
Load track number from entry.
5FC1
LD C,A 4F
Copy track number to C.
5FC2
LD B,00H 06 00
Clear B for 16-bit offset calculation.
5FC4
AND 1FHAND 00011111 E6 1F
Mask with 1FH to get track number (0-31).
5FC6
LD HL,597DH 21 7D 59
Load HL with address of sectors per track.
5FC9
CP (HL) BE
Compare track number with max sectors.
5FCA
If NC (out of range), JUMP to 6083H.
5FCD
LD HL,6291H 21 91 62
Load HL with address of track table at 6291H.
5FD0
ADD HL,BC 09
Add track number as offset.
5FD1
LD A,(HL) 7E
Load track table entry.
5FD2
OR A B7
Test if entry is used.
5FD3
EX DE,HL EB
Exchange DE and HL.
5FD4
If NZ FLAG (entry used), JUMP to 6083H.

5FD7H - Mark Track Entry and Copy Extent Data

This section executes when an unused track table entry is found. It marks the directory entry as processed, copies the track number into the table, and transfers extent information for file allocation.

5FD7
POP HL E1
Restore HL from stack (points to directory entry marker byte, saved at 5FB3H).
5FD8
SET 5,(HL) CB EE
Set bit 5 (completed flag) in directory entry marker to indicate this entry has been fully processed.
5FDA
PUSH HL E5
Save marker position to stack for later restoration.
5FDB
INC HL 23
Advance past marker byte.
5FDC
INC HL 23
Advance to sector number field in directory entry.
5FDD
LD A,(HL) 7E
Load the original sector number from directory entry.
5FDE
LD (DE),A 12
Store original sector number into track table entry at 6291H+offset (DE points here from 5FD3H).
5FDF
LD A,C 79
Load Register C (contains masked track number 0-31 from 5FC4H) into A.
5FE0
LD (HL),A 77
Store track number into directory entry's sector field (remapping).
5FE1
LD (6028H),A 32 28 60
Self-modifying code: Store track number at 6028H to patch the comparison instruction at 6027H.
5FE4
CALL 56E2H to set up sector buffer address based on track number in A.
5FE7
EX DE,HL EB
Exchange DE and HL. DE now holds directory entry position; HL holds buffer setup result.
5FE8
LD HL,(61D8H) 2A D8 61
Load HL with directory entry pointer from 61D8H (set by 6190H routine).
5FEB
LD BC,0016H 01 16 00
Load BC with 22 bytes (size of file extent record to copy).
5FEE
LDIR ED B0
Block copy 22 bytes from (HL) to (DE), transferring extent allocation data.
5FF0
LD C,(HL) 4E
Load low byte of next extent pointer into C.
5FF1
INC HL 23
Advance to high byte of next extent pointer.
5FF2
LD B,(HL) 46
Load high byte of next extent pointer into B. BC now contains the chain link.
5FF3
PUSH BC C5
Save extent chain pointer to stack.
5FF4
LD B,0AH 06 0A
Load B with 10 (number of granule entries to initialize).
5FF6
LD (6078H),DE ED 53 78 60
Store DE (current buffer position) to 6078H for later reference.

[LOOP START] Initialize 10 granule allocation bytes to FFH (unallocated).

5FFA
LD A,FFH 3E FF
Load A with FFH (unallocated granule marker).
5FFC
LD (DE),A 12
Store FFH to current granule position.
5FFD
INC DE 13
Advance to next granule byte.
5FFE
[LOOP] Decrement B and loop until all 10 granule bytes are initialized.
6000
POP BC C1
Restore extent chain pointer from stack.
6001
CALL 5706H to process the extent chain and build granule allocation map.
6004
POP HL E1
Restore HL (directory entry marker position from 5FDAH).
6005
BIT 6,(HL) CB 76
Test bit 6 (extended attributes flag) in directory entry.
6007
PUSH HL E5
Save marker position to stack again.
6008
If Z FLAG (no extended attributes), JUMP to 6083H to continue loop.

600BH - Process Extended File Attributes

This section handles files with extended attributes (bit 6 set), calculating granule positions for multi-extent files.

600B
LD A,C 79
Load extent chain low byte into A.
600C
CP FEH FE FE
Compare with FEH (end-of-chain marker). If A equals FEH, Z FLAG set.
600E
If NC (A >= FEH, meaning end of chain or invalid), JUMP to 6083H.
6010
LD L,A 6F
Load extent chain low byte into L for address calculation.
6011
LD A,(59BCH) 3A BC 59
Load sectors per granule from 59BCH.
6014
CALL 4C92H (SYS0) to calculate H = L * A (granule to sector conversion).
6017
LD A,B 78
Load extent chain high byte into A.
6018
AND 1FHAND 00011111 E6 1F
Mask with 1FH to extract sector offset (bits 0-4).
601A
LD C,A 4F
Store sector offset in C.
601B
LD A,B 78
Reload extent chain high byte.
601C
RLCA 07
Rotate left (shift bits toward high positions).
601D
RLCA 07
Continue rotating.
601E
RLCA 07
Continue rotating (now bits 5-7 are in positions 0-2).
601F
AND 07HAND 00000111 E6 07
Mask with 07H to extract track bits (originally bits 5-7).
6021
LD E,A 5F
Store track offset in E.
6022
LD D,00H 16 00
Clear D for 16-bit addition.
6024
ADD HL,DE 19
Add track offset to granule position.
6025
LD A,02H 3E 02
Load A with 02H (comparison value).

The following instruction at 6027H is self-modified - the immediate value 00H was patched at 5FE1H with the actual sector number.

6027
CP 00H FE 00
Self-modified: Compare A (02H) with patched sector number. The 00H here was set by code at 5FE1H.
6029
If NZ FLAG (sector mismatch), JUMP to 6030H for normal calculation.
602B
LD HL,0001H 21 01 00
Load HL with 0001H (special case: first sector).
602E
JUMP to 6064H to continue with special case value.

6030H - Calculate Granule Position

This section performs complex calculations to determine the correct granule position within the disk allocation map.

6030
EX DE,HL EB
Exchange DE and HL. DE now holds calculated position.
6031
LD A,(59B7H) 3A B7 59
Load track count from 59B7H.
6034
LD L,A 6F
Store track count in L.
6035
LD A,(59BCH) 3A BC 59
Load sectors per granule from 59BCH.
6038
CALL 4C92H (SYS0) to multiply: H = L * A.
603B
EX DE,HL EB
Exchange back. HL has previous value, DE has multiplication result.
603C
LD A,(59C0H) 3A C0 59
Load granules per lump from 59C0H.
603F
LD B,A 47
Store granules per lump in B for loop counter.
6040
PUSH DE D5
Save multiplication result to stack.

[LOOP START] Increment DE by granules per lump times.

6041
INC DE 13
Increment DE.
6042
[LOOP] Decrement B and loop until granules per lump iterations complete.
6044
OR A B7
Clear carry flag for subtraction.
6045
SBC HL,DE ED 52
Subtract DE from HL (HL = HL - DE).
6047
If Carry (HL < DE, underflow), JUMP to 6053H for alternate path.
6049
POP DE D1
Restore saved multiplication result.
604A
LD A,(59CEH) 3A CE 59
Load extra sectors count from 59CEH.
604D
LD E,A 5F
Store extra sectors in E.
604E
LD D,00H 16 00
Clear D for 16-bit addition.
6050
ADD HL,DE 19
Add extra sectors to HL.
6051
JUMP to 6058H to continue.

6053H - Alternate Granule Calculation Path

This path handles the case where the subtraction resulted in underflow.

6053
ADD HL,DE 19
Add DE back to HL (restore from underflow).
6054
POP DE D1
Restore saved multiplication result from stack.
6055
OR A B7
Clear carry flag.
6056
SBC HL,DE ED 52
Subtract multiplication result from HL.

6058H - Complete Granule Position Calculation

Final steps to calculate the absolute granule position and store it in the allocation map.

6058
EX DE,HL EB
Exchange DE and HL.
6059
LD A,(59C5H) 3A C5 59
Load directory starting lump from 59C5H.
605C
LD L,A 6F
Store starting lump in L.
605D
LD A,(59CAH) 3A CA 59
Load granules per track from 59CAH.
6060
CALL 4C92H (SYS0) to multiply: H = L * A.
6063
ADD HL,DE 19
Add offset in DE to get final granule position.

6064H - Store Granule Allocation Entry

This section stores the calculated granule information into the allocation map and handles overflow conditions.

6064
LD D,C 51
Load sector offset (from 601AH) into D.
6065
LD A,(59CAH) 3A CA 59
Load granules per track from 59CAH.
6068
CALL 4CB4H (SYS0) for division/modulo operation.
606B
INC H 24
Increment H (test for overflow).
606C
DEC H 25
Decrement H back. Z FLAG set if H was 00H (no overflow).
606D
If NZ FLAG (overflow detected), CALL 5240H to handle error condition.
6070
LD B,A 47
Store result in B.
6071
RRCA 0F
Rotate A right (divide by 2).
6072
RRCA 0F
Rotate A right again (divide by 4).
6073
RRCA 0F
Rotate A right again (divide by 8, extracting high bits).
6074
PUSH HL E5
Save granule position to stack.
6075
OR D B2
OR with sector offset in D.
6076
LD H,A 67
Store combined value in H.
6077
LD (0000H),HL 22 00 00
Store HL to address 0000H (likely self-modified or placeholder).
607A
LD HL,6391H 21 91 63
Load HL with address of directory buffer at 6391H.
607D
LD C,D 4A
Copy sector offset from D to C.
607E
POP DE D1
Restore granule position from stack into DE.
607F
INC C 0C
Increment C (adjust offset).
6080
CALL 621CH to write granule entry to allocation map.

6083H - Directory Loop Continuation

This is the common exit point for directory loop iterations. It advances to the next entry and loops back to 5FA7H.

6083
CALL 61D6H to get next directory entry parameters.
6086
POP HL E1
Restore HL (directory entry marker position).
6087
BIT 5,(HL) CB 6E
Test bit 5 (completed flag) in directory entry.
6089
If NZ FLAG (entry completed), JUMP to 608FH.
608B
LD A,H 7C
Load high byte of HL into A.
608C
LD (60C3H),A 32 C3 60
Self-modifying code: Store H at 60C3H to patch instruction at 60C2H.
608F
[LOOP] JUMP back to 5FA7H to process next directory entry.

6092H - Finalize Directory Processing

This routine is called when all directory entries have been processed. It finalizes the track processing and writes allocation data.

6092
CALL 570DH to finalize track processing.
6095
LD HL,6291H 21 91 62
Load HL with address of track allocation table at 6291H.
6098
CALL 616FH to copy 256 bytes from track table to system buffer at 4200H.
609B
PUSH HL E5
Save HL (now points past track table) to stack.
609C
LD A,01H 3E 01
Load A with 01H (sector 1).
609E
CALL 5701H to write sector 1 (GAT - Granule Allocation Table).
60A1
POP HL E1
Restore HL from stack.
60A2
CALL 616FH to copy next 256 bytes (HIT - Hash Index Table).
60A5
XOR A AF
Set A to 00H (sector 0).
60A6
JUMP to 5701H to write sector 0 and return.

60A9H - Write Extended Directory Data

This routine writes extended directory information for files with special attributes. Called from 5F7BH.

60A9
CALL 4980H (SYS0) to initialize FCB operation.
60AC
XOR A AF
Set A to 00H.
60AD
LD (4FDBH),A 32 DB 4F
Store 00H to 4FDBH (FCB status flag).
60B0
PUSH HL E5
Save HL (FCB address) to stack.
60B1
INC L 2C
Increment L (advance in FCB).
60B2
INC L 2C
Increment L again.
60B3
INC L 2C
Increment L again (now at offset +3 in FCB).
60B4
LD A,(HL) 7E
Load byte at FCB+3 (file attribute byte).
60B5
LD DE,0011H 11 11 00
Load DE with offset 17 (0011H).
60B8
ADD HL,DE 19
Add 17 to HL (now at FCB+20).
60B9
LD E,(HL) 5E
Load low byte of extent pointer.
60BA
INC HL 23
Advance to high byte.
60BB
LD D,(HL) 56
Load high byte of extent pointer. DE now has extent address.
60BC
JUMP to 4E3DH to process extended attributes with DE as extent pointer.

60BFH - Source Directory Scan Entry

This routine initiates scanning of the source disk directory for COPY operations.

60BF
CALL 568BH to flush buffers and prepare for directory scan.
60C2
LD A,00H 3E 00
Self-modified: Load A with patched value (set by code at 608CH). Initial value 00H.
60C4
OR A B7
Test if A is zero.
60C5
If Z FLAG (A = 0, scan complete), JUMP to 6157H to finish.
60C8
CALL 5578H to set up source drive.
60CB
CALL 6190H to reset track position from directory pointers.

[DIRECTORY SCAN LOOP] Scan source directory entries.

60CE
CALL 5699H to get next directory entry.
60D1
If Z FLAG (end of directory), JUMP to 60F1H.
60D3
BIT 5,(HL) CB 6E
Test bit 5 (completed flag) in entry.
60D5
If NZ FLAG (already completed), [LOOP] skip to next entry.
60D7
CALL 61D6H to get directory entry parameters.
60DA
If Carry (valid entry found), JUMP to 60E1H.
60DC
CALL 60F5H to process destination directory.
60DF
[LOOP] Jump back to 60C8H to continue scan.

60E1H - Mark and Copy Source Entry

This section marks a source directory entry as processed and copies its extent data.

60E1
PUSH HL E5
Save directory entry pointer to stack.
60E2
SET 4,(HL) CB E6
Set bit 4 (processed flag) in directory entry.
60E4
INC HL 23
Advance past marker byte.
60E5
LD A,(HL) 7E
Load first data byte (track/sector info).
60E6
CALL 56EFH to initialize sector parameters from A.
60E9
LD BC,0016H 01 16 00
Load BC with 22 bytes (extent record size).
60EC
LDIR ED B0
Block copy 22 bytes of extent data from source to destination buffer.
60EE
POP HL E1
Restore directory entry pointer.
60EF
[LOOP] Jump back to 60CEH to continue scanning.

60F1H - End of Source Scan - Switch to Destination

This section handles the end of source directory scan and prepares to process the destination.

60F1
LD HL,6157H 21 57 61
Load HL with address 6157H (completion routine).
60F4
PUSH HL E5
Push return address to stack (will return to 6157H when done).

60F5H - Process Destination Directory

This routine scans the destination directory and allocates entries for files being copied.

60F5
CALL 557DH to set up destination drive (primary setup).
60F8
CALL 6190H to reset track position.

[DESTINATION SCAN LOOP]

60FB
CALL 5699H to get next directory entry.
60FE
RET Z C8
If Z FLAG (end of directory), RETURN.
60FF
BIT 4,(HL) CB 66
Test bit 4 (processed flag).
6101
If Z FLAG (not processed), [LOOP] skip to next entry.
6103
PUSH HL E5
Save directory entry pointer.
6104
RES 4,(HL) CB A6
Clear bit 4 (processed flag).
6106
CALL 61D6H to get directory entry parameters.
6109
INC HL 23
Advance past marker byte.
610A
LD B,(HL) 46
Load track number into B.
610B
INC HL 23
Advance to next field.
610C
PUSH DE D5
Save DE to stack.
610D
PUSH HL E5
Save current position to stack.
610E
CALL 50CFH to allocate directory entry on destination.
6111
If NZ FLAG (allocation error), JUMP to 521AH error handler.
6114
EX DE,HL EB
Exchange DE and HL. HL now has allocated entry address.
6115
POP HL E1
Restore source position into HL.
6116
LD (HL),A 77
Store allocation result byte.
6117
POP HL E1
Restore original HL (now has allocated entry from DE).
6118
PUSH DE D5
Save DE (destination entry address) to stack.
6119
LD BC,0016H 01 16 00
Load BC with 22 bytes.
611C
LDIR ED B0
Block copy 22 bytes of extent data to destination entry.
611E
POP DE D1
Restore destination entry address into DE.
611F
CALL 61FCH to check file attributes.
6122
If Z FLAG (no special attributes), JUMP to 614FH.
6124
BIT 5,A CB 6F
Test bit 5 (system file flag) in attribute byte.
6126
EX DE,HL EB
Exchange DE and HL.
6127
LD DE,0000H 11 00 00
Load DE with 0000H (default load address).
612A
LD BC,4296H 01 96 42
Load BC with 4296H (default entry point address).
612D
If Z FLAG (not system file), JUMP to 613AH with defaults.
612F
LD A,(4044H) 3A 44 40
Load system load address high byte from 4044H.
6132
LD D,A 57
Store in D.
6133
LD A,(4046H) 3A 46 40
Load system entry point high byte from 4046H.
6136
LD E,A 5F
Store in E.
6137
LD BC,5CEFH 01 EF 5C
Load BC with 5CEFH (system file entry point).

613AH - Store File Addresses in Directory Entry

This section stores the load address and entry point in the directory entry for executable files.

613A
INC HL 23
Advance to load address field in directory entry.
613B
LD (HL),E 73
Store low byte of load address.
613C
INC HL 23
Advance to high byte position.
613D
LD (HL),D 72
Store high byte of load address.
613E
INC HL 23
Advance to attribute byte.
613F
LD A,(HL) 7E
Load current attribute byte.
6140
LD DE,000DH 11 0D 00
Load DE with offset 13 to entry point fields.
6143
ADD HL,DE 19
Add offset to reach entry point location.
6144
LD (HL),C 71
Store low byte of entry point.
6145
INC HL 23
Advance to high byte.
6146
LD (HL),B 70
Store high byte of entry point.
6147
INC HL 23
Advance to next field.
6148
LD (HL),C 71
Store low byte again (duplicate for compatibility).
6149
INC HL 23
Advance.
614A
LD (HL),B 70
Store high byte again.
614B
INC HL 23
Advance to next section.
614C
CALL 6209H to finalize directory entry attributes.

614FH - Write Directory Entry and Continue

This section writes the completed directory entry and continues processing.

614F
CALL 5711H to write directory entry to disk.
6152
POP HL E1
Restore directory scan position from stack.
6153
SET 5,(HL) CB EE
Set bit 5 (completed flag) in entry.
6155
[LOOP] Jump back to 60FBH to continue destination scan.

6157H - Complete COPY Operation

This routine marks the COPY operation as complete and returns to the main DOS handler.

6157
LD A,FFH 3E FF
Load A with FFH (completion marker).
6159
LD (5B1EH),A 32 1E 5B
Store FFH to 5B1EH (copy complete flag).
615C
LD (586AH),A 32 6A 58
Store FFH to 586AH (secondary complete flag).
615F
JUMP to 524EH to return to DOS with success.

6162H - Read Disk Parameters

This routine reads disk parameters and sets up the track allocation table buffer.

6162
LD A,01H 3E 01
Load A with 01H (sector 1 - GAT sector).
6164
CALL 56FAH to read sector 1 into buffer.
6167
LD DE,6291H 11 91 62
Load DE with address of track allocation table at 6291H.
616A
CALL 6172H to copy 256 bytes from system buffer to track table.
616D
DEC H 25
Decrement H (adjust buffer pointer).
616E
RET C9
RETURN to caller.

616FH - Copy 256 Bytes to System Buffer

This utility routine copies 256 bytes from HL to the system buffer at 4200H.

616F
LD DE,4200H 11 00 42
Load DE with 4200H (system sector buffer address).

6172H - Block Copy 256 Bytes

General purpose 256-byte block copy routine. Entry: HL=source, DE=destination.

6172
LD BC,0100H 01 00 01
Load BC with 256 (0100H) bytes to copy.
6175
LDIR ED B0
Block copy 256 bytes from (HL) to (DE).
6177
RET C9
RETURN to caller. HL and DE now point past copied data.

6178H - Calculate Directory Sector Parameters

This routine calculates sector parameters based on directory configuration.

6178
CALL 61F6H to check double-density mode flag.
617B
LD A,10H 3E 10
Load A with 16 (10H) - default sectors for single density.
617D
LD C,06H 0E 06
Load C with 6 - default value.
617F
RET NZ C0
If NZ FLAG (single density), RETURN with defaults.
6180
LD E,05H 1E 05
Load E with 5 (sectors per granule for DD).
6182
LD A,(421FH) 3A 1F 42
Load A from 421FH (disk parameter byte).
6185
ADD 08H C6 08
Add 8 to disk parameter.
6187
LD B,A 47
Store result in B.
6188
LD C,00H 0E 00
Initialize C to 0.

[LOOP START] Calculate granule count by repeated subtraction.

618A
INC C 0C
Increment granule counter.
618B
SUB E 93
Subtract sectors per granule from A.
618C
[LOOP] If NC (not underflow), continue counting.
618E
LD A,B 78
Restore original parameter to A.
618F
RET C9
RETURN with A=parameter, C=granule count.

6190H - Reset Track Position from Directory Pointers

This routine initializes the directory scan position from system pointers at 5D12H-5D14H.

6190
LD HL,(5D14H) 2A 14 5D
Load HL with directory entry pointer from 5D14H.
6193
LD (61D8H),HL 22 D8 61
Store to 61D8H (working directory pointer).
6196
LD HL,(5D12H) 2A 12 5D
Load HL with directory buffer end from 5D12H.
6199
DEC HL 2B
Decrement HL (adjust for entry size).
619A
DEC HL 2B
Decrement again.
619B
DEC HL 2B
Decrement again (back up 3 bytes).
619C
RET C9
RETURN with HL pointing to adjusted position.

619DH - Track Table Lookup

This routine looks up a track entry in the allocation table at 6291H and validates it.

619D
LD B,00H 06 00
Clear B for 16-bit index (BC will be the offset).
619F
LD HL,6291H 21 91 62
Load HL with base address of track allocation table at 6291H.
61A2
ADD HL,BC 09
Add offset in BC to get address of specific track entry.
61A3
LD A,(HL) 7E
Load track table entry value into A.
61A4
CP 01H FE 01
Compare with 01H. If A < 1, Carry is set (entry is 00H/unused).
61A6
LD B,A 47
Copy track entry value to B for later use.
61A7
RET C D8
If Carry (entry < 1, meaning unused), RETURN early.
61A8
CALL 61F6H to check double-density mode flag.
61AB
LD A,C 79
Load sector counter from C into A.
61AC
If NZ FLAG (single density mode), JUMP to 61B1H.
61AE
CP 02H FE 02
Compare sector counter with 02H.
61B0
RET C D8
If Carry (sector < 2), RETURN (skip system sectors in DD mode).
61B1
CALL 56E2H to set up sector buffer from track number.
61B4
LD A,(HL) 7E
Load byte from sector buffer.
61B5
AND 90H E6 90
Mask with 90H (bits 7 and 4 - status flags).
61B7
CP 10H FE 10
Compare with 10H. Z FLAG set if only bit 4 is set.
61B9
RET C9
RETURN with Z FLAG indicating status (Z=valid entry).

61BAH - Advance Sector Counter

This routine advances the sector counter and checks if we've reached the end of the track. Returns Carry if track is complete.

61BA
CALL 61F6H to check double-density mode flag.
61BD
LD A,50H 3E 50
Load A with 80 (50H) - sectors per track for single density.
61BF
If NZ FLAG (single density), JUMP to 61C7H with A=50H.
61C1
LD A,C 79
Load current sector counter from C.
61C2
ADD 20H C6 20
Add 32 (20H) to sector counter (double-density increment).
61C4
LD C,A 4F
Store updated counter back to C.
61C5
RET NC D0
If NC (no overflow), RETURN - more sectors to process.
61C6
LD A,(HL) 7E
Load sectors per track from (HL) on overflow.
61C7
DEC A 3D
Decrement sectors per track (convert to max index).
61C8
INC C 0C
Increment sector counter.
61C9
CP C B9
Compare max sector with counter. Carry set if C > A (track complete).
61CA
RET C9
RETURN with Carry indicating track complete status.

61CBH - Granule Boundary Calculation

This routine calculates granule boundaries by repeated subtraction, storing intermediate values.

61CB
CP B B8
Compare A with B (granule count vs limit).
61CC
RET C D8
If Carry (A < B), RETURN - boundary reached.
61CD
LD (HL),2FH 36 2F
Store 2FH (ASCII '/') as delimiter marker at (HL).

[LOOP START] Increment marker and subtract until underflow.

61CF
INC (HL) 34
Increment value at (HL) (converts '/' to '0', then '1', etc.).
61D0
SUB B 90
Subtract B from A.
61D1
[LOOP] If NC (no underflow), continue incrementing.
61D3
ADD A,B 80
Add B back to restore remainder after underflow.
61D4
INC HL 23
Advance to next position.
61D5
RET C9
RETURN with A=remainder, HL=next position.

61D6H - Get Directory Entry Parameters

This routine retrieves directory entry parameters using RST 18H (DOS function call) and calculates the entry pointer.

61D6
PUSH HL E5
Save HL to stack.
61D7
LD HL,0000H 21 00 00
Load HL with 0000H (parameter for RST call).
61DA
LD DE,0000H 11 00 00
Load DE with 0000H (secondary parameter).
61DD
RST 18H DF
Call RST 18H - DOS function dispatcher. Returns directory info.
61DE
PUSH AF F5
Save flags and result to stack.
61DF
EX DE,HL EB
Exchange DE and HL. HL now has result from RST 18H.
61E0
LD HL,0018H 21 18 00
Load HL with 24 (0018H) - size of directory entry.
61E3
ADD HL,DE 19
Add base address from DE to get next entry pointer.
61E4
LD (61D8H),HL 22 D8 61
Store calculated pointer to 61D8H (working directory pointer).
61E7
POP AF F1
Restore flags and result.
61E8
POP HL E1
Restore original HL.
61E9
RET C9
RETURN to caller.

61EAH - Validate Directory Entry

This routine validates a directory entry by checking attribute flags. Returns Z if entry is valid for processing.

61EA
PUSH HL E5
Save HL to stack.
61EB
LD HL,59C7H 21 C7 59
Load HL with address of file attribute mask at 59C7H.
61EE
LD A,(59B9H) 3A B9 59
Load current file attributes from 59B9H.
61F1
OR (HL) B6
OR with attribute mask at (HL).
61F2
POP HL E1
Restore HL.
61F3
AND 20HAND 00100000 E6 20
Mask with 20H (bit 5 - system file flag). Z if not system file.
61F5
RET C9
RETURN with Z FLAG indicating validity (Z=valid for copy).

61F6H - Check Double-Density Mode Flag

This routine checks if the disk is operating in double-density mode by examining bit 5 of the drive configuration byte.

61F6
LD A,(430CH) 3A 0C 43
Load drive configuration byte from 430CH.
61F9
AND 20HAND 00100000 E6 20
Mask with 20H (bit 5 - double-density flag). Z if single density.
61FB
RET C9
RETURN with Z FLAG indicating density (Z=single, NZ=double).

61FCH - Check File Attributes

This routine checks file attributes for special handling requirements during copy operations.

61FC
PUSH HL E5
Save HL to stack.
61FD
LD HL,59C7H 21 C7 59
Load HL with address of file attribute mask at 59C7H.
6200
LD A,(59B9H) 3A B9 59
Load current file attributes from 59B9H.
6203
XOR (HL) AE
XOR with attribute mask (find differences).
6204
AND 20HAND 00100000 E6 20
Mask with 20H (bit 5). Z if attributes match for bit 5.
6206
LD A,(HL) 7E
Load attribute mask value into A.
6207
POP HL E1
Restore HL.
6208
RET C9
RETURN with Z FLAG and A=attribute mask.

6209H - Finalize Directory Entry Attributes

This routine finalizes directory entry attributes, adjusting load/entry addresses based on file type.

6209
OR A B7
Test A (attribute byte). Sets flags based on value.
620A
If NZ (has attributes), CALL 61FCH to check file attributes.
620D
RET Z C8
If Z FLAG (no special handling needed), RETURN.
620E
LD E,(HL) 5E
Load low byte of address field.
620F
INC HL 23
Advance to high byte.
6210
LD D,(HL) 56
Load high byte. DE now has address value.
6211
INC DE 13
Increment address by 1.
6212
BIT 5,A CB 6F
Test bit 5 (system file flag) in attribute byte.
6214
If Z FLAG (not system file), JUMP to 6218H.
6216
DEC DE 1B
Decrement DE (undo increment).
6217
DEC DE 1B
Decrement again (net -1 from original).
6218
LD (HL),D 72
Store adjusted high byte back.
6219
DEC HL 2B
Move back to low byte position.
621A
LD (HL),E 73
Store adjusted low byte.
621B
RET C9
RETURN to caller.

621CH - Write Granule Entry to Allocation Map

This routine writes a granule allocation entry to the GAT (Granule Allocation Table). It sets the appropriate bit in the allocation bitmap.

621C
LD D,00H 16 00
Clear D for 16-bit offset calculation.
621E
ADD HL,DE 19
Add offset E to HL (base address of allocation table).
621F
LD D,80H 16 80
Load D with 80H (bit 7 mask - starting bit position).
6221
LD A,B 78
Load granule bit position from B.
6222
INC B 04
Increment B for loop counter.

[LOOP START] Rotate bit mask to correct position.

6223
RLC D CB 02
Rotate D left (shift bit mask).
6225
[LOOP] Decrement B and loop until bit is in position.
6227
LD B,A 47
Restore original bit position to B.
6228
LD A,(59CAH) 3A CA 59
Load granules per track from 59CAH.
622B
SUB B 90
Subtract bit position from granules per track.
622C
LD B,A 47
Store remaining count in B.
622D
PUSH HL E5
Save current allocation table position.
622E
LD HL,59C6H 21 C6 59
Load HL with address of granule limit at 59C6H.
6231
LD A,E 7B
Load current byte offset into A.
6232
CP (HL) BE
Compare with granule limit.
6233
POP HL E1
Restore allocation table position.
6234
If NC (offset >= limit), JUMP to 6249H error handler.
6236
LD A,(HL) 7E
Load current allocation byte.
6237
AND D A2
AND with bit mask to test if granule already allocated.
6238
If NZ (already allocated), JUMP to 6249H error handler.
623A
LD A,(HL) 7E
Load current allocation byte again.
623B
OR D B2
OR with bit mask to set the granule bit.
623C
LD (HL),A 77
Store updated allocation byte.
623D
DEC C 0D
Decrement granule counter.
623E
RET Z C8
If Z FLAG (all granules processed), RETURN.
623F
RLC D CB 02
Rotate bit mask left for next granule.
6241
[LOOP] Decrement B and loop if more bits in this byte.
6243
LD D,01H 16 01
Reset bit mask to 01H (bit 0) for next byte.
6245
INC HL 23
Advance to next allocation byte.
6246
INC E 1C
Increment byte offset counter.
6247
[LOOP] Jump back to 6228H to continue processing.

6249H - Granule Allocation Error

This routine handles errors during granule allocation (overflow or duplicate allocation).

6249
CALL 5240H to handle allocation error.

624CH - Message Strings and Response Table (DATA)

This section contains ASCII message strings used for COPY command prompts and status messages. The strings are terminated with 03H (ETX).

624C
DEFB 20H,20H 20 20
Two space characters (padding).
624E
DEFB 20H,11H 20 11
Space + 11H (Device Control 1).
6250
DEFB D0H D0
High-bit character (possibly cursor control).
6251
DEFB 42H 42
ASCII B.
6252
DEFB 06H,08H 06 08
Control characters.
6254
DEFB 1AH 1A
1AH (Substitute/EOF marker).
6255
DEFB BEH BE
High-bit character.
6256
DEFB C0H C0
High-bit character.
6257
DEFB 13H 13
13H (XOFF/Device Control 3).
6258
DEFB 23H 23
ASCII #.
6259
DEFB 10H,F9H 10 F9
Control + high-bit character.
625B
DEFB C9H C9
High-bit character (or RET opcode if executed).
625C
DEFM "RQNY" 52 51 4E 59
Response key table: R=Restart, Q=Quit, N=No, Y=Yes.
6260
DEFB 00H 00
NUL terminator for response table.
6261
DEFM " COPY IT? (Y/N/R/Q) " 20 20 20 20 43 4F 50 59 20 49 54 3F 20 20 28 59 2F 4E 2F 52 2F 51 29 20 20
Prompt message for CFWO (Check File With Operator) option.
627A
DEFB 03H 03
ETX (End of Text) - string terminator.
627B
DEFM "COPYING" 43 4F 50 59 49 4E 47
Status message displayed during copy operation.
6282
DEFB 03H 03
ETX - string terminator.
6283
DEFM "ILF/XLF FILE " 49 4C 46 2F 58 4C 46 20 46 49 4C 45 20
Message for Include List File / Exclude List File operations.
6290
DEFB 03H 03
ETX - string terminator.

6291H - Main COPY/FORMAT Processing Entry

This is a major entry point for COPY/FORMAT processing. It checks option flags and sets up file operations. Note: Address 6291H is also used as the base of the track allocation table (256 bytes) - this code executes from a different context.

6291
LD A,(5997H) 3A 97 59
Load option flags byte 4 from 5997H.
6294
AND 30H E6 30
Mask with 30H (bits 4-5: ILF/XLF flags).
6296
LD HL,4200H 21 00 42
Load HL with system sector buffer at 4200H.
6299
LD DE,4480H 11 80 44
Load DE with secondary buffer at 4480H.
629C
If NZ (ILF or XLF active), CALL 4424H (SYS0) to open list file.
629F
If NZ FLAG (open failed), JUMP to 5D67H error handler.
62A2
LD A,(5996H) 3A 96 59
Load option flags byte 3 from 5996H.
62A5
AND 08HAND 00001000 E6 08
Mask with 08H (bit 3: special mode flag).
62A7
LD A,F3H 3E F3
Load A with F3H (default sector read mask).
62A9
If Z FLAG (normal mode), JUMP to 62ADH.
62AB
LD A,E5H 3E E5
Load A with E5H (special mode sector mask - deleted data mark).
62AD
CALL 568DH to initialize sector handling with mask in A.

62B0H - Initialize Source Drive and Check Options

This section initializes the source drive and checks various COPY option flags to determine the operation mode.

62B0
CALL 5578H to set up source drive.
62B3
LD A,(436CH) 3A 6C 43
Load drive status byte from 436CH.
62B6
AND 82H E6 82
Mask with 82H (bits 7 and 1 - density and side flags).
62B8
CP 80H FE 80
Compare with 80H. Z if only bit 7 set (single-sided DD).
62BA
If Z FLAG (single-sided DD), JUMP to 62C3H.
62BC
LD A,(5994H) 3A 94 59
Load option flags byte 1 from 5994H.
62BF
AND 02H E6 02
Mask with 02H (bit 1 - bypass directory update flag).
62C1
If NZ FLAG (BDU option set), JUMP to 632CH.
62C3
CALL 56F9H to reset FDC parameters.
62C6
LD A,(5995H) 3A 95 59
Load option flags byte 2 from 5995H.
62C9
BIT 5,A CB 6F
Test bit 5 (keep destination date flag - KDD).
62CB
If NZ FLAG (KDD set), JUMP to 62D3H - skip date copy.
62CD
LD HL,(42CEH) 2A CE 42
Load source disk date from 42CEH (sector buffer offset).
62D0
LD (5981H),HL 22 81 59
Store to 5981H (destination date buffer).
62D3
LD A,(5994H) 3A 94 59
Load option flags byte 1 from 5994H.
62D6
BIT 2,A CB 57
Test bit 2 (keep destination name flag - KDN).
62D8
If NZ FLAG (KDN set), JUMP to 62E5H - skip name copy.
62DA
LD HL,42D0H 21 D0 42
Load HL with source disk name address at 42D0H.
62DD
LD DE,5983H 11 83 59
Load DE with destination name buffer at 5983H.
62E0
LD BC,0008H 01 08 00
Load BC with 8 (disk name length).
62E3
LDIR ED B0
Block copy 8 bytes (disk name from source to destination buffer).
62E5
LD A,(5995H) 3A 95 59
Load option flags byte 2 from 5995H.
62E8
BIT 4,A CB 67
Test bit 4 (use source date flag - USD).
62EA
If Z FLAG (USD not set), JUMP to 62F7H.
62EC
LD HL,42D8H 21 D8 42
Load HL with source disk date string at 42D8H.
62EF
LD DE,598BH 11 8B 59
Load DE with destination date string buffer at 598BH.
62F2
LD BC,0008H 01 08 00
Load BC with 8 (date string length).
62F5
LDIR ED B0
Block copy 8 bytes (date string from source to destination).
62F7
LD A,(5996H) 3A 96 59
Load option flags byte 3 from 5996H.
62FA
BIT 7,A CB 7F
Test bit 7 (source name check flag - SN option).
62FC
If Z FLAG (SN not set), JUMP to 6314H.
62FE
LD HL,5968H 21 68 59
Load HL with address of expected source name at 5968H.
6301
CALL 624FH to compare source name with expected.
6304
If Z FLAG (names match), JUMP to 632CH to continue.
6306
LD HL,5A3CH 21 3C 5A
Load HL with address of mismatch message buffer at 5A3CH.
6309
CALL 692FH to format mismatch message.
630C
CALL 693BH to display name mismatch prompt.
630F
CALL 58C8H to get operator response (Y/N).
6312
If NZ FLAG (operator said No), [LOOP] back to 62C3H to retry.

6314H - Validate Disk Geometry Match

This section validates that source and destination disk geometries are compatible.

6314
LD A,(436CH) 3A 6C 43
Load drive status byte from 436CH.
6317
AND 82H E6 82
Mask with 82H (density and side flags).
6319
CP 80H FE 80
Compare with 80H.
631B
If NZ FLAG (not single-sided DD), JUMP to 632CH.
631D
LD HL,(42CEH) 2A CE 42
Load source disk parameters from 42CEH.
6320
LD DE,(5978H) ED 5B 78 59
Load destination disk parameters from 5978H.
6324
OR A B7
Clear Carry for subtraction.
6325
SBC HL,DE ED 52
Subtract destination from source parameters.
6327
LD A,37H 3E 37
Load A with error code 37H (geometry mismatch).
6329
If NZ FLAG (parameters don't match), JUMP to 521AH error handler.

632CH - Continue COPY Setup

This section continues COPY setup after option validation, clearing flags and checking for special modes.

632C
LD HL,5996H 21 96 59
Load HL with address of option flags byte 3 at 5996H.
632F
RES 7,(HL) CB BE
Clear bit 7 (source name check flag - no longer needed).
6331
LD A,(5996H) 3A 96 59
Load option flags byte 3 into A.
6334
BIT 3,A CB 5F
Test bit 3 (CBF - Copy By File mode).
6336
If NZ FLAG (CBF mode), JUMP to 5D16H for file-by-file copy.
6339
LD HL,(59D1H) 2A D1 59
Load source track count from 59D1H.
633C
LD DE,(59C3H) ED 5B C3 59
Load destination track count from 59C3H.
6340
RST 18H DF
Call RST 18H - DOS function to compare track counts.
6341
LD A,(5994H) 3A 94 59
Load option flags byte 1 into A.
6344
LD C,A 4F
Copy flags to C for bit testing.
6345
LD HL,(59C1H) 2A C1 59
Load first track allocation value from 59C1H.
6348
If NC (source <= destination), JUMP to 6352H.
634A
BIT 1,C CB 49
Test bit 1 (BDU - Bypass Directory Update flag).
634C
If Z FLAG (BDU not set and source > dest), JUMP to 5204H - disk too small error.
634F
LD HL,(59CFH) 2A CF 59
Load alternate allocation value from 59CFH.
6352
LD (5AF1H),HL 22 F1 5A
Store allocation value to 5AF1H.
6355
NOP 00
No operation (placeholder/alignment).
6356
NOP 00
No operation (placeholder/alignment).
6357
BIT 1,C CB 49
Test bit 1 (BDU flag) again.
6359
If NZ FLAG (BDU set), JUMP to 6365H - skip granule check.
635B
LD HL,59CAH 21 CA 59
Load HL with address of granules per track at 59CAH.
635E
LD A,(59BCH) 3A BC 59
Load sectors per granule from 59BCH.
6361
CP (HL) BE
Compare with granules per track.
6362
If NZ FLAG (granule size mismatch), JUMP to 5204H error.
6365
CALL 674DH to initialize track buffers.
6368
CALL 67C3H to set up copy parameters.
636B
LD HL,0000H 21 00 00
Load HL with 0000H.
636E
LD (5AEFH),HL 22 EF 5A
Store 0000H to 5AEFH (sector counter).
6371
LD (5B21H),HL 22 21 5B
Store 0000H to 5B21H (track counter).
6374
JUMP to 5273H to begin main copy loop.

6377H - Two-Drive Copy Initialization

This routine initializes parameters for copying between two different drives.

6377
LD BC,594CH 01 4C 59
Load BC with address of source drive number at 594CH.
637A
LD DE,5AE5H 11 E5 5A
Load DE with address of source filespec buffer at 5AE5H.
637D
CALL 6437H to set up source drive parameters.
6380
LD BC,5956H 01 56 59
Load BC with address of destination drive number at 5956H.
6383
LD DE,5B17H 11 17 5B
Load DE with address of destination filespec buffer at 5B17H.
6386
CALL 6437H to set up destination drive parameters.
6389
CALL 5C96H to initialize sector size parameters.
638C
CALL 568BH to flush buffers.
638F
JUMP to 5279H to continue copy operation.

6392H - Parse Destination Drive Number

This routine parses and validates the destination drive number from the command line.

6392
CALL 6ECBH to skip whitespace and get next character.
6395
RET NC D0
If NC (no valid drive number found), RETURN.
6396
LD (5B1DH),A 32 1D 5B
Store drive number to 5B1DH.
6399
LD (5956H),A 32 56 59
Store to destination drive number at 5956H.
639C
LD (4DFAH),A 32 FA 4D
Store to 4DFAH (self-modifying code location).
639F
RET C9
RETURN to caller.

63A0H - Parse Track Count Parameter

This routine parses track count parameter from command line (e.g., "=40" or "=80").

63A0
LD DE,64A9H 11 A9 64
Load DE with address of track count storage at 64A9H.
63A3
LD A,(HL) 7E
Load current character from command line.
63A4
CP 3DH FE 3D
Compare with = (3DH) character.
63A6
RET NZ C0
If NZ FLAG (not '='), RETURN - no track count specified.
63A7
PUSH DE D5
Save storage address to stack.
63A8
INC HL 23
Advance past '=' character.
63A9
CALL 6EE7H to parse decimal number.
63AC
POP DE D1
Restore storage address.
63AD
OR A B7
Test if parsed number is zero.
63AE
LD (DE),A 12
Store track count to (DE).
63AF
RET NZ C0
If NZ FLAG (valid non-zero count), RETURN.
63B0
JUMP to 5218H - invalid parameter error.

63B3H - Flush Drives and Initialize Parameters

This routine flushes both source and destination drives and loads disk parameters into working storage.

63B3
LD B,03H 06 03
Load B with 03H (flush mode for all drives).
63B5
CALL 5646H to flush all drive buffers.
63B8
LD B,02H 06 02
Load B with 02H (flush destination only).
63BA
LD HL,593BH 21 3B 59
Load HL with address of drive status flags at 593BH.
63BD
SET 7,(HL) CB FE
Set bit 7 (drive needs flush flag).
63BF
CALL 5646H to flush destination drive.
63C2
LD BC,(594CH) ED 4B 4C 59
Load BC with source drive number from 594CH (B=high, C=low).
63C6
LD HL,59B7H 21 B7 59
Load HL with address of source parameters buffer at 59B7H.
63C9
LD A,FFH 3E FF
Load A with FFH (default/all tracks).
63CB
CALL 63ECH to load source drive parameters.
63CE
LD BC,(5956H) ED 4B 56 59
Load BC with destination drive number from 5956H.
63D2
LD HL,59C5H 21 C5 59
Load HL with address of destination parameters buffer at 59C5H.
63D5
LD A,FFH 3E FF
Load A with FFH.
63D7
CALL 63ECH to load destination drive parameters.
63DA
LD HL,64A3H 21 A3 64
Load HL with address of parameter override table at 64A3H.
63DD
LD C,(HL) 4E
Load count of override entries into C.
63DE
INC HL 23
Advance to first entry's address low byte.

[LOOP START] Apply parameter overrides from table.

63DF
LD E,(HL) 5E
Load low byte of target address.
63E0
INC HL 23
Advance to high byte.
63E1
LD D,(HL) 56
Load high byte. DE now has target address.
63E2
INC HL 23
Advance to override value.
63E3
LD A,(HL) 7E
Load override value.
63E4
OR A B7
Test if value is zero (skip marker).
63E5
If Z FLAG (zero = skip), JUMP to 63E8H.
63E7
LD (DE),A 12
Store override value to target address.
63E8
DEC C 0D
Decrement entry counter.
63E9
[LOOP] If NZ (more entries), continue loop.
63EB
RET C9
RETURN to caller.

63ECH - Load Drive Parameters

This routine loads drive parameters from PDRIVE table into working storage. Entry: A=track count (FFH=use default), BC=drive info, HL=destination buffer.

63EC
CP FFH FE FF
Compare A with FFH (default marker).
63EE
RET Z C8
If Z FLAG (use default), RETURN without changes.
63EF
RLCA 07
Rotate A left (multiply by 2).
63F0
RLCA 07
Rotate again (multiply by 4).
63F1
RLCA 07
Rotate again (multiply by 8).
63F2
RLCA 07
Rotate again (multiply by 16 - PDRIVE entry size offset).
63F3
PUSH HL E5
Save destination buffer address.
63F4
LD HL,5940H 21 40 59
Load HL with drive flags buffer at 5940H.
63F7
PUSH AF F5
Save calculated offset.
63F8
LD A,C 79
Load drive number low byte into A.
63F9
OR A B7
Test if drive number is zero (source drive).
63FA
If NZ FLAG (not source), JUMP to 6406H.
63FC
DEC A 3D
Decrement A (now FFH).
63FD
XOR B A8
XOR with B (drive number high byte).
63FE
INC HL 23
Advance to second flag byte at 5941H.
63FF
AND (HL) A6
AND with flag byte to mask relevant bits.
6400
LD (HL),A 77
Store masked result back to flag byte.
6401
DEC HL 2B
Move back to first flag byte at 5940H.
6402
INC B 04
Increment B (drive number high byte).
6403
LD A,(HL) 7E
Load first flag byte.
6404
OR B B0
OR with incremented drive number.
6405
LD (HL),A 77
Store updated flag byte.
6406
LD A,(5956H) 3A 56 59
Load destination drive number from 5956H.
6409
LD B,A 47
Copy to B for comparison.
640A
LD A,(594CH) 3A 4C 59
Load source drive number from 594CH.
640D
CP B B8
Compare source with destination drive.
640E
If NZ FLAG (different drives), JUMP to 6417H.

Same drive for source and destination - set single-drive copy mode flags.

6410
LD A,(HL) 7E
Load flag byte.
6411
OR 06H F6 06
OR with 06H (bits 1-2: single-drive copy mode flags).
6413
LD (HL),A 77
Store updated flags.
6414
INC HL 23
Advance to second flag byte.
6415
LD (HL),01H 36 01
Store 01H (single-drive indicator).
6417
CALL 6424H to read PDRIVE table from disk.
641A
POP AF F1
Restore calculated offset into A.
641B
ADD A,L 85
Add offset to L (pointing into PDRIVE table).
641C
LD L,A 6F
Store result back to L. HL now points to specific PDRIVE entry.
641D
POP DE D1
Restore destination buffer address into DE.
641E
LD BC,000AH 01 0A 00
Load BC with 10 (PDRIVE entry size to copy).
6421
LDIR ED B0
Block copy 10 bytes from PDRIVE entry to destination buffer.
6423
RET C9
RETURN to caller.

6424H - Read PDRIVE Table from Disk

Reads the PDRIVE configuration sector (sector 2) from disk into the system buffer at 4200H. Called from 6417H during drive parameter initialization.

6424
LD HL,0002H 21 02 00
Load HL with 2 (PDRIVE sector number).
6427
LD (5B53H),HL 22 53 5B
Store sector number at 5B53H (sector parameter).
642A
LD HL,4200H 21 00 42
Load HL with 4200H (system buffer address).
642D
LD DE,5B49H 11 49 5B
Load DE with 5B49H (FCB address for sector read).
6430
CALL 4436H CD 36 44
CALL 4436H (SYS0) to read sector into buffer.
6433
RET Z C8
If Z FLAG (read successful), RETURN.
6434
JUMP to 521AH error handler on read failure.

6437H - Parse Drive Specification

Parses drive specification from command line. Handles "d:" format for drive numbers 0-5. Entry: DE=command line pointer, HL=5940H (drive flags), BC=parameter storage. Returns drive number or handles filespec parsing.

6437
LD HL,5940H 21 40 59
Load HL with 5940H (drive flags buffer).
643A
LD A,(DE) 1A
Load character from command line.
643B
CP 3AH FE 3A
Compare with ':' (colon - drive separator).
643D
INC DE 13
Advance command line pointer.
643E
If NZ FLAG (not colon), JUMP to 6458H check for ETX.
6440
LD A,(HL) 7E
Load current drive count from flags.
6441
CP 06H FE 06
Compare with 6 (max drive number + 1).
6443
If NC FLAG (6 or more drives), JUMP to 6482H error.
6445
PUSH HL E5
Save drive flags pointer.
6446
PUSH BC C5
Save parameter storage pointer.
6447
EX DE,HL EB
HL = command line pointer.
6448
CALL 6ED7H to parse drive number from command line.
644B
POP BC C1
Restore parameter storage pointer.
644C
POP HL E1
Restore drive flags pointer.
644D
OR A B7
Test if parse succeeded (A=0 on success).
644E
LD (BC),A 02
Store result at (BC).
644F
RET NZ C0
If NZ FLAG (parse failed), RETURN with error.
6450
INC BC 03
Advance to next parameter byte.
6451
LD A,(BC) 0A
Load next parameter byte.
6452
BIT 0,(HL) CB 46
Test bit 0 of drive flags.
6454
RET Z C8
If Z FLAG (bit clear), RETURN.
6455
OR (HL) B6
OR parameter with drive flags.
6456
LD (HL),A 77
Store updated flags.
6457
RET C9
RETURN to caller.

Handle end-of-text (03H) - generate drive spec from drive count.

6458
CP 03H FE 03
Compare with 03H (ETX - end of text).
645A
If NZ FLAG (not ETX), JUMP back to 643AH continue scan.
645C
LD A,(HL) 7E
Load drive count from flags.
645D
CP 06H FE 06
Compare with 6 (max drives).
645F
If C FLAG (less than 6), JUMP to 6474H check ILF/XLF.
6461
LD A,(BC) 0A
Load parameter byte.
6462
OR A B7
Test if zero.
6463
INC BC 03
Advance parameter pointer.
6464
If NZ FLAG (non-zero), JUMP to 6468H.
6466
SET 0,(HL) CB C6
Set bit 0 of drive flags (single drive mode).
6468
ADD 30H C6 30
Add 30H ('0') to convert to ASCII digit.
646A
LD (DE),A 12
Store ASCII drive number in command buffer.
646B
DEC DE 1B
Move back in buffer.
646C
EX DE,HL EB
HL = buffer pointer.
646D
LD (HL),3AH 36 3A
Store ':' (colon) before drive number.
646F
INC HL 23
Advance pointer.
6470
INC HL 23
Advance pointer (past drive digit).
6471
LD (HL),03H 36 03
Store 03H (ETX) to terminate.
6473
RET C9
RETURN to caller.

Check if ILF/XLF options allow filespec parsing.

6474
BIT 0,A CB 47
Test bit 0 of drive count.
6476
If NZ FLAG (odd), JUMP to 6482H error.
6478
LD A,(5997H) 3A 97 59
Load option flags from 5997H.
647B
AND C0H E6 C0
Mask bits 6-7 (ILF/XLF flags).
647D
LD H,B 60
Copy BC to HL.
647E
LD L,C 69
HL = BC (parameter pointer).
647F
If Z FLAG (no ILF/XLF), JUMP to 5538H setup drive.
6482
JUMP to 5200H error handler (bad parameter).

64A3H - Override Parameter Table (DATA)

Table of parameter override addresses used during COPY/FORMAT operations. Each entry is 3 bytes: count + address. Referenced by 63DDH during parameter override processing.

64A3
DEFB 04H 04
Count: 4 entries for first override.
64A4
DEFW 59BAH BA 59
Address: 59BAH (source parameter area).
64A6
DEFB 00H 00
Terminator/padding.
64A7
DEFW 59C8H C8 59
Address: 59C8H (destination parameter area).
64A9
DEFB 00H 00
Terminator/padding.
64AA
DEFW 59CDH CD 59
Address: 59CDH (track count storage).
64AC
DEFW 59CEH CE 59
Address: 59CEH (sector count storage).
64AE
DEFB 00H 00
End of table marker.

64B0H - Clear System Buffer

Clears 256 bytes of the system buffer at 4200H by writing the value in A. Uses DJNZ loop with B=0 (256 iterations).

64B0
LD HL,4200H 21 00 42
Load HL with 4200H (system buffer).
64B3
LD B,00H 06 00
Load B with 0 (256 iterations via wraparound).
64B5
LD (HL),A 77
Store A at buffer location.
64B6
INC HL 23
Advance buffer pointer.
64B7
Decrement B, JUMP to 64B5H if not zero.
64B9
RET C9
RETURN to caller.

64BAH - Boot Sector Loader Entry

This is the bootstrap loader code that gets written to the boot sector during FORMAT. It loads the system from disk into memory. The code runs at low memory addresses after being loaded by the ROM bootstrap. Contains FDC (Floppy Disk Controller) programming sequences.

64BA
DEFB 00H 00
NOP placeholder (adjusted during FORMAT).
64BB
CP 11H FE 11
Compare A with 11H (check for Model I/III).
64BD
DI F3
Disable interrupts during disk I/O.
64BE
LD HL,37ECH 21 EC 37
Load HL with 37ECH (FDC command register).
64C1
LD (HL),FEH 36 FE
Write FEH to FDC (drive select).
WD 1771 FDC Command Code: FEH (11111110)
Bit 7Bit 6Bit 5Bit 4Bit 3Bit 2Bit 1Bit 0Function/Parameters
11110100Command=Write Track (Format)
Bit 7-4: Write Command (1111)
Bit 3-0: Specific Code (0100)

On its own, this would be an invalid command to send to the stock FDC. HOWEVER, as Blair Robbins has pointed out, this is a perfectly valid command to a Percom Doubler, and it sets the doubler to use the 1771 single density chip instead of the 1791 double density chip.
64C3
LD (HL),D0H 36 D0
Write D0H to FDC (force interrupt/reset).
WD 1771 FDC Command Code: D0H (11010000)
Bit 7Bit 6Bit 5Bit 4I3I2I1I0Function/Parameters
11010000Command=Force Interrupt
Bit 7-4: Command Code (1101)
I3: 1=Interrupt Immediately
I2: 1=Interrupt on the next Index Pulse
I1: 1=Interrupt the next time Ready goes to Not Ready
I0: 1=Interrupt the next time Not Ready goes to Ready
64C5
INC HL 23
Advance to next FDC register which is the FDC Track Register.
64C6
LD (HL),00H 36 00
Write 00H (track 0).
64C8
INC HL 23
Advance to the next FDC register which is the FDC sector register.
64C9
LD (HL),80H 36 80
Write 80H (sector/data mark).
64CB
LD DE,0005H 11 05 00
Load DE with 5 (sector count).
64CE
EXX D9
Switch to alternate registers.
64CF
LD SP,41E0H 31 E0 41
Set stack to 41E0H (safe area during load).
64D2
LD HL,51FFH 21 FF 51
Load HL with 51FFH (load address - 1).
64D5
CALL 4252H CD 52 42
CALL 4252H (ROM: read byte from FDC).
64D8
CP 20H FE 20
Compare with 20H (space - end marker?).
64DA
LD B,A 47
Save byte in B.
64DB
If NC FLAG (>= 20H), JUMP to 6506H error.
64DD
LD D,A 57
D = block type/count.
64DE
CALL 4252H CD 52 42
CALL 4252H read next byte (count low).
64E1
LD C,A 4F
C = count low byte.
64E2
CALL 4252H CD 52 42
CALL 4252H read next byte (address low).
64E5
LD E,A 5F
E = address low byte.
64E6
Decrement B, if not zero JUMP to 64FAH.
64E8
CALL 4252H CD 52 42
CALL 4252H read address high byte.
64EB
LD D,A 57
D = address high byte.
64EC
DEC C 0D
Decrement count.
64ED
DEC C 0D
Decrement count again.
64EE
INC L 2C
Increment L (source pointer low).
64EF
CALL Z,4255H CC 55 42
If Z FLAG (L wrapped), CALL 4255H handle page cross.
64F2
LD A,(HL) 7E
Load byte from source buffer.
64F3
LD (DE),A 12
Store to destination address.
64F4
INC DE 13
Advance destination pointer.
64F5
DEC C 0D
Decrement byte count.
64F6
If NZ FLAG (more bytes), JUMP to 64EEH.
64F8
JUMP to 64D5H for next block.
64FA
Decrement B, if not zero JUMP to 64F5H.
64FC
CALL 4252H CD 52 42
CALL 4252H read next header byte.
64FF
LD D,A 57
D = header byte.
6500
LD A,(DE) 1A
Load byte at address in DE.
6501
CP A5H FE A5
Compare with A5H (signature byte).
6503
INC DE 13
Advance pointer.
6504
PUSH DE D5
Push entry address.
6505
RET Z C8
If Z FLAG (signature matched), RETURN to system entry.
6506
LD HL,42E5H 21 E5 42
Load HL with 42E5H (error message address).
6509
JP 42C3H C3 C3 42
JUMP to 42C3H (ROM: display error and halt).

650CH - FDC Sector Read Subroutine (Boot Loader Helper)

This subroutine is called during the boot process to read sectors from the floppy disk. It handles buffer pointer management and interfaces with the WD1771 FDC (Floppy Disk Controller). The addresses 37E1H, 37ECH, 37EEH, and 37EFH are the FDC hardware registers. This code runs from the boot sector after being loaded into memory.

650C
INC L 2C
Increment the low byte of HL (buffer pointer). This advances through the sector buffer one byte at a time.
650D
LD A,(HL) 7E
Load the byte at the current buffer position into Register A.
650E
RET NZ C0
If the byte is non-zero (NZ FLAG set), RETURN to caller with the byte in A. A zero byte indicates end-of-buffer or special marker.
650F
EXX D9
Switch to alternate register set (BC', DE', HL'). The primary registers are preserved while the FDC operation proceeds.
6510
LD B,0AH 06 0A
Load B with 10 (0AH). This is the retry counter for FDC read operations.

[RETRY LOOP START] - The following code attempts to read a sector from the FDC, retrying up to 10 times on failure.

6512
LD HL,37E1H 21 E1 37
Load HL with 37E1H (FDC Drive Select Latch). This register controls which drive is selected and motor status.
6515
LD (HL),01H 36 01
Write 01H to the drive select latch, selecting Drive 0 with motor on.
6517
PUSH DE D5
Save DE (contains sector address) to the stack.
6518
PUSH BC C5
Save BC (B = retry counter) to the stack.
6519
LD A,E 7B
Load A with E (sector number component).
651A
SUB 00H D6 00
Subtract 00H from A. This is a self-modifying code target - the operand at 651BH is patched at runtime to hold the sectors-per-track value for sector number calculation.
651C
If Carry FLAG set (sector number < sectors-per-track), JUMP to 6521H to continue without adjustment.
651E
LD E,A 5F
Store adjusted sector number back into E.
651F
LD (HL),09H 36 09
Write 09H to drive select (37E1H), selecting Drive 0 with side 1 (for double-sided disks).
6521
LD HL,37ECH 21 EC 37
Load HL with 37ECH (FDC Command/Status Register).
6524
CALL 42CEH - ROM routine to wait for FDC ready and handle timing.
6527
LD (37EEH),DE ED 53 EE 37
Write DE to 37EEH (FDC Sector Register). D = track number, E = sector number.
652B
LD (HL),1BH 36 1B
Write 1BH to FDC Command Register - this is a SEEK command with verify.
WD 1771 FDC Command Code: 1BH (00011011)Function Description
Bit 7Bit 6Bit 5Bit 4Bit 3Bit 2Bit 1Bit 0Summary of Bits
00011011Command=Seek
Bit 7-4: Command Code (0001)
h=1: Enable Head Load/Settle delay
V=0: No verification
r1,r0=11: Stepping Motor Rate = 15ms
652D
CALL 42CEH - Wait for SEEK command to complete.
6530
LD (HL),88H 36 88
Write 88H to FDC Command Register - READ SECTOR command.
WD 1771 FDC Command Code: 88H (10001000)Function Description
Bit 7Bit 6Bit 5Bit 4Bit 3Bit 2Bit 1Bit 0Summary of Bits
10001000Command=Read Sector
Bit 7-5: Read Command (100)
m=0: Single Record
b=1: IBM format
E=0: Assume Head Already Engaged, no Delay
Remainder: Unused (00)
6532
LD DE,37EFH 11 EF 37
Load DE with 37EFH (FDC Data Register address).
6535
LD BC,5100H 01 00 51
Load BC with 5100H. B = 51H (81 decimal) is the buffer page high byte, C = 00H is the buffer offset. This sets up the destination for sector data.
6538
CALL 42D7H - ROM routine to wait for FDC DRQ (Data Request) signal.
653B
LD A,(HL) 7E
Load A with FDC Status Register value (HL still points to 37ECH).
76543210
Not
Ready
ProtectedHead
Loaded
Seek
Error
CRC
Error
Track 00IndexBusy
653C
AND 83H E6 83
Mask with 83H to isolate BUSY (bit 0), DRQ (bit 1), and NOT READY (bit 7) status bits.
653E
If Parity Odd (odd number of bits set in result), JUMP to 4281H - ROM error handler. This detects abnormal FDC states.

[DATA TRANSFER LOOP] - Read bytes from FDC data register as they become available.

6541
LD A,(DE) 1A
Load A with byte from FDC Data Register (37EFH).
6542
LD (BC),A 02
Store the byte to the sector buffer at address in BC.
6543
INC BC 03
Increment buffer pointer BC.
6544
BIT 1,(HL) CB 4E
Test bit 1 of FDC Status (DRQ - Data Request). If set, more data is available.
6546
If NZ FLAG (DRQ active), JUMP to 4287H - ROM routine to handle rapid data transfer.
6549
BIT 1,(HL) CB 4E
Test DRQ bit again (timing window check).
654B
If NZ FLAG (DRQ still active), JUMP to 4287H.
654E
BIT 1,(HL) CB 4E
Test DRQ bit a third time.
6550
If NZ FLAG (DRQ active), JUMP back to 6541H to read next byte.
6552
BIT 0,(HL) CB 46
Test bit 0 of FDC Status (BUSY). If clear, operation is complete.
6554
If Z FLAG (not busy), JUMP to 655EH to complete the read.
6556
BIT 1,(HL) CB 4E
Test DRQ bit again while still busy.
6558
If NZ FLAG (DRQ active), JUMP to 6541H to read byte.
655A
BIT 7,(HL) CB 7E
Test bit 7 of FDC Status (NOT READY). If set, drive is not ready.
655C
If Z FLAG (drive is ready), JUMP back to 6544H to continue polling.

[READ COMPLETE] - Sector read finished. Check for errors and update pointers.

655E
LD A,(HL) 7E
Load A with final FDC Status value.
655F
LD (HL),D0H 36 D0
Write D0H to FDC Command Register - FORCE INTERRUPT to terminate any pending operation.
WD 1771 FDC Command Code: D0H (11010000)Function Description
Bit 7Bit 6Bit 5Bit 4I3I2I1I0Summary of Bits
11010000Command=Force Interrupt
Bit 7-4: Command Code (1101)
I3=0: No immediate interrupt
I2=0: No interrupt on Index Pulse
I1=0: No interrupt on Ready change
I0=0: No interrupt on Not Ready change
6561
POP BC C1
Restore BC (B = retry counter) from stack.
6562
POP DE D1
Restore DE (sector address) from stack.
6563
AND FCH E6 FC
Mask status with FCH to isolate error bits (CRC error, seek error, lost data, etc.). Bits 0-1 (BUSY, DRQ) are cleared.
6565
If NZ FLAG (error occurred), JUMP to 6573H for error recovery/retry.
6567
INC E 1C
Increment sector number in E for next sector.
6568
LD A,E 7B
Load A with new sector number.
6569
SUB 00H D6 00
Subtract sectors-per-track value. Self-modifying code target at 656AH - operand is patched at runtime.
656B
If NZ FLAG (not at track boundary), JUMP to 6570H to continue.
656D
INC D 14
Increment track number in D (crossed to next track).
656E
LD E,00H 1E 00
Reset sector number to 0 for new track. Self-modifying code target at 656FH - may be patched to 01H for 1-based sector numbering.
6570
EXX D9
Switch back to primary register set.
6571
LD A,(HL) 7E
Load next byte from sector buffer (HL was preserved in primary set).
6572
RET C9
RETURN to caller with data byte in A.

6573H - FDC Error Recovery and Retry

This section handles FDC read errors. It sends a RESTORE command to recalibrate the head to track 0, then retries the operation. If all retries fail, it enters a fatal error display loop.

6573
CALL 42D7H - ROM routine to wait for FDC ready.
6576
LD (HL),0BH 36 0B
Write 0BH to FDC Command Register - RESTORE command to seek to track 0.
WD 1771 FDC Command Code: 0BH (00001011)Function Description
Bit 7Bit 6Bit 5Bit 4Bit 3Bit 2Bit 1Bit 0Summary of Bits
00001011Command=Restore
Bit 7-4: Command Code (0000)
h=1: Enable Head Load/Settle delay
V=0: No verification of Track 0 ID
r1,r0=11: Stepping Motor Rate = 15ms
6578
Decrement B (retry counter). If NZ FLAG (retries remaining), JUMP to 6512H to retry the read.

[FATAL ERROR] - All retries exhausted. Display error message and halt.

657A
LD HL,42DDH 21 DD 42
Load HL with 42DDH - pointer to video display routine or error message table in ROM.
657D
LD A,(HL) 7E
[DISPLAY LOOP] Load character from message.
657E
CP 03H FE 03
Compare with 03H (ETX - End of Text marker).
6580
If Z FLAG (end of message), JUMP to 657DH - infinite loop (halt with message displayed).
6582
INC HL 23
Advance to next character in message.
6583
CALL 0033H - ROM routine to display character in A on screen.
6586
JUMP to 657DH to continue displaying message.

6588H - Wait for FDC Not Busy

This short subroutine waits for the FDC to finish any pending operation by polling the BUSY bit (bit 0) of the status register.

6588
CALL 42D7H - ROM routine for FDC timing/wait.
658B
BIT 0,(HL) CB 46
[BUSY WAIT LOOP] Test bit 0 of FDC Status Register (BUSY flag).
658D
If NZ FLAG (still busy), JUMP to 658BH to keep waiting.
658F
LD A,(HL) 7E
Load A with final FDC Status value.
6590
RET C9
RETURN to caller with status in A.

6591H - Short Delay Loop

A simple timing delay loop that counts down from 6 to 0. Used to provide brief delays for FDC timing requirements.

6591
LD A,06H 3E 06
Load A with 6 as the delay counter.
6593
DEC A 3D
[DELAY LOOP] Decrement the counter.
6594
If NZ FLAG (counter not zero), JUMP to 6593H to continue delay.
6596
RET C9
RETURN to caller.

6597H - Boot Error Message Strings

This section contains the error message strings displayed during boot failures. The strings are prefixed with cursor positioning codes (1CH = cursor home, 1FH = cursor down) and terminated with 03H (ETX - End of Text).

6597
DEFB 1CH 1C
Cursor control: HOME (move cursor to top-left).
6598
DEFB 1FH 1F
Cursor control: CURSOR DOWN.
6599
DEFB 'E' 45
ASCII character E.
659A
DEFB 'R' 52
ASCII character R.
659B
DEFB 'R' 52
ASCII character R.
659C
DEFB 'O' 4F
ASCII character O.
659D
DEFB 'R' 52
ASCII character R.
659E
DEFB 03H 03
ETX (End of Text) - string terminator. Complete string: "ERROR"
659F
DEFB 1CH 1C
Cursor control: HOME.
65A0
DEFB 1FH 1F
Cursor control: CURSOR DOWN.
65A1
DEFB 'N' 4E
ASCII character N.
65A2
DEFB 'O' 4F
ASCII character O.
65A3
DEFB ' ' 20
ASCII character SPACE.
65A4
DEFB 'S' 53
ASCII character S.
65A5
DEFB 'Y' 59
ASCII character Y.
65A6
DEFB 'S' 53
ASCII character S.
65A7
DEFB 03H 03
ETX (End of Text) - string terminator. Complete string: "NO SYS"

65B0H - Boot Sector FCB Template: BOOT/SYS

This is an FCB (File Control Block) template for the BOOT/SYS file. During FORMAT, this data is copied and modified to create the directory entry for the boot system file. The FCB structure follows the standard NEWDOS/80 directory entry format.

65B0
DEFB 00H 00
FCB attribute/status byte (00H = normal file).
65B1
DEFB 00H 00
Reserved byte.
65B2
DEFB 00H 00
Reserved byte.
65B3
DEFB 00H 00
Reserved byte.
65B4
DEFB 00H 00
Reserved byte.
65B5
DEFB 00H 00
Reserved byte.
65B6
DEFB 00H 00
Reserved byte.
65B7
DEFB 00H 00
Sectors per track - patched at runtime based on disk format.
65B8
DEFB 00H 00
Disk density flag - patched at runtime.
65B9
DEFB 00H 00
Disk configuration byte - patched at runtime.
65BA
DEFB 5EH 5E
GAT (Granule Allocation Table) pointer or file attribute.
65BB
DEFB 00H 00
Reserved byte.
65BC
DEFB 00H 00
Reserved byte.
65BD
DEFB 00H 00
Reserved byte.
65BE
DEFB 00H 00
Reserved byte.
65BF
DEFB 'B' 42
Filename character 1: B
65C0
DEFB 'O' 4F
Filename character 2: O
65C1
DEFB 'O' 4F
Filename character 3: O
65C2
DEFB 'T' 54
Filename character 4: T
65C3
DEFB ' ' 20
Filename character 5: SPACE
65C4
DEFB ' ' 20
Filename character 6: SPACE
65C5
DEFB ' ' 20
Filename character 7: SPACE
65C6
DEFB ' ' 20
Filename character 8: SPACE
65C7
DEFB 'S' 53
Extension character 1: S
65C8
DEFB 'Y' 59
Extension character 2: Y
65C9
DEFB 'S' 53
Extension character 3: S. Complete filename: BOOT /SYS
65CA
DEFB 60H 60
File attributes byte (60H = system file, invisible).
65CB
DEFB 7FH 7F
EOF offset within last sector.
65CC
DEFB 1FH 1F
Logical record length or flag byte.
65CD
DEFB B2H B2
Extent/allocation information.
65CE
DEFB 05H 05
Extent/allocation information.
65CF
DEFB 00H 00
Reserved byte.

65D0H - Boot Sector Padding

Padding bytes and filler data in the boot sector template area.

65D0
DEFB 00H 00
Padding byte.
65D1
DEFB 00H 00
Padding byte.
65D2
DEFB FFH FF
Filler byte (FFH).
65D3
DEFB FFH FF
Filler byte (FFH).
65D4
DEFB FFH FF
Filler byte (FFH).
65D5
DEFB FFH FF
Filler byte (FFH).
65D6
DEFB FFH FF
Filler byte (FFH).
65D7
DEFB FFH FF
Filler byte (FFH).
65D8
DEFB FFH FF
Filler byte (FFH).
65D9
DEFB FFH FF
Filler byte (FFH).

65DAH - Boot Sector FCB Template: DIR/SYS

FCB template for the DIR/SYS system file (directory handler). This is written to the disk directory during FORMAT.

65DA
DEFB 5DH 5D
GAT pointer or attribute byte.
65DB
DEFB 00H 00
Reserved byte.
65DC
DEFB 00H 00
Reserved byte.
65DD
DEFB 00H 00
Reserved byte.
65DE
DEFB 00H 00
Reserved byte.
65DF
DEFB 'D' 44
Filename character 1: D
65E0
DEFB 'I' 49
Filename character 2: I
65E1
DEFB 'R' 52
Filename character 3: R
65E2
DEFB ' ' 20
Filename character 4: SPACE
65E3
DEFB ' ' 20
Filename character 5: SPACE
65E4
DEFB ' ' 20
Filename character 6: SPACE
65E5
DEFB ' ' 20
Filename character 7: SPACE
65E6
DEFB ' ' 20
Filename character 8: SPACE
65E7
DEFB 'S' 53
Extension character 1: S
65E8
DEFB 'Y' 59
Extension character 2: Y
65E9
DEFB 'S' 53
Extension character 3: S. Complete filename: DIR /SYS
65EA
DEFB A7H A7
File attributes byte (A7H = system file with special flags).
65EB
DEFB 1DH 1D
EOF offset or record length.
65EC
DEFB F9H F9
Extent/allocation information.
65ED
DEFB E5H E5
Extent/allocation information.
65EE
DEFB 0AH 0A
Sectors count - patched at runtime based on disk format.
65EF
DEFB 00H 00
Reserved byte.

65F0H - Boot Sector Configuration Data

Configuration data for the boot sector, including track/sector information that gets patched during FORMAT based on the target disk format.

65F0
DEFW FF01H 01 FF
Track/sector configuration word - patched at runtime. Low byte = first sector, high byte = last track.
65F2
DEFB FFH FF
Filler byte (FFH).
65F3
DEFB FFH FF
Filler byte (FFH).
65F4
DEFB FFH FF
Filler byte (FFH).
65F5
DEFB FFH FF
Filler byte (FFH).
65F6
DEFB FFH FF
Filler byte (FFH).
65F7
DEFB FFH FF
Filler byte (FFH).
65F8
DEFB FFH FF
Filler byte (FFH).
65F9
DEFB FFH FF
Filler byte (FFH). End of boot sector template area.

65FAH - COPY Command: File Copy Handler

This is the entry point for the COPY command's file copy operation. It handles the TO parameter parsing and sets up flags for the copy operation.

65FA
CALL 6392H - Parse destination filespec (TO parameter).
65FD
If NC FLAG (parse error), JUMP to 5218H - error handler.
6600
CALL 63A0H - Validate filespec and set up FCB.
6603
PUSH HL E5
Save HL (command line pointer) to stack.
6604
LD HL,5997H 21 97 59
Load HL with 5997H - address of COPY command flags.
6607
SET 2,(HL) CB D6
Set bit 2 of flags - indicates destination filespec is valid.
6609
POP HL E1
Restore HL (command line pointer) from stack.
660A
CALL 6EB5H - Skip whitespace and check for more parameters.
660D
If Carry FLAG set (more parameters), CALL 4F95H - parse additional options.
6610
CALL 6FB8H - Validate source/destination drive compatibility.
6613
CALL 6EB5H - Check for additional parameters.
6616
If NC FLAG (no more parameters), JUMP to 661FH.
6618
CALL 5025H - Parse numeric parameter (file count or size).
661B
LD (5981H),DE ED 53 81 59
Store parsed value to 5981H (copy parameter storage).
661F
LD B,40H 06 40
Load B with 40H (64 decimal) - option flags mask.
6621
CALL 4EA7H - Process COPY command options and validate.
6624
LD HL,5994H 21 94 59
Load HL with 5994H - address of operation status flags.
6627
LD A,(HL) 7E
Load A with current status flags.
6628
AND F9H E6 F9
Mask with F9H to test specific flag bits.
662A
If NZ FLAG (flags set), JUMP to 6630H to continue.
662C
LD A,(HL) 7E
Load A with status flags again.
662D
OR 80H F6 80
Set bit 7 (default option flag).
662F
LD (HL),A 77
Store updated flags.
6630
CALL 63B3H - Initialize file operation structures.
6633
LD HL,6DF3H 21 F3 6D
Load HL with 6DF3H - address of "Copying" message string.
6636
CALL 4467H (SYS0) - Display message string.
6639
CALL 6710H - Calculate and display disk space requirements.
663C
CALL 4DF3H - Read PDRIVE table from disk.
663F
LD HL,552DH 21 2D 55
Load HL with 552DH - return address for copy completion.
6642
PUSH HL E5
Push return address to stack (will return here after copy).

6643H - Initialize Copy Operation

This routine initializes the copy operation, checking various flags to determine the copy mode and whether disk swapping prompts are needed for single-drive copies.

6643
CALL 67C3H - Set up FCB and disk parameters for copy.
6646
LD A,(5997H) 3A 97 59
Load A with COPY command flags from 5997H.
6649
BIT 3,A CB 5F
Test bit 3 - special copy mode flag.
664B
RET NZ C0
If NZ FLAG (special mode active), RETURN - copy already set up.
664C
LD A,(5996H) 3A 96 59
Load A with additional flags from 5996H.
664F
BIT 7,A CB 7F
Test bit 7 - verify mode flag.
6651
RET NZ C0
If NZ FLAG (verify mode), RETURN.
6652
LD DE,0000H 11 00 00
Load DE with 0 - clear counter/parameter.
6655
CALL 5784H - Initialize disk I/O parameters.
6658
LD A,(5994H) 3A 94 59
Load A with operation status from 5994H.
665B
BIT 1,A CB 4F
Test bit 1 - multi-file copy flag.
665D
RET NZ C0
If NZ FLAG (multi-file mode), RETURN.
665E
LD HL,6DDAH 21 DA 6D
Load HL with 6DDAH - address of prompt message.
6661
CALL 4467H (SYS0) - Display prompt message.
6664
CALL 67AAH - Get user response or wait for keypress.
6667
LD DE,6EB5H 11 B5 6E
Load DE with 6EB5H - default value or parameter address.
666A
LD BC,0002H 01 02 00
Load BC with 2 - parameter count or size.
666D
If Z FLAG (default response), CALL 67B4H to use defaults.
6670
If NZ FLAG (error or cancel), JUMP to 521AH error handler.
6673
LD A,FFH 3E FF
Load A with FFH - all bits set (full track/all sectors flag).
6675
CALL 64B0H - Set up disk track parameters.
6678
LD DE,(59D1H) ED 5B D1 59
Load DE with value from 59D1H - disk geometry parameter.
667C
LD HL,4200H 21 00 42
Load HL with 4200H - sector buffer address.
667F
LD (5B1AH),HL 22 1A 5B
Store buffer address to 5B1AH (FCB buffer pointer).
6682
LD C,L 4D
Load C with L (00H - buffer low byte).
6683
PUSH HL E5
Save buffer address to stack.
6684
CALL 5762H - Read sector into buffer.
6687
POP HL E1
Restore buffer address from stack.
6688
SET 0,(HL) CB C6
Set bit 0 of first byte in buffer (directory entry flag).
668A
LD A,(59CDH) 3A CD 59
Load A with value from 59CDH - sectors per track.
668D
LD (59C5H),A 32 C5 59
Store to 59C5H - working sectors per track.
6690
LD HL,(4399H) 2A 99 43
Load HL with pointer from 4399H (system area pointer).
6693
LD (HL),A 77
Store sectors per track to system area.
6694
LD B,00H 06 00
Load B with 0 - initialize counter.
6696
LD E,A 5F
Load E with sectors per track.
6697
LD A,(59CEH) 3A CE 59
Load A with value from 59CEH - total tracks.
669A
LD C,A 4F
Load C with total tracks.
669B
PUSH DE D5
Save DE (sectors per track) to stack.
669C
LD HL,4200H 21 00 42
Load HL with 4200H - sector buffer address.
669F
CALL 621CH - Calculate disk capacity or allocation.
66A2
LD HL,597EH 21 7E 59
Load HL with 597EH - source data area.
66A5
LD DE,42CBH 11 CB 42
Load DE with 42CBH - destination in sector buffer.
66A8
LD BC,0016H 01 16 00
Load BC with 22 (16H) - bytes to copy.
66AB
LDIR ED B0
Block copy 22 bytes from (HL) to (DE).
66AD
POP HL E1
Restore HL (was DE - sectors per track).
66AE
LD A,(59CAH) 3A CA 59
Load A with value from 59CAH - granule size.
66B1
LD H,A 67
Load H with granule size.
66B2
RLCA 07
Rotate left (multiply by 2).
66B3
RLCA 07
Rotate left again (multiply by 4).
66B4
ADD A,H 84
Add original value (A = granule_size * 5).
66B5
CALL 4C92H (SYS0) - Multiply or calculate offset.
66B8
LD (5B21H),HL 22 21 5B
Store result to 5B21H - allocation table pointer.
66BB
LD C,00H 0E 00
Load C with 0 - initialize sector counter.
66BD
JUMP to 66FBH to begin sector write loop.

66BFH - Write System Sectors Loop

This loop writes the system sectors to the disk during FORMAT. It writes the boot sector, directory, and system file entries. The loop processes sectors 0-9 (10 sectors total).

66BF
PUSH BC C5
[SECTOR WRITE LOOP] Save BC (C = sector counter) to stack.
66C0
XOR A AF
Clear A (set to 0).
66C1
CALL 64B0H - Set track 0 for boot sector writes.
66C4
LD A,C 79
Load A with current sector number from C.
66C5
DEC A 3D
Decrement A (check if sector 1).
66C6
If NZ FLAG (not sector 1), JUMP to 66E6H to check other sectors.

Sector 1 processing - set up GAT (Granule Allocation Table) header.

66C8
LD HL,4200H 21 00 42
Load HL with 4200H - sector buffer address.
66CB
LD (HL),A2H 36 A2
Write A2H to buffer - GAT signature byte 1.
66CD
INC HL 23
Advance buffer pointer.
66CE
LD (HL),C4H 36 C4
Write C4H to buffer - GAT signature byte 2. Together A2C4H identifies a valid GAT sector.
66D0
LD A,(59CEH) 3A CE 59
Load A with total tracks from 59CEH.
66D3
SUB 02H D6 02
Subtract 2 (reserved tracks for system).
66D5
LD C,A 4F
Save result in C (usable tracks).
66D6
RLCA 07
Rotate left (multiply by 2).
66D7
RLCA 07
Rotate left again (multiply by 4).
66D8
ADD A,C 81
Add original (A = usable_tracks * 5).
66D9
LD (421FH),A 32 1F 42
Store calculated value to 421FH (GAT size in buffer).
66DC
ADD 0AH C6 0A
Add 10 to get offset for directory entry.
66DE
LD (65EEH),A 32 EE 65
Patch the DIR/SYS FCB template at 65EEH with sector count.
66E1
LD (670CH),A 32 0C 67
Store value at 670CH for later reference.
66E4
JUMP to 66FAH to write this sector.

Check for directory sectors (sectors 2-3) to copy FCB templates.

66E6
LD HL,65BAH 21 BA 65
Load HL with 65BAH - BOOT/SYS FCB template address.
66E9
CP 02H FE 02
Compare A with 2 (sector 2 = first directory sector).
66EB
If Carry FLAG (sector < 2), JUMP to 66F2H to copy FCB.
66ED
If NZ FLAG (sector > 2), JUMP to 66FAH (skip FCB copy).
66EF
LD HL,65DAH 21 DA 65
Load HL with 65DAH - DIR/SYS FCB template address (for sector 2).
66F2
LD DE,4200H 11 00 42
Load DE with 4200H - sector buffer destination.
66F5
LD BC,0020H 01 20 00
Load BC with 32 (20H) - FCB entry size.
66F8
LDIR ED B0
Block copy 32 bytes of FCB template to buffer.
66FA
POP BC C1
Restore BC (sector counter) from stack.
66FB
SET 0,(IX+00H) DD CB 00 C6
Set bit 0 of (IX+00H) - mark sector as modified/needs write.
66FF
CALL 57D4H - Write sector to disk.
6702
RES 0,(IX+00H) DD CB 00 86
Clear bit 0 of (IX+00H) - mark sector write complete.
6706
If NZ FLAG (write error), JUMP to 521AH error handler.
6709
INC C 0C
Increment sector counter.
670A
LD A,C 79
Load A with current sector count.
670B
CP 0AH FE 0A
Compare with 10 (0AH) - total system sectors. Self-modifying code target at 670CH - may be patched.
670D
If Carry FLAG (more sectors to write), JUMP to 66BFH.
670F
RET C9
RETURN - all system sectors written.

6710H - Calculate Disk Space Requirements

This routine calculates and displays the disk space requirements for a copy or format operation. It reads disk parameters and calculates free space, sectors needed, etc.

6710
LD HL,59C5H 21 C5 59
Load HL with 59C5H - disk parameter block address.
6713
PUSH IX DD E5
Save IX to stack.
6715
PUSH HL E5
Push HL to stack.
6716
POP IX DD E1
Pop into IX (IX now points to disk parameter block at 59C5H).
6718
LD A,(IX+04H) DD 7E 04
Load A with (IX+04H) = byte at 59C9H (sectors per granule).
671B
LD L,(IX+03H) DD 6E 03
Load L with (IX+03H) = byte at 59C8H (granules per track).
671E
CALL 4C92H (SYS0) - Multiply A * L, result in HL.
6721
LD (IX+0AH),L DD 75 0A
Store L to (IX+0AH) = 59CFH.
6724
LD (IX+0BH),H DD 74 0B
Store H to (IX+0BH) = 59D0H.
6727
CALL 5CF2H - Additional disk space calculation.
672A
LD (IX+0CH),L DD 75 0C
Store L to (IX+0CH) = 59D1H.
672D
LD (IX+0DH),H DD 74 0D
Store H to (IX+0DH) = 59D2H.
6730
LD A,(IX+05H) DD 7E 05
Load A with (IX+05H) = byte at 59CAH (granule size).
6733
CALL 4CB4H (SYS0) - Divide or calculate ratio.
6736
OR A B7
Test A for zero.
6737
If Z FLAG (A = 0), JUMP to 673AH.
6739
INC HL 23
Increment HL (round up).
673A
LD A,H 7C
Load A with high byte of result.
673B
OR A B7
Test if H is non-zero.
673C
If NZ FLAG (overflow - too many granules), JUMP to 6747H error.
673E
LD A,L 7D
Load A with low byte of granule count.
673F
CP C1H FE C1
Compare with 193 (C1H) - maximum granules per disk.
6741
LD (IX+01H),A DD 77 01
Store granule count to (IX+01H) = 59C6H.
6744
POP IX DD E1
Restore IX from stack.
6746
RET C D8
If Carry FLAG (granule count < 193), RETURN - disk is valid.

[ERROR PATH] - Disk format exceeds maximum capacity or other error.

6747
LD HL,6E57H 21 57 6E
Load HL with 6E57H - address of "Disk too large" error message.
674A
JUMP to 5243H - display error message and abort.

674DH - Validate Disk Space for Copy

Validates that sufficient disk space exists for the copy operation.

674D
CALL 61EAH - Check available disk space.
6750
RET Z C8
If Z FLAG (sufficient space), RETURN.
6751
LD A,(5994H) 3A 94 59
Load A with operation flags from 5994H.
6754
BIT 1,A CB 4F
Test bit 1 - multi-file flag.
6756
If Z FLAG (single file mode), JUMP to 6747H error handler.
6758
RET C9
RETURN - continue in multi-file mode (will prompt for next disk).

6759H - Patch Boot Sector Parameters

This routine patches the boot sector template with the actual disk parameters. It modifies self-modifying code targets in the boot loader to match the disk format being used.

6759
LD A,(59CBH) 3A CB 59
Load A with value from 59CBH - sectors per track configuration.
675C
LD (65B7H),A 32 B7 65
Patch 65B7H in BOOT/SYS FCB template.
675F
LD (64CAH),A 32 CA 64
Patch 64CAH in boot sector code (sector register initial value).
6762
LD A,(59CCH) 3A CC 59
Load A with value from 59CCH - disk configuration flags.
6765
LD (65B9H),A 32 B9 65
Patch 65B9H in BOOT/SYS FCB template.
6768
BIT 1,A CB 4F
Test bit 1 - double-sided disk flag.
676A
If Z FLAG (single-sided), JUMP to 6770H.
676C
LD HL,64CDH 21 CD 64
Load HL with 64CDH - boot sector sector count location.
676F
INC (HL) 34
Increment sector count for double-sided operation.
6770
BIT 4,A CB 67
Test bit 4 - special density/format flag.
6772
If Z FLAG (standard format), JUMP to 677DH.
6774
LD HL,64CCH 21 CC 64
Load HL with 64CCH - boot sector parameter location.
6777
INC (HL) 34
Increment parameter for special format.
6778
LD HL,656FH 21 6F 65
Load HL with 656FH - boot sector self-mod target for sector base.
677B
LD (HL),01H 36 01
Write 01H - set starting sector to 1 (instead of 0).
677D
BIT 0,A CB 47
Test bit 0 - alternate timing flag.
677F
If Z FLAG (standard timing), JUMP to 6786H.
6781
LD HL,64C2H 21 C2 64
Load HL with 64C2H - boot sector FDC command location.
6784
SET 0,(HL) CB C6
Set bit 0 - modify FDC command timing.
6786
BIT 6,A CB 77
Test bit 6 - sectors per track modifier flag.
6788
LD A,(59C9H) 3A C9 59
Load A with value from 59C9H - sectors per granule.
678B
LD (656AH),A 32 6A 65
Patch 656AH in boot sector (self-mod target for sector count).
678E
If Z FLAG (bit 6 clear), JUMP to 6791H.
6790
RRCA 0F
Rotate A right (divide by 2 for alternate format).
6791
LD (651BH),A 32 1B 65
Patch 651BH in boot sector (SUB instruction operand).
6794
LD A,(59CDH) 3A CD 59
Load A with value from 59CDH - first sector number.
6797
LD (64BCH),A 32 BC 64
Patch 64BCH in boot sector.
679A
LD L,A 6F
Load L with first sector number.
679B
LD A,(59CEH) 3A CE 59
Load A with value from 59CEH - total tracks.
679E
LD H,A 67
Load H with total tracks.
679F
DEC H 25
Decrement H (last track number = total - 1).
67A0
LD (65F0H),HL 22 F0 65
Store HL to 65F0H - boot sector track/sector configuration.
67A3
LD A,(59C7H) 3A C7 59
Load A with value from 59C7H - density configuration.
67A6
LD (65B8H),A 32 B8 65
Patch 65B8H in BOOT/SYS FCB template.
67A9
RET C9
RETURN - boot sector patching complete.

67AAH - Wait for User Response

Waits for user input (keypress) and sets up parameters for disk write operations.

67AA
LD BC,0000H 01 00 00
Load BC with 0 - clear counter/parameter.
67AD
CALL 67B1H - set up FCB and wait.
67B0
INC BC 03
Increment BC.
67B1
LD DE,64BAH 11 BA 64
Load DE with 64BAH - boot sector template address.
67B4
LD (5B1AH),DE ED 53 1A 5B
Store DE to 5B1AH - FCB buffer pointer.
67B8
LD IX,5B17H DD 21 17 5B
Load IX with 5B17H - FCB address.
67BC
LD (5B21H),BC ED 43 21 5B
Store BC to 5B21H - allocation table pointer.
67C0
JUMP to 57D4H - perform disk I/O operation.

67C3H - Copy/Format Setup Routine

This routine sets up the parameters for a COPY or FORMAT operation. It patches the boot sector, initializes the FCB, and checks various disk compatibility flags.

67C3
CALL 6759H - Patch boot sector parameters based on disk format.
67C6
LD IX,5B17H DD 21 17 5B
Load IX with 5B17H - FCB (File Control Block) address.
67CA
CALL 557DH - Initialize FCB and open file.
67CD
LD A,(5994H) 3A 94 59
Load A with operation flags from 5994H.
67D0
LD C,A 4F
Save flags in C for later testing.
67D1
BIT 6,C CB 71
Test bit 6 - verify-only mode flag.
67D3
If NZ FLAG (verify mode), JUMP to 6886H to skip actual copy.
67D6
CALL 57C8H - Read first sector / check disk.
67D9
If Z FLAG (read successful), JUMP to 67EEH.
67DB
CP 05H FE 05
Compare error code with 5 (record not found).
67DD
If NZ FLAG (different error), JUMP to 521AH error handler.
67E0
BIT 7,C CB 79
Test bit 7 - format mode flag.
67E2
If NZ FLAG (format mode), JUMP to 6886H - formatting expected.
67E5
LD HL,6D94H 21 94 6D
Load HL with 6D94H - "Disk is blank" message address.
67E8
CALL 4467H (SYS0) - Display message.
67EB
JUMP to 6880H - prompt for retry.

Disk read successful - validate disk format and copy parameters.

67EE
XOR A AF
Clear A (set to 0).
67EF
CALL 490AH - Validate disk format signature.
67F2
If Z FLAG (valid format), JUMP to 6806H.
67F4
LD L,A 6F
Save validation result in L.
67F5
LD A,C 79
Load A with flags from C.
67F6
AND 19H E6 19
Mask with 19H to test critical mode flags.
67F8
LD A,L 7D
Restore validation result to A.
67F9
If NZ FLAG (incompatible modes), JUMP to 521AH error.
67FC
LD HL,42D0H 21 D0 42
Load HL with 42D0H - disk name buffer in sector buffer.
67FF
LD B,10H 06 10
Load B with 16 (10H) - disk name length.
6801
LD (HL),3FH 36 3F
[CLEAR NAME LOOP] Write 3FH (?) to buffer - fill with wildcards.
6803
INC HL 23
Advance buffer pointer.
6804
Decrement B, if NZ FLAG (more bytes), JUMP to 6801H.
6806
BIT 7,C CB 79
Test bit 7 - format mode flag.
6808
If Z FLAG (not format mode), JUMP to 6812H.
680A
LD HL,6D82H 21 82 6D
Load HL with 6D82H - "Formatting" message address.
680D
CALL 4467H (SYS0) - Display formatting message.
6810
JUMP to 687AH to begin format operation.
6812
LD A,(436CH) 3A 6C 43
Load A with system flag byte from 436CH.
6815
AND 82H E6 82
Mask with 82H to isolate specific flags.
6817
CP 80H FE 80
Compare with 80H.
6819
If NZ FLAG (flags don't match), JUMP to 6840H.
681B
LD A,(5996H) 3A 96 59
Load A with flags from 5996H.
681E
BIT 3,A CB 5F
Test bit 3 - date checking flag.
6820
If Z FLAG (no date check), JUMP to 6840H.
6822
LD A,(5995H) 3A 95 59
Load A with flags from 5995H.
6825
BIT 0,A CB 47
Test bit 0 - specific date comparison flag.
6827
If Z FLAG, JUMP to 6835H for date mismatch error.
6829
LD HL,(42CEH) 2A CE 42
Load HL with date value from sector buffer at 42CEH.
682C
LD DE,(597AH) ED 5B 7A 59
Load DE with expected date from 597AH.
6830
OR A B7
Clear Carry flag for comparison.
6831
SBC HL,DE ED 52
Subtract DE from HL to compare dates.
6833
If Z FLAG (dates match), JUMP to 6840H to continue.

[DATE MISMATCH ERROR] - Disk date doesn't match expected date.

6835
LD HL,5A44H 21 44 5A
Load HL with 5A44H - date mismatch warning message.
6838
CALL 4467H (SYS0) - Display warning message.
683B
LD A,37H 3E 37
Load A with error code 37H (date mismatch error).
683D
JUMP to 521AH - error handler.

6840H - Copy Disk Name and Date

Copies disk name and date information from the source disk to the destination parameters. Handles various copy options like preserving original dates.

6840
BIT 3,C CB 59
Test bit 3 of flags (C) - copy disk name flag.
6842
If Z FLAG (don't copy name), JUMP to 6851H.
6844
PUSH BC C5
Save BC to stack.
6845
LD HL,42D0H 21 D0 42
Load HL with 42D0H - disk name in sector buffer.
6848
LD DE,5983H 11 83 59
Load DE with 5983H - destination disk name buffer.
684B
LD BC,0008H 01 08 00
Load BC with 8 - disk name length.
684E
LDIR ED B0
Block copy 8 bytes of disk name.
6850
POP BC C1
Restore BC from stack.
6851
BIT 0,C CB 41
Test bit 0 of flags - copy disk date flag.
6853
If Z FLAG (don't copy date), JUMP to 6862H.
6855
PUSH BC C5
Save BC to stack.
6856
LD HL,42D8H 21 D8 42
Load HL with 42D8H - disk date in sector buffer.
6859
LD DE,598BH 11 8B 59
Load DE with 598BH - destination disk date buffer.
685C
LD BC,0008H 01 08 00
Load BC with 8 - date string length.
685F
LDIR ED B0
Block copy 8 bytes of disk date.
6861
POP BC C1
Restore BC from stack.
6862
BIT 4,C CB 61
Test bit 4 of flags - validate source disk flag.
6864
If Z FLAG (no validation needed), JUMP to 6876H.
6866
LD HL,5970H 21 70 59
Load HL with 5970H - source disk validation data.
6869
CALL 624FH - Validate disk against stored parameters.
686C
If Z FLAG (validation passed), JUMP to 6876H.
686E
LD HL,5A44H 21 44 5A
Load HL with 5A44H - validation error message.
6871
CALL 692FH - Display error and additional info.
6874
JUMP to 687AH to prompt user.
6876
BIT 5,C CB 69
Test bit 5 of flags - prompt user flag.
6878
If Z FLAG (no prompt needed), JUMP to 6886H.
687A
LD HL,5A44H 21 44 5A
Load HL with 5A44H - prompt message address.
687D
CALL 693BH - Display prompt and wait for response.
6880
CALL 58C8H - Get user response (Y/N).
6883
If NZ FLAG (user said Yes/retry), JUMP to 67CAH to retry.

6886H - Proceed with Copy/Format Operation

After setup and validation, this section proceeds with the actual copy or format operation. It checks density compatibility and prompts for physical formatting if needed.

6886
LD A,(5997H) 3A 97 59
Load A with command flags from 5997H.
6889
BIT 3,A CB 5F
Test bit 3 - special processing flag.
688B
RET NZ C0
If NZ FLAG (special processing), RETURN to caller.
688C
LD A,(59C7H) 3A C7 59
Load A with disk density flags from 59C7H.
688F
BIT 5,A CB 6F
Test bit 5 - double density flag.
6891
If NZ FLAG (double density), CALL 6751H to validate space.
6894
LD HL,6D61H 21 61 6D
Load HL with 6D61H - "Format disk?" prompt message.
6897
CALL 4467H (SYS0) - Display prompt.
689A
CALL 476EH - Get Y/N response from user.
689D
If Z FLAG (user said Yes), CALL 4745H - confirm operation.
68A0
If NZ FLAG (user cancelled), JUMP to 521AH error/abort.
68A3
LD A,(5997H) 3A 97 59
Load A with command flags from 5997H.
68A6
AND 02H E6 02
Mask with 02H to test track-by-track mode.
68A8
If Z FLAG (not track mode), JUMP to 68D0H.

Track-by-track format mode - format each track individually.

68AA
LD DE,0001H 11 01 00
Load DE with 1 - starting track number.
68AD
LD A,D 7A
Load A with D (0).
68AE
ADD A,E 83
Add E to A (result = 1).
68AF
LD C,A 4F
Save result in C.
68B0
If Carry (overflow), JUMP to 68B6H.
68B2
LD A,(59C8H) 3A C8 59
Load A with total tracks from 59C8H.
68B5
CP C B9
Compare total tracks with current track.
68B6
If Carry (past last track), JUMP to 5218H error.
68B9
BIT 1,(IY+91H) FD CB 91 4E
Test bit 1 of (IY+91H) - double-sided flag.
68BD
If Z FLAG (single-sided), JUMP to 68C0H.
68BF
INC D 14
Increment D (track count for double-sided).
68C0
LD A,D 7A
Load A with D (side/track offset).
68C1
LD (6AF4H),A 32 F4 6A
Store to 6AF4H - format routine parameter.
68C4
LD (37EFH),A 32 EF 37
Store to 37EFH - FDC data register (for format).
68C7
LD C,18H 0E 18
Load C with 18H (24) - format command parameter.
68C9
CALL 4747H - Execute format track operation.
68CC
LD A,D 7A
Load A with D.
68CD
ADD A,E 83
Add E to A.
68CE
JUMP to 6922H to continue format.

68D0H - Full Disk Format Mode

Handles full disk format operation, formatting all tracks. Checks for system requirements and double-density support.

68D0
LD A,(59C8H) 3A C8 59
Load A with total tracks from 59C8H.
68D3
LD HL,5996H 21 96 59
Load HL with 5996H - flags address.
68D6
BIT 7,(HL) CB 7E
Test bit 7 - full format flag.
68D8
If NZ FLAG (full format), JUMP to 6922H to begin.
68DA
BIT 6,(IY+8CH) FD CB 8C 76
Test bit 6 of (IY+8CH) - double-density capable flag.
68DE
If Z FLAG (single density only), JUMP to 6922H.

Double-density format setup - configure for double-density operation.

68E0
PUSH IX DD E5
Save IX to stack.
68E2
LD IX,(4399H) DD 2A 99 43
Load IX with pointer from 4399H (system area).
68E6
LD A,01H 3E 01
Load A with 1.
68E8
LD E,(IY+91H) FD 5E 91
Load E with (IY+91H) - density configuration.
68EB
XOR E AB
XOR A with E to toggle density bit.
68EC
AND C1H E6 C1
Mask with C1H to isolate relevant bits.
68EE
LD (IX+07H),A DD 77 07
Store to (IX+07H) - density configuration byte.
68F1
CALL 54D7H - Set up density parameters.
68F4
LD (IX+04H),04H DD 36 04 0A
Store 0AH to (IX+04H) - format parameter. Note: The immediate value appears to be 0AH based on opcode DD 36 04 0A.
68F8
EX (SP),IX DD E3
Exchange IX with value on stack (swap FCB pointers).
68FA
PUSH DE D5
Save DE to stack.
68FB
LD A,01H 3E 01
Load A with 1 - track number to format.
68FD
PUSH BC C5
Save BC to stack.
68FE
CALL 6959H - Format track routine.
6901
If Z FLAG (format successful), CALL 67AAH - wait/confirm.
6904
POP BC C1
Restore BC from stack.
6905
POP DE D1
Restore DE from stack.
6906
EX (SP),IX DD E3
Swap IX with stack again.
6908
PUSH AF F5
Save AF (flags) to stack.
6909
CALL 54ECH - Clean up density settings.
690C
LD (IX+04H),D DD 72 04
Restore (IX+04H) with D.
690F
CALL 4773H - Additional format cleanup.
6912
EX AF,AF' 08
Switch to alternate AF.
6913
POP AF F1
Restore AF from stack.
6914
POP IX DD E1
Restore IX from stack.
6916
If NZ FLAG (format error), JUMP to 6925H.
6918
EX AF,AF' 08
Switch back to alternate AF.
6919
If NZ FLAG (error in alternate flags), JUMP to 6925H.
691B
CALL 6CAFH - Finalize format operation.
691E
LD A,(59C8H) 3A C8 59
Load A with total tracks from 59C8H.
6921
INC A 3C
Increment track count.
6922
CALL 6959H - Format remaining tracks.
6925
EI FB
Enable interrupts (format runs with interrupts disabled).
6926
RET Z C8
If Z FLAG (success), RETURN.
6927
CP FFH FE FF
Compare error code with FFH (user abort).
6929
If NZ FLAG (real error), JUMP to 521AH.
692C
JUMP to 5243H - user abort handler.

692FH - Display Error with Disk Info

Displays an error message followed by disk identification information.

692F
PUSH HL E5
Save HL (message address) to stack.
6930
CALL 4467H (SYS0) - Display error message.
6933
LD HL,6DC2H 21 C2 6D
Load HL with 6DC2H - "Disk:" label message.
6936
CALL 4467H (SYS0) - Display disk label.
6939
POP HL E1
Restore HL from stack.
693A
RET C9
RETURN to caller.

693BH - Display Disk Name and Date Prompt

Displays a prompt message along with the current disk name and date from the sector buffer.

693B
CALL 4467H (SYS0) - Display first message (in HL).
693E
LD HL,6DA8H 21 A8 6D
Load HL with 6DA8H - "Name:" label message.
6941
CALL 4467H (SYS0) - Display name label.
6944
LD HL,42D0H 21 D0 42
Load HL with 42D0H - disk name in sector buffer.
6947
LD B,08H 06 08
Load B with 8 - disk name length.
6949
CALL 5886H - Display B bytes from (HL).
694C
LD B,04H 06 04
Load B with 4 - separator/spacing.
694E
CALL 5898H - Display B spaces.
6951
LD B,08H 06 08
Load B with 8 - date length.
6953
CALL 5886H - Display 8 bytes (date).
6956
JUMP to 5881H - output carriage return and continue.

6959H - Format Track Initialization

This routine initializes the format track operation. It selects timing parameters based on CPU speed (from system flags at 4311H) and patches self-modifying code locations throughout the format routine. The timing is critical for proper FDC operation across different TRS-80 CPU speeds (1.77MHz, 2.03MHz, 4MHz).

6959
LD (6C75H),A 32 75 6C
Store track count parameter to 6C75H for format operation.
695C
CALL 4773H - Check drive ready status.
695F
RET NZ C0
If NZ FLAG (drive not ready), RETURN with error.
6960
LD A,(4311H) 3A 11 43
Load A with system flags from 4311H. Bits 0-1 indicate CPU speed: 00=1.77MHz, 01=2.03MHz, 10=4MHz.
6963
RLCA 07
Rotate left to position speed bits for table offset calculation.
6964
AND 03H E6 03
Mask to isolate speed indicator (0, 1, or 2).
6966
LD L,1AH 2E 1A
Load L with 26 (1AH) - size of each timing parameter block.
6968
CALL 4C92H (SYS0) - Multiply A * L to get table offset.
696B
LD DE,6CC2H 11 C2 6C
Load DE with 6CC2H - base address of timing parameter tables.
696E
ADD HL,DE 19
Add offset to base - HL now points to correct timing table for CPU speed.

[PATCH TIMING VALUES] - Copy timing values from table to self-modifying code targets.

696F
LD A,(HL) 7E
Load first timing value from table.
6970
LD (6B1CH),A 32 1C 6B
Patch 6B1CH - gap byte count in ID field write.
6973
INC HL 23
Advance to next table entry.
6974
LD (6B83H),A 32 83 6B
Patch 6B83H - same value for sector gap.
6977
LD A,(HL) 7E
Load next timing value.
6978
LD (6AD8H),A 32 D8 6A
Patch 6AD8H - track number byte position.
697B
INC HL 23
Advance table pointer.
697C
LD (6B4DH),A 32 4D 6B
Patch 6B4DH - additional timing target.
697F
LD A,(HL) 7E
Load next timing value.
6980
LD (6B6FH),A 32 6F 6B
Patch 6B6FH - data field fill byte.
6983
INC HL 23
Advance table pointer.
6984
LD A,(HL) 7E
Load next timing value.
6985
LD (6B76H),A 32 76 6B
Patch 6B76H - data field timing.
6988
INC HL 23
Advance table pointer.
6989
LD A,(HL) 7E
Load next timing value.
698A
LD (6B8BH),A 32 8B 6B
Patch 6B8BH - inter-sector gap timing.
698D
INC HL 23
Advance table pointer.
698E
LD A,(HL) 7E
Load next timing value.
698F
LD (6AC8H),A 32 C8 6A
Patch 6AC8H - loop counter value.
6992
INC HL 23
Advance table pointer.
6993
LD A,(HL) 7E
Load next timing value.
6994
LD (6B26H),A 32 26 6B
Patch 6B26H - ID address mark timing.
6997
INC HL 23
Advance table pointer.
6998
LD A,(HL) 7E
Load next timing value.
6999
LD (6B3DH),A 32 3D 6B
Patch 6B3DH - data address mark timing.
699C
INC HL 23
Advance table pointer.

[LOAD 16-BIT TIMING VALUES] - Load word values for more complex timing patches.

699D
LD E,(HL) 5E
Load low byte of timing word.
699E
INC HL 23
Advance pointer.
699F
LD D,(HL) 56
Load high byte - DE now contains timing word.
69A0
INC HL 23
Advance pointer.
69A1
LD C,(HL) 4E
Load low byte of second timing word.
69A2
INC HL 23
Advance pointer.
69A3
LD B,(HL) 46
Load high byte - BC now contains second timing word.
69A4
LD (69DAH),BC ED 43 DA 69
Patch 69DAH with BC - self-modifying LD HL instruction operand.
69A8
INC HL 23
Advance table pointer.
69A9
LD C,(HL) 4E
Load low byte of third timing word.
69AA
INC HL 23
Advance pointer.
69AB
LD B,(HL) 46
Load high byte - BC contains third timing word.
69AC
LD (69F2H),BC ED 43 F2 69
Patch 69F2H with BC.
69B0
INC HL 23
Advance table pointer.
69B1
LD C,(HL) 4E
Load low byte of fourth timing word.
69B2
INC HL 23
Advance pointer.
69B3
LD B,(HL) 46
Load high byte.
69B4
LD (69D6H),BC ED 43 D6 69
Patch 69D6H with BC.
69B8
INC HL 23
Advance table pointer.
69B9
LD A,(HL) 7E
Load next single-byte timing value.
69BA
LD (6A00H),A 32 00 6A
Patch 6A00H - ADD instruction operand.
69BD
INC HL 23
Advance table pointer.
69BE
LD A,(HL) 7E
Load final timing value.
69BF
LD (6A33H),A 32 33 6A
Patch 6A33H - ADD instruction operand.
69C2
INC HL 23
Advance past timing table (HL now points to unused area).
69C3
NOP 00
No operation (padding/alignment).
69C4
NOP 00
No operation.
69C5
NOP 00
No operation.

[INITIALIZE FORMAT VARIABLES] - Clear working variables for format operation.

69C6
XOR A AF
Clear A to zero.
69C7
LD (6A02H),A 32 02 6A
Clear 6A02H - format sector counter.
69CA
LD (6C63H),A 32 63 6C
Clear 6C63H - side flag (0 = front side).
69CD
EX DE,HL EB
Exchange DE and HL (HL now contains timing word from earlier).
69CE
CALL 6CA4H - Get sectors per track into E.
69D1
LD A,E 7B
Load A with sectors per track.
69D2
CALL 4C94H (SYS0) - Calculate based on sectors per track.
69D5
LD BC,0000H 01 00 00
Load BC with 0. Self-modifying code target at 69D6H - patched with timing value.
69D8
EX DE,HL EB
Exchange DE and HL.
69D9
LD HL,0000H 21 00 00
Load HL with 0. Self-modifying code target at 69DAH - patched with timing value.
69DC
OR A B7
Clear Carry flag.
69DD
SBC HL,DE ED 52
Subtract DE from HL (calculate difference).
69DF
PUSH HL E5
Save result to stack.
69E0
If NC FLAG (no borrow), JUMP to 69F1H.
69E2
ADD HL,HL 29
Double HL (multiply by 2).
69E3
ADD HL,HL 29
Double HL again (multiply by 4).
69E4
ADD HL,BC 09
Add BC to HL.
69E5
If Carry FLAG (overflow), JUMP to 69EEH.
69E7
POP HL E1
Restore HL from stack.
69E8
LD HL,6D6CH 21 6C 6D
Load HL with 6D6CH - "MOTOR FAST" error message address.
69EB
OR FFH F6 FF
Set A to FFH (error code) and set flags.
69ED
RET C9
RETURN with error - motor speed too fast for format.
69EE
LD HL,0000H 21 00 00
Load HL with 0 (reset for next calculation).
69F1
LD DE,0000H 11 00 00
Load DE with 0. Self-modifying code target at 69F2H - patched with timing value.
69F4
ADD HL,DE 19
Add DE to HL.
69F5
LD (6BCDH),HL 22 CD 6B
Store result to 6BCDH - format timing parameter.
69F8
POP HL E1
Restore HL from stack.
69F9
ADD HL,DE 19
Add DE to HL.
69FA
ADD HL,BC 09
Add BC to HL.
69FB
ADD HL,BC 09
Add BC again.
69FC
LD (6BD6H),HL 22 D6 6B
Store result to 6BD6H - another timing parameter.
69FF
LD A,02H 3E 02
Load A with 2.
6A01
ADD 00H C6 00
Add 0 to A. Self-modifying code target at 6A00H - operand is patched.
6A03
CALL 6CA4H - Get sectors per track.
6A06
CP E BB
Compare A with E (sectors per track).
6A07
If Carry FLAG (A < E), JUMP to 6A0AH.
6A09
SUB E 93
Subtract E from A (wrap sector number).
6A0A
LD (6A02H),A 32 02 6A
Store starting sector number to 6A02H.
6A0D
LD (6A02H),A 32 02 6A
Store again (redundant but ensures value is set).
6A10
INC A 3C
Increment A.
6A11
LD D,A 57
Copy to D (sector counter for interleave).
6A12
PUSH DE D5
Save DE to stack.

6A13H - Generate Sector Interleave Table

This routine generates the sector interleave table at 6485H. The interleave pattern determines the physical order of sectors on the track to optimize read performance by allowing time for the system to process data between sequential sector reads.

6A13
LD HL,6485H 21 85 64
Load HL with 6485H - sector interleave table address.
6A16
LD B,E 43
Load B with E (sectors per track) as counter.
6A17
LD (HL),FFH 36 FF
[CLEAR TABLE LOOP] Initialize table entry to FFH (unused marker).
6A19
INC HL 23
Advance to next table entry.
6A1A
Decrement B, if NZ FLAG, JUMP to 6A17H to continue clearing.
6A1C
LD D,00H 16 00
Initialize D to 0 (physical sector number).
6A1E
LD B,D 42
Initialize B to 0.
6A1F
JUMP to 6A26H to start interleave generation.
6A21
INC C 0C
[FIND NEXT SLOT] Increment C (table position).
6A22
LD A,C 79
Load A with C.
6A23
CP E BB
Compare with E (sectors per track).
6A24
If Carry (C < sectors), JUMP to 6A28H.
6A26
LD C,00H 0E 00
Wrap C back to 0 (start of table).
6A28
LD HL,6485H 21 85 64
Load HL with 6485H - interleave table base.
6A2B
ADD HL,BC 09
Add BC to get table[C] address.
6A2C
LD A,(HL) 7E
Load current table entry.
6A2D
INC A 3C
Increment (test if FFH - unused slot becomes 00H).
6A2E
If NZ FLAG (slot already used), JUMP to 6A21H to find next.
6A30
LD (HL),D 72
Store physical sector number D into table slot.
6A31
LD A,C 79
Load A with current position C.
6A32
ADD 02H C6 02
Add interleave factor. Self-modifying target at 6A33H - value patched based on CPU speed.
6A34
CP E BB
Compare with sectors per track.
6A35
If Carry (within range), JUMP to 6A38H.
6A37
SUB E 93
Wrap position by subtracting sectors per track.
6A38
LD C,A 4F
Update C with new position.
6A39
INC D 14
Increment physical sector number D.
6A3A
LD A,D 7A
Load A with D.
6A3B
CP E BB
Compare with sectors per track.
6A3C
If Carry (more sectors to place), JUMP to 6A28H.

[ADJUST INTERLEAVE TABLE] - Post-process table for proper ordering.

6A3E
LD HL,6A02H 21 02 6A
Load HL with 6A02H - starting sector storage.
6A41
LD A,(HL) 7E
Load starting sector.
6A42
ADD A,C 81
Add current position C.
6A43
LD (HL),A 77
Store adjusted value.
6A44
POP DE D1
Restore DE from stack.
6A45
DEC D 15
Decrement D (rotation counter).
6A46
If Z FLAG (done rotating), JUMP to 6A58H.
6A48
LD C,E 4B
Load C with E (sectors per track).
6A49
PUSH DE D5
Save DE to stack.
6A4A
LD HL,6484H 21 84 64
Load HL with 6484H (one before table start).
6A4D
ADD HL,BC 09
Add BC to get end of table.
6A4E
LD D,H 54
Copy HL to DE for LDDR destination.
6A4F
LD E,L 5D
DE = end of table.
6A50
DEC BC 0B
Decrement BC (bytes to move).
6A51
LD A,(HL) 7E
Load last entry value.
6A52
DEC HL 2B
Move source back one position.
6A53
LDDR ED B8
Block copy downward (rotate table right).
6A55
LD (DE),A 12
Store saved last entry at first position.
6A56
JUMP to 6A44H to continue rotation.

6A58H - Adjust Sector Numbers for Base

Adjusts sector numbers in the interleave table if the disk format uses 1-based sector numbering (some formats start sectors at 1 instead of 0).

6A58
LD A,(4311H) 3A 11 43
Load A with system flags from 4311H.
6A5B
BIT 4,A CB 67
Test bit 4 - 1-based sector numbering flag.
6A5D
If Z FLAG (0-based), JUMP to 6A67H (no adjustment needed).
6A5F
LD B,E 43
Load B with E (sectors per track) as counter.
6A60
LD HL,6485H 21 85 64
Load HL with 6485H - interleave table address.
6A63
INC (HL) 34
[INCREMENT LOOP] Increment table entry (add 1 to sector number).
6A64
INC HL 23
Advance to next entry.
6A65
Decrement B, if NZ FLAG, JUMP to 6A63H.

6A67H - Format Track Main Entry

This is the main entry point for formatting a single track. It sets up the FDC registers, positions the head, and initiates the WRITE TRACK command. The track formatting writes ID fields, data fields, gaps, and sync patterns in the proper sequence.

6A67
LD A,0AH 3E 0A
Load A with 10 (0AH) - retry counter for format operation.
6A69
LD (6C95H),A 32 95 6C
Store retry count to 6C95H.
6A6C
CALL 4773H - Select drive and check ready status.
6A6F
RET NZ C0
If NZ FLAG (drive error), RETURN.
6A70
CALL 5733H - Seek to track (track number in FDC track register).
6A73
LD HL,4309H 21 09 43
Load HL with 4309H - FDC control flags address.
6A76
LD B,(IY+91H) FD 46 91
Load B with density/side flags from (IY+91H).
6A79
LD A,B 78
Copy flags to A.
6A7A
AND 40H E6 40
Mask to isolate double-density bit (bit 6).
6A7C
If Z FLAG (single density), JUMP to 6A87H.
6A7E
LD A,(6C63H) 3A 63 6C
Load A with side flag from 6C63H.
6A81
AND 01HAND 00000001 E6 01
Mask to bit 0 (side select).
6A83
If Z FLAG (side 0), JUMP to 6A87H.
6A85
SET 3,(HL) CB DE
Set bit 3 of (HL) - enable side 1 select in control byte.
6A87
LD (6AFCH),A 32 FC 6A
Store side/density flags to 6AFCH (self-mod target).
6A8A
CALL 4767H - Wait for drive motor and head settle.
6A8D
CALL 4750H - Wait for index pulse (start of track).
6A90
LD DE,37EFH 11 EF 37
Load DE with 37EFH - FDC Data Register address.
6A93
LD HL,37ECH 21 EC 37
Load HL with 37ECH - FDC Command/Status Register address.
6A96
LD BC,6485H 01 85 64
Load BC with 6485H - sector interleave table address.
6A99
PUSH HL E5
Save FDC status register address.
6A9A
PUSH DE D5
Save FDC data register address.
6A9B
EXX D9
Switch to alternate registers.
6A9C
CALL 6CA4H - Get sectors per track into E.
6A9F
LD C,E 4B
Copy sectors per track to C (sector counter).
6AA0
POP DE D1
Restore DE (37EFH - FDC data register).
6AA1
POP HL E1
Restore HL (37ECH - FDC status register).
6AA2
DI F3
Disable interrupts - critical timing section begins.
6AA3
CALL 47E3H - Wait for FDC ready.
6AA6
LD (HL),F4H 36 F4
Write F4H to FDC - WRITE TRACK command.
WD 1771 FDC Command Code: F4H (11110100)
Bit 7Bit 6Bit 5Bit 4Bit 3Bit 2Bit 1Bit 0Function
11110100Command=Write Track (Format)
6AA8
CALL 47E3H - Wait for FDC to accept command.
6AAB
LD A,01H 3E 01
Load A with 1 - initial DRQ check value.
6AAD
EX AF,AF' 08
Save A to alternate AF (used for status checking in timing loops).
6AAE
INC C 0C
Increment sector counter (adjust for loop logic).
6AAF
JUMP to 6B82H - enter main format loop at gap writing section.

6AB2H - Format Track: Write Sector ID Field

This section writes the sector ID field during formatting. The timing is critical - the code uses EX AF,AF' to quickly switch between checking FDC status (DRQ bit) and writing data bytes. The pattern: check status, wait for DRQ, switch registers, write byte, repeat.

6AB2
EX AF,AF' 08
[WRITE ID SYNC] Switch to alternate A (status check value).
6AB3
CP (HL) BE
Compare A with FDC status register - wait for DRQ.
6AB4
If Z FLAG (DRQ not set), loop waiting.
6AB6
EX AF,AF' 08
Switch back to primary A (data byte).
6AB7
LD (DE),A 12
Write byte to FDC data register.
6AB8
EX AF,AF' 08
[WRITE SYNC BYTES LOOP] Switch to status check.
6AB9
CP (HL) BE
Wait for DRQ.
6ABA
If Z FLAG, keep waiting.
6ABC
EX AF,AF' 08
Switch to data byte.
6ABD
LD (DE),A 12
Write sync byte to FDC.
6ABE
Decrement B, if NZ FLAG, continue writing sync bytes.
6AC0
XOR A AF
Clear A to 00H (gap byte value).
6AC1
EX AF,AF' 08
Switch to status check.
6AC2
CP (HL) BE
Wait for DRQ.
6AC3
If Z FLAG, keep waiting.
6AC5
EX AF,AF' 08
Switch to data (00H).
6AC6
LD (DE),A 12
Write gap byte.
6AC7
LD B,01H 06 01
Load B with count. Self-mod target at 6AC8H - patched with timing value.
6AC9
EX AF,AF' 08
[WRITE GAP BYTES] Status check.
6ACA
CP (HL) BE
Wait for DRQ.
6ACB
If Z FLAG, keep waiting.
6ACD
EX AF,AF' 08
Switch to data.
6ACE
LD (DE),A 12
Write gap byte.
6ACF
Decrement B, continue if more gap bytes.
6AD1
EX AF,AF' 08
Status check.
6AD2
CP (HL) BE
Wait for DRQ.
6AD3
If Z FLAG, keep waiting.
6AD5
EX AF,AF' 08
Switch to data.
6AD6
LD (DE),A 12
Write byte.
6AD7
LD A,00H 3E 00
Load track number. Self-mod target at 6AD8H - patched with actual track.

[WRITE ID ADDRESS MARK AND TRACK/HEAD/SECTOR]

6AD9
EX AF,AF' 08
Status check.
6ADA
CP (HL) BE
Wait for DRQ.
6ADB
If Z FLAG, keep waiting.
6ADD
EX AF,AF' 08
Switch to data (track number).
6ADE
LD (DE),A 12
Write track number to ID field.
6ADF
EX AF,AF' 08
Status check.
6AE0
CP (HL) BE
Wait for DRQ.
6AE1
If Z FLAG, keep waiting.
6AE3
EX AF,AF' 08
Switch to data.
6AE4
LD (DE),A 12
Write track number again (or head number).
6AE5
EX AF,AF' 08
Status check.
6AE6
CP (HL) BE
Wait for DRQ.
6AE7
If Z FLAG, keep waiting.
6AE9
EX AF,AF' 08
Switch to data.
6AEA
LD (DE),A 12
Write byte.
6AEB
LD A,FEH 3E FE
Load A with FEH - ID Address Mark for single density.
6AED
EX AF,AF' 08
Status check.
6AEE
CP (HL) BE
Wait for DRQ.
6AEF
If Z FLAG, keep waiting.
6AF1
EX AF,AF' 08
Switch to data (FEH).
6AF2
LD (DE),A 12
Write ID Address Mark.
6AF3
LD A,00H 3E 00
Load track number. Self-mod target at 6AF4H.
6AF5
EX AF,AF' 08
Status check.
6AF6
CP (HL) BE
Wait for DRQ.
6AF7
If Z FLAG, keep waiting.
6AF9
EX AF,AF' 08
Switch to data.
6AFA
LD (DE),A 12
Write track number in ID field.
6AFB
LD A,00H 3E 00
Load head/side. Self-mod target at 6AFCH.
6AFD
EX AF,AF' 08
Status check.
6AFE
CP (HL) BE
Wait for DRQ.
6AFF
If Z FLAG, keep waiting.
6B01
EX AF,AF' 08
Switch to data.
6B02
LD (DE),A 12
Write head/side number in ID field.
6B03
EXX D9
Switch to alternate register set.
6B04
LD A,(BC) 0A
Load sector number from interleave table (BC points to table).
6B05
EX AF,AF' 08
Status check (using alternate' A).
6B06
CP (HL) BE
Wait for DRQ.
6B07
If Z FLAG, keep waiting.
6B09
EX AF,AF' 08
Switch to sector number.
6B0A
LD (DE),A 12
Write sector number to ID field.
6B0B
LD A,01H 3E 01
Load A with 1 - sector size code (256 bytes).
6B0D
EX AF,AF' 08
Status check.
6B0E
CP (HL) BE
Wait for DRQ.
6B0F
If Z FLAG, keep waiting.
6B11
EX AF,AF' 08
Switch to data.
6B12
LD (DE),A 12
Write sector size code.
6B13
LD A,F7H 3E F7
Load A with F7H - CRC generation command for FDC.
6B15
EX AF,AF' 08
Status check.
6B16
CP (HL) BE
Wait for DRQ.
6B17
If Z FLAG, keep waiting.
6B19
EX AF,AF' 08
Switch to data.
6B1A
LD (DE),A 12
Write F7H - FDC generates CRC bytes.
6B1B
LD A,FFH 3E FF
Load gap byte. Self-mod target at 6B1CH.
6B1D
EX AF,AF' 08
Status check.
6B1E
CP (HL) BE
Wait for DRQ.
6B1F
If Z FLAG, keep waiting.
6B21
EX AF,AF' 08
Switch to data.
6B22
LD (DE),A 12
Write gap byte after ID CRC.
6B23
INC BC 03
Advance interleave table pointer.
6B24
EXX D9
Switch back to primary registers.
6B25
LD B,0AH 06 0A
Load gap byte count. Self-mod target at 6B26H.

6B27H - Format Track: Write Data Field

This section writes the data field for each sector - the gap before data, data address mark, 256 bytes of data (E5H fill pattern), and CRC.

6B27
EX AF,AF' 08
[WRITE GAP 2] Status check.
6B28
CP (HL) BE
Wait for DRQ.
6B29
If Z FLAG, keep waiting.
6B2B
EX AF,AF' 08
Switch to data.
6B2C
LD (DE),A 12
Write gap byte.
6B2D
EX AF,AF' 08
Status check.
6B2E
CP (HL) BE
Wait for DRQ.
6B2F
If Z FLAG, keep waiting.
6B31
EX AF,AF' 08
Switch to data.
6B32
LD (DE),A 12
Write gap byte.
6B33
Decrement B, continue gap writing.
6B35
XOR A AF
Clear A to 00H (sync bytes).
6B36
EX AF,AF' 08
Status check.
6B37
CP (HL) BE
Wait for DRQ.
6B38
If Z FLAG, keep waiting.
6B3A
EX AF,AF' 08
Switch to data (00H).
6B3B
LD (DE),A 12
Write sync byte.
6B3C
LD B,04H 06 04
Load sync byte count. Self-mod target at 6B3DH.
6B3E
EX AF,AF' 08
[WRITE DATA SYNC]
6B3F
CP (HL) BE
Wait for DRQ.
6B40
If Z FLAG, keep waiting.
6B42
EX AF,AF' 08
Switch to data.
6B43
LD (DE),A 12
Write sync byte.
6B44
Decrement B, continue sync writing.
6B46
EX AF,AF' 08
Status check.
6B47
CP (HL) BE
Wait for DRQ.
6B48
If Z FLAG, keep waiting.
6B4A
EX AF,AF' 08
Switch to data.
6B4B
LD (DE),A 12
Write byte.
6B4C
LD A,00H 3E 00
Load data mark. Self-mod target at 6B4DH.
6B4E
EX AF,AF' 08
Status check.
6B4F
CP (HL) BE
Wait for DRQ.
6B50
If Z FLAG, keep waiting.
6B52
EX AF,AF' 08
Switch to data.
6B53
LD (DE),A 12
Write byte.
6B54
EX AF,AF' 08
Status check.
6B55
CP (HL) BE
Wait for DRQ.
6B56
If Z FLAG, keep waiting.
6B58
EX AF,AF' 08
Switch to data.
6B59
LD (DE),A 12
Write byte.
6B5A
EX AF,AF' 08
Status check.
6B5B
CP (HL) BE
Wait for DRQ.
6B5C
If Z FLAG, keep waiting.
6B5E
EX AF,AF' 08
Switch to data.
6B5F
LD (DE),A 12
Write byte.
6B60
LD B,80H 06 80
Load B with 128 (80H) - half of 256-byte sector.

[WRITE 256 DATA BYTES] - Write sector data (E5H fill pattern, 256 bytes total).

6B62
EX AF,AF' 08
Status check.
6B63
CP (HL) BE
Wait for DRQ.
6B64
If Z FLAG, keep waiting.
6B66
EX DE,HL EB
Swap DE/HL (now HL=data reg, DE=status reg).
6B67
LD (HL),FBH 36 FB
Write FBH - Data Address Mark.
6B69
EX DE,HL EB
Swap back.
6B6A
CP (HL) BE
Wait for DRQ.
6B6B
If Z FLAG, keep waiting.
6B6D
EX DE,HL EB
Swap DE/HL.
6B6E
LD (HL),E5H 36 E5
Write E5H - data fill byte. Self-mod target at 6B6FH.
6B70
EX DE,HL EB
Swap back.
6B71
CP (HL) BE
Wait for DRQ.
6B72
If Z FLAG, keep waiting.
6B74
EX DE,HL EB
Swap DE/HL.
6B75
LD (HL),E5H 36 E5
Write another E5H. Self-mod target at 6B76H.
6B77
EX DE,HL EB
Swap back.
6B78
Decrement B, continue writing data bytes (128 iterations × 2 bytes = 256).
6B7A
CP (HL) BE
Wait for DRQ.
6B7B
If Z FLAG, keep waiting.
6B7D
EX DE,HL EB
Swap DE/HL.
6B7E
LD (HL),F7H 36 F7
Write F7H - CRC generation command.
6B80
EX DE,HL EB
Swap back.
6B81
EX AF,AF' 08
Switch to data register A.

6B82H - Format Track: Write Inter-Sector Gap

Writes the gap between sectors (Gap 3). After completing all sectors, the routine continues filling the track with gap bytes until the next index pulse.

6B82
LD A,FFH 3E FF
Load gap byte FFH. Self-mod target at 6B83H.
6B84
EX AF,AF' 08
Status check.
6B85
CP (HL) BE
Wait for DRQ.
6B86
If Z FLAG, keep waiting.
6B88
EX AF,AF' 08
Switch to data.
6B89
LD (DE),A 12
Write gap byte.
6B8A
LD B,0AH 06 0A
Load gap count. Self-mod target at 6B8BH.
6B8C
DEC C 0D
Decrement sector counter C.
6B8D
If NZ FLAG (more sectors), JUMP to 6AB2H to write next sector.

[FILL REMAINDER OF TRACK] - All sectors written, fill to index pulse.

6B90
LD BC,0001H 01 01 00
Initialize byte counter BC = 1.
6B93
EX AF,AF' 08
[FILL LOOP] Status check.
6B94
CP (HL) BE
Wait for DRQ.
6B95
If Z FLAG, keep waiting.
6B97
EX AF,AF' 08
Switch to data.
6B98
LD (DE),A 12
Write gap byte.
6B99
INC BC 03
Increment byte counter.
6B9A
NOP 00
Timing padding.
6B9B
BIT 1,(HL) CB 4E
Test DRQ bit of FDC status.
6B9D
If NZ FLAG (DRQ set), write another byte.
6BA0
BIT 1,(HL) CB 4E
Test DRQ again.
6BA2
If NZ FLAG, write another byte.
6BA5
BIT 1,(HL) CB 4E
Test DRQ third time.
6BA7
If NZ FLAG, write another byte.
6BA9
BIT 0,(HL) CB 46
Test BUSY bit of FDC status.
6BAB
If Z FLAG (not busy = format complete), JUMP to 6BB5H.
6BAD
BIT 1,(HL) CB 4E
Test DRQ while still busy.
6BAF
If NZ FLAG (DRQ set), write byte.
6BB1
BIT 7,(HL) CB 7E
Test NOT READY bit.
6BB3
If Z FLAG (drive ready), continue polling.

[FORMAT COMPLETE] - Track formatting finished.

6BB5
LD A,(HL) 7E
Read final FDC status.
6BB6
LD (HL),D0H 36 D0
Write D0H - FORCE INTERRUPT to terminate operation.

6BB8H - Format Track Verification

After writing the track, this section verifies the format by reading back sectors and checking for errors. It handles retry logic and reports format failures.

6BB8
LD H,B 60
Copy B to H (save counter high byte).
6BB9
LD L,C 69
Copy C to L - HL now contains byte count written.
6BBA
LD B,A 47
Save FDC status in B.
6BBB
CALL 4767H - Wait for motor/head settle.
6BBE
LD A,(5996H) 3A 96 59
Load operation flags from 5996H.
6BC1
BIT 7,A CB 7F
Test bit 7 - skip verify flag.
6BC3
If NZ FLAG (skip verify), JUMP to 6C5CH.
6BC6
LD A,B 78
Restore FDC status to A.
6BC7
AND FCH E6 FC
Mask to isolate error bits (ignore BUSY and DRQ).
6BC9
If NZ FLAG (format error), JUMP to 6C89H error handler.
6BCC
LD BC,0000H 01 00 00
Load expected byte count. Self-mod target at 6BCDH.
6BCF
OR A B7
Clear Carry flag.
6BD0
SBC HL,BC ED 42
Subtract expected from actual byte count.
6BD2
If Carry (too few bytes), JUMP to 6C7DH - "MOTOR FAST" error.
6BD5
LD BC,007DH 01 7D 00
Load tolerance value. Self-mod target at 6BD6H.
6BD8
OR A B7
Clear Carry flag.
6BD9
SBC HL,BC ED 42
Check if within tolerance.
6BDB
If NC FLAG (too many bytes), JUMP to 6C82H - "MOTOR SLOW" error.

[VERIFY FORMAT BY READING SECTORS]

6BDE
LD A,88H 3E 88
Load 88H - READ SECTOR command for verification.
6BE0
LD (46C4H),A 32 C4 46
Store command to 46C4H for sector read routine.
6BE3
LD HL,(4649H) 2A 49 46
Load current buffer pointer from 4649H.
6BE6
LD (46FCH),HL 22 FC 46
Store to 46FCH for read operation.
6BE9
LD HL,6485H 21 85 64
Load HL with 6485H - interleave table address.
6BEC
CALL 6CA4H - Get sectors per track.
6BEF
INC HL 23
[VERIFY LOOP] Advance to next sector in table.
6BF0
LD A,(HL) 7E
Load sector number from interleave table.
6BF1
LD (37EEH),A 32 EE 37
Write sector number to FDC Sector Register.
6BF4
LD A,(37EDH) 3A ED 37
Read current track from FDC Track Register.
6BF7
PUSH HL E5
Save interleave table pointer.
6BF8
LD HL,471AH 21 1A 47
Load HL with 471AH - routine address to patch.
6BFB
LD D,(HL) 56
Save original byte.
6BFC
PUSH DE D5
Save original byte and track.
6BFD
PUSH HL E5
Save patch address.
6BFE
LD (HL),C9H 36 C9
Patch with RET instruction (skip normal processing).
6C00
PUSH AF F5
Save track number.
6C01
LD A,(6AF4H) 3A F4 6A
Load side/track info from 6AF4H.
6C04
LD (37EDH),A 32 ED 37
Write to FDC Track Register.
6C07
LD BC,0000H 01 00 00
Clear BC for read operation.
6C0A
CALL 46BDH - Read sector for verification.
6C0D
LD B,A 47
Save read status in B.
6C0E
POP AF F1
Restore track number.
6C0F
LD (37EDH),A 32 ED 37
Restore FDC Track Register.
6C12
POP HL E1
Restore patch address.
6C13
POP DE D1
Restore original byte.
6C14
LD (HL),D 72
Restore original instruction.
6C15
POP HL E1
Restore interleave table pointer.
6C16
LD A,B 78
Load read status to A.
6C17
AND 9CH E6 9C
Mask to isolate significant error bits.
6C19
If Z FLAG (no errors), JUMP to 6C51H to verify next sector.

[VERIFY ERROR - RETRY]

6C1B
LD HL,6C95H 21 95 6C
Load HL with 6C95H - retry counter address.
6C1E
DEC (HL) 35
Decrement retry counter.
6C1F
If NZ FLAG (retries remaining), JUMP to 6A6CH to reformat track.

[FORMAT FAILED - ALL RETRIES EXHAUSTED]

6C22
EI FB
Enable interrupts.
6C23
LD HL,6EABH 21 AB 6E
Load HL with 6EABH - "FRONT" message address.
6C26
LD A,(6C63H) 3A 63 6C
Load side flag from 6C63H.
6C29
OR A B7
Test if side 0.
6C2A
If Z FLAG (side 0), JUMP to 6C2FH.
6C2C
LD HL,6EB0H 21 B0 6E
Load HL with 6EB0H - " BACK" message address.
6C2F
LD DE,6E96H 11 96 6E
Load DE with 6E96H - destination for side text.
6C32
LD BC,0005H 01 05 00
Load BC with 5 - length of side text.
6C35
LDIR ED B0
Copy side text to message buffer.
6C37
LD HL,6E89H 21 89 6E
Load HL with 6E89H - "CAN'T FORMAT" message.
6C3A
CALL 4467H (SYS0) - Display error message.
6C3D
LD A,(6AF4H) 3A F4 6A
Load track number from 6AF4H.
6C40
LD E,A 5F
Copy to E.
6C41
LD D,00H 16 00
Clear D (DE = track number).
6C43
CALL 5909H - Display track number.
6C46
CALL 5881H - Output carriage return.
6C49
CALL 58C8H - Wait for user keypress.
6C4C
If NZ FLAG (user wants retry), JUMP to 6A67H.
6C4F
JUMP to 6C5CH - continue to next track.

[CONTINUE VERIFICATION]

6C51
DEC E 1D
Decrement sector counter E.
6C52
LD A,01H 3E 01
Load A with 1 for comparison.
6C54
CP E BB
Compare with remaining sectors.
6C55
If Carry (more sectors), JUMP to 6BEFH to verify next.
6C57
LD A,(6485H) 3A 85 64
Load first sector from interleave table.
6C5A
If Z FLAG (last sector), verify sector 0.

6C5CH - Format Next Side/Track

After completing one side of a track, this section handles double-sided disks by formatting the back side, then advances to the next track.

6C5C
BIT 6,(IY+91H) FD CB 91 76
Test bit 6 of (IY+91H) - double-sided flag.
6C60
If Z FLAG (single-sided), JUMP to 6C6FH.
6C62
LD A,00H 3E 00
Load current side. Self-mod target at 6C63H.
6C64
XOR 01H EE 01
Toggle side bit (0→1 or 1→0).
6C66
LD (6C63H),A 32 63 6C
Store new side value.
6C69
If Z FLAG (back to side 0), JUMP to 6C6FH - advance track.
6C6B
XOR A AF
Clear A.
6C6C
JUMP to 6A01H - format side 1 of same track.

[ADVANCE TO NEXT TRACK]

6C6F
LD HL,6AF4H 21 F4 6A
Load HL with 6AF4H - track number storage.
6C72
INC (HL) 34
Increment track number.
6C73
LD A,(HL) 7E
Load new track number.
6C74
CP 23H FE 23
Compare with 35 (23H). Self-mod target at 6C75H - patched with max track.
6C76
RET Z C8
If Z FLAG (all tracks done), RETURN - format complete.
6C77
CALL 6CAFH - Motor delay between tracks.
6C7A
JUMP to 69FFH - format next track.

6C7DH - Motor Speed Errors

Error handlers for motor speed problems detected during format.

6C7D
LD HL,6D6CH 21 6C 6D
Load HL with 6D6CH - "MOTOR FAST" message address.
6C80
JUMP to 6C85H to set error code.
6C82
LD HL,6D77H 21 77 6D
Load HL with 6D77H - "MOTOR SLOW" message address.
6C85
LD B,FFH 06 FF
Load B with FFH - fatal error code.
6C87
JUMP to 6C94H to process error.

6C89H - FDC Error Handler

Handles FDC errors during format by analyzing the status bits and determining retry behavior.

6C89
LD B,11H 06 11
Initialize error bit counter.
6C8B
DEC B 05
[FIND ERROR BIT] Decrement counter.
6C8C
RLCA 07
Rotate A left to test next bit.
6C8D
If NC FLAG (bit not set), continue searching.
6C8F
LD A,B 78
Load error bit number to A.
6C90
CP 0FH FE 0F
Compare with 15 (write protect error).
6C92
If Z FLAG (write protected), JUMP to 6CA2H - fatal error.
6C94
LD A,00H 3E 00
Load retry count. Self-mod target at 6C95H.
6C96
DEC A 3D
Decrement retry counter.
6C97
LD (6C95H),A 32 95 6C
Store updated count.
6C9A
If NZ FLAG (retries remaining), JUMP to 6A6CH to retry.
6C9D
LD A,B 78
Load error code to A.
6C9E
CP 0BH FE 0B
Compare with specific error.
6CA0
If Z FLAG, JUMP to 6C22H - display error.
6CA2
OR A B7
Set flags based on A (error code in A).
6CA3
RET C9
RETURN with error code in A.

6CA4H - Get Sectors Per Track

Utility routine to get the sectors per track value, adjusting for double-sided disks.

6CA4
LD E,(IY+8EH) FD 5E 8E
Load E with sectors per track from (IY+8EH).
6CA7
BIT 6,(IY+91H) FD CB 91 76
Test bit 6 - double-sided flag.
6CAB
RET Z C8
If Z FLAG (single-sided), RETURN with E unchanged.
6CAC
SRL E CB 3B
Shift E right (divide by 2 for double-sided).
6CAE
RET C9
RETURN with adjusted sector count.

6CAFH - Motor Step Delay

Provides timing delay for drive motor stepping between tracks.

6CAF
LD A,(4311H) 3A 11 43
Load system flags from 4311H.
6CB2
BIT 2,A CB 57
Test bit 2 - extra delay needed flag.
6CB4
If NZ FLAG, CALL 6CB7H to add extra delay (recursive).
6CB7
LD BC,0100H 01 00 01
Load delay counter.
6CBA
CALL 4CEDH (SYS0) - Delay loop.
6CBD
LD C,58H 0E 58
Load C with 58H (88) - step rate command.
6CBF
JUMP to 4747H - Execute step command.

6CC2H - Format Timing Parameter Tables

These tables contain CPU speed-dependent timing parameters for the format routine. Each 26-byte (1AH) block contains values for a different CPU speed: 1.77MHz, 2.03MHz, and 4MHz. The values are copied to self-modifying code locations at runtime.

6CC2
DEFB FFH, 00H, E5H, E5H, 09H, 01H, 09H, 01H FF 00 E5 E5 09 01 09 01
Table 1 (1.77MHz) - Timing bytes 0-7.
6CCA
DEFB 2CH, 01H, ECH, 0BH, 0BH, 00H 2C 01 EC 0B 0B 00
Timing bytes 8-13.
6CD0
DEFB 3EH, 00H, 02H, 02H, 00H, 00H 3E 00 02 02 00 00
Timing bytes 14-19.
6CD6
DEFB 00H, 00H, 00H, 00H, 00H, 00H 00 00 00 00 00 00
Timing bytes 20-25 (padding).
6CDC
DEFB FFH, 00H, E5H, E5H, 08H, 01H, 09H, 01H FF 00 E5 E5 08 01 09 01
Table 2 (2.03MHz) - Timing bytes 0-7.
6CE4
DEFB 2BH, 01H, E6H, 13H, 0AH, 00H 2B 01 E6 13 0A 00
Timing bytes 8-13.
6CEA
DEFB 68H, 00H, 04H, 03H, 00H, 00H 68 00 04 03 00 00
Timing bytes 14-19.
6CF0
DEFB 00H, 00H, 00H, 00H, 00H, 00H 00 00 00 00 00 00
Timing bytes 20-25 (padding).
6CF6
DEFB 4EH, F5H, E5H, E5H, 0EH, 06H, 14H, 0AH 4E F5 E5 E5 0E 06 14 0A
Table 3 (4MHz) - Timing bytes 0-7.
6CFE
DEFB 4AH, 01H, DDH, 17H, 10H, 00H 4A 01 DD 17 10 00
Timing bytes 8-13.
6D04
DEFB 7DH, 00H, 04H, 03H, 00H, 00H 7D 00 04 03 00 00
Timing bytes 14-19.
6D0A
DEFB 00H, 00H, 00H, 00H, 00H, 00H 00 00 00 00 00 00
Timing bytes 20-25 (padding).
6D10
DEFB 4EH, F5H, E5H, E5H, 13H, 0AH, 14H, 0AH 4E F5 E5 E5 13 0A 14 0A
Table 4 (alternate 4MHz) - Timing bytes 0-7.
6D18
DEFB 53H, 01H, BAH, 27H, 26H, 00H 53 01 BA 27 26 00
Timing bytes 8-13.
6D1E
DEFB D0H, 00H, 05H, 04H, 00H, 00H D0 00 05 04 00 00
Timing bytes 14-19.
6D24
DEFS 3AH (58 bytes of 00H)
Reserved/unused space (filled with 00H).

6D5EH - Message Strings

ASCII message strings used by the FORMAT and COPY commands. Strings are terminated with 0DH (carriage return) or 03H (ETX). Control codes: 1CH=home cursor, 1FH=cursor down.

6D5E
DEFB 1CH, 1FH, 03H 1C 1F 03
Cursor control sequence.
6D61
DEFM 'FORMATTING' 46 4F 52 4D 41 54 54 49 4E 47
String: "FORMATTING"
6D6B
DEFB 0DH 0D
Carriage return terminator.
6D6C
DEFM 'MOTOR FAST' 4D 4F 54 4F 52 20 46 41 53 54
String: "MOTOR FAST"
6D76
DEFB 0DH 0D
Carriage return terminator.
6D77
DEFM 'MOTOR SLOW' 4D 4F 54 4F 52 20 53 4C 4F 57
String: "MOTOR SLOW"
6D81
DEFB 0DH 0D
Carriage return terminator.
6D82
DEFM 'DISKETTE HAS DATA' 44 49 53 4B 45 54 54 45 20 48 41 53 20 44 41 54 41
String: "DISKETTE HAS DATA"
6D93
DEFB 0DH 0D
Carriage return terminator.
6D94
DEFM 'UNREADABLE DISKETTE' 55 4E 52 45 41 44 41 42 4C 45 20 44 49 53 4B 45 54 54 45
String: "UNREADABLE DISKETTE"
6DA7
DEFB 0DH 0D
Carriage return terminator.
6DA8
DEFM 'DISKETTE OLD NAME/DATE = ' 44 49 53 4B 45 54 54 45 20 ...
String: "DISKETTE OLD NAME/DATE = "
6DC1
DEFB 03H 03
ETX terminator.
6DC2
DEFM 'DISKETTE NAME MISMATCH' 44 49 53 4B 45 54 54 45 20 4E 41 4D 45 ...
String: "DISKETTE NAME MISMATCH"
6DD9
DEFB 0AH, 0DH 0A 0D
Line feed + carriage return.
6DDA
DEFM 'INITIALIZING SYSTEM DATA' 49 4E 49 54 49 41 4C 49 5A 49 4E 47 ...
String: "INITIALIZING SYSTEM DATA"
6DF2
DEFB 0DH 0D
Carriage return terminator.
6DF3
DEFM 'STARTING DISKETTE FORMAT' 53 54 41 52 54 49 4E 47 ...
String: "STARTING DISKETTE FORMAT"
6E0BH
DEFB 0DH 0D
Carriage return terminator.
6E0C
DEFM 'STARTING DISKETTE COPY' 53 54 41 52 54 49 4E 47 ...
String: "STARTING DISKETTE COPY"
6E22
DEFB 0DH 0D
Carriage return terminator.
6E23
DEFM 'ARE SYSTEM AND THE SAME DISKETTE?' 41 52 45 20 53 59 53 54 45 4D ...
String: "ARE SYSTEM AND THE SAME DISKETTE?"
6E45
DEFB 03H 03
ETX terminator.
6E46
DEFM 'FORMAT DISKETTE?' 46 4F 52 4D 41 54 ...
String: "FORMAT DISKETTE?"
6E56
DEFB 03H 03
ETX terminator.
6E57
DEFM 'EITHER BAD PARAMETER OR CONFLICT WITH PDRIVE DATA' 45 49 54 48 45 52 ...
String: "EITHER BAD PARAMETER OR CONFLICT WITH PDRIVE DATA"
6E88
DEFB 0DH 0D
Carriage return terminator.
6E89
DEFM "CAN'T FORMAT" 43 41 4E 27 54 20 46 4F 52 4D 41 54
String: "CAN'T FORMAT"
6E95
DEFM ' FRONT SIDE OF TRACK ' 20 46 52 4F 4E 54 ...
String: " FRONT SIDE OF TRACK "
6EAAH
DEFB 03H 03
ETX terminator.
6EAB
DEFM 'FRONT' 46 52 4F 4E 54
String: "FRONT"
6EB0
DEFM ' BACK' 20 42 41 43 4B
String: " BACK"

6EB5H - Skip Whitespace and Check End

Utility routine to skip whitespace in command line input and check for end of line.

6EB5
CALL 6EC0H - Check for end of line.
6EB8
RET Z C8
If Z FLAG (end of line), RETURN.
6EB9
CALL 4CD9H (SYS0) - Skip whitespace.
6EBC
RET C D8
If Carry FLAG (found non-whitespace), RETURN.
6EBD
RET Z C8
If Z FLAG (end of line), RETURN.
6EBE
DEC HL 2B
Back up pointer.
6EBF
RET C9
RETURN.

6EC0H - Check End of Line

Checks if current character is end of line (0DH = carriage return).

6EC0
LD A,(HL) 7E
Load character at current position.
6EC1
CP 0DH FE 0D
Compare with 0DH (carriage return).
6EC3
RET Z C8
If Z FLAG (end of line), RETURN.
6EC4
CALL 4CD9H (SYS0) - Check character type.
6EC7
RET NC D0
If NC FLAG (delimiter), RETURN.
6EC8
JUMP to 521AH - syntax error.

6ECBH - Parse Drive Number

Parses a drive number from the command line (0-7).

6ECB
LD A,(HL) 7E
Load current character.
6ECC
CP 3AH FE 3A
Compare with ':' (colon).
6ECE
If NZ FLAG (not colon), JUMP to 6ED1H.
6ED0
INC HL 23
Skip the colon.
6ED1
LD A,(HL) 7E
Load drive digit.
6ED2
SUB 30H D6 30
Convert ASCII to number (subtract '0').
6ED4
CP 0AH FE 0A
Compare with 10.
6ED6
RET NC D0
If NC FLAG (not a digit), RETURN with error.
6ED7
CALL 6EE7H - Validate drive number.
6EDA
CALL 4776H - Select drive.
6EDD
If NZ FLAG (drive error), JUMP to 6EC8H.
6EDF
LD A,E 7B
Load drive number to A.
6EE0
SCF 37
Set Carry FLAG (success).
6EE1
RET C9
RETURN with drive number in A.

6EE7H - Validate and Parse Number

Validates a parsed number is within range and continues parsing.

6EE7
CALL 6F0FH - Parse decimal number.
6EEA
LD A,D 7A
Load high byte of result.
6EEB
OR A B7
Test if high byte is zero.
6EEC
LD A,E 7B
Load low byte to A.
6EED
RET Z C8
If Z FLAG (number < 256), RETURN success.
6EEE
JUMP to 5218H - number too large error.

6F0FH - Parse Decimal/Hex Number

Parses a decimal or hexadecimal number from input. Numbers ending in 'H' are treated as hexadecimal.

6F0F
PUSH HL E5
Save input pointer.
6F10
LD DE,6F09H 11 09 6F
Load return address for nested call.
6F13
PUSH DE D5
Push return address.
6F14
LD B,00H 06 00
Initialize flags (B=0 = decimal mode).
6F16
LD DE,0000H 11 00 00
Initialize result DE = 0.
6F19
LD A,(HL) 7E
[PARSE LOOP] Load current digit.
6F1A
SUB 30H D6 30
Convert ASCII to number.
6F1C
CP 0AH FE 0A
Compare with 10.
6F1E
If Carry (0-9), JUMP to 6F2AH to accumulate.
6F20
BIT 0,B CB 40
Test hex mode flag.
6F22
RET Z C8
If Z FLAG (decimal mode), RETURN - end of number.
6F23
SUB 11H D6 11
Adjust for hex digits A-F.
6F25
CP 06H FE 06
Compare with 6.
6F27
RET NC D0
If NC FLAG (not A-F), RETURN.
6F28
ADD 0AH C6 0A
Add 10 to get hex value (A=10, B=11, etc.).
6F2A
PUSH HL E5
[ACCUMULATE DIGIT] Save pointer.
6F2B
LD H,D 62
Copy current result to HL.
6F2C
LD L,E 6B
HL = current accumulated value.
6F2D
LD C,A 4F
Save new digit in C.
6F2E
XOR A AF
Clear A for overflow detection.
6F2F
SET 1,B CB C8
Set flag indicating digit was found.
6F31
ADD HL,HL 29
HL = HL × 2.
6F32
ADC A,A 8F
Carry overflow into A.
6F33
ADD HL,HL 29
HL = HL × 4.
6F34
ADC A,A 8F
Track overflow.
6F35
BIT 0,B CB 40
Test hex mode.
6F37
If Z FLAG (decimal), JUMP to 6F3CH.
6F39
ADD HL,HL 29
HL = HL × 8 (for hex).
6F3A
Skip decimal adjustment.
6F3C
ADD HL,DE 19
HL = HL + original (×5 for decimal).
6F3D
ADC A,A 8F
Track overflow.
6F3E
ADD HL,HL 29
HL = HL × 10 (decimal) or × 16 (hex).
6F3F
ADC A,A 8F
Track overflow.
6F40
LD E,C 59
Get new digit.
6F41
LD D,00H 16 00
DE = new digit (0-15).
6F43
ADD HL,DE 19
Add new digit to accumulated value.
6F44
ADC A,A 8F
Track overflow.
6F45
EX DE,HL EB
Result back to DE.
6F46
POP HL E1
Restore input pointer.
6F47
RET NZ C0
If NZ FLAG (overflow), RETURN with error.
6F48
INC HL 23
Advance to next character.
6F49
JUMP to 6F19H to parse next digit.

6FB8H - Validate Source/Destination Compatibility

Validates that source and destination disk parameters are compatible for copy operations.

6FB8
LD DE,598BH 11 8B 59
Load DE with 598BH - destination parameter buffer.
6FBB
LD C,03H 0E 03
Load C with 3 - parameter count.
6FBD
CALL 6EB5H - Skip whitespace.
6FC0
If NC FLAG (end of line), JUMP to 6FDEH.
6FC2
LD B,02H 06 02
[COMPARE LOOP] Compare 2 bytes at a time.
6FC4
LD A,(HL) 7E
Load source byte.
6FC5
CP 30H FE 30
Compare with '0'.
6FC7
If Carry (not digit), JUMP to 6FDBH error.
6FC9
EX DE,HL EB
Swap pointers.
6FCA
CP (HL) BE
Compare source with destination.
6FCB
If NC FLAG (mismatch), JUMP to 6FDBH error.
6FCD
LD (HL),A 77
Store source value to destination.
6FCE
EX DE,HL EB
Swap back.
6FCF
INC DE 13
Advance destination pointer.
6FD0
INC HL 23
Advance source pointer.
6FD1
Decrement B, continue if more bytes.
6FD3
DEC C 0D
Decrement parameter counter.
6FD4
RET Z C8
If Z FLAG (all parameters checked), RETURN success.
6FD5
LD A,(DE) 1A
Load next destination byte.
6FD6
CP (HL) BE
Compare with source.
6FD7
INC DE 13
Advance pointers.
6FD8
INC HL 23
Advance pointers.
6FD9
If Z FLAG (match), continue checking.
6FDB
JUMP to 5218H - parameter mismatch error.
6FDE
PUSH HL E5
Save pointer.
6FDF
EX DE,HL EB
HL = destination.
6FE0
CALL 4470H (SYS0) - Initialize destination defaults.
6FE3
POP HL E1
Restore pointer.
6FE4
RET C9
RETURN.

6FE5H - Search for File

Searches for a file matching the current filespec.

6FE5
CALL 6EC4H - Validate current filespec.
6FE8
LD D,H 54
Copy HL to DE.
6FE9
LD E,L 5D
DE = filespec pointer.
6FEA
LD BC,6FF7H 01 F7 6F
Load BC with 6FF7H - "TO" keyword address.
6FED
CALL 4CC5H (SYS0) - Compare strings.
6FF0
RET NZ C0
If NZ FLAG (not "TO"), RETURN.
6FF1
CALL 4CD9H (SYS0) - Skip whitespace after "TO".
6FF4
RET NC D0
If NC FLAG (end of line), RETURN.
6FF5
EX DE,HL EB
Swap pointers.
6FF6
RET C9
RETURN with updated pointer.

6FF7H - "TO" Keyword Constant

The "TO" keyword used for COPY command syntax (e.g., "COPY file1 TO file2").

6FF7
DEFM 'TO' 54 4F
String: "TO"
6FF9
DEFB 00H 00
Null terminator. End of SYS6/SYS file.