DOSPLUS 3.5 for the Model III - FORMAT/CMD Disassembled
Page Customization
Page Index
FORMAT/CMD
Other Navigation
Introduction/Summary
DOSPLUS 3.5 FORMAT/CMD Disassembly - The Floppy Formatter (Model III)
FORMAT/CMD is DOSPLUS's formatter of floppy diskettes, run from the DOS command level as FORMAT :d (NAME="name",DATE="date",PW="password",CYLS=n,SIDES=n,DEN="S" or "D",USE="Y"); its heading reads FORMAT - DOSPLUS Floppy formatter - 3.50. It is a load module of 10 blocks, 2474 bytes, at 5200H-5BA9H with the transfer address 5200H, after the two comment records (the name FORMAT and the copyright notice). The Model I and Model III files have the same length and differ in 45 bytes: the addresses in SYS0/SYS (DATE$, LOW$, HMEM$, SFLAG1$, DCTTBL, DISKIO%, LOCDCT%, the multiply and divide), the prompt Insert SYSTEM disk, which ends (ENTER) on the Model I and [ENTER] on the Model III, and the density taken for ENTER alone, single on the Model I and double on the Model III (5387H-53A5H). This page is the Model III one.
FORMAT makes a data diskette: it writes no boot code and no system files, only an empty directory with the entries of BOOT/SYS and DIR/SYS. It refuses a rigid drive (Drive NOT SUPPORTED!, 5293H). The track routines are the ones BACKUP/CMD uses (54F8H): the same interleave, skew and format descriptions.
The Parts of FORMAT/CMD
| Address | Contents |
|---|---|
| 5200H-52B4H | The heading, the buffer, EVAL@, the drive, the empty GAT (5200H). |
| 52B5H-5333H | The name, the date and the master password (52B5H). |
| 5334H-53ACH | The cylinders, the sides and the density (5334H). |
| 53ADH-53F1H | The drive and a diskette that holds data (53ADH). |
| 53F2H-547CH | Format and verify (53F2H). |
| 547DH-55B5H | The system information: the boot sectors and the directory (547DH). |
| 55B6H-55DFH | The errors (55B6H). |
| 55E0H-5720H | A cylinder, a track, a group, a granule's verify, the geometry, the format (55E0H, 55F4H, 56B9H, 56C3H, 56E0H, 5709H). |
| 5721H-5845H | Prompts, the password code, numbers, digits, bits, texts and the system disk prompt (5721H, 575EH, 578DH, 57BFH, 5804H). |
| 5846H-5BA9H | The directory entries, the formats and geometries, the texts, the evaluation block (5847H, 5887H, 590FH, 5B61H). |
How FORMAT Works
The buffer starts at 5D00H, or at the page above LOW$ (42A7H) when that is higher, and needs 2AF6H bytes below HMEM$ (4411H) for the image of a track (else No available memory!). EVAL@ takes the drive and the parameters (524DH); EVAL@ stores each string's address, or each number, straight into the operand of an LD HL instruction (52B6H, 52D9H, 531CH, 5335H, 535EH, 5383H, 53CAH). Whatever the command line does not give is asked for: Target drivespec ? (a drive name of DCTTBL), Diskette name ? (ENTER alone gives DATA), Format date ? (only when no system date is set; ENTER alone gives 00/00/00), Master password ? (ENTER alone gives eight spaces), Number of cylinders (35-96) ? (ENTER alone gives 40), Number of sides ? (1), Single or double density ? (double density (D)). BREAK at any prompt ends FORMAT with EXIT@.
The format code (5BAEH: bit 0 double density, bit 1 an 8 inch drive, bit 2 two sides) picks the drive's geometry from the table at 58BFH (56E0H): 10 sectors a track in single density and 18 in double on a 5 inch drive (16 and 30 on an 8 inch drive). A diskette whose GAT can be read holds data: FORMAT then asks Diskette contains data, use or not ? (or takes USE=), and anything but N formats it. Every cylinder is formatted, every granule verified (DVERF) from the last cylinder down, and a granule that does not verify is locked out (53F2H). Then (547DH) the boot granule is allocated (a flawed one ends FORMAT), the directory cylinder is chosen near the middle, cylinder 0's sectors 0 and 1 get 00H, FEH and the directory cylinder (the byte the DOS's logging reads), and the directory is written with the directory's data address mark: the GAT, the HIT, the entries of BOOT/SYS and DIR/SYS and empty sectors. The prompt Insert SYSTEM disk [ENTER] is flashed at the end only when drive 0 was formatted (5804H).
Findings
FORMAT does not test EVAL@'s return code; the string parameters (USE, DATE, PW, NAME, DEN) need quotation marks and the numbers (CYLS, SIDES) must not have them (5B61H). At Diskette contains data, use or not ? the answers Y, U and F all format the diskette; only N keeps it (53DEH). The count of cylinders is taken from 20 to 96, not 35 to 96 as the prompt says, so +CCH of the GAT (the count less 35) can be below zero (534DH). The directory cylinder is searched from the middle outwards, one above, one below and so on, but the search gives up as soon as one side reaches cylinder 0 or the last cylinder, even if the other side still has a free one (5492H). The page made at 5511H-5530H (the letters DCT and the drive's geometry, as in BOOT/SYS's sector 2) is never written: the HIT is made over it at 553FH. Sector 0 of cylinder 0 holds no boot code, so the diskette cannot boot. FORMAT sets bit 0 of the drive control table's type byte (DCT+00H) for the new geometry (56E2H). An error before the drive is known leaves the prompt for the system disk to a byte the file does not load (5804H).
Differences from the Manual
The manual (Utilities, FORMAT, pages 3-27 to 3-29) agrees with the parameters, their types and abbreviations (D, P, N, C, S, DE, U) and the prompts. Its defaults differ: no name (the bytes give DATA), the date 01/01/80 (00/00/00 when no system date is set and ENTER is pressed), and a count of cylinders of 40 in its table but 35 on the Model I and 40 on the Model III in its text (the bytes give 40 on both). It says to answer Y to proceed or N to abort; U and F also proceed. It says Insert SYSTEM disk is flashed when the format is complete; the bytes show it only when drive 0 was formatted, and not while a DO file runs.
Variables
FORMAT/CMD Variables
| Address Size | Contents |
|---|---|
| 5846H 1 byte | Flash state 1EH while the prompt is shown, 00H while the line is clear (5846H). |
| 5847H-5886H 64 bytes | Directory entries BOOT/SYS and DIR/SYS (5847H). |
| 5B61H-5BA9H 73 bytes | Evaluation block The block of EVAL@ and its seven parameters (5B61H). |
| 5BAAH 1 byte | Drive The drive to format (5BAAH). |
| 5BABH-5BAEH 4 bytes | Format The cylinders, the empty cylinder byte, the directory's last granule, the format code (5BABH). |
| 5BAFH-5BB0H 2 bytes | Buffer The start of the buffer (5BAFH). |
| 5BB1H-5BD1H 33 bytes | Field and reply The field block of EVAL@ and the replies (5BB1H). |
| 5BDAH-5BF9H 32 bytes | Sector order The sector order of a track being formatted (5BDAH). |
| 5C00H-5CFFH 256 bytes | New GAT The GAT of the new diskette (5C00H). |
Memory Outside FORMAT/CMD
| Address Size | Contents |
|---|---|
| 421AH-421CH 3 bytes | DATE$ The system date: year, day, month (52DFH). |
| 42A7H-42A8H 2 bytes | LOW$ The lowest address free for programs (5207H). |
| 4411H-4412H 2 bytes | HMEM$ The highest address free for programs (5224H). |
| 4297H 1 byte | SFLAG1$ Bit 5, a DO file runs (5809H). |
| 44E8H 32 bytes | DCTTBL The drive names (526DH). |
| 5D00H on to HMEM$ | Buffer The image of a track and the sectors written (5219H). |
Outside Routines
| Address | Contents |
|---|---|
| 4479H | SYS0/SYS: EVAL@ (524DH). |
| 4488H | SYS0/SYS: DISKIO% (53B3H and others). |
| 44A3H | SYS0/SYS: LOCDCT% (5299H). |
| 4491H | SYS0/SYS: 8 bit multiply (560AH, 56CAH). |
| 4494H | SYS0/SYS: 8 bit divide (54C5H, 5612H). |
| 402DH | SYS0/SYS: EXIT@ (55B3H). |
| 4030H | SYS0/SYS: ABORT@ (55DDH). |
| 0033H | ROM: display a character (57E5H, 5728H, 5834H). |
| 0040H | ROM: line input (5731H). |
| 002BH | ROM: scan the keyboard (5827H). |
Disassembly
5200H - FORMAT
FORMAT/CMD's transfer address, entered from the DOS command level with Register Pair HL at the command line after the word FORMAT: FORMAT :d (NAME="name",DATE="date",PW="password",CYLS=n,SIDES=n,DEN="S" or "D",USE="Y"). FORMAT shows its heading, sets its buffer above 5D00H, takes the drive, the diskette name, the date, the master password, the counts of cylinders and sides and the density from the command line or the prompts, checks the drive, asks before formatting a diskette that holds data, formats and verifies every cylinder (flawed granules locked out), and writes the system information: cylinder 0's sectors 0 and 1, and on a directory cylinder near the middle the GAT, the HIT, the entries of BOOT/SYS and DIR/SYS and empty directory sectors. It ends with EXIT@ (after the prompt for the system disk when drive 0 was formatted), or with an error message and ABORT@.
52B5H - The Name, the Date and the Password
The diskette name (NAME=, else the prompt Diskette name ?, ENTER alone giving DATA) goes to +D0H of the GAT; the date (DATE=, else the system date DATE$ as MM/DD/YY, else the prompt Format date ?, ENTER alone giving 00/00/00) to +D8H; the master password (PW=, else the prompt Master password ?, ENTER alone giving 8 spaces) is hashed (575EH) into +CEH-+CFH. Each is up to 8 characters padded with spaces.
5334H - The Cylinders, the Sides and the Density
CYLS= (a number), else the prompt Number of cylinders (35-96) ?, ENTER alone giving 40; a value below 20 or above 96 is asked for again. SIDES=, else Number of sides ?, ENTER alone giving 1; only 1 or 2 is taken. DEN="S" or "D", else Single or double density ?, ENTER alone giving single density on the Model I and double density on the Model III. The count of cylinders goes to 5BABH and, less 35, to +CCH of the GAT; the sides and the density complete the format code 5BAEH.
53ADH - The Drive and Its Diskette
DCHECK of the drive (not ready or write protected ends FORMAT). A diskette whose GAT can be read (SREAD of directory sector 0) holds data: then USE= (its first character) or the prompt Diskette contains data, use or not ? decides: N ends FORMAT; Y, U and F all go on to format it.
53F2H - Format and Verify
Gives the drive the geometry of the format code (56E0H), makes the empty GAT (the empty cylinder byte 5BACH in the allocation and lock out tables for each cylinder, the version 35H at +CBH, the flags at +CDH with bit 5 for two sides, no AUTO command at +E0H), formats every cylinder (55E0H), then verifies every granule from the last cylinder down (56C3H, DVERF): a granule that cannot be verified is shown as GRAN FLAWED! Locked out! and set in both tables.
547DH - The System Information
Shows Writing system information. The boot granule (granule 0 of cylinder 0) must not be flawed and is allocated. The directory cylinder is the free cylinder nearest the middle: from half the count of cylinders it tries one above, one below, two above and so on, and gives up (NO TRACK available for directory!) as soon as one side reaches cylinder 0 or the last cylinder, even if the other side still has a free cylinder. Its granules for the directory (enough for DCT+0EH sectors) are allocated. Then: cylinder 0's sectors 0 and 1 (00H, FEH, the directory cylinder, then 00H), the GAT (directory sector 0) and the HIT (sector 1, with the hash codes A2H and C4H of BOOT/SYS and DIR/SYS), the entries of BOOT/SYS (sector 2) and DIR/SYS (sector 3), and the other directory sectors filled with 00H, each directory sector with the directory's data address mark (DWRITA).
55B6H - The Errors
Each entry points Register Pair HL to its message and goes to 55D7H, which shows it, flashes the prompt for the system disk when drive 0 is the drive (5804H), and leaves by ABORT@. Every error of the format and of the writes is I/O ERROR! routine aborted!.
55E0H - Format a Cylinder
Formats cylinder Register D of drive Register C: side 0, then side 1 for a diskette with two sides (Register E = the sectors per track, the first sector of side 1).
55F4H - Make and Write a Track
Builds the image of one track in the buffer at (5BAFH) and writes it with DFORMT (function 09H), as BACKUP/CMD does: the interleave from 5709H (2 in single density, 3 in double) laid out from a place that moves by twice the interleave on each track, into the sector order at 5BDAH; the image from the format description (pairs of a count and a byte, 56B9H), each sector with its ID field (FEH, cylinder, side, sector, length code 01H, F7H for the CRC) and 256 data bytes of 6CH after FBH.
56B9H - Store a Group
Takes a count and a byte from Register Pair DE (a count of 00H is 256) and stores the byte that many times at Register Pair HL; both pointers are left after them.
56C3H - Verify a Granule
DVERF (function 04H) of every sector of granule Register E of cylinder Register D: the sectors are checked by the controller and not read into memory. Returns the Z FLAG, or the NZ FLAG and Register A the error code; Register Pairs BC and DE are kept.
56E0H - Give the Drive Its Geometry
Sets bit 0 of DCT+00H and copies the nine bytes DCT+0BH-DCT+13H for the format code 5BAEH (0-7) from the table at 58BFH (10 bytes an entry) into the drive control table at Index Register IY (set by LOCDCT% at 5299H). Register Pairs BC and DE are kept.
5709H - The Format of a Track
Returns Register A = the interleave and Register Pair HL = the format description, from the entry of the format code's bits 0-1 (density and 8 inch) in the table at 5887H; Register Pair DE is kept.
5721H - A Prompt and Its Reply
Shows the text at Register Pair HL up to its 03H, then as many spaces as the byte after the 03H gives, and takes a reply of up to Register B characters into 5BB1H with the ROM's line input (0040H). BREAK ends FORMAT at 55B0H, with EXIT@. Returns Register Pair HL = 5BB1H and Register A = the first character of the reply.
573AH - Copy Up to 8 Characters
Copies the text at Register Pair HL to 5BB1H, at most 8 characters, ending at a control character or at a double or single quotation mark (the end of a string given to a parameter), and fills the rest of the 8 with spaces. Returns Register Pair HL = 5BB1H.
575EH - The Password Code
Hashes the 8 characters at Register Pair DE (made upper case, taken from the last to the first) into the 16 bit password code in Register Pair HL, starting from FFFFH: for each character the code is mixed by shifts and XORs with the character, the same code the DOS compares with a file's or a diskette's password.
578DH - A Decimal Number
Reads the decimal digits at Register Pair HL into Register Pair DE and returns Register A = its low byte at the first control character. Any other character ends the reading at once with Register A = that character less 30H, which the caller's range test then refuses (or not, for a value it happens to allow).
57ADH - Two Decimal Digits
Stores Register A (0-99) at Register Pair HL as two ASCII digits, the tens first; Register Pair HL is left after them and Register Pair DE is kept.
57BFH - Set or Reset Bit E
57BFH sets bit Register E (0-7) of Register A and 57CFH resets it: each stores the bit number into the second byte of its SET or RES instruction (57CDH, 57DDH) and then runs it.
57DFH - Show a Text
Shows the characters at Register Pair HL with the ROM's 0033H until the 03H that ends the text. Returns Register Pair HL past the 03H and Register A = 03H; Register Pair DE is kept.
57EBH - Show a Pass and the Cylinder
Shows the text of the pass at Register Pair HL (a carriage return and a cursor up start it, so the line is written over), then Cylinder and the cylinder Register D in two decimal digits (stored over the 00 at 5A49H).
57FBH - Upper Case
Makes a lower case letter in Register A upper case; any other character is left as it is.
5804H - The Prompt for the System Disk
Only when the drive (5BAAH) is drive 0 and no DO file runs (bit 5 of SFLAG1$): flashes Insert SYSTEM disk [ENTER] until a key is pressed, 500 scans of the keyboard with the text shown and 500 with the line cleared. 5BAAH holds 03H from 5230H until the drive is known; for No available memory!, found before that, it is a byte the file does not load.
5834H - Clear the Line
Shows a carriage return, a cursor up (1BH) and an erase to the end of the line (1EH): the line of the cursor is cleared and the cursor is at its start. Sets the flash state 5846H to 1EH.
5847H - The Directory Entries
Data: the two 32 byte directory entries FORMAT writes, BOOT/SYS's in directory sector 2 and DIR/SYS's in sector 3 (5557H-5581H fill in the counts and DIR/SYS's extent).
5887H - The Formats and the Geometries
Data: the table of 5709H (an interleave and the address of a format description for each value of the format code's bits 0-1), the two format descriptions (pairs of a count and a byte for 56B9H, a count of 00H being 256), and the table of 56E0H: for each format code 0-7 the ten bytes DCT+0BH-DCT+14H (density, surfaces, sectors a track, directory length, sectors a granule, granules a cylinder, sectors a cylinder, then FFH), of which nine are copied.
590FH - The Texts
Data: the heading, the prompts (each followed by its 03H and the count of spaces 5721H shows after it), the texts of the passes and the messages, each ended by 03H for 57DFH.
5B61H - The Evaluation Block and the Variables
Data: the evaluation block of EVAL@ (5249H; its flag byte is also the 00H that ends the name DATA), its three fields all at 5BB1H, and the parameter block (9 byte entries: a six character name, the address for the value, the type byte: 80H a string, 40H a number). The values go straight into the operands of seven LD HL instructions. 5BAAH on is not loaded.