LDOS 5.3.1 for the Model III - BOOT/SYS Disassembled
Page Customization
Page Index
BOOT/SYS
Other Navigation
Introduction/Summary
LDOS 5.3.1 BOOT/SYS Disassembly - The Boot Sector and the System Information Sector (Model III)
BOOT/SYS is the first file of an LDOS 5.3.1 Model III system diskette: cylinder 0, sectors 0-4, 1280 bytes. It is not a load module. Sector 1 is the boot sector the ROM reads and runs, sector 0 is a byte for byte copy of it, sector 2 is the system information sector SYS0/SYS reads at start-up, sector 3 holds an old granule allocation table image and sector 4 the format fill.
When the computer is reset with a diskette in drive 0, the ROM reads cylinder 0, sector 1 into 4300H-43FFH and jumps to 4300H. The boot sector reads sector 4 of the directory cylinder (the cylinder named by its own byte 02H, 14H, cylinder 20) into 5100H-51FFH. The first 32 bytes of that sector are the directory entry of SYS0/SYS; if bit 4 of its attribute byte is clear the entry is not in use and the boot displays No system. Otherwise the starting cylinder and granule of the first extent (bytes 16H-17H of the entry) give the first sector of SYS0/SYS (granule times 6), and the boot reads SYS0/SYS a sector at a time through the same buffer, copying each load block (type 01H) to its address, passing over records of other types, until the transfer record (type 02H) sends it to SYS0/SYS at 4E00H with the interrupts still off. A sector that cannot be read in five tries displays Disk error. Either message waits for ENTER and restarts the computer through RST 00H.
Sector 0 is shown at its file offsets 0000H-00FFH, sector 1 at 4300H-43FFH, where it runs, sector 2 at 4300H-43FFH, where SYS0/SYS reads it, and sectors 3 and 4 at their file offsets. Rows of sectors 1 and 2 carry ids that name the sector (s1-4300H, s2-4300H).
How the Boot Sector Reads a Sector
The boot sector works the floppy disk controller through ports F0H-F4H. The data bytes are taken with the CPU held in wait states and the end of the command arrives as an NMI:
| Step | What the code does |
|---|---|
| Select | 81H (drive 0, double density) to port F4H (4391H) |
| Seek | The cylinder to the data port F3H and the Seek command 1BH to port F0H, then a wait for BUSY to go off (4394H-439FH); bits 1-0 of the command, byte 95H of the sector, are the bootstrap stepping rate |
| Sector | The sector to port F2H and 81H to port F4H again (43A1H) |
| NMI | JP 43D3H stored at the NMI vector 4049H (43A8H), which the ROM's NMI handler (0066H, 3039H, 351CH) jumps to when no reset is pending |
| Read | The Read Sector command 80H to port F0H, C0H to the NMI mask port E4H, a wait for the first DATA REQUEST, one INI, then 255 more with C1H (wait state generation) at port F4H before each (43B7H-43CFH) |
| End | A wait at 43D1H until the NMI; 43D3H drops the NMI's return address, takes back Register Pair DE, sends 00H to port E4H and 81H to port F4H and returns the status from port F0H (43D3H) |
| Tries | The status masked with 1CH (RECORD NOT FOUND, CRC ERROR, LOST DATA) must be 0; five tries (4374H) |
The Five Sectors
| Sector | Contents |
|---|---|
| 0 | The same 256 bytes as sector 1. FORMAT/CMD carries the sector as images at 6A00H and 6B00H, which differ from it only in byte 02H (the directory cylinder) and byte 95H (the stepping rate operand). The ROM does not read sector 0. |
| 1 | The boot sector, run at 4300H. |
| 2 | The system information sector: the S mark, the configuration byte, the days of the months, two blocks of eight drive code table entries, the date and time prompt switches and the names of the days and months. SYS0/SYS reads it into 4300H at start-up (4E91H-4E98H). |
| 3 | A granule allocation table for an empty 40 cylinder diskette named LDOS-513, dated 09/29/86; not this diskette's table. Not read during the boot. |
| 4 | The format fill, 6DH B6H repeated. |
Variables
Memory and Ports Outside BOOT/SYS
| Address Size | Contents |
|---|---|
| 4049H-404BH 3 bytes | NMI Vector The ROM's NMI handler jumps to 4049H. The boot sector stores JP 43D3H there before each read (43A8H-43B2H) and leaves it set when it jumps to SYS0/SYS. |
| 5100H-51FFH 256 bytes | Sector Buffer The directory entry of SYS0/SYS (sector 4 of the directory cylinder: attribute 5100H, first extent 5116H-5117H), then each sector of SYS0/SYS in turn. |
| Stack 8 bytes | The ROM's Stack The boot sector does not load the Stack Pointer: its calls, the push of the tries at 4376H, the push of Register Pair DE at 43B6H and the NMI's return address use the stack the ROM left. |
| Ports F0H-F3H 4 bytes | Floppy Disk Controller F0H command (write) and status (read), F2H sector register, F3H data register (the cylinder for the Seek, then each byte read). |
| Port F4H 1 byte | Drive Select 81H: drive 0, double density; C1H: the same with wait state generation (bit 6). |
| Port E4H 1 byte | NMI Mask C0H while a sector is read (bit 7 lets the controller's interrupt request raise the NMI, bit 6 the drive motor time-out), 00H after it. |
BOOT/SYS Data and Operands Other Files Read
| Address Size | Contents |
|---|---|
| 4302H 1 byte | Directory Cylinder 14H (cylinder 20), the operand of CP 14H. The boot reads it at 4304H; SYS0/SYS copies it to drive 0's drive code table at 4709H (4E85H). |
| 4395H 1 byte | Seek Command and Bootstrap Stepping Rate 1BH, the operand of LD A at 4394H. SYS0/SYS copies bits 1-0 into drive 0's drive code table at 4703H (4E77H-4E84H). |
| 43E6H-43F3H 14 bytes | Disk error Message 17H, E8H, Disk error, 1FH, 03H. |
| 43F4H-43FFH 12 bytes | No system Message 17H, E8H, No system, 03H. |
Sector 2 (read into 4300H by SYS0/SYS)
| Address Size | Contents |
|---|---|
| 4300H 1 byte | Mark 53H, S. |
| 4301H 1 byte | Configuration Byte C9H; SYS0/SYS takes it and stores 00H in its place (4E9BH-4EA0H). |
| 4302H-430DH 12 bytes | Days of the Months January to December; SYS0/SYS sets February (4303H) to 1CH or 1DH by the year. |
| 4320H-436FH 80 bytes | First Block of Drive Code Tables Eight entries of 10 bytes, drives 0-7; drives 0-3 present (JP 4583H), drives 4-7 C9H. |
| 4370H-43BFH 80 bytes | Second Block of Drive Code Tables Eight entries of 10 bytes; SYS0/SYS copies drives 1-7 (437AH-43BFH) to 470AH-474FH (4FC8H-4FD1H). |
| 43C2H 1 byte | Date Prompt Switch 00H: ask for the date (4EA1H). |
| 43C3H 1 byte | Time Prompt Switch 00H: ask for the time (4F94H). |
| 43C7H-43FFH 57 bytes | Day and Month Names SunMonTueWedThuFriSat and JanFebMarAprMayJunJulAugSepOctNovDec. |
Outside Routines
| Address | Use |
|---|---|
| 021BH 3 bytes | ROM: Display a Line Displays the text at Register Pair HL until 03H or 0DH (4387H). |
| 0040H 3 bytes | ROM: Line Input Waits for a line from the keyboard (438AH). |
| 0000H 1 byte | ROM: Restart RST 00H after an error (438DH). |
| 4E00H 3 bytes | SYS0/SYS Transfer Address Reached by JP (HL) at 434DH. |
Disassembly
Sector 0: The Copy of the Boot Sector
File offsets 0000H-00FFH, cylinder 0, sector 0. Byte for byte the same 256 bytes as sector 1, the boot sector the ROM reads and runs at 4300H (FORMAT/CMD carries the same sector as images at 6A00H and 6B00H, which differ from it only in byte 02H, the directory cylinder, and byte 95H, the stepping rate operand). The ROM reads sector 1 and the boot sector never reads this sector, so its bytes are shown as data, each row naming the instructions of sector 1 they repeat.
4300H - Sector 1: The Boot Sector
When the computer is reset with a diskette in drive 0, the ROM reads cylinder 0, sector 1 into 4300H-43FFH and jumps to 4300H. This sector reads sector 4 of the directory cylinder (the directory entry of SYS0/SYS) into 5100H, checks that the entry is in use, works out from its first extent where SYS0/SYS starts and loads SYS0/SYS record by record, a sector at a time through the same buffer, until the transfer record sends it to SYS0/SYS. It keeps the stack the ROM left and runs with the interrupts off.
432AH - 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 (the load address, then the data), type 02H the transfer address; any other type is passed over. Register B counts the bytes of a record and Register Pair HL holds the load address.
434EH - Fetch a Record Length and Address
Fetches the length byte and the two address bytes of a load block or transfer record. Register B returns the length less 2 (the data bytes that follow the address) and Register Pair HL the address.
435DH - Fetch the Next Byte of SYS0/SYS
Returns the next byte of SYS0/SYS in Register A. The alternate registers keep the reading position: Register Pair HL' the pointer into the buffer at 5100H-51FFH and Register Pair DE' the cylinder and sector of the next sector to read. When the pointer passes 51FFH, the next sector is read first.
4374H - Read a Sector, Five Tries
Reads cylinder Register D, sector Register E into the buffer at 5100H, trying up to five times. On return Register A holds the controller status masked with 1CH and the Z FLAG is set if the read succeeded; Register Pair DE is kept.
4380H - Display Disk error or No system and Restart
Entered at 4380H when a sector cannot be read in five tries, and at 4384H (inside the LD IX at 4383H) when the directory entry of SYS0/SYS is not in use. Displays the message, waits for a line from the keyboard and restarts the computer.
438EH - Seek and Read One Sector
Seeks cylinder Register D and reads sector Register E into 5100H-51FFH through ports F0H-F4H. The controller's data request holds the CPU in wait states for each byte, and the interrupt at the end of the command arrives as an NMI at 43D3H, which returns to the caller with the status in Register A. Register Pair DE is kept.
43D3H - End of Read (NMI)
Reached through the NMI vector at 4049H (JP 43D3H, set at 43A8H-43B2H) when the Read Sector command ends. The stack holds the address the NMI interrupted (43D1H), Register Pair DE pushed at 43B6H and the return address into 4374H.
43DFH - Send a Command to the Controller
Sends the command in Register A to port F0H, then waits a short time for the status to be valid. Register B returns 00H.
43E6H - The Two Messages
The texts 4387H displays through the ROM routine at 021BH, each ending in 03H.
Sector 2: The System Information Sector (at 4300H)
File offsets 0200H-02FFH, cylinder 0, sector 2. The boot sector does not read it. SYS0/SYS's start-up reads it into 4300H-43FFH (4E91H-4E98H), over the boot sector, and takes the configuration byte, the month lengths, the date and time switches and the names of the days and months from it, and the entries of drives 1-7 of the second block of drive code tables (4FC8H-4FD1H). The rows show it at 4300H, where it is read.
Sector 3: An Old Granule Allocation Table Image
File offsets 0300H-03FFH, cylinder 0, sector 3. A granule allocation table for an empty 40 cylinder diskette named LDOS-513, dated 09/29/86. It is not the allocation table of this diskette, which is sector 0 of the directory cylinder (named LDOS531, dated 08/09/91). The boot sector never reads this sector. The rows show it at its file offsets.
Sector 4: Format Fill
File offsets 0400H-04FFH, cylinder 0, sector 4, the last sector of BOOT/SYS. It holds only the fill pattern a freshly formatted sector carries; nothing reads it.