TRS-80 DOS - NEWDOS/80 v2.0 for the Model III - BOOT/SYS Disassembled

Page Customization

Introduction/Summary

NEWDOS/80 v2.0 BOOT/SYS Disassembly - The Boot Sector and the System Data Sector (Model III)

BOOT/SYS is the first file of every NEWDOS/80 diskette: the first five sectors of track 0 (one granule, 1,280 bytes). It is not a load module. Sector 0 is the boot sector, sector 1 is a copy of it, sector 2 is the system data sector (the PDRIVE records and the SYSTEM options), and sectors 3 and 4 are unused.

When the computer is reset with a diskette in drive 0, the ROM reads track 0, sector 1 into 4300H-43FFH and jumps to 4300H. The boot sector code then reads SYS0/SYS, which starts at sector 5, sector by sector into a buffer at 5100H-51FFH, copies each load block to its address, and jumps to SYS0/SYS's reset code at 4D01H once it finds A5H at the transfer address 4D00H. A record type of 20H or more, or no A5H, displays NO SYS; a sector that cannot be read in 10 tries displays ERROR. Both stop the computer until RESET is pressed.

The page shows every byte of the file once: sector 0 at the addresses where it runs (4300H-43FFH), sectors 1-4 by their offsets in the file (0100H-04FFH).

How a Sector Is Read

The code works the floppy disk controller through its ports and ends every read on a non maskable interrupt, as the ROM does:

StepWhat the code does
SelectPort F4H = 81H (drive 0, double density) or 91H (side 1), after the controller is not busy (4357H)
SeekTrack to port F3H (data register), sector to port F2H, command 1BH to port F0H, wait until not busy (435DH)
NMIStatus read once to clear the interrupt request, Stack Pointer saved in the operand 43A6H, NMI vector 4049H = JP 43A2H, port E4H = C0H (4370H)
ReadCommand 88H; the first byte is polled (data request, bit 1 of port F0H), the other 255 are taken with INI while port F4H bit 6 makes the CPU wait for each one (4385H)
EndJR 43A0H loops until the controller's interrupt request causes the NMI; 43A2H turns the NMI off, puts the stack back, tests the status (AND FCH), sends Force Interrupt D0H and advances to the next sector or restores the head (0BH) and tries again

The main register set does the loading (Register Pair HL = the buffer pointer, Register Pair DE = the load address, Register C = the bytes left in the record, Register B = the record type); the alternate set does the reading (Register Pair DE' = track and sector, Register B' = tries left, Register L' = the select byte).

The Five Sectors

SectorContents
0The boot sector, 4300H. Bytes 0-1 are 00H FEH, byte 2 is the directory lump (11H), bytes FDH-FFH are bytes +6, +2 and +7 of drive 0's PDRIVE record, which SYS0/SYS's reset takes from the buffer at 4300H.
1A copy of sector 0, 0100H. This is the one the ROM reads and runs.
2The system data sector, 0200H: PDRIVE records for drives 0-9 (16 bytes each), number options at A0H-A9H and D0H-D1H, A5H at EFH, yes/no options at F0H-F9H.
3-4Unused, 0300H: the format pattern 5BH.

SYS6/SYS (FORMAT, COPY) writes sectors 0 and 1 from its own image of the boot sector, patching the first sector of SYS0/SYS (4304H), the select bytes (434BH, 4355H), the sectors per side and per track (4350H, 43B6H), the first sector of a track (43BBH), the directory lump (4302H) and bytes FDH-FFH for the destination drive. On this diskette drive 0 is double density, one sided, 40 tracks of 18 sectors numbered from 0.

Variables

Memory Outside BOOT/SYS

Address
Size
Contents
4049H-404BH
3 bytes
NMI Vector
The ROM jumps here on an NMI (through 0066H). The ROM leaves EDH 45H (RETN); 437CH-437EH store JP 43A2H for every sector read. SYS0/SYS takes it over later.
41D6H-41DFH
10 bytes
Stack
Below 41E0H, set at 4308H: the return address into the loader, Register Pairs DE and BC (434DH, 434EH) and the return addresses of 43D7H and 43E2H.
5100H-51FFH
256 bytes
Sector Buffer
Each sector of SYS0/SYS in turn (4389H); 4345H takes the bytes from it with Register Pair HL. SYS0/SYS loads its own bytes into 5100H-51EBH behind the bytes still to be read.
4D00H
1 byte
SYS0/SYS Transfer Address
Must hold A5H after loading (433AH); the boot sector then jumps to 4D01H.

BOOT/SYS Data

Address
Size
Contents
4302H
1 byte
Directory Lump
Byte 2 of the boot sector, the operand of CP 11H: the lump where the directory starts. Read by SYS0/SYS (4898H) and SYS17/SYS, stored by SYS6/SYS.
43E8H-43EFH
8 bytes
ERROR Message
Clear screen, ERROR, 03H.
43F0H-43F8H
9 bytes
NO SYS Message
Clear screen, NO SYS, 03H.
43F9H-43FCH
4 bytes
Not Used
Not part of SYS6/SYS's boot sector image.
43FDH-43FFH
3 bytes
Drive 0 PDRIVE Bytes
+6, +2 and +7 of drive 0's PDRIVE record, read by SYS0/SYS's reset (4D37H, 4D41H).

Operands Changed at Run Time or by FORMAT

Address
Size
Contents
4305H-4306H
2 bytes
First Sector of SYS0/SYS
Sector 05H and track 00H in the LD DE at 4304H; SYS6/SYS 6774H and 676CH add 1 for drives numbered from 1.
434CH
1 byte
Select Byte, Side 0
81H: drive 0, double density (SYS6/SYS 6781H sets bit 7).
4351H
1 byte
Sectors on One Side
12H (18) in the SUB at 4350H (SYS6/SYS 6793H).
4356H
1 byte
Select Byte, Side 1
91H: drive 0, side 1, double density (SYS6/SYS 6786H sets bit 7).
43A6H-43A7H
2 bytes
Saved Stack Pointer
Stored by 4372H before each read, loaded by the LD SP at 43A5H in the NMI routine; 0000H in the file.
43B7H
1 byte
Sectors per Track
12H (18) in the SUB at 43B6H (SYS6/SYS 678DH).
43BCH
1 byte
First Sector of a Track
00H in the LD E at 43BBH (SYS6/SYS 6778H stores 01H for sectors numbered from 1).

Ports

AddressContents
E4HNMI mask: C0H (controller interrupt request and motor time-out) for the read at 4383H, 00H in the NMI routine at 43A3H.
F0HController command (1BH Seek, 88H Read Sector, D0H Force Interrupt, 0BH Restore) and status (busy bit 0, data request bit 1, errors bits 7-2).
F2H, F3HController sector register (4361H) and data register (track for the seek at 435EH, the sector's bytes through INI).
F4HDrive select: 81H or 91H, with bit 6 (40H) for wait states during the transfer.

Outside Routines

AddressContents
0033HROM: display the character in Register A (43D2H).
4D01HSYS0/SYS: its reset code, entered through the RET Z at 433EH.

Disassembly

4300H - Boot Sector: Entry

The ROM's bootstrap reads track 0, sector 1 of the diskette in drive 0 (double density, select byte 81H) into 4300H-43FFH through its own NMI routine and jumps here from 3513H, when its status test (IN A,(F0H) / AND 1CH at 350EH-3511H) gave 00H. Sector 1 of BOOT/SYS is a copy of sector 0, so the code below is what runs. On entry Register A = 00H, port E4H = 00H (no NMI) and the NMI vector 4049H-404AH holds EDH 45H (RETN), stored by the ROM at 3505H-3508H.

4300
NOP 00
No operation. Byte 0 of the boot sector is 00H: SYS17/SYS (WRDIRP, its 4F8DH) accepts a boot sector only when bytes 0 and 1 are 00H and FEH.
4301
CP 11H FE 11
Compare Register A (00H from the ROM's status test) against 11H. The flags are never tested: the instruction only steps over 4302H, byte 2 of the boot sector, which is data: 11H (17), the lump where the directory starts (DDSL). SYS0/SYS reads it at 4898H when a directory read fails, SYS17/SYS WRDIRP finds the GAT with it, and SYS6/SYS stores it into its boot sector image (6799H for FORMAT, 5C88H for a COPY).
4303
DI F3
Disable interrupts: Register A and every register below stay free for the loader, and no clock interrupt (the ROM's handler through the RST 38H vector at 4012H) runs while SYS0/SYS is loaded over the ROM's vectors and data in 4000H-42FFH.
4304
LD DE,0005H 11 05 00
Self-Modifying Code
Load Register Pair DE with 0005H: Register D = track 0 (the operand byte at 4306H) and Register E = sector 5 (4305H), the first sector of SYS0/SYS, the sector after BOOT/SYS's five sectors (one granule). SYS6/SYS FORMAT adds 1 to the track at 676CH when the drive's tracks are numbered from 1 and 1 to the sector at 6774H when its sectors are numbered from 1.
4307
EXX D9
Exchange Register Pairs BC, DE and HL with the alternate set. The alternate Register Pair DE' now keeps the track and sector (0005H) for the sector reader at 4348H, which works in the alternate set; the main Register Pairs BC, DE and HL are free for the loader.
4308
LD SP,41E0H 31 E0 41
Load the Stack Pointer with 41E0H. The stack holds at most five words below it (41D6H-41DFH): the return address into the loader, Register Pairs DE and BC pushed at 434DH/434EH, and the return addresses of 43D7H and 43E2H. SYS0/SYS loads nothing between 4080H and 41FCH, so the stack is never overwritten while it loads.
430B
LD HL,51FFH 21 FF 51
Point Register Pair HL to 51FFH, one byte before the sector buffer at 5100H. 4345H increments only Register L, so its first call turns 51FFH into 5100H with the Z FLAG set, and that makes it read the first sector (track 0, sector 5) into the buffer before it fetches a byte.

430EH - Load SYS0/SYS Record by Record

SYS0/SYS is a load module: records of a type byte, a length byte and the data. Type 01H is a load block (two address bytes, then the length minus 2 data bytes; a length of 02H gives 256), type 02H is the transfer address (two bytes); types 00H and 03H-1FH are passed over; a type of 20H or more means the file is not a load module. The bytes come one at a time from the sector buffer at 5100H-51FFH through 4345H, which reads the next sector when the buffer is used up.

430E
GOSUB to 4345H to fetch the next byte of SYS0/SYS from the buffer at Register Pair HL into Register A: the record type. 4331H comes back here after each record.
4311
CP 20H FE 20
Compare Register A (the record type) against 20H. If the type is 20H or more the NO CARRY FLAG is set: this is not a load module record.
4313
LD B,A 47
Copy Register A (the record type) into Register B. The DJNZ at 431FH and 4333H count it down to tell type 01H and type 02H from the rest. LD does not change the flags of the CP above.
4314
If the NO CARRY FLAG is set (the record type in Register A is 20H or more, so the diskette's SYS0/SYS is not a load module), JUMP to 433FH to display NO SYS.
4316
LD D,A 57
Copy Register A (the record type, 00H-1FH) into Register D. For a type 01H record Register D is replaced by the high byte of the load address at 4324H; for the other types it stays, so the bytes of a passed over record are stored at Register D x 256 + Register E, an address in the ROM (0000H-1FFFH), where the stores change nothing.
4317
GOSUB to 4345H to fetch the next byte into Register A from the buffer at Register Pair HL: the record's length byte.
431A
LD C,A 4F
Copy Register A (the record length) into Register C, the count of bytes of this record still to be read.
431B
GOSUB to 4345H to fetch the next byte into Register A from the buffer at Register Pair HL: the first byte after the length (for type 01H and 02H records the low byte of the address).
431E
LD E,A 5F
Copy Register A (the first byte after the length, the low byte of an address) into Register E.
431F
DECrement Register B (the record type) and, if it is not 0 (the record is not type 01H), JUMP to 4333H to check for type 02H.

4321H - Type 01H: Copy a Load Block

Register E holds the low byte of the load address and Register C the record length. The block's data bytes are copied one by one from the buffer to their load address.

4321
GOSUB to 4345H to fetch the next byte into Register A from the buffer at Register Pair HL: the high byte of the load address.
4324
LD D,A 57
Copy Register A (the high byte of the load address) into Register D. Register Pair DE now holds the load address of this block.
4325
DEC C 0D
DECrement Register C (the record length) by 1 for the low address byte already read.
4326
DEC C 0D
DECrement Register C by 1 more for the high address byte. Register C now holds the number of data bytes (a length byte of 02H gives 00H, which the loop below counts as 256).
4327
INC L 2C
INCrement Register L, the low byte of the buffer pointer in Register Pair HL. The Z FLAG is set when it wraps from FFH to 00H: the 256 bytes of the buffer at 5100H have all been used. 432FH loops back here.
4328
If the Z FLAG is set (Register L wrapped, the buffer is used up), GOSUB to 4348H to read the next sector of SYS0/SYS into 5100H-51FFH. It returns with Register Pair HL = 5100H and Register A = the first byte of the sector.
432B
LD A,(HL) 7E
Fetch the byte at Register Pair HL (the next data byte in the sector buffer) into Register A.
432C
LD (DE),A 12
Store Register A (the data byte) at the load address in Register Pair DE. In 5100H-51EBH, which SYS0/SYS also loads, Register Pair DE always stays below the buffer byte at Register Pair HL (SYS0/SYS's ALIGNMENT FILLER record places its last two load blocks that way), so no byte is overwritten before it is read.
432D
INC DE 13
INCrement Register Pair DE, the load address, to the next byte of the block.
432E
DEC C 0D
DECrement Register C, the count of data bytes left in this record. 4333H enters here to pass over the rest of a record of another type.
432F
If the NZ FLAG is set (Register C is not 0, bytes are left in the record), LOOP BACK to 4327H for the next byte.
4331
The record is finished: JUMP to 430EH to read the next record's type byte.

4333H - Not Type 01H: Transfer Address or Pass Over

Reached from 431FH with Register B = the record type minus 1, Register C = the record length and Register E = the first byte after the length.

4333
DECrement Register B (the record type minus 1) and, if it is not 0 (the record is not type 02H), JUMP to 432EH to count down Register C (the length, one byte already read) and pass over the rest of the record. Those bytes are stored at Register Pair DE, which points into the ROM (Register D = the type), so nothing in RAM changes.
4335
Type 02H: GOSUB to 4345H to fetch the next byte into Register A from the buffer at Register Pair HL: the high byte of the transfer address.
4338
LD D,A 57
Copy Register A (the high byte) into Register D. Register Pair DE now holds SYS0/SYS's transfer address (4D00H).
4339
LD A,(DE) 1A
Fetch the byte at the transfer address in Register Pair DE into Register A. SYS0/SYS has A5H at 4D00H, its transfer address.
433A
CP A5H FE A5
Compare Register A (the byte at the transfer address) against A5H. The Z FLAG is set only if it is A5H, which marks the loaded file as SYS0/SYS.
433C
INC DE 13
INCrement Register Pair DE past the A5H mark to the first instruction of SYS0/SYS's reset code (4D01H). INC DE does not change the flags.
433D
PUSH DE D5
Save Register Pair DE (4D01H, the entry of SYS0/SYS's reset code) onto the stack at the Stack Pointer, so that a RET jumps to it.
433E
RET Z C8
If the Z FLAG is set (the A5H mark was found), RETurn: the RET pops 4D01H from the stack and SYS0/SYS starts, with interrupts still disabled. The boot sector's work ends here.

433FH - NO SYS: SYS0/SYS Is Not a Load Module

Reached from 4314H (a record type of 20H or more) or by falling through from 433EH (no A5H at the transfer address).

433F
LD HL,43F0H 21 F0 43
Point Register Pair HL to 43F0H, the message clear screen and NO SYS, ended by 03H.
4342
JUMP to 43CCH to display the message at Register Pair HL (43F0H) and stop the computer there.

4345H - Fetch the Next Byte of SYS0/SYS

Returns in Register A the next byte of the sector buffer (5100H-51FFH) at Register Pair HL. When the buffer is used up it falls into 4348H, which reads the next sector first.

4345
INC L 2C
INCrement Register L, the low byte of the buffer pointer in Register Pair HL. The Z FLAG is set when it wraps to 00H: every byte of the buffer has been used (or this is the first call, with Register Pair HL = 51FFH).
4346
LD A,(HL) 7E
Fetch the byte at Register Pair HL (the next byte in the buffer) into Register A. LD does not change the Z FLAG.
4347
RET NZ C0
If the NZ FLAG is set (Register L did not wrap, the byte in Register A is valid), RETurn to the caller with it. Otherwise fall into 4348H to read a sector first.

4348H - Read the Next Sector of SYS0/SYS into 5100H

Reads the sector named by the alternate Register Pair DE' (Register D = track, Register E = sector) of drive 0 into 5100H-51FFH, with up to 10 tries, and advances DE' to the following sector. The transfer ends on the NMI that the controller's interrupt request causes at the end of the command (43A2H). Returns with the main register set, Register Pair HL = 5100H and Register A = the first byte of the sector.

4348
EXX D9
Exchange Register Pairs BC, DE and HL with the alternate set: Register Pair DE now holds the track (Register D) and sector (Register E) to read; the main set's buffer pointer (Register Pair HL = 5100H, Register L having wrapped) is kept in the alternate HL' until 43BDH.
4349
LD B,0AH 06 0A
Load Register B with 0AH (10), the number of tries for this sector.
434B
LD L,81H 2E 81
Self-Modifying Code
Load Register L with 81H, the byte for port F4H that selects drive 0 (bit 0), side 0 (bit 4 clear), double density (bit 7). The operand at 434CH is 01H in SYS6/SYS's boot sector image; FORMAT sets its bit 7 (SYS6/SYS 6781H) for a double density drive. 43C7H loops back here for another try.
434D
PUSH DE D5
Save Register Pair DE (Register D = track, Register E = sector) onto the stack at the Stack Pointer; Register E may be changed below for the second side, and 43B1H restores it.
434E
PUSH BC C5
Save Register Pair BC (Register B = tries left) onto the stack at the Stack Pointer; Register Pair BC becomes the transfer count and port at 438CH, and 43B0H restores it.
434F
LD A,E 7B
Copy Register E (the sector number) into Register A.
4350
SUB 12H D6 12
Self-Modifying Code
SUBtract 12H (18) from Register A (the sector number). The operand at 4351H is the number of sectors on one side of a track, stored by FORMAT (SYS6/SYS 6793H: the sectors per track, halved for a two sided drive); on this diskette it is 18, the whole track. If the sector number is below it the CARRY FLAG is set.
4352
If the CARRY FLAG is set (the sector in Register E is on side 0), JUMP to 4357H with Register L = the side 0 select byte.
4354
LD E,A 5F
Copy Register A (the sector number minus the sectors per side) into Register E: the sector number on side 1.
4355
LD L,91H 2E 91
Self-Modifying Code
Load Register L with 91H, the port F4H byte for drive 0, side 1 (bit 4), double density (bit 7). The operand at 4356H is 11H in SYS6/SYS's image; FORMAT sets its bit 7 (SYS6/SYS 6786H) for a double density drive.
4357
GOSUB to 43D7H to wait (after a short delay) until the controller's status (port F0H) shows it is not busy, so that it accepts a new command. Register A returns the status, which is not used.
435A
LD A,L 7D
Copy Register L (the select byte, 81H or 91H) into Register A.
435B
OUT (F4H),A D3 F4
Send Register A (the select byte) to port F4H: drive 0, the side and the density are selected, and the drive motor is started.
Port F4H: Drive Select and OptionsFunction Description
Bit 7Bit 6Bit 5Bit 4Bit 3Bit 2Bit 1Bit 0Summary of Bits
DWPSd3d2d1d0D (bit 7): 1 = double density (MFM), 0 = single density (FM)
W (bit 6): 1 = wait states while the controller has no data ready
P (bit 5): 1 = write precompensation
S (bit 4): 0 = side 0, 1 = side 1
d3-d0: one bit per drive, 1 = selected
435D
LD A,D 7A
Copy Register D (the track number) into Register A.
435E
OUT (F3H),A D3 F3
Send Register A (the track) to port F3H, the controller's data register, where the Seek command takes the destination track from.
4360
LD A,E 7B
Copy Register E (the sector number on its side) into Register A.
4361
OUT (F2H),A D3 F2
Send Register A (the sector number) to port F2H, the controller's sector register, for the Read Sector command at 4387H.
4363
LD A,1BH 3E 1B
Load Register A with 1BH, the Seek command for the controller.
1793 FDC Command: 1BH (00011011)Function Description
Bit 7Bit 6Bit 5Bit 4Bit 3Bit 2Bit 1Bit 0Summary of Bits
00011011Command=Seek (bits 7-4 = 0001)
h = 1: head load at the start
V = 0: no verify
r1 r0 = 11: stepping rate 30 ms; the code ORs in the drive's rate (6 ms, 12 ms, 20 ms or 30 ms)
4365
OUT (F0H),A D3 F0
Send Register A (1BH, Seek) to port F0H, the controller's command register: the head moves from the track in the track register (port F1H, last set by the ROM's read or by a Restore at 43C5H) to the track in the data register.
4367
GOSUB to 43D7H to wait until the controller (port F0H) is not busy: the seek is finished. Register A returns the status, which is not used.
436A
LD A,L 7D
Copy Register L (the select byte) into Register A.
436B
OR 40H F6 40
OR Register A (the select byte) with 40H, setting bit 6: wait states, so that the CPU waits at each port F3H read until the controller has the byte ready.
436D
LD E,A 5F
Copy Register A (the select byte with bit 6) into Register E; 4399H sends it to port F4H before every byte. The sector number in Register E is no longer needed (Register Pair DE was saved at 434DH).
436E
LD D,02H 16 02
Load Register D with 02H, the mask of bit 1 (data request) of the controller's status, for the test at 4394H.
4370
IN A,(F0H) DB F0
Read port F0H, the controller's status, into Register A. The value is not used: reading the status clears the controller's interrupt request left by the seek, so that enabling the NMI at 4383H does not fire it at once.
4372
LD (43A6H),SP ED 73 A6 43
Store the Stack Pointer at 43A6H, the operand of the LD SP at 43A5H: the NMI routine puts the stack back to this point (Register Pairs BC and DE saved on it), dropping the NMI's own return address.
4376
LD HL,43A2H 21 A2 43
Point Register Pair HL to 43A2H, the routine the NMI is to run when the read ends.
4379
LD (404AH),HL 22 4A 40
Store Register Pair HL (43A2H) at 404AH-404BH, the address part of the NMI vector at 4049H (which the ROM jumps to through 0066H).
437C
LD A,C3H 3E C3
Load Register A with C3H, the opcode of JP, for the NMI vector at 4049H.
437E
LD (4049H),A 32 49 40
Store Register A (C3H) at 4049H: the NMI vector is now JP 43A2H (the ROM had left EDH 45H, RETN, there).
4381
LD A,C0H 3E C0
Load Register A with C0H for port E4H, the NMI mask.
4383
OUT (E4H),A D3 E4
Send Register A (C0H) to port E4H: the controller's interrupt request and the drive motor time-out now cause an NMI.
Port E4H (NMI Mask): C0H (11000000)Function Description
Bit 7Bit 6Bit 5Bit 4Bit 3Bit 2Bit 1Bit 0Summary of Bits
11000000Bit 7 = 1: NMI from the controller's interrupt request (INTRQ) enabled
Bit 6 = 1: NMI from the drive motor time-out enabled
Bits 5-0: not used
4385
LD A,88H 3E 88
Load Register A with 88H, the Read Sector command.
1793 FDC Command: 88H (10001000)Function Description
Bit 7Bit 6Bit 5Bit 4Bit 3Bit 2Bit 1Bit 0Summary of Bits
10001000Command=Read Sector (bits 7-5 = 100)
m = 0: one sector
S = 1: side to compare (used only when C = 1)
E = 0: no 15 ms delay
C = 0: side compare off
4387
OUT (F0H),A D3 F0
Send Register A (88H, Read Sector) to port F0H, the controller's command register: read the sector in the sector register (port F2H) from the track under the head.
4389
LD HL,5100H 21 00 51
Point Register Pair HL to 5100H, the sector buffer, as the destination of the 256 bytes.
438C
LD BC,00F3H 01 F3 00
Load Register Pair BC with 00F3H: Register B = 00H, the byte count for INI (256), and Register C = F3H, the port INI reads, the controller's data register.
438F
GOSUB to 43E2H for a short delay, giving the controller time to set its busy bit for the new command. Register A returns 00H.
4392
IN A,(F0H) DB F0
Read port F0H, the controller's status, into Register A. 4395H loops back here.
4394
AND D A2
AND Register A (the status) with Register D (02H), keeping bit 1, data request. The Z FLAG is set while no byte is waiting.
4395
If the Z FLAG is set (no data request yet), LOOP BACK to 4392H: the controller is still looking for the sector.
4397
INI ED A2
Input from the port in Register C (F3H, the data register) to the byte at Register Pair HL (5100H): the first byte of the sector. Register Pair HL is incremented and Register B is decremented from 00H to FFH.
4399
LD A,E 7B
Copy Register E (the select byte with bit 6, wait states) into Register A, once: the loop below starts at 439AH and leaves Register A unchanged.
439A
OUT (F4H),A D3 F4
Send Register A (the select byte with bit 6) to port F4H. The drive stays selected, and the next read of port F3H waits until the controller has the byte. 439EH loops back here for every byte.
439C
INI ED A2
Input from the port in Register C (F3H) to the byte at Register Pair HL (the next byte of the buffer); Register Pair HL is incremented and Register B is decremented. The Z FLAG is set when Register B reaches 0: the 256th byte.
439E
If the NZ FLAG is set (Register B is not 0, bytes are left), LOOP BACK to 439AH to send the select byte in Register A again and take the next byte.
43A0
All 256 bytes are in: wait here (JUMP to 43A0H) until the controller ends the command; its interrupt request causes the NMI, which jumps through 4049H to 43A2H.

43A2H - End of the Read: the NMI Routine

Entered through the NMI vector 4049H (JP 43A2H) when the controller ends the Read Sector command (or the drive motor times out). The NMI's return address on the stack is dropped by the LD SP below.

43A2
XOR A AF
Set Register A to 00H for port E4H. The flags it sets are not used.
43A3
OUT (E4H),A D3 E4
Send Register A (00H) to port E4H: no NMI from the controller or the motor time-out.
Port E4H (NMI Mask): 00H (00000000)Function Description
Bit 7Bit 6Bit 5Bit 4Bit 3Bit 2Bit 1Bit 0Summary of Bits
00000000Bit 7 = 0: NMI from INTRQ disabled
Bit 6 = 0: NMI from the motor time-out disabled
Bits 5-0: not used
43A5
LD SP,0000H 31 00 00
Self-Modifying Code
Load the Stack Pointer with the value that 4372H stored at 43A6H (0000H in the file): the stack is back to Register Pairs BC and DE saved at 434DH/434EH, above them the return address into the loader. The NMI's return address is dropped.
43A8
IN A,(F0H) DB F0
Read port F0H, the controller's final status, into Register A.
43AA
AND FCH E6 FC
AND Register A (the status) with FCH, keeping bits 7-2. The Z FLAG is set only if none of them is set: the sector was read without an error.
1793 Status after Read/Write Sector, AND FCHFunction Description
Bit 7Bit 6Bit 5Bit 4Bit 3Bit 2Bit 1Bit 0Summary of Bits
NWRFCL00N: 1 = not ready
W: 1 = write protected (write)
R: 1 = deleted data mark F8H (read), write fault (write)
F: 1 = record not found
C: 1 = CRC error
L: 1 = lost data
Bits 1-0 (data request, busy): removed by AND FCH
43AC
LD A,D0H 3E D0
Load Register A with D0H, the Force Interrupt command. LD does not change the Z FLAG of the AND.
1793 FDC Command: D0H (11010000)Function Description
Bit 7Bit 6Bit 5Bit 4Bit 3Bit 2Bit 1Bit 0Summary of Bits
11010000Command=Force Interrupt (bits 7-4 = 1101)
I3-I0 = 0000: end the command without an interrupt
43AE
OUT (F0H),A D3 F0
Send Register A (D0H) to port F0H, the controller's command register: any command still running (after a motor time-out) is ended. OUT does not change the flags.
43B0
POP BC C1
Restore Register Pair BC from the stack at the Stack Pointer (saved at 434EH): Register B = the tries left.
43B1
POP DE D1
Restore Register Pair DE from the stack at the Stack Pointer (saved at 434DH): Register D = track and Register E = sector as they were before the side 1 adjustment.
43B2
If the NZ FLAG is set (the status in Register A showed an error), JUMP to 43C0H to restore the head and try again.
43B4
INC E 1C
INCrement Register E (the sector just read) to the next sector of SYS0/SYS.
43B5
LD A,E 7B
Copy Register E (the next sector number) into Register A.
43B6
SUB 12H D6 12
Self-Modifying Code
SUBtract 12H (18) from Register A (the next sector number). The operand at 43B7H is the number of sectors per track (both sides), stored by FORMAT (SYS6/SYS 678DH). The Z FLAG is set when the track is used up.
43B8
If the NZ FLAG is set (Register E is still a sector on this track), JUMP to 43BDH.
43BA
INC D 14
INCrement Register D, the track number, to the next track.
43BB
LD E,00H 1E 00
Self-Modifying Code
Load Register E with 00H, the first sector of the new track. FORMAT (SYS6/SYS 6778H) stores 01H in the operand at 43BCH when the drive's sectors are numbered from 1.
43BD
EXX D9
Exchange Register Pairs BC, DE and HL with the alternate set: the next track and sector go back into the alternate DE', and the main Register Pair HL is the buffer pointer again (5100H).
43BE
LD A,(HL) 7E
Fetch the first byte of the new sector at Register Pair HL (5100H) into Register A, the byte the caller of 4345H asked for.
43BF
RET C9
RETurn to the caller of 4345H (430EH, 4317H, 431BH, 4321H or 4335H) or of 4348H (4328H) with Register A = the first byte of the sector just read.

43C0H - A Failed Try: Restore and Retry

Register B = the tries left, Register Pair DE = track and sector (the main set is still the alternate one of the loader).

43C0
GOSUB to 43E2H for a short delay after the Force Interrupt at 43AEH, before the next command goes to the controller. Register A returns 00H.
43C3
LD A,0BH 3E 0B
Load Register A with 0BH, the Restore command.
1793 FDC Command: 0BH (00001011)Function Description
Bit 7Bit 6Bit 5Bit 4Bit 3Bit 2Bit 1Bit 0Summary of Bits
00001011Command=Restore (bits 7-4 = 0000)
h = 1: head load at the start
V = 0: no verify
r1 r0 = 11: stepping rate 30 ms; the code ORs in the drive's rate (6 ms, 12 ms, 20 ms or 30 ms)
43C5
OUT (F0H),A D3 F0
Send Register A (0BH, Restore) to port F0H, the controller's command register: the head goes back to track 0 and the track register (port F1H) is set to 0, so the next seek starts from a known track.
43C7
DECrement Register B (the tries left) and, if it is not 0, LOOP BACK to 434BH to select the drive and read the sector again. The restore is still running; 4357H waits for it.
43C9
LD HL,43E8H 21 E8 43
All 10 tries failed: point Register Pair HL to 43E8H, the message clear screen and ERROR, ended by 03H.

43CCH - Display a Message and Stop

Entered with Register Pair HL pointing to a message (43E8H ERROR or 43F0H NO SYS). The characters are displayed through the ROM up to the 03H that ends the message, and the computer then loops on that byte without end; the user must press RESET.

43CC
LD A,(HL) 7E
Fetch the character at Register Pair HL (the next byte of the message) into Register A. 43CFH and 43D5H loop back here.
43CD
CP 03H FE 03
Compare Register A (the message byte) against 03H, the end of message byte. The Z FLAG is set at the end.
43CF
If the Z FLAG is set (Register A = 03H, the message is fully displayed), JUMP to 43CCH: Register Pair HL is not advanced, so this reads the same 03H again and again, stopping the computer here.
43D1
INC HL 23
INCrement Register Pair HL to the next character of the message.
43D2
GOSUB to the ROM routine at 0033H to display the character in Register A at the cursor (1CH moves the cursor to the top left and 1FH erases to the end of the screen). The ROM loads Register Pair DE with 401DH, the display's control block; Register Pair HL comes back unchanged for the loop.
43D5
LOOP BACK to 43CCH for the next character of the message at Register Pair HL.

43D7H - Wait Until the Controller Is Not Busy

Returns with Register A = the controller's status (port F0H) once bit 0 (busy) is clear.

43D7
GOSUB to 43E2H for a short delay, so that the controller has set its busy bit for a command just written to port F0H. Register A returns 00H.
43DA
IN A,(F0H) DB F0
Read port F0H, the controller's status, into Register A. 43DDH loops back here.
43DC
RRCA 0F
Rotate Register A (the status) right: bit 0, busy, goes into the CARRY FLAG.
43DD
If the CARRY FLAG is set (the controller is still busy), LOOP BACK to 43DAH to read the status again.
43DF
IN A,(F0H) DB F0
Read port F0H, the controller's status, into Register A again, unrotated, for the caller.
43E1
RET C9
RETurn to the caller (4357H or 4367H) with Register A = the controller's status.

43E2H - Short Delay

A fixed delay of eight passes through a DEC/JR loop. Register A is the counter and returns 00H with the Z FLAG; no other register and no memory is touched.

43E2
LD A,08H 3E 08
Load Register A with 08H, the number of passes of the delay loop.
43E4
DEC A 3D
DECrement Register A, the delay count. The Z FLAG is set when it reaches 0. 43E5H loops back here.
43E5
If the NZ FLAG is set (Register A has not reached 0), LOOP BACK to 43E4H.
43E7
RET C9
RETurn to the caller (438FH, 43C0H or 43D7H) with Register A = 00H and the Z FLAG set.

43E8H - Messages and the Rest of the Boot Sector (Data)

The two messages displayed by 43CCH, four bytes that are not part of the boot sector image, and three bytes that FORMAT fills in from drive 0's PDRIVE record for SYS0/SYS's reset.

43E8-43EF
DEFB 1CH, 1FH / DEFM "ERROR", 03H 1C 1F 45 52 52 4F 52 03
The disk error message (43C9H): 1CH moves the cursor to the top left, 1FH erases to the end of the screen (together they clear the screen), then the text ERROR and 03H, the end of message byte that 43CDH tests for.
43F0-43F8
DEFB 1CH, 1FH / DEFM "NO SYS", 03H 1C 1F 4E 4F 20 53 59 53 03
The NO SYS message (433FH): 1CH and 1FH clear the screen, then the text NO SYS and the end of message byte 03H.
43F9-43FC
DEFB CAH, 72H, 96H, 3EH CA 72 96 3E
Not used by the boot code. These four bytes are not in SYS6/SYS's boot sector image (its 65B3H-65B6H are not loaded), so a FORMAT writes whatever its memory held there.
43FD
DEFB 00H 00
Byte FDH: byte +6 of drive 0's PDRIVE record (the value written to the sector register when the drive is selected), stored by SYS6/SYS FORMAT at 675CH. SYS0/SYS's reset reads it at 4D41H into 4297H, drive 0's +6. It is 00H.
43FE
DEFB 05H 05
Byte FEH: byte +2 of drive 0's PDRIVE record, stored by SYS6/SYS FORMAT at 67A8H. 05H = 0000 0101: step rate TSR 1 (bits 0-1) and interface code 1, TI A (bits 2-4). SYS0/SYS's reset reads it at 4D37H into 4293H, drive 0's +2.
43FF
DEFB 01H 01
Byte FFH: byte +7 of drive 0's PDRIVE record (the disk I/O flags), stored by SYS6/SYS FORMAT at 6762H. 01H: double density, tracks and sectors numbered from 0, one side. SYS0/SYS's reset reads it at 4D37H into 4298H, drive 0's +7.

Sector 1: The Copy of the Boot Sector the ROM Runs

The second sector of BOOT/SYS (track 0, sector 1) holds exactly the same 256 bytes as sector 0. SYS6/SYS writes its boot sector image as both sector 0 and sector 1 of every diskette it formats (its 67ACH-67B6H). The ROM reads sector 1 into 4300H-43FFH (it sends 01H to the sector register at 34E3H-34E5H) and runs it, so the instructions documented for sector 0 above are the ones that run; SYS0/SYS reads sector 0 (its 48B6H) when it needs byte 2, the directory lump. The rows show the file offsets 0100H-01FFH; each row's bytes run at 4300H plus the offset within the sector.

0100-011F
DEFB 00H, FEH, 11H, F3H, 11H, 05H, 00H, D9H, 31H, E0H, 41H, 21H, FFH, 51H, CDH, 45H, 43H, FEH, 20H, 47H, 30H, 29H, 57H, CDH, 45H, 43H, 4FH, CDH, 45H, 43H, 5FH, 10H 00 FE 11 F3 11 05 00 D9 31 E0 41 21 FF 51 CD 45 43 FE 20 47 30 29 57 CD 45 43 4F CD 45 43 5F 10
Bytes 00H-1FH of sector 1 (file offsets 0100H-011FH), equal byte for byte to bytes 00H-1FH of the boot sector, which run at 4300H-431FH (sector 0 above).
0120-013F
DEFB 12H, CDH, 45H, 43H, 57H, 0DH, 0DH, 2CH, CCH, 48H, 43H, 7EH, 12H, 13H, 0DH, 20H, F6H, 18H, DBH, 10H, F9H, CDH, 45H, 43H, 57H, 1AH, FEH, A5H, 13H, D5H, C8H, 21H 12 CD 45 43 57 0D 0D 2C CC 48 43 7E 12 13 0D 20 F6 18 DB 10 F9 CD 45 43 57 1A FE A5 13 D5 C8 21
Bytes 20H-3FH of sector 1 (file offsets 0120H-013FH), equal byte for byte to bytes 20H-3FH of the boot sector, which run at 4320H-433FH (sector 0 above).
0140-015F
DEFB F0H, 43H, C3H, CCH, 43H, 2CH, 7EH, C0H, D9H, 06H, 0AH, 2EH, 81H, D5H, C5H, 7BH, D6H, 12H, 38H, 03H, 5FH, 2EH, 91H, CDH, D7H, 43H, 7DH, D3H, F4H, 7AH, D3H, F3H F0 43 C3 CC 43 2C 7E C0 D9 06 0A 2E 81 D5 C5 7B D6 12 38 03 5F 2E 91 CD D7 43 7D D3 F4 7A D3 F3
Bytes 40H-5FH of sector 1 (file offsets 0140H-015FH), equal byte for byte to bytes 40H-5FH of the boot sector, which run at 4340H-435FH (sector 0 above).
0160-017F
DEFB 7BH, D3H, F2H, 3EH, 1BH, D3H, F0H, CDH, D7H, 43H, 7DH, F6H, 40H, 5FH, 16H, 02H, DBH, F0H, EDH, 73H, A6H, 43H, 21H, A2H, 43H, 22H, 4AH, 40H, 3EH, C3H, 32H, 49H 7B D3 F2 3E 1B D3 F0 CD D7 43 7D F6 40 5F 16 02 DB F0 ED 73 A6 43 21 A2 43 22 4A 40 3E C3 32 49
Bytes 60H-7FH of sector 1 (file offsets 0160H-017FH), equal byte for byte to bytes 60H-7FH of the boot sector, which run at 4360H-437FH (sector 0 above).
0180-019F
DEFB 40H, 3EH, C0H, D3H, E4H, 3EH, 88H, D3H, F0H, 21H, 00H, 51H, 01H, F3H, 00H, CDH, E2H, 43H, DBH, F0H, A2H, 28H, FBH, EDH, A2H, 7BH, D3H, F4H, EDH, A2H, 20H, FAH 40 3E C0 D3 E4 3E 88 D3 F0 21 00 51 01 F3 00 CD E2 43 DB F0 A2 28 FB ED A2 7B D3 F4 ED A2 20 FA
Bytes 80H-9FH of sector 1 (file offsets 0180H-019FH), equal byte for byte to bytes 80H-9FH of the boot sector, which run at 4380H-439FH (sector 0 above).
01A0-01BF
DEFB 18H, FEH, AFH, D3H, E4H, 31H, 00H, 00H, DBH, F0H, E6H, FCH, 3EH, D0H, D3H, F0H, C1H, D1H, 20H, 0CH, 1CH, 7BH, D6H, 12H, 20H, 03H, 14H, 1EH, 00H, D9H, 7EH, C9H 18 FE AF D3 E4 31 00 00 DB F0 E6 FC 3E D0 D3 F0 C1 D1 20 0C 1C 7B D6 12 20 03 14 1E 00 D9 7E C9
Bytes A0H-BFH of sector 1 (file offsets 01A0H-01BFH), equal byte for byte to bytes A0H-BFH of the boot sector, which run at 43A0H-43BFH (sector 0 above).
01C0-01DF
DEFB CDH, E2H, 43H, 3EH, 0BH, D3H, F0H, 10H, 82H, 21H, E8H, 43H, 7EH, FEH, 03H, 28H, FBH, 23H, CDH, 33H, 00H, 18H, F5H, CDH, E2H, 43H, DBH, F0H, 0FH, 38H, FBH, DBH CD E2 43 3E 0B D3 F0 10 82 21 E8 43 7E FE 03 28 FB 23 CD 33 00 18 F5 CD E2 43 DB F0 0F 38 FB DB
Bytes C0H-DFH of sector 1 (file offsets 01C0H-01DFH), equal byte for byte to bytes C0H-DFH of the boot sector, which run at 43C0H-43DFH (sector 0 above).
01E0-01FF
DEFB F0H, C9H, 3EH, 08H, 3DH, 20H, FDH, C9H, 1CH, 1FH, 45H, 52H, 52H, 4FH, 52H, 03H, 1CH, 1FH, 4EH, 4FH, 20H, 53H, 59H, 53H, 03H, CAH, 72H, 96H, 3EH, 00H, 05H, 01H F0 C9 3E 08 3D 20 FD C9 1C 1F 45 52 52 4F 52 03 1C 1F 4E 4F 20 53 59 53 03 CA 72 96 3E 00 05 01
Bytes E0H-FFH of sector 1 (file offsets 01E0H-01FFH), equal byte for byte to bytes E0H-FFH of the boot sector, which run at 43E0H-43FFH (sector 0 above).

Sector 2: The System Data Sector (Data)

The third sector of BOOT/SYS (track 0, sector 2) holds the system data of the diskette: ten 16-byte PDRIVE records (drives 0-9), the number options at A0H-A9H and D0H-D1H, the validity byte EFH and the yes/no options at F0H-F9H. SYS0/SYS's reset reads it into its buffer at 4300H through the DOS FCB at 4480H (NEXT = sector 2, its 4D47H-4D4AH) and copies what it needs; SYS16/SYS (PDRIVE, FCB 510EH) and SYS17/SYS (SYSTEM, FCB 4F16H) read, change and rewrite it; SYS6/SYS FORMAT writes it (666DH). The rows show the file offsets 0200H-02FFH; in the buffer each byte is at 4300H plus its offset within the sector (byte A0H at 43A0H).

0200-020F
DEFB 11H, 48H, 05H, 28H, 12H, 02H, 00H, 01H, 11H, 02H, 00H, 00H, 01H, 01H, 00H, 04H 11 48 05 28 12 02 00 01 11 02 00 00 01 01 00 04
PDRIVE record for drive 0. +00H = 11H: the directory starts at lump 17 (DDSL). +01H = 48H: 72 lumps (40 tracks x 18 sectors = 144 granules of 5 sectors, 2 per lump). +02H = 05H: step rate TSR 1 (bits 0-1), interface code 1 (TI A) (bits 2-4). +03H = 28H: 40 tracks (TC). +04H = 12H: 18 sectors per track (SPT). +05H = 02H: 2 granules per lump (GPL). +06H = 00H: the value written to the sector register when the drive is selected. +07H = 01H, the disk I/O flags: double density, tracks numbered from 0, sectors numbered from 0, one side. +08H = 11H: DDSL 17 as typed. +09H = 02H: DDGA 2, the directory granules. +0AH and +0BH = 00H. +0CH = 01H: TSR 1 as typed. +0DH, +0EH = 01H, 00H: the TI letters A. +0FH = 04H: TD 4 (5 inch, one side, double density). Option AL is 4, so SYS0/SYS's reset copies bytes +00H to +09H of this record to 4291H-429AH (its 4DEFH).
0210-021F
DEFB 11H, 48H, 05H, 28H, 12H, 02H, 00H, 01H, 11H, 02H, 00H, 00H, 01H, 01H, 00H, 04H 11 48 05 28 12 02 00 01 11 02 00 00 01 01 00 04
PDRIVE record for drive 1. +00H = 11H: the directory starts at lump 17 (DDSL). +01H = 48H: 72 lumps (40 tracks x 18 sectors = 144 granules of 5 sectors, 2 per lump). +02H = 05H: step rate TSR 1 (bits 0-1), interface code 1 (TI A) (bits 2-4). +03H = 28H: 40 tracks (TC). +04H = 12H: 18 sectors per track (SPT). +05H = 02H: 2 granules per lump (GPL). +06H = 00H: the value written to the sector register when the drive is selected. +07H = 01H, the disk I/O flags: double density, tracks numbered from 0, sectors numbered from 0, one side. +08H = 11H: DDSL 17 as typed. +09H = 02H: DDGA 2, the directory granules. +0AH and +0BH = 00H. +0CH = 01H: TSR 1 as typed. +0DH, +0EH = 01H, 00H: the TI letters A. +0FH = 04H: TD 4 (5 inch, one side, double density). Option AL is 4, so SYS0/SYS's reset copies bytes +00H to +09H of this record to 429BH-42A4H (its 4DEFH).
0220-022F
DEFB 11H, 48H, 05H, 28H, 12H, 02H, 00H, 01H, 11H, 02H, 00H, 00H, 01H, 01H, 00H, 04H 11 48 05 28 12 02 00 01 11 02 00 00 01 01 00 04
PDRIVE record for drive 2. +00H = 11H: the directory starts at lump 17 (DDSL). +01H = 48H: 72 lumps (40 tracks x 18 sectors = 144 granules of 5 sectors, 2 per lump). +02H = 05H: step rate TSR 1 (bits 0-1), interface code 1 (TI A) (bits 2-4). +03H = 28H: 40 tracks (TC). +04H = 12H: 18 sectors per track (SPT). +05H = 02H: 2 granules per lump (GPL). +06H = 00H: the value written to the sector register when the drive is selected. +07H = 01H, the disk I/O flags: double density, tracks numbered from 0, sectors numbered from 0, one side. +08H = 11H: DDSL 17 as typed. +09H = 02H: DDGA 2, the directory granules. +0AH and +0BH = 00H. +0CH = 01H: TSR 1 as typed. +0DH, +0EH = 01H, 00H: the TI letters A. +0FH = 04H: TD 4 (5 inch, one side, double density). Option AL is 4, so SYS0/SYS's reset copies bytes +00H to +09H of this record to 42A5H-42AEH (its 4DEFH).
0230-023F
DEFB 11H, 48H, 05H, 28H, 12H, 02H, 00H, 01H, 11H, 02H, 00H, 00H, 01H, 01H, 00H, 04H 11 48 05 28 12 02 00 01 11 02 00 00 01 01 00 04
PDRIVE record for drive 3. +00H = 11H: the directory starts at lump 17 (DDSL). +01H = 48H: 72 lumps (40 tracks x 18 sectors = 144 granules of 5 sectors, 2 per lump). +02H = 05H: step rate TSR 1 (bits 0-1), interface code 1 (TI A) (bits 2-4). +03H = 28H: 40 tracks (TC). +04H = 12H: 18 sectors per track (SPT). +05H = 02H: 2 granules per lump (GPL). +06H = 00H: the value written to the sector register when the drive is selected. +07H = 01H, the disk I/O flags: double density, tracks numbered from 0, sectors numbered from 0, one side. +08H = 11H: DDSL 17 as typed. +09H = 02H: DDGA 2, the directory granules. +0AH and +0BH = 00H. +0CH = 01H: TSR 1 as typed. +0DH, +0EH = 01H, 00H: the TI letters A. +0FH = 04H: TD 4 (5 inch, one side, double density). Option AL is 4, so SYS0/SYS's reset copies bytes +00H to +09H of this record to 42AFH-42B8H (its 4DEFH).
0240-024F
DEFB 11H, 28H, 26H, 28H, 12H, 06H, 00H, 11H, 11H, 02H, 00H, 00H, 02H, 01H, 10H, 04H 11 28 26 28 12 06 00 11 11 02 00 00 02 01 10 04
PDRIVE record for drive 4. +00H = 11H: the directory starts at lump 17 (DDSL). +01H = 28H: 40 lumps (40 tracks x 18 sectors = 240 granules of 3 sectors, 6 per lump). +02H = 26H: step rate TSR 2 (bits 0-1), interface code 1 (TI A) (bits 2-4), bit 5 TI M. +03H = 28H: 40 tracks (TC). +04H = 12H: 18 sectors per track (SPT). +05H = 06H: 6 granules per lump (GPL). +06H = 00H: the value written to the sector register when the drive is selected. +07H = 11H, the disk I/O flags: double density, tracks numbered from 0, sectors numbered from 1, one side. +08H = 11H: DDSL 17 as typed. +09H = 02H: DDGA 2, the directory granules. +0AH and +0BH = 00H. +0CH = 02H: TSR 2 as typed. +0DH, +0EH = 01H, 10H: the TI letters AM. +0FH = 04H: TD 4 (5 inch, one side, double density). Drive 4 is above option AL (4): SYS0/SYS's reset only checks its +02H (bits 2-4 not 0, its 4DF1H-4DF6H).
0250-025F
DEFB 11H, 28H, 06H, 28H, 0AH, 02H, 00H, 00H, 11H, 02H, 00H, 00H, 02H, 01H, 00H, 00H 11 28 06 28 0A 02 00 00 11 02 00 00 02 01 00 00
PDRIVE record for drive 5. +00H = 11H: the directory starts at lump 17 (DDSL). +01H = 28H: 40 lumps (40 tracks x 10 sectors = 80 granules of 5 sectors, 2 per lump). +02H = 06H: step rate TSR 2 (bits 0-1), interface code 1 (TI A) (bits 2-4). +03H = 28H: 40 tracks (TC). +04H = 0AH: 10 sectors per track (SPT). +05H = 02H: 2 granules per lump (GPL). +06H = 00H: the value written to the sector register when the drive is selected. +07H = 00H, the disk I/O flags: single density, tracks numbered from 0, sectors numbered from 0, one side. +08H = 11H: DDSL 17 as typed. +09H = 02H: DDGA 2, the directory granules. +0AH and +0BH = 00H. +0CH = 02H: TSR 2 as typed. +0DH, +0EH = 01H, 00H: the TI letters A. +0FH = 00H: TD 0 (5 inch, one side, single density). Drive 5 is above option AL (4): SYS0/SYS's reset only checks its +02H (bits 2-4 not 0, its 4DF1H-4DF6H).
0260-026F
DEFB 11H, 48H, 46H, 28H, 12H, 02H, 00H, 03H, 11H, 02H, 00H, 00H, 02H, 01H, 04H, 04H 11 48 46 28 12 02 00 03 11 02 00 00 02 01 04 04
PDRIVE record for drive 6. +00H = 11H: the directory starts at lump 17 (DDSL). +01H = 48H: 72 lumps (40 tracks x 18 sectors = 144 granules of 5 sectors, 2 per lump). +02H = 46H: step rate TSR 2 (bits 0-1), interface code 1 (TI A) (bits 2-4), bit 6 TI K. +03H = 28H: 40 tracks (TC). +04H = 12H: 18 sectors per track (SPT). +05H = 02H: 2 granules per lump (GPL). +06H = 00H: the value written to the sector register when the drive is selected. +07H = 03H, the disk I/O flags: double density, tracks numbered from 1, sectors numbered from 0, one side. +08H = 11H: DDSL 17 as typed. +09H = 02H: DDGA 2, the directory granules. +0AH and +0BH = 00H. +0CH = 02H: TSR 2 as typed. +0DH, +0EH = 01H, 04H: the TI letters AK. +0FH = 04H: TD 4 (5 inch, one side, double density). Drive 6 is above option AL (4): SYS0/SYS's reset only checks its +02H (bits 2-4 not 0, its 4DF1H-4DF6H).
0270-027F
DEFB 11H, A0H, 06H, 50H, 14H, 02H, 00H, 40H, 11H, 02H, 00H, 00H, 02H, 01H, 00H, 02H 11 A0 06 50 14 02 00 40 11 02 00 00 02 01 00 02
PDRIVE record for drive 7. +00H = 11H: the directory starts at lump 17 (DDSL). +01H = A0H: 160 lumps (80 tracks x 20 sectors = 320 granules of 5 sectors, 2 per lump). +02H = 06H: step rate TSR 2 (bits 0-1), interface code 1 (TI A) (bits 2-4). +03H = 50H: 80 tracks (TC). +04H = 14H: 20 sectors per track (SPT). +05H = 02H: 2 granules per lump (GPL). +06H = 00H: the value written to the sector register when the drive is selected. +07H = 40H, the disk I/O flags: single density, tracks numbered from 0, sectors numbered from 0, two sides. +08H = 11H: DDSL 17 as typed. +09H = 02H: DDGA 2, the directory granules. +0AH and +0BH = 00H. +0CH = 02H: TSR 2 as typed. +0DH, +0EH = 01H, 00H: the TI letters A. +0FH = 02H: TD 2 (5 inch, two sides, single density). Drive 7 is above option AL (4): SYS0/SYS's reset only checks its +02H (bits 2-4 not 0, its 4DF1H-4DF6H).
0280-028F
DEFB 11H, 48H, 06H, 28H, 12H, 02H, 00H, 01H, 11H, 02H, 00H, 00H, 02H, 01H, 00H, 04H 11 48 06 28 12 02 00 01 11 02 00 00 02 01 00 04
PDRIVE record for drive 8. +00H = 11H: the directory starts at lump 17 (DDSL). +01H = 48H: 72 lumps (40 tracks x 18 sectors = 144 granules of 5 sectors, 2 per lump). +02H = 06H: step rate TSR 2 (bits 0-1), interface code 1 (TI A) (bits 2-4). +03H = 28H: 40 tracks (TC). +04H = 12H: 18 sectors per track (SPT). +05H = 02H: 2 granules per lump (GPL). +06H = 00H: the value written to the sector register when the drive is selected. +07H = 01H, the disk I/O flags: double density, tracks numbered from 0, sectors numbered from 0, one side. +08H = 11H: DDSL 17 as typed. +09H = 02H: DDGA 2, the directory granules. +0AH and +0BH = 00H. +0CH = 02H: TSR 2 as typed. +0DH, +0EH = 01H, 00H: the TI letters A. +0FH = 04H: TD 4 (5 inch, one side, double density). Drive 8 is above option AL (4): SYS0/SYS's reset only checks its +02H (bits 2-4 not 0, its 4DF1H-4DF6H).
0290-029F
DEFB 11H, 28H, 26H, 28H, 12H, 06H, 00H, 11H, 11H, 02H, 00H, 00H, 02H, 01H, 10H, 04H 11 28 26 28 12 06 00 11 11 02 00 00 02 01 10 04
PDRIVE record for drive 9. +00H = 11H: the directory starts at lump 17 (DDSL). +01H = 28H: 40 lumps (40 tracks x 18 sectors = 240 granules of 3 sectors, 6 per lump). +02H = 26H: step rate TSR 2 (bits 0-1), interface code 1 (TI A) (bits 2-4), bit 5 TI M. +03H = 28H: 40 tracks (TC). +04H = 12H: 18 sectors per track (SPT). +05H = 06H: 6 granules per lump (GPL). +06H = 00H: the value written to the sector register when the drive is selected. +07H = 11H, the disk I/O flags: double density, tracks numbered from 0, sectors numbered from 1, one side. +08H = 11H: DDSL 17 as typed. +09H = 02H: DDGA 2, the directory granules. +0AH and +0BH = 00H. +0CH = 02H: TSR 2 as typed. +0DH, +0EH = 01H, 10H: the TI letters AM. +0FH = 04H: TD 4 (5 inch, one side, double density). Drive 9 is above option AL (4): SYS0/SYS's reset only checks its +02H (bits 2-4 not 0, its 4DF1H-4DF6H).
02A0
DEFB 04H 04
Byte A0H (04H in the buffer at 4300H): option AL = 4, the number of drives. SYS0/SYS's reset (4D6FH) stores it at 42BFH and as the operand at 4727H (the drive limit of the select routine); it must be 1-4, else error 27H.
02A1
DEFB 02H 02
Byte A1H (02H in the buffer at 4300H): option AW = 2, the number of tries of a write with verify. SYS0/SYS's reset (4D7DH) stores it as the operand at 4A5FH.
02A2
DEFB 00H 00
Byte A2H (00H in the buffer at 4300H): option AN = 0, the default drive of the DIR command. SYS0/SYS's reset (4D83H) stores it at 42C0H.
02A3
DEFB 00H 00
Byte A3H (00H in the buffer at 4300H): option AO = 0, the first drive searched for room when a file is created. SYS0/SYS's reset (4D89H) stores it at 42C1H.
02A4
DEFB 00H 00
Byte A4H (00H in the buffer at 4300H): no option uses this byte (SYS17/SYS's option table names none here); it is 00H.
02A5
DEFB 00H 00
Byte A5H (00H in the buffer at 4300H): option BI = 0, the cursor character. 0 keeps the ROM's own cursor: SYS0/SYS's reset stores a value other than 0 at 4023H (4E28H-4E2EH).
02A6
DEFB 0AH 0A
Byte A6H (0AH in the buffer at 4300H): option AM = 10 (0AH), the number of tries of a disk read or write. SYS0/SYS's reset (4D8FH) stores it as the operand at 4605H.
02A7
DEFB 1EH 1E
Byte A7H (1EH in the buffer at 4300H): option AV = 30 (1EH), the 25 ms ticks before a held key repeats. SYS0/SYS's reset (4E1FH) stores it at 4534H and 4508H when option AU is Y.
02A8
DEFB DFH DF
Byte A8H (DFH in the buffer at 4300H): option AX = 223 (DFH), the highest character the printer can print. SYS0/SYS's reset (4DB9H) stores it at 4290H.
02A9
DEFB 01H 01
Byte A9H (01H in the buffer at 4300H): option BJ = 1, the CPU speed factor. SYS0/SYS's reset (4D95H-4DB6H) stores it at 42C2H and 4C94H, 8 x BJ at 478AH and 2A00H x BJ at 4799H.
02AA-02CF
DEFB 00H x 38 00 x 38
Bytes AAH-CFH: no option uses these 38 bytes (SYS17/SYS's option table names none of them); all 00H.
02D0-02D1
DEFW 0000H 00 00
Bytes D0H-D1H: option AP = 0000H, the HIMEM wanted. SYS0/SYS's reset reads it at 4DC2H; 0000H leaves HIMEM (4411H) at the top of memory it found.
02D2-02EE
DEFB 00H x 29 00 x 29
Bytes D2H-EEH: no option uses these 29 bytes (SYS17/SYS's option table names none of them); all 00H.
02EF
DEFB A5H A5
Byte EFH: A5H, the mark of a valid system data sector. SYS0/SYS's reset tests it at 4D50H-4D55H (error 27H without it).
02F0
DEFB 20H 20
Byte F0H = 20H (0010 0000), copied to 428CH by SYS0/SYS's reset (4D63H): bit 7 AA = N (diskette passwords not checked), bit 6 AB = N (not RUN-ONLY), bit 5 AG = Y (BREAK is a key: 4E7BH sets 4289H bit 4), bit 1 AR = N. Bit 4 is set in 428CH by every reset (4E7FH); bits 3, 2 and 0 belong to no option.
02F1
DEFB F8H F8
Byte F1H = F8H (1111 1000), copied to 428DH (4D66H): bit 7 AT = Y (a chain file gives the keys for every keyboard request), bit 6 BC = Y (the arrow keys can stop or pause a chain file), bit 5 BE = Y (the R command repeats the last command), bit 4 BK = Y (WRDIRP allowed). Bit 3 is set but belongs to no option in SYS17/SYS's table.
02F2
DEFB 80H 80
Byte F2H = 80H, copied to 428EH by SYS0/SYS's reset (4D69H-4D6CH). No SYSTEM option uses this byte.
02F3
DEFB 00H 00
Byte F3H = 00H, copied to 428FH by SYS0/SYS's reset (4D69H-4D6CH). No SYSTEM option uses this byte.
02F4-02F7
DEFB 00H x 4 00 x 4
Bytes F4H-F7H: no option uses them and SYS0/SYS's reset does not read them; all 00H.
02F8
DEFB 77H 77
Byte F8H = 77H (0111 0111), read by SYS0/SYS's reset into Register C (4E02H) and kept at 504BH: bit 6 AD = Y (J-K-L screen print), bit 5 AE = Y (1-2-3 enters DEBUG), bit 4 AF = Y (D-F-G enters MINI-DOS), bit 2 AQ = Y (the CLEAR key is passed on), bit 1 AJ = Y (the DOS keyboard driver 44EBH), bit 0 AU = Y (repeat key). Bits 7 and 3 are 0 and belong to no option.
02F9
DEFB 0AH 0A
Byte F9H = 0AH (0000 1010), read by the reset into Register B (4E02H) and kept at 504CH: bit 7 AY = N and bit 6 AZ = N (no date and time questions), bit 5 BA = N (no ROUTE,DO,NL), bit 4 BB = N (60 Hz clock interrupts), bit 3 BD = Y (ENTER held at reset skips the AUTO command), bit 1 BG = Y (caps lock off, 4E49H), bit 0 BH = N (the cursor does not blink: 4E51H stores 01H at 401CH). Bit 2 is 0 and belongs to no option.
02FA
DEFB 00H 00
Byte FAH = 00H, copied with bytes F8H-FFH to 504DH by SYS0/SYS's reset (4D58H-4D61H). SYS17/SYS's option table names no option in this byte.
02FB
DEFB 46H 46
Byte FBH = 46H (0100 0110), copied to 504EH by SYS0/SYS's reset (4D58H-4D61H). SYS17/SYS's option table names no option in this byte, and no verified file of this DOS reads it.
02FC-02FF
DEFB 00H x 4 00 x 4
Bytes FCH-FFH, copied to 504FH-5052H by SYS0/SYS's reset (4D58H-4D61H); no option uses them; all 00H.

Sectors 3 and 4: Unused (Data)

BOOT/SYS is five sectors long because it fills the first granule of the diskette (five sectors). Only sectors 0-2 hold data: sectors 3 and 4 keep the pattern FORMAT writes into the data field of every double density sector (5BH, SYS6/SYS format table line 2 at 6CF5H), since nothing writes them afterwards.

0300-03FF
DEFB 5BH x 256 5B x 256
Sector 3 (track 0, sector 3, file offsets 0300H-03FFH): 256 bytes of 5BH, the format pattern; no data, and no code of this DOS reads them.
0400-04FF
DEFB 5BH x 256 5B x 256
Sector 4 (track 0, sector 4, file offsets 0400H-04FFH): 256 bytes of 5BH, the format pattern; it is the last sector of BOOT/SYS's granule, and SYS0/SYS starts at sector 5.