DOSPLUS 3.5 for the Model I - BOOT/SYS Disassembled

Page Customization

Introduction/Summary

DOSPLUS 3.5 BOOT/SYS Disassembly - The Boot Sector and the Boot Settings Sector (Model I)

BOOT/SYS is the first file of every DOSPLUS 3.5 diskette: granule 0 of cylinder 0, sectors 0-4 (its directory entry, the first entry of directory sector 2, gives 5 sectors in one granule). It is not a load module. Sector 0 is the boot sector the ROM runs, sector 1 is a byte for byte copy of it, sector 2 holds this diskette's copy of the perishable part of its drive control table (DCT) and the boot settings the SYSTEM command keeps, and sectors 3 and 4 are 00H. Byte 2 of sector 0 holds the directory cylinder, 11H (cylinder 17).

When the computer is reset with a diskette in drive 0, the ROM reads cylinder 0, sector 0 into 4200H-42FFH and jumps to 4200H. The boot sector clears the screen, reads sector 2 into 5200H, and switches a double density adapter to double density when the diskette's flags say so (bit 7 of 5203H; clear on this diskette). It then reads sector 4 of the directory cylinder (byte 0AH of sector 2) into 5300H, checks that its first entry is an active system file, works out from the entry's first segment descriptor where SYS0/SYS starts, and reads SYS0/SYS sector by sector into 5300H-53FFH, copying each load block to its address. The transfer record sends it to SYS0/SYS at 4E00H, with Index Register IX still pointing to the settings at 5200H. A sector that cannot be read in two tries, or a wrong directory entry, displays ERROR! and stops the computer until RESET is pressed.

Sector 0 is shown at 4200H-42FFH, where it runs, and sector 2 at 5200H-52FFH, where the boot sector reads it; sectors 1, 3 and 4 are shown at their file offsets (0100H-01FFH, 0300H-04FFH).

How Sector 0 Reads a Sector

Sector 0 works the floppy disk controller through its memory mapped registers, polling the status:

StepWhat the code does
Select01H (drive 0, side 0) or 09H (drive 0, side 1) to the drive select latch 37E1H before every read (42B9H); the byte fetch sets or clears bit 3 of the operand at 42BAH (4294H, 429DH)
SeekSector to 37EEH, cylinder to the data register 37EFH, command 13H to 37ECH, then a wait for BUSY to go off (42BEH)
ReadCommand 88H, then each byte is taken from 37EFH while DATA REQUEST is set, until BUSY goes off (42D5H)
CheckStatus AND 9CH (not ready, record not found, CRC error, lost data); a failed first try is followed by one more (42B2H)

The main register set does the loading (Register H = the record type, Register B = the bytes left in the record, Register Pair HL = the load address); the alternate set does the reading (Register D' = cylinder, Register B' = sector within the cylinder, Register Pair HL' = the buffer pointer). The side is chosen from the sector number against the sectors per track, the next cylinder from the sectors per cylinder, both taken from sector 2.

The Five Sectors

SectorContents
0The boot sector the ROM runs, 4200H. Byte 2 is the directory cylinder (11H).
1A copy of sector 0, 0100H, not read during the boot.
2The drive control table copy and the boot settings, 5200H: density and directory protection flags, surfaces, sectors per track, directory length, sectors per granule, granules per cylinder, sectors per cylinder, directory cylinder and cylinder count (bytes 03H-0BH); the time, date and logo switches and the alternate driver flag (byte 10H); the alternate driver address, the cursor blink, the cursor character, the caps switch, the default step rate and a port and value to output at boot (bytes 11H-18H).
300H, 0300H: the manual gives sectors 3 and up to an alternate system driver; this diskette has none.
400H, 0400H.

Variables

Memory Outside BOOT/SYS

Address
Size
Contents
37E1H
1 byte
Drive Select Latch
Written with 01H (drive 0, side 0) or 09H (drive 0, side 1) at 42BBH before each sector read.
37ECH
1 byte
Controller Command and Status
FFH (double density adapter on, only for a double density diskette, 421CH), D0H (Force Interrupt, 4222H), 13H (Seek, 42CAH) and 88H (Read Sector, 42D5H) are written here; reading gives the status (bit 0 BUSY, bit 1 DATA REQUEST, bit 2 LOST DATA, bit 3 CRC ERROR, bit 4 RECORD NOT FOUND, bit 7 NOT READY).
37EDH
1 byte
Controller Track Register
Set to 00H at 4222H for a double density diskette.
37EEH
1 byte
Controller Sector Register
The sector to read, stored with the cylinder by LD (37EEH),DE at 42BEH.
37EFH
1 byte
Controller Data Register
The cylinder for the seek (42BEH), then each byte of the sector as it is read (42E2H).
4200H-42FFH
256 bytes
Boot Sector
Sector 0, where the ROM puts it and runs it.
5200H-52FFH
256 bytes
Sector 2 Buffer
Sector 2 of BOOT/SYS, read at 420CH; Index Register IX points here for the rest of the boot and SYS0/SYS's start-up reads its fields here.
5300H-53FFH
256 bytes
Sector Buffer
The directory sector with SYS0/SYS's entry (5300H flags, 5316H-5317H first segment descriptor), then each sector of SYS0/SYS.

BOOT/SYS Data and Changed Operands

Address
Size
Contents
4202H
1 byte
Directory Cylinder
Byte 2 of the boot sector, the operand of CP 11H: 11H. The boot sector itself takes the directory cylinder from 520AH.
42BAH
1 byte
Drive Select Value
The operand of LD A,01H at 42B9H: 01H for side 0, 09H for side 1 (bit 3 reset at 4294H, set at 429DH).
42F9H-42FEH
6 bytes
Error Text
ERROR!, displayed by 427EH.

Sector 2 (at 5200H)

Address
Size
Contents
5200H-5202H
3 bytes
Mark
DCT.
5203H
1 byte
Diskette Flags
40H: bit 7 double density (tested at 4214H), bit 6 protected directory.
5204H
1 byte
Surfaces
01H.
5205H
1 byte
Sectors per Track
0AH, read at 4298H.
5206H
1 byte
Directory Length
0AH sectors.
5207H
1 byte
Sectors per Granule
05H, read at 4246H.
5208H
1 byte
Granules per Cylinder
02H.
5209H
1 byte
Sectors per Cylinder
0AH, read at 42A8H.
520AH
1 byte
Directory Cylinder
11H, read at 4226H.
520BH
1 byte
Cylinder Count
23H (35).
5210H
1 byte
Boot Flags
0EH: bit 3 ask the time, bit 2 ask the date, bit 1 display the logo, bit 0 jump to an alternate system driver (read by SYS0/SYS).
5211H-5212H
2 bytes
Alternate System Driver Address
0000H.
5213H
1 byte
Cursor Blink
00H, a steady cursor.
5214H
1 byte
Cursor Character
5FH.
5215H
1 byte
Caps Switch
FFH, capitals.
5216H
1 byte
Default Step Rate
03H.
5217H-5218H
2 bytes
Boot Port and Value
Port 00H, value 00H.

Outside Routines

AddressContents
0033HROM: display the character in Register A (4285H).
01C9HROM: clear the screen (4203H).
4E00HSYS0/SYS: its start-up, the transfer address of SYS0/SYS on this diskette (reached by JP (HL) at 4266H).

Disassembly

4200H - Sector 0: Boot Sector Entry

When the computer is reset with a diskette in drive 0, the ROM reads cylinder 0, sector 0 (single density) into 4200H-42FFH and jumps to 4200H. This sector reads sector 2 of BOOT/SYS (the drive control table copy and the boot settings) into 5200H, finds the directory entry of SYS0/SYS (the first entry of sector 4 of the directory cylinder) and loads SYS0/SYS from its first segment, record by record, until the transfer record sends it to SYS0/SYS. It works the floppy disk controller directly through its memory mapped registers at 37ECH-37EFH and uses the stack the ROM left (the ROM's boot loads the Stack Pointer with 407DH).

4200
NOP 00
No operation. Byte 0 of the boot sector is 00H; execution passes to 4201H.
4201
CP 11H FE 11
Compare Register A against 11H. The flags are never tested: the instruction only steps over byte 2 of the sector (4202H), which is data: 11H, the cylinder that holds the directory (17). FORMAT/CMD writes the directory cylinder there; this boot sector takes the directory cylinder from sector 2 instead (520AH, at 4226H).
4203
GOSUB to the ROM's clear screen routine at 01C9H: the screen is cleared and the cursor goes to the top left. Register A is used by the ROM routine.
4206
LD DE,0002H 11 02 00
Load Register Pair DE with 0002H: Register D = cylinder 00H, Register E = sector 02H, the third sector of BOOT/SYS, which holds the drive control table copy and the boot settings of this diskette.
4209
LD HL,5200H 21 00 52
Point Register Pair HL to 5200H, the 256 byte buffer sector 2 is read into. 5200H stays the base of those settings: SYS0/SYS's start-up reads them there.
420C
GOSUB to 42B2H to read cylinder Register D (00H), sector Register E (02H) into the buffer at Register Pair HL (5200H), two tries. On return the Z FLAG is set if a try succeeded and Register A holds the controller status masked with 9CH.
420F
If the NZ FLAG is set (sector 2 could not be read in two tries), JUMP to 427EH to display ERROR! and stop.
4211
PUSH HL E5
Save Register Pair HL (5200H, the start of sector 2) to the top of the stack, to move it into Index Register IX.
4212
POP IX DD E1
Restore Index Register IX from the top of the stack: Index Register IX = 5200H. Every field of sector 2 below is read as IX plus an offset for the rest of the boot.
4214
BIT 7,(IX+03H) DD CB 03 7E
Test bit 7 of the byte at Index Register IX+03H (5203H, the density flag of the drive control table copy: 0 single density, 1 double density). On this diskette the byte is 40H, so bit 7 is 0 and the Z FLAG is set.
4218
If the Z FLAG is set (bit 7 of 5203H is 0: a single density diskette), JUMP to 4226H, leaving the controller as the ROM left it.
421A
LD A,FFH 3E FF
Double density diskette: load Register A with FFH, the value DOSPLUS stores to 37ECH to switch the double density adapter to double density. The RS/TXT patch file on the distribution diskette (DO RS, for the Radio Shack Double Density Kit 26-1143) carries the DISKZAP values 80H and EEH, the same change it makes in SYS0/SYS: 80H stored to 37EEH.
421C
LD (37ECH),A 32 EC 37
Store Register A (FFH) to 37ECH, the controller's command register address: the double density adapter is switched to double density.
421F
LD DE,00D0H 11 D0 00
Load Register Pair DE with 00D0H: Register E = D0H, the Force Interrupt command with no interrupt condition, and Register D = 00H for the track register.
4222
LD (37ECH),DE ED 53 EC 37
Store Register Pair DE to 37ECH-37EDH: Register E (D0H, Force Interrupt) goes to the command register 37ECH, ending any command so the controller is idle, and Register D (00H) to the track register 37EDH: the head is on cylinder 0, where the ROM's boot left it.

4226H - Find SYS0/SYS in the Directory

The directory cylinder is byte 0AH of sector 2. Sector 4 of that cylinder holds the directory entry of SYS0/SYS in its first 32 bytes; the entry is read into 5300H and must describe an active system file.

4226
LD D,(IX+0AH) DD 56 0A
Load Register D with the byte at Index Register IX+0AH (520AH, the directory cylinder of the drive control table copy: 11H, cylinder 17), the cylinder for the next read.
4229
LD E,04H 1E 04
Load Register E with 04H: sector 4 of the directory cylinder, whose first directory entry (bytes 00H-1FH) is the entry of SYS0/SYS. Sectors 0 and 1 of the directory hold the granule allocation table and the hash index table; the first entries of sectors 2 and 3 are BOOT/SYS and DIR/SYS.
422B
INC H 24
Increment Register H: Register Pair HL goes from 5200H to 5300H, the buffer for the directory sector (and later for each sector of SYS0/SYS).
422C
GOSUB to 42B2H to read cylinder Register D (the directory cylinder), sector Register E (04H) into the buffer at Register Pair HL (5300H), two tries. On return the Z FLAG is set if a try succeeded.
422F
If the NZ FLAG is set (the directory sector could not be read), JUMP to 427EH to display ERROR! and stop.
4231
LD A,(HL) 7E
Fetch byte 00H of the directory entry from the address in Register Pair HL (5300H) into Register A: the flags of SYS0/SYS's entry (5EH on this diskette: bit 6 system file, bit 4 active file, bit 3 invisible, protection level 6).
4232
CPL 2F
Complement Register A: every bit of the entry's flags is inverted, so bits 6 and 4 are 0 when they were set in the entry.
4233
AND 50H E6 50
Mask Register A with 50H to bits 6 and 4 of the inverted flags. The Z FLAG is set only when both bits were set in the entry: an active (bit 4) system (bit 6) file.
4235
If the NZ FLAG is set (the first entry of directory sector 4 is not an active system file), JUMP to 427EH to display ERROR! and stop.

4237H - Work Out Where SYS0/SYS Starts

The first segment descriptor of the entry (5316H-5317H) gives the cylinder and the granule SYS0/SYS starts at. The alternate register set becomes the reading context: Register D' the cylinder, Register B' the sector within the cylinder, Register Pair HL' the pointer into the buffer at 5300H.

4237
EXX D9
Exchange Register Pairs BC, DE and HL with the alternate set: the registers loaded next are the reading context of the byte fetch at 428CH, which works in the alternate set.
4238
LD HL,(5316H) 2A 16 53
Fetch the first segment descriptor of SYS0/SYS from 5316H-5317H (bytes 16H-17H of the entry) into Register Pair HL: Register L = the cylinder the segment starts on (0FH on this diskette), Register H = bits 7-5 the granule in that cylinder, bits 4-0 the granule count less 1 (02H here: granule 0, three granules).
423B
LD D,L 55
Copy Register L (the starting cylinder) into Register D, the cylinder of the reading context.
423C
LD A,H 7C
Copy Register H (the granule and count byte of the segment descriptor) into Register A.
423D
RLCA 07
Rotate Register A left: bit 7 of the granule and count byte goes to bit 0.
423E
RLCA 07
Rotate Register A left again: bits 7-6 of the granule and count byte are now bits 1-0.
423F
RLCA 07
Rotate Register A left a third time: bits 7-5, the starting granule, are now bits 2-0 of Register A.
4240
AND 07H E6 07
Mask Register A to bits 2-0: the starting granule within the cylinder, 0-7. The Z FLAG is set when SYS0/SYS starts at granule 0 (00H on this diskette).
4242
If the Z FLAG is set (granule 0), JUMP to 424BH with Register A = 00H: the segment starts at sector 0 of the cylinder.
4244
LD B,A 47
Copy Register A (the starting granule) into Register B, the count of the multiplying loop below.
4245
XOR A AF
Zero Register A, the sector total of the multiplication.
4246
ADD A,(IX+07H) DD 86 07
Add the byte at Index Register IX+07H (5207H, the sectors per granule of the drive control table copy: 05H) to Register A, once per granule.
4249
Decrement Register B (the granules left to count) and loop back to 4246H while it is not zero. Register A ends as the starting granule times the sectors per granule: the first sector of SYS0/SYS within the cylinder.
424B
LD B,A 47
Copy Register A (the first sector within the cylinder) into Register B, the sector counter of the reading context.
424C
LD HL,53FFH 21 FF 53
Point Register Pair HL to 53FFH, the last byte of the buffer. The first INC L of the byte fetch at 428CH turns it to 5300H with the Z FLAG set, which makes the fetch read the first sector of SYS0/SYS.
424F
EXX D9
Exchange Register Pairs BC, DE and HL with the alternate set again: the reading context (cylinder Register D, sector Register B, buffer pointer Register Pair HL) is put aside for the byte fetch, and the main set is free for the loader.

4250H - Load SYS0/SYS Record by Record

SYS0/SYS is a load module: each record is a type byte, a length byte and that many bytes. Type 01H is a load block (address, then the data), type 02H the transfer address; any other type is passed over. The main register set does the loading: Register H the record type, Register B the bytes left in the record, Register Pair HL the load address.

4250
GOSUB to 428CH to fetch the next byte of SYS0/SYS into Register A: the type byte of a record.
4253
LD H,A 67
Copy Register A (the record type) into Register H, to be tested below.
4254
GOSUB to 428CH to fetch the next byte into Register A: the length byte of the record (the number of bytes that follow it; 00H stands for 256).
4257
LD B,A 47
Copy Register A (the record length) into Register B, the count of bytes left in the record.
4258
GOSUB to 428CH to fetch the next byte into Register A: the first byte after the length, the low byte of the address for a type 01H or 02H record.
425B
LD L,A 6F
Copy Register A (the low byte of the address) into Register L.
425C
DEC H 25
Decrement Register H (the record type). The Z FLAG is set when the type was 01H, a load block.
425D
If the Z FLAG is set (type 01H, a load block), JUMP to 426FH to copy its data to memory.
425F
DEC H 25
Decrement Register H again. The Z FLAG is set when the type was 02H, the transfer address.
4260
If the NZ FLAG is set (neither type 01H nor 02H, such as the 05H and 07H comment records at the front of SYS0/SYS), JUMP to 4267H to pass over the rest of the record.
4262
Type 02H: GOSUB to 428CH to fetch the high byte of the transfer address into Register A.
4265
LD H,A 67
Copy Register A (the high byte of the transfer address) into Register H: Register Pair HL is the transfer address of SYS0/SYS (4E00H on this diskette).
4266
JP (HL) E9
JUMP to the address in Register Pair HL (4E00H), the start of SYS0/SYS. The alternate registers still hold the reading context and Index Register IX still points to 5200H; SYS0/SYS's start-up reads sector 2's settings from 5200H.

4267H - Pass Over a Record

A record of any type other than 01H or 02H: the byte at Register L has already been taken, Register B counts the bytes left.

4267
DEC B 05
Decrement Register B, the bytes left in the record (the byte fetched into Register L at 4258H is counted off first). The Z FLAG is set when the record has been passed over.
4268
If the Z FLAG is set (no bytes left in the record), JUMP back to 4250H for the next record.
426A
GOSUB to 428CH to fetch the next byte of the record into Register A, which is thrown away.
426D
JUMP back to 4267H to count the byte off Register B.

426FH - Copy a Load Block

Type 01H: the low byte of the load address is in Register L; the high byte follows, then the data.

426F
GOSUB to 428CH to fetch the next byte into Register A: the high byte of the load address.
4272
LD H,A 67
Copy Register A (the high byte of the load address) into Register H: Register Pair HL is the load address of the block.
4273
DEC B 05
Decrement Register B (the bytes left in the record) for the low byte of the address taken at 4258H.
4274
DEC B 05
Decrement Register B again for the high byte of the address: Register B is now the number of data bytes. A length byte of 02H leaves 00H, which the DJNZ loop below runs 256 times.
4275
GOSUB to 428CH to fetch the next data byte of the block into Register A.
4278
LD (HL),A 77
Store Register A (the data byte) to the address in Register Pair HL, its place in memory.
4279
INC HL 23
Increment Register Pair HL to the next load address.
427A
Decrement Register B (the data bytes left) and loop back to 4275H while it is not zero.
427C
JUMP back to 4250H to read the type byte of the next record of SYS0/SYS.

427EH - Display ERROR! and Stop

Reached when a sector cannot be read in two tries or the directory entry of SYS0/SYS is not an active system file.

427E
LD HL,42F9H 21 F9 42
Point Register Pair HL to 42F9H, the six characters ERROR! in this sector.
4281
LD B,06H 06 06
Load Register B with 06H, the number of characters to display.
4283
LD A,(HL) 7E
Fetch the character at the address in Register Pair HL into Register A.
4284
INC HL 23
Increment Register Pair HL to the next character of the text.
4285
GOSUB to the ROM's display routine at 0033H to display the character in Register A at the cursor. The ROM routine uses Register Pair DE (the video device control block address it loads).
4288
Decrement Register B (the characters left) and loop back to 4283H while it is not zero.
428A
JUMP to itself, 428AH: the computer stops here until RESET is pressed.

428CH - Fetch the Next Byte of SYS0/SYS

Returns the next byte of the file in Register A, reading the next sector into 5300H-53FFH when the buffer is used up. The reading context is in the alternate registers: Register Pair HL' the buffer pointer, Register B' the sector within the cylinder, Register D' the cylinder; Index Register IX points to sector 2 at 5200H.

428C
EXX D9
Exchange Register Pairs BC, DE and HL with the alternate set: the reading context (buffer pointer HL, sector Register B, cylinder Register D) is now in the main registers, and the loader's registers are put aside.
428D
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 buffer at 5300H-53FFH has been used up (on the first call, 53FFH becomes 5300H).
428E
If the NZ FLAG is set (a byte of the buffer is left), JUMP to 42AFH to fetch it.
4290
PUSH HL E5
Save Register Pair HL (5300H, the start of the buffer) to the top of the stack.
4291
LD HL,42BAH 21 BA 42
Point Register Pair HL to 42BAH, the operand of the LD A,01H at 42B9H: the value the read routine stores to the drive select latch.
4294
RES 3,(HL) CB 9E
Reset bit 3 of the byte at the address in Register Pair HL (42BAH): the drive select value is 01H, drive 0 on side 0. Self-Modifying Code
42BAH is the operand of LD A,01H at 42B9H; bit 3 of the value written to 37E1H selects side 1 on a two sided drive.
4296
LD E,B 58
Copy Register B (the sector within the cylinder, counted across both sides) into Register E, the sector for the read.
4297
LD A,E 7B
Copy Register E (the sector within the cylinder) into Register A.
4298
SUB (IX+05H) DD 96 05
Subtract the byte at Index Register IX+05H (5205H, the sectors per track of the drive control table copy: 0AH) from Register A. The CARRY FLAG is set when the sector is on side 0.
429B
If the CARRY FLAG is set (the sector number is less than the sectors per track: side 0), JUMP to 42A0H with Register E unchanged.
429D
SET 3,(HL) CB DE
Side 1: set bit 3 of the byte at the address in Register Pair HL (42BAH): the drive select value becomes 09H, drive 0 on side 1. Self-Modifying Code
The operand of LD A,01H at 42B9H.
429F
LD E,A 5F
Copy Register A (the sector number less the sectors per track) into Register E: the sector number on side 1.
42A0
POP HL E1
Restore Register Pair HL from the top of the stack: 5300H, the buffer the sector is read into.
42A1
GOSUB to 42B2H to read cylinder Register D, sector Register E into the buffer at Register Pair HL (5300H), two tries. On return the Z FLAG is set if a try succeeded.
42A4
If the NZ FLAG is set (the sector could not be read), JUMP to 427EH to display ERROR! and stop.
42A6
INC B 04
Increment Register B, the sector within the cylinder, to the sector after the one just read.
42A7
LD A,B 78
Copy Register B (the next sector within the cylinder) into Register A.
42A8
SUB (IX+09H) DD 96 09
Subtract the byte at Index Register IX+09H (5209H, the sectors per cylinder of the drive control table copy: 0AH) from Register A. The CARRY FLAG is set while the next sector is on the same cylinder.
42AB
If the CARRY FLAG is set (the next sector is on this cylinder), JUMP to 42AFH.
42AD
LD B,A 47
Copy Register A (00H: the sector count wrapped) into Register B: the next sector is sector 0.
42AE
INC D 14
Increment Register D, the cylinder: the next sector is on the next cylinder.
42AF
LD A,(HL) 7E
Fetch the byte at the address in Register Pair HL (the buffer pointer, 5300H-53FFH) into Register A: the next byte of SYS0/SYS.
42B0
EXX D9
Exchange Register Pairs BC, DE and HL with the alternate set: the reading context is put aside again and the loader's registers come back.
42B1
RET C9
RETurn to the caller with the next byte of SYS0/SYS in Register A.

42B2H - Read a Sector, Two Tries

Reads cylinder Register D, sector Register E into the buffer at Register Pair HL. Register Pairs BC, DE and HL are kept. On return the Z FLAG is set if the read succeeded and Register A holds the status masked with 9CH.

42B2
GOSUB to 42B6H for the first try at reading cylinder Register D, sector Register E into the buffer at Register Pair HL.
42B5
RET Z C8
If the Z FLAG is set (the first try succeeded), RETurn to the caller. Otherwise execution falls into 42B6H for the second try, whose RETurn goes back to the caller of 42B2H.
42B6
PUSH BC C5
Save Register Pair BC to the top of the stack.
42B7
PUSH DE D5
Save Register Pair DE (cylinder Register D, sector Register E) to the top of the stack.
42B8
PUSH HL E5
Save Register Pair HL (the buffer address) to the top of the stack.
42B9
LD A,01H 3E 01
Load Register A with the drive select value: 01H in the sector (drive 0, side 0); 09H while the byte fetch has set bit 3 for side 1. Self-Modifying Code
The operand at 42BAH is changed by RES 3,(HL) at 4294H and SET 3,(HL) at 429DH.
42BB
LD (37E1H),A 32 E1 37
Store Register A (the drive select value) to the drive select latch at 37E1H: drive 0 is selected (and side 1 when bit 3 is set), and its motor runs.
42BE
LD (37EEH),DE ED 53 EE 37
Store Register Pair DE to 37EEH-37EFH: Register E (the sector) goes to the sector register 37EEH, Register D (the cylinder) to the data register 37EFH, where the Seek command takes the cylinder to step to.
42C2
LD DE,37EFH 11 EF 37
Point Register Pair DE to 37EFH, the controller's data register, which the data bytes are read from.
42C5
LD B,H 44
Copy Register H (the high byte of the buffer address) into Register B.
42C6
LD C,L 4D
Copy Register L (the low byte of the buffer address) into Register C: Register Pair BC is the buffer address.
42C7
LD HL,37ECH 21 EC 37
Point Register Pair HL to 37ECH, the controller's command and status register.
42CA
LD (HL),13H 36 13
Store 13H to the address in Register Pair HL (37ECH): the Seek command (0001 0011: no head load, no verify, step rate bits 11, the slowest), which steps the head to the cylinder in the data register.
42CC
LD A,14H 3E 14
Load Register A with 14H, the count of a short delay before the status is valid.
42CE
DEC A 3D
Decrement Register A, the delay count, giving the controller time to set BUSY.
42CF
Loop back to 42CEH while Register A is not zero.
42D1
BIT 0,(HL) CB 46
Test bit 0 of the status at the address in Register Pair HL (37ECH): BUSY. The NZ FLAG is set while the Seek is running.
42D3
Loop back to 42D1H while the NZ FLAG is set (the controller is still busy with the Seek).
42D5
LD (HL),88H 36 88
Store 88H to the address in Register Pair HL (37ECH): the Read Sector command (1000 1000: single sector, the IBM sector length flag set, no head load delay).
42D7
LD A,14H 3E 14
Load Register A with 14H, the count of a short delay before the status is valid.
42D9
DEC A 3D
Decrement Register A, the delay count, giving the controller time to set BUSY.
42DA
Loop back to 42D9H while Register A is not zero.
42DC
LD A,(HL) 7E
Fetch the status at the address in Register Pair HL (37ECH) into Register A.
42DD
AND 03H E6 03
Mask Register A to bits 1-0 of the status: DATA REQUEST and BUSY. The parity flag is even for 00H (the command has ended) and 03H (busy with a byte waiting), odd for 01H (busy, no byte yet) and 02H.
42DF
If the parity is odd (busy with no byte waiting yet), JUMP back to 42DCH to look at the status again.
42E2
LD A,(DE) 1A
Fetch the data byte from the address in Register Pair DE (37EFH, the data register) into Register A.
42E3
LD (BC),A 02
Store Register A (the data byte) to the address in Register Pair BC, its place in the buffer.
42E4
INC BC 03
Increment Register Pair BC to the next buffer address.
42E5
BIT 1,(HL) CB 4E
Test bit 1 of the status at the address in Register Pair HL (37ECH): DATA REQUEST. The NZ FLAG is set when the next byte is waiting.
42E7
If the NZ FLAG is set (a byte is waiting), JUMP back to 42E2H to take it.
42E9
BIT 1,(HL) CB 4E
Test bit 1 of the status at the address in Register Pair HL (37ECH) again: DATA REQUEST.
42EB
If the NZ FLAG is set (a byte is waiting), JUMP back to 42E2H to take it.
42ED
BIT 0,(HL) CB 46
Test bit 0 of the status at the address in Register Pair HL (37ECH): BUSY. The NZ FLAG is set while the command is still running.
42EF
If the NZ FLAG is set (the Read Sector is still running), JUMP back to 42E5H to wait for the next byte.
42F2
LD A,(HL) 7E
Fetch the final status from the address in Register Pair HL (37ECH) into Register A.
42F3
AND 9CH E6 9C
Mask Register A with 9CH to the error bits of the status: bit 7 NOT READY, bit 4 RECORD NOT FOUND, bit 3 CRC ERROR, bit 2 LOST DATA. The Z FLAG is set when the read succeeded.
42F5
POP HL E1
Restore Register Pair HL (the buffer address) from the top of the stack.
42F6
POP DE D1
Restore Register Pair DE (cylinder Register D, sector Register E) from the top of the stack.
42F7
POP BC C1
Restore Register Pair BC from the top of the stack.
42F8
RET C9
RETurn to the caller with the Z FLAG set if the read succeeded and Register A holding the masked status.

42F9H - Sector 0 Data

The text of the error display and the last byte of the sector.

42F9-42FE
DEFM "ERROR!" 45 52 52 4F 52 21
The six characters ERROR!, displayed one by one by the loop at 4283H when a sector cannot be read or SYS0/SYS's directory entry is wrong.
42FF
DEFB 00H 00
Byte FFH of sector 0: 00H, the last byte of the sector, not read by any code of this sector.

Sector 1: A Copy of Sector 0

File offsets 0100H-01FFH, cylinder 0, sector 1. Byte for byte the same 256 bytes as sector 0. The ROM reads only sector 0 and this boot sector reads sectors 2 and 4 of the directory cylinder and SYS0/SYS, so nothing during the boot reads sector 1.

0100-010F
DEFB 00H, FEH, 11H, CDH, C9H, 01H, 11H, 02H, 00H, 21H, 00H, 52H, CDH, B2H, 42H, 20H 00 FE 11 CD C9 01 11 02 00 21 00 52 CD B2 42 20
Bytes 00H-0FH of sector 1: the same bytes as 4200H-420FH of sector 0, not executed from here.
0110-011F
DEFB 6DH, E5H, DDH, E1H, DDH, CBH, 03H, 7EH, 28H, 0CH, 3EH, FFH, 32H, ECH, 37H, 11H 6D E5 DD E1 DD CB 03 7E 28 0C 3E FF 32 EC 37 11
Bytes 10H-1FH of sector 1: the same bytes as 4210H-421FH of sector 0, not executed from here.
0120-012F
DEFB D0H, 00H, EDH, 53H, ECH, 37H, DDH, 56H, 0AH, 1EH, 04H, 24H, CDH, B2H, 42H, 20H D0 00 ED 53 EC 37 DD 56 0A 1E 04 24 CD B2 42 20
Bytes 20H-2FH of sector 1: the same bytes as 4220H-422FH of sector 0, not executed from here.
0130-013F
DEFB 4DH, 7EH, 2FH, E6H, 50H, 20H, 47H, D9H, 2AH, 16H, 53H, 55H, 7CH, 07H, 07H, 07H 4D 7E 2F E6 50 20 47 D9 2A 16 53 55 7C 07 07 07
Bytes 30H-3FH of sector 1: the same bytes as 4230H-423FH of sector 0, not executed from here.
0140-014F
DEFB E6H, 07H, 28H, 07H, 47H, AFH, DDH, 86H, 07H, 10H, FBH, 47H, 21H, FFH, 53H, D9H E6 07 28 07 47 AF DD 86 07 10 FB 47 21 FF 53 D9
Bytes 40H-4FH of sector 1: the same bytes as 4240H-424FH of sector 0, not executed from here.
0150-015F
DEFB CDH, 8CH, 42H, 67H, CDH, 8CH, 42H, 47H, CDH, 8CH, 42H, 6FH, 25H, 28H, 10H, 25H CD 8C 42 67 CD 8C 42 47 CD 8C 42 6F 25 28 10 25
Bytes 50H-5FH of sector 1: the same bytes as 4250H-425FH of sector 0, not executed from here.
0160-016F
DEFB 20H, 05H, CDH, 8CH, 42H, 67H, E9H, 05H, 28H, E6H, CDH, 8CH, 42H, 18H, F8H, CDH 20 05 CD 8C 42 67 E9 05 28 E6 CD 8C 42 18 F8 CD
Bytes 60H-6FH of sector 1: the same bytes as 4260H-426FH of sector 0, not executed from here.
0170-017F
DEFB 8CH, 42H, 67H, 05H, 05H, CDH, 8CH, 42H, 77H, 23H, 10H, F9H, 18H, D2H, 21H, F9H 8C 42 67 05 05 CD 8C 42 77 23 10 F9 18 D2 21 F9
Bytes 70H-7FH of sector 1: the same bytes as 4270H-427FH of sector 0, not executed from here.
0180-018F
DEFB 42H, 06H, 06H, 7EH, 23H, CDH, 33H, 00H, 10H, F9H, 18H, FEH, D9H, 2CH, 20H, 1FH 42 06 06 7E 23 CD 33 00 10 F9 18 FE D9 2C 20 1F
Bytes 80H-8FH of sector 1: the same bytes as 4280H-428FH of sector 0, not executed from here.
0190-019F
DEFB E5H, 21H, BAH, 42H, CBH, 9EH, 58H, 7BH, DDH, 96H, 05H, 38H, 03H, CBH, DEH, 5FH E5 21 BA 42 CB 9E 58 7B DD 96 05 38 03 CB DE 5F
Bytes 90H-9FH of sector 1: the same bytes as 4290H-429FH of sector 0, not executed from here.
01A0-01AF
DEFB E1H, CDH, B2H, 42H, 20H, D8H, 04H, 78H, DDH, 96H, 09H, 38H, 02H, 47H, 14H, 7EH E1 CD B2 42 20 D8 04 78 DD 96 09 38 02 47 14 7E
Bytes A0H-AFH of sector 1: the same bytes as 42A0H-42AFH of sector 0, not executed from here.
01B0-01BF
DEFB D9H, C9H, CDH, B6H, 42H, C8H, C5H, D5H, E5H, 3EH, 01H, 32H, E1H, 37H, EDH, 53H D9 C9 CD B6 42 C8 C5 D5 E5 3E 01 32 E1 37 ED 53
Bytes B0H-BFH of sector 1: the same bytes as 42B0H-42BFH of sector 0, not executed from here.
01C0-01CF
DEFB EEH, 37H, 11H, EFH, 37H, 44H, 4DH, 21H, ECH, 37H, 36H, 13H, 3EH, 14H, 3DH, 20H EE 37 11 EF 37 44 4D 21 EC 37 36 13 3E 14 3D 20
Bytes C0H-CFH of sector 1: the same bytes as 42C0H-42CFH of sector 0, not executed from here.
01D0-01DF
DEFB FDH, CBH, 46H, 20H, FCH, 36H, 88H, 3EH, 14H, 3DH, 20H, FDH, 7EH, E6H, 03H, E2H FD CB 46 20 FC 36 88 3E 14 3D 20 FD 7E E6 03 E2
Bytes D0H-DFH of sector 1: the same bytes as 42D0H-42DFH of sector 0, not executed from here.
01E0-01EF
DEFB DCH, 42H, 1AH, 02H, 03H, CBH, 4EH, 20H, F9H, CBH, 4EH, 20H, F5H, CBH, 46H, C2H DC 42 1A 02 03 CB 4E 20 F9 CB 4E 20 F5 CB 46 C2
Bytes E0H-EFH of sector 1: the same bytes as 42E0H-42EFH of sector 0, not executed from here.
01F0-01FF
DEFB E5H, 42H, 7EH, E6H, 9CH, E1H, D1H, C1H, C9H, 45H, 52H, 52H, 4FH, 52H, 21H, 00H E5 42 7E E6 9C E1 D1 C1 C9 45 52 52 4F 52 21 00
Bytes F0H-FFH of sector 1: the same bytes as 42F0H-42FFH of sector 0, not executed from here.

Sector 2: Drive Control Table Copy and Boot Settings (at 5200H)

File offsets 0200H-02FFH, cylinder 0, sector 2. Read into 5200H-52FFH by the boot sector (4206H-420CH), which keeps Index Register IX at 5200H; SYS0/SYS's start-up reads the same buffer. Bytes 03H-0BH are this diskette's copy of the perishable part of its drive control table (DCT+0BH to DCT+13H); bytes 10H-18H are the boot settings the SYSTEM command keeps.

5200-5202
DEFM "DCT" 44 43 54
Bytes 00H-02H of sector 2: the three characters DCT that open the table. Neither the boot sector nor SYS0/SYS's start-up compares them.
5203
DEFB 40H 40
Byte 03H, the diskette flags (DCT+0BH): 40H, bit 6 set (the directory is written with a protected data address mark), bit 7 clear (single density). The boot sector tests bit 7 at 4214H; SYS0/SYS's start-up copies bytes 03H-0BH into drive 0's drive control table.
5204
DEFB 01H 01
Byte 04H, the surface count (DCT+0CH): 01H, a one sided diskette.
5205
DEFB 0AH 0A
Byte 05H, the sectors per track (DCT+0DH): 0AH, ten sectors. The boot sector's byte fetch compares the sector within the cylinder with it at 4298H to choose the side.
5206
DEFB 0AH 0A
Byte 06H, the directory length (DCT+0EH): 0AH, ten sectors (the whole directory cylinder).
5207
DEFB 05H 05
Byte 07H, the sectors per granule (DCT+0FH): 05H. The boot sector multiplies the starting granule of SYS0/SYS by it at 4246H.
5208
DEFB 02H 02
Byte 08H, the granules per cylinder (DCT+10H): 02H.
5209
DEFB 0AH 0A
Byte 09H, the sectors per cylinder (DCT+11H): 0AH. The byte fetch moves to the next cylinder when the sector count reaches it (42A8H).
520A
DEFB 11H 11
Byte 0AH, the directory cylinder (DCT+12H): 11H, cylinder 17. The boot sector reads sector 4 of this cylinder at 4226H-422CH.
520B
DEFB 23H 23
Byte 0BH, the cylinder count (DCT+13H): 23H, 35 cylinders.
520C-520F
DEFB 00H x 4 00 x 4
Bytes 0CH-0FH of sector 2: four bytes of 00H, which neither the boot sector nor SYS0/SYS's start-up reads.
5210
DEFB 0EH 0E
Byte 10H, the boot flags: 0EH. Bit 3 set: SYS0/SYS asks for the time (its 4F2EH); bit 2 set: it asks for the date (4EF0H); bit 1 set: it displays the DOSPLUS logo (4ED1H); bit 0 clear: no alternate system driver to jump to (4EBEH).
5211-5212
DEFW 0000H 00 00
Bytes 11H-12H, the alternate system driver address: 0000H. SYS0/SYS jumps to it (its 4EC1H-4EC4H) only when bit 0 of byte 10H is set, which it is not on this diskette.
5213
DEFB 00H 00
Byte 13H, the cursor blink switch: 00H, a steady cursor. SYS0/SYS's start-up stores it to 401CH.
5214
DEFB 5FH 5F
Byte 14H, the cursor character: 5FH, the underline character. SYS0/SYS's start-up stores it to 4023H.
5215
DEFB FFH FF
Byte 15H, the caps switch: FFH, unshifted letter keys give capitals. SYS0/SYS's start-up stores it to 4019H.
5216
DEFB 03H 03
Byte 16H, the default step rate code of the floppy drives: 03H. SYS0/SYS's start-up stores it into byte 04H of the drive control tables of drives 0-3.
5217
DEFB 00H 00
Byte 17H, the port to output to at boot: 00H. SYS0/SYS's start-up loads bytes 17H-18H into Register Pair BC and does OUT (C),B (its 4E84H-4E88H).
5218
DEFB 00H 00
Byte 18H, the value output to the port in byte 17H at boot: 00H.
5219-52FF
DEFB 00H x 231 00 x 231
Bytes 19H-FFH of sector 2: 231 bytes of 00H, which neither the boot sector nor SYS0/SYS's start-up reads.

Sector 3: Not Used on This Diskette

File offsets 0300H-03FFH, cylinder 0, sector 3. The manual gives sectors 3 and up of BOOT/SYS to an alternate system driver; bit 0 of byte 10H of sector 2 is clear, and the boot sector never reads this sector.

0300-03FF
DEFB 00H x 256 00 x 256
All 256 bytes of sector 3 are 00H: no alternate system driver is stored on this diskette.

Sector 4: Not Used on This Diskette

File offsets 0400H-04FFH, cylinder 0, sector 4, the last sector of BOOT/SYS (one granule of five sectors). The boot sector never reads it.

0400-04FF
DEFB 00H x 256 00 x 256
All 256 bytes of sector 4 are 00H; nothing during the boot reads them.