TRS-80 DOS - NEWDOS/80 v2.0 for the Model I - SYS6/SYS Disassembled
Page Customization
Page Index
SYS6/SYS
Other Navigation
Introduction/Summary
NEWDOS/80 v2.0 SYS6/SYS Disassembly - FORMAT, COPY and APPEND (Model I)
SYS6/SYS is the overlay that carries out the library commands FORMAT, COPY and APPEND (manual sections 2.22, 2.14 and 2.2). NEWDOS/80 has no BACKUP program: a diskette is backed up with COPY format 5 (sector by sector) or format 6 (file by file, CBF). SYS6 is far larger than the overlay area. Its 37 load records fill four address ranges, 4D00H-5185H, 5200H-6484H, 64A3H-65A7H and 65B7H-6FF9H (8,787 bytes), and its transfer address is 4D00H. SYS1 loads it with RST 28H code 28H (FORMAT), 48H (COPY) or 68H (APPEND), and 4D00H sends each code to its command.
The file on the system diskette has the mandatory zaps up to zap 085 applied (see Zaps). The page shows every byte once, in address order; bytes that are not in the file are shown as DEFS rows without a byte column.
Commands and Program Flow
- COPY (4D1EH) parses the command to decide the format. A leading drive number followed by a second drive number is a diskette COPY (formats 5 and 6); a leading drive number followed by two filespecs is format 3 or 4 (4D8BH); otherwise it is format 1 or 2 (4D98H). A $ before the first filespec says that the system diskette must be swapped in and out of drive 0. The options are parsed by 4EA7H with the keyword table at 505CH.
- Single file COPY (formats 1 to 4, 6377H): the drive of each filespec is found (6437H), the files are opened through the source FCB at 5AE5H and the destination FCB at 5B17H, and the COPY engine (5273H) copies the sectors. The destination is allocated in one piece by writing its last sector first (5360H) and is closed with the source's EOF at 54ACH.
- Diskette COPY (format 5, 6291H): the source diskette's GAT is checked (SN, SPW, USD), the destination is checked and formatted if asked (67C3H), and the COPY engine copies every sector through FCBs that address sectors of the whole diskette. Unless BDU is given, the boot sectors are replaced by SYS6's own and the destination drive's PDRIVE record goes into the system data sector (52DBH). SYS17 finishes the job at its 501CH (code moved there by zap 057; 54D4H jumps there): the destination is verified and its GAT brought up to date.
- COPY by file (format 6, 5D16H): the destination is formatted and given its system data (6643H) unless NFMT is given, the files to copy are chosen from the source directory (5D86H) with ILF, XLF, UPD, USR, /ext and CFWO, their directory entries are made on the destination (5EE4H, 60BFH) and then the COPY engine copies them one after another, opening each file by its directory entry code (DEC) through SYS2's FCB builder (56A2H).
- FORMAT (65FAH) parses dn2[=tc2],name,date,password and the options, then uses the same code as a formatting COPY: 67C3H checks the old contents and formats the tracks (6959H), and 6643H reads the diskette back and writes the boot sectors, the PDRIVE sector, the GAT, the HIT and the FDE sectors.
- APPEND (6F4BH) opens the second file, positions it to its end and copies the first file onto it byte by byte through the ROM routines at 0013H and 001BH.
Every error ends at 521AH, which puts the system diskette back in drive 0, restores the PDRIVE data changed by the command, and exits through SYS0 4409H. Disk errors during a COPY or FORMAT give the operator the choice C (cancel), R (retry) or P (proceed) (57DAH). Unless NDMW is given, holding the right arrow pauses and the up arrow cancels at any time (571BH).
Memory Use
SYS6 reuses its own memory as it goes, so several addresses have more than one use:
| Address Range | Use |
|---|---|
| 4D00H-51FFH | SYS6's command parsing code. After the options have been parsed, 4D3EH-4D8DH holds a copy of the command line (4DA6H), and SYS2, SYS3 or SYS17 is loaded into the overlay area (568BH). SYS6 then calls into that overlay directly and changes some of its operands (SYS2 4F56H and 4F5EH, SYS3 4FDBH). |
| 4200H-42FFH | Sector buffer: the GAT, HIT and directory sectors, the PDRIVE sector, and the read back buffer of the verify. |
| 5933H-5D15H | Variables, control blocks, FCBs, messages, and the patch lists and routines for a diskette with TI flag M. |
| (5D14H)-(593CH) | Sector buffers of the COPY engine, 258 bytes each, up to 6FFFH, or up to HIMEM when COPY does not run under DOS-CALL. In a COPY by file the file list and the 24-byte copies of directory entries come first. |
| 6291H-6390H | COPY setup code, then a copy of the HIT sector. |
| 6391H-6490H | COPY setup code, then a copy of the destination's GAT sector. |
| 6485H-64A2H | Not in the file: the interleave table of the track being formatted (from 6485H) and the start of the COPY by file list (6491H). |
| 64BAH-65B9H | The boot sector written to every new diskette (it runs at 4200H). 65A8H-65B6H is not in the file. |
| 6EB5H-6FB4H | Command line parsing code and APPEND, replaced by 4DF3H with the PDRIVE sector that is written to the new diskette. |
Diskette Control Blocks and Swapping
The three diskettes of a COPY or FORMAT each have a 10-byte control block: system 5942H, source 594CH, destination 5956H. It holds the drive number, a role bit (01H system, 02H source, 04H destination), the FCB address, the address of the working PDRIVE record, the address of the saved original PDRIVE record and the address of the diskette's name. 5585H switches to a diskette. 5940H holds the set of diskettes that share a drive and must be swapped, 5941H the set that is mounted now; when a diskette is needed that is not mounted, the operator is asked to mount it (PRESS "ENTER" WHEN ... DISKETTE MOUNTED ON DRIVE n).
PDRIVE Records
Sector 2 of a NEWDOS/80 system diskette (the third sector of BOOT/SYS) holds a 16-byte PDRIVE record for each of drives 0-9. SYS0 keeps the first ten bytes of the records of its drives at 4371H (10 bytes per drive; the current drive's address at 4399H, and a copy of the current drive's first eight bytes at 430AH-4311H). SYS6 works with ten-byte records in the same format: saved originals at 5999H, 59A3H and 59ADH, and the working records of the source (59B7H) and destination (59C5H), each followed by two words of its own (the total sectors and the total granules, 6710H).
| Byte | Contents |
|---|---|
| +0 | Starting lump of the directory of the diskette in the drive (the DDSL, or the value from the diskette's boot sector). |
| +1 | Number of lumps on the diskette. |
| +2 | Bits 0-1: TSR (stepping rate). Bits 2-4: interface (1 = TI flag A standard, 2 = D Radio Shack doubler, 3 = B Omikron, 4 = C Percom, 5 = E LNW). Bit 5: TI flag M (see Diskettes with TI Flag M). Bit 6: TI flag K (track 0 in the other density). Bit 7: TI flag H (head settle delay). |
| +3 | TC, the track count. |
| +4 | SPT, the sectors per track. |
| +5 | GPL, the granules per lump. |
| +6 | The byte SYS0 writes to the FDC sector register when it selects the drive (47C0H): 00H for the standard and Percom interfaces, 80H or C0H for Omikron and LNW, 80H or A0H for the Radio Shack doubler. |
| +7 | Disk I/O flags (4311H for the current drive): bit 0 double density, bit 1 tracks numbered from 1 (TI flags J or K), bit 2 double step (TI flag L), bit 4 sectors numbered from 1 (TI flag I), bit 6 double sided, bit 7 8 inch. |
| +8 | DDSL, the default starting lump of the directory. |
| +9 | DDGA, the default granules of the directory. |
Bytes 10-15 of the 16-byte record on the diskette hold the values typed in the PDRIVE command (TSR, the TI letters and the TD letter), from which SYS16 works out bytes +0 to +2, +6 and +7.
Diskettes with TI Flag M
A drive whose PDRIVE entry has TI flag M (bit 5 of byte +2, 430CH for the current drive) holds a diskette with its own directory layout. SYS6 knows such a diskette only by this flag and the density bit. When it is in double density (bit 0 of the disk I/O flags), sets of patches are exchanged with bytes of SYS0, SYS2 and SYS3 whenever that diskette is selected, and exchanged back when a diskette without TI flag M is (55FBH, patch sets at 5B57H). With the patches in, SYS0 reverses the meaning of the two data address marks, reads the directory lump from byte 1 of the boot sector, handles five 48-byte directory entries to a sector, 13 extent elements and 3-sector granules, and does not mark a written file updated in its directory entry. Some patches jump to routines in SYS6 (5C0BH).
5C96H prepares the patches for each command. Two TI flag M diskettes of different density cannot be used together. In single density the SYS0 set is left out, the SYS2 and SYS3 lists are shortened and three instructions of the COPY by file code are changed (612DH, 617FH, 61BFH). A sector by sector diskette COPY with such a diskette, and formatting a destination with TI flag M, need BDU (674DH): SYS6 does not write system data for it. A COPY by file does not copy system files to or from it (5E5EH).
Option Flags
Each option found in the table at 505CH sets one bit in 5994H-5997H.
| Bit | 5994H | 5995H | 5996H | 5997H |
|---|---|---|---|---|
| 7 | N | NDMW | SN (COPY), RWF (FORMAT) | SPDN |
| 6 | Y | CFWO | SPW | DPDN |
| 5 | DDND | NDPW | UBB | XLF |
| 4 | ODN | USD | USR | ILF |
| 3 | KDN | DFO | CBF | NFMT |
| 2 | NDN | DDSL | single file COPY | FMT |
| 1 | BDU | DDGA | /ext | PFST |
| 0 | KDD | ODPW | UPD | PFTC |
Zaps
The file has the mandatory SYS6 zaps from the official zap list applied: 015 (5C80H), 017 (4EF2H), 023 (5751H), 024 (5C8EH, 6891H), 028 (the PFST entry of the option table), 031 (5C96H), 032 (5CE4H), 044 (5784H), 047 (68ECH and the table at 6D10H), 056 (5CF2H), 057 (54D4H, 62A7H), 076 (54D7H), 079 (5324H) and 085 (6355H). The optional zaps 012 (the data pattern is E5H E5H), 013, 077 and 078 are not applied. Where later zaps moved code, the patch addresses in the zap list no longer match this file.
Variables
SYS0 Memory Used by SYS6
| Address Size | Contents |
|---|---|
| 4049H-404AH 2 bytes | HIMEM The top of memory. 4D2BH copies it to 593CH when COPY does not run under DOS-CALL. |
| 4044H-4046H 3 bytes | System Date Read by 5C72H, 5C77H, 612FH and 6133H (the year at 4044H, the month at 4046H). |
| 4200H-42FFH 256 bytes | Sector Buffer The GAT, HIT and directory sectors, the system data sector of drive 0 and the read back buffer of the verify pass (5D10H). |
| 4309H 1 byte | Drive Select Latch The value last sent to the drive select latch, used by the track writing code at 6A73H. |
| 430CH 1 byte | Current Drive's PDRIVE Flags Bit 5 is TI flag M of the drive selected now, tested at 55FBH, 5CE4H and 61F6H. |
| 4311H 1 byte | Disk I/O Flags Of the drive selected now: bit 0 double density, bit 2 double step, bit 6 double sided, bit 7 8 inch. 6959H picks the line of the format table from them. |
| 4317H 1 byte | Resident Overlay The number of the overlay in 4D00H-51FFH (04H SYS2, 05H SYS3). 4D00H clears it because SYS6's own code is there; 54C9H and 5F86H store 05H after SYS3 has cleared it. |
| 4369H 1 byte | System Flags Bit 3 is set by 4D0DH while FORMAT or COPY runs and cleared by 5238H; the key combinations D-F-G, 1-2-3 and J-K-L are ignored while it is set. |
| 436AH 1 byte | System Flags Bit 6, a DOS-CALL is active: COPY then keeps below 7000H (4D21H) and a COPY with the source and destination in the same drive ends with error 15H (4E36H). |
| 436BH 1 byte | Temporary Flags Bit 1 (538EH) stops SYS2 taking extra granules; bit 2 (5F74H) makes SYS3 leave the FCB alone when it frees space. |
| 436CH 1 byte | System Options Bit 7 (AA) and bit 1 (AR): when AA is set and AR is clear the diskette passwords are checked (62B3H, 6314H). |
| 4399H-439AH 2 bytes | PDRIVE Entry Address The address of the selected drive's 10-byte PDRIVE entry in SYS0, read by 566DH and 6690H. |
| 4480H-449FH 32 bytes | DOS FCB Holds the ILF= or XLF= filespec (4FACH) and is used to read that list file (5D30H); 448CH is the middle byte of its EOF. |
SYS6 Variables
| Address Size | Contents |
|---|---|
| 5933H-593AH 8 bytes | Powers of Ten -10000, -1000, -100 and -10 for the decimal display routine at 5909H. |
| 593BH 1 byte | SYS6 Flags Bit 7 is set by 63BDH once the drives' PDRIVE data has been saved; from then on each diskette gets its own data and the exit puts the drives' data back. |
| 593CH-593DH 2 bytes | Top of the Buffers 6FFFH as loaded, or HIMEM (4D2EH): the highest address COPY may use. |
| 593EH-593FH 2 bytes | Current Control Block 5942H, 594CH or 5956H, stored by 5585H. |
| 5940H 1 byte | Swap Set Bit 0 system, bit 1 source, bit 2 destination: the diskettes that share a drive and must be swapped. |
| 5941H 1 byte | Mounted Set The same bits for the diskettes that are in their drives now (07H as loaded). |
| 5942H-595FH 30 bytes | Diskette Control Blocks System 5942H, source 594CH, destination 5956H (see Diskette Control Blocks). |
| 5960H-5967H 8 bytes | Password Buffer Used by the password encoder at 5025H. |
| 5968H-596FH 8 bytes | SN Name The source diskette name from SN=. |
| 5970H-5977H 8 bytes | ODN Name The old destination name from ODN=. |
| 5978H-5979H 2 bytes | SPW Code The encoded source diskette password from SPW=. |
| 597AH-597BH 2 bytes | ODPW Code The encoded old destination password from ODPW=. |
| 597CH 1 byte | Source FDE Sectors The number of FDE sectors in the source directory (5D8FH). |
| 597DH 1 byte | Destination FDE Sectors The number of FDE sectors in the destination directory (5EEDH). |
| 597EH-5993H 22 bytes | New GAT System Data Copied to GAT bytes CBH-E0H of a new diskette by 66A2H: the password code at 5981H, the name at 5983H, the date at 598BH and the AUTO byte at 5993H. |
| 5994H-5997H 4 bytes | Option Flags Set through the option table at 505CH (see Option Flags). |
| 5999H-59D2H 58 bytes | PDRIVE Records and Sizes The saved records of drive 0 (5999H), the source (59A3H) and the destination (59ADH), the working records of the source (59B7H) and destination (59C5H), and after each working record its total sectors and total granules. |
| 5AE5H-5B16H 50 bytes | Source FCB Opened by sector number on the diskette for a diskette COPY, or by filespec for a file COPY. |
| 5B17H-5B48H 50 bytes | Destination FCB Set up in the same way. |
| 5B49H-5B56H 14 bytes | System Data FCB Reads sector 2 of the system diskette in drive 0 into 4200H (6424H). |
| 5B57H-5B62H 12 bytes | TI Flag M Patch Sets Three 4-byte records for SYS0, SYS2 and SYS3 (see Diskettes with TI Flag M). |
| 5D10H-5D11H 2 bytes | Verify Buffer 4200H. |
| 5D12H-5D13H 2 bytes | File List Start The start of the COPY by file list (5D16H as loaded). |
| 5D14H-5D15H 2 bytes | File List End The end of the file list and the start of the sector buffers. |
Operands Changed at Run Time
| Address Size | Contents |
|---|---|
| 4DFAH 1 byte | Destination Drive for the PDRIVE Sector (Self-Modifying Code) The operand of the instruction at 4DF9H. The destination drive number (or the DPDN= number), stored by 639CH when the destination drive is parsed; 4DF3H uses it to pick the PDRIVE record written to the new diskette. |
| 4F85H-4F86H 2 bytes | Option Handler (Self-Modifying Code) The operand of the instruction at 4F84H. 0000H in the file. 4F7DH stores the handler address of each option from the table at 505CH before the CALL NZ. |
| 52BAH-52BBH 2 bytes | File List Entry Being Read (Self-Modifying Code) The operand of the instruction at 52B9H. 0000H in the file. In a COPY by file 56AAH stores the address of the file list entry of the file just read. |
| 52D2H 1 byte | Marker Byte (Self-Modifying Code) The operand of the instruction at 52D1H. FFH in the file. In a COPY by file 56B1H stores the destination DEC of the file being read, which is put into the entry's first byte. |
| 5314H 1 byte | Sectors Read (Self-Modifying Code) The operand of the instruction at 5313H. 00H in the file. 5316H stores the number of sectors read into the batch; the write loop counts it down at 53F5H. |
| 531AH 1 byte | Buffer Entries (Self-Modifying Code) The operand of the instruction at 5319H. 0AH in the file. 528EH stores the number of 258-byte sector buffers that fit between the file list and the top of memory. |
| 53D7H 1 byte | Skip Flag (Self-Modifying Code) The operand of the instruction at 53D6H. 00H in the file. 5368H stores 00H for each new file and 53CEH stores FFH when the file did not fit on the destination. |
| 53ECH 1 byte | Sectors Written (Self-Modifying Code) The operand of the instruction at 53EBH. 00H in the file. 533BH clears it, 53EEH counts it up, and the verify pass counts it down at 545DH. |
| 5401H-5402H 2 bytes | First Sector of the Pass (Self-Modifying Code) The operand of the instruction at 5400H. 0000H in the file. 5336H stores the destination FCB's NEXT at the start of each write pass, so that the verify pass reads the same sectors back. |
| 544FH-5450H 2 bytes | Entry Being Verified (Self-Modifying Code) The operand of the instruction at 544EH. 0000H in the file. 532FH stores the first entry of the pass and 5454H advances it. |
| 55F7H-55F8H 2 bytes | First Patch Set (Self-Modifying Code) The operand of the instruction at 55F6H. 5B57H in the file, the SYS0 patch set. 5CC3H stores 5B5BH to leave the SYS0 set out for a TI flag M diskette in single density. |
| 570EH 1 byte | Changed Directory Sector (Self-Modifying Code) The operand of the instruction at 570DH. FFH in the file (none). 5706H stores the number of a directory sector that has been changed in the buffer and 5713H puts FFH back once it is written. |
| 57EBH 1 byte | Operation for the Error Report (Self-Modifying Code) The operand of the instruction at 57EAH. 00H in the file. 80H reading the source (52A5H), 40H writing the destination (547EH), 20H verifying the destination (540EH, 578CH). |
| 586AH 1 byte | COPY by File Flag (Self-Modifying Code) The operand of the instruction at 5869H. 00H in the file. 615CH stores FFH when a COPY by file starts copying, so that error reports name the file. |
| 5F1EH-5F1FH 2 bytes | Destination Entry (Self-Modifying Code) The operand of the instruction at 5F1DH. 0000H in the file. 5F04H stores the address of the destination directory entry being filled in. |
| 6028H 1 byte | DEC Being Tested (Self-Modifying Code) The operand of the instruction at 6027H. 00H in the file. 5FE1H stores the DEC of the entry being looked at. |
| 6078H-6079H 2 bytes | Extent Destination (Self-Modifying Code) The operand of the instruction at 6077H. 0000H in the file. 5FF6H stores the address of byte 22 of the entry, where the first extent element goes. |
| 60C3H 1 byte | Files Without an Entry (Self-Modifying Code) The operand of the instruction at 60C2H. 00H in the file. 608CH stores a value that is not 0 when a file still needs a destination entry, which 60BFH then makes. |
| 612DH 1 byte | Opcode JR Z or JR (Self-Modifying Code) The instruction at 612DH. 28H (JR Z) in the file. 5CE0H stores 18H (JR) when a TI flag M diskette is in single density. |
| 617FH 1 byte | Opcode RET NZ or NOP (Self-Modifying Code) The instruction at 617FH. C0H (RET NZ) in the file. 5CD3H stores 00H (NOP) when a TI flag M diskette is in single density, which then has a normal directory. |
| 61BFH-61C0H 2 bytes | Opcode JR NZ or Two NOPs (Self-Modifying Code) The instruction at 61BFH. 20H 06H (JR NZ) in the file. 5CD8H stores two 00H bytes when a TI flag M diskette is in single density. |
| 61D8H-61D9H 2 bytes | Next 24-Byte Space (Self-Modifying Code) The operand of the instruction at 61D7H. 0000H in the file. 6190H stores the end of the file list and 61E4H advances it by 24 for each entry copied. |
| 61DBH-61DCH 2 bytes | Limit of the 24-Byte Spaces (Self-Modifying Code) The operand of the instruction at 61DAH. 0000H in the file. 5D9DH stores the top of memory less 24. |
| 63CAH 1 byte | SPDN Number (Self-Modifying Code) The operand of the instruction at 63C9H. FFH in the file (none). 500BH stores the PDRIVE number given with SPDN=. |
| 63D6H 1 byte | DPDN Number (Self-Modifying Code) The operand of the instruction at 63D5H. FFH in the file (none). 500BH stores the PDRIVE number given with DPDN=. |
| 64CAH 1 byte | Boot Sector: Drive Select Byte (Self-Modifying Code) The operand of the instruction at 64C9H. 4210H when the boot sector runs. 675FH stores byte +6 of the destination drive's PDRIVE record, the byte written to the FDC sector register when the drive is selected. |
| 651BH 1 byte | Boot Sector: Sectors on One Side (Self-Modifying Code) The operand of the instruction at 651AH. 4261H when the boot sector runs. 6791H stores the sectors per track, halved for a double sided drive. |
| 656AH 1 byte | Boot Sector: Sectors per Track (Self-Modifying Code) The operand of the instruction at 6569H. 42B0H when the boot sector runs. 678BH stores the sectors per track of both sides. |
| 656FH 1 byte | Boot Sector: First Sector Number (Self-Modifying Code) The operand of the instruction at 656EH. 42B5H when the boot sector runs. 6778H stores 01H when the drive's sectors are numbered from 1. |
| 670CH 1 byte | Directory Sectors (Self-Modifying Code) The operand of the instruction at 670BH. 0AH in the file. 66E1H stores the number of directory sectors when the HIT is made. |
| 68ABH-68ACH 2 bytes | Tracks to Format (Self-Modifying Code) The operand of the instruction at 68AAH. 0001H in the file: one track from track 0. 4FD1H stores PFTC= (the number of tracks) at 68ABH and 4FD9H stores PFST= (the first track) at 68ACH. |
| 69D6H-69D7H 2 bytes | Second Tolerance (Self-Modifying Code) The operand of the instruction at 69D5H. 0000H in the file. 69B4H stores bytes 14-15 of the format table line. |
| 69DAH-69DBH 2 bytes | Track Size (Self-Modifying Code) The operand of the instruction at 69D9H. 0000H in the file. 69A4H stores bytes 10-11 of the format table line. |
| 69F2H-69F3H 2 bytes | First Tolerance (Self-Modifying Code) The operand of the instruction at 69F1H. 0000H in the file. 69ACH stores bytes 12-13 of the format table line. |
| 6A00H 1 byte | Sector Skew (Self-Modifying Code) The operand of the instruction at 69FFH. 02H in the file. 69BAH stores byte 16 of the format table line, the skew from one track to the next. |
| 6A02H 1 byte | Previous First Sector (Self-Modifying Code) The operand of the instruction at 6A01H. 00H in the file. 69C7H clears it; 6A0AH and 6A43H store the place of the track's first sector. |
| 6A33H 1 byte | Interleave (Self-Modifying Code) The operand of the instruction at 6A32H. 02H in the file. 69BFH stores byte 17 of the format table line. |
| 6AC8H 1 byte | Zero Bytes Before the ID Field (Self-Modifying Code) The operand of the instruction at 6AC7H. 01H in the file. 698FH stores byte 5 of the format table line. |
| 6AD8H 1 byte | ID Address Mark Lead-In (Self-Modifying Code) The operand of the instruction at 6AD7H. 00H in the file. 6978H stores byte 1 of the format table line (00H single density, F5H double density, which the FDC writes as A1H). |
| 6AF4H 1 byte | Track Number (Self-Modifying Code) The operand of the instruction at 6AF3H. 00H in the file. 68C1H stores the first track and 6C72H counts it up. |
| 6AFCH 1 byte | Side Number (Self-Modifying Code) The operand of the instruction at 6AFBH. 00H in the file. 6A87H stores 00H or 01H. |
| 6B1CH 1 byte | Gap Byte After the ID Field (Self-Modifying Code) The operand of the instruction at 6B1BH. FFH in the file. 6970H stores byte 0 of the format table line (FFH single density, 4EH double density). |
| 6B26H 1 byte | Gap Between the ID and Data Fields (Self-Modifying Code) The operand of the instruction at 6B25H. 0AH in the file. 6994H stores byte 6 of the format table line. |
| 6B3DH 1 byte | Zero Bytes Before the Data Field (Self-Modifying Code) The operand of the instruction at 6B3CH. 04H in the file. 6999H stores byte 7 of the format table line. |
| 6B4DH 1 byte | Data Address Mark Lead-In (Self-Modifying Code) The operand of the instruction at 6B4CH. 00H in the file. 697CH stores byte 1 of the format table line. |
| 6B6FH 1 byte | First Data Pattern Byte (Self-Modifying Code) The operand of the instruction at 6B6EH. E5H in the file. 6980H stores byte 2 of the format table line. |
| 6B76H 1 byte | Second Data Pattern Byte (Self-Modifying Code) The operand of the instruction at 6B75H. E5H in the file. 6985H stores byte 3 of the format table line. |
| 6B83H 1 byte | Gap Byte After the Data Field (Self-Modifying Code) The operand of the instruction at 6B82H. FFH in the file. 6974H stores byte 0 of the format table line. |
| 6B8BH 1 byte | Gap Before the Next ID Field (Self-Modifying Code) The operand of the instruction at 6B8AH. 0AH in the file. 698AH stores byte 4 of the format table line. |
| 6BCDH-6BCEH 2 bytes | Fewest End Gap Bytes (Self-Modifying Code) The operand of the instruction at 6BCCH. 0000H in the file. 69F5H stores it. |
| 6BD6H-6BD7H 2 bytes | End Gap Range (Self-Modifying Code) The operand of the instruction at 6BD5H. 007DH in the file. 69FCH stores it. |
| 6C63H 1 byte | Side Just Formatted (Self-Modifying Code) The operand of the instruction at 6C62H. 00H in the file. 69CAH clears it and 6C66H changes it. |
| 6C75H 1 byte | Track to Stop At (Self-Modifying Code) The operand of the instruction at 6C74H. 23H in the file. 6959H stores the end track. |
| 6C95H 1 byte | Tries Left (Self-Modifying Code) The operand of the instruction at 6C94H. 00H in the file. 6A69H stores 10. |
Operands Changed in SYS2 and SYS3
| Address Size | Contents |
|---|---|
| 4F56H 1 byte | SYS2: DEC Operand Inside SYS2's FCB building code in the overlay area: 56B9H stores the DEC there before calling SYS2 at 4F2EH, and 5DF1H reads back the DEC that a SYS2 open left there. |
| 4F5EH 1 byte | SYS2: Record Length Operand 56C0H stores 00H there, so the file is handled in whole sectors. |
| 4FDBH 1 byte | SYS3: Mode Operand 60ADH stores 00H there, so SYS3 works in its CLOSE mode. |
Outside Routines Used
SYS0 routines: 4409H (error exit), 4420H/4424H (open), 4428H (close), 4436H (read), 4439H (write), 443CH (write with verify), 4448H (position to EOF), 4467H (display a message), 4470H (date), 45B5H (upper case), 46BDH (inside the FDC routine, from the track writing code), 4745H/4747H (FDC Type I commands), 4750H, 4767H, 4773H/4776H/476EH (select a drive), 47E3H (delay), 47ECH (wait for a diskette), 490AH/491FH/4922H/492FH/4936H/494BH (directory sectors), 4980H, 4C92H/4C94H (multiply), 4CB2H/4CB4H (divide), 4CC5H/4CD5H/4CD9H (command line), 4CEDH (delay). The routines at 5C0BH run as part of SYS0 and jump back into it (4813H, 4838H, 4947H, 48B8H, 49DDH). ROM routines: 0013H, 001BH (byte I/O), 002BH (keyboard), 0033H (display).
SYS2 (loaded by 568BH): 4E21H, 4F2EH (build an FCB from a directory entry) and 50CFH (make a directory entry). SYS3: 4E3DH (free the space past the EOF). SYS17 (loaded by 62ADH) is entered at 501CH and calls SYS6 at 5535H, 5784H, 56F9H, 5762H, 552DH and 54CBH when it finishes a diskette COPY.
Disassembly
4D00H - SYS6 Entry: Command Dispatcher
SYS0 loads SYS6 into 4D00H-6FF9H and enters it at 4D00H when SYS1 runs the FORMAT, COPY or APPEND command. Register A holds the RST 28H code from SYS1's command table (bits 5-7 = function number, bits 0-4 = 08H for SYS6): 28H = FORMAT (function 1), 48H = COPY (function 2), 68H = APPEND (function 3). Register Pair HL points to the command line just past the command name.
4D1EH - COPY: Memory Limit and First Drive Number
Entered with Register Pair HL pointing to the COPY parameters. The manual lists six formats. Formats 1 and 2 start with a filespec (2 has a leading $). Formats 3 and 4 start with a drive number and copy one file between two diskettes on that drive. Formats 5 and 6 name two drives and copy a whole diskette (sector by sector, or file by file with CBF). This part sets the memory limit and decides which kind of COPY it is.
Formats 5 and 6: COPY dn1[=tc1] [TO] dn2[=tc2] [,mm/dd/yy] [,options].
4D8BH - COPY Formats 3 and 4: One Drive, Two Diskettes
The source and destination files are on different diskettes in the same drive. 5940H is the set of diskettes that have to be swapped (bit 0 = system, bit 1 = source, bit 2 = destination) and 5941H the set that is mounted now.
4D98H - COPY Formats 1 to 4: Parse the Two Filespecs
Formats 1 and 2 arrive here from 4D36H and formats 3 and 4 from 4D97H, with the command line pointer on the stack.
The second filespec starts with :, . or /. Everything in the first filespec before the same character is copied in front of it, so COPY USERFILE/DAT:0 :1 becomes USERFILE/DAT:1.
Search Loop
Borrow Loop
4DF3H - Build the Destination PDRIVE Sector and the Swap Flags
Called from 4D85H (COPY formats 5 and 6) and 663CH (FORMAT). Reads sector 2 of the system diskette in drive 0 (the PDRIVE sector, 16 bytes for each of drives 0-9) and builds from it at 6EB5H the PDRIVE sector that will be written to the new diskette, then works out which diskettes share a drive.
The operand at 4DFAH is stored by 639CH when the destination drive is parsed.
Work out which diskettes must be swapped. Register E collects the set that shares a drive (bit 0 = system, bit 1 = source, bit 2 = destination) and Register D the set that is mounted at the start.
4E68H - Ask Whether the System Diskette Is Also the Source or Destination
Entered with Register A = 03H (source) or 05H (destination), Register B = the SPDN or DPDN bit and Register Pair HL pointing to the word SOURCE or DESTINATION. If the operator says the system diskette is that diskette, nothing has to be swapped.
4E86H - Unreferenced Code
Nothing jumps or calls to 4E86H. The four bytes would OR Register C into Register D and return.
4E8AH - Copy a Filespec from the Command Line into an FCB
Enter at 4E8AH for the destination FCB at 5B17H, or at 4E8DH with Register Pair DE pointing to any FCB (4DB3H and 6F4EH pass the source FCB at 5AE5H). Register Pair HL points to the filespec in the command line. Up to 32 characters are copied into the FCB, followed by 03H. On return Register Pair DE again points to the FCB and Register Pair HL to the separator that ended the filespec; the Z FLAG is set when the line ended there.
Copy Loop: Register Pair HL walks the command line, Register Pair DE the FCB, Register B counts the room left.
4EA7H - Parse the Options and Check Their Combinations
Entered with Register Pair HL pointing to the command line and Register B holding the command's bit in the option table's attribute bytes (08H = COPY formats 1 to 4 from 4DEBH, 20H = COPY formats 5 and 6 from 4D61H, 40H = FORMAT from 6621H). Each option is looked up at 4F1DH, which records it in the flag bytes 5994H-5997H and jumps back here. At the end of the line the combinations are checked: options that select files need CBF, options that change the diskette's name, date or password cannot be used when CBF copies onto an existing diskette, and the FORMAT DISKETTE? question decides between FMT and NFMT when neither was given.
CBF with NFMT copies files onto an existing diskette, so its name, date, password and directory cannot be changed.
4F1DH - Look Up One Option in the Option Table
Entered from 4EAAH with Register Pair HL pointing to an option word and Register B holding the command's bit. The table at 505CH is searched for a keyword that matches the start of the word. Each entry holds the keyword, an attribute byte (bit 7 always set; bit 3 allowed in COPY formats 1 to 4, bit 5 in COPY formats 5 and 6, bit 6 in FORMAT; bit 4 a handler address follows; bit 2 four exclusion bytes follow; bits 0-1 the flag byte 5994H-5997H), a flag mask, the optional exclusion bytes and the optional handler address. The option's bit is set, the exclusion bytes are checked against the options already given, the handler (if any) parses the option's value, and the search goes back to 4EA7H.
Entry Loop: Register Pair HL walks the table, Register Pair DE the option word.
The whole keyword matched (the byte that differs is the attribute byte). Register Pair DE points just past the keyword in the command line, Register Pair HL to the attribute byte.
Exclusion Loop: Register Pair DE walks 5994H-5997H, Register Pair HL the four exclusion bytes, Register C counts.
The operand at 4F85H-4F86H is 0000H in the file; 4F7DH stores the handler address there for each option.
4F8BH - Option Value Handlers
Called from 4F84H with Register Pair HL pointing to the value that follows the option keyword (and its =). Each one stores the value where the command will use it and returns with Register Pair HL past it. A missing or bad value ends the command with error 2FH at 4F49H. FORMAT also calls 4F95H and 4FE5H for its name and password parameters.
Copy Loop for the list filespec.
Copy Loop: letters and digits are copied until a different character or the third one.
5025H - Encode a Password
Entered with Register Pair HL pointing to a password in the command line. The password (up to 8 letters and digits) is copied to 5960H-5967H, padded with spaces, and turned into the 16-bit code that NEWDOS/80 keeps in the GAT and the directory. Each character is mixed in from the last to the first, and each is set back to a space as it is used, so the buffer is all spaces again at the end. On return Register Pair DE holds the code and Register Pair HL points past the password. A blank password gives 4296H.
Encoding Loop: Register Pair DE is the code, Register Pair HL steps back through the buffer, Register B counts the characters.
505CH - Option Keyword Table (Data)
Searched by 4F1DH. One row for each option: the keyword (including the = of options that take a value), the attribute byte, the flag mask, the four exclusion bytes if attribute bit 2 is set, and the handler address if attribute bit 4 is set. Attribute bits: 7 always set (marks the end of the keyword), 6 allowed in FORMAT, 5 in COPY formats 5 and 6, 3 in COPY formats 1 to 4, 4 handler follows, 2 exclusion bytes follow, 1-0 the flag byte (0 = 5994H, 1 = 5995H, 2 = 5996H, 3 = 5997H). Longer keywords come before shorter ones that start the same way (NDMW, NFMT and NDN= before N). The flag bits are: 5994H bit 7 N, 6 Y, 5 DDND, 4 ODN, 3 KDN, 2 NDN, 1 BDU, 0 KDD; 5995H bit 7 NDMW, 6 CFWO, 5 NDPW, 4 USD, 3 DFO, 2 DDSL, 1 DDGA, 0 ODPW; 5996H bit 7 SN (COPY) or RWF (FORMAT), 6 SPW, 5 UBB, 4 USR, 3 CBF, 2 single file COPY (4DE5H), 1 /ext, 0 UPD; 5997H bit 7 SPDN, 6 DPDN, 5 XLF, 4 ILF, 3 NFMT, 2 FMT, 1 PFST, 0 PFTC.
5186H - End of the Overlay Area (Not in the File)
SYS6's first load block ends at 5185H. These 122 bytes of the DOS overlay area are not loaded. From 4DA6H on the whole overlay area is reused: the command line is copied to 4D3EH, and SYS2, SYS3 or SYS17 is loaded into 4D00H-51FFH (568DH) when SYS6 needs its code.
5200H - Error Exits
Each entry loads a DOS error code into Register A and joins the common exit at 521AH. 5210H is a check used by APPEND: nothing may follow the last parameter.
521AH - Common Exit
521AH ends the command with the error code in Register A: it starts a new line and continues at 521EH, which is also entered directly (with the error code on the stack) when the cursor is already at the start of a line. 5222H is entered with Register Pair HL holding the SYS0 exit to use: 4409H displays the error in Register A, 4030H (error already displayed) and 402DH (no error) go to DOS READY. Every exit switches back to the system diskette in drive 0, puts back the drives' own PDRIVE data if COPY or FORMAT changed it, and clears the FORMAT/COPY bit of 4369H.
5240H - Display a Message and Exit
5240H reports DISKETTE/GAT OVERFLOW. 5243H is entered with Register Pair HL pointing to any message. Either way the message is shown on a new line and the command ends through 4030H (error already displayed), with the clean-up at 5222H.
524EH - COPY by File: Compact the File List and Start Copying
Reached by the JP 524EH at 615FH, in the code at 6157H whose address 60F1H pushes as a return address, once the destination directory entries have been made. The list of files to copy (three bytes for each file, from (5D12H) to (5D14H)) is moved down to 5D16H, so that all memory after it can be used for sector buffers, the source diskette is selected and the first file to copy is opened.
5273H - COPY Engine: Read a Batch of Source Sectors
Used by the diskette COPY (format 5), the COPY by file (format 6, from 5270H) and the single file COPY (formats 1 to 4, from 638FH, entering at 5279H). The free memory from (5D14H) to (593CH) is divided into entries of 258 bytes: a marker byte, a record type byte and the 256 bytes of a sector. As many source sectors as fit are read, then 5324H writes and verifies them. The marker byte is FFH, or in a COPY by file the destination DEC of the file the sector belongs to; the record type is 00H for a normal sector and 06H for a sector written with the directory mark. In a diskette COPY the boot sectors and the drive 0 record of the system data sector are replaced on the way (52DBH).
Count Loop: Register A counts how many 258-byte entries fit in Register Pair HL bytes.
Read Loop: Register Pair HL is the entry being filled; 5314H counts the sectors read.
The operand at 52BAH-52BBH is 0000H in the file; 56AAH stores the entry address there in a COPY by file.
The operand at 52D2H is FFH in the file; in a COPY by file 56B1H stores the destination DEC of the file being read there.
A diskette COPY replaces the boot sectors with SYS6's own boot sector and puts the destination drive's PDRIVE record into the system data sector, unless BDU was given.
The operand at 5314H is 00H in the file; 5316H stores the count there, and the write loop counts it down at 53F5H.
The operand at 531AH is 0AH in the file; 528EH stores the number of entries that fit there.
5324H - COPY Engine: Write the Batch
Writes the entries read by 5291H-5321H (their number is at 5314H) to the destination, then verifies them at 53FBH. In a single file COPY and a COPY by file the whole destination file is first allocated by writing its last sector (5367H), so that it gets its space in one piece. In a COPY by file a change of the marker byte means that the sector belongs to the next file: the sectors written so far are verified and the next destination file is opened.
Write Loop: Register Pair HL is the entry being written; 5314H counts the entries left.
First sector of a destination file: allocate the whole file at once by writing the sector at its end, so that DOS gives it its granules in one search.
The operand at 53D7H is 00H in the file; 5368H stores 00H for each new file and 53CEH stores FFH when the file did not fit.
The operand at 53ECH is 00H in the file; 533BH clears it, 53EEH counts up, and the verify pass counts it down at 545DH.
53FBH - COPY Engine: Verify the Sectors Just Written
Reads back every sector written in this pass into the buffer at (5D10H) (4200H) and compares the record type and the 256 data bytes with the entry it was written from. A sector that does not match is reported with the C, R or P question: R on a read error or wrong record type writes the sector again and checks it again, R on a data mismatch reads it again.
The operand at 5401H-5402H is 0000H in the file; 5336H stores the destination FCB's NEXT there at the start of the pass.
Verify Loop: 544FH holds the entry being checked, 53ECH the sectors left.
Compare Loop: Register Pair HL walks the entry's copy, Register Pair DE the sector read back, Register B counts.
The operand at 544FH-5450H is 0000H in the file; 532FH stores the first entry of the pass there and 5454H advances it. 541AH, 5434H, 5439H and 5469H come here.
546DH - Write One Sector from a Buffer Entry
Entered with Register Pair HL pointing to an entry (marker byte, record type byte, 256 data bytes) and Index Register IX to the destination FCB. The sector is written at the FCB's NEXT, with the directory mark if its record type is 06H. On a write error C, R or P is asked. Returns the Z FLAG if the sector was written, or the NZ FLAG and Register A = FFH for P. Register Pair HL is kept.
5492H - Step the Destination NEXT Back One Sector
DECrements the destination FCB's NEXT (5B21H), which the last read or write moved on. Register Pair HL is kept.
549CH - COPY Engine: End of the Source
Reached from 52C4H when the source file, the last file to copy, or the source diskette has ended. The last batch is written and verified, then each kind of COPY finishes in its own way: a COPY by file displays DONE, a single file COPY closes the destination file with the source's EOF, and a diskette COPY continues in SYS17.
54D7H - Radio Shack Doubler: Opposite Density for Track 0
Added by zap 076. Called from 68F1H while track 0 of a drive with PDRIVE TI flag K (track 0 in the other density) is formatted, with Index Register IX pointing to the drive's in-memory PDRIVE entry (from 4399H). 54D7H returns the entry's sectors per track in Register D and its drive select byte in Register C, and on a Radio Shack doubler (interface letter D) flips the select byte's density bit. 54ECH (from 6909H) puts the select byte and the disk I/O flags back from Registers C and E.
54F3H - Unreachable Remains of the Old Diskette COPY Ending
Zap 057 moved the code that ended a diskette COPY to SYS17 (501CH-508EH) and zap 076 reused the start of the space. These bytes are the rest of the old code; the same instructions are at SYS17 5051H-508AH. Nothing jumps or calls into 54F3H-552CH, so none of these rows ever runs; the comments say what each instruction would do.
552DH - Display DONE and Exit
Reached when a COPY by file or a FORMAT has finished, and from SYS17 (508CH) at the end of a diskette COPY.
5535H - Switch to a Diskette and Open Its FCB
Enter at 5535H for the destination, or at 5538H with Register Pair HL pointing to a diskette control block. A control block is 10 bytes: +0 the drive number (FFH = not used), +1 the role bit (01H system, 02H source, 04H destination), +2/+3 the FCB address, +4/+5 the address of the working PDRIVE record, +6/+7 the address of the saved original record, +8/+9 the address of the diskette's name for the mount prompt. The diskette is switched in (5585H), Index Register IX is pointed to its FCB, and the FCB is opened if it is not open yet. An open sets the control block's drive number to the drive the file was found on.
5578H - Switch to the Source, Destination or System Diskette
5578H selects the source (594CH), 557DH the destination (5956H), 5582H the system diskette (5942H) and 5585H the control block at Register Pair HL. The drive gets the PDRIVE data needed for that diskette (once 63BDH has saved the drives' own data), the diskette is asked for if another one shares its drive, and the TI flag M patches in SYS0, SYS2 and SYS3 are put in or taken out to match the diskette now in use. Register Pairs HL, DE and BC are kept.
Mount Prompt Loop: PRESS "ENTER" WHEN name DISKETTE MOUNTED ON DRIVE n, until ENTER is pressed and a diskette turns in the drive.
The operand at 55F7H-55F8H is 5B57H in the file (the SYS0 set first); 5CC3H stores 5B5BH there to leave the SYS0 set out.
Patch Set Loop. Each record at 5B57H is four bytes: the overlay the patches belong to (02H SYS0, 04H SYS2, 05H SYS3, the numbers kept at 4317H), a flag byte whose bit 5 shows that the patches are in, and the address of the patch list. The patches are exchanged with the bytes they replace, so doing it again takes them out. They must be in exactly while the current drive's PDRIVE flags have TI flag M (bit 5 of 430CH). Register Pair HL points to the record's flag byte, Register C holds its overlay number and the Z FLAG is set for SYS0.
Patch List Loop: each entry is the address to patch (2 bytes, 0000H ends the list), a byte count and the bytes. Register Pair HL walks the list, Register Pair DE the memory patched, Register B counts.
5646H - Save or Restore the PDRIVE Data of All Three Diskettes
5646H calls 5658H for the system, source and destination control blocks that have a drive, with Register B unchanged. 5658H works on the control block at Register Pair HL, with Register B saying what to do: bit 0 clear = the working record (control block +4), set = the saved original (+6); bit 1 clear = copy that record into the drive's PDRIVE entry, set = copy the drive's entry into it; bit 2 set = ignore errors. After the copy SYS0 reselects the drive so that 430AH-4311H follow the entry.
Control Block Loop: Register Pair HL is the control block, Register C counts.
568BH - Load an Overlay into the Overlay Area
568BH loads SYS2. 568DH loads the overlay whose number is in Register A (04H SYS2, 05H SYS3, the code E5H for SYS3 or F3H for SYS17; 00H = none, only switch to the system diskette). The system diskette is switched in first, so that SYS0 can read the overlay from drive 0. The overlay is called as function 7 with Register C = FFH, a sub-function that SYS2, SYS3 and SYS17 do not have: each returns at once with error 2AH, and its code stays in 4D00H-51FFH for SYS6 to call into and patch. The SYS0 dispatcher discards the RST 28H's own return address, so the overlay's RETurn goes straight back to the caller of 568DH.
5699H - Step Through the COPY-by-File List
The file list (from (5D12H) to (5D14H)) holds three bytes for each source file: flags (bit 7 entry used, bit 6 system file, bit 5 to be copied, bit 4 already in the destination directory), the source DEC and the destination DEC. 5699H moves Register Pair HL to the next entry and returns the Z FLAG at the end of the list. 56A2H moves on to the next entry marked to be copied (56A6H tests the current one first) and opens its source file; it returns the Z FLAG when there are no more. 56B9H opens a file from its DEC through SYS2's FCB building code, which 568BH has loaded into the overlay area.
Search Loop for the next entry marked to be copied.
56D4H - Unreferenced Code
Nothing jumps or calls to 56D4H. The four instructions would multiply Register A by the sectors per track at 430EH (IY-72H, with Index Register IY = 4380H from 4D00H) using the SYS0 routine at 4C94H.
56DDH - Directory Sector Helpers
Each routine ends the command at 56FEH on an error. 56DDH reads the directory entry of the file open in the FCB at Index Register IX (Register Pair HL = the entry). 56E2H points Register Pair HL to the entry of the DEC in Register A, reading its sector unless it is already in 4200H and first writing back a changed sector. 56F4H always reads the sector of the DEC in Register A. 56F9H reads the GAT (56FAH: directory sector A). 5701H writes directory sector A from 4200H. 5706H marks the sector in 4200H as changed, 570DH writes it back if one was marked and 5711H writes it back now. Directory sector 0 is the GAT, 1 the HIT and 2 onward the FDE sectors; a DEC's entry is in sector (DEC AND 1FH) + 2, entry DEC / 32.
The operand at 570EH is FFH in the file; 5706H stores a sector number there and 5713H puts FFH back. 56EBH and 6092H call here.
571BH - Progress Asterisk and Operator Keys
571BH blinks an asterisk in the top right corner of the screen (3C3FH) once for each sector. 572BH reads a key (00H if none) and changes it to upper case. Both then check the keyboard unless NDMW was given: holding the right arrow pauses until ENTER (continue) or the up arrow (cancel) is pressed, and the up arrow cancels the command with error 39H. Register Pair AF is returned as it was (572BH: the key); Register Pairs BC, DE and HL are not changed.
Pause Loop: wait for ENTER (continue) or the up arrow (cancel).
5751H - Free Granules in the GAT
Entered at 5762H with Register Pair HL pointing to a lump's byte in the GAT sector at 4200H, Register C holding the first granule's number in the lump and Register Pair DE the number of granules. The bit of each granule is cleared (free) from there on, lump after lump. If the destination has no more than 96 lumps, the same bits are then cleared in the lockout table 60H bytes further on (5751H, zap 023). Used by FORMAT (6684H) and by SYS17 (5083H) at the end of a diskette COPY. Register Pairs HL, DE and BC are kept.
Lump Loop: Register L walks the lump bytes, Register C the granules in a lump, Register Pair DE counts the granules left.
5784H - Verify the Whole Destination Diskette
Entered with Register Pair DE = the first sector to read and Index Register IX pointing to the destination FCB (5B17H). Every sector from there to the end of the destination diskette is read into 4200H; a sector with the directory mark (error 06H) is correct, any other read error is reported with the C, R or P question. Zap 044 replaced the test of SYSTEM option BM at 5784H with six NOPs, so the verify is always done. Called by FORMAT (6655H) and by SYS17 (5023H) after a diskette COPY.
Verify Loop: Register Pair HL counts the sectors left.
57C8H - Read, Write and Verify Through the FCB at IX
57C8H reads the sector at the FCB's NEXT (SYS0 4436H), 57CEH writes it (through 5CE4H, zap 032) and 57D4H writes it and reads it back (SYS0 443CH). Register Pair DE is set to Index Register IX, the FCB. Each returns the Z FLAG, or the NZ FLAG with the error code in Register A.
57DAH - Report a Disk Error and Ask C, R or P
Called from 585AH with the error code in Register A. The line ERROR WHILE READING/WRITING/VERIFYING SOURCE/DESTINATION SECTOR n is displayed (n = the FCB's NEXT), and in a COPY by file the file's name. A single file COPY ends here with the error. Otherwise the system diskette is switched in so that SYS4 can display the DOS error message, the operator is asked, the overlay that was in the overlay area is loaded again and the diskette that was in use is switched back. Returns Register A = 1 and the Z FLAG for P, Register A = 2 and the NZ FLAG for R; C ends the command. Register Pairs HL, DE and BC are kept.
The operand at 57EBH is 00H in the file; it is stored before each operation: 80H reading the source (52A5H), 40H writing the destination (547EH), 20H verifying the destination (540EH, 578CH).
584AH - Display the DOS Error and Ask C, R or P
Entered with the error code in Register A. With NDMW the command ends with the error. Otherwise SYS4 displays the error message and returns here, and the operator is asked.
585AH - Disk Error: Retry, Proceed or Cancel
Entered with the error code in Register A and Index Register IX pointing to the FCB. Returns the NZ FLAG if the operator chose R (retry). For P (proceed) the FCB's NEXT is moved past the bad sector and the Z FLAG is returned with Register A = 0. 585EH only moves NEXT on.
5868H - Display the Name of the File Being Copied
Only in a COPY by file (the OR operand at 586AH is set to FFH by 615CH): WITHIN FILE and the name of the file open in the FCB at Index Register IX are displayed and the NZ FLAG is returned. 586FH displays the message at Register Pair HL followed by the file's name.
The operand at 586AH is 00H in the file; 615CH stores FFH there when a COPY by file starts copying.
587EH - Display Routines
587EH displays the message at Register Pair HL and starts a new line; 5881H only starts a new line. 5886H displays Register B characters from Register Pair HL, showing a space for control codes and graphics. 5898H displays Register B spaces. 58A0H displays the NAME/EXT of the directory entry at Register Pair HL. 58BDH displays the character in Register A through the ROM routine at 0033H, keeping Register Pairs DE and AF.
Character Loop of 5886H: Register Pair HL walks the text, Register B counts.
Field Loop: Register B characters at Register Pair HL, spaces left out.
58C5H - Operator Questions
58C5H (not called) would display the message at Register Pair HL before 58C8H. 58C8H asks REPLY C (CANCEL), R (RETRY) OR P (PROCEED): C ends the command with error 39H, P returns Register A = 1 with the Z FLAG, R returns Register A = 2 with the NZ FLAG. With NDMW the command ends at once. 58DEH displays the question at Register Pair HL and asks (Y OR N), returning the Z FLAG for N. 58E4H is the general routine: Register Pair HL points to a list of allowed replies ending with 00H, followed by the prompt text; it returns Register A = the reply's position in the list, with the Z FLAG for the first one.
Skip Loop to the 00H that ends the list.
Key Loop: wait for a key that is in the list.
5909H - Display a Number in Decimal
Displays Register Pair DE (0-65535) without leading zeros, using the table of negative powers of ten at 5933H. The last digit is always shown.
Digit Loop: Register Pair DE is the rest of the number, Register Pair HL the table pointer.
5933H - Variables, Control Blocks and Messages (Data)
The values shown are the ones in the file; the comments give their use at run time. The Variables section of the introduction lists them with their sizes.
SYS0 patches, put in while a diskette whose PDRIVE entry has TI flag M (bit 5 of 430CH) and double density is in use. They swap the two data address marks (463DH, 4641H, 5C0BH), read the directory lump from byte 1 of the boot sector (48F4H), make SYS0 handle five 48-byte directory entries to a sector (4938H), 13 extent elements (4837H, 4877H, 4892H) and 3-sector granules (4C88H, 4CB3H), and stop the directory write that marks a file updated (4A7FH). 56EBH is in SYS6: its CALL NZ becomes a CALL, so a changed directory sector is always written back first. Each entry is the address, the byte count and the bytes; after an exchange the entry holds the bytes it replaced.
SYS2 patches, all of them for a TI flag M diskette in double density. For a TI flag M diskette in single density 5CC9H makes the list start at 5BB1H and 5CDBH clears the address at 5BB5H, so that only the 4F68H patch is used.
SYS3 patches. For a TI flag M diskette in single density 5CCFH makes the list start at 5C00H, so only the 5032H and 4E40H patches are used.
5C0BH - Routines Patched into SYS0, SYS2 and SYS3 for TI Flag M
The patch lists at 5B64H-5C09H put jumps to these routines into SYS0, SYS2 and SYS3 while a TI flag M diskette in double density is in use. They run as part of those modules, so their jumps go back into them. 5C0BH replaces the end of SYS0's error code routine at 4737H for the read and write commands: a read that ends without an error now reports error 06H and a read that reports error 06H (the other mark) now has no error, so the meaning of the two data address marks is reversed.
5C1EH replaces SYS0 4938H (the jump to it is put at 4938H): five 48-byte entries in each directory sector. Entered from SYS0 4936H with Register A = the DEC and Register L = the number of the directory sector held in 4200H (FFH to force a read). Returns Register Pair HL pointing to the entry.
5C3EH replaces SYS0 4877H and 5C43H replaces SYS0 4892H in the loop at SYS0 4838H that goes through a file's extent elements; the element count (13 with the 4837H patch) is kept in Register A'.
5C5BH replaces SYS2 50D6H: look for a free entry in the first 80 bytes of the HIT sector at Register Pair HL.
5C69H replaces SYS3 4E72H (DEC E / JR NZ,4E62H) in the loop over a file's extent elements.
5C71H is called in place of SYS2 4E1FH (the CALL at SYS2 4DEFH), when SYS2 makes a new directory entry: it first puts two bytes of the system date into the entry.
5C80H - Boot Sector Length and Directory Lump (Zap 015)
Called from 52F9H while a diskette COPY replaces sector 0 or 1 with SYS6's boot sector. Register A = the sector number and Register Pair DE = the source sector's data. Returns Register Pair BC = 0100H for the LDIR. For sector 0 the source's directory starting lump (byte 2 of its boot sector) is first copied into the boot sector image, so that the copy finds its directory where the source had it.
5C8EH - Set the Destination Buffer (Zap 024)
Called from 5479H with Register Pair HL pointing to the sector data to write. Makes it the destination FCB's buffer and sets bit 6 of the FCB's second byte, so that SYS0 moves the EOF only when a write goes past it. This stops a rewrite after a verify error from moving the EOF back.
5C96H - Load the Drive Data and Prepare the TI Flag M Patches (Zap 031)
Called from 4D79H and 6389H. After 63B3H has loaded the source and destination PDRIVE data, the TI flag M bit (bit 5 of the flags, +2) and the density bit (bit 0 of the disk I/O flags, +7) of each are checked. Two TI flag M diskettes of different density cannot be used together. If a TI flag M diskette is single density, only a few of the patches are used: the SYS0 set is left out, the SYS2 and SYS3 lists are shortened, and three instructions of the COPY by file code are changed (612DH, 617FH, 61BFH).
A TI flag M diskette in single density: only the SYS2 4F68H patch and the SYS3 5032H and 4E40H patches are used, and the COPY by file code is changed.
5CE4H - Write a Sector (Zap 032)
Reached from 57D1H with Register Pair DE = Index Register IX = the FCB. When the current drive's PDRIVE flags have TI flag M (bit 5 of 430CH), bit 5 of the FCB's third byte is set first, so that SYS0's write does not mark the file updated in its directory entry.
5CF2H - Sectors to Granules (Zap 056)
Called from 6727H with Register Pair HL = a number of sectors and Index Register IX pointing to a working PDRIVE record. Divides by 3 for a diskette with TI flag M in double density, otherwise by 5, the NEWDOS/80 granule size. Returns Register Pair HL = the granules, Register A = the sectors left over.
5D04H - Pointers for the Sector Buffers and File List
Three words that move as COPY runs, with 12 unused bytes before them.
5D16H - COPY by File (Format 6): Format, Read the Include/Exclude List
Reached from 6336H when CBF was given. The destination is formatted first if required (6643H). The source and destination FCBs are then used for real files, so bit 1 of their first bytes is cleared. With ILF= or XLF= the list file (whose filespec 4FACH put into the DOS FCB at 4480H and which 629CH opened) is read into 6491H: one name/ext per line ended by 0DH, lines starting with a semicolon are comments, spaces and empty lines are skipped, each byte is taken modulo 128, and a 0DH on its own ends the list.
Line Loop: Register Pair HL is the end of the names collected, Register B counts the characters of one name.
5D86H - COPY by File: Choose the Source Files
The source directory's HIT sector (one byte per DEC: 00H free, otherwise the hash code of the file's name) is copied to 6291H and used as the table of candidates. ILF starts from an empty table and puts back the hash code of each listed file; XLF clears each listed file's byte. Then every directory entry is looked at in DEC order; the files that pass the USR, UPD, /ext and system file tests (and the operator's answer with CFWO) get a 3-byte entry in the file list from 6491H: flags (80H, plus bit 6 for a system file that must keep its DEC), the source DEC and the hash code.
Name Loop: Register Pair HL walks the names; each is opened on the source diskette to find its DEC.
Entry Loop: Register C is the DEC being looked at.
5EB3H - COPY by File: Collect the Source Directory Entries
For each file in the list the first 24 bytes of its source directory entry are copied into memory after the list, 24 bytes per file (61D6H), and bit 4 of its list flags is set. When memory runs out the files collected so far are handled on the destination (5EE4H), and the collecting starts again in the same spaces. After the last file 5EE4H is entered once more with 60BFH as its return address.
Collect Loop: Register Pair HL is the list entry.
5EE4H - COPY by File: Make the Destination Directory Entries
Handles the files of the current group (list flag bit 4 set, their 24 source directory bytes collected after the list). With NFMT the destination directory is searched first, entry by entry, for files with the same name: such a file gets the source's EOF and record length and keeps its place, and its space past the new EOF is freed through SYS3 (60A9H). Then, unless DFO was given, the remaining files of the group that are system files kept in place (list flag bit 6) get the same DEC as on the source and their granules at the same distance from the directory; the other files get their entries at 60BFH. The HIT and GAT copies are written back at 6092H.
Destination Entry Loop: Register C is the destination DEC; each file in use is compared with the files of the group by name.
The operand at 5F1EH-5F1FH is 0000H in the file; 5F04H stores the entry's address there.
Group Loop: each file of the group gets its flag bit 4 cleared; system files kept in place get their entry and granules here.
The operand at 6028H is 00H in the file; 5FE1H stores the DEC there.
The operand at 6078H-6079H is 0000H in the file; 5FF6H stores the address of the entry's byte 22 there.
60A9H - Free the Space Past a File's New EOF
Called from 5F7BH with Register Pair HL pointing to the destination directory entry and Register Pair DE to the destination FCB. SYS0's routine at 4980H saves the registers and runs the code after the CALL (60ACH) as a DOS function with Index Register IX = the FCB. That code hands the entry's EOF to SYS3, whose CLOSE code (still in the overlay area) works out the granules the EOF needs and releases the rest.
60BFH - COPY by File: Give the Remaining Files New Entries
Reached when 5EE4H returns for the last group (5EE0H pushed 60BFH as its return address). Files that did not get a destination entry at 5EE4H get a new one from SYS2 (50CFH), in groups as memory allows: their bytes 0-21 are collected from the source directory (60C8H) and copied into the new entries (60F5H). When only one of the two diskettes has TI flag M, the entry's bytes 1-2 and both password codes are set for the destination's kind and the EOF is adjusted. Then the copying starts (6157H).
The operand at 60C3H is 00H in the file; 608CH stores a value that is not 0 there when a file still needs an entry.
Collect Loop: Register Pair HL is the list entry; bytes 0-21 of each file without an entry are collected.
Entry Loop: each file of the group gets a new destination entry.
The opcode at 612DH is 28H (JR Z) in the file; 5CE0H stores 18H (JR) there when a TI flag M diskette is in single density.
6162H - COPY by File Helpers
6162H reads the HIT sector of the current diskette and copies it to 6291H (Register Pair HL = 4200H on return). 616FH copies 256 bytes from Register Pair HL to 4200H, 6172H from Register Pair HL to Register Pair DE. 6178H returns Register A = the number of FDE sectors in the directory and Register C = the directory's granules. 6190H prepares a walk through the file list and the 24-byte spaces.
The opcode at 617FH is C0H (RET NZ) in the file; 5CD3H stores 00H (NOP) there when a TI flag M diskette is in single density, which then has a normal directory.
619DH - Look at a Directory Entry
Entered with Register C = a DEC. The HIT copy at 6291H is checked first: a free entry returns the CARRY FLAG and the NZ FLAG, and on a diskette without TI flag M so do DECs 0 and 1 (BOOT/SYS and DIR/SYS). Otherwise the entry is read and the Z FLAG returned if it is a primary entry in use (bit 4 set, bit 7 clear), with Register Pair HL pointing to it and Register B holding its HIT byte.
61BAH - Step to the Next DEC
Entered with Register C = the DEC and Register Pair HL pointing to the directory's FDE sector count. Steps through the entries in DEC order (the next entry position in the sector, then the next sector) and returns the CARRY FLAG after the last one. On a TI flag M diskette in double density the DECs are numbered 0-4FH one after another.
The bytes at 61BFH-61C0H are 20H 06H (JR NZ) in the file; 5CD8H stores two 00H bytes (NOPs) there when a TI flag M diskette is in single density.
61CBH - Store a Decimal Digit
Entered with Register A = a number, Register B = 100 or 10 and Register Pair HL pointing to where the digit goes. Nothing is stored if the number is below Register B. Returns Register A = the remainder.
61D6H - Take the Next 24-Byte Space
Returns Register Pair DE = the next 24-byte space after the file list and the CARRY FLAG if it is still below the limit at 61DBH (the top of memory less 24). The pointer at 61D8H moves on by 24 either way. Register Pair HL is kept.
The operand at 61D8H-61D9H is 0000H in the file; 6190H stores the end of the file list there and 61E4H advances it.
The operand at 61DBH-61DCH is 0000H in the file; 5D9DH stores the top of memory less 24 there.
61EAH - TI Flag M Tests
61EAH returns the NZ FLAG if either diskette has TI flag M (bit 5 of the flags at 59B9H or 59C7H), 61F6H if the current drive has (430CH), and 61FCH if exactly one of the two has, with Register A = the destination's flags. 6209H adjusts the EOF middle and high bytes at Register Pair HL when a file with a partly used last sector moves between a diskette with TI flag M and one without.
621CH - Allocate Granules in a GAT Copy
Entered with Register Pair HL = the GAT sector (or its copy), Register E = the lump, Register B = the first granule in it and Register C = the number of granules. Each granule's bit is set. A granule past the destination's last lump, or one already allocated, ends the command with DISKETTE/GAT OVERFLOW (5240H). Used by 6080H and by FORMAT (669FH).
Lump Loop: Register Pair HL is the lump's byte, Register D the granule's bit, Register B the granules left in the lump, Register C the granules left to allocate.
624FH - Compare a Diskette Name
624FH compares the 8 characters at Register Pair HL with the diskette name in the GAT sector at 42D0H; 6254H compares Register B characters at Register Pair HL and Register Pair DE. The Z FLAG is set if they are the same.
6291H - Diskette COPY (Formats 5 and 6): Check the Diskettes
Reached from 4D88H. This code runs once; afterwards 6291H-6390H and 6391H-6490H are reused as copies of the destination's HIT and GAT sectors and 6491H onward for the file list. The list file of ILF or XLF is opened, the overlay needed at the end is loaded (SYS17 for a sector by sector COPY, SYS3 for a COPY by file), the source diskette's GAT is read for its name, date and password (SN, SPW, USD), and the two diskettes are checked against each other before the COPY engine starts.
Sector by sector COPY (format 5). The source FCB's EOF is set to the number of sectors to copy.
6377H - Single File COPY (Formats 1 to 4): Find the Drives
Reached from 4DF0H. The drive of each filespec is found (6437H), the drive data and TI flag M patches are set up, SYS2 is loaded for the opens, and the COPY engine is entered.
6392H - Parse the Destination Drive Number
Returns the CARRY FLAG and the drive number in Register A if the parameter at Register Pair HL is a drive number. The number is stored as the destination FCB's drive, the destination drive and at 4DFAH.
63A0H - Parse an Optional Track Count
63A0H stores the destination track count at 64A9H; 63A3H stores it where Register Pair DE points (64A6H for the source). Nothing happens unless the character at Register Pair HL is =. A count of 0 gives error 2FH.
63B3H - Save and Load the Drive Data
Called from 5C96H and 6630H. The PDRIVE entries of the drives used by the system, source and destination diskettes are saved as the originals (63B5H) and copied into each diskette's working record (63BFH). A source or destination given a PDRIVE number with SPDN= or DPDN= takes that record from the system diskette instead (63ECH), and the values typed in the command are put into the working records from the override table (63DAH). From now on each switch installs the diskette's working record.
The operand at 63CAH is FFH in the file (none); 500BH stores the number there.
The operand at 63D6H is FFH in the file (none); 500BH stores the number there.
Override Loop: each entry is the address of a byte in a working record and the value typed in the command (00H = not given).
63ECH - Take a Working Record from the System Diskette's PDRIVE Data
Entered with Register A = a PDRIVE number (FFH = none), Register C = the diskette's drive, Register B = its role bit and Register Pair HL pointing to its working record. The ten bytes of that PDRIVE number's record are copied from the system diskette's PDRIVE sector. A diskette on drive 0 with other PDRIVE data cannot be the system diskette, so it is made a swapped diskette; and when the source and destination share a drive both are swapped.
6424H - Read the System Diskette's PDRIVE Sector
Reads sector 2 of the diskette in drive 0 (the third sector of BOOT/SYS, which holds the PDRIVE records and the SYSTEM options) into 4200H through the FCB at 5B49H, whose drive byte is 00H.
6437H - Find the Drive of a Filespec
Entered with Register Pair DE pointing to a filespec in an FCB and Register Pair BC to its diskette control block. A drive number in the filespec (:d) becomes the control block's drive. In formats 3 and 4 the filespec may not have one, and the drive from the command is added to it instead. In formats 1 and 2 a filespec without a drive number is opened at once (5538H), which finds its drive; that is not allowed with $, SPDN or DPDN.
Scan Loop: look for a colon or the 03H that ends the filespec.
6485H - Not in the File
The second load block ends at 6484H. 6485H-64A2H is the interleave table of the track format code (6A13H, 6A28H, 6A60H, 6A96H, 6BE9H, 6C57H). From 6491H on, memory is also used for the include/exclude names and the COPY by file list.
64A3H - Override Table (Data)
Used by 63DAH after the PDRIVE data has been loaded: a count, then for each entry the address of a byte in a working PDRIVE record and the value typed in the command (00H = not given).
64B0H - Fill the Sector Buffer
Fills 4200H-42FFH with the byte in Register A. Called from 6675H (FFH, a new GAT sector) and 66C1H (00H, the other directory sectors).
64BAH - Boot Sector Image
These 256 bytes (64BAH-65B9H) are the NEWDOS/80 boot sector. 6700H writes them as sectors 0 and 1 of every diskette FORMAT makes, and a diskette COPY puts them in place of the source's boot sectors (52F6H). The Model I ROM reads sector 0 into 4200H and jumps to 4200H, so each comment starts with the address the byte has there, and the branches link to the rows by that address. FORMAT fills in the drive's values first (6759H): the directory lump (64BCH), the Percom density byte (64C2H), the drive select byte (64CAH, 65B7H), the first sector of SYS0/SYS (64CCH-64CDH), the sectors per side (651BH) and per track (656AH), the first sector number (656FH) and the PDRIVE flags (65B8H, 65B9H). The loader reads SYS0/SYS from track 0 sector 5 into memory record by record and enters it at 4D01H.
The operand at 64CAH (4210H at run time) is byte +6 of the destination drive's PDRIVE record, stored by 675FH: the drive select byte that some interfaces read from the sector register to choose the density (00H standard or Percom, 80H/C0H Omikron or LNW, 80H/A0H Radio Shack doubler).
The operand at 651BH (4261H at run time) is filled in by 6791H: the sectors per track, halved for a double sided drive. If the sector number is below it the CARRY FLAG is set.
The operand at 656AH (42B0H at run time) is the sectors per track (both sides), filled in by 678BH. The Z FLAG is set when the track is used up.
FORMAT (6778H) stores 01H in the operand at 42B5H when the drive's sectors are numbered from 1.
65BAH - Directory Entries for BOOT/SYS and DIR/SYS (Data)
The first two directory entries of a new diskette. 66E6H copies them into the first places of directory sectors 2 and 3 (DEC 0 and DEC 1).
65FAH - FORMAT Command
Entered from 4D13H with Register Pair HL pointing to dn2[=tc2],name2,mm/dd/yy,password3[,options]. Null name, date and password parameters give NOTNAMED, the system date and PASSWORD. N is the default when none of N, Y, DDND, ODN, KDN or KDD is given. FORMAT shares the formatting code with COPY formats 5 and 6 (6643H) and ends by displaying DONE (552DH).
6643H - Format the Destination and Write Its System Data
Called from 5D16H (COPY by file) and entered from 6642H (FORMAT). After 67C3H has checked (and with FMT formatted) the diskette, the whole diskette is read back (5784H). Unless BDU was given the system data is then written: the boot sector as sectors 0 and 1, the PDRIVE sector as sector 2, and the directory: a GAT with every granule of the diskette free except BOOT/SYS's and the directory's, a HIT with the hash codes of BOOT/SYS and DIR/SYS, and the FDE sectors with their two entries. Nothing is written after an NFMT or an RWF.
Directory Sector Loop: Register C is the directory sector being written.
The operand at 670CH is 0AH in the file; 66E1H stores the real number there when the HIT is made.
6710H - Work Out a Diskette's Size
6710H does the destination (working record at 59C5H), 6713H the record at Register Pair HL (4D7CH passes the source's at 59B7H). The total sectors (tracks times sectors per track) are stored at +10, the total granules at +12, and the number of lumps at +1. More than 192 lumps gives the PDRIVE conflict message.
674DH - A TI Flag M Diskette Needs BDU
674DH checks whether either diskette has TI flag M; 6751H goes straight to the test of BDU. Without BDU the command ends with the PDRIVE conflict message: SYS6 does not write system data for such a diskette.
6759H - Fill In the Boot Sector and DIR/SYS Entry for the Destination
Called from 67C3H. Puts the destination drive's values into the boot sector image (64BAH-65B9H) and into DIR/SYS's directory entry (65DAH).
67AAH - Write the Boot Sectors or Another Sector
67AAH writes the boot sector at 64BAH as sectors 0 and 1 of the destination. 67B1H writes it as sector Register Pair BC, 67B4H writes the 256 bytes at Register Pair DE as sector Register Pair BC. Each sector is read back (57D4H). The flags returned are those of the last write: the Z FLAG if it went well.
67C3H - Check the Destination Diskette and Format It
Called from 6368H (diskette COPY) and 6643H. Unless Y was given, the destination's first sector and GAT are read to see what is on it: N requires an unformatted diskette, ODN, ODPW and DDND look at its old name, date and password, and KDN/KDD keep them. Then, unless NFMT was given, the diskette is formatted: a partial format with PFST, or every track, with track 0 in the other density for TI flag K.
The operand at 68ABH-68ACH is 0001H in the file (one track from track 0); 4FD1H stores PFTC= at 68ABH and 4FD9H stores PFST= at 68ACH.
TI flag K: track 0 is formatted in the other density with 10 sectors, the boot sectors are written to it, and the other tracks follow in the drive's own density.
692FH - Display the Old Diskette Name and Date
692FH displays the word at Register Pair HL (SOURCE or DESTINATION) followed by DISKETTE NAME MISMATCH. 693BH displays the word followed by DISKETTE OLD NAME/DATE = and the name and date from the GAT sector in 4200H.
6959H - Format Tracks
Entered with Register A = the track to stop at, Index Register IX pointing to the destination FCB and the head over the first track (its number at 6AF4H). The drive's kind (the 8 inch and double density bits of 4311H) picks a line of the table at 6CC2H, whose values are stored into the code below. For every track (and each side of a double sided drive) the sector numbers are laid out with the line's interleave and skew (6A13H), the track is written with Write Track (6AA6H), the bytes that fit after the last sector tell whether the drive turns at the right speed (6BCCH), and every sector is read back (6BDEH). A track that fails is tried 10 times. Returns the Z FLAG, or the NZ FLAG with Register A = a DOS error code, or Register A = FFH and Register Pair HL = MOTOR FAST or MOTOR SLOW.
The operand at 69D6H-69D7H is 0000H in the file; 69B4H stores bytes 14-15 of the table line there.
The operand at 69DAH-69DBH is 0000H in the file; 69A4H stores bytes 10-11 of the table line there.
The operand at 69F2H-69F3H is 0000H in the file; 69ACH stores bytes 12-13 of the table line there. 69E0H comes here.
Track Loop: each pass lays out the sector numbers of one side and formats it.
The operand at 6A00H is 02H in the file; 69BAH stores byte 16 of the table line there. 6C7AH comes here.
The operand at 6A02H is 00H in the file; 69C7H clears it and 6A0AH and 6A43H store into it. 6C6CH jumps here with Register A = 0 for the back side.
Build the interleave table at 6485H: the sector numbers in the order they pass the head.
The operand at 6A33H is 02H in the file; 69BFH stores byte 17 of the table line there.
Turn Loop: the table is turned by one place, Register D - 1 times, so that each track starts at its skewed place.
Try Loop: write the track and read it back.
Sector Loop: Register C counts the sectors of this side; each pass writes the gap before the ID field, the ID field, the gap, and the data field. Every byte is sent the same way: wait while the status equals the 01H kept in Register A', then store the byte in the data register.
The operand at 6AC8H is 01H in the file; 698FH stores byte 5 of the format table line there.
The operand at 6AD8H is 00H in the file; 6978H stores byte 1 of the format table line there (00H single density, F5H double density, which the FDC writes as A1H).
The operand at 6AF4H is 00H in the file; 68C1H stores the first track and 6C72H counts it up.
The operand at 6AFCH is 00H in the file; 6A87H stores 00H or 01H there.
The operand at 6B1CH is FFH in the file; 6970H stores byte 0 of the format table line there (FFH single density, 4EH double density).
The operand at 6B26H is 0AH in the file; 6994H stores byte 6 of the format table line there.
The operand at 6B3DH is 04H in the file; 6999H stores byte 7 of the format table line there.
The operand at 6B4DH is 00H in the file; 697CH stores byte 1 of the format table line there.
Data Field: Register A holds the status value 01H here and the bytes are stored with LD (HL),n.
The operand at 6B6FH is E5H in the file; 6980H stores byte 2 of the format table line there.
The operand at 6B76H is E5H in the file; 6985H stores byte 3 of the format table line there.
The operand at 6B83H is FFH in the file; 6974H stores byte 0 of the format table line there. 6AAFH jumps here for the first gap of the track.
The operand at 6B8BH is 0AH in the file; 698AH stores byte 4 of the format table line there.
End of Track: gap bytes are written until the FDC ends the Write Track at the index hole; Register Pair BC counts them, which tells how fast the diskette turns.
The operand at 6BCDH-6BCEH is 0000H in the file; 69F5H stores it.
The operand at 6BD6H-6BD7H is 007DH in the file; 69FCH stores it.
Read back every sector of the side with SYS0's FDC routine, keeping only the status.
Read Back Loop: Register Pair HL walks the table from its second place; the first place is read last.
The operand at 6C63H is 00H in the file; 69CAH clears it and 6C66H changes it.
The operand at 6C75H is 23H in the file; 6959H stores the end track there.
The operand at 6C95H is 00H in the file; 6A69H stores 10 there. 6C87H comes here.
6CA4H - Sectors per Side
Returns Register E = the sectors per track (430EH), halved for a double sided drive.
6CAFH - Step to the Next Track
Steps the head in by one track, or by two for a drive with TI flag L (the double step bit, bit 2 of the disk I/O flags).
6CC2H - Track Format Table (Data)
One 26-byte line for each kind of drive, chosen by 6960H from the 8 inch and double density bits of the disk I/O flags. Bytes: 0 gap byte, 1 address mark lead-in (F5H writes A1H in double density), 2-3 data pattern, 4 gap before each ID field, 5 further zero bytes before the ID mark, 6 gap between the ID and data fields, 7 further zero bytes before the data mark, 8-9 bytes one sector takes on the track, 10-11 bytes a track holds at the nominal speed, 12-13 and 14-15 the tolerances for the speed check, 16 the sector skew from track to track, 17 the interleave, 18-25 not used.
6D61H - FORMAT and COPY Messages (Data)
Displayed through the SYS0 routine at 4467H: 0DH ends a line, 03H ends a message without a new line.
6EB5H - Command Line Parsing Routines
Used only while the command line is parsed: 4DF3H copies the new PDRIVE sector over 6EB5H-6FB4H afterwards. 6EB5H steps to the next parameter: it returns the Z FLAG at the end of the line, the CARRY FLAG if a parameter follows, and the NO CARRY FLAG with the NZ FLAG if the parameter is null (two separators). 6EC0H returns the Z FLAG at the end of the line and otherwise steps over a separator; 6EC4H requires a separator (error 34H).
6ECBH - Parse a Drive Number
Parses an optional colon and a drive number at Register Pair HL. Returns the CARRY FLAG with the number in Register A if the parameter starts with a digit, otherwise the NO CARRY FLAG. 6ED7H is entered with Register Pair HL on the digit (from 6448H). The drive must be available (SYS0 4776H), or the command ends with the error.
6EE2H - Parse a Number of 0-255
6EE2H accepts a decimal number or a hexadecimal one ending in H; 6EE7H a decimal number. Returns the value in Register A (and Register Pair DE) with Register Pair HL past the number. A missing number or one over 255 gives error 2FH. A number over 65535 is not detected (6F47H).
Digit Loop: Register Pair DE is the number, Register Pair HL the text, Register B the flags (bit 0 hexadecimal, bit 1 a digit seen).
6F4BH - APPEND Command
Entered from 4D0AH (function code 68H) with Register Pair HL pointing to filespec1[,TO],filespec2. filespec2 is opened and positioned to its end, then every byte of filespec1 is read and written to it. The file is closed, which also writes its new EOF. The command returns to SYS1 through 4428H, so the SYS6 exit at 521AH is used only for errors.
Byte Loop: each byte of the first file is read and written to the second.
6F8FH - Copy a Name
Copies up to 8 letters and digits (the first must be a letter) from Register Pair HL to Register Pair DE and pads the rest of the 8 bytes with spaces. Returns Register A = Register C = the number of characters copied, with the Z FLAG if there were none. Register Pair HL points past the name.
Character Loop: Register Pair HL walks the text, Register Pair DE the name, Register B counts the places.
6FB8H - Parse the Date
Parses mm/dd/yy into 598BH, checking each digit against the highest value stored there in the file (2:/4:/::: the month's first digit below 2, the day's below 4, the others below :). A null or missing date parameter takes the system date instead.
Part Loop: two digits, then a slash, three times.
6FE5H - Step to the Next Parameter, Skipping TO
Requires a separator (error 34H), then steps over the keyword TO and the separator after it if they are there. A word that only starts with TO (such as a file named TOM) is left alone.