LDOS 5.3.1 for the Model III - FORMAT/CMD Disassembled

Page Customization

Introduction/Summary

LDOS 5.3.1 FORMAT/CMD Disassembly - The Diskette Formatter (Model III)

FORMAT writes the tracks of a diskette, checks every sector, and writes the system information: the two boot sectors and the system information sector on cylinder 0, a copy of the allocation table, and a directory with the records of BOOT/SYS and DIR/SYS on a cylinder near the middle. The command is FORMAT :d (NAME="name",MPW="password",SDEN,DDEN,SIDES=n,CYL=n,STEP=n,ABS,QUERY=N,SYSTEM,WAIT=n,DIR=n); whatever is not given is asked for or taken as a default.

The file is a load module of 4845 bytes: a copyright record, 23 load blocks with 4698 bytes in 6000H-7565H (with gaps that are not in the file), and the transfer address 6D00H. The program has two parts. The front end (6D00H-7162H) reads the parameters and the replies, copies the target drive's drive code table to 6505H and changes the copy, checks the diskette and jumps to the engine (70E9H). The engine (6000H-6504H) builds each track from a template into the memory from 6D00H up, over the front end, which has finished; it reaches the drive's driver itself, through the JP at the start of the working copy (6401H), so the system's own drive code table is never changed.

The Parameters

@PARAM reads the parameters only when the command line starts with :d; without it the drive is asked for and the rest of the line is not read (6D36H). Each parameter's value goes into the operand of the instruction that reads it (the table at 719DH).

ParameterWhat the Code Does
NAME="name" (N)The diskette name, at most 8 characters, put in upper case into the allocation table (+D0H). NAME alone asks Diskette name ?; without NAME the QUERY setting decides: ask, or take LDOSDISK (6DE0H).
MPW="password" (M)The master password, the same way, default PASSWORD. It must start with a letter and hold only letters and digits; its hash (SYS2/SYS) goes to +CEH-+CFH (70FFH).
SDEN, DDENSingle or double density. Without them the density is double when the drive's controller can do it (bit 6 of +04H), else single (6E73H).
SIDES=nSIDES=2 formats both sides (bit 5 of +04H); anything else one side.
CYL=n (C)The cylinders of a 5 inch floppy, below 96; 96 or more gives Parameter error. Without it the drive's cylinders from the system information sector (SYSTEM (DRIVE=d,CYL=n)). An 8 inch diskette always gets 77.
STEP=nThe bootstrap step rate, 0-3, written into both boot sectors. Without it the rate of drive 0's table in the system information sector (SYSTEM (BSTEP=n), 6D17H).
ABS (A)A diskette that holds data is formatted without the question Are you sure you want to format it ? (70C1H).
QUERY=N (Q)No question: NAME and MPW take their defaults and the format the defaults of the drive. Any of SDEN, DDEN, SIDES, CYL or STEP also stops every question about the format.
SYSTEMAccepted only for a hard disk (bit 3 of +03H); for any other drive FORMAT ends with Can't "SYSTEM" a floppy! before it writes anything (6DCDH). On a drive whose table has bit 4 of +04H set only the system information is written; the memory is not checked and the contents of the diskette are not looked at (7044H, 7067H). The Model I file instead writes cylinder 0 of a 5 inch double density floppy again in single density.
WAIT=n (W)A wait of n counts of the ROM's delay (0060H) after each Step In of the format, and before each cylinder of the verify (6125H).
DIR=n (D)The cylinder of the directory, when it is below the highest cylinder; else the middle cylinder. A locked out cylinder moves it to the nearest good one (61F8H).

The Questions

In this order: Which drive is to be used ? (without :d), Diskette name ?, Master password ?, Single or Double density <S,D> ? (only when the controller can do double density), Enter number of sides <1,2> ?, Number of cylinders ? (5 inch floppies only), and the bootstrap step rate in milliseconds: 6, 12, 20 or 30 for a 5 inch drive (the question names these; 40 is taken too), 3, 6, 10, 15 or 20 for an 8 inch drive. ENTER takes the default. For drive 0 Load destination diskette and hit <ENTER> follows, and at the end Load SYSTEM diskette and hit <ENTER>. A JCL job, which cannot answer, ends at Load destination diskette and at Are you sure you want to format it ?; the question for the system diskette waits for ENTER.

Before the format the drive must be ready, the head on track 0 after a Restore, a diskette turning (the index hole passes within half a second, 713CH), not write protected, and HIGH$ must leave room for the track above 6D00H. When cylinder 0, sector 0 can be read in the new format, the diskette is shown as Disk contains data -- with its name and date, or Non-standard format, Unreadable directory or Non-initialized directory (705FH).

The Track Templates

Four descriptors (6512H) give for each size and density the template, the values of +07H and +08H, and the memory the track takes. A template holds the sectors on a track, the skew, the order of the sectors on the track and a stream of codes that 6013H expands: 01H-F0H (and F6H-FFH; 00H means 256) put the next byte that many times, F1H-F2H enclose the part repeated for every sector, F3H marks an ID field, F5H repeats a pair of bytes, F4H ends the stream; the list of the sectors in the order of the verify follows.

TemplateFormatSectorsInterleave, SkewTrack
652AH5 inch, single density102, 73105 bytes; 2 granules of 5 sectors on a track; data E5H.
656AH5 inch, double density183, 136334 bytes; 3 granules of 6 sectors; data 6DH B6H. Its memory size (196AH) is 84 bytes less than the 6590 bytes 6013H writes.
65C4H8 inch, single density163, 25176 bytes; 2 granules of 8 sectors; data E5H.
6609H8 inch, double density305, 310357 bytes; 3 granules of 10 sectors; data 6DH B6H.

What FORMAT Writes

Every track of every cylinder (both sides with SIDES=2), from cylinder 0 up, the head moved only by Restore and Step In; then every sector is verified, and a cylinder with a sector not found or a CRC error is shown with an asterisk and locked out (FFH in the allocation table and the lock out table). The directory goes on the middle cylinder or the nearest good one.

Cylinder, SectorContents
0, 0A copy of the boot sector, from 6A00H, with the directory cylinder and the step rate.
0, 1The boot sector, from 6B00H, the same bytes: the sector the Model III ROM reads into 4300H and runs at a reset (the BOOT/SYS page shows it as it is on the system diskette).
0, 2The system information sector: 53H and 255 bytes of 00H.
0, 3A copy of the allocation table.
Directory, 0The allocation table (6900H-69FFH): a byte for each cylinder, a bit set for each granule not free; the lock out table at +60H; +CCH the cylinders less 35; +CDH the configuration byte; +CEH the hash of the master password; +D0H the name; +D8H the date; +E0H no AUTO command.
Directory, 1The hash index table: A2H (BOOT/SYS) and C4H (DIR/SYS).
Directory, 2 and 3The records of BOOT/SYS (64C5H) and DIR/SYS (64E5H).
Directory, 4 onEmpty sectors of 00H.

Every sector of the directory cylinder is written with the deleted data mark and read back: only the error 06H of that mark is accepted (6438H). The other sectors are written with the normal mark and verified.

Drives Without Track Writing

A drive whose table has bit 4 of +04H set gets no questions about the format (density, sides, cylinders, step rate) and no check of the controller's status or of the memory, but the name, the password and the test for data on the diskette as any other; the engine writes no tracks (61B3H). A hard disk (bit 3 of +03H) is formatted only when the operator answers Y to The target drive is a hard disk!. Without SYSTEM the drive's driver gets function 0CH, with SYSTEM nothing is done to the surface. SYSTEM is given only for a hard disk (6DD7H). Then the system information is written.

About This Page

The Model III file is the Model I file of the same release with the engine and its tables moved down (the allocation table image is at 6900H, the Model I file's 6A00H; the buffer at 6C00H, the Model I file's 6D00H; the front end at 6D00H, the Model I file's 6E00H) and these changes in the code: there is no second pass over cylinder 0 in single density, so SYSTEM is refused for every floppy (6DCDH) and the configuration byte never gets bit 4; with SYSTEM the memory check and the look at the old contents are left out (7044H, 7067H); for a hard disk the directory search starts from the directory cylinder of the drive's own table (61F8H); both boot sector images hold the Model III boot sector, which runs at 4300H, and each gets the bootstrap step rate in its Seek command at +95H (6252H); the system information sector's drive tables are always taken from its second block at 4370H (6D17H); the date comes from the ROM's @DATE at 3033H (6E20H); the half second of the index test is 15 of the Model III's 30 ticks (713FH); the default bootstrap step rate in the file is 00H (650FH) and the 5 inch question names 30 ms as the slowest rate. The calls into the system use the Model III addresses: @LOGOT 428AH, @PARAM 4454H, SFLAG$ 442BH, HIGH$ 4411H, TIMER$ 4288H, MULTEA 4B6BH and the sector buffer 4300H. The ROM routines it calls (0033H, 0040H, 0049H, 0060H, 3033H) are those of the Model III ROM, version 3.1; 0060H is a JP 01FBH to the delay loop there.

Every byte of the file has its row; the rows of the two boot sector images (6A00H-6BFFH) show their code as it runs at 4300H, and their branches link to the rows of the image. Further points read from the code: when no cylinder can take the directory, the JP 63D5H at 6238H displays Format aborted! and not the text at 66B6H; Number of cylinders ? takes at most 95; the default name is LDOSDISK; the question Special non-standard format desired ? (730BH) is not used; the bootstrap step rate stays 00H on a drive with bit 4 of +04H set; after the clock interrupt was shut out (6007H) FORMAT ends with Note: Realtime clock no longer accurate.

Memory Map

Load Blocks in File Order

The file starts with a copyright record (type 1FH, 49 bytes: Copyright 1991 MISOSYS, Inc., All rights reserved), then 23 load blocks with 4842 bytes in the order LDOS loads them (the two boot sector images come last), then the transfer address 6D00H. 6505H-650EH, 6510H-6511H, 67D9H-67FFH, 6804H-69CAH, 6C00H-6CFFH and 7163H-7174H are not in the file.

AddressContents
6000H-60FFH256 bytes
6100H-61FFH256 bytes
6200H-62FFH256 bytes
6300H-63FFH256 bytes
6400H-64FFH256 bytes
6500H-6504H5 bytes
650FH-650FH1 bytes
6512H-6611H256 bytes
6612H-6711H256 bytes
6712H-67D8H199 bytes
6800H-6803H4 bytes
69CBH-69FFH53 bytes
6D00H-6DFFH256 bytes
6E00H-6EFFH256 bytes
6F00H-6FFFH256 bytes
7000H-70FFH256 bytes
7100H-7162H99 bytes
7175H-7274H256 bytes
7275H-7374H256 bytes
7375H-7474H256 bytes
7475H-7565H241 bytes
6A00H-6AFFH256 bytes
6B00H-6BFFH256 bytes

The Parts of the File

AddressContents
6000H-64C4HThe engine: the track expander (6013H), the format of every cylinder (6095H), the verify (612EH), the directory cylinder (61F8H), the system information (6252H-63B9H), the end (63BBH), the calls to the driver (6401H) and its helpers.
64C5H-6672HThe records of BOOT/SYS and DIR/SYS, the working drive code table (not in the file), the four track descriptors and templates.
6673H-69FFHThe engine's texts, the pointers at 6800H and the allocation table image (6900H-69FFH).
6A00H-6BFFHThe images of boot sectors 0 and 1 (run at 4300H).
6C00H-6CFFHNot in the file: the table of the ID fields of the track, then the buffer of the replies and of the sectors written.
6D00H-7162HThe front end; from 6000H on the engine builds the tracks here, up to 6D00H plus the memory size of the descriptor.
7163H-7565HThe saved table and the cylinders of the drives (not in the file), the two supervisor requests, the master password, the table of the parameters and the front end's texts.

Sections of the Disassembly

AddressContents
6000HThe Format Engine: Entry
6013HExpand the Track Template
6095HFormat Every Cylinder
60D6HWrite the Track, the Second Side, Step In
612EHVerify Every Cylinder
619AHA Sector Failed the Verify
61B3HA Drive Without Track Writing: the Hard Disk Question
61F8HChoose the Directory Cylinder
6252HThe Boot Sectors: Cylinder 0, Sectors 0 and 1
62B3HThe Allocation Table: Cylinder 0, Sector 3; the System Information: Sector 2
6305HThe Directory Cylinder
63BBHThe End: Formatting Complete
63D0HA Period, the Abort, and Putting Back the Interrupt Vector
6401HCalls to the Drive's Driver
6438HVerify a Directory Sector, the Error Exits, Small Helpers
64C5HThe Directory Records of BOOT/SYS and DIR/SYS
6505HThe Working Drive Code Table and the Counts
6512HThe Four Track Descriptors
652AHTemplate: 5 Inch, Single Density
656AHTemplate: 5 Inch, Double Density
65C4HTemplate: 8 Inch, Single Density
6609HTemplate: 8 Inch, Double Density
6673HThe Engine's Texts (1)
6704HThe Engine's Texts (2)
67D9HMemory Not in the File, the Boot Sector Pointers, the Allocation Table Image
6A00HImage of Boot Sector 0 (Runs at 4300H)
6A2AHImage of Boot Sector 0: Load SYS0/SYS Record by Record (Runs at 432AH)
6A4EHImage of Boot Sector 0: Fetch a Record Length and Address (Runs at 434EH)
6A5DHImage of Boot Sector 0: Fetch the Next Byte of SYS0/SYS (Runs at 435DH)
6A74HImage of Boot Sector 0: Read a Sector, Five Tries (Runs at 4374H)
6A80HImage of Boot Sector 0: Display Disk error or No system and Restart (Runs at 4380H)
6A8EHImage of Boot Sector 0: Seek and Read One Sector (Runs at 438EH)
6AD3HImage of Boot Sector 0: End of Read (NMI) (Runs at 43D3H)
6ADFHImage of Boot Sector 0: Send a Command to the Controller (Runs at 43DFH)
6AE6HImage of Boot Sector 0: The Two Messages (Runs at 43E6H)
6B00HImage of Boot Sector 1 (Runs at 4300H)
6B2AHImage of Boot Sector 1: Load SYS0/SYS Record by Record (Runs at 432AH)
6B4EHImage of Boot Sector 1: Fetch a Record Length and Address (Runs at 434EH)
6B5DHImage of Boot Sector 1: Fetch the Next Byte of SYS0/SYS (Runs at 435DH)
6B74HImage of Boot Sector 1: Read a Sector, Five Tries (Runs at 4374H)
6B80HImage of Boot Sector 1: Display Disk error or No system and Restart (Runs at 4380H)
6B8EHImage of Boot Sector 1: Seek and Read One Sector (Runs at 438EH)
6BD3HImage of Boot Sector 1: End of Read (NMI) (Runs at 43D3H)
6BDFHImage of Boot Sector 1: Send a Command to the Controller (Runs at 43DFH)
6BE6HImage of Boot Sector 1: The Two Messages (Runs at 43E6H)
6C00HThe Buffer at 6C00H (Not in the File)
6D00HThe Front End: the Banner, the System Information Sector
6D36HThe Drive and the Parameters
6D93HNAME and MPW Follow QUERY, the Drive's Table
6DE0HThe Diskette Name, the Date, the Master Password
6E73HThe Density
6EF8HThe Sides and the Cylinders
6F50HThe Bootstrap Step Rate
6FC1HThe Allocation Table Image, the Target Diskette
700CHCheck the Target Diskette
70ECHA Number From Digits
70FFHCheck and Hash the Master Password
713CHDoes a Diskette Turn?
7163HNot in the File: the Saved Table and the Cylinders of the Drives
7175HTwo Supervisor Requests
717BHThe Master Password, a Text
719DHThe Table of the Parameters
7236HThe Front End's Texts

Memory FORMAT Uses

AddressContents
0033H, 0040H, 0049H, 0060HROM: display the character in Register A; the line input (Register Pair HL the buffer, Register B the length, the CARRY FLAG for BREAK; it ends the reply with 0DH); wait for a key; the delay, Register Pair BC counted down.
4012HThe interrupt vector (ROM 0038H jumps here): C3H, the JP to 44A5H. FORMAT stores C9H (RET) here while it writes the tracks (6010H) and puts the byte back (63E7H).
402DH, 4030H, 4409H@EXIT (the end, Register Pair HL = 0000H), @ABORT and @ERROR (a disk error or error 2CH, bit 6 set for the short message).
4288HTIMER$, the tick counter (30 a second on the Model III): the half second of the test whether a diskette turns.
4411H-4412HHIGH$: the track must end below it (7053H).
4300H-43FFHThe system's sector buffer: the system information sector of drive 0 is read here (6D11H); its drive tables in the second block at 4370H give the default step rate (+03H of drive 0) and each drive's highest cylinder (+06H).
442BHSFLAG$: bit 5 a JCL job runs (no question can be answered).
4467H, 428AH, 4454H@DSPLY, @LOGOT and @PARAM.
3033HROM: @DATE, the date as MM/DD/YY into the allocation table (6E20H); the Model I file calls the LDOS vector 4470H.
4700H-474FHDCT$: the target drive's table is copied from here (47A5H, 6DBEH); FORMAT never writes it.
4777HRDSECT: the read of the system information sector.
47A5HThe address of drive Register C's table: Register Pair HL = 4700H + the drive x 10.
4B6BHMULTEA: Register A = Register A x Register E (8 bits).
RST 28H, 84H and E4HSYS2/SYS: 84H loads it, E4H the hash of the master password (its 4E27H).
4583HSYS0/SYS's floppy disk driver, called through the working table (functions 00H, 01H, 04H, 05H, 07H, 09H, 0AH, 0CH, 0DH, 0EH, 0FH).

Variables

The entry points of FORMAT, then the data of the file, the operands it changes, and the memory outside the file that it uses, by address.

Entry Points

AddressContents
6D00HThe start of FORMAT, the transfer address of the file: the front end.
6000HThe engine, entered from 70E9H with Index Register IY = 6505H.
6013HBuild the track from the template.
6095HFormat every cylinder.
612EHVerify every cylinder.
61F8HChoose the directory cylinder (6201H after the verify).
6252HWrite the boot sectors, the allocation table, the system information sector and the directory.
63BBHThe end through @EXIT.
63D5HFormat aborted! (63D8H another text) and @ABORT.
63E1HPut back the interrupt vector, ask for the system diskette, Restore.
6401HThe calls to the driver: 6401H function 00H, 6404H 01H, 6408H 04H, 640CH 05H, 6410H 07H, 6414H 0FH, 6418H 0CH, 641CH 0DH, 6420H 0EH, 6424H 09H, 6428H 0AH; 642AH the common part.
6438HVerify a sector with the deleted data mark.
6448HReport a disk error and end; 6452H error 2CH.
6456HTwo digits of a number (Register C, Register B).
6463HDisplay a question and read up to 3 characters; 646AH up to 8; 646FH into the buffer at Register Pair HL.
648AHWrite two digits over the last two on the screen.
649CHPut a track descriptor into effect with the default cylinders; 64ABH without them.
70ECHA number from digits.
70FFHCheck and hash the master password.
713CHDoes a diskette turn?
7175HThe requests 84H (7175H) and E4H (7178H).

Data in the File

Address
Size
Contents
64C5H
1 byte
DEFB 5EH
64C5H, BOOT/SYS +00H, the attribute: 5EH, bit 6 a system file, bit 4 in use, bit 3 invisible, bits 2-0 access level 6 (execute only without the password).
64C6H
1 byte
DEFB 00H
64C6H, BOOT/SYS +01H: 00H, no flags and no month (the record is not dated).
64C7H
1 byte
DEFB 00H
64C7H, BOOT/SYS +02H: 00H, the day and the year of the date, none.
64C8H
1 byte
DEFB 00H
64C8H, BOOT/SYS +03H: 00H, the end of file byte: the last sector is full.
64C9H
1 byte
DEFB 00H
64C9H, BOOT/SYS +04H: 00H, the record length: 256 bytes.
64CAH-64D1H
8 bytes
DEFM "BOOT "
64CAH-64D1H, BOOT/SYS +05H-+0CH: the name BOOT, padded with spaces to 8 bytes.
64D2H-64D4H
3 bytes
DEFM "SYS"
64D2H-64D4H, BOOT/SYS +0DH-+0FH: the extension SYS.
64D5H-64D6H
2 bytes
DEFW 01AEH
64D5H-64D6H, BOOT/SYS +10H-+11H: 01AEH, the hash of the file's password (4296H would be no password); SYS2/SYS's @OPEN compares it.
64D7H-64D8H
2 bytes
DEFW 0000H
64D7H-64D8H, BOOT/SYS +12H-+13H: 0000H, the time and the year of the date stamp, none.
64D9H-64DAH
2 bytes
DEFW 0005H
64D9H-64DAH, BOOT/SYS +14H-+15H: 0005H, the ending record number: 5 sectors, cylinder 0 sectors 0-4.
64DBH
1 byte
DEFB 00H
64DBH, BOOT/SYS +16H: 00H, the cylinder of the first extent: cylinder 0.
64DCH
1 byte
DEFB 00H
64DCH, BOOT/SYS +17H: 00H, the first extent's first granule (bits 7-5: granule 0) and its granules less one (bits 4-0: one granule).
64DDH-64E2H
6 bytes
DEFB FFH x 6
64DDH-64E2H, BOOT/SYS +18H-+1DH: the three other extents, FFH (no extent).
64E3H
1 byte
DEFB FFH
64E3H, BOOT/SYS +1EH: FFH, no link to an extension record.
64E4H
1 byte
DEFB FFH
64E4H, BOOT/SYS +1FH: FFH, the number of an extension record, none.
64E5H
1 byte
DEFB 5DH
64E5H, DIR/SYS +00H, the attribute: 5DH, bit 6 a system file, bit 4 in use, bit 3 invisible, bits 2-0 access level 5 (read only without the password).
64E6H
1 byte
DEFB 00H
64E6H, DIR/SYS +01H: 00H, no flags and no month.
64E7H
1 byte
DEFB 00H
64E7H, DIR/SYS +02H: 00H, the day and the year of the date, none.
64E8H
1 byte
DEFB 00H
64E8H, DIR/SYS +03H: 00H, the end of file byte: the last sector is full.
64E9H
1 byte
DEFB 00H
64E9H, DIR/SYS +04H: 00H, the record length: 256 bytes.
64EAH-64F1H
8 bytes
DEFM "DIR "
64EAH-64F1H, DIR/SYS +05H-+0CH: the name DIR, padded with spaces to 8 bytes.
64F2H-64F4H
3 bytes
DEFM "SYS"
64F2H-64F4H, DIR/SYS +0DH-+0FH: the extension SYS.
64F5H-64F6H
2 bytes
DEFW 01AEH
64F5H-64F6H, DIR/SYS +10H-+11H: 01AEH, the hash of the file's password, the same as BOOT/SYS.
64F7H-64F8H
2 bytes
DEFW 4296H
64F7H-64F8H, DIR/SYS +12H-+13H: 4296H, the hash of eight spaces. DATECONV/CMD treats a record with 4296H here as one without a date stamp.
64F9H-64FAH
2 bytes
DEFW 000AH
64F9H-64FAH, DIR/SYS +14H-+15H: the ending record number, 000AH in the file; 635FH stores the sectors of the directory cylinder (at most 34) in the low byte.
64FBH
1 byte
DEFB 11H
64FBH, DIR/SYS +16H: the cylinder of the first extent, 11H (17) in the file; 625CH and 6372H store the directory cylinder.
64FCH
1 byte
DEFB 01H
64FCH, DIR/SYS +17H: the first extent's first granule (bits 7-5) and granules less one (bits 4-0), 01H in the file; 636CH stores granule 0 and the granules of the cylinder less one.
64FDH-6502H
6 bytes
DEFB FFH x 6
64FDH-6502H, DIR/SYS +18H-+1DH: the three other extents, FFH (no extent).
6503H
1 byte
DEFB FFH
6503H, DIR/SYS +1EH: FFH, no link to an extension record.
6504H
1 byte
DEFB FFH
6504H, DIR/SYS +1FH: FFH, the number of an extension record, none.
6505H-650EH
10 bytes
DEFS 10
6505H-650EH: not in the file. The working copy of the target drive's drive code table: the front end copies the drive's table here (6DC1H) and changes it for the format chosen; the engine reaches the driver through it (6436H).
650FH
1 byte
DEFB 00H
650FH: the bootstrap step rate, 0-3: 00H in the file, the value the front end chooses stored by 6FBEH; 6268H and 6295H put it into bits 1-0 of the Seek command of the two boot sectors.
6510H-6511H
2 bytes
DEFS 2
6510H-6511H: not in the file. 6510H the sectors on a cylinder (6023H, 61EFH), 6511H the sectors on a track (6018H).
6512H-6517H
6 bytes
DEFW 652AH, 2409H, 0D35H
6512H-6517H: 5 inch single density. Template 652AH; +07H 09H (10 sectors on a track, one head), +08H 24H (2 granules on a track, 5 sectors to a granule); 0D35H (3381) bytes of memory, 20 more than the 3105 bytes of the track and the 256 bytes of FFH after it.
6518H-651DH
6 bytes
DEFW 656AH, 4511H, 196AH
6518H-651DH: 5 inch double density. Template 656AH; +07H 11H (18 sectors on a track), +08H 45H (3 granules on a track, 6 sectors to a granule); 196AH (6506) bytes of memory, 84 fewer than the 6334 bytes of the track and the 256 bytes of FFH after it (19BEH) that 6013H writes.
651EH-6523H
6 bytes
DEFW 65C4H, 270FH, 1558H
651EH-6523H: 8 inch single density. Template 65C4H; +07H 0FH (16 sectors on a track), +08H 27H (2 granules on a track, 8 sectors to a granule); 1558H (5464) bytes of memory, 32 more than the 5176 bytes of the track and the 256 bytes of FFH.
6524H-6529H
6 bytes
DEFW 6609H, 491DH, 29B1H
6524H-6529H: 8 inch double density. Template 6609H; +07H 1DH (30 sectors on a track), +08H 49H (3 granules on a track, 10 sectors to a granule); 29B1H (10673) bytes of memory, 60 more than the 10357 bytes of the track and the 256 bytes of FFH.
652AH
1 byte
DEFB 0AH
652AH, template +00H: 0AH, 10 sectors on a track (6016H).
652BH
1 byte
DEFB 07H
652BH, template +01H: 07H, the skew: each cylinder starts the order of the sectors 7 places further on (6026H).
652CH-6535H
10 bytes
DEFB 00H, 05H, 01H, 06H, 02H, 07H, 03H, 08H, 04H, 09H
652CH-6535H: the order of the sectors on the track, with an interleave of 2: each sector number lies two places after the one before.
6536H-653DH
8 bytes
DEFB F6H x 8
6536H-653DH: F6H (minus 10) eight times, the skew plus 1: a pointer that runs past the last sector number moves back 10 places (60C2H-60CBH).
653EH-653FH
2 bytes
DEFB 0EH, FFH
653EH-653FH: 14 bytes of FFH, the gap at the start of the track after the index pulse.
6540H
1 byte
DEFB F1H
6540H: F1H, the start of the part built once for each of the 10 sectors.
6541H-6542H
2 bytes
DEFB 06H, 00H
6541H-6542H: 6 bytes of 00H before the ID field.
6543H-6544H
2 bytes
DEFB 01H, FEH
6543H-6544H: 1 byte FEH, the ID address mark.
6545H
1 byte
DEFB F3H
6545H: F3H, the address of the next byte of the track goes into the table at 6C00H: the ID field's cylinder byte.
6546H-6547H
2 bytes
DEFB 03H, 00H
6546H-6547H: 3 bytes of 00H, the cylinder, side and sector of the ID field, filled in for each cylinder by 60B2H-60CDH.
6548H-6549H
2 bytes
DEFB 01H, 01H
6548H-6549H: 1 byte 01H, the size code of the ID field: 256 bytes.
654AH-654BH
2 bytes
DEFB 01H, F7H
654AH-654BH: 1 byte F7H: the controller writes the two CRC bytes of the ID field.
654CH-654DH
2 bytes
DEFB 01H, FFH
654CH-654DH: 1 byte FFH, the start of the gap after the ID field.
654EH-654FH
2 bytes
DEFB 0BH, FFH
654EH-654FH: 11 bytes of FFH, the rest of the gap after the ID field.
6550H-6551H
2 bytes
DEFB 06H, 00H
6550H-6551H: 6 bytes of 00H before the data field.
6552H-6553H
2 bytes
DEFB 01H, FBH
6552H-6553H: 1 byte FBH, the data address mark.
6554H-6555H
2 bytes
DEFB 00H, E5H
6554H-6555H: 256 bytes of E5H (a count of 00H), the data of the sector.
6556H-6557H
2 bytes
DEFB 01H, F7H
6556H-6557H: 1 byte F7H: the controller writes the two CRC bytes of the data field.
6558H-6559H
2 bytes
DEFB 01H, FFH
6558H-6559H: 1 byte FFH, the start of the gap after the data field.
655AH-655BH
2 bytes
DEFB 0DH, FFH
655AH-655BH: 13 bytes of FFH, the rest of the gap after the data field.
655CH
1 byte
DEFB F2H
655CH: F2H, the end of the part built for each sector.
655DH-655EH
2 bytes
DEFB 47H, FFH
655DH-655EH: 71 bytes of FFH, the gap at the end of the track.
655FH
1 byte
DEFB F4H
655FH: F4H, the end of the template; 6085H finishes the track there.
6560H-6569H
10 bytes
DEFB 00H, 01H, 02H, 03H, 04H, 05H, 06H, 07H, 08H, 09H
6560H-6569H: the sectors in the order the verify pass reads them (6155H): every second sector around the track, positions 0, 2, 4 and so on, then 1, 3, 5 and so on, so each read has the time of one sector before the next.
656AH
1 byte
DEFB 12H
656AH, template +00H: 12H, 18 sectors on a track (6016H).
656BH
1 byte
DEFB 0DH
656BH, template +01H: 0DH, the skew: each cylinder starts the order of the sectors 13 places further on (6026H).
656CH-657DH
18 bytes
DEFB 00H, 06H, 0CH, 01H, 07H, 0DH, 02H, 08H, 0EH, 03H, 09H, 0FH, 04H, 0AH, 10H, 05H, 0BH, 11H
656CH-657DH: the order of the 18 sectors on the track (an interleave of 3).
657EH-658BH
14 bytes
DEFB EEH x 14
657EH-658BH: EEH (minus 18) fourteen times, the skew plus 1: a pointer that runs past the last sector number moves back 18 places (60C2H-60CBH).
658CH-658DH
2 bytes
DEFB 20H, 4EH
658CH-658DH: 32 bytes of 4EH, the gap at the start of the track.
658EH
1 byte
DEFB F1H
658EH: F1H, the start of the part built once for each of the 18 sectors.
658FH-6590H
2 bytes
DEFB 0CH, 00H
658FH-6590H: 12 bytes of 00H before the ID field.
6591H-6592H
2 bytes
DEFB 03H, F5H
6591H-6592H: 3 bytes F5H: the controller writes the sync byte A1H with a missing clock bit before the address mark.
6593H-6594H
2 bytes
DEFB 01H, FEH
6593H-6594H: 1 byte FEH, the ID address mark.
6595H
1 byte
DEFB F3H
6595H: F3H, the address of the next byte of the track goes into the table at 6C00H: the ID field's cylinder byte.
6596H-6597H
2 bytes
DEFB 03H, 00H
6596H-6597H: 3 bytes of 00H, the cylinder, side and sector of the ID field, filled in for each cylinder by 60B2H-60CDH.
6598H-6599H
2 bytes
DEFB 01H, 01H
6598H-6599H: 1 byte 01H, the size code of the ID field: 256 bytes.
659AH-659BH
2 bytes
DEFB 01H, F7H
659AH-659BH: 1 byte F7H: the controller writes the two CRC bytes of the ID field.
659CH-659DH
2 bytes
DEFB 16H, 4EH
659CH-659DH: 22 bytes of 4EH, the gap after the ID field.
659EH-659FH
2 bytes
DEFB 0CH, 00H
659EH-659FH: 12 bytes of 00H before the data field.
65A0H-65A1H
2 bytes
DEFB 03H, F5H
65A0H-65A1H: 3 bytes F5H, the sync bytes A1H before the data address mark.
65A2H-65A3H
2 bytes
DEFB 01H, FBH
65A2H-65A3H: 1 byte FBH, the data address mark.
65A4H-65A7H
4 bytes
DEFB F5H, 80H, 6DH, B6H
65A4H-65A7H: F5H: the pair after the count is put that many times, 80H (128) pairs 6DH B6H, the 256 bytes of the sector's data.
65A8H-65A9H
2 bytes
DEFB 01H, F7H
65A8H-65A9H: 1 byte F7H: the controller writes the two CRC bytes of the data field.
65AAH-65ABH
2 bytes
DEFB 01H, 4EH
65AAH-65ABH: 1 byte 4EH, the start of the gap after the data field.
65ACH-65ADH
2 bytes
DEFB 17H, 4EH
65ACH-65ADH: 23 bytes of 4EH, the rest of the gap after the data field.
65AEH
1 byte
DEFB F2H
65AEH: F2H, the end of the part built for each sector.
65AFH-65B0H
2 bytes
DEFB B6H, 4EH
65AFH-65B0H: 182 bytes of 4EH, the gap at the end of the track.
65B1H
1 byte
DEFB F4H
65B1H: F4H, the end of the template; 6085H finishes the track there.
65B2H-65C3H
18 bytes
DEFB 00H, 0CH, 07H, 02H, 0EH, 09H, 04H, 10H, 0BH, 06H, 01H, 0DH, 08H, 03H, 0FH, 0AH, 05H, 11H
65B2H-65C3H: the sectors in the order the verify pass reads them (6155H): every second sector around the track, positions 0, 2, 4 and so on, then 1, 3, 5 and so on, so each read has the time of one sector before the next.
65C4H
1 byte
DEFB 10H
65C4H, template +00H: 10H, 16 sectors on a track (6016H).
65C5H
1 byte
DEFB 02H
65C5H, template +01H: 02H, the skew: each cylinder starts the order of the sectors 2 places further on (6026H).
65C6H-65D5H
16 bytes
DEFB 0AH, 05H, 00H, 0BH, 06H, 01H, 0CH, 07H, 02H, 0DH, 08H, 03H, 0EH, 09H, 04H, 0FH
65C6H-65D5H: the order of the 16 sectors on the track (an interleave of 3).
65D6H-65D8H
3 bytes
DEFB F0H x 3
65D6H-65D8H: F0H (minus 16) three times, the skew plus 1: a pointer that runs past the last sector number moves back 16 places (60C2H-60CBH).
65D9H-65DAH
2 bytes
DEFB 28H, FFH
65D9H-65DAH: 40 bytes of FFH, the gap at the start of the track.
65DBH
1 byte
DEFB F1H
65DBH: F1H, the start of the part built once for each of the 16 sectors.
65DCH-65DDH
2 bytes
DEFB 06H, 00H
65DCH-65DDH: 6 bytes of 00H before the ID field.
65DEH-65DFH
2 bytes
DEFB 01H, FEH
65DEH-65DFH: 1 byte FEH, the ID address mark.
65E0H
1 byte
DEFB F3H
65E0H: F3H, the address of the next byte of the track goes into the table at 6C00H: the ID field's cylinder byte.
65E1H-65E2H
2 bytes
DEFB 03H, 00H
65E1H-65E2H: 3 bytes of 00H, the cylinder, side and sector of the ID field, filled in for each cylinder by 60B2H-60CDH.
65E3H-65E4H
2 bytes
DEFB 01H, 01H
65E3H-65E4H: 1 byte 01H, the size code of the ID field: 256 bytes.
65E5H-65E6H
2 bytes
DEFB 01H, F7H
65E5H-65E6H: 1 byte F7H: the controller writes the two CRC bytes of the ID field.
65E7H-65E8H
2 bytes
DEFB 0BH, FFH
65E7H-65E8H: 11 bytes of FFH, the gap after the ID field.
65E9H-65EAH
2 bytes
DEFB 06H, 00H
65E9H-65EAH: 6 bytes of 00H before the data field.
65EBH-65ECH
2 bytes
DEFB 01H, FBH
65EBH-65ECH: 1 byte FBH, the data address mark.
65EDH-65EEH
2 bytes
DEFB 00H, E5H
65EDH-65EEH: 256 bytes of E5H (a count of 00H), the data of the sector.
65EFH-65F0H
2 bytes
DEFB 01H, F7H
65EFH-65F0H: 1 byte F7H: the controller writes the two CRC bytes of the data field.
65F1H-65F2H
2 bytes
DEFB 01H, FFH
65F1H-65F2H: 1 byte FFH, the start of the gap after the data field.
65F3H-65F4H
2 bytes
DEFB 14H, FFH
65F3H-65F4H: 20 bytes of FFH, the rest of the gap after the data field.
65F5H
1 byte
DEFB F2H
65F5H: F2H, the end of the part built for each sector.
65F6H-65F7H
2 bytes
DEFB D0H, FFH
65F6H-65F7H: 208 bytes of FFH, the gap at the end of the track.
65F8H
1 byte
DEFB F4H
65F8H: F4H, the end of the template; 6085H finishes the track there.
65F9H-6608H
16 bytes
DEFB 0AH, 00H, 06H, 0CH, 02H, 08H, 0EH, 04H, 05H, 0BH, 01H, 07H, 0DH, 03H, 09H, 0FH
65F9H-6608H: the sectors in the order the verify pass reads them (6155H): every second sector around the track, positions 0, 2, 4 and so on, then 1, 3, 5 and so on, so each read has the time of one sector before the next.
6609H
1 byte
DEFB 1EH
6609H, template +00H: 1EH, 30 sectors on a track (6016H).
660AH
1 byte
DEFB 03H
660AH, template +01H: 03H, the skew: each cylinder starts the order of the sectors 3 places further on (6026H).
660BH-6628H
30 bytes
DEFB 00H, 06H, 0CH, 12H, 18H, 01H, 07H, 0DH, 13H, 19H, 02H, 08H, 0EH, 14H, 1AH, 03H, 09H, 0FH, 15H, 1BH, 04H, 0AH, 10H, 16H, 1CH, 05H, 0BH, 11H, 17H, 1DH
660BH-6628H: the order of the 30 sectors on the track (an interleave of 5).
6629H-662CH
4 bytes
DEFB E2H x 4
6629H-662CH: E2H (minus 30) four times, the skew plus 1: a pointer that runs past the last sector number moves back 30 places (60C2H-60CBH).
662DH-662EH
2 bytes
DEFB 14H, 4EH
662DH-662EH: 20 bytes of 4EH, the gap at the start of the track.
662FH
1 byte
DEFB F1H
662FH: F1H, the start of the part built once for each of the 30 sectors.
6630H-6631H
2 bytes
DEFB 0CH, 00H
6630H-6631H: 12 bytes of 00H before the ID field.
6632H-6633H
2 bytes
DEFB 03H, F5H
6632H-6633H: 3 bytes F5H: the controller writes the sync byte A1H with a missing clock bit before the address mark.
6634H-6635H
2 bytes
DEFB 01H, FEH
6634H-6635H: 1 byte FEH, the ID address mark.
6636H
1 byte
DEFB F3H
6636H: F3H, the address of the next byte of the track goes into the table at 6C00H: the ID field's cylinder byte.
6637H-6638H
2 bytes
DEFB 03H, 00H
6637H-6638H: 3 bytes of 00H, the cylinder, side and sector of the ID field, filled in for each cylinder by 60B2H-60CDH.
6639H-663AH
2 bytes
DEFB 01H, 01H
6639H-663AH: 1 byte 01H, the size code of the ID field: 256 bytes.
663BH-663CH
2 bytes
DEFB 01H, F7H
663BH-663CH: 1 byte F7H: the controller writes the two CRC bytes of the ID field.
663DH-663EH
2 bytes
DEFB 16H, 4EH
663DH-663EH: 22 bytes of 4EH, the gap after the ID field.
663FH-6640H
2 bytes
DEFB 0CH, 00H
663FH-6640H: 12 bytes of 00H before the data field.
6641H-6642H
2 bytes
DEFB 03H, F5H
6641H-6642H: 3 bytes F5H, the sync bytes A1H before the data address mark.
6643H-6644H
2 bytes
DEFB 01H, FBH
6643H-6644H: 1 byte FBH, the data address mark.
6645H-6648H
4 bytes
DEFB F5H, 80H, 6DH, B6H
6645H-6648H: F5H: the pair after the count is put that many times, 80H (128) pairs 6DH B6H, the 256 bytes of the sector's data.
6649H-664AH
2 bytes
DEFB 01H, F7H
6649H-664AH: 1 byte F7H: the controller writes the two CRC bytes of the data field.
664BH-664CH
2 bytes
DEFB 01H, FFH
664BH-664CH: 1 byte FFH after the data field's CRC (the other templates of double density put 4EH here).
664DH-664EH
2 bytes
DEFB 11H, 4EH
664DH-664EH: 17 bytes of 4EH, the gap after the data field.
664FH
1 byte
DEFB F2H
664FH: F2H, the end of the part built for each sector.
6650H-6651H
2 bytes
DEFB 00H, 4EH
6650H-6651H: 256 bytes of 4EH (a count of 00H), the first part of the gap at the end of the track.
6652H-6653H
2 bytes
DEFB 3DH, 4EH
6652H-6653H: 61 bytes of 4EH, the rest of the gap at the end of the track.
6654H
1 byte
DEFB F4H
6654H: F4H, the end of the template; 6085H finishes the track there.
6655H-6672H
30 bytes
DEFB 00H, 0CH, 18H, 07H, 13H, 02H, 0EH, 1AH, 09H, 15H, 04H, 10H, 1CH, 0BH, 17H, 06H, 12H, 01H, 0DH, 19H, 08H, 14H, 03H, 0FH, 1BH, 0AH, 16H, 05H, 11H, 1DH
6655H-6672H: the sectors in the order the verify pass reads them (6155H): every second sector around the track, positions 0, 2, 4 and so on, then 1, 3, 5 and so on, so each read has the time of one sector before the next.
6673H
1 byte
DEFB 1DH
6673H: 1DH, the cursor to the start of its line: the start of the text of 6095H.
6674H-6689H
22 bytes
DEFM "Formatting cylinder "
6674H-6689H: Formatting cylinder and three spaces; 648AH writes the cylinder number over the last two.
668AH
1 byte
DEFB 03H
668AH: 03H, the end of the text: the cursor stays after the spaces.
668BH
1 byte
DEFB 1DH
668BH: 1DH, the cursor to the start of its line: the start of the text of 6136H.
668CH-66A1H
22 bytes
DEFM "Verifying cylinder "
668CH-66A1H: Verifying, two spaces, cylinder and three spaces, as long as the text above; 648AH writes the cylinder number over the last two.
66A2H
1 byte
DEFB 03H
66A2H: 03H, the end of the text: the cursor stays after the spaces.
66A3H-66A6H
4 bytes
DEFM "* "
66A3H-66A6H: an asterisk and three spaces, displayed after the number of a cylinder that failed the verify (61A4H).
66A7H
1 byte
DEFB 03H
66A7H: 03H, the end of the text: the next cylinder number goes two places before its end.
66A8H-66B4H
13 bytes
DEFM "Formatting..."
66A8H-66B4H: Formatting..., displayed before the driver's function 0CH (61CCH).
66B5H
1 byte
DEFB 0DH
66B5H: 0DH, the end of the line and of the text.
66B6H-66DAH
37 bytes
DEFM "No cylinders available for directory!"
66B6H-66DAH: the text 6235H points to when no cylinder can take the directory; the JP 63D5H after it displays Format aborted! instead.
66DBH
1 byte
DEFB 0DH
66DBH: 0DH, the end of the line and of the text.
66DCH-6700H
37 bytes
DEFM "Directory will be placed on cylinder "
66DCH-6700H: Directory will be placed on cylinder and a space, displayed by 6246H.
6701H-6702H
2 bytes
DEFM "00"
6701H-6702H: two digits, 00 in the file: 6242H stores the directory cylinder here.
6703H
1 byte
DEFB 0DH
6703H: 0DH, the end of the line and of the text.
6704H
1 byte
DEFB 0AH
6704H: 0AH, a new line: the start of the text of 624CH.
6705H-6724H
32 bytes
DEFM "Initializing SYSTEM information "
6705H-6724H: Initializing SYSTEM information and a space; the periods and plus signs of the sectors written follow on the line.
6725H
1 byte
DEFB 03H
6725H: 03H, the end of the text: the cursor stays at its end.
6726H
1 byte
DEFB 0AH
6726H: 0AH, a new line: the start of the text of 63F2H.
6727H-674AH
36 bytes
DEFM "Load SYSTEM diskette and hit <ENTER>"
6727H-674AH: Load SYSTEM diskette and hit <ENTER>, displayed after a format of drive 0.
674BH
1 byte
DEFB 0DH
674BH: 0DH, the end of the line and of the text.
674CH
1 byte
DEFB 0AH
674CH: 0AH, a new line: the start of the text of 63BEH.
674DH-675FH
19 bytes
DEFM "Formatting complete"
674DH-675FH: Formatting complete, displayed and written to the job log by @LOGOT at the end.
6760H
1 byte
DEFB 0DH
6760H: 0DH, the end of the line and of the text.
6761H
1 byte
DEFB 0AH
6761H: 0AH, a new line: the start of the text of 63C4H.
6762H-6788H
39 bytes
DEFM "Note: Realtime clock no longer accurate"
6762H-6788H: Note: Realtime clock no longer accurate, since the clock interrupt was shut out while the tracks were written.
6789H
1 byte
DEFB 0DH
6789H: 0DH, the end of the line and of the text.
678AH-6798H
15 bytes
DEFM "Format aborted!"
678AH-6798H: Format aborted!, the text of 63D5H, displayed and written to the job log.
6799H
1 byte
DEFB 0DH
6799H: 0DH, the end of the line and of the text.
679AH-67B7H
30 bytes
DEFM "Can't, Diskette not formatted!"
679AH-67B7H: the text of 627AH, for a diskette whose cylinder 0, sector 0 cannot be read when only the system information is to be written.
67B8H
1 byte
DEFB 0DH
67B8H: 0DH, the end of the line and of the text.
67B9H-67D8H
32 bytes
DEFB 00H x 32
67B9H-67D8H: 32 bytes of 00H at the end of the block. No code addresses them.
67D9H-67FFH
39 bytes
DEFS 39
67D9H-67FFH: not in the file, and no code of FORMAT uses it.
6800H-6801H
2 bytes
DEFW 6A95H
6800H-6801H: 6A95H, +95H of the image of boot sector 0, the operand of its Seek command LD A,18H (4395H when the sector runs), read by 626CH.
6802H-6803H
2 bytes
DEFW 6B95H
6802H-6803H: 6B95H, +95H of the image of boot sector 1, the operand of its Seek command LD A,18H (4395H when the sector runs), read by 6299H.
6804H-68FFH
252 bytes
DEFS 252
6804H-68FFH: not in the file, and no code of FORMAT uses it.
6900H-69CAH
203 bytes
DEFS 203
6900H-69CAH: not in the file. The allocation table image, +00H-+CAH: 6900H-695FH one byte for each cylinder, a bit set for each granule not free (the front end fills it, 6FD8H; the verify sets FFH for a bad cylinder, 61AEH); 6960H-69BFH the lock out table (6191H copies the allocation bytes there); 69C0H-69CAH what memory holds.
69CBH
1 byte
DEFB 53H
69CBH, the allocation table +CBH: 53H, written to the diskette as it is.
69CCH
1 byte
DEFB 00H
69CCH, +CCH: the number of cylinders less 35, 00H in the file, stored by 62B8H.
69CDH
1 byte
DEFB 00H
69CDH, +CDH: the configuration byte, 00H in the file, stored by 62D6H (bit 7 and bit 3 always, bit 6 double density, bit 5 two sides, bit 4 (cylinder 0 single density) never set by this file, bits 2-0 the granules on a track less one).
69CEH-69CFH
2 bytes
DEFW 0000H
69CEH-69CFH, +CEH-+CFH: the hash of the master password, 0000H in the file, stored by the front end (6E71H).
69D0H-69D7H
8 bytes
DEFM " "
69D0H-69D7H, +D0H-+D7H: the diskette name, eight spaces in the file, stored by the front end (6DEFH, 6E19H).
69D8H-69DFH
8 bytes
DEFM "MM/DD/YY"
69D8H-69DFH, +D8H-+DFH: the date the diskette is formatted, MM/DD/YY in the file, stored by the front end (6E1EH).
69E0H
1 byte
DEFB 0DH
69E0H, +E0H: 0DH, the AUTO command of the diskette: none.
69E1H-69FFH
31 bytes
DEFM " "
69E1H-69FFH, +E1H-+FFH: 31 spaces, the rest of the AUTO command field.
6AE6H-6AE7H
2 bytes
DEFB 17H, E8H
The start of the Disk error message: 17H turns the display to 32 characters a line and E8H is a space compression code that moves the cursor on by 40 spaces.
6AE8H-6AF1H
10 bytes
DEFM "Disk error"
The ten characters Disk error, displayed by 4387H when a sector cannot be read in five tries.
6AF2H-6AF3H
2 bytes
DEFB 1FH, 03H
The end of the Disk error message: 1FH clears from the cursor to the end of the screen and 03H ends the text for the ROM routine at 021BH.
6AF4H-6AF5H
2 bytes
DEFB 17H, E8H
The start of the No system message, at 43F4H, the operand of the LD IX at 4383H and of the LD HL read from 4384H: 17H selects 32 characters a line and E8H moves the cursor on by 40 spaces.
6AF6H-6AFEH
9 bytes
DEFM "No system"
The nine characters No system, displayed when the directory entry of SYS0/SYS is not in use.
6AFFH
1 byte
DEFB 03H
The end byte of the No system message for the ROM routine at 021BH, and the last byte of the boot sector.
6BE6H-6BE7H
2 bytes
DEFB 17H, E8H
The start of the Disk error message: 17H turns the display to 32 characters a line and E8H is a space compression code that moves the cursor on by 40 spaces.
6BE8H-6BF1H
10 bytes
DEFM "Disk error"
The ten characters Disk error, displayed by 4387H when a sector cannot be read in five tries.
6BF2H-6BF3H
2 bytes
DEFB 1FH, 03H
The end of the Disk error message: 1FH clears from the cursor to the end of the screen and 03H ends the text for the ROM routine at 021BH.
6BF4H-6BF5H
2 bytes
DEFB 17H, E8H
The start of the No system message, at 43F4H, the operand of the LD IX at 4383H and of the LD HL read from 4384H: 17H selects 32 characters a line and E8H moves the cursor on by 40 spaces.
6BF6H-6BFEH
9 bytes
DEFM "No system"
The nine characters No system, displayed when the directory entry of SYS0/SYS is not in use.
6BFFH
1 byte
DEFB 03H
The end byte of the No system message for the ROM routine at 021BH, and the last byte of the boot sector.
6C00H-6CFFH
256 bytes
DEFS 256
6C00H-6CFFH: not in the file. While a track is built, the address of each sector's ID field in the track (6039H, 607DH), ended by 0000H; the replies to the questions (646CH, 6D7AH); the sector read from the target diskette (706DH-70B9H); then the sectors FORMAT writes: the system information sector, the hash index table, the directory records and the empty directory sectors (62ECH-63B9H).
7163H-716CH
10 bytes
DEFS 10
7163H-716CH: not in the file. The copy of the working drive code table taken at 7015H and put back at 70E4H.
716DH-7174H
8 bytes
DEFS 8
716DH-7174H: not in the file. The highest cylinder of drives 0-7 from the system information sector (6D2DH); 6DB9H takes the target drive's.
717BH-7182H
8 bytes
DEFM " "
717BH-7182H: the master password, eight spaces in the file: filled from the command line, the reply or PASSWORD (6E31H-6E68H), then checked and hashed (70FFH).
7183H
1 byte
DEFB 20H
7183H: a space after the buffer. The ROM's line input puts its 0DH here after a reply of 8 characters (6E53H).
7184H-719BH
24 bytes
DEFM "Can't " / DEFB 22H / DEFM "SYSTEM" / DEFB 22H / DEFM " a floppy!"
7184H-719BH: the text of 712AH, Can't "SYSTEM" a floppy!, for SYSTEM given for a drive that is not a hard disk (6DD7H).
719CH
1 byte
DEFB 0DH
719CH: 0DH, the end of the line and of the text.
719DH-71A4H
8 bytes
DEFM "NAME " / DEFW 6DE1H
719DH-71A4H: NAME, the diskette name: the operand of LD HL,0000H at 6DE0H.
71A5H-71ACH
8 bytes
DEFM "N " / DEFW 6DE1H
71A5H-71ACH: N, the short form of NAME: 6DE1H.
71ADH-71B4H
8 bytes
DEFM "MPW " / DEFW 6E24H
71ADH-71B4H: MPW, the master password: the operand of LD HL,0000H at 6E23H.
71B5H-71BCH
8 bytes
DEFM "M " / DEFW 6E24H
71B5H-71BCH: M, the short form of MPW: 6E24H.
71BDH-71C4H
8 bytes
DEFM "SDEN " / DEFW 6D57H
71BDH-71C4H: SDEN, single density: the operand of LD DE,0000H at 6D56H.
71C5H-71CCH
8 bytes
DEFM "DDEN " / DEFW 6D5CH
71C5H-71CCH: DDEN, double density: the operand of LD DE,0000H at 6D5BH.
71CDH-71D4H
8 bytes
DEFM "SIDES " / DEFW 6D61H
71CDH-71D4H: SIDES=n, the sides: the operand of LD DE,0000H at 6D60H.
71D5H-71DCH
8 bytes
DEFM "CYL " / DEFW 6D66H
71D5H-71DCH: CYL=n, the cylinders: the operand of LD DE,0000H at 6D65H.
71DDH-71E4H
8 bytes
DEFM "C " / DEFW 6D66H
71DDH-71E4H: C, the short form of CYL: 6D66H.
71E5H-71ECH
8 bytes
DEFM "STEP " / DEFW 6D6BH
71E5H-71ECH: STEP=n, the bootstrap step rate: the operand of LD DE,FF00H at 6D6AH.
71EDH-71F4H
8 bytes
DEFM "ABS " / DEFW 70C2H
71EDH-71F4H: ABS, no question for a diskette that holds data: the operand of LD DE,0000H at 70C1H.
71F5H-71FCH
8 bytes
DEFM "A " / DEFW 70C2H
71F5H-71FCH: A, the short form of ABS: 70C2H.
71FDH-7204H
8 bytes
DEFM "QUERY " / DEFW 6EB1H
71FDH-7204H: QUERY, ask the questions (FFFFH) or not (0000H): the operand of LD DE,FFFFH at 6EB0H.
7205H-720CH
8 bytes
DEFM "Q " / DEFW 6EB1H
7205H-720CH: Q, the short form of QUERY: 6EB1H.
720DH-7214H
8 bytes
DEFM "SYSTEM" / DEFW 61C6H
720DH-7214H: SYSTEM, only the system information, for a hard disk (refused for a floppy, 6DD7H): the operand of LD HL,0000H at 61C5H.
7215H-721CH
8 bytes
DEFM "WAIT " / DEFW 6126H
7215H-721CH: WAIT=n, a wait after each step: the operand of LD BC,0000H at 6125H.
721DH-7224H
8 bytes
DEFM "W " / DEFW 6126H
721DH-7224H: W, the short form of WAIT: 6126H.
7225H-722CH
8 bytes
DEFM "DIR " / DEFW 620DH
7225H-722CH: DIR=n, the cylinder of the directory: the operand of LD BC,0000H at 620CH.
722DH-7234H
8 bytes
DEFM "D " / DEFW 620DH
722DH-7234H: D, the short form of DIR: 620DH.
7235H
1 byte
DEFB 00H
7235H: 00H, the end of the table: @PARAM stops here.
7236H-7237H
2 bytes
DEFB 1CH, 1FH
7236H-7237H: 1CH, the cursor to the top left, and 1FH, clear to the end of the screen: the start of the banner (6D01H).
7238H-726BH
52 bytes
DEFM "FORMAT - LDOS Disk Formatter Program - Version 5.3.1"
7238H-726BH: the name and the version of the program.
726CH
1 byte
DEFB 0AH
726CH: 0AH, a new line: the copyright goes on the next line.
726DH-729DH
49 bytes
DEFM "Copyright 1991 MISOSYS, Inc., All rights reserved"
726DH-729DH: the copyright line of the program, Copyright 1991 MISOSYS, Inc.
729EH-729FH
2 bytes
DEFB 0AH, 0DH
729EH-729FH: 0AH, a new line, and 0DH, the end of the banner.
72A0H-72C8H
41 bytes
DEFM "Insufficient memory for specified format!"
72A0H-72C8H: the text of 7059H, when HIGH$ leaves no room for the track.
72C9H
1 byte
DEFB 0DH
72C9H: 0DH, the end of the line and of the text.
72CAH-72E5H
28 bytes
DEFM "Which drive is to be used ? "
72CAH-72E5H: the question of 6D74H, when no :d is on the command line.
72E6H
1 byte
DEFB 03H
72E6H: 03H, the end of the question: the cursor stays for the reply.
72E7H-72F6H
16 bytes
DEFM "Diskette name ? "
72E7H-72F6H: the question of 6E0AH, for the diskette name.
72F7H
1 byte
DEFB 03H
72F7H: 03H, the end of the question: the cursor stays for the reply.
72F8H-7309H
18 bytes
DEFM "Master password ? "
72F8H-7309H: the question of 6E48H, for the master password.
730AH
1 byte
DEFB 03H
730AH: 03H, the end of the question: the cursor stays for the reply.
730BH-7330H
38 bytes
DEFM "Special non-standard format desired ? "
730BH-7330H: a question that no code of the file displays.
7331H
1 byte
DEFB 03H
7331H: 03H, the end of the question that no code displays.
7332H-7347H
22 bytes
DEFM "Number of cylinders ? "
7332H-7347H: the question of 6F29H, for a 5 inch floppy.
7348H
1 byte
DEFB 03H
7348H: 03H, the end of the question: the cursor stays for the reply.
7349H-7379H
49 bytes
DEFM "Boot strap stepping rate <6, 12, 20, 30 msecs> ? "
7349H-7379H: the question of 6F62H, for a 5 inch drive. It names 30 as the slowest rate, the slowest the Model III's DEVICE table knows for a 5 inch drive; the Model I text reads 30/40.
737AH
1 byte
DEFB 03H
737AH: 03H, the end of the question: the cursor stays for the reply.
737BH-73ACH
50 bytes
DEFM "Bootstrap stepping rate <3, 6, 10, 15/20 msecs> ? "
737BH-73ACH: the question of 6F8CH, for an 8 inch drive.
73ADH
1 byte
DEFB 03H
73ADH: 03H, the end of the question: the cursor stays for the reply.
73AEH-73CBH
30 bytes
DEFM "Enter number of sides <1,2> ? "
73AEH-73CBH: the question of 6EFEH, for the number of sides.
73CCH
1 byte
DEFB 03H
73CCH: 03H, the end of the question: the cursor stays for the reply.
73CDH-73EDH
33 bytes
DEFM "Single or Double density <S,D> ? "
73CDH-73EDH: the question of 6EC4H, for the density.
73EEH
1 byte
DEFB 03H
73EEH: 03H, the end of the question: the cursor stays for the reply.
73EFH-73FEH
16 bytes
DEFM "Drive not ready!"
73EFH-73FEH: the text of 7023H, when the controller's status shows NOT READY.
73FFH
1 byte
DEFB 0DH
73FFH: 0DH, the end of the line and of the text.
7400H-7414H
21 bytes
DEFM "Write protected disk!"
7400H-7414H: the text of 7038H, for a write protected diskette or drive.
7415H
1 byte
DEFB 0DH
7415H: 0DH, the end of the line and of the text.
7416H-7429H
20 bytes
DEFM "Drive not in system!"
7416H-7429H: the text of 702BH, when the head is not on track 0 after a Restore.
742AH
1 byte
DEFB 0DH
742AH: 0DH, the end of the line and of the text.
742BH-7453H
41 bytes
DEFM "Load destination diskette and hit <ENTER>"
742BH-7453H: the text of 6FF2H, for drive 0 and when no diskette turns.
7454H
1 byte
DEFB 0DH
7454H: 0DH, the end of the line and of the text.
7455H
1 byte
DEFB 0AH
7455H: 0AH, a new line: the start of the text of 7133H.
7456H-746DH
24 bytes
DEFM "Invalid Master Password!"
7456H-746DH: the text of 7133H, for a password with other characters than letters and digits.
746EH-746FH
2 bytes
DEFB 0AH, 0DH
746EH-746FH: 0AH, a new line, and 0DH, the end of the text.
7470H-7485H
22 bytes
DEFM "Disk contains data -- "
7470H-7485H: the text of 7079H, followed on the line by one of the four texts below.
7486H
1 byte
DEFB 03H
7486H: 03H, the end of the text: the cursor stays at its end.
7487H-7499H
19 bytes
DEFM "Non-standard format"
7487H-7499H: the text of 707FH, for a diskette whose directory cylinder is not below the highest cylinder.
749AH
1 byte
DEFB 0DH
749AH: 0DH, the end of the line and of the text.
749BH-74AEH
20 bytes
DEFM "Unreadable directory"
749BH-74AEH: the text of 7099H, for a directory sector 0 without the deleted data mark.
74AFH
1 byte
DEFB 0DH
74AFH: 0DH, the end of the line and of the text.
74B0H-74C8H
25 bytes
DEFM "Non-initialized directory"
74B0H-74C8H: the text of 709EH, for a directory whose date has no slash.
74C9H
1 byte
DEFB 0DH
74C9H: 0DH, the end of the line and of the text.
74CAH-74CEH
5 bytes
DEFM "Name="
74CAH-74CEH: Name=, the start of the text of 70BBH.
74CFH-74D6H
8 bytes
DEFM "XXXXXXXX"
74CFH-74D6H: eight X in the file; 70B1H copies the diskette's name here.
74D7H-74DDH
7 bytes
DEFM " Date="
74D7H-74DDH: two spaces and Date=, between the name and the date.
74DEH-74E5H
8 bytes
DEFM "MM/DD/YY"
74DEH-74E5H: MM/DD/YY in the file; 70B9H copies the diskette's date here.
74E6H
1 byte
DEFB 0DH
74E6H: 0DH, the end of the line and of the text.
74E7H-750EH
40 bytes
DEFM "*** The target drive is a hard disk! ***"
74E7H-750EH: the first line of the text of 61B3H.
750FH
1 byte
DEFB 0AH
750FH: 0AH, a new line between the two lines of the text.
7510H-7534H
37 bytes
DEFM "Are you sure you want to format it ? "
7510H-7534H: the question of 61B3H and, on its own, of 70CFH.
7535H
1 byte
DEFB 03H
7535H: 03H, the end of the question: the cursor stays for the reply.
7536H-753DH
8 bytes
DEFM "LDOSDISK"
7536H-753DH: LDOSDISK, the default diskette name (6DEBH). The 1992 manual (M-40-060) gives DOSDISK.
753EH-7545H
8 bytes
DEFM "PASSWORD"
753EH-7545H: PASSWORD, the default master password (6E2EH).
7546H-7565H
32 bytes
DEFB 00H x 32
7546H-7565H: 32 bytes of 00H at the end of the file. No code addresses them.

Operands Changed While It Runs

Address
Size
Contents
6014H-6015H
2 bytes
The operand of LD DE,0000H at 6013H: the address of the template (64AFH).
60A5H-60A6H
2 bytes
The operand of LD BC,0000H at 60A4H: the place in the order of the sectors where the next cylinder starts (602BH, 60D2H, 6103H).
60FDH
1 byte
The operand of LD A,00H at 60FCH: the skew (6028H).
6126H-6127H
2 bytes
The operand of LD BC,0000H at 6125H: WAIT=n, stored by @PARAM.
6156H-6157H
2 bytes
The operand of LD BC,0000H at 6155H: the list of the sectors in the order of the verify (6085H).
615AH
1 byte
The operand of ADD A,00H at 6159H: 00H for side 0, the sectors on a track for side 1 (6152H, 6176H).
6164H
1 byte
The operand of LD A,00H at 6163H: the sectors of the cylinder verified (614FH, 6166H).
61C6H-61C7H
2 bytes
The operand of LD HL,0000H at 61C5H: SYSTEM, FFFFH when given; 6DCDH, 7044H and 7067H read its low byte.
620DH-620EH
2 bytes
The operand of LD BC,0000H at 620CH: DIR=n.
6363H
1 byte
The operand of LD A,00H at 6362H: the granules on a track less one (62D0H).
63E2H
1 byte
The operand of LD A,00H at 63E1H: the byte of 4012H (600BH), 00H until the engine runs.
642DH
1 byte
The operand of LD C,FFH at 642CH: the target drive (6D49H, 6D90H), FFH until it is known.
64F9H, 64FBH, 64FCH
1 byte each
The ending record number (635FH), the cylinder (625CH, 6372H) and the granules (636CH) of DIR/SYS's record.
6701H-6702H
2 bytes
The two digits of the directory cylinder in the text at 66DCH (6242H).
6A02H, 6A95H
1 byte each
Boot sector 0: the directory cylinder (6265H) and the Seek command with the step rate (6273H).
6B02H, 6B95H
1 byte each
Boot sector 1: the directory cylinder (6292H) and the Seek command with the step rate (62A0H).
6D57H-6D58H, 6D5CH-6D5DH
2 bytes each
The operands of LD DE,0000H at 6D56H and 6D5BH: SDEN and DDEN, FFFFH when given.
6D61H-6D62H, 6D66H-6D67H
2 bytes each
The operands of LD DE,0000H at 6D60H and 6D65H: SIDES=n and CYL=n.
6D6BH-6D6CH
2 bytes
The operand of LD DE,FF00H at 6D6AH: STEP=n; 6D6BH the default rate (6D21H), 6D6CH FFH until STEP is given.
6DE1H-6DE2H
2 bytes
The operand of LD HL,0000H at 6DE0H: NAME (@PARAM, or the QUERY value from 6D9EH).
6E24H-6E25H
2 bytes
The operand of LD HL,0000H at 6E23H: MPW (@PARAM, or the QUERY value from 6DA9H).
6EACH
1 byte
The operand of LD A,00H at 6EABH: not 0 when SDEN, DDEN, SIDES, CYL or STEP was given (6D6FH).
6EB1H-6EB2H
2 bytes
The operand of LD DE,FFFFH at 6EB0H: QUERY, 0000H for Q=N.
6EDFH-6EE0H, 6EEFH-6EF0H
2 bytes each
The operands of LD HL,0000H at 6EDEH and 6EEEH: the double and the single density descriptor of the drive's size (6E8DH, 6E88H).
6F36H
1 byte
The operand of LD A,00H at 6F35H: the default cylinders of the drive (6DBBH).
704EH-704FH
2 bytes
The operand of LD DE,0000H at 704DH: the memory the track takes (64C0H).
70C2H-70C3H
2 bytes
The operand of LD DE,0000H at 70C1H: ABS, FFFFH when given.
74CFH-74D6H, 74DEH-74E5H
8 bytes each
The name and the date of a diskette that holds data, in the text at 74CAH (70B1H, 70B9H).

Memory Outside the File That FORMAT Uses

Address
Size
Contents
6505H-650EH
10 bytes
The working drive code table, Index Register IY: +00H-+02H the JP to the driver, +03H the flags (bits 1-0 step rate, bit 3 hard disk, bit 4 side 1, bit 5 8 inch, bit 6 double density, bit 7 write protect), +04H (bits 3-0 the select lines, bit 4 no track writing, bit 5 two sides, bit 6 the controller can do double density), +05H the cylinder the head is on, +06H the highest cylinder, +07H the highest sector and the heads less one, +08H the granules and the sectors of a granule less one, +09H the directory cylinder.
6510H-6511H
2 bytes
The sectors on a cylinder and on a track of the format.
6900H-69CAH
203 bytes
The allocation table image: 6900H-695FH a byte for each cylinder (6FD8H), FFH after the last; 6960H-69BFH the lock out table; 69C0H-69CAH FFH.
6C00H-6CFFH
256 bytes
The address of each sector's ID field in the track (6039H), ended by 0000H; afterwards the buffer of the replies and of the sectors written (62ECH-63B9H) and read (705FH-70B9H).
6D00H-
up to 10673 bytes
The track built by 6013H, over the front end, and 256 bytes of FFH after it.
7163H-716CH
10 bytes
The working table saved during the checks of the diskette (7015H, 70E4H).
716DH-7174H
8 bytes
The highest cylinder of drives 0-7 from the system information sector (6D2DH).

Disassembly

6000H - The Format Engine: Entry

The front end ends with JP 6000H (70E9H) after it has put the drive code table of the target drive, with every choice made, into the working copy at 6505H-650EH and pointed Index Register IY at it. A drive whose table has bit 4 of +04H set gets no tracks written (61B3H). For every other drive the clock interrupt is shut out: the byte at 4012H, the JP of the interrupt vector, becomes a RET until 63E1H puts it back.

6000
BIT 4,(IY+04H) FD CB 04 66
Test bit 4 of +04H of the working drive code table at Index Register IY (6509H): set for a drive whose driver FORMAT does not lay tracks on (SYS2/SYS's @CKDRV skips its index pulse test for such a drive too).
6004
If the NZ FLAG is set (bit 4 of +04H is set), JUMP to 61B3H: no track is written; only the system information goes onto the drive.
6007
DI F3
Disable interrupts: the clock interrupt must not take the processor away while a track is written byte by byte.
6008
LD A,(4012H) 3A 12 40
Fetch the byte at 4012H into Register A: C3H, the JP of the interrupt vector (ROM 0038H jumps to 4012H, which jumps to the interrupt service routine at 44A5H).
600B
LD (63E2H),A 32 E2 63
Store Register A (the byte from 4012H) at 63E2H, the operand of LD A,00H at 63E1H, so that 63E1H can put it back at the end.
600E
LD A,C9H 3E C9
Load Register A with C9H, the opcode of RET, for the interrupt vector at 4012H.
6010
LD (4012H),A 32 12 40
Store Register A (C9H, RET) at 4012H. The driver's read and write engine enables interrupts after each transfer (4668H); an interrupt taken then runs this RET instead of the service routine, and interrupts stay off until the next EI. The clock does not count meanwhile.

6013H - Expand the Track Template

The template (one of four, 652AH-6673H, chosen by 64ABH) is a byte stream that describes one track: byte 0 the sectors on a track, byte 1 the skew from one cylinder to the next, then the table of the order of the sectors on the track (the skew plus 1 plus the sectors on a track bytes), then the codes that build the track. 01H-F0H (and F6H-FFH, 00H = 256) put the next byte that many times into the track; F1H starts the part repeated once for every sector, F2H ends it; F3H notes where the next sector's ID field is (cylinder, side, sector); F5H puts a pair of bytes the count after it times; F4H ends the template. The track is built from 6D00H up, over the front end, which has finished; the address of every ID field goes into the table at 6C00H.

6013
LD DE,0000H 11 00 00
Load Register Pair DE with the address of the template: the operand 6014H-6015H, 0000H in the file, stored by 64AFH from the first word of the track descriptor (652AH, 656AH, 65C4H or 6609H).
6016
LD A,(DE) 1A
Fetch byte 0 of the template at Register Pair DE into Register A: the sectors on a track (10, 18, 16 or 30).
6017
INC DE 13
INCrement Register Pair DE to byte 1 of the template.
6018
LD (6511H),A 32 11 65
Store Register A (the sectors on a track) at 6511H, where 606CH takes it as the count of the repeated part and the verify pass at 6170H reads it.
601B
LD B,A 47
Copy Register A (the sectors on a track) into Register B, for working out where the table of the sector order ends.
601C
BIT 5,(IY+04H) FD CB 04 6E
Test bit 5 of +04H of the working drive code table at Index Register IY (6509H): set for a drive with two sides.
6020
If the Z FLAG is set (one side), JUMP to 6023H with Register A = the sectors on a track.
6022
ADD A,A 87
Double Register A (ADD A,A): a cylinder of two sides has the sectors on a track twice.
6023
LD (6510H),A 32 10 65
Store Register A (the sectors on a cylinder) at 6510H, read by the verify pass (616AH), the directory sizing (6353H) and the loop that writes the directory sectors (63B5H).
6026
LD A,(DE) 1A
Fetch byte 1 of the template at Register Pair DE into Register A: the skew, the number of places the order of the sectors moves on from one cylinder to the next (7, 13, 2 or 3).
6027
INC DE 13
INCrement Register Pair DE to byte 2 of the template, the first byte of the table of the sector order.
6028
LD (60FDH),A 32 FD 60
Store Register A (the skew) at 60FDH, the operand of LD A,00H at 60FCH, which moves the pointer into the table on after every cylinder.
602B
LD (60A5H),DE ED 53 A5 60
Store Register Pair DE (the address of the table of the sector order) at 60A5H-60A6H, the operand of LD BC,0000H at 60A4H: the first cylinder starts at the head of the table.
602F
INC A 3C
INCrement Register A (the skew): the skew plus 1.
6030
ADD A,B 80
ADD Register B (the sectors on a track) to Register A: the length of the table of the sector order, the skew plus 1 plus the sectors on a track.
6031
ADD A,E 83
ADD Register E (the low byte of the address of the table) to Register A: the low byte of the address after the table; the CARRY FLAG is the carry into the high byte.
6032
LD E,A 5F
Copy Register A (the low byte of the address after the table) into Register E.
6033
ADC A,D 8A
ADD Register D (the high byte of the address of the table) and the CARRY FLAG to Register A.
6034
SUB E 93
SUBtract Register E from Register A: Register A = Register D plus the carry, the high byte of the address after the table.
6035
LD D,A 57
Copy Register A (the high byte) into Register D. Register Pair DE now points to the first code of the stream that builds the track.
6036
LD HL,6D00H 21 00 6D
Point Register Pair HL to 6D00H, where the track is built: the front end's code, which has finished.
6039
LD BC,6C00H 01 00 6C
Point Register Pair BC to 6C00H, the table that gets the address of every sector's ID field in the track.
603C
LD A,(DE) 1A
Fetch the next code of the stream at Register Pair DE into Register A.
603D
INC DE 13
INCrement Register Pair DE past the code, to the byte after it in the template.
603E
CP F1H FE F1
Compare Register A (the code) against F1H, the start of the part repeated for every sector.
6040
If the Z FLAG is set (F1H), JUMP to 606CH to start the repeated part.
6042
CP F2H FE F2
Compare Register A (the code) against F2H, the end of the repeated part.
6044
If the Z FLAG is set (F2H), JUMP to 6073H to count one sector and go round again.
6046
CP F3H FE F3
Compare Register A (the code) against F3H: the next three bytes of the track are an ID field's cylinder, side and sector.
6048
If the Z FLAG is set (F3H), JUMP to 607DH to note the address of the ID field.
604A
CP F4H FE F4
Compare Register A (the code) against F4H, the end of the template.
604C
If the Z FLAG is set (F4H), JUMP to 6085H to finish the track.
604E
CP F5H FE F5
Compare Register A (the code) against F5H, a pair of bytes to put into the track a number of times. The flags stay as this CP leaves them through the PUSH below.
6050
PUSH BC C5
Save Register Pair BC (the pointer into the table at 6C00H) to the stack: both loops below count in Register B.
6051
If the NZ FLAG is set (any other code: a count of bytes), JUMP to 6062H to put one byte that many times.
6053
LD A,(DE) 1A
Fetch the count after F5H at Register Pair DE into Register A.
6054
INC DE 13
INCrement Register Pair DE to the first byte of the pair.
6055
LD B,A 47
Copy Register A (the count of pairs) into Register B for the DJNZ below: 00H counts 256.
6056
LD A,(DE) 1A
Fetch the first byte of the pair at Register Pair DE into Register A.
6057
INC DE 13
INCrement Register Pair DE to the second byte of the pair.
6058
LD C,A 4F
Copy Register A (the first byte of the pair) into Register C.
6059
LD A,(DE) 1A
Fetch the second byte of the pair at Register Pair DE into Register A. Register Pair DE stays on it: 6069H moves it on.
605A
LD (HL),C 71
Store Register C (the first byte of the pair) into the track at Register Pair HL.
605B
INC HL 23
INCrement Register Pair HL to the next byte of the track.
605C
LD (HL),A 77
Store Register A (the second byte of the pair) into the track at Register Pair HL.
605D
INC HL 23
INCrement Register Pair HL to the next byte of the track.
605E
DECrement Register B (the pairs left) and LOOP BACK to 605AH until it reaches 0.
6060
JUMP to 6068H to take back the pointer into the table at 6C00H and move Register Pair DE past the pair.
6062
LD B,A 47
Copy Register A (the code: the count of bytes) into Register B for the DJNZ below: 00H counts 256 (the 256 bytes of a sector's data field take two bytes of the template).
6063
LD A,(DE) 1A
Fetch the byte to put into the track at Register Pair DE into Register A. Register Pair DE stays on it: 6069H moves it on.
6064
LD (HL),A 77
Store Register A (the byte) into the track at Register Pair HL.
6065
INC HL 23
INCrement Register Pair HL to the next byte of the track.
6066
DECrement Register B (the bytes left) and LOOP BACK to 6064H until it reaches 0.
6068
POP BC C1
Restore Register Pair BC (the pointer into the table at 6C00H) from the stack.
6069
INC DE 13
INCrement Register Pair DE past the last byte of the item, to the next code of the stream.
606A
LOOP BACK to 603CH for the next code of the template, with Register Pair DE on it.
606C
LD A,(6511H) 3A 11 65
Fetch the sectors on a track from 6511H (stored at 6018H) into Register A: the number of times the repeated part is put into the track.
606F
PUSH DE D5
Save Register Pair DE (the address of the code after F1H, the start of the repeated part) to the stack.
6070
PUSH AF F5
Save Register Pair AF (Register A = the times the part is still to be put) to the stack above it.
6071
JUMP to 603CH to build the repeated part once.
6073
POP AF F1
Restore Register Pair AF from the stack: Register A = the times the repeated part was still to be put.
6074
DEC A 3D
DECrement Register A, the times the repeated part is still to be put: one sector is built.
6075
If the Z FLAG is set (every sector of the track is built), JUMP to 607AH to drop the start address of the part.
6077
POP DE D1
Restore Register Pair DE from the stack: the start of the repeated part, to build it again.
6078
LOOP BACK to 606FH to save the start and the new count again and build the next sector.
607A
POP AF F1
Restore Register Pair AF from the stack: this only drops the start address of the repeated part saved at 606FH.
607B
JUMP to 603CH for the code after F2H, the rest of the template after the repeated part.
607D
LD A,L 7D
Copy Register L (the low byte of the address in the track at Register Pair HL, where the ID field's cylinder byte goes next) into Register A.
607E
LD (BC),A 02
Store Register A (the low byte) into the table at Register Pair BC.
607F
INC BC 03
INCrement Register Pair BC to the next byte of the table.
6080
LD A,H 7C
Copy Register H (the high byte of the address in the track) into Register A.
6081
LD (BC),A 02
Store Register A (the high byte) into the table at Register Pair BC: one word, the address of this sector's ID field.
6082
INC BC 03
INCrement Register Pair BC to the next word of the table.
6083
JUMP to 603CH for the next code: the template goes on with three bytes for the cylinder, side and sector, which 60B2H-60CDH fill in for each cylinder.
6085
LD (6156H),DE ED 53 56 61
Store Register Pair DE (the address after the F4H code: the list of the sectors in the order the verify pass reads them) at 6156H-6157H, the operand of LD BC,0000H at 6155H.
6089
XOR A AF
Set Register A to 00H (XOR A), for the word 0000H that ends the table at 6C00H.
608A
LD (BC),A 02
Store Register A (00H) into the table at Register Pair BC: the low byte of the word 0000H that ends the table.
608B
INC BC 03
INCrement Register Pair BC to the high byte of the word that ends the table.
608C
LD (BC),A 02
Store Register A (00H) into the table at Register Pair BC: the table ends with 0000H, which 60AFH tests.
608D
LD B,00H 06 00
Load Register B with 00H: the DJNZ below counts 256.
608F
LD A,FFH 3E FF
Load Register A with FFH, the byte put after the track.
6091
LD (HL),A 77
Store Register A (FFH) into the track at Register Pair HL.
6092
INC HL 23
INCrement Register Pair HL to the next byte after the track in the buffer.
6093
DECrement Register B and LOOP BACK to 6091H until 256 bytes of FFH follow the track: the Write Track command takes bytes until the index pulse, so a track that turns longer than the template still gets FFH bytes.

6095H - Format Every Cylinder

The track in the buffer at 6D00H is complete except for the cylinder, side and sector bytes of each ID field. For each cylinder, from the one the head is on (cylinder 0 after the Restore at 70E6H) to the highest (+06H of the table), and for each side, the ID fields are filled in, the track is written, and the head steps in one cylinder. The order of the sectors comes from the table of the template; Register Pair BC moves on through it from side to side and cylinder to cylinder, so each cylinder starts its order further on by the skew, and by one place more on a drive with two sides.

6095
LD HL,6673H 21 73 66
Point Register Pair HL to 6673H, the text 1DH (the cursor to the start of its line), Formatting cylinder and three spaces, ended by 03H so the cursor stays at its end.
6098
GOSUB to 4467H, @DSPLY, to display the text at Register Pair HL (6673H). The cylinder number is written over its last two spaces for each cylinder.
609B
LD A,(IY+05H) FD 7E 05
Fetch +05H of the working drive code table at Index Register IY (650AH) into Register A: the cylinder the head is on, kept by the driver (0 after a Restore, plus 1 for each Step In). 6124H returns here for every cylinder.
609E
GOSUB to 6456H to turn Register A (the cylinder) into two digits: Register C = the tens digit, Register B = the units digit.
60A1
GOSUB to 648AH to go back two places on the screen and display Register C and Register B, the cylinder number, over the last two characters of the line.
60A4
LD BC,0000H 01 00 00
Load Register Pair BC with the pointer into the table of the sector order: the operand 60A5H-60A6H, 0000H in the file, stored by 602BH (the head of the table) and after every side and cylinder (60D2H, 6103H).
60A7
LD HL,6C00H 21 00 6C
Point Register Pair HL to 6C00H, the table of the addresses of the ID fields in the track. Side 1 comes back here (60F6H).
60AA
LD E,(HL) 5E
Fetch the low byte of the next address of the table at Register Pair HL into Register E.
60AB
INC HL 23
INCrement Register Pair HL to the high byte of the address.
60AC
LD D,(HL) 56
Fetch the high byte of the address at Register Pair HL into Register D: Register Pair DE = the address of an ID field's cylinder byte in the track.
60AD
INC HL 23
INCrement Register Pair HL to the next word of the table at 6C00H.
60AE
LD A,D 7A
Copy Register D (the high byte of the address) into Register A.
60AF
OR E B3
OR Register E (the low byte) into Register A: the Z FLAG is set by the word 0000H that ends the table (608AH).
60B0
If the Z FLAG is set (every ID field of the track is filled in), JUMP to 60D2H to keep the pointer and write the track.
60B2
LD A,(IY+05H) FD 7E 05
Fetch +05H of the working drive code table at Index Register IY (650AH) into Register A: the cylinder the head is on.
60B5
LD (DE),A 12
Store Register A (the cylinder) into the ID field at Register Pair DE: its cylinder byte.
60B6
INC DE 13
INCrement Register Pair DE to the ID field's side byte.
60B7
LD A,(IY+03H) FD 7E 03
Fetch +03H of the working drive code table at Index Register IY (6508H) into Register A: the drive's flags, bit 4 the side the next write goes to.
60BA
AND 10H E6 10
Mask Register A to bit 4 (AND 10H), the side bit: 00H for side 0, 10H for side 1.
60BC
RRCA 0F
Rotate Register A (the side bit) right one place, from bit 4 to bit 3.
60BD
RRCA 0F
Rotate Register A (the side bit) right one place, from bit 3 to bit 2.
60BE
RRCA 0F
Rotate Register A (the side bit) right one place, from bit 2 to bit 1.
60BF
RRCA 0F
Rotate Register A (the side bit) right one place, from bit 1 to bit 0: Register A = 00H for side 0 or 01H for side 1.
60C0
LD (DE),A 12
Store Register A (the side, 00H or 01H) into the ID field at Register Pair DE: its side byte.
60C1
INC DE 13
INCrement Register Pair DE to the ID field's sector byte.
60C2
LD A,(BC) 0A
Fetch the entry of the table of the sector order at Register Pair BC into Register A: a sector number (bit 7 clear), or the negative number of the sectors on a track (bit 7 set) after the last sector number.
60C3
OR A B7
Set the flags from Register A (OR A): the S FLAG is bit 7 of the entry.
60C4
If the P FLAG is set (bit 7 clear: a sector number), JUMP to 60CCH to use it.
60C7
ADD A,C 81
ADD Register C (the low byte of the pointer) to Register A (the negative count, for example F6H, minus 10): the low byte of the pointer moved back by the sectors on a track. The CARRY FLAG is set when the high byte stays.
60C8
LD C,A 4F
Copy Register A (the new low byte) into Register C.
60C9
If the CARRY FLAG is set (no borrow from the high byte), JUMP to 60CCH: Register Pair BC is moved back.
60CB
DEC B 05
DECrement Register B, the high byte of the pointer, for the borrow: Register Pair BC is moved back by the sectors on a track.
60CC
LD A,(BC) 0A
Fetch the entry at Register Pair BC into Register A: the sector number for this ID field.
60CD
LD (DE),A 12
Store Register A (the sector number) into the ID field at Register Pair DE: its sector byte.
60CE
INC DE 13
INCrement Register Pair DE past the ID field. Register Pair DE is loaded again from the table for the next one.
60CF
INC BC 03
INCrement Register Pair BC, the pointer into the table of the sector order, to the next sector.
60D0
LOOP BACK to 60AAH for the next ID field, with Register Pair HL on the next word of the table at 6C00H.
60D2
LD (60A5H),BC ED 43 A5 60
Store Register Pair BC (the pointer into the table of the sector order after this side) at 60A5H-60A6H, the operand of LD BC,0000H at 60A4H.

60D6H - Write the Track, the Second Side, Step In

The track goes to the drive through the driver's Write Track (function 0FH). On a drive with two sides the same buffer is written again on side 1, its ID fields filled in again: the side byte 01H, and the sector numbers from one place further on in the order table (60F5H). Then the pointer into the table of the sector order moves on by the skew, and, until the highest cylinder is written, the head steps in one cylinder and the loop goes round again at 609BH through the wait at 611EH.

60D6
LD D,(IY+05H) FD 56 05
Fetch +05H of the working drive code table at Index Register IY (650AH) into Register D: the cylinder the head is on. The driver writes Register D to the controller's track register before the command (46E1H).
60D9
GOSUB to 6404H, the driver's function 01H, to select the drive with the side in bit 4 of +03H (bit 4 of the value the driver sends to port F4H, the drive select latch).
60DC
LD HL,6D00H 21 00 6D
Point Register Pair HL to 6D00H, the track built by 6013H, the buffer of the Write Track.
60DF
GOSUB to 6414H, the driver's function 0FH, Write Track: the command F4H, the bytes from Register Pair HL until the next index pulse. The Z FLAG on success, else Register A = the error number.
60E2
If the NZ FLAG is set (the write failed), JUMP to 6448H to give back the interrupt vector and report the error in Register A through @ERROR.
60E5
BIT 5,(IY+04H) FD CB 04 6E
Test bit 5 of +04H of the working drive code table at Index Register IY (6509H): set for a drive with two sides.
60E9
If the Z FLAG is set (one side), JUMP to 60F8H: the cylinder is done.
60EB
BIT 4,(IY+03H) FD CB 03 66
Test bit 4 of +03H of the working drive code table at Index Register IY (6508H): set while side 1 is written.
60EF
If the NZ FLAG is set (side 1 was just written), JUMP to 60F8H: both sides are done.
60F1
SET 4,(IY+03H) FD CB 03 E6
Set bit 4 of +03H of the working drive code table at Index Register IY (6508H): the next select and the side bytes of the ID fields are for side 1.
60F5
INC BC 03
INCrement Register Pair BC, the pointer into the table of the sector order: side 1 starts its order one place further on than where side 0 ended.
60F6
LOOP BACK to 60A7H to fill in the ID fields for side 1 and write the track again.
60F8
RES 4,(IY+03H) FD CB 03 A6
Reset bit 4 of +03H of the working drive code table at Index Register IY (6508H): side 0 for the next cylinder.
60FC
LD A,00H 3E 00
Load Register A with the skew: the operand 60FDH, 00H in the file, stored by 6028H from byte 1 of the template.
60FE
ADD A,C 81
ADD Register C (the low byte of the pointer into the table of the sector order) to Register A (the skew); the CARRY FLAG is the carry into the high byte.
60FF
LD C,A 4F
Copy Register A (the new low byte) into Register C.
6100
ADC A,B 88
ADD Register B (the high byte of the pointer) and the CARRY FLAG to Register A.
6101
SUB C 91
SUBtract Register C from Register A: Register A = Register B plus the carry, the new high byte.
6102
LD B,A 47
Copy Register A (the new high byte) into Register B: Register Pair BC has moved on by the skew.
6103
LD (60A5H),BC ED 43 A5 60
Store Register Pair BC (the pointer, moved on by the skew) at 60A5H-60A6H, the operand of LD BC,0000H at 60A4H, for the next cylinder.
6107
LD A,(IY+05H) FD 7E 05
Fetch +05H of the working drive code table at Index Register IY (650AH) into Register A: the cylinder just written.
610A
CP (IY+06H) FD BE 06
Compare Register A (the cylinder just written) against +06H of the working drive code table at Index Register IY (650BH), the highest cylinder.
610D
If the Z FLAG is set (the highest cylinder is written), JUMP to 612EH to verify.
610F
LD BC,0090H 01 90 00
Load Register Pair BC with 0090H (144), the count of the wait below.
6112
GOSUB to 0060H, the ROM's delay, to count Register Pair BC (144) down to 0 before the head steps.
6115
GOSUB to 640CH, the driver's function 05H, Step In: +05H (650AH) goes up by 1 and the command 58H steps the head in at the drive's rate.
6118
If the NZ FLAG is set (the driver gave an error), JUMP to 6448H to give back the interrupt vector and report the error in Register A.
611B
LD BC,609BH 01 9B 60
Load Register Pair BC with 609BH, the start of the loop over the cylinders, the address the tail below returns to. The verify pass comes to 611EH with 613EH in Register Pair BC (6181H).
611E
GOSUB to 6410H, the driver's function 07H: wait until the controller is not busy (the Step In or the Restore is finished).
6121
If the NZ FLAG is set (the driver gave an error), JUMP to 6448H to give back the interrupt vector and report the error in Register A.
6124
PUSH BC C5
Save Register Pair BC (609BH, or 613EH for the verify pass) to the stack: the RET below, or the RET of the ROM's delay, goes there.
6125
LD BC,0000H 01 00 00
Load Register Pair BC with the WAIT parameter: the operand 6126H-6127H, 0000H in the file, stored by @PARAM for WAIT=n (the table entries WAIT and W at 719DH).
6128
LD A,B 78
Copy Register B (the high byte of the WAIT count) into Register A.
6129
OR C B1
OR Register C (the low byte) into Register A: the Z FLAG is set when no WAIT was given.
612A
RET Z C8
If the Z FLAG is set (no WAIT), RETurn to the address saved at 6124H (609BH or 613EH).
612B
JUMP to 0060H, the ROM's delay: Register Pair BC (the WAIT count) is counted down to 0 and its RET goes to the address saved at 6124H.

612EH - Verify Every Cylinder

Every sector of every cylinder is read back with the driver's Verify (function 0AH), in the order of the list after the template's F4H code (6085H): every second sector around the track, so that each read has the time of one sector before the next comes under the head. Register D is the cylinder; the driver seeks it for each sector. A cylinder with a sector that is not found or fails its CRC is marked with an asterisk on the screen and gets FFH in its byte of the allocation table at 6900H (no granule free); any other error ends the format.

612E
LD A,0DH 3E 0D
Load Register A with 0DH, the end of a line, to end the line of the cylinder numbers.
6130
GOSUB to 0033H, the ROM's routine that displays the character in Register A (0DH): the next text starts on a new line.
6133
GOSUB to 6408H, the driver's function 04H, Restore: +05H (650AH) = 0 and the head goes back to cylinder 0.
6136
LD HL,668BH 21 8B 66
Point Register Pair HL to 668BH, the text 1DH (the cursor to the start of its line), Verifying, two spaces, cylinder and three spaces, ended by 03H.
6139
GOSUB to 4467H, @DSPLY, to display the text at Register Pair HL (668BH). The cylinder number is written over its last two spaces.
613C
LD D,00H 16 00
Load Register D with 00H: the verify starts at cylinder 0.
613E
LD L,D 6A
Copy Register D (the cylinder to verify) into Register L. The tail at 6124H returns here for every cylinder (6181H).
613F
LD H,69H 26 69
Load Register H with 69H: Register Pair HL = 6900H + the cylinder, its byte in the allocation table being built.
6141
LD A,(HL) 7E
Fetch the cylinder's byte of the allocation table at Register Pair HL into Register A: a bit set for each granule not free.
6142
INC A 3C
INCrement Register A: the Z FLAG is set when the byte was FFH, no granule of the cylinder free.
6143
If the Z FLAG is set (the byte is FFH), JUMP to 617CH: the cylinder is not read.
6145
LD A,D 7A
Copy Register D (the cylinder) into Register A, for the display.
6146
GOSUB to 6456H to turn Register A (the cylinder) into two digits: Register C = the tens digit, Register B = the units digit.
6149
PUSH DE D5
Save Register Pair DE (Register D = the cylinder) to the stack across the display.
614A
GOSUB to 648AH to go back two places on the screen and display Register C and Register B, the cylinder number.
614D
POP DE D1
Restore Register Pair DE from the stack: Register D = the cylinder.
614E
XOR A AF
Set Register A to 00H (XOR A), for the two operands below.
614F
LD (6164H),A 32 64 61
Store Register A (00H) at 6164H, the operand of LD A,00H at 6163H: no sector of this cylinder verified yet.
6152
LD (615AH),A 32 5A 61
Store Register A (00H) at 615AH, the operand of ADD A,00H at 6159H: the sector numbers of side 0 are used as they are.
6155
LD BC,0000H 01 00 00
Point Register Pair BC to the list of the sectors in the order they are verified: the operand 6156H-6157H, 0000H in the file, stored by 6085H (the bytes after the template's F4H code).
6158
LD A,(BC) 0A
Fetch the next sector number of the list at Register Pair BC into Register A.
6159
ADD A,00H C6 00
ADD the side offset to Register A (the sector number): the operand 615AH, 00H for side 0, the sectors on a track for side 1 (6176H). The driver takes a sector number at or above the sectors on a track as one on side 1.
615B
LD E,A 5F
Copy Register A (the sector number) into Register E, the sector for the driver.
615C
GOSUB to 6428H, the driver's function 0AH, Verify: seek cylinder Register D, read sector Register E without storing its bytes. The Z FLAG on success, else Register A = the error number.
615F
If the NZ FLAG is set (the sector failed), JUMP to 619AH to lock the cylinder out or report the error in Register A.
6162
INC BC 03
INCrement Register Pair BC to the next sector number of the list.
6163
LD A,00H 3E 00
Load Register A with the count of sectors verified on this cylinder: the operand 6164H, set to 00H at 614FH.
6165
INC A 3C
INCrement Register A, the count of sectors verified on this cylinder.
6166
LD (6164H),A 32 64 61
Store Register A (the count) back at 6164H, the operand of LD A,00H at 6163H.
6169
LD E,A 5F
Copy Register A (the count of sectors verified) into Register E.
616A
LD A,(6510H) 3A 10 65
Fetch the sectors on a cylinder from 6510H (6023H) into Register A.
616D
CP E BB
Compare Register A (the sectors on a cylinder) against Register E (the count verified).
616E
If the Z FLAG is set (every sector of the cylinder is verified), JUMP to 617CH for the next cylinder.
6170
LD A,(6511H) 3A 11 65
Fetch the sectors on a track from 6511H (6018H) into Register A.
6173
CP E BB
Compare Register A (the sectors on a track) against Register E (the count verified): equal when side 0 of a drive with two sides is done.
6174
If the NZ FLAG is set (sectors of this side are left), LOOP BACK to 6158H for the next sector of the list.
6176
LD (615AH),A 32 5A 61
Store Register A (the sectors on a track) at 615AH, the operand of ADD A,00H at 6159H: the sector numbers now count from the first sector of side 1.
6179
INC BC 03
INCrement Register Pair BC. Without effect: 6155H loads Register Pair BC again.
617A
LOOP BACK to 6155H to go through the list again for side 1.
617C
LD A,D 7A
Copy Register D (the cylinder just verified or passed over) into Register A.
617D
INC D 14
INCrement Register D to the next cylinder, which the next Verify seeks.
617E
CP (IY+06H) FD BE 06
Compare Register A (the cylinder just done) against +06H of the working drive code table at Index Register IY (650BH), the highest cylinder.
6181
LD BC,613EH 01 3E 61
Load Register Pair BC with 613EH, the start of the loop over the cylinders, for the tail at 611EH to return to. LD does not change the flags.
6184
If the NZ FLAG is set (cylinders are left), JUMP to 611EH to wait until the controller is not busy, wait the WAIT count and go on at 613EH. No code of the Model III file changes this JR (the Model I file turns it into a JR for a second pass over cylinder 0 in single density).
6186
LD HL,6900H 21 00 69
Point Register Pair HL to 6900H, the allocation table image, the source of the copy below. The verify comes here after the highest cylinder (6184H falls through), and 61F6H for a drive without track writing that is not a hard disk.
6189
LD DE,6960H 11 60 69
Point Register Pair DE to 6960H, the lock out table (allocation table +60H), the destination.
618C
LD B,L 45
Copy Register L (00H, the low byte of 6900H) into Register B, the high byte of the count.
618D
LD C,(IY+06H) FD 4E 06
Fetch +06H of the working drive code table at Index Register IY (650BH) into Register C: the highest cylinder.
6190
INC C 0C
INCrement Register C: Register Pair BC = the number of cylinders.
6191
LDIR ED B0
Copy one byte for each cylinder from Register Pair HL (6900H) to Register Pair DE (6960H), Register Pair BC the count (LDIR): the lock out table starts the same as the allocation table, with FFH for each cylinder that failed.
6193
LD A,0DH 3E 0D
Load Register A with 0DH, the end of a line, to end the line of the verify.
6195
GOSUB to 0033H, the ROM's routine that displays the character in Register A (0DH).
6198
JUMP to 6201H to choose the directory cylinder from the highest cylinder and write the system information.

619AH - A Sector Failed the Verify

Register A holds the driver's error number for the read (0AH Verify): 05H, the sector's ID field was not found, and 04H, a CRC error, mean the surface is bad and the cylinder is locked out; any other error number ends the format through @ERROR.

619A
CP 05H FE 05
Compare Register A (the error number) against 05H, not found.
619C
If the Z FLAG is set (05H, not found), JUMP to 61A3H to lock the cylinder out.
619E
CP 04H FE 04
Compare Register A (the error number) against 04H, a CRC error.
61A0
If the NZ FLAG is set (another error), JUMP to 6448H to give back the interrupt vector and report the error in Register A.
61A3
PUSH DE D5
Save Register Pair DE (Register D = the cylinder) to the stack across the display.
61A4
LD HL,66A3H 21 A3 66
Point Register Pair HL to 66A3H, the text an asterisk and three spaces, ended by 03H: the number of the cylinder stays on the screen with the asterisk after it, and the next number goes two places on.
61A7
GOSUB to 4467H, @DSPLY, to display the text at Register Pair HL (66A3H).
61AA
POP DE D1
Restore Register Pair DE from the stack: Register D = the cylinder.
61AB
LD L,D 6A
Copy Register D (the cylinder) into Register L.
61AC
LD H,69H 26 69
Load Register H with 69H: Register Pair HL = 6900H + the cylinder, its byte of the allocation table.
61AE
LD (HL),FFH 36 FF
Store FFH at Register Pair HL: no granule of the cylinder is free. 6191H copies it into the lock out table too.
61B0
JUMP to 617CH for the next cylinder: the rest of this one is not read.

61B3H - A Drive Without Track Writing: the Hard Disk Question

The entry at 6004H comes here when bit 4 of +04H of the drive's table is set. A drive with bit 3 of +03H set (a hard disk) is formatted only when the operator answers Y. Without SYSTEM the drive's driver gets function 0CH; with SYSTEM nothing is done to the surface. Then the sectors on a cylinder are worked out from the table, and the run joins the choice of the directory cylinder: at 61F8H for a hard disk, through the lock out table copy at 6186H for any other drive.

61B3
LD HL,74E7H 21 E7 74
Point Register Pair HL to 74E7H, the text The target drive is a hard disk! between three asterisks on each side, a new line and Are you sure you want to format it ? ended by 03H.
61B6
BIT 3,(IY+03H) FD CB 03 5E
Test bit 3 of +03H of the working drive code table at Index Register IY (6508H): set for a hard disk.
61BA
If the Z FLAG is set (not a hard disk), JUMP to 61C5H: no question.
61BC
GOSUB to 6463H to display the text at Register Pair HL (74E7H) and read up to 3 characters into 6C00H, in upper case; Register Pair HL comes back pointing to 6C00H. BREAK ends the program at 63D5H.
61BF
LD A,(HL) 7E
Fetch the first character of the reply at Register Pair HL (6C00H) into Register A (0DH when only ENTER was pressed).
61C0
CP 59H FE 59
Compare Register A (the first character) against 59H, Y.
61C2
If the NZ FLAG is set (not Y), JUMP to 63D5H to display Format aborted! and end at @ABORT.
61C5
LD HL,0000H 21 00 00
Load Register Pair HL with the SYSTEM parameter: the operand 61C6H-61C7H, 0000H in the file, FFFFH when @PARAM found SYSTEM (the table entry SYSTEM at 719DH).
61C8
LD A,H 7C
Copy Register H (the high byte of the SYSTEM parameter) into Register A.
61C9
OR L B5
OR Register L (the low byte) into Register A: the Z FLAG is set when SYSTEM was not given.
61CA
If the NZ FLAG is set (SYSTEM given), JUMP to 61D8H: only the system information is written.
61CC
LD HL,66A8H 21 A8 66
Point Register Pair HL to 66A8H, the text Formatting... ended by 0DH.
61CF
GOSUB to 4467H, @DSPLY, to display the text at Register Pair HL (66A8H); Register Pair HL comes back unchanged.
61D2
GOSUB to 6418H, the driver's function 0CH, the only use of it in the file: the drive's own driver formats its surface. SYS0/SYS's floppy driver would take 0CH as a Write Sector, as it takes 0DH (463CH); FORMAT gives it only to a drive with bit 4 of +04H set.
61D5
If the NZ FLAG is set (the driver gave an error), JUMP to 6448H to give back the interrupt vector (unchanged on this path) and report the error in Register A.
61D8
LD A,(IY+07H) FD 7E 07
Fetch +07H of the working drive code table at Index Register IY (650CH) into Register A: bits 4-0 the highest sector on a track, bits 7-5 the heads less one.
61DB
LD D,A 57
Copy Register A (+07H) into Register D, to take the two fields apart.
61DC
AND 1FH E6 1F
Mask Register A to bits 4-0 (AND 1FH): the highest sector on a track.
61DE
LD E,A 5F
Copy Register A (the highest sector) into Register E.
61DF
INC E 1C
INCrement Register E: the sectors on a track (sectors are numbered from 0).
61E0
XOR D AA
Exclusive OR Register D (+07H) into Register A (bits 4-0 of it): Register A = bits 7-5 of +07H only, the heads less one.
61E1
RLCA 07
Rotate Register A left one place (RLCA): bit 7 goes round to bit 0.
61E2
RLCA 07
Rotate Register A left one place (RLCA): bits 7-6 of +07H are now bits 1-0.
61E3
RLCA 07
Rotate Register A left one place (RLCA): Register A = bits 7-5 of +07H as a number 0-7, the heads less one.
61E4
INC A 3C
INCrement Register A: the number of heads of the drive.
61E5
GOSUB to 4B6BH, MULTEA, to multiply Register A (the heads) by Register E (the sectors on a track): Register A = the sectors on a cylinder.
61E8
BIT 5,(IY+04H) FD CB 04 6E
Test bit 5 of +04H of the working drive code table at Index Register IY (6509H): set for a drive with two sides.
61EC
If the Z FLAG is set (one side), JUMP to 61EFH with Register A unchanged.
61EE
ADD A,A 87
Double Register A (ADD A,A), the sectors on a cylinder of a drive with two sides.
61EF
LD (6510H),A 32 10 65
Store Register A (the sectors on a cylinder) at 6510H, which the directory sizing (6353H) and the directory loop (63B5H) read.
61F2
BIT 3,(IY+03H) FD CB 03 5E
Test bit 3 of +03H of the working drive code table at Index Register IY (6508H): set for a hard disk.
61F6
If the Z FLAG is set (not a hard disk), JUMP to 6186H to copy the allocation table to the lock out table, then to 6201H.

61F8H - Choose the Directory Cylinder

Register L starts as the highest cylinder (6201H, the path of a floppy after the verify) or, for a hard disk, as the directory cylinder of the drive's own table (+09H) when that is below the highest cylinder. The directory goes on the cylinder given by DIR=n when it is below Register L, else on the middle cylinder, (Register L + 1) / 2; when that cylinder's byte of the allocation table is FFH (locked out), the cylinders on either side are tried in turn, one up, one down, two up, two down and so on. The search gives up when it reaches the highest cylinder or cylinder 0. The cylinder chosen goes into +09H of the working table, into the text 66DCH and, at 6252H on, into the first extent of DIR/SYS and both boot sectors.

61F8
LD A,(IY+09H) FD 7E 09
Fetch +09H of the working drive code table at Index Register IY (650EH) into Register A: the directory cylinder the drive's own table holds. 61F6H comes here only for a hard disk (bit 3 of +03H set).
61FB
LD L,A 6F
Copy Register A (the directory cylinder of the drive's table) into Register L, the base of the search below.
61FC
CP (IY+06H) FD BE 06
Compare Register A (the directory cylinder of the table) against +06H of the working drive code table at Index Register IY (650BH), the highest cylinder: the CARRY FLAG is set when it is below.
61FF
If the CARRY FLAG is set (the table's directory cylinder is below the highest cylinder), JUMP to 6204H with it in Register L.
6201
LD L,(IY+06H) FD 6E 06
Fetch +06H of the working drive code table at Index Register IY (650BH) into Register L: the highest cylinder. 6198H comes here after the verify of a floppy, and a hard disk whose table holds no lower directory cylinder goes on into it.
6204
LD H,69H 26 69
Load Register H with 69H: Register Pair HL = 6900H + Register L (the highest cylinder, or the directory cylinder of a hard disk's table).
6206
GOSUB to 6408H, the driver's function 04H, Restore: the head goes back to cylinder 0 and +05H = 0.
6209
If the NZ FLAG is set (the driver gave an error), JUMP to 6448H to give back the interrupt vector and report the error in Register A.
620C
LD BC,0000H 01 00 00
Load Register Pair BC with the DIR parameter: the operand 620DH-620EH, 0000H in the file, stored by @PARAM for DIR=n (the table entries DIR and D at 719DH).
620F
LD A,C 79
Copy Register C (the low byte of the DIR value) into Register A.
6210
OR B B0
OR Register B (the high byte) into Register A: the Z FLAG is set when DIR was not given.
6211
If the Z FLAG is set (no DIR), JUMP to 6219H to start at the middle cylinder.
6213
CP L BD
Compare Register A (the low byte of the DIR value, or of the OR with the high byte when that is not 0) against Register L (the highest cylinder, or the hard disk table's directory cylinder).
6214
If the NO CARRY FLAG is set (the value is not below Register L), JUMP to 6219H: the value is ignored and the search starts at the middle cylinder.
6216
LD L,A 6F
Copy Register A (the DIR cylinder) into Register L: Register Pair HL = its byte of the allocation table.
6217
JUMP to 621CH to start the search at the DIR cylinder.
6219
INC L 2C
INCrement Register L (the highest cylinder, or the hard disk table's directory cylinder): for a floppy the number of cylinders.
621A
SRL L CB 3D
Shift Register L right one place (SRL): half of Register L plus 1, for a floppy the middle cylinder; Register Pair HL = its byte of the allocation table.
621C
LD C,00H 0E 00
Load Register C with 00H, the distance of the next try from the cylinder before it.
621E
LD A,(HL) 7E
Fetch the byte of the allocation table at Register Pair HL (the cylinder tried) into Register A.
621F
INC A 3C
INCrement Register A: the Z FLAG is set when the byte was FFH (the cylinder failed the verify).
6220
If the NZ FLAG is set (not FFH), JUMP to 623BH: the directory goes on cylinder Register L.
6222
INC C 0C
INCrement Register C, the distance of the next try.
6223
LD A,C 79
Copy Register C (the distance) into Register A.
6224
RRCA 0F
Rotate Register A right one place (RRCA): bit 0 of the distance goes into the CARRY FLAG, set for an odd distance.
6225
LD A,L 7D
Copy Register L (the cylinder tried) into Register A. LD does not change the flags.
6226
If the NO CARRY FLAG is set (an even distance), JUMP to 6231H to try a cylinder further down.
6228
ADD A,C 81
ADD Register C (the distance) to Register A (the cylinder tried): a cylinder further up.
6229
LD L,A 6F
Copy Register A (the new cylinder) into Register L: Register Pair HL = its byte of the allocation table.
622A
CP (IY+06H) FD BE 06
Compare Register A (the new cylinder) against +06H of the working drive code table at Index Register IY (650BH), the highest cylinder.
622D
If the NZ FLAG is set (not the highest cylinder), LOOP BACK to 621EH to test it.
622F
JUMP to 6235H: the search reached the highest cylinder, the directory has no place.
6231
SUB C 91
SUBtract Register C (the distance) from Register A (the cylinder tried): a cylinder further down.
6232
LD L,A 6F
Copy Register A (the new cylinder) into Register L: Register Pair HL = its byte of the allocation table. LD does not change the flags.
6233
If the NZ FLAG is set (not cylinder 0), LOOP BACK to 621EH to test it.
6235
LD HL,66B6H 21 B6 66
Point Register Pair HL to 66B6H, the text No cylinders available for directory! ended by 0DH. The search reached cylinder 0 or the highest cylinder.
6238
JUMP to 63D5H. 63D5H loads Register Pair HL with 678AH, so the text at 66B6H is not displayed: the operator sees Format aborted!, and the program ends at @ABORT.
623B
LD (IY+09H),L FD 75 09
Store Register L (the cylinder chosen) into +09H of the working drive code table at Index Register IY (650EH): the directory cylinder of every later directory read and write.
623E
LD A,L 7D
Copy Register L (the directory cylinder) into Register A.
623F
GOSUB to 6456H to turn Register A (the directory cylinder) into two digits: Register C = the tens digit, Register B = the units digit.
6242
LD (6701H),BC ED 43 01 67
Store Register Pair BC at 6701H-6702H: Register C (the tens digit) at 6701H and Register B (the units digit) at 6702H, the 00 at the end of the text at 66DCH.
6246
LD HL,66DCH 21 DC 66
Point Register Pair HL to 66DCH, the text Directory will be placed on cylinder nn ended by 0DH.
6249
GOSUB to 4467H, @DSPLY, to display the text at Register Pair HL (66DCH).
624C
LD HL,6704H 21 04 67
Point Register Pair HL to 6704H, the text 0AH (a new line), Initializing SYSTEM information and a space, ended by 03H: the progress marks follow on the same line.
624F
GOSUB to 4467H, @DSPLY, to display the text at Register Pair HL (6704H).

6252H - The Boot Sectors: Cylinder 0, Sectors 0 and 1

Granule 0 of cylinder 0 (the boot sectors and the system information) and the whole directory cylinder are marked used in the allocation table. Both boot sector images (6A00H and 6B00H) hold the same Model III boot sector, the sector 1 of BOOT/SYS: the Model III ROM reads cylinder 0, sector 1 into 4300H and runs it, and sector 0 is a copy byte for byte. Each image gets the directory cylinder at its +02H (6A02H, 6B02H: 4302H, the operand of CP at 4301H when it runs) and the bootstrap step rate (650FH) in bits 1-0 of its Seek command at +95H (6A95H, 6B95H: 4395H, the operand of LD A,18H at 4394H), through the pointers at 6800H and 6802H. Sector 0 is verified before anything is written: a drive that was never formatted (the paths that write no tracks) ends here.

6252
LD HL,6900H 21 00 69
Point Register Pair HL to 6900H, cylinder 0's byte of the allocation table.
6255
LD A,(HL) 7E
Fetch the byte at Register Pair HL (6900H) into Register A: a bit set for each granule of cylinder 0 not free.
6256
OR 01H F6 01
Set bit 0 in Register A (OR 01H): granule 0 of cylinder 0, the boot sectors, the system information sector and the copy of the allocation table, is used.
6258
LD (HL),A 77
Store Register A (cylinder 0's byte) back at Register Pair HL (6900H).
6259
LD A,(IY+09H) FD 7E 09
Fetch +09H of the working drive code table at Index Register IY (650EH) into Register A: the directory cylinder.
625C
LD (64FBH),A 32 FB 64
Store Register A (the directory cylinder) at 64FBH, +16H of the record of DIR/SYS (64E5H): the cylinder of its first extent.
625F
LD L,A 6F
Copy Register A (the directory cylinder) into Register L: Register Pair HL = 6900H + the directory cylinder, its byte of the allocation table.
6260
LD (HL),FFH 36 FF
Store FFH at Register Pair HL: every granule of the directory cylinder is used.
6262
LD A,(IY+09H) FD 7E 09
Fetch +09H of the working drive code table at Index Register IY (650EH) into Register A: the directory cylinder.
6265
LD (6A02H),A 32 02 6A
Store Register A (the directory cylinder) at 6A02H, +02H of the image of boot sector 0: the operand of CP 11H at 4301H when the sector runs at 4300H.
6268
LD A,(650FH) 3A 0F 65
Fetch the bootstrap step rate from 650FH into Register A: 0-3 (03H in the file; the front end stores the value chosen, 6FBEH).
626B
LD B,A 47
Copy Register A (the step rate) into Register B.
626C
LD HL,(6800H) 2A 00 68
Fetch the word at 6800H into Register Pair HL: 6A95H, +95H of the image of boot sector 0, the operand of LD A,18H at 6A94H (4394H when the sector runs), the Seek command the boot sends to the controller.
626F
LD A,(HL) 7E
Fetch the Seek command at Register Pair HL (6A95H) into Register A: 18H in the file, bits 1-0 the step rate.
6270
AND FCH E6 FC
Mask Register A (the Seek command) to bits 7-2 (AND FCH): the step rate bits 1-0 cleared.
6272
OR B B0
OR Register B (the step rate) into Register A: the Seek command with the step rate chosen.
6273
LD (HL),A 77
Store Register A (the Seek command) back at Register Pair HL (6A95H).
6274
LD DE,0000H 11 00 00
Load Register Pair DE with 0000H: Register D = cylinder 0, Register E = sector 0.
6277
GOSUB to 6428H, the driver's function 0AH, Verify: read cylinder Register D (0), sector Register E (0). The Z FLAG when the sector can be read.
627A
LD HL,679AH 21 9A 67
Point Register Pair HL to 679AH, the text Can't, Diskette not formatted! ended by 0DH. LD does not change the flags.
627D
If the NZ FLAG is set (cylinder 0, sector 0 cannot be read), JUMP to 63D8H to display the text at Register Pair HL (679AH), give back the interrupt vector and end at @ABORT.
6280
LD HL,6A00H 21 00 6A
Point Register Pair HL to 6A00H, the image of boot sector 0, a copy of the boot sector (the Model III ROM reads sector 1).
6283
GOSUB to 641CH, the driver's function 0DH, Write Sector: Register Pair HL (6A00H) to cylinder Register D (0), sector Register E (0).
6286
If the Z FLAG is set (written), GOSUB to 6428H, the driver's function 0AH, to verify cylinder 0, sector 0.
6289
If the NZ FLAG is set (the write or the verify failed), JUMP to 6448H to give back the interrupt vector and report the error in Register A.
628C
GOSUB to 63D0H to display a period after Initializing SYSTEM information: one sector written.
628F
LD A,(IY+09H) FD 7E 09
Fetch +09H of the working drive code table at Index Register IY (650EH) into Register A: the directory cylinder.
6292
LD (6B02H),A 32 02 6B
Store Register A (the directory cylinder) at 6B02H, +02H of the image of boot sector 1: the operand of CP 11H at 4301H when the ROM runs it.
6295
LD A,(650FH) 3A 0F 65
Fetch the bootstrap step rate from 650FH into Register A.
6298
LD B,A 47
Copy Register A (the step rate) into Register B.
6299
LD HL,(6802H) 2A 02 68
Fetch the word at 6802H into Register Pair HL: 6B95H, +95H of the image of boot sector 1, the operand of LD A,18H at 6B94H (4394H when the sector runs), its Seek command.
629C
LD A,(HL) 7E
Fetch the Seek command at Register Pair HL (6B95H) into Register A: 18H in the file, bits 1-0 the step rate.
629D
AND FCH E6 FC
Mask Register A (the Seek command) to bits 7-2 (AND FCH): the step rate bits 1-0 cleared.
629F
OR B B0
OR Register B (the step rate) into Register A: the Seek command with the step rate chosen.
62A0
LD (HL),A 77
Store Register A (the Seek command) back at Register Pair HL (6B95H).
62A1
LD DE,0001H 11 01 00
Load Register Pair DE with 0001H: Register D = cylinder 0, Register E = sector 1.
62A4
LD HL,6B00H 21 00 6B
Point Register Pair HL to 6B00H, the image of boot sector 1, the sector the Model III ROM reads into 4300H and runs at a reset.
62A7
GOSUB to 641CH, the driver's function 0DH, Write Sector: Register Pair HL (6B00H) to cylinder Register D (0), sector Register E (1).
62AA
If the Z FLAG is set (written), GOSUB to 6428H, the driver's function 0AH, to verify cylinder 0, sector 1.
62AD
If the NZ FLAG is set (the write or the verify failed), JUMP to 6448H to give back the interrupt vector and report the error in Register A.
62B0
GOSUB to 63D0H to display a period: two sectors written.

62B3H - The Allocation Table: Cylinder 0, Sector 3; the System Information: Sector 2

+CCH and +CDH of the allocation table image at 6900H are built from the working table, the image is written to cylinder 0, sector 3, and a system information sector of 53H and 255 bytes of 00H to sector 2. The Model III file has no second pass over cylinder 0 and keeps no copy of the table, so the configuration byte has no single density cylinder 0 bit (bit 4 stays 0).

62B3
LD A,(IY+06H) FD 7E 06
Fetch +06H of the working drive code table at Index Register IY (650BH) into Register A: the highest cylinder.
62B6
SUB 22H D6 22
SUBtract 22H (34) from Register A: the number of cylinders less 35.
62B8
LD (69CCH),A 32 CC 69
Store Register A (the cylinders less 35) at 69CCH, +CCH of the allocation table image. @CKDRV (SYS2/SYS) puts 22H plus this byte into +06H of a drive's table.
62BB
LD A,(IY+04H) FD 7E 04
Fetch +04H of the working drive code table at Index Register IY (6509H) into Register A.
62BE
AND 20H E6 20
Mask Register A to bit 5 (AND 20H): set for a drive with two sides; it becomes bit 5 of the configuration byte.
62C0
LD B,A 47
Copy Register A (the two sides bit) into Register B.
62C1
LD A,(IY+03H) FD 7E 03
Fetch +03H of the working drive code table at Index Register IY (6508H) into Register A.
62C4
AND 40H E6 40
Mask Register A to bit 6 (AND 40H): set for double density; it becomes bit 6 of the configuration byte.
62C6
OR B B0
OR Register B (the two sides bit) into Register A.
62C7
LD B,A 47
Copy Register A (bits 6 and 5 of the configuration byte) into Register B.
62C8
LD A,(IY+08H) FD 7E 08
Fetch +08H of the working drive code table at Index Register IY (650DH) into Register A: bits 7-5 the granules on a track less one, bits 4-0 the sectors in a granule less one.
62CB
RLCA 07
Rotate Register A left one place (RLCA): bit 7 goes round to bit 0.
62CC
RLCA 07
Rotate Register A left one place (RLCA): bits 7-6 are now bits 1-0.
62CD
RLCA 07
Rotate Register A left one place (RLCA): bits 7-5 of +08H are now bits 2-0.
62CE
AND 07H E6 07
Mask Register A to bits 2-0 (AND 07H): the granules on a track less one.
62D0
LD (6363H),A 32 63 63
Store Register A (the granules on a track less one) at 6363H, the operand of LD A,00H at 6362H, for the extent of DIR/SYS.
62D3
OR B B0
OR Register B (bits 6 and 5) into Register A.
62D4
OR 88H F6 88
Set bits 7 and 3 in Register A (OR 88H): the configuration byte is complete. Bit 3 marks a diskette whose directory records carry this release's date and time format (SYS2/SYS sets the drive's bit of 475DH from it).
62D6
LD (69CDH),A 32 CD 69
Store Register A (the configuration byte) at 69CDH, +CDH of the allocation table image.
62D9
LD HL,6900H 21 00 69
Point Register Pair HL to 6900H, the allocation table image, now complete.
62DC
LD D,00H 16 00
Load Register D with 00H, cylinder 0, for the copy of the allocation table.
62DE
LD E,03H 1E 03
Load Register E with 03H, sector 3: the copy of the allocation table on cylinder 0.
62E0
GOSUB to 641CH, the driver's function 0DH, Write Sector: Register Pair HL (6900H) to cylinder Register D (0), sector Register E (3).
62E3
If the Z FLAG is set (written), GOSUB to 6428H, the driver's function 0AH, to verify cylinder 0, sector 3.
62E6
If the NZ FLAG is set (the write or the verify failed), JUMP to 6448H to give back the interrupt vector and report the error in Register A.
62E9
GOSUB to 63D0H to display a period: three sectors written.
62EC
LD HL,6C00H 21 00 6C
Point Register Pair HL to 6C00H, the sector buffer (the table of the ID fields while the tracks were written).
62EF
LD (HL),00H 36 00
Store 00H at Register Pair HL, a byte of the sector buffer.
62F1
INC L 2C
INCrement Register L to the next byte of the buffer: the Z FLAG is set when Register L wraps from FFH to 00H.
62F2
If the NZ FLAG is set (Register L has not wrapped), LOOP BACK to 62EFH: all 256 bytes of 6C00H-6CFFH become 00H.
62F4
LD HL,6C00H 21 00 6C
Point Register Pair HL to 6C00H, the first byte of the cleared buffer.
62F7
LD (HL),53H 36 53
Store 53H (S) at Register Pair HL (6C00H): byte 0 of the system information sector, the mark that DATECONV/CMD tests. The other 255 bytes stay 00H.
62F9
LD DE,0002H 11 02 00
Load Register Pair DE with 0002H: Register D = cylinder 0, Register E = sector 2, the system information sector.
62FC
GOSUB to 641CH, the driver's function 0DH, Write Sector: Register Pair HL (6C00H) to cylinder Register D (0), sector Register E (2).
62FF
If the Z FLAG is set (written), GOSUB to 6428H, the driver's function 0AH, to verify cylinder 0, sector 2.
6302
If the Z FLAG is set (verified), GOSUB to 63D0H to display a period: four sectors written. The CALL Z at 630DH tests the flags as this instruction leaves them.

6305H - The Directory Cylinder

Every sector of the directory cylinder is written with the deleted data mark (the driver's function 0EH) and read back by 6438H, which accepts only error 06H, the deleted data mark. Sector 0 gets the allocation table, sector 1 the hash index table with the bytes A2H (BOOT/SYS) and C4H (DIR/SYS), sector 2 the record of BOOT/SYS, sector 3 the record of DIR/SYS, every other sector 256 bytes of 00H. A plus sign is displayed for each of the first two sectors and a period for each sector after them.

6305
LD HL,6900H 21 00 69
Point Register Pair HL to 6900H, the allocation table image.
6308
LD D,(IY+09H) FD 56 09
Fetch +09H of the working drive code table at Index Register IY (650EH) into Register D: the directory cylinder.
630B
LD E,00H 1E 00
Load Register E with 00H, sector 0 of the directory cylinder: the allocation table.
630D
If the Z FLAG is set (the sectors of cylinder 0 were written and verified), GOSUB to 6420H, the driver's function 0EH, Write Sector with the deleted data mark: Register Pair HL (6900H) to cylinder Register D, sector Register E (0).
6310
If the Z FLAG is set (written), GOSUB to 6438H to verify that the sector carries the deleted data mark.
6313
LD A,2BH 3E 2B
Load Register A with 2BH, a plus sign, the progress mark of a sector of the directory cylinder. LD does not change the flags.
6315
If the Z FLAG is set (all went well), GOSUB to 0033H, the ROM's routine that displays the character in Register A (+).
6318
LD HL,6C00H 21 00 6C
Point Register Pair HL to 6C00H, the sector buffer: 53H and 255 bytes of 00H.
631B
LD (HL),A2H 36 A2
Store A2H at Register Pair HL (6C00H): byte 0 of the hash index table, the hash of the name BOOT/SYS for directory record 0.
631D
INC HL 23
INCrement Register Pair HL to 6C01H, byte 1 of the hash index table.
631E
LD (HL),C4H 36 C4
Store C4H at Register Pair HL (6C01H): byte 1 of the hash index table, the hash of the name DIR/SYS for directory record 1. Every other byte is 00H, a free record.
6320
DEC HL 2B
DECrement Register Pair HL back to 6C00H, the start of the buffer.
6321
LD D,(IY+09H) FD 56 09
Fetch +09H of the working drive code table at Index Register IY (650EH) into Register D: the directory cylinder.
6324
LD E,01H 1E 01
Load Register E with 01H, sector 1 of the directory cylinder: the hash index table.
6326
If the Z FLAG is set (all went well), GOSUB to 6420H, the driver's function 0EH, Write Sector with the deleted data mark: Register Pair HL (6C00H) to cylinder Register D, sector Register E (1).
6329
If the Z FLAG is set (written), GOSUB to 6438H to verify that the sector carries the deleted data mark.
632C
If the NZ FLAG is set (a write or a verify since 6305H failed), JUMP to 6448H to give back the interrupt vector and report the error in Register A.
632F
LD A,2BH 3E 2B
Load Register A with 2BH, a plus sign, the progress mark of a sector of the directory cylinder.
6331
GOSUB to 0033H, the ROM's routine that displays the character in Register A (+).
6334
LD DE,6C00H 11 00 6C
Point Register Pair DE to 6C00H, the sector buffer, the destination of the copy below.
6337
LD HL,64C5H 21 C5 64
Point Register Pair HL to 64C5H, the record of BOOT/SYS, the source.
633A
LD BC,0020H 01 20 00
Load Register Pair BC with 0020H, the 32 bytes of a directory record.
633D
LDIR ED B0
Copy the 32 bytes from Register Pair HL (64C5H) to Register Pair DE (6C00H-6C1FH), Register Pair BC the count (LDIR): record 0 of the sector. The other 224 bytes of the buffer are 00H.
633F
LD D,(IY+09H) FD 56 09
Fetch +09H of the working drive code table at Index Register IY (650EH) into Register D: the directory cylinder.
6342
LD E,02H 1E 02
Load Register E with 02H, sector 2 of the directory cylinder: the first sector of directory records.
6344
LD HL,6C00H 21 00 6C
Point Register Pair HL to 6C00H, the sector buffer with the record of BOOT/SYS.
6347
GOSUB to 6420H, the driver's function 0EH, Write Sector with the deleted data mark: Register Pair HL (6C00H) to cylinder Register D, sector Register E (2).
634A
If the Z FLAG is set (written), GOSUB to 6438H to verify that the sector carries the deleted data mark.
634D
If the NZ FLAG is set (the write or the verify failed), JUMP to 6448H to give back the interrupt vector and report the error in Register A.
6350
GOSUB to 63D0H to display a period: one directory record sector written.
6353
LD A,(6510H) 3A 10 65
Fetch the sectors on a cylinder from 6510H into Register A: the size of the directory, a whole cylinder.
6356
OR A B7
Set the flags from Register A (OR A): the Z FLAG is set for 0, a count of sectors that did not fit in one byte.
6357
If the Z FLAG is set (0), JUMP to 635DH to use 34.
6359
CP 22H FE 22
Compare Register A (the sectors on a cylinder) against 22H (34): the allocation table, the hash index table and the 32 sectors of 8 records whose 256 entries the hash index table can hold.
635B
If the CARRY FLAG is set (fewer than 34 sectors), JUMP to 635FH with Register A unchanged.
635D
LD A,22H 3E 22
Load Register A with 22H (34), the most sectors the directory uses.
635F
LD (64F9H),A 32 F9 64
Store Register A (the sectors of the directory) at 64F9H, +14H of the record of DIR/SYS: the low byte of its ending record number.
6362
LD A,00H 3E 00
Load Register A with the granules on a track less one: the operand 6363H, 00H in the file, stored by 62D0H from bits 7-5 of +08H.
6364
BIT 5,(IY+04H) FD CB 04 6E
Test bit 5 of +04H of the working drive code table at Index Register IY (6509H): set for a drive with two sides.
6368
If the Z FLAG is set (one side), JUMP to 636CH: Register A = the granules on the cylinder less one.
636A
ADD A,A 87
Double Register A (ADD A,A): twice the granules on a track less one.
636B
INC A 3C
INCrement Register A: twice the granules on a track, less one, the granules on a cylinder of two sides less one.
636C
LD (64FCH),A 32 FC 64
Store Register A (the granules on the cylinder less one; the first granule, bits 7-5, is 0) at 64FCH, +17H of the record of DIR/SYS: its first extent is the whole cylinder.
636F
LD A,(IY+09H) FD 7E 09
Fetch +09H of the working drive code table at Index Register IY (650EH) into Register A: the directory cylinder.
6372
LD (64FBH),A 32 FB 64
Store Register A (the directory cylinder) at 64FBH, +16H of the record of DIR/SYS: the cylinder of its first extent (625CH stored it too).
6375
LD HL,64E5H 21 E5 64
Point Register Pair HL to 64E5H, the record of DIR/SYS, the source of the copy below.
6378
LD DE,6C00H 11 00 6C
Point Register Pair DE to 6C00H, the sector buffer, the destination.
637B
LD BC,0020H 01 20 00
Load Register Pair BC with 0020H, the 32 bytes of a directory record.
637E
LDIR ED B0
Copy the 32 bytes from Register Pair HL (64E5H) to Register Pair DE (6C00H-6C1FH), Register Pair BC the count (LDIR): record 0 of the sector, over the record of BOOT/SYS.
6380
LD D,(IY+09H) FD 56 09
Fetch +09H of the working drive code table at Index Register IY (650EH) into Register D: the directory cylinder.
6383
LD E,03H 1E 03
Load Register E with 03H, sector 3 of the directory cylinder: the second sector of directory records.
6385
LD HL,6C00H 21 00 6C
Point Register Pair HL to 6C00H, the sector buffer with the record of DIR/SYS.
6388
GOSUB to 6420H, the driver's function 0EH, Write Sector with the deleted data mark: Register Pair HL (6C00H) to cylinder Register D, sector Register E (3).
638B
If the Z FLAG is set (written), GOSUB to 6438H to verify that the sector carries the deleted data mark.
638E
If the NZ FLAG is set (the write or the verify failed), JUMP to 6448H to give back the interrupt vector and report the error in Register A.
6391
GOSUB to 63D0H to display a period: two directory record sectors written.
6394
LD HL,6C00H 21 00 6C
Point Register Pair HL to 6C00H, the record of DIR/SYS in the buffer.
6397
LD B,20H 06 20
Load Register B with 20H (32), the bytes of the record to clear.
6399
LD (HL),00H 36 00
Store 00H at Register Pair HL, a byte of the record in the buffer.
639B
INC HL 23
INCrement Register Pair HL to the next byte of the record.
639C
DECrement Register B and LOOP BACK to 6399H until the 32 bytes are 00H: the whole buffer is now 256 bytes of 00H.
639E
LD D,(IY+09H) FD 56 09
Fetch +09H of the working drive code table at Index Register IY (650EH) into Register D: the directory cylinder.
63A1
LD E,04H 1E 04
Load Register E with 04H, the first sector of the directory cylinder without a record.
63A3
LD HL,6C00H 21 00 6C
Point Register Pair HL to 6C00H, the buffer of 256 bytes of 00H, an empty sector of directory records.
63A6
GOSUB to 6420H, the driver's function 0EH, Write Sector with the deleted data mark: Register Pair HL (6C00H) to cylinder Register D, sector Register E.
63A9
If the Z FLAG is set (written), GOSUB to 6438H to verify that the sector carries the deleted data mark.
63AC
If the NZ FLAG is set (the write or the verify failed), JUMP to 6448H to give back the interrupt vector and report the error in Register A.
63AF
PUSH DE D5
Save Register Pair DE (Register D = the directory cylinder, Register E = the sector) to the stack across the display.
63B0
GOSUB to 63D0H to display a period: one more directory sector written.
63B3
POP DE D1
Restore Register Pair DE from the stack: Register D = the directory cylinder, Register E = the sector.
63B4
INC E 1C
INCrement Register E to the next sector of the directory cylinder.
63B5
LD A,(6510H) 3A 10 65
Fetch the sectors on a cylinder from 6510H into Register A.
63B8
CP E BB
Compare Register A (the sectors on a cylinder) against Register E (the next sector).
63B9
If the NZ FLAG is set (sectors are left on the cylinder), LOOP BACK to 63A3H to write the next empty sector.

63BBH - The End: Formatting Complete

The interrupt vector is put back, the operator is asked for the system diskette when drive 0 was formatted, and the program returns to LDOS through @EXIT with Register Pair HL = 0000H.

63BB
GOSUB to 63E1H to put the byte back at 4012H, ask for the system diskette when drive 0 was formatted, and restore the head to cylinder 0.
63BE
LD HL,674CH 21 4C 67
Point Register Pair HL to 674CH, the text 0AH (a new line), Formatting complete and 0DH.
63C1
GOSUB to 428AH, @LOGOT, to display the text at Register Pair HL (674CH) and write it to the job log.
63C4
LD HL,6761H 21 61 67
Point Register Pair HL to 6761H, the text 0AH (a new line), Note: Realtime clock no longer accurate and 0DH: the clock did not count while the interrupt vector held RET (6010H).
63C7
GOSUB to 4467H, @DSPLY, to display the text at Register Pair HL (6761H).
63CA
LD HL,0000H 21 00 00
Load Register Pair HL with 0000H, the return code of a program that ended without an error.
63CD
JUMP to 402DH, @EXIT, to return to LDOS with Register Pair HL = 0000H.

63D0H - A Period, the Abort, and Putting Back the Interrupt Vector

63D0H displays a period. 63D5H displays Format aborted! (63D8H another text at Register Pair HL), writes it to the job log, puts back the interrupt vector and ends at @ABORT. 63E1H puts back the byte at 4012H that 600BH saved, asks for the system diskette when drive 0 was the target, and restores the head of the target drive to cylinder 0.

63D0
LD A,2EH 3E 2E
Load Register A with 2EH, a period, the progress mark of a sector written.
63D2
JUMP to 0033H, the ROM's routine that displays the character in Register A (a period); its RET goes back to the caller of 63D0H.
63D5
LD HL,678AH 21 8A 67
Point Register Pair HL to 678AH, the text Format aborted! ended by 0DH.
63D8
GOSUB to 428AH, @LOGOT, to display the text at Register Pair HL and write it to the job log.
63DB
GOSUB to 63E1H to put back the interrupt vector, ask for the system diskette when drive 0 was the target, and restore the head.
63DE
JUMP to 4030H, @ABORT: the program ends with an error.
63E1
LD A,00H 3E 00
Load Register A with the byte saved from 4012H: the operand 63E2H, 00H in the file, C3H after 600BH.
63E3
OR A B7
Set the flags from Register A (OR A): the Z FLAG is set when nothing was saved (the engine did not reach 600BH).
63E4
If the Z FLAG is set (nothing saved), JUMP to 63EAH.
63E6
EI FB
Enable interrupts: the clock interrupt is served again from here on.
63E7
LD (4012H),A 32 12 40
Store Register A (the saved byte, C3H) at 4012H: the interrupt vector jumps to the service routine again.
63EA
LD A,(642DH) 3A 2D 64
Fetch the target drive from 642DH into Register A: the operand of LD C,FFH at 642CH, FFH in the file until the front end stores the drive.
63ED
INC A 3C
INCrement Register A: the Z FLAG is set when the drive byte is still FFH.
63EE
RET Z C8
If the Z FLAG is set (no drive chosen yet), RETurn to the caller.
63EF
DEC A 3D
DECrement Register A back to the drive number: the Z FLAG is set for drive 0.
63F0
If the NZ FLAG is set (not drive 0), JUMP to 63FFH: the system diskette is still in drive 0.
63F2
LD HL,6726H 21 26 67
Point Register Pair HL to 6726H, the text 0AH (a new line), Load SYSTEM diskette and hit <ENTER> and 0DH.
63F5
GOSUB to 4467H, @DSPLY, to display the text at Register Pair HL (6726H).
63F8
GOSUB to 0049H, the ROM's routine that waits for a key and returns it in Register A.
63FB
CP 0DH FE 0D
Compare Register A (the key) against 0DH, ENTER.
63FD
If the NZ FLAG is set (not ENTER), LOOP BACK to 63F8H to wait for the next key.
63FF
JUMP to 6408H, the driver's function 04H, Restore: the head of the target drive goes back to cylinder 0, and its RET goes back to the caller of 63E1H.

6401H - Calls to the Drive's Driver

FORMAT calls the driver of the target drive itself, through the working drive code table at Index Register IY (6505H), whose first three bytes are the JP to the driver (C3H and the driver address) or, for a drive that is not present, RET (C9H). Each entry loads a function number into Register A and goes to 642AH, which puts the function into Register B and the drive into Register C, as the driver wants them (SYS0/SYS's floppy driver, 4583H). Register Pair BC is kept; Register D (the cylinder), Register E (the sector) and Register Pair HL (the buffer) go to the driver as they are. The driver returns the Z FLAG and Register A = 00H on success, else Register A = the error number.

6401
XOR A AF
Set Register A to 00H (XOR A), function 00H: SYS0/SYS's floppy driver returns at once with Register A = 00H and the Z FLAG. A drive that is not present returns NZ with Register A = 20H (642AH), so this is the test of whether the drive is there.
6402
JUMP to 642AH to call the driver with the function in Register A (00H).
6404
LD A,01H 3E 01
Load Register A with 01H, function 01H: select the drive and the side (bit 4 of +03H) through port F4H, waiting for the motor when it was off (45A6H).
6406
JUMP to 642AH to call the driver with the function in Register A (01H).
6408
LD A,04H 3E 04
Load Register A with 04H, function 04H, Restore: +05H of the table = 00H and the controller's command 09H (45A2H) moves the head to cylinder 0.
640A
JUMP to 642AH to call the driver with the function in Register A (04H).
640C
LD A,05H 3E 05
Load Register A with 05H, function 05H, Step In: +05H of the table goes up by 1 and the command 58H steps the head in one cylinder.
640E
JUMP to 642AH to call the driver with the function in Register A (05H).
6410
LD A,07H 3E 07
Load Register A with 07H, function 07H: wait until the controller is not busy, keeping the drive selected.
6412
JUMP to 642AH to call the driver with the function in Register A (07H).
6414
LD A,0FH 3E 0F
Load Register A with 0FH, function 0FH, Write Track: the command F0H (4644H) and the bytes from Register Pair HL, on the cylinder the head is on.
6416
JUMP to 642AH to call the driver with the function in Register A (0FH).
6418
LD A,0CH 3E 0C
Load Register A with 0CH, function 0CH (61D2H, for a drive with bit 4 of +04H set). SYS0/SYS's floppy driver takes 0CH as a Write Sector, like 0DH (463CH).
641A
JUMP to 642AH to call the driver with the function in Register A (0CH).
641C
LD A,0DH 3E 0D
Load Register A with 0DH, function 0DH, Write Sector: the command A2H (463AH), the 256 bytes at Register Pair HL to cylinder Register D, sector Register E.
641E
JUMP to 642AH to call the driver with the function in Register A (0DH).
6420
LD A,0EH 3E 0E
Load Register A with 0EH, function 0EH, Write Sector with the deleted data mark (the command A3H, 4640H): the mark of a directory sector.
6422
JUMP to 642AH to call the driver with the function in Register A (0EH).
6424
LD A,09H 3E 09
Load Register A with 09H, function 09H, Read Sector: the 256 bytes of cylinder Register D, sector Register E into the buffer at Register Pair HL. The front end reads the target diskette with it (7073H, 7092H).
6426
JUMP to 642AH to call the driver with the function in Register A (09H).
6428
LD A,0AH 3E 0A
Load Register A with 0AH, function 0AH, Verify: read the sector at cylinder Register D, sector Register E without storing its bytes, and give its error number.
642A
PUSH BC C5
Save Register Pair BC to the stack: the callers keep pointers in it.
642B
LD B,A 47
Copy Register A (the function) into Register B, where the driver takes it.
642C
LD C,FFH 0E FF
Load Register C with the target drive: the operand 642DH, FFH in the file, stored by the front end when the drive is known.
642E
LD A,20H 3E 20
Load Register A with 20H, error 20H, Illegal drive number: what Register A holds when the call returns from a table that starts with RET.
6430
OR A B7
Set the flags from Register A (OR A): the NZ FLAG, which the RET of a drive that is not present returns with.
6431
GOSUB to 6436H to jump into the working drive code table: the driver's RET comes back here.
6434
POP BC C1
Restore Register Pair BC from the stack, as the caller had it.
6435
RET C9
RETurn to the caller with the driver's result: the Z FLAG on success, else Register A = the error number.
6436
JP (IY) FD E9
JUMP to Index Register IY (6505H), the working drive code table: its JP goes to the drive's driver, its RET (C9H) back to 6434H.

6438H - Verify a Directory Sector, the Error Exits, Small Helpers

6438H reads back a sector written with the deleted data mark: the read gives error 06H for that mark, which here is success; a read without an error means the mark is missing. 6448H reports a disk error and ends the program; 6452H gives error 2CH. 6456H turns a number into two digits, 6463H and 646AH read a reply from the keyboard, 648AH writes two digits over the last two on the screen, 649CH and 64ABH put a track descriptor into effect.

6438
GOSUB to 6428H, the driver's function 0AH, Verify, for the sector just written at cylinder Register D, sector Register E.
643B
If the Z FLAG is set (no error: the sector has the normal data mark), JUMP to 6443H to give an error.
643D
SUB 06H D6 06
SUBtract 06H from Register A (the error number): 0 when the read found the deleted data mark (error 06H).
643F
RET Z C8
If the Z FLAG is set (error 06H), RETurn with the Z FLAG and Register A = 00H: the sector carries the deleted data mark.
6440
ADD A,06H C6 06
ADD 06H back to Register A: the driver's error number, with the NZ FLAG.
6442
RET C9
RETurn with the NZ FLAG and Register A = the driver's error number.
6443
OR 01H F6 01
OR 01H into Register A (00H): the NZ FLAG, a failure for the caller.
6445
LD A,00H 3E 00
Load Register A with 00H, error 0. LD does not change the flags.
6447
RET C9
RETurn with the NZ FLAG and Register A = 00H: the sector was read without the deleted data mark.
6448
PUSH AF F5
Save Register Pair AF (Register A = the error number) to the stack.
6449
GOSUB to 63E1H to put back the interrupt vector, ask for the system diskette when drive 0 was the target, and restore the head.
644C
POP AF F1
Restore Register Pair AF from the stack: Register A = the error number.
644D
OR 40H F6 40
Set bit 6 in Register A (OR 40H): the short message; bit 7 clear means @ERROR does not return.
644F
JUMP to 4409H, @ERROR, to display the message of the error in Register A and end the program at @ABORT.
6452
LD A,2CH 3E 2C
Load Register A with 2CH, the error Parameter error, for a drive or a parameter value the front end cannot use.
6454
JUMP to 644DH to set bit 6 of Register A (2CH) and give the error through @ERROR.
6456
LD C,30H 0E 30
Load Register C with 30H, the digit 0, the tens digit before counting.
6458
SUB 0AH D6 0A
SUBtract 0AH (10) from Register A, the number: the CARRY FLAG is set when Register A was below 10.
645A
If the CARRY FLAG is set (the tens are counted), JUMP to 645FH to make the units digit.
645C
INC C 0C
INCrement Register C, the tens digit: one more ten taken off.
645D
LOOP BACK to 6458H to take off another 10 from Register A.
645F
ADD A,3AH C6 3A
ADD 3AH to Register A (the units less 10): plus 10 back, plus 30H, the units digit 0-9.
6461
LD B,A 47
Copy Register A (the units digit) into Register B.
6462
RET C9
RETurn with Register C = the tens digit and Register B = the units digit.
6463
GOSUB to 4467H, @DSPLY, to display the question at Register Pair HL.
6466
LD B,03H 06 03
Load Register B with 03H, the most characters of the reply: a number of up to three digits or a letter.
6468
JUMP to 646CH to read the reply into the buffer at 6C00H.
646A
LD B,08H 06 08
Load Register B with 08H, the most characters of the reply: a diskette name or a password. The caller has displayed its question.
646C
LD HL,6C00H 21 00 6C
Point Register Pair HL to 6C00H, the buffer of the reply.
646F
GOSUB to 0040H, the ROM's line input: up to Register B characters into the buffer at Register Pair HL (6C00H), ended by 0DH; Register B comes back as the count typed, the CARRY FLAG set for BREAK.
6472
If the CARRY FLAG is set (BREAK), JUMP to 63D5H to display Format aborted! and end at @ABORT.
6475
LD A,B 78
Copy Register B (the count of characters typed) into Register A.
6476
OR A B7
Set the flags from Register A (OR A): the Z FLAG is set when only ENTER was pressed.
6477
RET Z C8
If the Z FLAG is set (no reply), RETurn with the Z FLAG and Register Pair HL = 6C00H: the caller takes its default.
6478
PUSH AF F5
Save Register Pair AF (the NZ FLAG) to the stack.
6479
PUSH BC C5
Save Register Pair BC (Register B = the count) to the stack.
647A
PUSH HL E5
Save Register Pair HL (6C00H, the reply) to the stack.
647B
LD A,(HL) 7E
Fetch the next character of the reply at Register Pair HL into Register A.
647C
CP 61H FE 61
Compare Register A (the character) against 61H, the letter a.
647E
If the CARRY FLAG is set (below 61H), JUMP to 6483H: the character stays as it is.
6480
SUB 20H D6 20
SUBtract 20H from Register A: a lower case letter becomes upper case (every character from 61H up is changed).
6482
LD (HL),A 77
Store Register A (the character) back into the buffer at Register Pair HL.
6483
INC HL 23
INCrement Register Pair HL to the next character of the reply.
6484
DECrement Register B (the characters left) and LOOP BACK to 647BH until it reaches 0.
6486
POP HL E1
Restore Register Pair HL from the stack: 6C00H, the reply.
6487
POP BC C1
Restore Register Pair BC from the stack: Register B = the count of characters.
6488
POP AF F1
Restore Register Pair AF from the stack: the NZ FLAG.
6489
RET C9
RETurn with the NZ FLAG, Register Pair HL = 6C00H (the reply in upper case) and Register B = its length.
648A
LD A,08H 3E 08
Load Register A with 08H, the backspace: the cursor goes back one place and the character there is erased.
648C
GOSUB to 0033H, the ROM's routine that displays the character in Register A (08H).
648F
LD A,08H 3E 08
Load Register A with 08H, the backspace, a second time.
6491
GOSUB to 0033H, the ROM's routine that displays the character in Register A (08H): the cursor is on the first of the last two characters.
6494
LD A,C 79
Copy Register C (the tens digit) into Register A.
6495
GOSUB to 0033H, the ROM's routine that displays the character in Register A (the tens digit).
6498
LD A,B 78
Copy Register B (the units digit) into Register A.
6499
JUMP to 0033H, the ROM's routine that displays the character in Register A (the units digit); its RET goes back to the caller of 648AH.
649C
LD A,(6F36H) 3A 36 6F
Load Register A with the default number of cylinders of the target drive: the operand 6F36H of LD A,00H at 6F35H, stored by the front end from the system information sector (6DB9H).
649F
BIT 5,(IY+03H) FD CB 03 6E
Test bit 5 of +03H of the working drive code table at Index Register IY (6508H): set for an 8 inch drive.
64A3
If the Z FLAG is set (a 5 inch drive), JUMP to 64A7H with the default number of cylinders in Register A.
64A5
LD A,4DH 3E 4D
Load Register A with 4DH (77), the cylinders of an 8 inch diskette.
64A7
DEC A 3D
DECrement Register A: the highest cylinder (cylinders are numbered from 0).
64A8
LD (IY+06H),A FD 77 06
Store Register A (the highest cylinder) into +06H of the working drive code table at Index Register IY (650BH).
64AB
LD E,(HL) 5E
Fetch the low byte of the template address, the first word of the descriptor at Register Pair HL, into Register E. No instruction of the Model III file calls this entry (the Model I file's second pass over cylinder 0 did); 649CH runs on into it.
64AC
INC HL 23
INCrement Register Pair HL to the high byte of the template address.
64AD
LD D,(HL) 56
Fetch the high byte at Register Pair HL into Register D: Register Pair DE = the template address.
64AE
INC HL 23
INCrement Register Pair HL to the second word of the descriptor.
64AF
LD (6014H),DE ED 53 14 60
Store Register Pair DE (the template address) at 6014H-6015H, the operand of LD DE,0000H at 6013H.
64B3
LD E,(HL) 5E
Fetch the low byte of the second word at Register Pair HL into Register E: the value for +07H.
64B4
INC HL 23
INCrement Register Pair HL to the high byte of the second word.
64B5
LD D,(HL) 56
Fetch the high byte at Register Pair HL into Register D: the value for +08H.
64B6
INC HL 23
INCrement Register Pair HL to the third word of the descriptor.
64B7
LD (IY+07H),E FD 73 07
Store Register E into +07H of the working drive code table at Index Register IY (650CH): the highest sector on a track (bits 4-0), one head (bits 7-5 = 0).
64BA
LD (IY+08H),D FD 72 08
Store Register D into +08H of the working drive code table at Index Register IY (650DH): the granules on a track less one (bits 7-5) and the sectors in a granule less one (bits 4-0).
64BD
LD E,(HL) 5E
Fetch the low byte of the third word at Register Pair HL into Register E.
64BE
INC HL 23
INCrement Register Pair HL to the high byte of the third word.
64BF
LD D,(HL) 56
Fetch the high byte at Register Pair HL into Register D: Register Pair DE = the memory the track takes above 6D00H.
64C0
LD (704EH),DE ED 53 4E 70
Store Register Pair DE (the memory size) at 704EH-704FH, the operand of LD DE,0000H at 704DH, where the front end checks it against HIGH$.
64C4
RET C9
RETurn to the caller with Register Pair HL past the descriptor.

64C5H - The Directory Records of BOOT/SYS and DIR/SYS

The two 32 byte directory records FORMAT writes: BOOT/SYS as record 0 (directory sector 2, 6334H-6350H) and DIR/SYS as record 1 (sector 3, 6375H-6391H). Their hash index table bytes are A2H and C4H (631BH-631EH). Before DIR/SYS is written, its ending record number (+14H) and its first extent (+16H-+17H) are filled in from the directory cylinder and the geometry (625CH, 635FH, 636CH, 6372H).

64C5
DEFB 5EH 5E
64C5H, BOOT/SYS +00H, the attribute: 5EH, bit 6 a system file, bit 4 in use, bit 3 invisible, bits 2-0 access level 6 (execute only without the password).
64C6
DEFB 00H 00
64C6H, BOOT/SYS +01H: 00H, no flags and no month (the record is not dated).
64C7
DEFB 00H 00
64C7H, BOOT/SYS +02H: 00H, the day and the year of the date, none.
64C8
DEFB 00H 00
64C8H, BOOT/SYS +03H: 00H, the end of file byte: the last sector is full.
64C9
DEFB 00H 00
64C9H, BOOT/SYS +04H: 00H, the record length: 256 bytes.
64CA-64D1
DEFM "BOOT " 42 4F 4F 54 20 20 20 20
64CAH-64D1H, BOOT/SYS +05H-+0CH: the name BOOT, padded with spaces to 8 bytes.
64D2-64D4
DEFM "SYS" 53 59 53
64D2H-64D4H, BOOT/SYS +0DH-+0FH: the extension SYS.
64D5-64D6
DEFW 01AEH AE 01
64D5H-64D6H, BOOT/SYS +10H-+11H: 01AEH, the hash of the file's password (4296H would be no password); SYS2/SYS's @OPEN compares it.
64D7-64D8
DEFW 0000H 00 00
64D7H-64D8H, BOOT/SYS +12H-+13H: 0000H, the time and the year of the date stamp, none.
64D9-64DA
DEFW 0005H 05 00
64D9H-64DAH, BOOT/SYS +14H-+15H: 0005H, the ending record number: 5 sectors, cylinder 0 sectors 0-4.
64DB
DEFB 00H 00
64DBH, BOOT/SYS +16H: 00H, the cylinder of the first extent: cylinder 0.
64DC
DEFB 00H 00
64DCH, BOOT/SYS +17H: 00H, the first extent's first granule (bits 7-5: granule 0) and its granules less one (bits 4-0: one granule).
64DD-64E2
DEFB FFH x 6 FF FF FF FF FF FF
64DDH-64E2H, BOOT/SYS +18H-+1DH: the three other extents, FFH (no extent).
64E3
DEFB FFH FF
64E3H, BOOT/SYS +1EH: FFH, no link to an extension record.
64E4
DEFB FFH FF
64E4H, BOOT/SYS +1FH: FFH, the number of an extension record, none.
64E5
DEFB 5DH 5D
64E5H, DIR/SYS +00H, the attribute: 5DH, bit 6 a system file, bit 4 in use, bit 3 invisible, bits 2-0 access level 5 (read only without the password).
64E6
DEFB 00H 00
64E6H, DIR/SYS +01H: 00H, no flags and no month.
64E7
DEFB 00H 00
64E7H, DIR/SYS +02H: 00H, the day and the year of the date, none.
64E8
DEFB 00H 00
64E8H, DIR/SYS +03H: 00H, the end of file byte: the last sector is full.
64E9
DEFB 00H 00
64E9H, DIR/SYS +04H: 00H, the record length: 256 bytes.
64EA-64F1
DEFM "DIR " 44 49 52 20 20 20 20 20
64EAH-64F1H, DIR/SYS +05H-+0CH: the name DIR, padded with spaces to 8 bytes.
64F2-64F4
DEFM "SYS" 53 59 53
64F2H-64F4H, DIR/SYS +0DH-+0FH: the extension SYS.
64F5-64F6
DEFW 01AEH AE 01
64F5H-64F6H, DIR/SYS +10H-+11H: 01AEH, the hash of the file's password, the same as BOOT/SYS.
64F7-64F8
DEFW 4296H 96 42
64F7H-64F8H, DIR/SYS +12H-+13H: 4296H, the hash of eight spaces. DATECONV/CMD treats a record with 4296H here as one without a date stamp.
64F9-64FA
DEFW 000AH 0A 00
64F9H-64FAH, DIR/SYS +14H-+15H: the ending record number, 000AH in the file; 635FH stores the sectors of the directory cylinder (at most 34) in the low byte.
64FB
DEFB 11H 11
64FBH, DIR/SYS +16H: the cylinder of the first extent, 11H (17) in the file; 625CH and 6372H store the directory cylinder.
64FC
DEFB 01H 01
64FCH, DIR/SYS +17H: the first extent's first granule (bits 7-5) and granules less one (bits 4-0), 01H in the file; 636CH stores granule 0 and the granules of the cylinder less one.
64FD-6502
DEFB FFH x 6 FF FF FF FF FF FF
64FDH-6502H, DIR/SYS +18H-+1DH: the three other extents, FFH (no extent).
6503
DEFB FFH FF
6503H, DIR/SYS +1EH: FFH, no link to an extension record.
6504
DEFB FFH FF
6504H, DIR/SYS +1FH: FFH, the number of an extension record, none.

6505H - The Working Drive Code Table and the Counts

6505H-650EH, not in the file, is the working copy of the target drive's drive code table (Index Register IY all through the engine); 650FH the bootstrap step rate; 6510H-6511H, not in the file, the sectors on a cylinder and on a track of the format.

6505-650E
DEFS 10
6505H-650EH: not in the file. The working copy of the target drive's drive code table: the front end copies the drive's table here (6DC1H) and changes it for the format chosen; the engine reaches the driver through it (6436H).
650F
DEFB 00H 00
650FH: the bootstrap step rate, 0-3: 00H in the file, the value the front end chooses stored by 6FBEH; 6268H and 6295H put it into bits 1-0 of the Seek command of the two boot sectors.
6510-6511
DEFS 2
6510H-6511H: not in the file. 6510H the sectors on a cylinder (6023H, 61EFH), 6511H the sectors on a track (6018H).

6512H - The Four Track Descriptors

Six bytes each: the address of the template, the values for +07H and +08H of the drive code table, and the bytes of memory the track takes above 6D00H. The front end picks the pair for the drive's size (6512H for 5 inch, 651EH for 8 inch), the first of a pair for single density and the second for double density; 649CH or 64ABH put it into effect.

6512-6517
DEFW 652AH, 2409H, 0D35H 2A 65 09 24 35 0D
6512H-6517H: 5 inch single density. Template 652AH; +07H 09H (10 sectors on a track, one head), +08H 24H (2 granules on a track, 5 sectors to a granule); 0D35H (3381) bytes of memory, 20 more than the 3105 bytes of the track and the 256 bytes of FFH after it.
6518-651D
DEFW 656AH, 4511H, 196AH 6A 65 11 45 6A 19
6518H-651DH: 5 inch double density. Template 656AH; +07H 11H (18 sectors on a track), +08H 45H (3 granules on a track, 6 sectors to a granule); 196AH (6506) bytes of memory, 84 fewer than the 6334 bytes of the track and the 256 bytes of FFH after it (19BEH) that 6013H writes.
651E-6523
DEFW 65C4H, 270FH, 1558H C4 65 0F 27 58 15
651EH-6523H: 8 inch single density. Template 65C4H; +07H 0FH (16 sectors on a track), +08H 27H (2 granules on a track, 8 sectors to a granule); 1558H (5464) bytes of memory, 32 more than the 5176 bytes of the track and the 256 bytes of FFH.
6524-6529
DEFW 6609H, 491DH, 29B1H 09 66 1D 49 B1 29
6524H-6529H: 8 inch double density. Template 6609H; +07H 1DH (30 sectors on a track), +08H 49H (3 granules on a track, 10 sectors to a granule); 29B1H (10673) bytes of memory, 60 more than the 10357 bytes of the track and the 256 bytes of FFH.

652AH - Template: 5 Inch, Single Density

10 sectors of 256 bytes, skew 7. The order of the sectors on the track, then the stream that 6013H expands: a gap of FFH bytes, then for each sector 6 bytes of 00H, the ID address mark FEH, the cylinder, side and sector (filled in by 60B2H), the size 01H (256 bytes), F7H (the controller writes the two CRC bytes), a gap, 6 bytes of 00H, the data address mark FBH, 256 bytes of E5H, F7H and a gap; then FFH to the end of the track. The track is 3105 bytes.

652A
DEFB 0AH 0A
652AH, template +00H: 0AH, 10 sectors on a track (6016H).
652B
DEFB 07H 07
652BH, template +01H: 07H, the skew: each cylinder starts the order of the sectors 7 places further on (6026H).
652C-6535
DEFB 00H, 05H, 01H, 06H, 02H, 07H, 03H, 08H, 04H, 09H 00 05 01 06 02 07 03 08 04 09
652CH-6535H: the order of the sectors on the track, with an interleave of 2: each sector number lies two places after the one before.
6536-653D
DEFB F6H x 8 F6 F6 F6 F6 F6 F6 F6 F6
6536H-653DH: F6H (minus 10) eight times, the skew plus 1: a pointer that runs past the last sector number moves back 10 places (60C2H-60CBH).
653E-653F
DEFB 0EH, FFH 0E FF
653EH-653FH: 14 bytes of FFH, the gap at the start of the track after the index pulse.
6540
DEFB F1H F1
6540H: F1H, the start of the part built once for each of the 10 sectors.
6541-6542
DEFB 06H, 00H 06 00
6541H-6542H: 6 bytes of 00H before the ID field.
6543-6544
DEFB 01H, FEH 01 FE
6543H-6544H: 1 byte FEH, the ID address mark.
6545
DEFB F3H F3
6545H: F3H, the address of the next byte of the track goes into the table at 6C00H: the ID field's cylinder byte.
6546-6547
DEFB 03H, 00H 03 00
6546H-6547H: 3 bytes of 00H, the cylinder, side and sector of the ID field, filled in for each cylinder by 60B2H-60CDH.
6548-6549
DEFB 01H, 01H 01 01
6548H-6549H: 1 byte 01H, the size code of the ID field: 256 bytes.
654A-654B
DEFB 01H, F7H 01 F7
654AH-654BH: 1 byte F7H: the controller writes the two CRC bytes of the ID field.
654C-654D
DEFB 01H, FFH 01 FF
654CH-654DH: 1 byte FFH, the start of the gap after the ID field.
654E-654F
DEFB 0BH, FFH 0B FF
654EH-654FH: 11 bytes of FFH, the rest of the gap after the ID field.
6550-6551
DEFB 06H, 00H 06 00
6550H-6551H: 6 bytes of 00H before the data field.
6552-6553
DEFB 01H, FBH 01 FB
6552H-6553H: 1 byte FBH, the data address mark.
6554-6555
DEFB 00H, E5H 00 E5
6554H-6555H: 256 bytes of E5H (a count of 00H), the data of the sector.
6556-6557
DEFB 01H, F7H 01 F7
6556H-6557H: 1 byte F7H: the controller writes the two CRC bytes of the data field.
6558-6559
DEFB 01H, FFH 01 FF
6558H-6559H: 1 byte FFH, the start of the gap after the data field.
655A-655B
DEFB 0DH, FFH 0D FF
655AH-655BH: 13 bytes of FFH, the rest of the gap after the data field.
655C
DEFB F2H F2
655CH: F2H, the end of the part built for each sector.
655D-655E
DEFB 47H, FFH 47 FF
655DH-655EH: 71 bytes of FFH, the gap at the end of the track.
655F
DEFB F4H F4
655FH: F4H, the end of the template; 6085H finishes the track there.
6560-6569
DEFB 00H, 01H, 02H, 03H, 04H, 05H, 06H, 07H, 08H, 09H 00 01 02 03 04 05 06 07 08 09
6560H-6569H: the sectors in the order the verify pass reads them (6155H): every second sector around the track, positions 0, 2, 4 and so on, then 1, 3, 5 and so on, so each read has the time of one sector before the next.

656AH - Template: 5 Inch, Double Density

18 sectors of 256 bytes, skew 13. The stream: a gap of 4EH bytes, then for each sector 12 bytes of 00H, three F5H (the controller writes the sync byte A1H), the ID address mark FEH, the cylinder, side and sector, the size 01H, F7H (the two CRC bytes), a gap of 4EH, 12 bytes of 00H, three F5H, the data address mark FBH, 128 pairs 6DH B6H as the data, F7H and a gap; then 4EH to the end of the track. The track is 6334 bytes.

656A
DEFB 12H 12
656AH, template +00H: 12H, 18 sectors on a track (6016H).
656B
DEFB 0DH 0D
656BH, template +01H: 0DH, the skew: each cylinder starts the order of the sectors 13 places further on (6026H).
656C-657D
DEFB 00H, 06H, 0CH, 01H, 07H, 0DH, 02H, 08H, 0EH, 03H, 09H, 0FH, 04H, 0AH, 10H, 05H, 0BH, 11H 00 06 0C 01 07 0D 02 08 0E 03 09 0F 04 0A 10 05 0B 11
656CH-657DH: the order of the 18 sectors on the track (an interleave of 3).
657E-658B
DEFB EEH x 14 EE EE EE EE EE EE EE EE EE EE EE EE EE EE
657EH-658BH: EEH (minus 18) fourteen times, the skew plus 1: a pointer that runs past the last sector number moves back 18 places (60C2H-60CBH).
658C-658D
DEFB 20H, 4EH 20 4E
658CH-658DH: 32 bytes of 4EH, the gap at the start of the track.
658E
DEFB F1H F1
658EH: F1H, the start of the part built once for each of the 18 sectors.
658F-6590
DEFB 0CH, 00H 0C 00
658FH-6590H: 12 bytes of 00H before the ID field.
6591-6592
DEFB 03H, F5H 03 F5
6591H-6592H: 3 bytes F5H: the controller writes the sync byte A1H with a missing clock bit before the address mark.
6593-6594
DEFB 01H, FEH 01 FE
6593H-6594H: 1 byte FEH, the ID address mark.
6595
DEFB F3H F3
6595H: F3H, the address of the next byte of the track goes into the table at 6C00H: the ID field's cylinder byte.
6596-6597
DEFB 03H, 00H 03 00
6596H-6597H: 3 bytes of 00H, the cylinder, side and sector of the ID field, filled in for each cylinder by 60B2H-60CDH.
6598-6599
DEFB 01H, 01H 01 01
6598H-6599H: 1 byte 01H, the size code of the ID field: 256 bytes.
659A-659B
DEFB 01H, F7H 01 F7
659AH-659BH: 1 byte F7H: the controller writes the two CRC bytes of the ID field.
659C-659D
DEFB 16H, 4EH 16 4E
659CH-659DH: 22 bytes of 4EH, the gap after the ID field.
659E-659F
DEFB 0CH, 00H 0C 00
659EH-659FH: 12 bytes of 00H before the data field.
65A0-65A1
DEFB 03H, F5H 03 F5
65A0H-65A1H: 3 bytes F5H, the sync bytes A1H before the data address mark.
65A2-65A3
DEFB 01H, FBH 01 FB
65A2H-65A3H: 1 byte FBH, the data address mark.
65A4-65A7
DEFB F5H, 80H, 6DH, B6H F5 80 6D B6
65A4H-65A7H: F5H: the pair after the count is put that many times, 80H (128) pairs 6DH B6H, the 256 bytes of the sector's data.
65A8-65A9
DEFB 01H, F7H 01 F7
65A8H-65A9H: 1 byte F7H: the controller writes the two CRC bytes of the data field.
65AA-65AB
DEFB 01H, 4EH 01 4E
65AAH-65ABH: 1 byte 4EH, the start of the gap after the data field.
65AC-65AD
DEFB 17H, 4EH 17 4E
65ACH-65ADH: 23 bytes of 4EH, the rest of the gap after the data field.
65AE
DEFB F2H F2
65AEH: F2H, the end of the part built for each sector.
65AF-65B0
DEFB B6H, 4EH B6 4E
65AFH-65B0H: 182 bytes of 4EH, the gap at the end of the track.
65B1
DEFB F4H F4
65B1H: F4H, the end of the template; 6085H finishes the track there.
65B2-65C3
DEFB 00H, 0CH, 07H, 02H, 0EH, 09H, 04H, 10H, 0BH, 06H, 01H, 0DH, 08H, 03H, 0FH, 0AH, 05H, 11H 00 0C 07 02 0E 09 04 10 0B 06 01 0D 08 03 0F 0A 05 11
65B2H-65C3H: the sectors in the order the verify pass reads them (6155H): every second sector around the track, positions 0, 2, 4 and so on, then 1, 3, 5 and so on, so each read has the time of one sector before the next.

65C4H - Template: 8 Inch, Single Density

16 sectors of 256 bytes, skew 2. The same fields as the 5 inch single density template (652AH) with longer gaps. The track is 5176 bytes.

65C4
DEFB 10H 10
65C4H, template +00H: 10H, 16 sectors on a track (6016H).
65C5
DEFB 02H 02
65C5H, template +01H: 02H, the skew: each cylinder starts the order of the sectors 2 places further on (6026H).
65C6-65D5
DEFB 0AH, 05H, 00H, 0BH, 06H, 01H, 0CH, 07H, 02H, 0DH, 08H, 03H, 0EH, 09H, 04H, 0FH 0A 05 00 0B 06 01 0C 07 02 0D 08 03 0E 09 04 0F
65C6H-65D5H: the order of the 16 sectors on the track (an interleave of 3).
65D6-65D8
DEFB F0H x 3 F0 F0 F0
65D6H-65D8H: F0H (minus 16) three times, the skew plus 1: a pointer that runs past the last sector number moves back 16 places (60C2H-60CBH).
65D9-65DA
DEFB 28H, FFH 28 FF
65D9H-65DAH: 40 bytes of FFH, the gap at the start of the track.
65DB
DEFB F1H F1
65DBH: F1H, the start of the part built once for each of the 16 sectors.
65DC-65DD
DEFB 06H, 00H 06 00
65DCH-65DDH: 6 bytes of 00H before the ID field.
65DE-65DF
DEFB 01H, FEH 01 FE
65DEH-65DFH: 1 byte FEH, the ID address mark.
65E0
DEFB F3H F3
65E0H: F3H, the address of the next byte of the track goes into the table at 6C00H: the ID field's cylinder byte.
65E1-65E2
DEFB 03H, 00H 03 00
65E1H-65E2H: 3 bytes of 00H, the cylinder, side and sector of the ID field, filled in for each cylinder by 60B2H-60CDH.
65E3-65E4
DEFB 01H, 01H 01 01
65E3H-65E4H: 1 byte 01H, the size code of the ID field: 256 bytes.
65E5-65E6
DEFB 01H, F7H 01 F7
65E5H-65E6H: 1 byte F7H: the controller writes the two CRC bytes of the ID field.
65E7-65E8
DEFB 0BH, FFH 0B FF
65E7H-65E8H: 11 bytes of FFH, the gap after the ID field.
65E9-65EA
DEFB 06H, 00H 06 00
65E9H-65EAH: 6 bytes of 00H before the data field.
65EB-65EC
DEFB 01H, FBH 01 FB
65EBH-65ECH: 1 byte FBH, the data address mark.
65ED-65EE
DEFB 00H, E5H 00 E5
65EDH-65EEH: 256 bytes of E5H (a count of 00H), the data of the sector.
65EF-65F0
DEFB 01H, F7H 01 F7
65EFH-65F0H: 1 byte F7H: the controller writes the two CRC bytes of the data field.
65F1-65F2
DEFB 01H, FFH 01 FF
65F1H-65F2H: 1 byte FFH, the start of the gap after the data field.
65F3-65F4
DEFB 14H, FFH 14 FF
65F3H-65F4H: 20 bytes of FFH, the rest of the gap after the data field.
65F5
DEFB F2H F2
65F5H: F2H, the end of the part built for each sector.
65F6-65F7
DEFB D0H, FFH D0 FF
65F6H-65F7H: 208 bytes of FFH, the gap at the end of the track.
65F8
DEFB F4H F4
65F8H: F4H, the end of the template; 6085H finishes the track there.
65F9-6608
DEFB 0AH, 00H, 06H, 0CH, 02H, 08H, 0EH, 04H, 05H, 0BH, 01H, 07H, 0DH, 03H, 09H, 0FH 0A 00 06 0C 02 08 0E 04 05 0B 01 07 0D 03 09 0F
65F9H-6608H: the sectors in the order the verify pass reads them (6155H): every second sector around the track, positions 0, 2, 4 and so on, then 1, 3, 5 and so on, so each read has the time of one sector before the next.

6609H - Template: 8 Inch, Double Density

30 sectors of 256 bytes, skew 3. The same fields as the 5 inch double density template (656AH) with other gaps. The track is 10357 bytes.

6609
DEFB 1EH 1E
6609H, template +00H: 1EH, 30 sectors on a track (6016H).
660A
DEFB 03H 03
660AH, template +01H: 03H, the skew: each cylinder starts the order of the sectors 3 places further on (6026H).
660B-6628
DEFB 00H, 06H, 0CH, 12H, 18H, 01H, 07H, 0DH, 13H, 19H, 02H, 08H, 0EH, 14H, 1AH, 03H, 09H, 0FH, 15H, 1BH, 04H, 0AH, 10H, 16H, 1CH, 05H, 0BH, 11H, 17H, 1DH 00 06 0C 12 18 01 07 0D 13 19 02 08 0E 14 1A 03 09 0F 15 1B 04 0A 10 16 1C 05 0B 11 17 1D
660BH-6628H: the order of the 30 sectors on the track (an interleave of 5).
6629-662C
DEFB E2H x 4 E2 E2 E2 E2
6629H-662CH: E2H (minus 30) four times, the skew plus 1: a pointer that runs past the last sector number moves back 30 places (60C2H-60CBH).
662D-662E
DEFB 14H, 4EH 14 4E
662DH-662EH: 20 bytes of 4EH, the gap at the start of the track.
662F
DEFB F1H F1
662FH: F1H, the start of the part built once for each of the 30 sectors.
6630-6631
DEFB 0CH, 00H 0C 00
6630H-6631H: 12 bytes of 00H before the ID field.
6632-6633
DEFB 03H, F5H 03 F5
6632H-6633H: 3 bytes F5H: the controller writes the sync byte A1H with a missing clock bit before the address mark.
6634-6635
DEFB 01H, FEH 01 FE
6634H-6635H: 1 byte FEH, the ID address mark.
6636
DEFB F3H F3
6636H: F3H, the address of the next byte of the track goes into the table at 6C00H: the ID field's cylinder byte.
6637-6638
DEFB 03H, 00H 03 00
6637H-6638H: 3 bytes of 00H, the cylinder, side and sector of the ID field, filled in for each cylinder by 60B2H-60CDH.
6639-663A
DEFB 01H, 01H 01 01
6639H-663AH: 1 byte 01H, the size code of the ID field: 256 bytes.
663B-663C
DEFB 01H, F7H 01 F7
663BH-663CH: 1 byte F7H: the controller writes the two CRC bytes of the ID field.
663D-663E
DEFB 16H, 4EH 16 4E
663DH-663EH: 22 bytes of 4EH, the gap after the ID field.
663F-6640
DEFB 0CH, 00H 0C 00
663FH-6640H: 12 bytes of 00H before the data field.
6641-6642
DEFB 03H, F5H 03 F5
6641H-6642H: 3 bytes F5H, the sync bytes A1H before the data address mark.
6643-6644
DEFB 01H, FBH 01 FB
6643H-6644H: 1 byte FBH, the data address mark.
6645-6648
DEFB F5H, 80H, 6DH, B6H F5 80 6D B6
6645H-6648H: F5H: the pair after the count is put that many times, 80H (128) pairs 6DH B6H, the 256 bytes of the sector's data.
6649-664A
DEFB 01H, F7H 01 F7
6649H-664AH: 1 byte F7H: the controller writes the two CRC bytes of the data field.
664B-664C
DEFB 01H, FFH 01 FF
664BH-664CH: 1 byte FFH after the data field's CRC (the other templates of double density put 4EH here).
664D-664E
DEFB 11H, 4EH 11 4E
664DH-664EH: 17 bytes of 4EH, the gap after the data field.
664F
DEFB F2H F2
664FH: F2H, the end of the part built for each sector.
6650-6651
DEFB 00H, 4EH 00 4E
6650H-6651H: 256 bytes of 4EH (a count of 00H), the first part of the gap at the end of the track.
6652-6653
DEFB 3DH, 4EH 3D 4E
6652H-6653H: 61 bytes of 4EH, the rest of the gap at the end of the track.
6654
DEFB F4H F4
6654H: F4H, the end of the template; 6085H finishes the track there.
6655-6672
DEFB 00H, 0CH, 18H, 07H, 13H, 02H, 0EH, 1AH, 09H, 15H, 04H, 10H, 1CH, 0BH, 17H, 06H, 12H, 01H, 0DH, 19H, 08H, 14H, 03H, 0FH, 1BH, 0AH, 16H, 05H, 11H, 1DH 00 0C 18 07 13 02 0E 1A 09 15 04 10 1C 0B 17 06 12 01 0D 19 08 14 03 0F 1B 0A 16 05 11 1D
6655H-6672H: the sectors in the order the verify pass reads them (6155H): every second sector around the track, positions 0, 2, 4 and so on, then 1, 3, 5 and so on, so each read has the time of one sector before the next.

6673H - The Engine's Texts (1)

The texts of the format, the verify and the directory. 03H ends a text with the cursor left at its end, 0DH ends the line, 0AH starts a new line, 1DH moves the cursor to the start of its line.

6673
DEFB 1DH 1D
6673H: 1DH, the cursor to the start of its line: the start of the text of 6095H.
6674-6689
DEFM "Formatting cylinder " 46 6F 72 6D 61 74 74 69 6E 67 20 63 79 6C 69 6E 64 65 72 20 20 20
6674H-6689H: Formatting cylinder and three spaces; 648AH writes the cylinder number over the last two.
668A
DEFB 03H 03
668AH: 03H, the end of the text: the cursor stays after the spaces.
668B
DEFB 1DH 1D
668BH: 1DH, the cursor to the start of its line: the start of the text of 6136H.
668C-66A1
DEFM "Verifying cylinder " 56 65 72 69 66 79 69 6E 67 20 20 63 79 6C 69 6E 64 65 72 20 20 20
668CH-66A1H: Verifying, two spaces, cylinder and three spaces, as long as the text above; 648AH writes the cylinder number over the last two.
66A2
DEFB 03H 03
66A2H: 03H, the end of the text: the cursor stays after the spaces.
66A3-66A6
DEFM "* " 2A 20 20 20
66A3H-66A6H: an asterisk and three spaces, displayed after the number of a cylinder that failed the verify (61A4H).
66A7
DEFB 03H 03
66A7H: 03H, the end of the text: the next cylinder number goes two places before its end.
66A8-66B4
DEFM "Formatting..." 46 6F 72 6D 61 74 74 69 6E 67 2E 2E 2E
66A8H-66B4H: Formatting..., displayed before the driver's function 0CH (61CCH).
66B5
DEFB 0DH 0D
66B5H: 0DH, the end of the line and of the text.
66B6-66DA
DEFM "No cylinders available for directory!" 4E 6F 20 63 79 6C 69 6E 64 65 72 73 20 61 76 61 69 6C 61 62 6C 65 20 66 6F 72 20 64 69 72 65 63 74 6F 72 79 21
66B6H-66DAH: the text 6235H points to when no cylinder can take the directory; the JP 63D5H after it displays Format aborted! instead.
66DB
DEFB 0DH 0D
66DBH: 0DH, the end of the line and of the text.
66DC-6700
DEFM "Directory will be placed on cylinder " 44 69 72 65 63 74 6F 72 79 20 77 69 6C 6C 20 62 65 20 70 6C 61 63 65 64 20 6F 6E 20 63 79 6C 69 6E 64 65 72 20
66DCH-6700H: Directory will be placed on cylinder and a space, displayed by 6246H.
6701-6702
DEFM "00" 30 30
6701H-6702H: two digits, 00 in the file: 6242H stores the directory cylinder here.
6703
DEFB 0DH 0D
6703H: 0DH, the end of the line and of the text.

6704H - The Engine's Texts (2)

The texts of the system information, of the end and of the errors, and 32 bytes of 00H that end the block. The Model I file has one more text before them, the line of its second pass over cylinder 0 in single density, which the Model III file does not make.

6704
DEFB 0AH 0A
6704H: 0AH, a new line: the start of the text of 624CH.
6705-6724
DEFM "Initializing SYSTEM information " 49 6E 69 74 69 61 6C 69 7A 69 6E 67 20 53 59 53 54 45 4D 20 69 6E 66 6F 72 6D 61 74 69 6F 6E 20
6705H-6724H: Initializing SYSTEM information and a space; the periods and plus signs of the sectors written follow on the line.
6725
DEFB 03H 03
6725H: 03H, the end of the text: the cursor stays at its end.
6726
DEFB 0AH 0A
6726H: 0AH, a new line: the start of the text of 63F2H.
6727-674A
DEFM "Load SYSTEM diskette and hit <ENTER>" 4C 6F 61 64 20 53 59 53 54 45 4D 20 64 69 73 6B 65 74 74 65 20 61 6E 64 20 68 69 74 20 3C 45 4E 54 45 52 3E
6727H-674AH: Load SYSTEM diskette and hit <ENTER>, displayed after a format of drive 0.
674B
DEFB 0DH 0D
674BH: 0DH, the end of the line and of the text.
674C
DEFB 0AH 0A
674CH: 0AH, a new line: the start of the text of 63BEH.
674D-675F
DEFM "Formatting complete" 46 6F 72 6D 61 74 74 69 6E 67 20 63 6F 6D 70 6C 65 74 65
674DH-675FH: Formatting complete, displayed and written to the job log by @LOGOT at the end.
6760
DEFB 0DH 0D
6760H: 0DH, the end of the line and of the text.
6761
DEFB 0AH 0A
6761H: 0AH, a new line: the start of the text of 63C4H.
6762-6788
DEFM "Note: Realtime clock no longer accurate" 4E 6F 74 65 3A 20 52 65 61 6C 74 69 6D 65 20 63 6C 6F 63 6B 20 6E 6F 20 6C 6F 6E 67 65 72 20 61 63 63 75 72 61 74 65
6762H-6788H: Note: Realtime clock no longer accurate, since the clock interrupt was shut out while the tracks were written.
6789
DEFB 0DH 0D
6789H: 0DH, the end of the line and of the text.
678A-6798
DEFM "Format aborted!" 46 6F 72 6D 61 74 20 61 62 6F 72 74 65 64 21
678AH-6798H: Format aborted!, the text of 63D5H, displayed and written to the job log.
6799
DEFB 0DH 0D
6799H: 0DH, the end of the line and of the text.
679A-67B7
DEFM "Can't, Diskette not formatted!" 43 61 6E 27 74 2C 20 44 69 73 6B 65 74 74 65 20 6E 6F 74 20 66 6F 72 6D 61 74 74 65 64 21
679AH-67B7H: the text of 627AH, for a diskette whose cylinder 0, sector 0 cannot be read when only the system information is to be written.
67B8
DEFB 0DH 0D
67B8H: 0DH, the end of the line and of the text.
67B9-67D8
DEFB 00H x 32 00 x 32
67B9H-67D8H: 32 bytes of 00H at the end of the block. No code addresses them.

67D9H - Memory Not in the File, the Boot Sector Pointers, the Allocation Table Image

67D9H-67FFH and 6804H-68FFH are not used. 6800H-6803H point to the Seek command byte of each boot sector image. 6900H-69FFH is the image of the allocation table, with the offsets of the sector: 6900H-69CAH is built at run time and not in the file; 69CBH-69FFH holds the fields after it.

67D9-67FF
DEFS 39
67D9H-67FFH: not in the file, and no code of FORMAT uses it.
6800-6801
DEFW 6A95H 95 6A
6800H-6801H: 6A95H, +95H of the image of boot sector 0, the operand of its Seek command LD A,18H (4395H when the sector runs), read by 626CH.
6802-6803
DEFW 6B95H 95 6B
6802H-6803H: 6B95H, +95H of the image of boot sector 1, the operand of its Seek command LD A,18H (4395H when the sector runs), read by 6299H.
6804-68FF
DEFS 252
6804H-68FFH: not in the file, and no code of FORMAT uses it.
6900-69CA
DEFS 203
6900H-69CAH: not in the file. The allocation table image, +00H-+CAH: 6900H-695FH one byte for each cylinder, a bit set for each granule not free (the front end fills it, 6FD8H; the verify sets FFH for a bad cylinder, 61AEH); 6960H-69BFH the lock out table (6191H copies the allocation bytes there); 69C0H-69CAH what memory holds.
69CB
DEFB 53H 53
69CBH, the allocation table +CBH: 53H, written to the diskette as it is.
69CC
DEFB 00H 00
69CCH, +CCH: the number of cylinders less 35, 00H in the file, stored by 62B8H.
69CD
DEFB 00H 00
69CDH, +CDH: the configuration byte, 00H in the file, stored by 62D6H (bit 7 and bit 3 always, bit 6 double density, bit 5 two sides, bit 4 (cylinder 0 single density) never set by this file, bits 2-0 the granules on a track less one).
69CE-69CF
DEFW 0000H 00 00
69CEH-69CFH, +CEH-+CFH: the hash of the master password, 0000H in the file, stored by the front end (6E71H).
69D0-69D7
DEFM " " 20 20 20 20 20 20 20 20
69D0H-69D7H, +D0H-+D7H: the diskette name, eight spaces in the file, stored by the front end (6DEFH, 6E19H).
69D8-69DF
DEFM "MM/DD/YY" 4D 4D 2F 44 44 2F 59 59
69D8H-69DFH, +D8H-+DFH: the date the diskette is formatted, MM/DD/YY in the file, stored by the front end (6E1EH).
69E0
DEFB 0DH 0D
69E0H, +E0H: 0DH, the AUTO command of the diskette: none.
69E1-69FF
DEFM " " 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
69E1H-69FFH, +E1H-+FFH: 31 spaces, the rest of the AUTO command field.

6A00H - Image of Boot Sector 0 (Runs at 4300H)

The 256 bytes 6A00H-6AFFH are the sector FORMAT writes to cylinder 0, sector 0 (6280H-6289H). They are the Model III boot sector, byte for byte the same as the image of boot sector 1 at 6B00H and as sector 1 of BOOT/SYS, but for +02H (6A02H: 11H in the file, the directory cylinder, stored by 6265H) and +95H (6A95H: the Seek command 18H, whose bits 1-0 6273H sets to the bootstrap step rate; BOOT/SYS of the system diskette has 14H and 1BH there). The Model III ROM boots from sector 1, so sector 0 is a copy that no reset runs. The rows show the code as it would run at 4300H: the addresses in the comments are run addresses, 4300H plus the offset in the image, and the branches are linked to the rows of this image.

6A00
NOP 00
No operation. Byte 00H of the boot sector; the ROM jumps to 4300H and execution simply passes on to the compare at 4301H.
6A01
CP 11H FE 11
Compare Register A with 11H, the operand byte at 4302H (6A02H in this image). The compare does nothing useful: its operand is the directory cylinder, 11H in the file, which FORMAT replaces with the directory cylinder of the new diskette (6265H), kept at byte 02H of the boot sector, where 4304H reads it and SYS0/SYS's start-up copies it into drive 0's drive code table (4709H).
6A03
DI F3
Disable the interrupts. The boot sector runs with them off from here to the jump into SYS0/SYS; the end of each read reaches it through the NMI, which DI does not mask.
6A04
LD A,(4302H) 3A 02 43
Load Register A with the directory cylinder from 4302H (6A02H in this image, stored by FORMAT at 6265H), the operand byte of the compare at 4301H.
6A07
LD D,A 57
Copy the directory cylinder from Register A into Register D, the cylinder the read at 4374H seeks to.
6A08
LD E,04H 1E 04
Load Register E with 04H: sector 4 of the directory cylinder holds the directory entry of SYS0/SYS in its first 32 bytes. Register Pair DE is now the directory cylinder, sector 4.
6A0A
Call 4374H to read cylinder Register D, sector Register E into the buffer at 5100H-51FFH, with up to five tries. Register A returns the status masked with 1CH and the Z FLAG is set when the read succeeded.
6A0D
If the NZ FLAG is set (all five tries of the read failed), jump to 4380H (6A80H in this image) to display Disk error and restart the computer.
6A0F
LD A,(5100H) 3A 00 51
Load Register A with the attribute byte of the directory entry at 5100H, byte 00H of the entry of SYS0/SYS.
6A12
AND 10H E6 10
Mask Register A with 10H to keep bit 4 of the attribute byte, the bit that marks a directory entry in use. The Z FLAG is set when the entry is free.
6A14
If the Z FLAG is set (the directory entry of SYS0/SYS is not in use, so this diskette has no system), jump to 4384H (6A84H in this image), inside the LD IX at 4383H, to display No system and restart the computer.
6A16
EXX D9
Exchange Register Pairs BC, DE and HL with the alternate set. From here the alternate Register Pair DE' holds the cylinder and sector of the next sector of SYS0/SYS and the alternate Register Pair HL' the pointer into the buffer at 5100H, which the byte fetch at 435DH uses.
6A17
LD HL,(5116H) 2A 16 51
Load Register Pair HL with the first extent of SYS0/SYS from 5116H-5117H, bytes 16H-17H of its directory entry: Register L the starting cylinder, Register H the starting granule in bits 7-5 and the granule count in bits 4-0.
6A1A
LD D,L 55
Copy the starting cylinder from Register L into Register D: Register D now names the first cylinder of SYS0/SYS.
6A1B
LD A,H 7C
Copy the granule byte from Register H into Register A, to take the starting granule out of its bits 7-5.
6A1C
RLCA 07
Rotate Register A left once. With the two rotates that follow, the starting granule in bits 7-5 moves into bits 2-0.
6A1D
RLCA 07
Rotate Register A left a second time, moving the starting granule one more place towards bits 2-0.
6A1E
RLCA 07
Rotate Register A left a third time: bits 7-5 of the granule byte are now in bits 2-0 of Register A.
6A1F
AND 07H E6 07
Mask Register A with 07H to keep only the starting granule (0, 1 or 2 on a cylinder of three granules).
6A21
LD H,A 67
Save the starting granule from Register A in Register H for the addition at 4323H.
6A22
RLCA 07
Rotate Register A left: the starting granule times 2 (bit 7 is 0, so nothing enters bit 0).
6A23
ADD A,H 84
Add Register H to Register A: the starting granule times 3.
6A24
RLCA 07
Rotate Register A left: the starting granule times 6, the first sector of the granule on its cylinder (six sectors a granule, sectors numbered from 0).
6A25
LD E,A 5F
Store the first sector of SYS0/SYS from Register A in Register E: Register Pair DE now holds the cylinder and sector where SYS0/SYS starts.
6A26
LD HL,51FFH 21 FF 51
Load Register Pair HL with 51FFH, the last byte of the buffer, so that the first call of the byte fetch at 435DH steps Register L to 00H and reads the first sector of SYS0/SYS before it takes a byte.
6A29
EXX D9
Exchange Register Pairs BC, DE and HL with the alternate set again, putting the cylinder and sector (now in Register Pair DE') and the buffer pointer (now in Register Pair HL') aside for the byte fetch.

6A2AH - Image of Boot Sector 0: Load SYS0/SYS Record by Record (Runs at 432AH)

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.

6A2A
Call 435DH to fetch the next byte of SYS0/SYS into Register A: the type byte of the next record.
6A2D
DEC A 3D
Decrement Register A, the record type. The Z FLAG is set when the type was 01H, a load block.
6A2E
If the NZ FLAG is set (the record is not a load block), jump to 433CH (6A3CH in this image) to test for the transfer record.
6A30
Call 434EH to fetch the length of the load block into Register B and its load address into Register Pair HL; Register B returns as the count of data bytes that follow.
6A33
Call 435DH to fetch the next data byte of the load block into Register A.
6A36
LD (HL),A 77
Store the data byte from Register A at the load address in Register Pair HL.
6A37
INC HL 23
Increment Register Pair HL to the next load address of the block.
6A38
Decrement Register B, the data bytes left in the load block, and loop back to 4333H (6A33H in this image) until it reaches zero.
6A3A
Jump back to 432AH (6A2AH in this image) to fetch the type byte of the next record.
6A3C
DEC A 3D
Decrement Register A again. The Z FLAG is set when the record type was 02H, the transfer record.
6A3D
If the Z FLAG is set (the record is the transfer record), jump to 434AH (6A4AH in this image) to take the transfer address and jump to it.
6A3F
Call 435DH to fetch the length byte of a record of another type into Register A.
6A42
LD B,A 47
Copy the length of the record from Register A into Register B, the count of bytes to pass over.
6A43
Call 435DH to fetch the next byte of the record into Register A. The byte is not used: the record is passed over byte by byte.
6A46
Decrement Register B, the bytes left in the record being passed over, and loop back to 4343H (6A43H in this image) until it reaches zero.
6A48
Jump back to 432AH (6A2AH in this image) to fetch the type byte of the next record.
6A4A
Call 434EH to fetch the transfer record: Register B its length and Register Pair HL the transfer address of SYS0/SYS (4E00H for the SYS0/SYS of LDOS 5.3.1).
6A4D
JP (HL) E9
Jump to the transfer address in Register Pair HL: SYS0/SYS takes over. The interrupts are still off and the NMI vector at 4049H still holds JP 43D3H.

6A4EH - Image of Boot Sector 0: Fetch a Record Length and Address (Runs at 434EH)

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.

6A4E
Call 435DH to fetch the length byte of the record into Register A.
6A51
LD B,A 47
Copy the length of the record from Register A into Register B: it counts the address bytes and the data bytes together.
6A52
Call 435DH to fetch the low byte of the load address or transfer address into Register A.
6A55
LD L,A 6F
Store the low byte of the address from Register A in Register L.
6A56
DEC B 05
Decrement Register B, the record length, for the low address byte just taken.
6A57
Call 435DH to fetch the high byte of the load address or transfer address into Register A.
6A5A
LD H,A 67
Store the high byte of the address from Register A in Register H: Register Pair HL now holds the address.
6A5B
DEC B 05
Decrement Register B for the high address byte: Register B now counts only the data bytes that follow.
6A5C
RET C9
Return to the caller with Register B holding the count of data bytes and Register Pair HL the address.

6A5DH - Image of Boot Sector 0: Fetch the Next Byte of SYS0/SYS (Runs at 435DH)

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.

6A5D
EXX D9
Exchange Register Pairs BC, DE and HL with the alternate set: Register Pair HL now holds the buffer pointer and Register Pair DE the cylinder and sector of the next sector, while the caller's Register B and Register Pair HL are kept aside.
6A5E
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 end of the buffer.
6A5F
If the NZ FLAG is set (the pointer is still inside the buffer), jump to 4370H (6A70H in this image) to take the byte at Register Pair HL.
6A61
PUSH HL E5
Save the buffer pointer in Register Pair HL (now 5100H) on the stack while the next sector is read.
6A62
Call 4374H to read cylinder Register D, sector Register E into the buffer at 5100H-51FFH, with up to five tries.
6A65
If the NZ FLAG is set (all five tries failed), jump to 4380H (6A80H in this image) to display Disk error and restart the computer. The pushed buffer pointer is left on the stack, which no longer matters.
6A67
POP HL E1
Restore the buffer pointer (5100H) from the stack into Register Pair HL.
6A68
INC E 1C
Increment Register E, the sector number, to the next sector of SYS0/SYS.
6A69
LD A,E 7B
Copy the sector number from Register E into Register A to test it against the end of the cylinder.
6A6A
SUB 12H D6 12
Subtract 12H (18, the sectors of a double density cylinder, numbered 00H-11H) from Register A. The Z FLAG is set when Register E has passed the last sector of the cylinder.
6A6C
If the NZ FLAG is set (the sector is still on this cylinder), jump to 4370H (6A70H in this image) to take the byte.
6A6E
LD E,A 5F
Store 00H from Register A (the result of the subtraction) into Register E: the next sector is sector 0 of the next cylinder.
6A6F
INC D 14
Increment Register D, the cylinder number, to the next cylinder.
6A70
LD A,(HL) 7E
Load Register A with the byte of SYS0/SYS at the buffer pointer in Register Pair HL.
6A71
EXX D9
Exchange Register Pairs BC, DE and HL with the alternate set again, giving the caller back its Register B and Register Pair HL and putting the reading position aside. Register A keeps the byte.
6A72
RET C9
Return to the caller with the byte of SYS0/SYS in Register A.
6A73
RST 00H C7
RST 00H, one byte that no code reaches: the RET at 4372H ends the byte fetch and the read routine starts at 4374H. Executed, it would restart the computer through 0000H.

6A74H - Image of Boot Sector 0: Read a Sector, Five Tries (Runs at 4374H)

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.

6A74
LD B,05H 06 05
Load Register B with 05H, the number of tries the read gets.
6A76
PUSH BC C5
Save Register B, the tries left, on the stack: the read at 438EH uses Register Pair BC for the port number and the byte count.
6A77
Call 438EH to seek cylinder Register D and read sector Register E into 5100H-51FFH. Register A returns the controller status.
6A7A
POP BC C1
Restore the tries left from the stack into Register Pair BC: Register B holds the count of tries left.
6A7B
AND 1CH E6 1C
Mask the controller status in Register A with 1CH: bit 4 RECORD NOT FOUND, bit 3 CRC ERROR and bit 2 LOST DATA. The Z FLAG is set when none of them is set.
6A7D
RET Z C8
If the Z FLAG is set (the sector was read without error), return to the caller.
6A7E
Decrement Register B, the tries left, and loop back to 4376H (6A76H in this image) to read the sector again until five tries have failed. After the last try the code falls into 4380H.

6A80H - Image of Boot Sector 0: Display Disk error or No system and Restart (Runs at 4380H)

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.

6A80
LD HL,43E6H 21 E6 43
Point Register Pair HL to 43E6H, the Disk error message.
6A83
LD IX,43F4H DD 21 F4 43
Load Index Register IX with 43F4H. Nothing uses Index Register IX afterwards: the instruction only lets the path from 4380H pass over the three bytes 21H F4H 43H at 4384H-4386H, which the jump from 4314H takes as LD HL,43F4H, pointing Register Pair HL to the No system message instead.
6A87
Call the ROM routine at 021BH to display the message at Register Pair HL until its 03H end byte: 17H turns the display to 32 characters a line, E8H is a space compression code for 40 spaces, then the text and, for Disk error, 1FH, which clears to the end of the screen.
6A8A
Call the ROM routine at 0040H to take a line from the keyboard: the computer waits until ENTER is pressed.
6A8D
RST 00H C7
RST 00H: restart the computer through 0000H, which tries the boot again.

6A8EH - Image of Boot Sector 0: Seek and Read One Sector (Runs at 438EH)

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.

6A8E
LD BC,81F4H 01 F4 81
Load Register Pair BC with 81F4H: Register B holds 81H, the drive select value (bit 0 drive 0, bit 7 double density), and Register C holds F4H, the drive select port.
6A91
OUT (C),B ED 41
Send 81H from Register B to port F4H in Register C: select drive 0 in double density, which also starts its motor.
6A93
DEC C 0D
Decrement Register C from F4H to F3H, the data register of the floppy disk controller.
6A94
LD A,18H 3E 18
Load Register A with 18H, the Seek command: bit 3 loads the head and bits 1-0 (00 in the file) give the stepping rate. FORMAT sets these two bits of 6A95H to the bootstrap step rate (6273H); SYS0/SYS's start-up copies them into drive 0's drive code table.
6A96
OUT (C),D ED 51
Send the cylinder number in Register D to port F3H in Register C, the data register, where the Seek command takes the cylinder to move to.
6A98
Call 43DFH to send the Seek command in Register A to the command port F0H and wait for its status to be valid.
6A9B
IN A,(F0H) DB F0
Read the controller status from port F0H into Register A.
6A9D
BIT 0,A CB 47
Test bit 0 of Register A, BUSY. The NZ FLAG is set while the seek is still going on.
6A9F
If the NZ FLAG is set (the controller is still busy with the seek), jump back to 439BH (6A9BH in this image) to read the status again.
6AA1
LD A,E 7B
Copy the sector number from Register E into Register A.
6AA2
OUT (F2H),A D3 F2
Send the sector number in Register A to port F2H, the sector register of the controller.
6AA4
LD A,81H 3E 81
Load Register A with 81H, the drive select value for drive 0 in double density.
6AA6
OUT (F4H),A D3 F4
Send 81H from Register A to port F4H, selecting drive 0 again to keep its motor running.
6AA8
LD HL,43D3H 21 D3 43
Point Register Pair HL to 43D3H, the end of read routine of this sector.
6AAB
LD (404AH),HL 22 4A 40
Store 43D3H from Register Pair HL at 404AH-404BH, the address bytes of the NMI vector at 4049H.
6AAE
LD A,C3H 3E C3
Load Register A with C3H, the opcode of JP, for the first byte of the NMI vector at 4049H.
6AB0
LD (4049H),A 32 49 40
Store C3H from Register A at 4049H: the NMI vector now holds JP 43D3H. The ROM's NMI handler at 0066H jumps to 4049H when no reset is pending, so the interrupt that ends the read lands at 43D3H.
6AB3
LD HL,5100H 21 00 51
Point Register Pair HL to 5100H, the buffer the sector is read into, for the INI instructions that follow.
6AB6
PUSH DE D5
Save Register Pair DE (cylinder and sector) on the stack: 43D3H takes it back after the NMI.
6AB7
LD DE,C102H 11 02 C1
Load Register Pair DE with C102H: Register D holds C1H, the drive select value with bit 6 (wait state generation) set, and Register E holds 02H, the DATA REQUEST bit of the status.
6ABA
LD A,80H 3E 80
Load Register A with 80H, the Read Sector command (one sector, no settling delay, no side compare).
6ABC
Call 43DFH to send the Read Sector command in Register A to port F0H and wait for its status to be valid. Register B returns 00H.
6ABF
LD A,C0H 3E C0
Load Register A with C0H for the NMI mask port.
6AC1
OUT (E4H),A D3 E4
Send C0H from Register A to port E4H, the NMI mask: bit 7 lets the controller's interrupt request at the end of the command raise the NMI, and bit 6 is set as well.
6AC3
IN A,(F0H) DB F0
Read the controller status from port F0H into Register A.
6AC5
AND E A3
Mask the status in Register A with Register E (02H), keeping only DATA REQUEST. The Z FLAG is set while the first byte is not ready.
6AC6
If the Z FLAG is set (the first byte of the sector has not arrived), jump back to 43C3H (6AC3H in this image) to read the status again.
6AC8
INI ED A2
Read the first data byte from port F3H in Register C into the buffer at Register Pair HL, increment Register Pair HL and decrement Register B from 00H to FFH, leaving 255 bytes to take.
6ACA
LD A,D 7A
Copy C1H from Register D into Register A: drive 0, double density, with wait state generation.
6ACB
OUT (F4H),A D3 F4
Send C1H from Register A to port F4H: with bit 6 set, the next read of the data port holds the CPU in wait states until the controller has the byte ready.
6ACD
INI ED A2
Read the next data byte from port F3H in Register C into the buffer at Register Pair HL, increment Register Pair HL and decrement Register B, the bytes left.
6ACF
If the NZ FLAG is set (Register B has not reached zero), jump back to 43CBH (6ACBH in this image) for the next byte. After 256 bytes the code falls through to 43D1H.
6AD1
Jump to 43D1H (6AD1H in this image) itself: wait here until the controller ends the command and its interrupt request raises the NMI, which goes through 0066H and 4049H to 43D3H.

6AD3H - Image of Boot Sector 0: End of Read (NMI) (Runs at 43D3H)

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.

6AD3
POP HL E1
Remove the return address of the NMI (43D1H, the wait loop) from the stack into Register Pair HL; the code does not go back there.
6AD4
POP DE D1
Restore Register Pair DE, the cylinder and sector pushed at 43B6H.
6AD5
XOR A AF
Set Register A to 00H (XOR A with itself) for the NMI mask port E4H.
6AD6
OUT (E4H),A D3 E4
Send 00H from Register A to port E4H, turning off every NMI source of the port.
6AD8
LD A,81H 3E 81
Load Register A with 81H, the drive select value for drive 0 in double density without wait states.
6ADA
OUT (F4H),A D3 F4
Send 81H from Register A to port F4H, turning off wait state generation while keeping drive 0 selected.
6ADC
IN A,(F0H) DB F0
Read the final status of the Read Sector command from port F0H into Register A.
6ADE
RET C9
Return to 437AH, the caller of the read, with the controller status in Register A.

6ADFH - Image of Boot Sector 0: Send a Command to the Controller (Runs at 43DFH)

Sends the command in Register A to port F0H, then waits a short time for the status to be valid. Register B returns 00H.

6ADF
OUT (F0H),A D3 F0
Send the command in Register A to port F0H, the command register of the floppy disk controller.
6AE1
LD B,0CH 06 0C
Load Register B with 0CH, the count of the short delay loop that lets the controller's status become valid after a command.
6AE3
Decrement Register B and loop to 43E3H (6AE3H in this image) itself until it reaches zero: 12 passes of the delay.
6AE5
RET C9
Return to the caller with Register B at 00H and the command running in the controller.

6AE6H - Image of Boot Sector 0: The Two Messages (Runs at 43E6H)

The texts 4387H displays through the ROM routine at 021BH, each ending in 03H.

6AE6-6AE7
DEFB 17H, E8H 17 E8
The start of the Disk error message: 17H turns the display to 32 characters a line and E8H is a space compression code that moves the cursor on by 40 spaces.
6AE8-6AF1
DEFM "Disk error" 44 69 73 6B 20 65 72 72 6F 72
The ten characters Disk error, displayed by 4387H when a sector cannot be read in five tries.
6AF2-6AF3
DEFB 1FH, 03H 1F 03
The end of the Disk error message: 1FH clears from the cursor to the end of the screen and 03H ends the text for the ROM routine at 021BH.
6AF4-6AF5
DEFB 17H, E8H 17 E8
The start of the No system message, at 43F4H, the operand of the LD IX at 4383H and of the LD HL read from 4384H: 17H selects 32 characters a line and E8H moves the cursor on by 40 spaces.
6AF6-6AFE
DEFM "No system" 4E 6F 20 73 79 73 74 65 6D
The nine characters No system, displayed when the directory entry of SYS0/SYS is not in use.
6AFF
DEFB 03H 03
The end byte of the No system message for the ROM routine at 021BH, and the last byte of the boot sector.

6B00H - Image of Boot Sector 1 (Runs at 4300H)

The 256 bytes 6B00H-6BFFH are the sector FORMAT writes to cylinder 0, sector 1 (62A1H-62ADH), the sector the Model III ROM reads into 4300H-43FFH at a reset and jumps to. It 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 until the transfer record sends it to SYS0/SYS. +02H (6B02H) gets the directory cylinder (6292H) and bits 1-0 of the Seek command at +95H (6B95H) the bootstrap step rate (62A0H). The rows show the code as it runs at 4300H: the addresses in the comments are run addresses, 4300H plus the offset in the image, and the branches are linked to the rows of this image.

6B00
NOP 00
No operation. Byte 00H of the boot sector; the ROM jumps to 4300H and execution simply passes on to the compare at 4301H.
6B01
CP 11H FE 11
Compare Register A with 11H, the operand byte at 4302H (6B02H in this image). The compare does nothing useful: its operand is the directory cylinder, 11H in the file, which FORMAT replaces with the directory cylinder of the new diskette (6292H), kept at byte 02H of the boot sector, where 4304H reads it and SYS0/SYS's start-up copies it into drive 0's drive code table (4709H).
6B03
DI F3
Disable the interrupts. The boot sector runs with them off from here to the jump into SYS0/SYS; the end of each read reaches it through the NMI, which DI does not mask.
6B04
LD A,(4302H) 3A 02 43
Load Register A with the directory cylinder from 4302H (6B02H in this image, stored by FORMAT at 6292H), the operand byte of the compare at 4301H.
6B07
LD D,A 57
Copy the directory cylinder from Register A into Register D, the cylinder the read at 4374H seeks to.
6B08
LD E,04H 1E 04
Load Register E with 04H: sector 4 of the directory cylinder holds the directory entry of SYS0/SYS in its first 32 bytes. Register Pair DE is now the directory cylinder, sector 4.
6B0A
Call 4374H to read cylinder Register D, sector Register E into the buffer at 5100H-51FFH, with up to five tries. Register A returns the status masked with 1CH and the Z FLAG is set when the read succeeded.
6B0D
If the NZ FLAG is set (all five tries of the read failed), jump to 4380H (6B80H in this image) to display Disk error and restart the computer.
6B0F
LD A,(5100H) 3A 00 51
Load Register A with the attribute byte of the directory entry at 5100H, byte 00H of the entry of SYS0/SYS.
6B12
AND 10H E6 10
Mask Register A with 10H to keep bit 4 of the attribute byte, the bit that marks a directory entry in use. The Z FLAG is set when the entry is free.
6B14
If the Z FLAG is set (the directory entry of SYS0/SYS is not in use, so this diskette has no system), jump to 4384H (6B84H in this image), inside the LD IX at 4383H, to display No system and restart the computer.
6B16
EXX D9
Exchange Register Pairs BC, DE and HL with the alternate set. From here the alternate Register Pair DE' holds the cylinder and sector of the next sector of SYS0/SYS and the alternate Register Pair HL' the pointer into the buffer at 5100H, which the byte fetch at 435DH uses.
6B17
LD HL,(5116H) 2A 16 51
Load Register Pair HL with the first extent of SYS0/SYS from 5116H-5117H, bytes 16H-17H of its directory entry: Register L the starting cylinder, Register H the starting granule in bits 7-5 and the granule count in bits 4-0.
6B1A
LD D,L 55
Copy the starting cylinder from Register L into Register D: Register D now names the first cylinder of SYS0/SYS.
6B1B
LD A,H 7C
Copy the granule byte from Register H into Register A, to take the starting granule out of its bits 7-5.
6B1C
RLCA 07
Rotate Register A left once. With the two rotates that follow, the starting granule in bits 7-5 moves into bits 2-0.
6B1D
RLCA 07
Rotate Register A left a second time, moving the starting granule one more place towards bits 2-0.
6B1E
RLCA 07
Rotate Register A left a third time: bits 7-5 of the granule byte are now in bits 2-0 of Register A.
6B1F
AND 07H E6 07
Mask Register A with 07H to keep only the starting granule (0, 1 or 2 on a cylinder of three granules).
6B21
LD H,A 67
Save the starting granule from Register A in Register H for the addition at 4323H.
6B22
RLCA 07
Rotate Register A left: the starting granule times 2 (bit 7 is 0, so nothing enters bit 0).
6B23
ADD A,H 84
Add Register H to Register A: the starting granule times 3.
6B24
RLCA 07
Rotate Register A left: the starting granule times 6, the first sector of the granule on its cylinder (six sectors a granule, sectors numbered from 0).
6B25
LD E,A 5F
Store the first sector of SYS0/SYS from Register A in Register E: Register Pair DE now holds the cylinder and sector where SYS0/SYS starts.
6B26
LD HL,51FFH 21 FF 51
Load Register Pair HL with 51FFH, the last byte of the buffer, so that the first call of the byte fetch at 435DH steps Register L to 00H and reads the first sector of SYS0/SYS before it takes a byte.
6B29
EXX D9
Exchange Register Pairs BC, DE and HL with the alternate set again, putting the cylinder and sector (now in Register Pair DE') and the buffer pointer (now in Register Pair HL') aside for the byte fetch.

6B2AH - Image of Boot Sector 1: Load SYS0/SYS Record by Record (Runs at 432AH)

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.

6B2A
Call 435DH to fetch the next byte of SYS0/SYS into Register A: the type byte of the next record.
6B2D
DEC A 3D
Decrement Register A, the record type. The Z FLAG is set when the type was 01H, a load block.
6B2E
If the NZ FLAG is set (the record is not a load block), jump to 433CH (6B3CH in this image) to test for the transfer record.
6B30
Call 434EH to fetch the length of the load block into Register B and its load address into Register Pair HL; Register B returns as the count of data bytes that follow.
6B33
Call 435DH to fetch the next data byte of the load block into Register A.
6B36
LD (HL),A 77
Store the data byte from Register A at the load address in Register Pair HL.
6B37
INC HL 23
Increment Register Pair HL to the next load address of the block.
6B38
Decrement Register B, the data bytes left in the load block, and loop back to 4333H (6B33H in this image) until it reaches zero.
6B3A
Jump back to 432AH (6B2AH in this image) to fetch the type byte of the next record.
6B3C
DEC A 3D
Decrement Register A again. The Z FLAG is set when the record type was 02H, the transfer record.
6B3D
If the Z FLAG is set (the record is the transfer record), jump to 434AH (6B4AH in this image) to take the transfer address and jump to it.
6B3F
Call 435DH to fetch the length byte of a record of another type into Register A.
6B42
LD B,A 47
Copy the length of the record from Register A into Register B, the count of bytes to pass over.
6B43
Call 435DH to fetch the next byte of the record into Register A. The byte is not used: the record is passed over byte by byte.
6B46
Decrement Register B, the bytes left in the record being passed over, and loop back to 4343H (6B43H in this image) until it reaches zero.
6B48
Jump back to 432AH (6B2AH in this image) to fetch the type byte of the next record.
6B4A
Call 434EH to fetch the transfer record: Register B its length and Register Pair HL the transfer address of SYS0/SYS (4E00H for the SYS0/SYS of LDOS 5.3.1).
6B4D
JP (HL) E9
Jump to the transfer address in Register Pair HL: SYS0/SYS takes over. The interrupts are still off and the NMI vector at 4049H still holds JP 43D3H.

6B4EH - Image of Boot Sector 1: Fetch a Record Length and Address (Runs at 434EH)

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.

6B4E
Call 435DH to fetch the length byte of the record into Register A.
6B51
LD B,A 47
Copy the length of the record from Register A into Register B: it counts the address bytes and the data bytes together.
6B52
Call 435DH to fetch the low byte of the load address or transfer address into Register A.
6B55
LD L,A 6F
Store the low byte of the address from Register A in Register L.
6B56
DEC B 05
Decrement Register B, the record length, for the low address byte just taken.
6B57
Call 435DH to fetch the high byte of the load address or transfer address into Register A.
6B5A
LD H,A 67
Store the high byte of the address from Register A in Register H: Register Pair HL now holds the address.
6B5B
DEC B 05
Decrement Register B for the high address byte: Register B now counts only the data bytes that follow.
6B5C
RET C9
Return to the caller with Register B holding the count of data bytes and Register Pair HL the address.

6B5DH - Image of Boot Sector 1: Fetch the Next Byte of SYS0/SYS (Runs at 435DH)

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.

6B5D
EXX D9
Exchange Register Pairs BC, DE and HL with the alternate set: Register Pair HL now holds the buffer pointer and Register Pair DE the cylinder and sector of the next sector, while the caller's Register B and Register Pair HL are kept aside.
6B5E
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 end of the buffer.
6B5F
If the NZ FLAG is set (the pointer is still inside the buffer), jump to 4370H (6B70H in this image) to take the byte at Register Pair HL.
6B61
PUSH HL E5
Save the buffer pointer in Register Pair HL (now 5100H) on the stack while the next sector is read.
6B62
Call 4374H to read cylinder Register D, sector Register E into the buffer at 5100H-51FFH, with up to five tries.
6B65
If the NZ FLAG is set (all five tries failed), jump to 4380H (6B80H in this image) to display Disk error and restart the computer. The pushed buffer pointer is left on the stack, which no longer matters.
6B67
POP HL E1
Restore the buffer pointer (5100H) from the stack into Register Pair HL.
6B68
INC E 1C
Increment Register E, the sector number, to the next sector of SYS0/SYS.
6B69
LD A,E 7B
Copy the sector number from Register E into Register A to test it against the end of the cylinder.
6B6A
SUB 12H D6 12
Subtract 12H (18, the sectors of a double density cylinder, numbered 00H-11H) from Register A. The Z FLAG is set when Register E has passed the last sector of the cylinder.
6B6C
If the NZ FLAG is set (the sector is still on this cylinder), jump to 4370H (6B70H in this image) to take the byte.
6B6E
LD E,A 5F
Store 00H from Register A (the result of the subtraction) into Register E: the next sector is sector 0 of the next cylinder.
6B6F
INC D 14
Increment Register D, the cylinder number, to the next cylinder.
6B70
LD A,(HL) 7E
Load Register A with the byte of SYS0/SYS at the buffer pointer in Register Pair HL.
6B71
EXX D9
Exchange Register Pairs BC, DE and HL with the alternate set again, giving the caller back its Register B and Register Pair HL and putting the reading position aside. Register A keeps the byte.
6B72
RET C9
Return to the caller with the byte of SYS0/SYS in Register A.
6B73
RST 00H C7
RST 00H, one byte that no code reaches: the RET at 4372H ends the byte fetch and the read routine starts at 4374H. Executed, it would restart the computer through 0000H.

6B74H - Image of Boot Sector 1: Read a Sector, Five Tries (Runs at 4374H)

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.

6B74
LD B,05H 06 05
Load Register B with 05H, the number of tries the read gets.
6B76
PUSH BC C5
Save Register B, the tries left, on the stack: the read at 438EH uses Register Pair BC for the port number and the byte count.
6B77
Call 438EH to seek cylinder Register D and read sector Register E into 5100H-51FFH. Register A returns the controller status.
6B7A
POP BC C1
Restore the tries left from the stack into Register Pair BC: Register B holds the count of tries left.
6B7B
AND 1CH E6 1C
Mask the controller status in Register A with 1CH: bit 4 RECORD NOT FOUND, bit 3 CRC ERROR and bit 2 LOST DATA. The Z FLAG is set when none of them is set.
6B7D
RET Z C8
If the Z FLAG is set (the sector was read without error), return to the caller.
6B7E
Decrement Register B, the tries left, and loop back to 4376H (6B76H in this image) to read the sector again until five tries have failed. After the last try the code falls into 4380H.

6B80H - Image of Boot Sector 1: Display Disk error or No system and Restart (Runs at 4380H)

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.

6B80
LD HL,43E6H 21 E6 43
Point Register Pair HL to 43E6H, the Disk error message.
6B83
LD IX,43F4H DD 21 F4 43
Load Index Register IX with 43F4H. Nothing uses Index Register IX afterwards: the instruction only lets the path from 4380H pass over the three bytes 21H F4H 43H at 4384H-4386H, which the jump from 4314H takes as LD HL,43F4H, pointing Register Pair HL to the No system message instead.
6B87
Call the ROM routine at 021BH to display the message at Register Pair HL until its 03H end byte: 17H turns the display to 32 characters a line, E8H is a space compression code for 40 spaces, then the text and, for Disk error, 1FH, which clears to the end of the screen.
6B8A
Call the ROM routine at 0040H to take a line from the keyboard: the computer waits until ENTER is pressed.
6B8D
RST 00H C7
RST 00H: restart the computer through 0000H, which tries the boot again.

6B8EH - Image of Boot Sector 1: Seek and Read One Sector (Runs at 438EH)

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.

6B8E
LD BC,81F4H 01 F4 81
Load Register Pair BC with 81F4H: Register B holds 81H, the drive select value (bit 0 drive 0, bit 7 double density), and Register C holds F4H, the drive select port.
6B91
OUT (C),B ED 41
Send 81H from Register B to port F4H in Register C: select drive 0 in double density, which also starts its motor.
6B93
DEC C 0D
Decrement Register C from F4H to F3H, the data register of the floppy disk controller.
6B94
LD A,18H 3E 18
Load Register A with 18H, the Seek command: bit 3 loads the head and bits 1-0 (00 in the file) give the stepping rate. FORMAT sets these two bits of 6B95H to the bootstrap step rate (62A0H); SYS0/SYS's start-up copies them into drive 0's drive code table.
6B96
OUT (C),D ED 51
Send the cylinder number in Register D to port F3H in Register C, the data register, where the Seek command takes the cylinder to move to.
6B98
Call 43DFH to send the Seek command in Register A to the command port F0H and wait for its status to be valid.
6B9B
IN A,(F0H) DB F0
Read the controller status from port F0H into Register A.
6B9D
BIT 0,A CB 47
Test bit 0 of Register A, BUSY. The NZ FLAG is set while the seek is still going on.
6B9F
If the NZ FLAG is set (the controller is still busy with the seek), jump back to 439BH (6B9BH in this image) to read the status again.
6BA1
LD A,E 7B
Copy the sector number from Register E into Register A.
6BA2
OUT (F2H),A D3 F2
Send the sector number in Register A to port F2H, the sector register of the controller.
6BA4
LD A,81H 3E 81
Load Register A with 81H, the drive select value for drive 0 in double density.
6BA6
OUT (F4H),A D3 F4
Send 81H from Register A to port F4H, selecting drive 0 again to keep its motor running.
6BA8
LD HL,43D3H 21 D3 43
Point Register Pair HL to 43D3H, the end of read routine of this sector.
6BAB
LD (404AH),HL 22 4A 40
Store 43D3H from Register Pair HL at 404AH-404BH, the address bytes of the NMI vector at 4049H.
6BAE
LD A,C3H 3E C3
Load Register A with C3H, the opcode of JP, for the first byte of the NMI vector at 4049H.
6BB0
LD (4049H),A 32 49 40
Store C3H from Register A at 4049H: the NMI vector now holds JP 43D3H. The ROM's NMI handler at 0066H jumps to 4049H when no reset is pending, so the interrupt that ends the read lands at 43D3H.
6BB3
LD HL,5100H 21 00 51
Point Register Pair HL to 5100H, the buffer the sector is read into, for the INI instructions that follow.
6BB6
PUSH DE D5
Save Register Pair DE (cylinder and sector) on the stack: 43D3H takes it back after the NMI.
6BB7
LD DE,C102H 11 02 C1
Load Register Pair DE with C102H: Register D holds C1H, the drive select value with bit 6 (wait state generation) set, and Register E holds 02H, the DATA REQUEST bit of the status.
6BBA
LD A,80H 3E 80
Load Register A with 80H, the Read Sector command (one sector, no settling delay, no side compare).
6BBC
Call 43DFH to send the Read Sector command in Register A to port F0H and wait for its status to be valid. Register B returns 00H.
6BBF
LD A,C0H 3E C0
Load Register A with C0H for the NMI mask port.
6BC1
OUT (E4H),A D3 E4
Send C0H from Register A to port E4H, the NMI mask: bit 7 lets the controller's interrupt request at the end of the command raise the NMI, and bit 6 is set as well.
6BC3
IN A,(F0H) DB F0
Read the controller status from port F0H into Register A.
6BC5
AND E A3
Mask the status in Register A with Register E (02H), keeping only DATA REQUEST. The Z FLAG is set while the first byte is not ready.
6BC6
If the Z FLAG is set (the first byte of the sector has not arrived), jump back to 43C3H (6BC3H in this image) to read the status again.
6BC8
INI ED A2
Read the first data byte from port F3H in Register C into the buffer at Register Pair HL, increment Register Pair HL and decrement Register B from 00H to FFH, leaving 255 bytes to take.
6BCA
LD A,D 7A
Copy C1H from Register D into Register A: drive 0, double density, with wait state generation.
6BCB
OUT (F4H),A D3 F4
Send C1H from Register A to port F4H: with bit 6 set, the next read of the data port holds the CPU in wait states until the controller has the byte ready.
6BCD
INI ED A2
Read the next data byte from port F3H in Register C into the buffer at Register Pair HL, increment Register Pair HL and decrement Register B, the bytes left.
6BCF
If the NZ FLAG is set (Register B has not reached zero), jump back to 43CBH (6BCBH in this image) for the next byte. After 256 bytes the code falls through to 43D1H.
6BD1
Jump to 43D1H (6BD1H in this image) itself: wait here until the controller ends the command and its interrupt request raises the NMI, which goes through 0066H and 4049H to 43D3H.

6BD3H - Image of Boot Sector 1: End of Read (NMI) (Runs at 43D3H)

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.

6BD3
POP HL E1
Remove the return address of the NMI (43D1H, the wait loop) from the stack into Register Pair HL; the code does not go back there.
6BD4
POP DE D1
Restore Register Pair DE, the cylinder and sector pushed at 43B6H.
6BD5
XOR A AF
Set Register A to 00H (XOR A with itself) for the NMI mask port E4H.
6BD6
OUT (E4H),A D3 E4
Send 00H from Register A to port E4H, turning off every NMI source of the port.
6BD8
LD A,81H 3E 81
Load Register A with 81H, the drive select value for drive 0 in double density without wait states.
6BDA
OUT (F4H),A D3 F4
Send 81H from Register A to port F4H, turning off wait state generation while keeping drive 0 selected.
6BDC
IN A,(F0H) DB F0
Read the final status of the Read Sector command from port F0H into Register A.
6BDE
RET C9
Return to 437AH, the caller of the read, with the controller status in Register A.

6BDFH - Image of Boot Sector 1: Send a Command to the Controller (Runs at 43DFH)

Sends the command in Register A to port F0H, then waits a short time for the status to be valid. Register B returns 00H.

6BDF
OUT (F0H),A D3 F0
Send the command in Register A to port F0H, the command register of the floppy disk controller.
6BE1
LD B,0CH 06 0C
Load Register B with 0CH, the count of the short delay loop that lets the controller's status become valid after a command.
6BE3
Decrement Register B and loop to 43E3H (6BE3H in this image) itself until it reaches zero: 12 passes of the delay.
6BE5
RET C9
Return to the caller with Register B at 00H and the command running in the controller.

6BE6H - Image of Boot Sector 1: The Two Messages (Runs at 43E6H)

The texts 4387H displays through the ROM routine at 021BH, each ending in 03H.

6BE6-6BE7
DEFB 17H, E8H 17 E8
The start of the Disk error message: 17H turns the display to 32 characters a line and E8H is a space compression code that moves the cursor on by 40 spaces.
6BE8-6BF1
DEFM "Disk error" 44 69 73 6B 20 65 72 72 6F 72
The ten characters Disk error, displayed by 4387H when a sector cannot be read in five tries.
6BF2-6BF3
DEFB 1FH, 03H 1F 03
The end of the Disk error message: 1FH clears from the cursor to the end of the screen and 03H ends the text for the ROM routine at 021BH.
6BF4-6BF5
DEFB 17H, E8H 17 E8
The start of the No system message, at 43F4H, the operand of the LD IX at 4383H and of the LD HL read from 4384H: 17H selects 32 characters a line and E8H moves the cursor on by 40 spaces.
6BF6-6BFE
DEFM "No system" 4E 6F 20 73 79 73 74 65 6D
The nine characters No system, displayed when the directory entry of SYS0/SYS is not in use.
6BFF
DEFB 03H 03
The end byte of the No system message for the ROM routine at 021BH, and the last byte of the boot sector.

6C00H - The Buffer at 6C00H (Not in the File)

256 bytes the program uses for three things in turn.

6C00-6CFF
DEFS 256
6C00H-6CFFH: not in the file. While a track is built, the address of each sector's ID field in the track (6039H, 607DH), ended by 0000H; the replies to the questions (646CH, 6D7AH); the sector read from the target diskette (706DH-70B9H); then the sectors FORMAT writes: the system information sector, the hash index table, the directory records and the empty directory sectors (62ECH-63B9H).

6D00H - The Front End: the Banner, the System Information Sector

The transfer address. LDOS runs FORMAT with Register Pair HL pointing to the command line after the program name. The front end, 6D00H-7162H, asks for or reads every choice, puts the target drive's drive code table into 6505H and goes to the engine (70E9H); the engine then builds its tracks over the front end from 6D00H up. First the banner, a request that loads SYS2/SYS, and the system information sector of drive 0 (cylinder 0, sector 2) into 4300H: from its block of drive code tables (always the second block, at 4370H: the Model I file takes the first block, 4320H, after a boot through a disk driver) the default bootstrap step rate (drive 0's +03H, bits 1-0) and each drive's highest cylinder (+06H) are taken.

6D00
PUSH HL E5
Save Register Pair HL (the pointer to the command line) to the stack, for 6D36H.
6D01
LD HL,7236H 21 36 72
Point Register Pair HL to 7236H, the banner: 1CH 1FH (the cursor to the top left, the screen cleared), the name and version of FORMAT, the copyright, ended by 0DH.
6D04
GOSUB to 4467H, @DSPLY, to display the text at Register Pair HL (7236H).
6D07
GOSUB to 7175H, the request 84H: SYS2/SYS is loaded into the overlay area (its entry does nothing for function 00H), so the request E4H at 711EH finds it there.
6D0A
LD DE,0002H 11 02 00
Load Register Pair DE with 0002H: Register D = cylinder 0, Register E = sector 2, the system information sector.
6D0D
LD C,D 4A
Copy Register D (00H) into Register C: drive 0, the system drive.
6D0E
LD HL,4300H 21 00 43
Point Register Pair HL to 4300H, the system's sector buffer.
6D11
GOSUB to 4777H, RDSECT, to read drive Register C (0), cylinder Register D (0), sector Register E (2) into the buffer at Register Pair HL (4300H). Register Pairs BC, DE and HL come back unchanged; the Z FLAG on success.
6D14
If the NZ FLAG is set (the read failed), JUMP to 6448H to report the error in Register A (no drive chosen yet, so 63E1H does nothing).
6D17
LD L,76H 2E 76
Load Register L with 76H: Register Pair HL = 4376H, +06H of drive 0's table in the second block of drive code tables at 4370H, the block the Model III system uses (SYS6/SYS's RESET and SYS7/SYS's DRIVE also read only this block).
6D19
PUSH HL E5
Save Register Pair HL (4376H, +06H of drive 0's table in the block) to the stack, to move it into Index Register IY.
6D1A
POP IY FD E1
Restore it into Index Register IY: Index Register IY = +06H of drive 0's table of the block.
6D1C
LD A,(IY-03H) FD 7E FD
Fetch the byte 3 below Index Register IY (IY-03H: 4373H, +03H of drive 0's table) into Register A: the flags with the bootstrap step rate in bits 1-0 (SYSTEM (BSTEP) sets it).
6D1F
AND 03H E6 03
Mask Register A to bits 1-0 (AND 03H): the bootstrap step rate, 0-3.
6D21
LD (6D6BH),A 32 6B 6D
Store Register A (the default step rate) at 6D6BH, the low byte of the STEP parameter (the operand of LD DE,FF00H at 6D6AH); STEP=n on the command line replaces it.
6D24
LD B,08H 06 08
Load Register B with 08H, one pass for each of the drives 0-7.
6D26
LD IX,716DH DD 21 6D 71
Point Index Register IX to 716DH, the eight bytes of the highest cylinder of each drive (not in the file).
6D2A
LD DE,000AH 11 0A 00
Load Register Pair DE with 000AH, the ten bytes from one drive's table to the next.
6D2D
LD A,(HL) 7E
Fetch +06H of the drive's table at Register Pair HL into Register A: its highest cylinder (SYSTEM (DRIVE=d,CYL=n) sets it).
6D2E
LD (IX+00H),A DD 77 00
Store Register A (the highest cylinder) at Index Register IX (IX+00H), the drive's byte of 716DH-7174H.
6D31
INC IX DD 23
INCrement Index Register IX to the next drive's byte.
6D33
ADD HL,DE 19
ADD Register Pair DE (000AH) to Register Pair HL: +06H of the next drive's table.
6D34
DECrement Register B (the drives left) and LOOP BACK to 6D2DH until all eight drives are done.

6D36H - The Drive and the Parameters

The command line may start with :d, the drive (0-7); then @PARAM reads the parameters (the table at 719DH), which store their values into the operands of the instructions that read them. Without :d the drive is asked for and the parameters on the line are not read. The values of SDEN, DDEN, SIDES, CYL and STEP are ORed together into 6EACH: not 0 when any of them was given, which means no question is asked.

6D36
POP HL E1
Restore Register Pair HL from the stack: the pointer to the command line.
6D37
LD A,(HL) 7E
Fetch the next character of the command line at Register Pair HL into Register A.
6D38
INC HL 23
INCrement Register Pair HL past the character.
6D39
CP 20H FE 20
Compare Register A (the character) against 20H, a space.
6D3B
If the Z FLAG is set (a space), LOOP BACK to 6D37H to skip it.
6D3D
CP 3AH FE 3A
Compare Register A (the first character after the spaces) against 3AH, the colon that starts a drive.
6D3F
If the NZ FLAG is set (no drive given), JUMP to 6D74H to ask for the drive. The rest of the line is not read.
6D41
LD A,(HL) 7E
Fetch the character after the colon at Register Pair HL into Register A.
6D42
SUB 30H D6 30
SUBtract 30H from Register A: the value of a digit (a character below 30H gives a borrow and a large value).
6D44
CP 08H FE 08
Compare Register A (the drive) against 08H: the CARRY FLAG for drives 0-7.
6D46
If the NO CARRY FLAG is set (not a digit 0-7), JUMP to 6452H to give error 2CH, Parameter error.
6D49
LD (642DH),A 32 2D 64
Store Register A (the drive) at 642DH, the operand of LD C,FFH at 642CH: the drive of every call to the driver.
6D4C
INC HL 23
INCrement Register Pair HL past the drive digit, to the parameters.
6D4D
LD DE,719DH 11 9D 71
Point Register Pair DE to 719DH, the table of the parameters.
6D50
GOSUB to 4454H, @PARAM, to read the parameters at Register Pair HL against the table at Register Pair DE (719DH): a parameter given alone stores FFFFH, a value stores the value, a quoted text stores the address of its first character. The Z FLAG on success.
6D53
If the NZ FLAG is set (an unknown parameter or a bad value), JUMP to 6452H to give error 2CH, Parameter error.
6D56
LD DE,0000H 11 00 00
Load Register Pair DE with the SDEN parameter: the operand 6D57H-6D58H, 0000H in the file, FFFFH when SDEN was given.
6D59
LD A,D 7A
Copy Register D (the high byte of SDEN) into Register A.
6D5A
OR E B3
OR Register E (the low byte of SDEN) into Register A.
6D5B
LD DE,0000H 11 00 00
Load Register Pair DE with the DDEN parameter: the operand 6D5CH-6D5DH, 0000H in the file, FFFFH when DDEN was given.
6D5E
OR D B2
OR Register D (the high byte of DDEN) into Register A.
6D5F
OR E B3
OR Register E (the low byte of DDEN) into Register A.
6D60
LD DE,0000H 11 00 00
Load Register Pair DE with the SIDES parameter: the operand 6D61H-6D62H, 0000H in the file, the value of SIDES=n.
6D63
OR D B2
OR Register D (the high byte of SIDES) into Register A.
6D64
OR E B3
OR Register E (the low byte of SIDES) into Register A.
6D65
LD DE,0000H 11 00 00
Load Register Pair DE with the CYL parameter: the operand 6D66H-6D67H, 0000H in the file, the value of CYL=n.
6D68
OR D B2
OR Register D (the high byte of CYL) into Register A.
6D69
OR E B3
OR Register E (the low byte of CYL) into Register A.
6D6A
LD DE,FF00H 11 00 FF
Load Register Pair DE with the STEP parameter: the operand 6D6BH-6D6CH, FF00H in the file with the default rate at 6D6BH (6D21H); STEP=n stores n, so the high byte 6D6CH becomes 00H.
6D6D
INC D 14
INCrement Register D (the high byte of STEP): 00H when STEP was not given (FFH), not 0 when it was.
6D6E
OR D B2
OR Register D into Register A: Register A is not 0 when any of SDEN, DDEN, SIDES, CYL or STEP was given.
6D6F
LD (6EACH),A 32 AC 6E
Store Register A at 6EACH, the operand of LD A,00H at 6EABH: not 0 means the format is taken from the parameters and no question is asked.
6D72
JUMP to 6D93H, past the question for the drive.
6D74
LD HL,72CAH 21 CA 72
Point Register Pair HL to 72CAH, the question Which drive is to be used ? ended by 03H.
6D77
GOSUB to 4467H, @DSPLY, to display the text at Register Pair HL (72CAH).
6D7A
LD HL,6C00H 21 00 6C
Point Register Pair HL to 6C00H, the buffer of the reply.
6D7D
LD B,01H 06 01
Load Register B with 01H, one character for the reply.
6D7F
GOSUB to 0040H, the ROM's line input: up to Register B (1) characters into the buffer at Register Pair HL (6C00H), ended by 0DH; the CARRY FLAG for BREAK.
6D82
If the CARRY FLAG is set (BREAK), JUMP to 63D5H to display Format aborted! and end at @ABORT.
6D85
LD A,(HL) 7E
Fetch the character typed at Register Pair HL (6C00H) into Register A (0DH when only ENTER was pressed).
6D86
SUB 30H D6 30
SUBtract 30H from Register A: the value of a digit.
6D88
If the CARRY FLAG is set (a character below 30H, such as 0DH), JUMP to 6D74H to ask again.
6D8B
CP 08H FE 08
Compare Register A (the drive) against 08H: the CARRY FLAG for drives 0-7.
6D8D
If the NO CARRY FLAG is set (8 or more), JUMP to 6D74H to ask again.
6D90
LD (642DH),A 32 2D 64
Store Register A (the drive) at 642DH, the operand of LD C,FFH at 642CH: the drive of every call to the driver.

6D93H - NAME and MPW Follow QUERY, the Drive's Table

When NAME or MPW was not given, its operand gets the QUERY value: FFFFH (the default, or Q=Y) means ask, 0000H (Q=N) means take the default. The drive's default cylinders go to 6F36H; the drive's table is copied to the working table at 6505H, Index Register IY points to it, SYSTEM is refused for a drive that is not a hard disk (6DCDH-6DD7H), and the driver's function 00H tests that the drive is present.

6D93
LD DE,(6EB1H) ED 5B B1 6E
Fetch the QUERY parameter from 6EB1H-6EB2H (the operand of LD DE,FFFFH at 6EB0H) into Register Pair DE: FFFFH in the file, 0000H for Q=N.
6D97
LD HL,(6DE1H) 2A E1 6D
Fetch the NAME parameter from 6DE1H-6DE2H (the operand of LD HL,0000H at 6DE0H) into Register Pair HL.
6D9A
LD A,H 7C
Copy Register H (the high byte of NAME) into Register A.
6D9B
OR L B5
OR Register L (the low byte of NAME) into Register A: the Z FLAG when NAME was not given.
6D9C
If the NZ FLAG is set (NAME given), JUMP to 6DA2H.
6D9E
LD (6DE1H),DE ED 53 E1 6D
Store Register Pair DE (the QUERY value) at 6DE1H-6DE2H, the NAME parameter: FFFFH asks for the name, 0000H takes the default.
6DA2
LD HL,(6E24H) 2A 24 6E
Fetch the MPW parameter from 6E24H-6E25H (the operand of LD HL,0000H at 6E23H) into Register Pair HL.
6DA5
LD A,H 7C
Copy Register H (the high byte of MPW) into Register A.
6DA6
OR L B5
OR Register L (the low byte of MPW) into Register A: the Z FLAG when MPW was not given.
6DA7
If the NZ FLAG is set (MPW given), JUMP to 6DADH.
6DA9
LD (6E24H),DE ED 53 24 6E
Store Register Pair DE (the QUERY value) at 6E24H-6E25H, the MPW parameter.
6DAD
LD A,(642DH) 3A 2D 64
Fetch the target drive from 642DH into Register A.
6DB0
LD C,A 4F
Copy Register A (the drive) into Register C, for 47A5H below.
6DB1
LD HL,716DH 21 6D 71
Point Register Pair HL to 716DH, the highest cylinder of each drive (6D2DH).
6DB4
ADD A,L 85
ADD Register L (6DH) to Register A (the drive): the low byte of the drive's entry; the CARRY FLAG is the carry into the high byte.
6DB5
LD L,A 6F
Copy Register A (the low byte) into Register L.
6DB6
ADC A,H 8C
ADD Register H (71H) and the CARRY FLAG to Register A.
6DB7
SUB L 95
SUBtract Register L from Register A: Register A = Register H plus the carry.
6DB8
LD H,A 67
Copy Register A into Register H: Register Pair HL = 716DH + the drive.
6DB9
LD A,(HL) 7E
Fetch the drive's highest cylinder at Register Pair HL into Register A.
6DBA
INC A 3C
INCrement Register A: the default number of cylinders of the drive.
6DBB
LD (6F36H),A 32 36 6F
Store Register A (the default cylinders) at 6F36H, the operand of LD A,00H at 6F35H, which 649CH and the cylinder question use.
6DBE
GOSUB to 47A5H to point Register Pair HL to the drive code table of drive Register C (4700H + the drive x 10).
6DC1
LD DE,6505H 11 05 65
Point Register Pair DE to 6505H, the working drive code table.
6DC4
LD BC,000AH 01 0A 00
Load Register Pair BC with 000AH, the ten bytes of a drive code table.
6DC7
LDIR ED B0
Copy the drive's table from Register Pair HL to Register Pair DE (6505H), Register Pair BC the count (LDIR). FORMAT changes only this copy.
6DC9
LD IY,6505H FD 21 05 65
Point Index Register IY to 6505H, the working drive code table: every +nnH below is a byte of it, and 6436H calls the driver through it.
6DCD
LD A,(61C6H) 3A C6 61
Fetch the low byte of the SYSTEM parameter from 61C6H (the operand of LD HL,0000H at 61C5H) into Register A: FFH when SYSTEM was given, 00H when it was not.
6DD0
INC A 3C
INCrement Register A: the Z FLAG when it was FFH, SYSTEM given.
6DD1
If the NZ FLAG is set (no SYSTEM), JUMP to 6DDAH to test that the drive is present.
6DD3
BIT 3,(IY+03H) FD CB 03 5E
Test bit 3 of +03H of the working drive code table at Index Register IY (6508H): set for a hard disk, the only drive SYSTEM may be given for.
6DD7
If the Z FLAG is set (SYSTEM for a drive that is not a hard disk), JUMP to 712AH to display Can't "SYSTEM" a floppy! and end at @ABORT before anything is written.
6DDA
GOSUB to 6401H, the driver's function 00H: the Z FLAG for a drive that is present; Register A = 20H and the NZ FLAG when the table starts with RET.
6DDD
If the NZ FLAG is set (no drive), JUMP to 6448H to report error 20H, Illegal drive number, in Register A.

6DE0H - The Diskette Name, the Date, the Master Password

NAME: 0000H takes LDOSDISK (7536H), FFFFH asks (Diskette name ?), else the address of a text on the command line. The name goes into the allocation table image at 69D0H (+D0H) in upper case, the date of today at 69D8H (+D8H). MPW the same way: PASSWORD (753EH) or the question Master password ? or the text; it goes to 717BH, is checked (letters and digits, the first a letter) and its hash goes to 69CEH (+CEH).

6DE0
LD HL,0000H 21 00 00
Load Register Pair HL with the NAME parameter: the operand 6DE1H-6DE2H, 0000H in the file.
6DE3
LD A,H 7C
Copy Register H (the high byte of NAME) into Register A.
6DE4
OR L B5
OR Register L (the low byte of NAME) into Register A.
6DE5
INC A 3C
INCrement Register A: the Z FLAG when the OR of the two bytes was FFH (FFFFH: ask).
6DE6
If the Z FLAG is set (ask), JUMP to 6E0AH to ask for the name.
6DE8
DEC A 3D
DECrement Register A back to the OR of the two bytes: the Z FLAG for 0000H.
6DE9
If the NZ FLAG is set (the address of a text), JUMP to 6DEEH to copy the name from the command line at Register Pair HL.
6DEB
LD HL,7536H 21 36 75
Point Register Pair HL to 7536H, the default name LDOSDISK. 6E13H comes here when only ENTER is pressed.
6DEE
LD DE,69D0H 11 D0 69
Point Register Pair DE to 69D0H, +D0H of the allocation table image: the diskette name (eight spaces in the file).
6DF1
LD B,08H 06 08
Load Register B with 08H, the most characters of the name.
6DF3
LD A,(HL) 7E
Fetch the next character of the name at Register Pair HL into Register A.
6DF4
CP 22H FE 22
Compare Register A (the character) against 22H, the quote that ends a text on the command line.
6DF6
If the Z FLAG is set (the quote), JUMP to 6E1DH: the rest of the name stays spaces.
6DF8
CP 20H FE 20
Compare Register A (the character) against 20H, a space.
6DFA
If the CARRY FLAG is set (a control character such as 0DH ends the text), JUMP to 6E1DH.
6DFD
CP 61H FE 61
Compare Register A (the character) against 61H, the letter a.
6DFF
If the CARRY FLAG is set (below 61H), JUMP to 6E03H: the character is stored as it is.
6E01
XOR 20H EE 20
Exclusive OR 20H into Register A: a lower case letter becomes upper case.
6E03
LD (DE),A 12
Store Register A (the character) into the name at Register Pair DE.
6E04
INC HL 23
INCrement Register Pair HL to the next character of the text.
6E05
INC DE 13
INCrement Register Pair DE to the next byte of the name.
6E06
DECrement Register B (the characters left) and LOOP BACK to 6DF3H until eight are stored.
6E08
JUMP to 6E1DH to store the date in the allocation table image.
6E0A
LD HL,72E7H 21 E7 72
Point Register Pair HL to 72E7H, the question Diskette name ? ended by 03H.
6E0D
GOSUB to 4467H, @DSPLY, to display the text at Register Pair HL (72E7H).
6E10
GOSUB to 646AH to read up to 8 characters into 6C00H in upper case: Register Pair HL = 6C00H, Register B = the count, the Z FLAG when only ENTER was pressed.
6E13
If the Z FLAG is set (no reply), JUMP to 6DEBH to take the default name LDOSDISK.
6E15
LD C,B 48
Copy Register B (the characters typed) into Register C.
6E16
LD B,00H 06 00
Load Register B with 00H: Register Pair BC = the characters typed.
6E18
LD DE,69D0H 11 D0 69
Point Register Pair DE to 69D0H, the diskette name in the allocation table image.
6E1B
LDIR ED B0
Copy the reply from Register Pair HL (6C00H) to Register Pair DE (69D0H), Register Pair BC the count (LDIR); a name shorter than 8 keeps the spaces after it.
6E1D
LD HL,69D8H 21 D8 69
Point Register Pair HL to 69D8H, +D8H of the allocation table image: the date (MM/DD/YY in the file).
6E20
GOSUB to 3033H, @DATE, the ROM's date routine on the Model III (the Model I file calls the LDOS vector 4470H), to store the system date as MM/DD/YY (8 characters) at Register Pair HL (69D8H).
6E23
LD HL,0000H 21 00 00
Load Register Pair HL with the MPW parameter: the operand 6E24H-6E25H, 0000H in the file.
6E26
LD A,H 7C
Copy Register H (the high byte of MPW) into Register A.
6E27
OR L B5
OR Register L (the low byte of MPW) into Register A.
6E28
INC A 3C
INCrement Register A: the Z FLAG when the OR of the two bytes was FFH (FFFFH: ask).
6E29
If the Z FLAG is set (ask), JUMP to 6E48H to ask for the master password.
6E2B
DEC A 3D
DECrement Register A back to the OR of the two bytes: the Z FLAG for 0000H.
6E2C
If the NZ FLAG is set (the address of a text), JUMP to 6E31H to copy the password from the command line at Register Pair HL.
6E2E
LD HL,753EH 21 3E 75
Point Register Pair HL to 753EH, the default master password PASSWORD. 6E56H comes here when only ENTER is pressed.
6E31
LD DE,717BH 11 7B 71
Point Register Pair DE to 717BH, the buffer of the master password (spaces in the file).
6E34
LD B,08H 06 08
Load Register B with 08H, the most characters of the password.
6E36
LD A,(HL) 7E
Fetch the next character of the password at Register Pair HL into Register A.
6E37
CP 30H FE 30
Compare Register A (the character) against 30H, the digit 0.
6E39
If the CARRY FLAG is set (below 30H: a quote, a space or 0DH ends the text), JUMP to 6E6AH to check and hash the password.
6E3B
CP 61H FE 61
Compare Register A (the character) against 61H, the letter a.
6E3D
If the CARRY FLAG is set (below 61H), JUMP to 6E41H: the character is stored as it is.
6E3F
XOR 20H EE 20
Exclusive OR 20H into Register A: a lower case letter becomes upper case.
6E41
LD (DE),A 12
Store Register A (the character) into the buffer at Register Pair DE.
6E42
INC DE 13
INCrement Register Pair DE to the next byte of the buffer.
6E43
INC HL 23
INCrement Register Pair HL to the next character of the text.
6E44
DECrement Register B (the characters left) and LOOP BACK to 6E36H until eight are stored.
6E46
JUMP to 6E6AH to check and hash the password.
6E48
LD HL,72F8H 21 F8 72
Point Register Pair HL to 72F8H, the question Master password ? ended by 03H.
6E4B
GOSUB to 4467H, @DSPLY, to display the text at Register Pair HL (72F8H).
6E4E
LD HL,717BH 21 7B 71
Point Register Pair HL to 717BH, the buffer of the master password: the reply is read straight into it.
6E51
LD B,08H 06 08
Load Register B with 08H, the most characters of the reply.
6E53
GOSUB to 646FH, the line input of 6463H without its buffer: up to Register B (8) characters into Register Pair HL (717BH), in upper case. The ROM ends the reply with 0DH, at 7183H after 8 characters. Register A comes back as the count, the Z FLAG when only ENTER was pressed.
6E56
If the Z FLAG is set (no reply), JUMP to 6E2EH to take the default PASSWORD.
6E58
EX DE,HL EB
Exchange Register Pairs DE and HL: Register Pair DE = 717BH, the buffer.
6E59
ADD A,E 83
ADD Register E (7BH) to Register A (the characters typed): the low byte of the address after the reply.
6E5A
LD L,A 6F
Copy Register A (the low byte) into Register L.
6E5B
LD A,D 7A
Copy Register D (71H, the high byte of 717BH) into Register A.
6E5C
ADC A,00H CE 00
ADD 00H and the CARRY FLAG to Register A: the high byte.
6E5E
LD H,A 67
Copy Register A (the high byte) into Register H: Register Pair HL = the byte after the reply (its 0DH).
6E5F
LD A,08H 3E 08
Load Register A with 08H, the length of the password.
6E61
SUB B 90
SUBtract Register B (the characters typed) from Register A: the bytes left to fill.
6E62
If the Z FLAG is set (8 characters typed), JUMP to 6E6AH.
6E64
LD B,A 47
Copy Register A (the bytes left) into Register B.
6E65
LD (HL),20H 36 20
Store 20H, a space, at Register Pair HL: the 0DH and the bytes after the reply become spaces.
6E67
INC HL 23
INCrement Register Pair HL to the next byte of the buffer.
6E68
DECrement Register B (the bytes left) and LOOP BACK to 6E65H until the password is 8 bytes.
6E6A
LD DE,717BH 11 7B 71
Point Register Pair DE to 717BH, the master password of 8 characters.
6E6D
GOSUB to 70FFH to check the password at Register Pair DE and hash it: Register Pair HL = the hash. A password with other characters ends at 7133H.
6E70
LD (69CEH),HL 22 CE 69
Store Register Pair HL (the hash of the master password) at 69CEH-69CFH, +CEH-+CFH of the allocation table image.

6E73H - The Density

A drive with bit 4 of +04H set gets no questions (6FC1H). For the others the track descriptors of the drive's size are chosen (6512H for 5 inch, 651EH for 8 inch, bit 5 of +03H). The default is single density, or double density when the drive's controller can do it (bit 6 of +04H); one side; the default cylinders. Without any of SDEN, DDEN, SIDES, CYL or STEP, and with QUERY not 0000H, the questions are asked; with Q=N none is, and the defaults are used. The density question is asked only when the controller can do double density.

6E73
BIT 4,(IY+04H) FD CB 04 66
Test bit 4 of +04H of the working drive code table at Index Register IY (6509H): the drive FORMAT writes no tracks on.
6E77
If the NZ FLAG is set (bit 4 set), JUMP to 6FC1H: no question about the format; the drive's own +06H, +07H and +08H are kept, and the bootstrap step rate stays the 00H of 650FH.
6E7A
LD HL,6512H 21 12 65
Point Register Pair HL to 6512H, the first track descriptor (5 inch, single density).
6E7D
LD DE,0006H 11 06 00
Load Register Pair DE with 0006H, the length of a descriptor.
6E80
BIT 5,(IY+03H) FD CB 03 6E
Test bit 5 of +03H of the working drive code table at Index Register IY (6508H): set for an 8 inch drive.
6E84
If the Z FLAG is set (a 5 inch drive), JUMP to 6E88H with Register Pair HL = 6512H.
6E86
ADD HL,DE 19
ADD Register Pair DE (6) to Register Pair HL: 6518H.
6E87
ADD HL,DE 19
ADD Register Pair DE (6) to Register Pair HL again: 651EH, the 8 inch single density descriptor.
6E88
LD (6EEFH),HL 22 EF 6E
Store Register Pair HL (the single density descriptor of the drive's size) at 6EEFH-6EF0H, the operand of LD HL,0000H at 6EEEH.
6E8B
EX DE,HL EB
Exchange Register Pairs DE and HL: Register Pair HL = 0006H, Register Pair DE = the single density descriptor.
6E8C
ADD HL,DE 19
ADD Register Pair DE to Register Pair HL: the double density descriptor of the drive's size (6518H or 6524H).
6E8D
LD (6EDFH),HL 22 DF 6E
Store Register Pair HL (the double density descriptor) at 6EDFH-6EE0H, the operand of LD HL,0000H at 6EDEH.
6E90
EX DE,HL EB
Exchange Register Pairs DE and HL: Register Pair HL = the single density descriptor, Register Pair DE = the double density descriptor.
6E91
RES 6,(IY+03H) FD CB 03 B6
Reset bit 6 of +03H of the working drive code table at Index Register IY (6508H): single density.
6E95
BIT 6,(IY+04H) FD CB 04 76
Test bit 6 of +04H of the working drive code table at Index Register IY (6509H): set when the drive's controller can do double density.
6E99
If the Z FLAG is set (single density only), JUMP to 6EA0H with Register Pair HL = the single density descriptor.
6E9B
EX DE,HL EB
Exchange Register Pairs DE and HL: Register Pair HL = the double density descriptor.
6E9C
SET 6,(IY+03H) FD CB 03 F6
Set bit 6 of +03H of the working drive code table at Index Register IY (6508H): double density, the default with such a controller.
6EA0
GOSUB to 649CH to put the descriptor at Register Pair HL into effect: the default highest cylinder into +06H, the template, +07H, +08H and the memory size.
6EA3
RES 5,(IY+04H) FD CB 04 AE
Reset bit 5 of +04H of the working drive code table at Index Register IY (6509H): one side.
6EA7
RES 4,(IY+03H) FD CB 03 A6
Reset bit 4 of +03H of the working drive code table at Index Register IY (6508H): side 0.
6EAB
LD A,00H 3E 00
Load Register A with the value at 6EACH, 00H in the file: not 0 when SDEN, DDEN, SIDES, CYL or STEP was given (6D6FH).
6EAD
OR A B7
Set the flags from Register A (OR A): the Z FLAG when none of them was given.
6EAE
If the NZ FLAG is set (parameters given), JUMP to 6EB8H: the format comes from the parameters.
6EB0
LD DE,FFFFH 11 FF FF
Load Register Pair DE with the QUERY parameter: the operand 6EB1H-6EB2H, FFFFH in the file, 0000H for Q=N.
6EB3
LD A,D 7A
Copy Register D (the high byte of QUERY) into Register A.
6EB4
OR E B3
OR Register E (the low byte of QUERY) into Register A: the Z FLAG for Q=N.
6EB5
If the Z FLAG is set (Q=N), JUMP to 6FB6H: no question, the defaults are used.
6EB8
BIT 6,(IY+04H) FD CB 04 76
Test bit 6 of +04H of the working drive code table at Index Register IY (6509H): set when the controller can do double density. 6ED5H comes back here.
6EBC
If the Z FLAG is set (single density only), JUMP to 6EF8H: no density question.
6EBE
LD A,(6EACH) 3A AC 6E
Fetch the value at 6EACH (6D6FH) into Register A.
6EC1
OR A B7
Set the flags from Register A (OR A): the Z FLAG when no format parameter was given.
6EC2
If the NZ FLAG is set (parameters given), JUMP to 6ED7H to take the density from DDEN or SDEN.
6EC4
LD HL,73CDH 21 CD 73
Point Register Pair HL to 73CDH, the question Single or Double density <S,D> ? ended by 03H.
6EC7
GOSUB to 6463H to display the question at Register Pair HL and read up to 3 characters into 6C00H in upper case; the Z FLAG when only ENTER was pressed.
6ECA
If the Z FLAG is set (no reply), JUMP to 6EF8H: the default density stays.
6ECC
LD A,(HL) 7E
Fetch the first character of the reply at Register Pair HL (6C00H) into Register A.
6ECD
CP 53H FE 53
Compare Register A (the character) against 53H, S.
6ECF
If the Z FLAG is set (S), JUMP to 6EEEH for single density.
6ED1
CP 44H FE 44
Compare Register A (the character) against 44H, D.
6ED3
If the Z FLAG is set (D), JUMP to 6EDEH for double density.
6ED5
LOOP BACK to 6EB8H to ask again: the reply was neither S nor D.
6ED7
LD A,(6D5CH) 3A 5C 6D
Fetch the low byte of the DDEN parameter from 6D5CH into Register A: FFH when DDEN was given.
6EDA
XOR FFH EE FF
Exclusive OR FFH into Register A: the Z FLAG when DDEN was given.
6EDC
If the NZ FLAG is set (no DDEN), JUMP to 6EE7H to test SDEN.
6EDE
LD HL,0000H 21 00 00
Load Register Pair HL with the double density descriptor of the drive's size: the operand 6EDFH-6EE0H, 0000H in the file, stored by 6E8DH.
6EE1
SET 6,(IY+03H) FD CB 03 F6
Set bit 6 of +03H of the working drive code table at Index Register IY (6508H): double density.
6EE5
JUMP to 6EF5H to put the descriptor into effect.
6EE7
LD A,(6D57H) 3A 57 6D
Fetch the low byte of the SDEN parameter from 6D57H into Register A: FFH when SDEN was given.
6EEA
XOR FFH EE FF
Exclusive OR FFH into Register A: the Z FLAG when SDEN was given.
6EEC
If the NZ FLAG is set (neither DDEN nor SDEN), JUMP to 6EF8H: the default density stays.
6EEE
LD HL,0000H 21 00 00
Load Register Pair HL with the single density descriptor of the drive's size: the operand 6EEFH-6EF0H, 0000H in the file, stored by 6E88H.
6EF1
RES 6,(IY+03H) FD CB 03 B6
Reset bit 6 of +03H of the working drive code table at Index Register IY (6508H): single density.
6EF5
GOSUB to 649CH to put the descriptor at Register Pair HL into effect: the default highest cylinder into +06H, the template, +07H, +08H and the memory size.

6EF8H - The Sides and the Cylinders

SIDES=2 (or the reply 2) sets bit 5 of +04H. The number of cylinders is asked for (or taken from CYL=n) only for a 5 inch floppy (bits 5 and 3 of +03H clear); a reply of 0 or ENTER takes the default, and 96 or more is refused: the question is asked again, and CYL=n of 96 or more gives error 2CH.

6EF8
LD A,(6EACH) 3A AC 6E
Fetch the value at 6EACH (6D6FH) into Register A. 6F0DH comes back here.
6EFB
OR A B7
Set the flags from Register A (OR A): the Z FLAG when no format parameter was given.
6EFC
If the NZ FLAG is set (parameters given), JUMP to 6F11H to take the sides from SIDES.
6EFE
LD HL,73AEH 21 AE 73
Point Register Pair HL to 73AEH, the question Enter number of sides <1,2> ? ended by 03H.
6F01
GOSUB to 6463H to display the question at Register Pair HL and read up to 3 characters into 6C00H; the Z FLAG when only ENTER was pressed.
6F04
If the Z FLAG is set (no reply), JUMP to 6F1CH: one side.
6F06
LD A,(HL) 7E
Fetch the first character of the reply at Register Pair HL (6C00H) into Register A.
6F07
CP 31H FE 31
Compare Register A (the character) against 31H, the digit 1.
6F09
If the Z FLAG is set (1), JUMP to 6F1CH: one side.
6F0B
CP 32H FE 32
Compare Register A (the character) against 32H, the digit 2.
6F0D
If the NZ FLAG is set (neither 1 nor 2), LOOP BACK to 6EF8H to ask again.
6F0F
JUMP to 6F16H with the Z FLAG set (the reply 2): two sides.
6F11
LD A,(6D61H) 3A 61 6D
Fetch the low byte of the SIDES parameter from 6D61H into Register A.
6F14
CP 02H FE 02
Compare Register A (SIDES) against 02H: the Z FLAG for SIDES=2.
6F16
If the NZ FLAG is set (not 2), JUMP to 6F1CH: one side.
6F18
SET 5,(IY+04H) FD CB 04 EE
Set bit 5 of +04H of the working drive code table at Index Register IY (6509H): two sides.
6F1C
LD A,(IY+03H) FD 7E 03
Fetch +03H of the working drive code table at Index Register IY (6508H) into Register A.
6F1F
AND 28H E6 28
Mask Register A to bits 5 and 3 (AND 28H): an 8 inch drive or a hard disk.
6F21
If the NZ FLAG is set (8 inch or a hard disk), JUMP to 6F50H: the number of cylinders stays as 649CH set it (77 for 8 inch).
6F23
LD A,(6EACH) 3A AC 6E
Fetch the value at 6EACH (6D6FH) into Register A. 6F39H comes back here.
6F26
OR A B7
Set the flags from Register A (OR A): the Z FLAG when no format parameter was given.
6F27
If the NZ FLAG is set (parameters given), JUMP to 6F41H to take the cylinders from CYL.
6F29
LD HL,7332H 21 32 73
Point Register Pair HL to 7332H, the question Number of cylinders ? ended by 03H.
6F2C
GOSUB to 6463H to display the question at Register Pair HL and read up to 3 characters into 6C00H; Register Pair HL comes back as 6C00H.
6F2F
GOSUB to 70ECH to turn the digits at Register Pair HL into a number in Register A (0 when no digit comes first).
6F32
OR A B7
Set the flags from Register A (OR A): the Z FLAG for 0.
6F33
If the NZ FLAG is set (a number), JUMP to 6F37H to check it.
6F35
LD A,00H 3E 00
Load Register A with the default number of cylinders of the drive: the operand 6F36H, 00H in the file, stored by 6DBBH.
6F37
CP 60H FE 60
Compare Register A (the number of cylinders) against 60H (96).
6F39
If the NO CARRY FLAG is set (96 or more), LOOP BACK to 6F23H to ask again. The 1992 manual (M-40-060) allows up to 96; the code takes at most 95.
6F3B
DEC A 3D
DECrement Register A: the highest cylinder (cylinders count from 0).
6F3C
LD (IY+06H),A FD 77 06
Store Register A (the highest cylinder) into +06H of the working drive code table at Index Register IY (650BH).
6F3F
JUMP to 6F50H, to the question of the bootstrap step rate.
6F41
LD A,(6D66H) 3A 66 6D
Fetch the low byte of the CYL parameter from 6D66H into Register A.
6F44
OR A B7
Set the flags from Register A (OR A): the Z FLAG when CYL was not given.
6F45
If the Z FLAG is set (no CYL), JUMP to 6F50H: the default stays.
6F47
CP 60H FE 60
Compare Register A (the low byte of CYL) against 60H (96).
6F49
If the NO CARRY FLAG is set (96 or more, or CYL given without a value: FFH), JUMP to 6452H to give error 2CH, Parameter error.
6F4C
DEC A 3D
DECrement Register A: the highest cylinder (cylinders count from 0).
6F4D
LD (IY+06H),A FD 77 06
Store Register A (the highest cylinder) into +06H of the working drive code table at Index Register IY (650BH).

6F50H - The Bootstrap Step Rate

The step rate is asked for in milliseconds, with the values of a 5 inch drive (6, 12, 20 or 30, the rates the question names; 40 is taken too, as rate 3) or an 8 inch drive (3, 6, 10, 15 or 20), and turned into 0-3; ENTER, Q=N and the parameters take STEP or the default from the system information sector (6D21H). The Model I file refuses SYSTEM here unless the format is 5 inch double density; the Model III file has refused SYSTEM for every floppy already (6DD7H).

6F50
BIT 4,(IY+04H) FD CB 04 66
Test bit 4 of +04H of the working drive code table at Index Register IY (6509H). Never set here: 6E77H sends such a drive to 6FC1H.
6F54
If the NZ FLAG is set (never), JUMP to 6EF8H.
6F56
LD A,(6EACH) 3A AC 6E
Fetch the value at 6EACH (6D6FH) into Register A.
6F59
OR A B7
Set the flags from Register A (OR A): the Z FLAG when no format parameter was given.
6F5A
If the NZ FLAG is set (parameters given), JUMP to 6FB6H to take STEP or the default.
6F5C
BIT 5,(IY+03H) FD CB 03 6E
Test bit 5 of +03H of the working drive code table at Index Register IY (6508H): set for an 8 inch drive.
6F60
If the NZ FLAG is set (8 inch), JUMP to 6F8CH for the question with the 8 inch rates.
6F62
LD HL,7349H 21 49 73
Point Register Pair HL to 7349H, the question Boot strap stepping rate <6, 12, 20, 30 msecs> ? ended by 03H. 6F8AH comes back here.
6F65
GOSUB to 6463H to display the question at Register Pair HL and read up to 3 characters into 6C00H; Register Pair HL comes back as 6C00H.
6F68
GOSUB to 70ECH to turn the digits at Register Pair HL into a number in Register A.
6F6B
OR A B7
Set the flags from Register A (OR A): the Z FLAG for 0 (no number).
6F6C
If the Z FLAG is set (no number), JUMP to 6FB6H to take the default rate.
6F6E
LD B,00H 06 00
Load Register B with 00H, rate 0. LD does not change the flags.
6F70
CP 06H FE 06
Compare Register A (the reply) against 06H (6 ms).
6F72
If the Z FLAG is set (6), JUMP to 6FBDH with rate 0 in Register B.
6F74
LD B,01H 06 01
Load Register B with 01H, rate 1, for the next compare.
6F76
CP 0CH FE 0C
Compare Register A (the reply) against 0CH (12 ms).
6F78
If the Z FLAG is set (12), JUMP to 6FBDH with rate 1 in Register B.
6F7A
LD B,02H 06 02
Load Register B with 02H, rate 2, for the next compare.
6F7C
CP 14H FE 14
Compare Register A (the reply) against 14H (20 ms).
6F7E
If the Z FLAG is set (20), JUMP to 6FBDH with rate 2 in Register B.
6F80
LD B,03H 06 03
Load Register B with 03H, rate 3, for the next two compares.
6F82
CP 1EH FE 1E
Compare Register A (the reply) against 1EH (30 ms).
6F84
If the Z FLAG is set (30), JUMP to 6FBDH with rate 3 in Register B.
6F86
CP 28H FE 28
Compare Register A (the reply) against 28H (40 ms), also rate 3, though the question names only 30.
6F88
If the Z FLAG is set (40), JUMP to 6FBDH with rate 3 in Register B.
6F8A
LOOP BACK to 6F62H to ask again: the reply is none of the rates.
6F8C
LD HL,737BH 21 7B 73
Point Register Pair HL to 737BH, the question Bootstrap stepping rate <3, 6, 10, 15/20 msecs> ? ended by 03H. 6FB4H comes back here.
6F8F
GOSUB to 6463H to display the question at Register Pair HL and read up to 3 characters into 6C00H; Register Pair HL comes back as 6C00H.
6F92
GOSUB to 70ECH to turn the digits at Register Pair HL into a number in Register A.
6F95
OR A B7
Set the flags from Register A (OR A): the Z FLAG for 0 (no number).
6F96
If the Z FLAG is set (no number), JUMP to 6FB6H to take the default rate.
6F98
LD B,00H 06 00
Load Register B with 00H, rate 0. LD does not change the flags.
6F9A
CP 03H FE 03
Compare Register A (the reply) against 03H (3 ms).
6F9C
If the Z FLAG is set (3), JUMP to 6FBDH with rate 0 in Register B.
6F9E
LD B,01H 06 01
Load Register B with 01H, rate 1, for the next compare.
6FA0
CP 06H FE 06
Compare Register A (the reply) against 06H (6 ms).
6FA2
If the Z FLAG is set (6), JUMP to 6FBDH with rate 1 in Register B.
6FA4
LD B,02H 06 02
Load Register B with 02H, rate 2, for the next compare.
6FA6
CP 0AH FE 0A
Compare Register A (the reply) against 0AH (10 ms).
6FA8
If the Z FLAG is set (10), JUMP to 6FBDH with rate 2 in Register B.
6FAA
LD B,03H 06 03
Load Register B with 03H, rate 3, for the next two compares.
6FAC
CP 0FH FE 0F
Compare Register A (the reply) against 0FH (15 ms).
6FAE
If the Z FLAG is set (15), JUMP to 6FBDH with rate 3 in Register B.
6FB0
CP 14H FE 14
Compare Register A (the reply) against 14H (20 ms), also rate 3.
6FB2
If the Z FLAG is set (20), JUMP to 6FBDH with rate 3 in Register B.
6FB4
LOOP BACK to 6F8CH to ask again: the reply is none of the rates.
6FB6
LD A,(6D6BH) 3A 6B 6D
Fetch the low byte of the STEP parameter from 6D6BH into Register A: STEP=n, or the default rate from the system information sector (6D21H).
6FB9
AND 03H E6 03
Mask Register A to bits 1-0 (AND 03H): the rate, 0-3.
6FBB
JUMP to 6FBEH to store the rate in Register A at 650FH.
6FBD
LD A,B 78
Copy Register B (the rate of the reply) into Register A.
6FBE
LD (650FH),A 32 0F 65
Store Register A (the bootstrap step rate) at 650FH, for the two boot sectors (6268H, 6295H).

6FC1H - The Allocation Table Image, the Target Diskette

Each cylinder's byte of the allocation table image (6900H up to the highest cylinder) gets a bit set for every granule the cylinder does not have: FFH shifted left once for each granule of a cylinder (the granules on a track, twice that with two sides). The bytes after it up to 69CAH, the lock out table among them, get FFH. For drive 0 the operator is asked to put in the diskette to be formatted; a JCL job cannot answer, so it ends there.

6FC1
LD A,(IY+08H) FD 7E 08
Fetch +08H of the working drive code table at Index Register IY (650DH) into Register A: bits 7-5 the granules on a track less one.
6FC4
RLCA 07
Rotate Register A left one place (RLCA): bit 7 goes round to bit 0.
6FC5
RLCA 07
Rotate Register A left one place (RLCA): bits 7-6 are now bits 1-0.
6FC6
RLCA 07
Rotate Register A left one place (RLCA): bits 7-5 of +08H are now bits 2-0.
6FC7
AND 07H E6 07
Mask Register A to bits 2-0 (AND 07H): the granules on a track less one.
6FC9
INC A 3C
INCrement Register A: the granules on a track.
6FCA
LD B,FFH 06 FF
Load Register B with FFH, every granule not free, before the shifts below free the cylinder's granules.
6FCC
BIT 5,(IY+04H) FD CB 04 6E
Test bit 5 of +04H of the working drive code table at Index Register IY (6509H): set for two sides.
6FD0
If the Z FLAG is set (one side), JUMP to 6FD3H with Register A = the granules on a track.
6FD2
ADD A,A 87
Double Register A (ADD A,A): the granules on a cylinder of two sides.
6FD3
SLA B CB 20
Shift Register B left one place (SLA): one more granule bit, from bit 0 up, is clear (free). 6FD6H loops back here.
6FD5
DEC A 3D
DECrement Register A, the granules of the cylinder still to free.
6FD6
If the NZ FLAG is set (granules left), LOOP BACK to 6FD3H: Register B ends as FCH for 2 granules, F8H for 3, F0H for 4, C0H for 6.
6FD8
LD HL,6900H 21 00 69
Point Register Pair HL to 6900H, cylinder 0's byte of the allocation table image.
6FDB
LD A,(IY+06H) FD 7E 06
Fetch +06H of the working drive code table at Index Register IY (650BH) into Register A: the highest cylinder.
6FDE
LD (HL),B 70
Store Register B (the free granule pattern) at Register Pair HL, the byte of a cylinder.
6FDF
INC L 2C
INCrement Register L to the next cylinder's byte.
6FE0
CP L BD
Compare Register A (the highest cylinder) against Register L (the next cylinder): the CARRY FLAG once Register L is past it.
6FE1
If the NO CARRY FLAG is set (Register L is not past the highest cylinder), LOOP BACK to 6FDEH.
6FE3
LD B,FFH 06 FF
Load Register B with FFH: no granule free, for the bytes after the last cylinder.
6FE5
LD A,CBH 3E CB
Load Register A with CBH, the low byte of 69CBH, where the loaded part of the image starts.
6FE7
LD (HL),B 70
Store Register B (FFH) at Register Pair HL, a byte after the cylinders.
6FE8
INC L 2C
INCrement Register L to the next byte of the image.
6FE9
CP L BD
Compare Register A (CBH) against Register L, the low byte of the pointer.
6FEA
If the NZ FLAG is set (69CBH not reached), LOOP BACK to 6FE7H: every byte up to 69CAH is FFH, the lock out table (6960H-69BFH) and +C0H-+CAH included.
6FEC
LD A,(642DH) 3A 2D 64
Fetch the target drive from 642DH into Register A.
6FEF
OR A B7
Set the flags from Register A (OR A): the Z FLAG for drive 0.
6FF0
If the NZ FLAG is set (not drive 0), JUMP to 700CH to check the target diskette.
6FF2
LD HL,742BH 21 2B 74
Point Register Pair HL to 742BH, the text Load destination diskette and hit <ENTER> ended by 0DH. 7036H comes back here when no diskette turns in the drive.
6FF5
GOSUB to 4467H, @DSPLY, to display the text at Register Pair HL (742BH).
6FF8
LD A,(442BH) 3A 2B 44
Fetch SFLAG$ from 442BH into Register A: bit 5 is set while a JCL job runs.
6FFB
BIT 5,A CB 6F
Test bit 5 of Register A (SFLAG$): a JCL job.
6FFD
If the NZ FLAG is set (a job runs: no one can change the diskette), JUMP to 63D5H to display Format aborted! and end at @ABORT.
7000
LD HL,6C00H 21 00 6C
Point Register Pair HL to 6C00H, a buffer for the line input.
7003
LD BC,0000H 01 00 00
Load Register Pair BC with 0000H: Register B = 0, no character can be typed; only ENTER or BREAK end the input.
7006
GOSUB to 0040H, the ROM's line input, to wait for ENTER or BREAK with Register B (0) and Register Pair HL (6C00H); the CARRY FLAG for BREAK.
7009
If the CARRY FLAG is set (BREAK), JUMP to 63D5H to display Format aborted! and end at @ABORT.

700CH - Check the Target Diskette

The working table is saved at 7163H, since the checks move the head and change +05H. After a Restore the controller's status must show the drive ready and the head on track 0, a diskette must turn (713CH) and must not be write protected, and HIGH$ must leave room for the track (not looked at with SYSTEM, 7044H). A drive with bit 4 of +04H set skips these. Then, when cylinder 0, sector 0 can be read (in the density of the new format), the diskette's name and date are shown from its directory, and the operator must answer Y unless ABS (or SYSTEM, 7067H) was given; a JCL job ends there. The saved table is put back, the head restored, and the engine starts at 6000H.

700C
PUSH IY FD E5
Save Index Register IY (6505H, the working drive code table) to the stack.
700E
POP HL E1
Restore it into Register Pair HL: the source of the copy below.
700F
LD DE,7163H 11 63 71
Point Register Pair DE to 7163H, the save area (not in the file).
7012
LD BC,000AH 01 0A 00
Load Register Pair BC with 000AH, the ten bytes of a drive code table.
7015
LDIR ED B0
Copy the working table from Register Pair HL (6505H) to Register Pair DE (7163H), Register Pair BC the count (LDIR).
7017
GOSUB to 6408H, the driver's function 04H, Restore: the head goes to cylinder 0.
701A
GOSUB to 6410H, the driver's function 07H: wait until the Restore is finished; Register A = the controller's status.
701D
BIT 4,(IY+04H) FD CB 04 66
Test bit 4 of +04H of the working drive code table at Index Register IY (6509H): the drive FORMAT writes no tracks on.
7021
If the NZ FLAG is set (bit 4 set), JUMP to 705FH: no floppy status checks, no memory check.
7023
LD HL,73EFH 21 EF 73
Point Register Pair HL to 73EFH, the text Drive not ready! ended by 0DH.
7026
BIT 7,A CB 7F
Test bit 7 of Register A (the status): NOT READY.
7028
If the NZ FLAG is set (not ready), JUMP to 63D8H to display the text at Register Pair HL (73EFH), put back the interrupt vector and end at @ABORT.
702B
LD HL,7416H 21 16 74
Point Register Pair HL to 7416H, the text Drive not in system! ended by 0DH.
702E
BIT 2,A CB 57
Test bit 2 of Register A (the status after the Restore): TRACK 0, the head is on cylinder 0.
7030
If the Z FLAG is set (the head is not on track 0 after the Restore), JUMP to 63D8H to display the text at Register Pair HL (7416H) and end at @ABORT.
7033
GOSUB to 713CH to see whether a diskette turns: the Z FLAG when the index hole passed within 15 ticks (half a second); Register A = the last status.
7036
If the NZ FLAG is set (no diskette turns), LOOP BACK to 6FF2H to ask for the diskette and wait for ENTER.
7038
LD HL,7400H 21 00 74
Point Register Pair HL to 7400H, the text Write protected disk! ended by 0DH.
703B
RLCA 07
Rotate Register A (the status) left one place (RLCA): bit 6, WRITE PROTECT (the notch is covered), goes to bit 7.
703C
OR (IY+03H) FD B6 03
OR +03H of the working drive code table at Index Register IY (6508H) into Register A: bit 7 of +03H is the software write protect.
703F
AND 80H E6 80
Mask Register A to bit 7 (AND 80H): set when the diskette or the drive is write protected.
7041
If the NZ FLAG is set (write protected), JUMP to 63D8H to display the text at Register Pair HL (7400H) and end at @ABORT.
7044
LD A,(61C6H) 3A C6 61
Fetch the low byte of the SYSTEM parameter from 61C6H (the operand of LD HL,0000H at 61C5H) into Register A: FFH when SYSTEM was given (only for a hard disk, 6DD7H).
7047
OR A B7
Set the flags from Register A (OR A): the NZ FLAG when SYSTEM was given.
7048
If the NZ FLAG is set (SYSTEM: no track is built), JUMP to 705FH, past the memory check.
704A
LD HL,6D00H 21 00 6D
Point Register Pair HL to 6D00H, where the track will be built.
704D
LD DE,0000H 11 00 00
Load Register Pair DE with the memory the track takes: the operand 704EH-704FH, 0000H in the file, stored by 64C0H from the descriptor.
7050
ADD HL,DE 19
ADD Register Pair DE to Register Pair HL: the address after the track's memory.
7051
LD D,H 54
Copy Register H (the high byte of the end of the track's memory) into Register D.
7052
LD E,L 5D
Copy Register L into Register E: Register Pair DE = the address after the track's memory.
7053
LD HL,(4411H) 2A 11 44
Fetch HIGH$ from 4411H into Register Pair HL: the highest address free for programs.
7056
XOR A AF
Set Register A to 00H (XOR A): the CARRY FLAG is clear for the SBC.
7057
SBC HL,DE ED 52
SUBtract Register Pair DE (the end of the track's memory) from Register Pair HL (HIGH$): the CARRY FLAG when HIGH$ is below it.
7059
LD HL,72A0H 21 A0 72
Point Register Pair HL to 72A0H, the text Insufficient memory for specified format! ended by 0DH. LD does not change the flags.
705C
If the CARRY FLAG is set (not enough memory), JUMP to 63D8H to display the text at Register Pair HL (72A0H) and end at @ABORT.
705F
LD DE,0000H 11 00 00
Load Register Pair DE with 0000H: Register D = cylinder 0, Register E = sector 0.
7062
GOSUB to 6428H, the driver's function 0AH, Verify: can cylinder Register D (0), sector Register E (0) be read in the format chosen?
7065
If the NZ FLAG is set (it cannot: a blank diskette or another format), JUMP to 70DBH to start the format.
7067
LD A,(61C6H) 3A C6 61
Fetch the low byte of the SYSTEM parameter from 61C6H into Register A: FFH when SYSTEM was given.
706A
OR A B7
Set the flags from Register A (OR A): the NZ FLAG for SYSTEM.
706B
If the NZ FLAG is set (SYSTEM given), JUMP to 70DBH: the contents of the diskette are not looked at, only the system information will be written.
706D
LD HL,6C00H 21 00 6C
Point Register Pair HL to 6C00H, the sector buffer.
7070
LD DE,0000H 11 00 00
Load Register Pair DE with 0000H: Register D = cylinder 0, Register E = sector 0.
7073
GOSUB to 6424H, the driver's function 09H, Read Sector: cylinder Register D (0), sector Register E (0) into the buffer at Register Pair HL (6C00H).
7076
If the NZ FLAG is set (the read failed), JUMP to 6448H to report the error in Register A.
7079
LD HL,7470H 21 70 74
Point Register Pair HL to 7470H, the text Disk contains data -- ended by 03H.
707C
GOSUB to 428AH, @LOGOT, to display the text at Register Pair HL (7470H) and write it to the job log; the cursor stays at its end.
707F
LD HL,7487H 21 87 74
Point Register Pair HL to 7487H, the text Non-standard format ended by 0DH: shown unless the directory is found.
7082
LD A,(6C02H) 3A 02 6C
Fetch byte 2 of the boot sector just read, 6C02H, into Register A: the diskette's directory cylinder.
7085
CP (IY+06H) FD BE 06
Compare Register A (the directory cylinder) against +06H of the working drive code table at Index Register IY (650BH), the highest cylinder of the new format.
7088
If the NO CARRY FLAG is set (the directory cylinder is not below it), JUMP to 70BEH to display Non-standard format.
708A
LD HL,6C00H 21 00 6C
Point Register Pair HL to 6C00H, the sector buffer.
708D
LD E,L 5D
Copy Register L (00H) into Register E: sector 0, the diskette's allocation table.
708E
LD D,A 57
Copy Register A (the directory cylinder) into Register D.
708F
LD HL,6C00H 21 00 6C
Point Register Pair HL to 6C00H, the sector buffer, again.
7092
GOSUB to 6424H, the driver's function 09H, Read Sector: cylinder Register D (the directory), sector Register E (0) into the buffer at Register Pair HL (6C00H).
7095
CP 06H FE 06
Compare Register A (the driver's result) against 06H, the error of a sector with the deleted data mark: the mark of a directory sector.
7097
If the Z FLAG is set (06H), JUMP to 709EH: the directory was found.
7099
LD HL,749BH 21 9B 74
Point Register Pair HL to 749BH, the text Unreadable directory ended by 0DH: the sector failed, or carries the normal data mark.
709C
JUMP to 70BEH to display the text at Register Pair HL (749BH).
709E
LD HL,74B0H 21 B0 74
Point Register Pair HL to 74B0H, the text Non-initialized directory ended by 0DH: shown unless the date is found.
70A1
LD A,(6CDAH) 3A DA 6C
Fetch the allocation table's +DAH from 6CDAH into Register A: the third character of the date MM/DD/YY.
70A4
CP 2FH FE 2F
Compare Register A (the character) against 2FH, the slash of a date.
70A6
If the NZ FLAG is set (no date), JUMP to 70BEH to display Non-initialized directory.
70A8
LD HL,6CD0H 21 D0 6C
Point Register Pair HL to 6CD0H, the diskette name in the allocation table read (+D0H).
70AB
LD DE,74CFH 11 CF 74
Point Register Pair DE to 74CFH, the eight X of the text Name=XXXXXXXX at 74CAH.
70AE
LD BC,0008H 01 08 00
Load Register Pair BC with 0008H, the length of the name.
70B1
LDIR ED B0
Copy the name from Register Pair HL (6CD0H) to Register Pair DE (74CFH), Register Pair BC the count (LDIR); Register Pair HL comes out at 6CD8H, the date.
70B3
LD DE,74DEH 11 DE 74
Point Register Pair DE to 74DEH, the MM/DD/YY of the text.
70B6
LD BC,0008H 01 08 00
Load Register Pair BC with 0008H, the length of the date.
70B9
LDIR ED B0
Copy the date from Register Pair HL (6CD8H) to Register Pair DE (74DEH), Register Pair BC the count (LDIR).
70BB
LD HL,74CAH 21 CA 74
Point Register Pair HL to 74CAH, the text Name=, the name, two spaces, Date= and the date, ended by 0DH.
70BE
GOSUB to 428AH, @LOGOT, to display the text at Register Pair HL (one of 7487H, 749BH, 74B0H, 74CAH) and write it to the job log.
70C1
LD DE,0000H 11 00 00
Load Register Pair DE with the ABS parameter: the operand 70C2H-70C3H, 0000H in the file, FFFFH when ABS was given.
70C4
INC E 1C
INCrement Register E (the low byte of ABS): the Z FLAG when ABS was given.
70C5
If the Z FLAG is set (ABS), JUMP to 70DBH: no question.
70C7
LD HL,442BH 21 2B 44
Point Register Pair HL to 442BH, SFLAG$, the system flags.
70CA
BIT 5,(HL) CB 6E
Test bit 5 of the byte at Register Pair HL (SFLAG$): set while a JCL job runs.
70CC
If the NZ FLAG is set (a job runs: no one can answer), JUMP to 63D5H to display Format aborted! and end at @ABORT.
70CF
LD HL,7510H 21 10 75
Point Register Pair HL to 7510H, the question Are you sure you want to format it ? ended by 03H (the second line of the text at 74E7H).
70D2
GOSUB to 6463H to display the question at Register Pair HL and read up to 3 characters into 6C00H in upper case.
70D5
LD A,(HL) 7E
Fetch the first character of the reply at Register Pair HL (6C00H) into Register A (0DH when only ENTER was pressed).
70D6
CP 59H FE 59
Compare Register A (the character) against 59H, Y.
70D8
If the NZ FLAG is set (not Y), JUMP to 63D5H to display Format aborted! and end at @ABORT.
70DB
PUSH IY FD E5
Save Index Register IY (6505H, the working drive code table) to the stack.
70DD
POP DE D1
Restore it into Register Pair DE: the destination of the copy below.
70DE
LD HL,7163H 21 63 71
Point Register Pair HL to 7163H, the table saved at 7015H.
70E1
LD BC,000AH 01 0A 00
Load Register Pair BC with 000AH, the ten bytes of a drive code table.
70E4
LDIR ED B0
Copy the saved table from Register Pair HL (7163H) to Register Pair DE (6505H), Register Pair BC the count (LDIR): the working table as it was before the checks.
70E6
GOSUB to 6408H, the driver's function 04H, Restore: the head goes to cylinder 0, and +05H = 0.
70E9
JUMP to 6000H, the format engine, with Index Register IY at 6505H.

70ECH - A Number From Digits

Register Pair HL points to a reply; the decimal digits at its start are turned into a number in Register A (the low 8 bits), ending at the first character that is not a digit. Register Pair HL comes back past that character.

70EC
LD E,00H 1E 00
Load Register E with 00H, the number so far: no digit yet.
70EE
LD A,(HL) 7E
Fetch the next character at Register Pair HL into Register A. 70FDH loops back here.
70EF
INC HL 23
INCrement Register Pair HL past the character.
70F0
SUB 30H D6 30
SUBtract 30H from Register A: the value of a digit, 0-9.
70F2
LD B,A 47
Copy Register A (the value of the character) into Register B.
70F3
CP 0AH FE 0A
Compare Register A (the value) against 0AH: the CARRY FLAG for a digit.
70F5
LD A,E 7B
Copy Register E (the number so far) into Register A. LD does not change the flags.
70F6
RET NC D0
If the NO CARRY FLAG is set (not a digit), RETurn with the number in Register A.
70F7
ADD A,A 87
Double Register A (ADD A,A): the number so far x 2.
70F8
ADD A,A 87
Double Register A (ADD A,A): the number so far x 4.
70F9
ADD A,E 83
ADD Register E (the number) to Register A: the number x 5.
70FA
ADD A,A 87
Double Register A (ADD A,A): the number x 10.
70FB
ADD A,B 80
ADD Register B (the value of the digit) to Register A.
70FC
LD E,A 5F
Copy Register A (the new number) into Register E.
70FD
LOOP BACK to 70EEH for the next character at Register Pair HL.

70FFH - Check and Hash the Master Password

Register Pair DE points to the 8 characters of the password. The first must be a letter A-Z, each of the others a letter or a digit 0-9, and once a space comes every character after it must be a space. A password that fails gives Invalid Master Password! and Format aborted!. A good one is hashed by SYS2/SYS (request E4H): Register Pair HL = the hash.

70FF
LD B,08H 06 08
Load Register B with 08H, the characters of the password.
7101
PUSH DE D5
Save Register Pair DE (the address of the password) to the stack.
7102
POP HL E1
Restore it into Register Pair HL: Register Pair HL points to the first character.
7103
LD A,(HL) 7E
Fetch the first character at Register Pair HL into Register A.
7104
JUMP to 7114H: the first character must be a letter.
7106
INC HL 23
INCrement Register Pair HL to the next character. 711CH loops back here.
7107
LD A,(HL) 7E
Fetch the character at Register Pair HL into Register A.
7108
CP 20H FE 20
Compare Register A (the character) against 20H, a space.
710A
If the Z FLAG is set (a space), JUMP to 7126H: the rest must be spaces.
710C
CP 30H FE 30
Compare Register A (the character) against 30H, the digit 0.
710E
If the CARRY FLAG is set (below 30H), JUMP to 7133H: Invalid Master Password!.
7110
CP 3AH FE 3A
Compare Register A (the character) against 3AH, the character after the digit 9.
7112
If the CARRY FLAG is set (a digit 0-9), JUMP to 711CH: the character is good.
7114
CP 41H FE 41
Compare Register A (the character) against 41H, the letter A.
7116
If the CARRY FLAG is set (below 41H), JUMP to 7133H: Invalid Master Password!.
7118
CP 5BH FE 5B
Compare Register A (the character) against 5BH, the character after the letter Z.
711A
If the NO CARRY FLAG is set (above Z), JUMP to 7133H: Invalid Master Password!.
711C
DECrement Register B (the characters left) and LOOP BACK to 7106H until all 8 are checked.
711E
GOSUB to 7178H, the request E4H: SYS2/SYS hashes the 8 characters at Register Pair DE and returns the hash in Register Pair HL.
7121
RET C9
RETurn with the hash of the master password in Register Pair HL.
7122
INC HL 23
INCrement Register Pair HL to the next character after a space. 7126H loops back here.
7123
CP (HL) BE
Compare Register A (20H, a space) against the character at Register Pair HL.
7124
If the NZ FLAG is set (not a space), JUMP to 7133H: Invalid Master Password!.
7126
DECrement Register B (the characters left) and LOOP BACK to 7122H until the rest of the 8 are checked.
7128
JUMP to 711EH to hash the password, which has passed the checks.
712A
LD HL,7184H 21 84 71
Point Register Pair HL to 7184H, the text Can't "SYSTEM" a floppy! ended by 0DH. 6DD7H comes here when SYSTEM is given for a drive that is not a hard disk.
712D
GOSUB to 428AH, @LOGOT, to display the text at Register Pair HL (7184H) and write it to the job log.
7130
JUMP to 4030H, @ABORT: the program ends with an error; nothing has been written to the diskette.
7133
LD HL,7455H 21 55 74
Point Register Pair HL to 7455H, the text 0AH, Invalid Master Password!, 0AH and 0DH.
7136
GOSUB to 428AH, @LOGOT, to display the text at Register Pair HL (7455H) and write it to the job log.
7139
JUMP to 63D5H to display Format aborted! and end at @ABORT.

713CH - Does a Diskette Turn?

The controller's status bit 1 (INDEX) is 1 while the index hole is under the sensor. The routine waits for it to be 0, then 1, then 0 again, each within the deadline of TIMER$ (4288H) plus 15 ticks (half a second at the 30 ticks a second of the Model III). It returns the Z FLAG when the hole passed; at the deadline 715FH drops the return address of the poll and returns to the caller of 713CH with the NZ FLAG.

713C
LD A,(4288H) 3A 88 42
Fetch TIMER$ from 4288H into Register A: the tick count, 30 a second on the Model III.
713F
ADD A,0FH C6 0F
ADD 0FH (15) to Register A: the tick of the deadline, half a second on at 30 ticks a second (the Model I file adds 14H, 20 of its 40).
7141
LD D,A 57
Copy Register A (the deadline) into Register D.
7142
GOSUB to 7152H to read the status: the Z FLAG when the index hole is not under the sensor.
7145
If the NZ FLAG is set (the hole is under the sensor), LOOP BACK to 7142H until it is not.
7147
GOSUB to 7152H to read the status: the Z FLAG when the index hole is not under the sensor.
714A
If the Z FLAG is set (no hole), LOOP BACK to 7147H until the hole comes.
714C
GOSUB to 7152H to read the status: the Z FLAG when the index hole is not under the sensor.
714F
If the NZ FLAG is set (the hole is under the sensor), LOOP BACK to 714CH until it has passed.
7151
RET C9
RETurn with the Z FLAG: the diskette turns. Register A holds the last status.
7152
EI FB
Enable interrupts, so that TIMER$ (4288H) goes on counting.
7153
LD A,(4288H) 3A 88 42
Fetch TIMER$ from 4288H into Register A: the tick count now.
7156
CP D BA
Compare Register A (TIMER$) against Register D (the deadline).
7157
If the Z FLAG is set (the deadline), JUMP to 715FH to give up.
7159
GOSUB to 6410H, the driver's function 07H: Register A = the controller's status when it is not busy.
715C
BIT 1,A CB 4F
Test bit 1 of Register A (the status): INDEX, set while the index hole is under the sensor.
715E
RET C9
RETurn to the poll with the Z FLAG when the hole is not under the sensor.
715F
POP AF F1
Restore Register Pair AF from the stack: this drops the return address of the poll that called 7152H.
7160
OR 01H F6 01
OR 01H into Register A: the NZ FLAG, no diskette turns.
7162
RET C9
RETurn to the caller of 713CH with the NZ FLAG: no diskette turns.

7163H - Not in the File: the Saved Table and the Cylinders of the Drives

Two areas the front end fills.

7163-716C
DEFS 10
7163H-716CH: not in the file. The copy of the working drive code table taken at 7015H and put back at 70E4H.
716D-7174
DEFS 8
716DH-7174H: not in the file. The highest cylinder of drives 0-7 from the system information sector (6D2DH); 6DB9H takes the target drive's.

7175H - Two Supervisor Requests

Each loads a request code into Register A and does RST 28H. The supervisor's dispatcher (4BCCH) drops the return address the RST pushed, so the RET at the end of the system file goes back to the caller of the CALL: neither needs a RET of its own. Both codes name SYS2/SYS (low four bits 4: file 2 plus 2).

7175
LD A,84H 3E 84
Load Register A with 84H, the request for SYS2/SYS function 00H (bits 6-4), which loads the file and does nothing else. 6D07H calls it.
7177
RST 28H EF
RST 28H with Register A = 84H: the supervisor's dispatcher loads SYS2/SYS into 4E00H when it is not there; its RET goes back to the caller of 7175H.
7178
LD A,E4H 3E E4
Load Register A with E4H, the request for SYS2/SYS function 60H: the hash of the 8 character password at Register Pair DE. 711EH calls it.
717A
RST 28H EF
RST 28H with Register A = E4H: SYS2/SYS (its 4E27H) returns the hash of the password at Register Pair DE in Register Pair HL, to the caller of 7178H.

717BH - The Master Password, a Text

The buffer of the master password and the text of 712AH.

717B-7182
DEFM " " 20 20 20 20 20 20 20 20
717BH-7182H: the master password, eight spaces in the file: filled from the command line, the reply or PASSWORD (6E31H-6E68H), then checked and hashed (70FFH).
7183
DEFB 20H 20
7183H: a space after the buffer. The ROM's line input puts its 0DH here after a reply of 8 characters (6E53H).
7184-719B
DEFM "Can't " / DEFB 22H / DEFM "SYSTEM" / DEFB 22H / DEFM " a floppy!" 43 61 6E 27 74 20 22 53 59 53 54 45 4D 22 20 61 20 66 6C 6F 70 70 79 21
7184H-719BH: the text of 712AH, Can't "SYSTEM" a floppy!, for SYSTEM given for a drive that is not a hard disk (6DD7H).
719C
DEFB 0DH 0D
719CH: 0DH, the end of the line and of the text.

719DH - The Table of the Parameters

The table @PARAM reads (6D50H): for each parameter its name, 6 characters padded with spaces, and the address of the operand that takes its value; the short forms point to the same operands. 00H ends it. The operands: 0000H in the file (not given), FFFFH for a parameter given alone (or Y), 0000H for N, the number for =n, the address of the text for a quoted text.

719D-71A4
DEFM "NAME " / DEFW 6DE1H 4E 41 4D 45 20 20 E1 6D
719DH-71A4H: NAME, the diskette name: the operand of LD HL,0000H at 6DE0H.
71A5-71AC
DEFM "N " / DEFW 6DE1H 4E 20 20 20 20 20 E1 6D
71A5H-71ACH: N, the short form of NAME: 6DE1H.
71AD-71B4
DEFM "MPW " / DEFW 6E24H 4D 50 57 20 20 20 24 6E
71ADH-71B4H: MPW, the master password: the operand of LD HL,0000H at 6E23H.
71B5-71BC
DEFM "M " / DEFW 6E24H 4D 20 20 20 20 20 24 6E
71B5H-71BCH: M, the short form of MPW: 6E24H.
71BD-71C4
DEFM "SDEN " / DEFW 6D57H 53 44 45 4E 20 20 57 6D
71BDH-71C4H: SDEN, single density: the operand of LD DE,0000H at 6D56H.
71C5-71CC
DEFM "DDEN " / DEFW 6D5CH 44 44 45 4E 20 20 5C 6D
71C5H-71CCH: DDEN, double density: the operand of LD DE,0000H at 6D5BH.
71CD-71D4
DEFM "SIDES " / DEFW 6D61H 53 49 44 45 53 20 61 6D
71CDH-71D4H: SIDES=n, the sides: the operand of LD DE,0000H at 6D60H.
71D5-71DC
DEFM "CYL " / DEFW 6D66H 43 59 4C 20 20 20 66 6D
71D5H-71DCH: CYL=n, the cylinders: the operand of LD DE,0000H at 6D65H.
71DD-71E4
DEFM "C " / DEFW 6D66H 43 20 20 20 20 20 66 6D
71DDH-71E4H: C, the short form of CYL: 6D66H.
71E5-71EC
DEFM "STEP " / DEFW 6D6BH 53 54 45 50 20 20 6B 6D
71E5H-71ECH: STEP=n, the bootstrap step rate: the operand of LD DE,FF00H at 6D6AH.
71ED-71F4
DEFM "ABS " / DEFW 70C2H 41 42 53 20 20 20 C2 70
71EDH-71F4H: ABS, no question for a diskette that holds data: the operand of LD DE,0000H at 70C1H.
71F5-71FC
DEFM "A " / DEFW 70C2H 41 20 20 20 20 20 C2 70
71F5H-71FCH: A, the short form of ABS: 70C2H.
71FD-7204
DEFM "QUERY " / DEFW 6EB1H 51 55 45 52 59 20 B1 6E
71FDH-7204H: QUERY, ask the questions (FFFFH) or not (0000H): the operand of LD DE,FFFFH at 6EB0H.
7205-720C
DEFM "Q " / DEFW 6EB1H 51 20 20 20 20 20 B1 6E
7205H-720CH: Q, the short form of QUERY: 6EB1H.
720D-7214
DEFM "SYSTEM" / DEFW 61C6H 53 59 53 54 45 4D C6 61
720DH-7214H: SYSTEM, only the system information, for a hard disk (refused for a floppy, 6DD7H): the operand of LD HL,0000H at 61C5H.
7215-721C
DEFM "WAIT " / DEFW 6126H 57 41 49 54 20 20 26 61
7215H-721CH: WAIT=n, a wait after each step: the operand of LD BC,0000H at 6125H.
721D-7224
DEFM "W " / DEFW 6126H 57 20 20 20 20 20 26 61
721DH-7224H: W, the short form of WAIT: 6126H.
7225-722C
DEFM "DIR " / DEFW 620DH 44 49 52 20 20 20 0D 62
7225H-722CH: DIR=n, the cylinder of the directory: the operand of LD BC,0000H at 620CH.
722D-7234
DEFM "D " / DEFW 620DH 44 20 20 20 20 20 0D 62
722DH-7234H: D, the short form of DIR: 620DH.
7235
DEFB 00H 00
7235H: 00H, the end of the table: @PARAM stops here.

7236H - The Front End's Texts

The banner, the questions (ended by 03H: the cursor stays for the reply), the error texts (ended by 0DH), the defaults LDOSDISK and PASSWORD, and 32 bytes of 00H.

7236-7237
DEFB 1CH, 1FH 1C 1F
7236H-7237H: 1CH, the cursor to the top left, and 1FH, clear to the end of the screen: the start of the banner (6D01H).
7238-726B
DEFM "FORMAT - LDOS Disk Formatter Program - Version 5.3.1" 46 4F 52 4D 41 54 20 2D 20 4C 44 4F 53 20 44 69 73 6B 20 46 6F 72 6D 61 74 74 65 72 20 50 72 6F 67 72 61 6D 20 2D 20 56 65 72 73 69 6F 6E 20 35 2E 33 2E 31
7238H-726BH: the name and the version of the program.
726C
DEFB 0AH 0A
726CH: 0AH, a new line: the copyright goes on the next line.
726D-729D
DEFM "Copyright 1991 MISOSYS, Inc., All rights reserved" 43 6F 70 79 72 69 67 68 74 20 31 39 39 31 20 4D 49 53 4F 53 59 53 2C 20 49 6E 63 2E 2C 20 41 6C 6C 20 72 69 67 68 74 73 20 72 65 73 65 72 76 65 64
726DH-729DH: the copyright line of the program, Copyright 1991 MISOSYS, Inc.
729E-729F
DEFB 0AH, 0DH 0A 0D
729EH-729FH: 0AH, a new line, and 0DH, the end of the banner.
72A0-72C8
DEFM "Insufficient memory for specified format!" 49 6E 73 75 66 66 69 63 69 65 6E 74 20 6D 65 6D 6F 72 79 20 66 6F 72 20 73 70 65 63 69 66 69 65 64 20 66 6F 72 6D 61 74 21
72A0H-72C8H: the text of 7059H, when HIGH$ leaves no room for the track.
72C9
DEFB 0DH 0D
72C9H: 0DH, the end of the line and of the text.
72CA-72E5
DEFM "Which drive is to be used ? " 57 68 69 63 68 20 64 72 69 76 65 20 69 73 20 74 6F 20 62 65 20 75 73 65 64 20 3F 20
72CAH-72E5H: the question of 6D74H, when no :d is on the command line.
72E6
DEFB 03H 03
72E6H: 03H, the end of the question: the cursor stays for the reply.
72E7-72F6
DEFM "Diskette name ? " 44 69 73 6B 65 74 74 65 20 6E 61 6D 65 20 3F 20
72E7H-72F6H: the question of 6E0AH, for the diskette name.
72F7
DEFB 03H 03
72F7H: 03H, the end of the question: the cursor stays for the reply.
72F8-7309
DEFM "Master password ? " 4D 61 73 74 65 72 20 70 61 73 73 77 6F 72 64 20 3F 20
72F8H-7309H: the question of 6E48H, for the master password.
730A
DEFB 03H 03
730AH: 03H, the end of the question: the cursor stays for the reply.
730B-7330
DEFM "Special non-standard format desired ? " 53 70 65 63 69 61 6C 20 6E 6F 6E 2D 73 74 61 6E 64 61 72 64 20 66 6F 72 6D 61 74 20 64 65 73 69 72 65 64 20 3F 20
730BH-7330H: a question that no code of the file displays.
7331
DEFB 03H 03
7331H: 03H, the end of the question that no code displays.
7332-7347
DEFM "Number of cylinders ? " 4E 75 6D 62 65 72 20 6F 66 20 63 79 6C 69 6E 64 65 72 73 20 3F 20
7332H-7347H: the question of 6F29H, for a 5 inch floppy.
7348
DEFB 03H 03
7348H: 03H, the end of the question: the cursor stays for the reply.
7349-7379
DEFM "Boot strap stepping rate <6, 12, 20, 30 msecs> ? " 42 6F 6F 74 20 73 74 72 61 70 20 73 74 65 70 70 69 6E 67 20 72 61 74 65 20 3C 36 2C 20 31 32 2C 20 32 30 2C 20 33 30 20 6D 73 65 63 73 3E 20 3F 20
7349H-7379H: the question of 6F62H, for a 5 inch drive. It names 30 as the slowest rate, the slowest the Model III's DEVICE table knows for a 5 inch drive; the Model I text reads 30/40.
737A
DEFB 03H 03
737AH: 03H, the end of the question: the cursor stays for the reply.
737B-73AC
DEFM "Bootstrap stepping rate <3, 6, 10, 15/20 msecs> ? " 42 6F 6F 74 73 74 72 61 70 20 73 74 65 70 70 69 6E 67 20 72 61 74 65 20 3C 33 2C 20 36 2C 20 31 30 2C 20 31 35 2F 32 30 20 6D 73 65 63 73 3E 20 3F 20
737BH-73ACH: the question of 6F8CH, for an 8 inch drive.
73AD
DEFB 03H 03
73ADH: 03H, the end of the question: the cursor stays for the reply.
73AE-73CB
DEFM "Enter number of sides <1,2> ? " 45 6E 74 65 72 20 6E 75 6D 62 65 72 20 6F 66 20 73 69 64 65 73 20 3C 31 2C 32 3E 20 3F 20
73AEH-73CBH: the question of 6EFEH, for the number of sides.
73CC
DEFB 03H 03
73CCH: 03H, the end of the question: the cursor stays for the reply.
73CD-73ED
DEFM "Single or Double density <S,D> ? " 53 69 6E 67 6C 65 20 6F 72 20 44 6F 75 62 6C 65 20 64 65 6E 73 69 74 79 20 3C 53 2C 44 3E 20 3F 20
73CDH-73EDH: the question of 6EC4H, for the density.
73EE
DEFB 03H 03
73EEH: 03H, the end of the question: the cursor stays for the reply.
73EF-73FE
DEFM "Drive not ready!" 44 72 69 76 65 20 6E 6F 74 20 72 65 61 64 79 21
73EFH-73FEH: the text of 7023H, when the controller's status shows NOT READY.
73FF
DEFB 0DH 0D
73FFH: 0DH, the end of the line and of the text.
7400-7414
DEFM "Write protected disk!" 57 72 69 74 65 20 70 72 6F 74 65 63 74 65 64 20 64 69 73 6B 21
7400H-7414H: the text of 7038H, for a write protected diskette or drive.
7415
DEFB 0DH 0D
7415H: 0DH, the end of the line and of the text.
7416-7429
DEFM "Drive not in system!" 44 72 69 76 65 20 6E 6F 74 20 69 6E 20 73 79 73 74 65 6D 21
7416H-7429H: the text of 702BH, when the head is not on track 0 after a Restore.
742A
DEFB 0DH 0D
742AH: 0DH, the end of the line and of the text.
742B-7453
DEFM "Load destination diskette and hit <ENTER>" 4C 6F 61 64 20 64 65 73 74 69 6E 61 74 69 6F 6E 20 64 69 73 6B 65 74 74 65 20 61 6E 64 20 68 69 74 20 3C 45 4E 54 45 52 3E
742BH-7453H: the text of 6FF2H, for drive 0 and when no diskette turns.
7454
DEFB 0DH 0D
7454H: 0DH, the end of the line and of the text.
7455
DEFB 0AH 0A
7455H: 0AH, a new line: the start of the text of 7133H.
7456-746D
DEFM "Invalid Master Password!" 49 6E 76 61 6C 69 64 20 4D 61 73 74 65 72 20 50 61 73 73 77 6F 72 64 21
7456H-746DH: the text of 7133H, for a password with other characters than letters and digits.
746E-746F
DEFB 0AH, 0DH 0A 0D
746EH-746FH: 0AH, a new line, and 0DH, the end of the text.
7470-7485
DEFM "Disk contains data -- " 44 69 73 6B 20 63 6F 6E 74 61 69 6E 73 20 64 61 74 61 20 2D 2D 20
7470H-7485H: the text of 7079H, followed on the line by one of the four texts below.
7486
DEFB 03H 03
7486H: 03H, the end of the text: the cursor stays at its end.
7487-7499
DEFM "Non-standard format" 4E 6F 6E 2D 73 74 61 6E 64 61 72 64 20 66 6F 72 6D 61 74
7487H-7499H: the text of 707FH, for a diskette whose directory cylinder is not below the highest cylinder.
749A
DEFB 0DH 0D
749AH: 0DH, the end of the line and of the text.
749B-74AE
DEFM "Unreadable directory" 55 6E 72 65 61 64 61 62 6C 65 20 64 69 72 65 63 74 6F 72 79
749BH-74AEH: the text of 7099H, for a directory sector 0 without the deleted data mark.
74AF
DEFB 0DH 0D
74AFH: 0DH, the end of the line and of the text.
74B0-74C8
DEFM "Non-initialized directory" 4E 6F 6E 2D 69 6E 69 74 69 61 6C 69 7A 65 64 20 64 69 72 65 63 74 6F 72 79
74B0H-74C8H: the text of 709EH, for a directory whose date has no slash.
74C9
DEFB 0DH 0D
74C9H: 0DH, the end of the line and of the text.
74CA-74CE
DEFM "Name=" 4E 61 6D 65 3D
74CAH-74CEH: Name=, the start of the text of 70BBH.
74CF-74D6
DEFM "XXXXXXXX" 58 58 58 58 58 58 58 58
74CFH-74D6H: eight X in the file; 70B1H copies the diskette's name here.
74D7-74DD
DEFM " Date=" 20 20 44 61 74 65 3D
74D7H-74DDH: two spaces and Date=, between the name and the date.
74DE-74E5
DEFM "MM/DD/YY" 4D 4D 2F 44 44 2F 59 59
74DEH-74E5H: MM/DD/YY in the file; 70B9H copies the diskette's date here.
74E6
DEFB 0DH 0D
74E6H: 0DH, the end of the line and of the text.
74E7-750E
DEFM "*** The target drive is a hard disk! ***" 2A 2A 2A 20 54 68 65 20 74 61 72 67 65 74 20 64 72 69 76 65 20 69 73 20 61 20 68 61 72 64 20 64 69 73 6B 21 20 2A 2A 2A
74E7H-750EH: the first line of the text of 61B3H.
750F
DEFB 0AH 0A
750FH: 0AH, a new line between the two lines of the text.
7510-7534
DEFM "Are you sure you want to format it ? " 41 72 65 20 79 6F 75 20 73 75 72 65 20 79 6F 75 20 77 61 6E 74 20 74 6F 20 66 6F 72 6D 61 74 20 69 74 20 3F 20
7510H-7534H: the question of 61B3H and, on its own, of 70CFH.
7535
DEFB 03H 03
7535H: 03H, the end of the question: the cursor stays for the reply.
7536-753D
DEFM "LDOSDISK" 4C 44 4F 53 44 49 53 4B
7536H-753DH: LDOSDISK, the default diskette name (6DEBH). The 1992 manual (M-40-060) gives DOSDISK.
753E-7545
DEFM "PASSWORD" 50 41 53 53 57 4F 52 44
753EH-7545H: PASSWORD, the default master password (6E2EH).
7546-7565
DEFB 00H x 32 00 x 32
7546H-7565H: 32 bytes of 00H at the end of the file. No code addresses them.