TRSDOS v2.3 Disassembled – FORMAT/CMD

This is a disassembly of TRSDOS v2.3’s FORMAT/CMD File.

The FORMAT process is mostly about building a directory track, so an understanding of the TRSDOS v2.3 directory structure is important.

There are three files which MUST be in specifical locations on a TRSDOS v2.3 disk: BOOT/SYS, SYS0/SYS, and DIR/SYS. BOOT/SYS must start at Track 0, Sector 0. SYS0/SYS must start at Track 0, Sector 5. DIR/SYS must start at Track 17 (11H) and go for 10 consecutive sectors.

The directory is 10 sectors. The first sector (sector 0) is the Granule Allocation Table, or GAT. The second sector (sector 1) is the Hash Code Index Table, or HIT. The remaining 8 sectors are for the actual files.

  • The GAT sector contains all the information needed to let DOS allocate space for files. The sector covers assigned/unassigned granules, locked out granules, the master disk password, the disk name and date, and the AUTO command, if any.
    The first 35 bytes of the GAT, representing tracks 00-34, contain either FF, FE, FD, ar FC.
    • FF = the first and second granules are allocated (all 10 sectors)
    • FE = the second granule is allocated (sectors 5-9)
    • FD = the first granule is allocated (sectors 0-4)
    • FC = no granules allocated (all sectors are free)
    Byte 60 and on is the track lockout table, with FC meaning Track Available and FF meaning Track is Locked Out
    Bytes CE-CF are the master disk password hash.
    Bytes D0-DF is the disk name and backup date
    Bytes E0-FF are the AUTO command, with the note that if E0H contains an 0DH then the AUTO command will NOT execute.
  • The HIT sector contains the program name hash code and the corresponding location in the remaining 8 sectors for the relevant information about that file. The program filename’s hash will appear on columns 01-08 to signify where in the 8 remaining sectors the file’s information can be found. Columns 9-16 are not used.
  • The rest of the sectors (2-9), called the FPDE (File Primary Directory Entry)/DXDE (File Extension Directory Entry) include the file type, entry status, space availability status, the End of File number, the logocal record length, the filename and extension, the passwords, the number of sectors assigned to the file, the file extents, the track and sector location of the start of the file, the number of continguous sectors in the extent, and the entry type. Each sector has 8 entries (00-1F, 20-3F, 40-5F, …, E0-FF).
    • Byte 00 = Bit Record: Bits 0-2 = 3 Bit Protection Level, Bit 3 = Visible [0] or Invisible [1], Bit 4 = Assigned [1], Bit 5 = Not Used, Bit 6 = System File [1], Bit 7 = Primary [0] or Extended [1]
    • Byte 01 = Not used if this is a FPDE (and will be 00H). If this is a FXDE then it is the DEC pointing back to the FPDE.
    • Byte 02 = Not used
    • Byte 03 = Relative position of the last byte of the program in the EOF sector (i.e., how many bytes in on the final sector)
    • Byte 04 = Logical Record Length (0-255). TRSDOS v2.3 does not use this byte, so it is normally 00H.
    • Bytes 05-0C = Filename. The “/” is not stored.
    • Bytes 0D-0F = Extension
    • Bytes 10-11 = Hash of UPDATE password
    • Bytes 12-13 = Hash of ACCESS password
    • Bytes 14-15 = EOF Relative Sector. If the EOF byte = 00H, then this is the ACTUAL relative sector count. If the EOF byte is NOT 00H, then this is the relative sector count + 1.
    • Bytes 16-17 = Extent 1
    • Bytes 18-19 = Extent 2
    • Bytes 1A-1B = Extent 3
    • Bytes 1C-1D = Extent 4
    • Bytes 1E-1F = Extent 5
5200H
DI
Disable Interrupts.
5201H
LD SP,41FCH
Set the STACK POINTER to 41FCH.
5204H
PUSH HL
Save the contents of Register Pair HL to the top of the stack.
5205H
LD A,(4030H)
Fetch the OPCODE at 4030H and store it into Register A. This would normally the the opcode LD A,n. 4030H is the is the address DOS jumps to at DOS READY to load the command interpreter (SYS1/SYS).
5208H
CP C7H
Compare the value held in Register A against C7H / (Binary:1100 0111).. Results:
  • If Register A equals C7H/199, the Z FLAG is set.
  • If A < C7H/199/, the CARRY FLAG will be set.
  • if A >= C7H/199/, the NO CARRY FLAG will be set.
520AH
If the Z FLAG (Zero) has been set, JUMP to the next routine at 521CH.
520CH
LD A,(430FH)
Fetch the byte at 430FH and put it into register A. 430FH is used by TRSDOS 2.3 to track certain system conditions.
  • If Bit 4 is set, then SYS6/SYS is loaded in RAM (and can be called by RST 28H).
  • If Bit 5 is set, then CHAINING is in effect.
  • If Bit 7 is set, then DEBUG was set to active.
520FH
BIT 5,A
Check to see if FORMAT was called as part of a BATCH FILE by testing Bit Number 5 of Register A. Z FLAG will be set if that bit is 0 (meaning, no batch file), and NZ FLAG will be set if that bit is 1 (meaning, batch file call).
5211H
If the Z FLAG (Zero) has been set then this was not called from a batch file, so JUMP to the next routine at 521CH.
5213H
LD HL,57C0H
If we are here, then FORMAT was called by in a batch file. Let Register Pair HL equal 57C0H which is the start of the message “FORMAT INVALID DURING PROGRAM CHAINING!” + 0DH.
5216H
GOSUB to 4467H.
NOTE: 4467H is a vector call to 44CFH which sends the message pointed to by HL to the video display. HL is preserved.
5219H
JUMP to 4030H.
NOTE: 4030H will load and execute the SYS1/SYS overlay with a Request Code of 2, so as to get the next command.

521CH – Continuing the FORMAT Routine now that we know that it was not called from a BATCH file.

521CH
LD HL,5E00H
Prepare to move 256 bytes from 5E00H to 4200H by first setting Register Pair HL to 5E00H. 5E00H-5EFF is holding the literal code for the BOOT sector of a TRSDOS v2.3 Disk
521FH
LD DE,4200H
Let Register Pair DE equal 4200H, which is the storage location for the System Sector Buffer Area
5222H
LD BC,0100H
Let Register Pair BC equal 0100H to move 256 bytes.
5225H
LDIR
Transfers a byte of data from the memory location pointed to by HL to the memory location pointed to by DE. Then HL and DE are incremented and BC is decremented. If BC is not zero, this operation is repeated. Interrupts can trigger while this instruction is processing.
5227H
LD HL,57E8H
Let Register Pair HL equal 57E8H so as to point to the message 1C + 1F + “TRSDOS DISK FORMATTER PROGRAM 2.3” + 0A + 0D.
522AH
GOSUB to 429AH (part of SYS0/SYS) to send the message pointed to by Register Pair HL to the video display.
522DH
POP HL
Restore HL from the STACK where it was put at the top of the FORMAT routine.
522EH
LD HL,580EH
Let Register Pair HL equal 580EH to point to the message WHICH DRIVE IS TO BE USED? + 03H.
5231H
GOSUB to 429AH (part of SYS0/SYS) to send the message pointed to by Register Pair HL to the video display.

We now need to fetch a single drive number from the user.

5234H
LD HL,5D00H
Let Register Pair HL equal 5D00H which will be where the keyboard entry is stored.
5237H
LD B,01H
Let Register B equal 01H to indicate that we are going to seek user input of ONE character.
5239H
GOSUB to 0040H.
NOTE: 0040H is the Model I ROM routine to wait for keyboard input of B characters and put store the character at (HL).
523CH
LD A,(HL)
Fetch the character which was just input by the user and store it into Register A for testing.
523DH
SUB 30H
SUBtract the value 30H from Register A. Note: Subtracting 30H from from Register A will convert an ASCII number ‘0’-‘9’ to its decimal equivalent (i.e., 6 in ASCII is 36H in Hex; so 36H-30H = 6). The Carry Flag will be affected.
523FH
If the C FLAG (Carry) has been set then we definitely don’t have a “0”-“3”, so JUMP BACK to 522EH to redisplay the prompt and ask again.
5242H
CP 04H
Compare the value held in Register A against 04H, which is also an invalid answer as is every number above it. Results:
  • If Register A equals 04H, the Z FLAG is set.
  • If A < 04H, the CARRY FLAG will be set.
  • if A >= 04H/4/, the NO CARRY FLAG will be set.
5244H
If the NC FLAG (No Carry) has been set then we got a number from the user over “3”, so JUMP BACK to 522EH to redisplay the prompt and ask again.

At this point we know we received either a “0”, “1”, “2”, or “3” as the drive number from the user; now we need to conver that into something we can use.

5247H
RLCA
Rotate the bits of Register left (i.e., lower bit moves higher) one bit position. The contents of bit 7 are copied to the CARRY FLAG and to bit 0.
5248H
RLCA
Rotate the bits of Register left (i.e., lower bit moves higher) one bit position. The contents of bit 7 are copied to the CARRY FLAG and to bit 0.
5249H
RLCA
Rotate the bits of Register left (i.e., lower bit moves higher) one bit position. The contents of bit 7 are copied to the CARRY FLAG and to bit 0.

These 3 RLCAS turn a “0” into an 00H, “1” into an 08H, a “2” into a 10H, and a “3” into 0CH.

524AH
OR C7H
OR Register A against C7H (Binary 1100 0111) to turn on bits 0, 1, 2, 6, and 7.

That OR C7H turns a “0” into C7H, a “1” into CFH, a “2” into D7H, and a “3” into DFH.

524CH
LD (5251H),A
Store the value held in Register A into memory location 5251H.
524FH
XOR A
Set Register A to ZERO and clear all Flags.
5250H
SET n,A
While this is coded as SET 0,A, the n actually changes to 0-3 based on the users entry of a drive number. This means A becomes 01H for a “0”, 02H for a “1”, 04H for a “2”, and 08H for a “3”
5252H
LD (5768H),A
Store the value held in Register A (00, 02, 04, or 08 corresponding to a choice of drive “0”, “1”, “2”, or “3”) into memory location 5768H which is part of a routine which sends that code to the disk drive select latch address and RETurns.
5255H
GOSUB to 5767H to send a nnH to the disk drive select latch address and RETurn.
5258H
GOSUB to 5754H to send a RESTORE/LOAD HEAD to the Floppy Drive and then keep checking the floppy drive controller status until the drive is not BUSY, at which point the routine RETurns.
525BH
LD BC,0000H
Let Register Pair BC equal 0000H which will be a delay count of approximately 3 seconds.
525EH
GOSUB to 0060H to delay for the length of BC * 14.66 microseconds and RETurn.
5261H
LD A,(37ECH)
Fetch the FDC’s status (which is mirrored to 37ECH) and store it into Register A.
5264H
BIT 0,A
Test Bit Number 0 of Register A. Bit 0 will be 1 if the drive is busy and 0 if it isn’t. Z FLAG will be set if that bit is 0, and NZ FLAG will be set if that bit is 1.
5266H
If the NZ FLAG (Not Zero) has been set, the drive is busy, so LOPP BACK to 5261H and keep checking until its not busy.
5268H
LD HL,586BH
Let Register Pair HL equal 586BH, to point to the message “DRIVE NOT READY” + 0DH.
526BH
BIT 7,A
Test Bit Number 7 of Register A, which will test for a drive status of NOT READY. Z FLAG will be set if that bit is 0 (meaning the drive is ready), and NZ FLAG will be set if that bit is 1 (meaning the drive is NOT ready).
526DH
If the NZ FLAG (Not Zero) has been set, then the drive is returning NOT READY, so JUMP to 56ADH to display HIT ENTER TO CONTINUE, loop until an ENTER is hit, and then HALT the system.
5270H
LD HL,5896H
Let Register Pair HL equal 5896H to point to the message “DRIVE NOT IN SYSTEM!” +0DH.
5273H
BIT 2,A
Test Bit Number 2 of Register A, which will test to see if the Read/Write head is at Track 0 or not. Z FLAG will be set if that bit is 0 (not positioned at track 0), and NZ FLAG will be set if that bit is 1 (positioned at track 0).
5275H
If the Z FLAG (Zero) has been set, meaning that the head is not positioned at track 0, JUMP to 56ADH to display HIT ENTER TO CONTINUE, loop until an ENTER is hit, and then HALT the system.
5278H
LD HL,582BH
Let Register Pair HL equal 582BH to point to the message “DISKETTE NAME ? ” + 03H.
527BH
GOSUB to 429AH (part of SYS0/SYS) to send the message pointed to by Register Pair HL to the video display.

The next instructions move the 8 spaces stored at 5778H to 5CD0H, which will be the buffer used to hold the DISK NAME the user enters.

527EH
LD HL,5778H
Let Register Pair HL equal 5778H to point to 8 spaces
5281H
LD DE,5CD0H
Let Register Pair DE equal 5CD0H which will be the storage buffer for the DISK NAME.
5284H
LD BC,0008H
Let Register Pair BC equal 0008H for an 8 character move.
5287H
LDIR
Transfers a byte of data from the memory location pointed to by HL to the memory location pointed to by DE. Then HL and DE are incremented and BC is decremented. If BC is not zero, this operation is repeated. Interrupts can trigger while this instruction is processing.
5289H
LD HL,5D00H
Let Register Pair HL equal 5D00H, which will be the buffer used by the ROM to accept keyboard input and store the keys entered.
528CH
LD B,08H
Let Register B equal 08H to tell the ROM routine at 0040H to capture 8 keystrokes into the buffer pointed to by Register Pair HL.
528EH
GOSUB to 0040H to get B characters from the keyboard and store them at (HL).
5291H
LD A,B
Copy the contents of Register B, which should be the number of characters actually received from the user, into Register A.
5292H
OR A
Since a LD command does not set any FLAGS, Set FLAGS based on the contents of Register A (and, in all events, clear the CARRY FLAG).
5293H
If the Z FLAG (Zero) has been set, meaning we didn’t get any user input, LOOP back to 5278H to display the prompt for DISK NAME and try again to get the disk name from the user.
5295H
LD C,B
If we are here, then we got SOME input from the user in response to the DISKETTE NAME prompt. Copy the contents of Register B (the number of characters entered) into Register C.
5296H
5296H
LD B,00H
Zero out Register B
5298H
LD DE,5CD0H
Let Register Pair DE equal 5CD0H, which the storage buffer for the DISK NAME.
529BH
LDIR
Transfers a byte of data from the memory location pointed to by HL to the memory location pointed to by DE. Then HL and DE are incremented and BC is decremented. If BC is not zero, this operation is repeated. Interrupts can trigger while this instruction is processing.
529DH
LD HL,583CH
Let Register Pair HL equal 583CH, which points to the message “CREATION DATE (MM/DD/YY) ? ” + 03H.
52A0H
GOSUB to 429AH to display the message pointed to by Register Pair HL

Set up to the creastion date, of 8 characters, from the user and store it at 5D00H

52A3H
LD HL,5D00H
Let Register Pair HL equal 5D00H, which will be the buffer used by the ROM to accept keyboard input and store the keys entered.
52A6H
LD B,08H
Let Register B equal 08H to signify that we want 8 characters of keyboard input from the user.
52A8H
GOSUB to 0040H.
NOTE: 0040H is the Model I ROM routine to wait for keyboard input of B characters and put store the character at (HL).
52ABH
LD A,B
Copy the number of keystrokes received from the user (held in Register B) into Register A.
52ACH
CP 08H
Compare the value held in Register A against 08H. Results:
  • If Register A equals 08H, the Z FLAG is set.
  • If A < 08H, the CARRY FLAG will be set.
  • if A >= 08H, the NO CARRY FLAG will be set.
52AEH
If we didn’t get exactly 8 characters the NZ FLAG (Not Zero) will have been set, so JUMP BACK to force the user to re-enter the information.
52B1H
LD A,(5D02H)
Fetch third key which the user pressed (held in memory location 5D02H) and store it into Register A.
52B4H
CP 2FH
Compare the value held in Register A against 2FH / (ASCII: /). Results: If Register A equals /, the Z FLAG is set; otherwise the NZ FLAG will be set.
52B6H
If the character was not the required /, the NZ FLAG (Not Zero) will have been set, so JUMP BACK to force the user to re-enter the information.
52B9H
LD A,(5D05H)
Fetch sixth key which the user pressed (held in memory location 5D05H) and store it into Register A.
52BCH
CP 2FH
Compare the value held in Register A against 2FH / (ASCII: /). Results: If Register A equals /, the Z FLAG is set; otherwise the NZ FLAG will be set.
52BEH
If the character was not the required /, the NZ FLAG (Not Zero) will have been set, so JUMP BACK to force the user to re-enter the information.

We are now going to move the user entered date to 5CD8H.

52C1H
LD C,B
Preserve Register B into Register C so we can use Register B again.
52C2H
LD B,00H
Zero out Register B.
52C4H
LD DE,5CD8H
Let Register Pair DE equal 5CD8H to point to the message “MM/DD/YY” + 0DH
52C7H
LD HL,5D00H
Let Register Pair HL equal 5D00H, which will be the buffer used by the ROM to accept keyboard input and store the keys entered.
52CAH
LDIR
Transfers a byte of data from the memory location pointed to by HL to the memory location pointed to by DE. Then HL and DE are incremented and BC is decremented. If BC is not zero, this operation is repeated. Interrupts can trigger while this instruction is processing.
52CCH
LD HL,5858H
Let Register Pair HL equal 5858H, to point to the message “MASTER PASSWORD ? ” + 03H
52CFH
GOSUB to 429AH (part of SYS0/SYS) to send the message pointed to by Register Pair HL to the video display.
52D2H
LD HL,5D00H
Let Register Pair HL equal 5D00H, which will be the buffer used by the ROM to accept keyboard input and store the keys entered.
52D5H
LD B,08H
Let Register B equal 08H, which is the maximum number of characters to fetch from the user.
52D7H
GOSUB to 0040H.
NOTE: 0040H is the Model I ROM routine to wait for keyboard input of B characters and put store the character at (HL).
52DAH
LD A,B
Copy the number of characters which the user entered in resopnse to the MASTER PASSWORD prompt, held in Register B, into Register A.
52DBH
OR A
Since a LD command does not set any FLAGS, Set FLAGS based on the contents of Register A (and, in all events, clear the CARRY FLAG).
52DCH
If the user didn’t enter any information then the Z FLAG (Zero) will have been set, so JUMP BACK to 52CCH to reprompt for the MASTER PASSWORD.

At this point, both A and B contain the number of characters the user entered for the MASTER PASSWORD, C contains 8 (which was the number of acceptable characters in a date), HL contains 5D00, and DE contains 401DH.

52DEH
EX DE,HL
EXchange the value stored in Register Pair HL with the value stored in Register Pair DE so that DE now points to the user entry buffer.
52DFH
ADD A,E
LET Register A = the number of characters typed in for the MASTER PASSWORD (held in Register A) + Register E (which is 00H). The Carry Flag will be affected.
52E0H
LD L,A
Copy the contents of Register A into Register L.
52E1H
LD A,D
Copy the contents of Register D (which is 52H) into Register A.
52E2H
ADC 00H
LET Register A = Register A + 00H. The Carry Flag will be affected.
52E4H
LD H,A
Copy the contents of Register A (which is 52H) into Register H. HL now points to 1 beyond the last letter entered as the MASTER PASSWORD in the buffer
52E5H
LD A,08H
Let Register A equal 08H.
52E7H
SUB B
LET Register A = Register A (which is the maximum number of possible characters for the master password, being 8) – Register B (which is the number of characters of the master password the user gave).
52E8H
LD B,A
Copy the contents of Register A into Register B. Now Register B also holds the number of characters the master password was short from 8. B is chosen because a DJNZ loop uses that as a counter.
52E9H
LD (HL),20H
To prepare to fill the unprovided characters, Store the value 20H / (ASCII: SPACE) into the memory location pointed to by Register Pair HL.
52EBH
INC HL
INCrement the value stored in Register Pair HL by 1 to point to the next location in the buffer where the master password is being stored.
52ECH
LOOP back to 52E9H to keep filling the remaining unprovided characters with blanks, reducing Register B each time, and continue to LOOP until Register B has been reduced to ZERO, in which case, continue with the next instruction.

At this point 5200H points to 8 characters of a master password; padded with spaces if need be.

52EEH
GOSUB to the next routine (2 instructions down), at 52F6H to hash the master password.
52F1H
LD (5CCEH),HL
Store the hashed master password (held in Register Pair HL) into memory location 5CCEH.
52F4H
JUMP to 5322H (i.e., over then next set of instructions, which is a subroutine) to continue processing.

52F6H – This subroutine will hash the master password into HL and RETurn.

52F6H
LD HL,FFFFH
Let Register Pair HL equal FFFFH.
52F9H
LD B,08H
Let Register B equal 08H.
52FBH
LD A,E
Copy the contents of Register E into Register A. On the first pass, E is 00H, so this zeroes out A.
52FCH
ADD 07H
LET Register A = Register A + 07H. The Carry Flag will be affected. On the first pass, A is now 07H, and the NC FLAG is set.
52FEH
LD E,A
Copy the contents of Register A into Register E.
52FFH
If the NC FLAG (No Carry) has been set, skip the next instruction and JUMP to 5302H.
5301H
INC D
If the CARRY FLAG was set, we need to also bump Register D, so INCrement the value stored in Register D by 1.
5302H
LD A,(DE)
Fetch the character held in the MASTER PASSWORD buffer (from last to first in this loop) held in the memory location pointed to by Register Pair DE and store it into Register A. For all examples below, it is assumed this was just a space. With this, on the first pass, this is 5D07H, which is the last character in an 8 character MASTER PASSWORD
5303H
PUSH DE
Save the contents of Register Pair DE (i.e., the pointer to character in the the master password being used to hash in this pass) to the top of the stack.
5304H
LD D,A
Copy the contents of Register A into Register D. On the first pass, this will upt a SPACE into Register D.
5305H
LD E,H
Copy the contents of Register H into Register E. On the first pass, this wil put a FFH into Register E.
5306H
LD A,L
Copy the contents of Register L into Register A. On the first pass, this wil put a FFH into Register A.

On the first pass, right now A=FF, B=08, C=08, D=20, E=FF, H=FF, and L=FF

5307H
AND 07H
MASK the value of Register A against 07H (0000 0111). This has the effect of turning off bits 7, 6, 5, 4, 3, leaving only bits 2, 1, 0 active. On the first pass, since A was FFH, this turns A into 07H (Binary 0000 0111)

The next 3 rotations take the lower 3 bits (which are the only ones which are still live, and moves them to the highest bits)

5309H
RRCA
Rotate the bits in A right (i.e., higher bit moves lower), with Bit 0 being copied to both the CARRY FLAG and Bit 7. On the first pass, this turns the 07H held in Register A into 83H (1000 0011).
530AH
RRCA
Rotate the bits in A right (i.e., higher bit moves lower), with Bit 0 being copied to both the CARRY FLAG and Bit 7. On the first pass, this turns the 83H held in Register A into C1H (1100 0001).
530BH
RRCA
Rotate the bits in A right (i.e., higher bit moves lower), with Bit 0 being copied to both the CARRY FLAG and Bit 7. On the first pass, this turns the C1H held in Register A into E0H (1110 0000).
530CH
XOR L
eXclusive OR Register L against Register A. The results are stored in Register A. On the first pass, L is FFH, so this turns 1110 0000 into 0001 1111 (which is 1F)
530DH
LD L,A
Copy the masked rotated contents of Register A into Register L.
530EH
LD H,00H
Let Register H equal 00H. On the first pass, this now has HL being 001FH.
5310H
ADD HL,HL
LET Register Pair HL = Register Pair HL + Register HL. The Carry Flag will be affected. On the first pass, HL is now 3E
5311H
ADD HL,HL
LET Register Pair HL = Register Pair HL + Register HL. The Carry Flag will be affected. On the first pass, HL is now 7C.
5312H
ADD HL,HL
LET Register Pair HL = Register Pair HL + Register HL. The Carry Flag will be affected. On the first pass, HL is now F8.
5313H
ADD HL,HL
LET Register Pair HL = Register Pair HL + Register HL. The Carry Flag will be affected. On the first pass, HL is now 01F0H.
5314H
XOR H
eXclusive OR Register H against Register A. The results are stored in Register A. On the first pass, H is 01H (0000 0001) and A is 1FH (0001 1111), so Register A becomes 1EH (0001 1110).
5315H
XOR D
eXclusive OR Register D against Register A. The results are stored in Register A. On the first pass, D is 20H (0010 0000) and A is 1EH (0001 1110), so Register A becomes 3EH (0011 1110).
5316H
LD D,A
Copy the contents of Register A into Register D. On the first pass, D now is 3EH.
5317H
LD A,L
Copy the contents of Register L into Register A. On the first pass, A is now 01H.
5318H
ADD HL,HL
LET Register Pair HL = Register Pair HL + Register HL. The Carry Flag will be affected. On the first pass, HL was 01F0H, so HL is now 03E0H.
5319H
XOR H
eXclusive OR Register H against Register A. The results are stored in Register A. On the first pass, H is 03H (0000 0011) and A is F0H (1111 0000) so A becomes F3 (1111 0011).
531AH
XOR E
eXclusive OR Register E against Register A. The results are stored in Register A. On the first pass, E is FFH (1111 1111) and A is F3H (1111 0011) so A becomes 0CH (0000 1100).
531BH
LD E,A
Copy the contents of Register A into Register E. On the first pass, E is now 0CH.
531CH
EX DE,HL
EXchange the value stored in Register Pair HL with the value stored in Register Pair DE. This swaps HL (which was 03E0H) with DE (which was 3E0CH).
531DH
POP DE
Put the value held at the top of the STACK into Register Pair DE, and then remove the entry from the stack. On the first pass, this was 5D07H which was the first character in the buffer after the stored MASTER PASSWORD.
531EH
DEC DE
DECrement the value stored in Register Pair DE by 1, so that DE now points to the prior character in the MASTER PASSWORD.
531FH
LOOP back to 5302H, reducing Register B each time, and continue to LOOP until Register B has been reduced to ZERO, in which case, continue with the next instruction.
5321H
RET
RETurn to the caller.

5322H – Continuation of the FORMAT command. Jumped here from 52F4H At this point, the DATE and MASTER PASSWORD have been entered, validated, and hashed. The DATE is at 5CD8H, the MASTER PASSWORD at 5D00H, the DISK NAME at 5CD0H, the DATE at 5CD8H, and the MASTER PASSWORD hash is at 5CCEH.

5C00H-5CCAH are all FFH at this point. The next instructions will fill bytes 5C00-5C22H with FCH.

5322H
LD HL,5C00H
Let Register Pair HL equal 5C00H to be used as a buffer.
5325H
XOR A
Set Register A to ZERO and clear all Flags.
5326H
LD (HL),0FCH
Store the value held in FCH into the memory location pointed to by Register Pair HL.
5328H
INC HL
INCrement the value stored in Register Pair HL by 1.
5329H
INC A
INCrement the value stored in Register A by 1.
532AH
CP 23H
Compare the value held in Register A against 23H (Decimal: 35). When A hits 23H the Z FLAG will be set.
532CH
If there haven’t been 35 bytes yet the NZ FLAG (Not Zero) will not have been set, so JUMP BACK to 5326H to keep filling with FC’s.

Once A hits 23H it will fall through here and fill with FFH’s A until it gets to CBH.

532EH
CP CBH
Compare the value held in Register A against CBH (Decimal: 203). When A hits CBH the Z FLAG will be set.
5330H
If the Z FLAG (Zero) has been set, JUMP to the next routine at 533EH to continue the FORMAT command.
5332H
LD (HL),FFH
Store the value held in FFH into the memory location pointed to by Register Pair HL.
5334H
INC HL
INCrement the value stored in Register Pair HL by 1.
5335H
INC A
INCrement the value stored in Register A by 1.
5336H
JUMP BACK to 532EH to keep filling with FF’s.

5338H – Not sequential. Jumped here from 536DH.

5338H
LD HL,5963H
Let Register Pair HL equal 5963H to point to the message “INVALID TRACK NUMBER!” + 0DH
533BH
GOSUB to 429AH (part of SYS0/SYS) to send the message pointed to by Register Pair HL to the video display.

Continuation of the FORMAT command. Jumped here from 5330H, which just filled the RAM from 5C00H to 5CCAH with FC’s or FF’s.

533EH
LD HL,5926H
Let Register Pair HL equal 5926H to point to the message “DO YOU WANT TO LOCK OUT ANY TRACKS? ” + 03H
5341H
GOSUB to 429AH (part of SYS0/SYS) to send the message pointed to by Register Pair HL to the video display.
5344H
LD HL,5D00H
Let Register Pair HL equal 5D00H, which will be the buffer used by the ROM to accept keyboard input and store the keys entered.
5347H
LD B,03H
Let Register B equal 03H to signify that we will take 3 or fewer characters
5349H
GOSUB to 0040H.
NOTE: 0040H is the Model I ROM routine to wait for keyboard input of B characters and put store the character at (HL).
534CH
LD A,(HL)
Fetch the first character which the user provided and store it into Register A.
534DH
CP 59H
Compare the value held in Register A against 59H (ASCII: Y). If the user typed a Y, the Z FLAG is set.
534FH
If the user did not type a Y then the NZ FLAG (Not Zero) will have been set, so JUMP to 539EH to bypass the outine which processes the request to lock out tracks.

If we are here, the user said YES to DO YOU WANT TO LOCK OUT ANY TRACKS, so now we have to process that.

5351H
LD HL,594CH
Let Register Pair HL equal 594CH to point to the message “WHICH TRACKS (1-34)? ” + 03H.
5354H
GOSUB to 429AH (part of SYS0/SYS) to send the message pointed to by Register Pair HL to the video display.
5357H
LD HL,5D00H
Let Register Pair HL equal 5D00H, which will be the buffer used by the ROM to accept keyboard input and store the keys entered.
535AH
LD B,1EH
Let Register B equal 1EH (Decimal: 30) to signify that we will accept 30 or fewer characters.
535CH
GOSUB to 0040H.
NOTE: 0040H is the Model I ROM routine to wait for keyboard input of B characters and put store the character at (HL).
535FH
GOSUB to 5733H to parse a memory buffer pointed to by Register Pair HL and accumulate the number held at that buffer into Register E. Once it hits a character not “0” to “9” it will RETurn, presumably when the “-” is hit.
5362H
LD D,E
Preserve the contents of Register E into Register D since we will be using E again on the same math routine.
5363H
CP 2DH
Compare the value held in Register A against 2DH (ASCII: ) to see if that was the current character when parsed. If it is NOT a , NZ will be set
5365H
If the NZ FLAG (Not Zero) has been set, then we had a character which was not “0”-“9” and also not , meaning that we have nothing left to parse, so JUMP to 536AH.

If we are here, then we found a “-” so we need to parse the second set of numbers.

5367H
GOSUB to 5733H to parse a memory buffer pointed to by Register Pair HL and accumulate the number held at that buffer into Register E.
536AH
EX AF,AF’
Preserve A and the FLAGS by swapping Register Pair AF’ with AF.
536BH
LD A,D
Copy the contents of Register D (which is holding the value of the first track to lock out) into Register A.
536CH
OR A
Since a LD command does not set any FLAGS, Set FLAGS based on the contents of Register A (and, in all events, clear the CARRY FLAG).
536DH
If the Z FLAG (Zero) has been set then the user had started the track lockout with 00, which cannot work. With this, LOOP BACK to the top of this routine at 5338H to say that an invalid track was provided, and start the process again.
536FH
CP 23H
Compare the value held in Register A against 23H (Decimal: 35). Results:
  • If Register A equals 35, the Z FLAG is set.
  • If A < 35, the CARRY FLAG will be set.
  • if A >= 35, the NO CARRY FLAG will be set.
5371H
If the NC FLAG (No Carry) has been set then the user had started the track lockout with 35, which cannot work. With this, LOOP BACK to the top of this routine at 5338H to say that an invalid track was provided, and start the process again.
5373H
LD A,E
Copy the contents of Register E (which is the value of the last track to lock out) into Register A.
5374H
CP 23H
Compare the value held in Register A against 23H (Decimal: 35). Results:
  • If Register A equals 35, the Z FLAG is set.
  • If A < 35, the CARRY FLAG will be set.
  • if A >= 35, the NO CARRY FLAG will be set.
5376H
If the NC FLAG (No Carry) has been set then the user had set the last track lockout with 35, which cannot work. With this, LOOP BACK to the top of this routine at 5338H to say that an invalid track was provided, and start the process again.
5378H
SUB D
LET Register A = Register A (the last track to lock out) – Register D (the first track to lock out).
5379H
If the C FLAG (Carry) has been set, the the last track to lock out is BEFORE the first track to lock out, which cannot work. With this, LOOP BACK to the top of this routine at 5338H to say that an invalid track was provided, and start the process again.
537BH
INC A
INCrement the value stored in Register A by 1 to set Register A to the actual number of tracks to be locked out.
537CH
LD B,A
Copy the contents of Register A (the actual number of tracks to be locked out) into Register B. Register B is the loop counter for a DJNZ loop.
537DH
PUSH HL
Save the contents of Register Pair HL to the top of the stack so we can use HL for the following loop. It will be POP’d back at 5386H.

Start of a DJNZ loop to put FFH’s into the locations at 5CxxH which represent the tracks to be locked out.

537EH
LD L,D
Copy the contents of Register D (the first track to lock out) into Register L.
537FH
LD H,5CH
Let Register H equal 5CH. With this HL will point to an offset from 5C00H, which is the representation of the GAT table of the disk being formatted.
5381H
LD (HL),FFH
Store the value held in FFH into the memory location pointed to by Register Pair HL.
5383H
INC HL
INCrement the value stored in Register Pair HL by 1.
5384H
LOOP back to 5381H, reducing Register B each time, and continue to LOOP until Register B has been reduced to ZERO, in which case, continue with the next instruction.

At this point, a FFH has been placed in 5Css (starting track to lock out) to 5cee (ending track to lock out) .

5386H
POP HL
Restore HL from the stack.
5387H
EX AF,AF’
Restore Register A from the Stack. This will restore A from what it was when the routine at 5733H returned.
5388H
CP 0DH
Compare the value held in Register A against 0DH (ASCII: CARRIAGE RETURN). If Register A equals CARRIAGE RETURN, the Z FLAG is set; otherwise the NZ FLAG is set.
538AH
If the NZ FLAG (Not Zero) has been set, and we didn’t have a CARRIAGE RETURN, JUMP BACK to 535FH to keep processing the line identifying the tracks to skip.

If we are here, then we have finished processing the DO YOU WANT TO LOCK OUT TRACKS / WHICH TRACKS routines.

538CH
LD HL,5979H
Let Register Pair HL equal 5979H to point to the message “FORMAT THE LOCKED OUT TRACKS? ” + 03H
538FH
GOSUB to 429AH (part of SYS0/SYS) to send the message pointed to by Register Pair HL to the video display.
5392H
LD HL,5D00H
Let Register Pair HL equal 5D00H, which will be the buffer used by the ROM to accept keyboard input and store the keys entered.
5395H
LD B,03H
Let Register B equal 03 to indicate to accept 3 or fewer characters from the user.
5397H
GOSUB to 0040H.
NOTE: 0040H is the Model I ROM routine to wait for keyboard input of B characters and put store the character at (HL).
539AH
LD A,(HL)
Fetch the value held in the memory location pointed to by Register Pair HL (which will be the first character the user typed in response to FORMAT THE LOCKED OUT TRACKS) and store it into Register A.
539BH
LD (548DH),A
Store the value held in Register A into memory location 548DH. This will trigger a break in that routine if it is 59H
539EH
GOSUB to 5767H to send a nnH to the disk drive select latch address and RETurn.
53A1H
LD BC,0000H
Let Register Pair BC equal 0000H.
53A4H
GOSUB to 0060H to delay for the length of BC * 14.66 microseconds and RETurn.
53A7H
LD A,(37ECH)
Fetch the FDC’s status (which is mirrored to 37ECH) and store it into Register A.
53AAH
LD HL,586BH
Let Register Pair HL equal 586BH to point to the message “DRIVE NOT READY” + 0DH.
53ADH
BIT 7,A
Test Bit Number 7 of Register A to see if the Floppy Disk Controller response (held in Register A) was “NOT READY” (1=Not Ready, 0=Ready). Z FLAG will be set if that bit is 0, and NZ FLAG will be set if that bit is 1.
53AFH
If the NZ FLAG (Not Zero) has been set, then the controller returned NOT READY, so JUMP to 56ADH to display HIT ENTER TO CONTINUE, loop until an ENTER is hit, and then HALT the system.
53B2H
LD HL,5896H
Let Register Pair HL equal 5896H to point to the message “DRIVE NOT IN SYSTEM!” +0DH.
53B5H
BIT 2,A
Test Bit Number 2 of Register A to see if the Floppy Disk Controller response (held in Register A) was “TRACK 0” (1=Positioned at TRACK 0, 0=Not Positioned at TRACK 0). Z FLAG will be set if that bit is 0, and NZ FLAG will be set if that bit is 1.
53B7H
If the Z FLAG (Zero) has been set, then the controller returned NOT POSITIONED AT TRACK 0, so JUMP to 56ADH, so JUMP to 56ADH to display HIT ENTER TO CONTINUE, loop until an ENTER is hit, and then HALT the system.
53BAH
LD HL,587CH
Let Register Pair HL equal 587CH, to point to the message “WRITE PROTECTED DISKETTE!”+ 0DH
53BDH
BIT 6,A
Test Bit Number 6 of Register A to see if the Floppy Disk Controller response (held in Register A) was “PROTECTED” (1=Write Protected, 0=Not Write Protected). Z FLAG will be set if that bit is 0, and NZ FLAG will be set if that bit is 1.
53BFH
If the NZ FLAG (Not Zero) has been set, then the controller returned WRITE PROTECTED, so JUMP to 56ADH, so JUMP to 56ADH to display HIT ENTER TO CONTINUE, loop until an ENTER is hit, and then HALT the system.

If we are here, then Floppy Disk Controller did not return any error response codes, so we can continue.

53C2H
LD BC,00CDH
Let Register Pair BC equal 00CDH (Decimal: 205).
53C5H
LD HL,58ABH
Let Register Pair HL equal 58ABH to point to the message “NO DISKETTE IN DRIVE!” + 0DH

Set up for the next disk-in-drive-and-ready test. This will count down from 204 to 0 to test for a DISKETTE IN DRIVE.

53C8H
DEC BC
DECrement the value stored in Register Pair BC by 1.
53C9H
53CAH
LD A,B
OR C
Since the Z-80 cannot test Register Pair BC against zero, the common trick is to set Register A to equal to Register B, and then OR A against Register C. Only if both Register B and Register C were zero can the Z FLAG be set.
53CBH
If the Z FLAG (Zero) has been set then we have unsuccessfully timed out, JUMP to 56ADH to display HIT ENTER TO CONTINUE, loop until an ENTER is hit, and then HALT the system.
53CEH
LD A,(37ECH)
Fetch the FDC’s status (which is mirrored to 37ECH) and store it into Register A.
53D1H
AND 02H
MASK the value of Register A against 02H (0000 0010). This has the effect of turning off bits 7, 6, 5, 4, 3, 2, 0, leaving only bit 1 active. Bit 1 is the INDEX FOUND response.
53D3H
If the NZ FLAG (Not Zero) has been set, meaning it found the index hole, LOOP BACK to to 53C8H.

Set up for the next disk-in-drive-and-ready test. This will count down from 6557 to 0 to test for DOOR OPEN.

53D5H
LD BC,199DH
Let Register Pair BC equal 199DH (Decimal: 6557).
53D8H
LD HL,58C1H
Let Register Pair HL equal 58C1H, to point to the message “DOOR NOT CLOSED ON DRIVE!” + 0DH
53DBH
DEC BC
DECrement the value stored in Register Pair BC by 1.
53DCH
53DDH
LD A,B
OR C
Since the Z-80 cannot test Register Pair BC against zero, the common trick is to set Register A to equal to Register B, and then OR A against Register C. Only if both Register B and Register C were zero can the Z FLAG be set.
53DEH
If the Z FLAG (Zero) has been set then we ran out tries, so JUMP to 56ADH to display HIT ENTER TO CONTINUE, loop until an ENTER is hit, and then HALT the system.
53E1H
LD A,(37ECH)
Fetch the FDC’s status (which is mirrored to 37ECH) and store it into Register A.
53E4H
AND 02H
MASK the value of Register A against 02H (0000 0010). This has the effect of turning off bits 7, 6, 5, 4, 3, 2, 0, leaving only bit 1 active. Bit 1 is the INDEX FOUND response.
53E6H
If the Z FLAG (Zero) has been set, LOOP BACK to 53DBH to decrement the BC counter and try again.

Set up for the next disk-in-drive-and-ready test. This will count down from 186 to 0 to test for a DISKETTE IN DRIVE.

53E8H
LD DE,0000H
Let Register Pair DE equal 0000H. DE will be a counter up
53EBH
LD BC,00BAH
Let Register Pair BC equal 00BAH (Decimal: 186). BC will be a try counter down.
53EEH
LD HL,58ABH
Let Register Pair HL equal 58ABH to point to the message “NO DISKETTE IN DRIVE!” + 0DH
53F1H
DEC BC
DECrement the value stored in Register Pair BC by 1.
53F2H
53F3H
LD A,B
OR C
Since the Z-80 cannot test Register Pair BC against zero, the common trick is to set Register A to equal to Register B, and then OR A against Register C. Only if both Register B and Register C were zero can the Z FLAG be set.
53F4H
If the Z FLAG (Zero) has been set then we have unsuccessfully timed out, JUMP to 56ADH to display HIT ENTER TO CONTINUE, loop until an ENTER is hit, and then HALT the system.
53F7H
INC DE
INCrement the value stored in Register Pair DE by 1.
53F8H
LD A,(37ECH)
Fetch the FDC’s status (which is mirrored to 37ECH) and store it into Register A.
53FBH
AND 02H
MASK the value of Register A against 02H (0000 0010). This has the effect of turning off bits 7, 6, 5, 4, 3, 2, 0, leaving only bit 1 active. Bit 1 is the INDEX FOUND response.
53FDH
If the NZ FLAG (Not Zero) has been set, LOOP BACK to 53F1H to decrement the BC counter and try again.

Set up for the next disk-in-drive-and-ready test. This will count down from 5920 to 0 to test for DOOR OPEN.

53FFH
LD BC,1720H
Let Register Pair BC equal 1720H (Decimal: 5920).
5402H
LD HL,58C1H
Let Register Pair HL equal 58C1H, to point to the message “DOOR NOT CLOSED ON DRIVE!” + 0DH
5405H
DEC BC
DECrement the try counter stored in Register Pair BC by 1.
5406H
5407H
LD A,B
OR C
Since the Z-80 cannot test Register Pair BC against zero, the common trick is to set Register A to equal to Register B, and then OR A against Register C. Only if both Register B and Register C were zero can the Z FLAG be set.
5408H
If the Z FLAG (Zero) then we ran out tries, so JUMP to 56ADH to display HIT ENTER TO CONTINUE, loop until an ENTER is hit, and then HALT the system.
540BH
INC DE
INCrement the counter stored in Register Pair DE by 1.
540CH
LD A,(37ECH)
Fetch the FDC’s status (which is mirrored to 37ECH) and store it into Register A.
540FH
AND 02H
MASK the value of Register A against 02H (0000 0010). This has the effect of turning off bits 7, 6, 5, 4, 3, 2, 0, leaving only bit 1 active. Bit 1 is the INDEX FOUND response.
5411H
If the Z FLAG (Zero) has been set, meaning no INDEX MARKER FOUND, LOOP BACK to 5405H to decrement the BC counter and try again.
5413H
LD HL,EACBH
Let Register Pair HL equal to EACBH as the start of an offset.
5416H
ADD HL,DE
LET Register Pair HL = Register Pair HL + Register DE. The Carry Flag will be affected.
5417H
LD HL,58DBH
Let Register Pair HL equal 58DBH to point to the message “DISKETTE UNUSABLE! HARD-SECTORED!” + 0DH
541AH
If EACBH (held in HL) + DE does NOT trigger a CARRY, then NC FLAG (No Carry) will have been set, so JUMP to 56ADH to display HIT ENTER TO CONTINUE, loop until an ENTER is hit, and then HALT the system.
541DH
GOSUB to 5767H to send a nnH to the disk drive select latch address and RETurn.
5420H
LD BC,5D00H
Let Register Pair BC equal 5D00H, which will be the buffer used by this routine.
5423H
LD DE,0000H
Let Register Pair DE equal 0000H.
5426H
GOSUB to 42AAH to read a sector from the disk. D must hold the track, E must hold the sector, and BC must point to the start of the memory buffer to hold the sector data. On exit, Register A holds the FDC Status.
5429H
If the Z FLAG (Zero) has been set then that CALL exited successfully, so next GOSUB to 5B9CH to display “DISKETTE CONTAINS DATA, FORMAT OR NOT?” message and get a “Y” or “N” from the user. Jump to 56B0H for a NO and RETurn for a YES.
542CH
NOP
No Operation (Do Nothing).
542DH
NOP
No Operation (Do Nothing).
542EH
NOP
No Operation (Do Nothing).
542FH
LD H,5CH
Let Register H equal 5CH, which MSB of the in-RAM representation of the GAT table of the disk being formatted.
5431H
LD L,11H
Let Register L equal 11H.
5433H
LD C,00H
Let Register C equal 00H which will be a counter/offset in the table at 5Dnn.

Top of a loop of 35 tracks to look for the directory track.

5435H
LD A,(HL)
Fetch the value held in the memory location pointed to by Register Pair HL and store it into Register A.
5436H
CP FCH
Compare the value held in Register A against FCH. If Register A equals FCH the Z FLAG is set.
5438H
If a FCH was found at (HL), then the Z FLAG (Zero) will been set, and we have identified the Directory Track (now held in Register A), so continue via a JUMP to 5452H.
543AH
INC C
If a FCH was not found, INCrement the counter stored in Register C by 1.
543BH
LD A,C
Copy the contents of Register C into Register A so that math can be done on it.
543CH
RRCA
Rotate the bits in A right (i.e., higher bit moves lower), with Bit 0 being copied to both the CARRY FLAG and Bit 7. This is done to trigger a C or NC.
543DH
LD A,L
Copy the contents of Register L (which is the current track location in the 5Cnn lookup table) into Register A.
543EH
If the NC FLAG (No Carry) has been set, JUMP to 5448H to break out of this loop and continue.
5440H
ADD A,C
LET Register A = Register A (which is the current track location in the 5Cnn lookup table) + Register C. .
5441H
LD L,A
Copy the contents of Register A into Register L, which then moves the HL pointer forward C units.
5442H
CP 23H
Compare the value held in Register A (which is the current track location in the 5Cnn lookup table) against 23H (Decimal: 35). If Register A had not yet hit 35 tracks the NZ FLAG will be set
5444H
If the NZ FLAG (Not Zero) has been set, LOOP BACK to 5435H and keep processing tracks until 35 is hit.
5446H
Continue in the next routine via a JUMP to 544CH.

5448H – Continuation of FORMAT routine. On entry, Register A is holding the offset into 5Cnn for the byte being worked on.

5448H
SUB C
LET Register A = Register A – Register C to back out the last ADDITION from 5440H.
5449H
LD L,A
Copy the contents of Register A into Register L to udpate the which is the current track location in the 5Cnn lookup table.
544AH
If the subtraction of C from A did not result in a 0, the NZ FLAG (Not Zero) has been set, JUMP to 5435H to keep processing tracks.

This is a jump point from 5446H when all 35 tracks have been checked for FC vs FF

544CH
LD HL,5998H
Let Register Pair HL equal 5998H to point to the message “CAN’T FORMAT, NO TRACKS AVAILABLE FOR DIRECTORY!” + 0DH
544FH
JUMP to 56ADH to display HIT ENTER TO CONTINUE, loop until an ENTER is hit, and then HALT the system.

5452H – Continuation of FORMAT routine. Jumped here from 5438H if a FCH byte is found when scanning 5Cnn. The Directory Track to be used is held in A

5452H
LD A,L
Copy the contents of Register L (which is the current track location in the 5Cnn lookup table) into Register A so that it can be put into 4202H as the directory track.
5453H
LD (4202H),A
Store the value held in Register A into memory location 4202H.
NOTE: 4202H is the where TRSDOS 2.3 stores the Directory Track Number.
5456H
GOSUB to 5726H to to set Registers C and B to the ASCII bumber corresponding to Register A (Tens Digit in ASCII to C and Ones Digit in ASCII to B). Assuming everything is normal, A=11H and HL=5C11H before the CALL.
5459H
LD (59EBH),BC
Store the value held in Register Pair BC into memory location 59EBH which is in the “nn” of the stored message “DIRECTORY WILL BE PLACED ON TRACK nn”.
545DH
LD HL,59C9H
Let Register Pair HL equal 59C9H to point to the message “DIRECTORY WILL BE PLACED ON TRACK 00” + 0DH
5460H
GOSUB to 429AH (part of SYS0/SYS) to send the message pointed to by Register Pair HL to the video display.
5463H
XOR A
Set Register A to ZERO and clear all Flags. A will be holding the current track being formatted.
5464H
LD (54B1H),A
Store the value held in Register A into memory location 54B1H. 54B1H is the nn in an opcode LD C,nn.
5467H
LD A,(54B1H)
Fetch the value held in memory location 54B1H and store it into Register A as the current track being formatted. 54B1H is the nn in an opcode LD C,nn.
546AH
GOSUB to 5726H to to set Registers C and B to the ASCII bumber corresponding to Register A (Tens Digit in ASCII to C and Ones Digit in ASCII to B).
546DH
LD (5A26H),BC
Store the value held in Register Pair BC into memory location 5A26H, which is the “nn” in the message “FORMATTING TRACK nn”.
5471H
LD HL,5A14H
Let Register Pair HL equal 5A14H to point to the message 1DH + “FORMATTING TRACK 00” + 03H
5474H
GOSUB to 429AH (part of SYS0/SYS) to send the message pointed to by Register Pair HL to the video display.
5477H
LD A,(54B1H)
Fetch the value held in memory location 54B1H (the current track being formatted) and store it into Register A. 54B1H is the nn in an opcode LD C,nn.
547AH
LD B,A
Copy the contents of Register A (the current track being formatted) into Register B.
547BH
LD A,(4202H)
Fetch the DIRECTORY TRACK NUMBER (which is stored at 4202H in TRSDOS v2.3) and put it into Register A.
547EH
CP B
Check to see if the current track being formatted is the directory track by comparing the value held in Register A against the value held in Register B.. Results:
  • If Register A equals the value held in Register B, the Z FLAG is set.
  • If A < B/23060/, the CARRY FLAG will be set.
  • if A >= B/23060/, the NO CARRY FLAG will be set.
547FH
LD B,FAH
Let Register B equal FAH which is a special TRSDOS flag byte It will be put where the “nn” is in the below pattern.
5481H
If we are currently formatting the directory track then the Z FLAG (Zero) will have been set, so JUMP to 5495H to create the below pattern.
5483H
LD L,A
Copy the contents of Register A (the directory track number) into Register L.
5484H
LD H,5CH
Let Register H equal 5CH, which MSB of the in-RAM representation of the GAT table of the disk being formatted. HL will now point to the directory track number in the track number table.
5486H
LD A,(HL)
Fetch the value held in the memory location pointed to by Register Pair HL (which is the 17th byte of the GAT Table, or the DIRECTORY TRACK) and store it into Register A.
5487H
INC A
INCrement the value stored in Register A by 1. If that entry was FC then Register A is now FD.
5488H
LD B,FBH
Let Register B equal FBH.
548AH
If the INC A instruction did not cause A to be 0 (meaning that it was not FFH), then NZ FLAG (Not Zero) will have been set, JUMP FORWARD to 5495H.
548CH
LD A,nnH
Let Register A equal nnH.
548EH
CP 59H
Compare the value held in Register A against 59H. If A is not 59H then the NZ FLAG will be set, otherwise the Z FLAG will be set.
5490H
If the NZ FLAG (Not Zero) has been set, JUMP to 5502H.
5493H
LD B,F9H
Let Register B equal F9H
5495H
LD A,B
Copy the contents of Register B into Register A. Note: B could be FAH (if jumped here from 5481H), FBH (if jumped here from 548AH), or F9H (if passed through)
5496H
LD (54DBH),A
Store the value held in Register A, whatever it might have been when jumped here, into memory location 54DBH. In the following chart, it is noted as the “nn” entry.

This next routine sets up the following fixed pattern in RAM:

5F00: FF FF FF FF  FF FF FF FF  FF FF FF FF  FF FF 00 00
5F10: 00 00 00 00  FE 00 00 00  01 F7 FF FF  FF FF FF FF
5F20: FF FF FF FF  FF FF 00 00  00 00 00 00  nn E5 E5 E5
5F30: E5 E5 E5 E5  E5 E5 E5 E5  E5 E5 E5 E5  E5 E5 E5 E5
...
6010: E5 E5 E5 E5  E5 E5 E5 E5  E5 E5 E5 E5  E5 E5 E5 E5
6020: E5 E5 E5 E5  E5 E5 E5 E5  E5 E5 E5 E5  E5 F7 FF FF
6030: FF FF FF FF  FF FF FF FF  FF FF 00 00  00 00 00 00
6040: FE 00 00 05  01 F7 FF FF  FF FF FF FF  FF FF FF FF
6050: FF FF 00 00  00 00 00 00  FB E5 E5 E5  E5 E5 E5 E5
6060: E5 E5 E5 E5  E5 E5 E5 E5  E5 E5 E5 E5  E5 E5 E5 E5
...
6140: E5 E5 E5 E5  E5 E5 E5 E5  E5 E5 E5 E5  E5 E5 E5 E5
6150: E5 E5 E5 E5  E5 E5 E5 E5  E5 F7 FF FF  FF FF FF FF
6160: FF FF FF FF  FF FF 00 00  00 00 00 00  FE 00 00 01
6170: 01 F7 FF FF  FF FF FF FF  FF FF FF FF  FF FF 00 00
6180: 00 00 00 00  FB E5 E5 E5  E5 E5 E5 E5  E5 E5 E5 E5
6190: E5 E5 E5 E5  E5 E5 E5 E5  E5 E5 E5 E5  E5 E5 E5 E5
...
6270: E5 E5 E5 E5  E5 E5 E5 E5  E5 E5 E5 E5  E5 E5 E5 E5
6280: E5 E5 E5 E5  E5 F7 FF FF  FF FF FF FF  FF FF FF FF
6290: FF FF 00 00  00 00 00 00  FE 00 00 06  01 F7 FF FF
62A0: FF FF FF FF  FF FF FF FF  FF FF 00 00  00 00 00 00
62B0: FB E5 E5 E5  E5 E5 E5 E5  E5 E5 E5 E5  E5 E5 E5 E5
...
63A0: E5 E5 E5 E5  E5 E5 E5 E5  E5 E5 E5 E5  E5 E5 E5 E5
63B0: E5 F7 FF FF  FF FF FF FF  FF FF FF FF  FF FF 00 00
63C0: 00 00 00 00  FE 00 00 02  01 F7 FF FF  FF FF FF FF
63D0: FF FF FF FF  FF FF 00 00  00 00 00 00  FB E5 E5 E5
63E0: E5 E5 E5 E5  E5 E5 E5 E5  E5 E5 E5 E5  E5 E5 E5 E5
...
64C0: E5 E5 E5 E5  E5 E5 E5 E5  E5 E5 E5 E5  E5 E5 E5 E5
64D0: E5 E5 E5 E5  E5 E5 E5 E5  E5 E5 E5 E5  E5 F7 FF FF
64E0: FF FF FF FF  FF FF FF FF  FF FF 00 00  00 00 00 00
64F0: FE 00 00 07  01 F7 FF FF  FF FF FF FF  FF FF FF FF
6500: FF FF 00 00  00 00 00 00  FB E5 E5 E5  E5 E5 E5 E5
6500: FF FF 00 00  00 00 00 00  FB E5 E5 E5  E5 E5 E5 E5
6510: E5 E5 E5 E5  E5 E5 E5 E5  E5 E5 E5 E5  E5 E5 E5 E5
...
65F0: E5 E5 E5 E5  E5 E5 E5 E5  E5 E5 E5 E5  E5 E5 E5 E5
6600: E5 E5 E5 E5  E5 E5 E5 E5  E5 F7 FF FF  FF FF FF FF
6600: E5 E5 E5 E5  E5 E5 E5 E5  E5 F7 FF FF  FF FF FF FF
6610: FF FF FF FF  FF FF 00 00  00 00 00 00  FE 00 00 03
6620: 01 F7 FF FF  FF FF FF FF  FF FF FF FF  FF FF 00 00
6630: 00 00 00 00  FB E5 E5 E5  E5 E5 E5 E5  E5 E5 E5 E5
...
6720: E5 E5 E5 E5  E5 E5 E5 E5  E5 E5 E5 E5  E5 E5 E5 E5
6730: E5 E5 E5 E5  E5 F7 FF FF  FF FF FF FF  FF FF FF FF
6740: FF FF 00 00  00 00 00 00  FE 00 00 08  01 F7 FF FF
6750: FF FF FF FF  FF FF FF FF  FF FF 00 00  00 00 00 00
6760: FB E5 E5 E5  E5 E5 E5 E5  E5 E5 E5 E5  E5 E5 E5 E5
6770: E5 E5 E5 E5  E5 E5 E5 E5  E5 E5 E5 E5  E5 E5 E5 E5
...
6850: E5 E5 E5 E5  E5 E5 E5 E5  E5 E5 E5 E5  E5 E5 E5 E5
6860: E5 F7 FF FF  FF FF FF FF  FF FF FF FF  FF FF 00 00
6870: 00 00 00 00  FE 00 00 04  01 F7 FF FF  FF FF FF FF
6880: FF FF FF FF  FF FF 00 00  00 00 00 00  FB E5 E5 E5
6890: E5 E5 E5 E5  E5 E5 E5 E5  E5 E5 E5 E5  E5 E5 E5 E5
...

5499H
LD HL,5F00H
Let Register Pair HL equal 5F00H. Im having trouble figuring out what this memory block is. It is 14 FF’s, 6 00H’s, 1 FEH, 1 counter of the current track being written/formatted, 2 00’s, 1 01H, 1 F7H, 12 FF’s, 6 00’s, 1 FBH, and the rest are E5’s.
549CH
LD DE,576DH
Let Register Pair DE equal 576DH, which is a RAM storage location. For purposes of this routine, it is the TRACK BEING FORMATTED.
549FH
LD B,0EH
Let Register B equal 0EH (Decimal: 14).
54A1H
GOSUB to 5749H which will set C = FFH and then do ‘put the FFH into (HL) and then BUMP HL by 1’ Register B times.
54A4H
LD B,06H
Let Register B equal 06H, to fill 6 bytes of (HL) with Register C
54A6H
LD C,00H
Let Register C equal 00H.
54A8H
GOSUB to 574BH to do a loop of ‘put the value held in Register C into (HL) and then BUMP HL by 1’ Register B times.
54ABH
LD C,FEH
Let Register C equal FEH.
54ADH
GOSUB to 5751H to store the value held in Register C into (HL) and then BUMP HL by 1.
54B0H
LD C,00H
Let Register C equal 00H. Note the nn is polled at 5467H, 5477H, 5502H and changed at 5464H and 5506H.
54B2H
GOSUB to 5751H to store the value held in Register C into (HL) and then BUMP HL by 1.
54B5H
LD C,00H
Let Register C equal 00H.
54B7H
GOSUB to 5751H to store the value held in Register C into (HL) and then BUMP HL by 1.
54BAH
LD A,(DE)
Fetch the value held in the memory location pointed to by Register Pair DE and store it into Register A.
54BBH
LD C,A
Copy the contents of Register A into Register C.
54BCH
GOSUB to 5751H to store the value held in Register C into (HL) and then BUMP HL by 1.
54BFH
LD C,01H
Let Register C equal 01H.
54C1H
GOSUB to 5751H to store the value held in Register C into (HL) and then BUMP HL by 1.
54C4H
LD C,F7H
Let Register C equal F7H.
54C6H
GOSUB to 5751H to store the value held in Register C into (HL) and then BUMP HL by 1.
54C9H
LD C,FFH
Let Register C equal FFH.
54CBH
GOSUB to 5751H to store the value held in Register C into (HL) and then BUMP HL by 1.
54CEH
LD B,0BH
Let Register B equal 0BH.
54D0H
GOSUB to 5749H which will set C = FFH and then do ‘put the FFH into (HL) and then BUMP HL by 1’ Register B times.
54D3H
LD B,06H
Let Register B equal 06H, to fill 6 bytes of (HL) with Register C
54D5H
LD C,00H
Let Register C equal 00H.
54D7H
GOSUB to 574BH to do a loop of ‘put the value held in Register C into (HL) and then BUMP HL by 1’ Register B times.
54DAH
LD C,nnH
Let Register C equal nnH. nnH was set at 5496H and will be either FAH, FBH, or F9H
54DCH
GOSUB to 5751H to store the value held in Register C into (HL) and then BUMP HL by 1.
54DFH
LD B,00H
Let Register B equal 00H, to fill 256 bytes of (HL) with Register C
54E1H
LD C,E5H
Let Register C equal E5H.
54E3H
GOSUB to 574BH to do a loop of ‘put the value held in Register C into (HL) and then BUMP HL by 1’ Register B times.
54E6H
LD C,F7H
Let Register C equal F7H.
54E8H
GOSUB to 5751H to store the value held in Register C into (HL) and then BUMP HL by 1.
54EBH
LD C,FFH
Let Register C equal FFH.
54EDH
GOSUB to 5751H to store the value held in Register C into (HL) and then BUMP HL by 1.
54F0H
LD B,0BH
Let Register B equal 0BH.
54F2H
GOSUB to 5749H which will set C = FFH and then do ‘put the FFH into (HL) and then BUMP HL by 1’ Register B times.
54F5H
INC DE
INCrement the value stored in Register Pair DE by 1.
54F6H
LD A,(DE)
Fetch the value held in the memory location pointed to by Register Pair DE and store it into Register A.
54F7H
INC A
INCrement the value stored in Register A by 1.
54F8H
If the NZ FLAG (Not Zero) has been set, JUMP to 54A4H and keep filling.
54FAH
LD B,5BH
Let Register B equal 5BH.
54FCH
GOSUB to 5749H which will set C = FFH and then do ‘put the FFH into (HL) and then BUMP HL by 1’ Register B times.
54FFH
GOSUB to 551FH to select the designated drive, trigger a write track with the code from the above routine, point DE at the address of the floppy drive controller status register, and then continue by jumping to 553BH.
5502H
LD A,(54B1H)
Fetch the value held in memory location 54B1H and store it into Register A. 54B1H is the nn in an opcode LD C,nn.
5505H
INC A
INCrement the value stored in Register A by 1.
5506H
LD (54B1H),A
Store the value held in Register A into memory location 54B1H. 54B1H is the nn in an opcode LD C,nn.
5509H
CP 23H
Compare the value held in Register A against 23H (Decimal: 35). If we are at track 35, set the Z FLAG
550BH
If the Z FLAG (Zero) has been set, JUMP way down to 556BH to the last routine of FORMAT – verifies the format, writes out the directory, and finished up.
550DH
LD A,5BH
Let Register A equal 5BH.
550FH
LD A,(37ECH)
Fetch the FDC’s status (which is mirrored to 37ECH) and store it into Register A.
5512H
5513H
5514H
5515H
PUSH AF
POP AF
PUSH AF
POP AF
Standard delay tactic to let the FDC catch up
5516H
LD A,(37ECH)
Fetch the FDC’s status (which is mirrored to 37ECH) and store it into Register A.
5519H
RRCA
Rotate the bits in A right (i.e., higher bit moves lower), with Bit 0 being copied to both the CARRY FLAG and Bit 7. This means that the CARRY flag will be the same as BIT 0 (which is the BUSY return code)
551AH
If the C FLAG (Carry) has been set then the FDC returned “BUSY”, so LOOP BACK to 5516H to keep polling until the FDC isn’t BUSY.
551CH
JUMP to 5467H to continue now that the FDC is not busy. I don’t get this. 5467H is also a JP,C so it can never trigger. This could have just as easily been a RET and saved some time.

551FH – Selects the designated drive, triggers a write track with the code from the above routine, point DE at the address of the floppy drive controller status register, and JUMP to 553BH.

551FH
GOSUB to 5523H, which selects the designated drive, triggers a write track with the code from the above routine, and points DE at the address of the floppy drive controller status register.
5522H
RET Z
If the Z FLAG (Zero) has been set, RETurn to the caller.
5523H
GOSUB to 5767H to send a nnH to the disk drive select latch address and RETurn.
5526H
LD BC,5F00H
Let Register Pair BC equal 5F00H to point to that all that code that was set up in the prior routine.
5529H
LD HL,37ECH
Let Register Pair HL equal 37ECH.
NOTE: 37ECH is the Floppy Disk Controller’s Command Status Register
552CH
LD (HL),F4H
Store the value held in F4H (Binary: 1111 0100) into the memory location pointed to by Register Pair HL. This sends: Write Track (1111 0n00), n = 15ms Delay (1),
552EH
LD DE,37EFH
Let Register Pair DE equal 37EFH.
NOTE: 37EFH is the Floppy Disk Controller’s Data Register (i.e., the byte to be written/read from disk).
5531H
5532H
5533H
5534H
PUSH BC
POP BC
PUSH BC
POP BC
4 Instruction Delay
5535H
DI
Disable Interrupts.
5536H
Continue via a JUMP to 553BH which will write out all that code to the diskette.

5538H – Check that the drive is ready, and write the byte pointed at by BC to the diskette.

5538H
RRCA
Rotate the bits in A right (i.e., higher bit moves lower), with Bit 0 being copied to both the CARRY FLAG and Bit 7. This will have the effect of moving the FDC’s BUSY FLAG to the CARRY FLAG
5539H
If the NC FLAG (No Carry) has been set, then the drive is NOT BUSY, so JUMP out of this loop to the next routine 5546H because the disk might be moving at the wrong speed. That routine will either declare “TRANSFER RATE TOO FAST,” “MOTOR FAST,” “MOTOR SLOW,” and HALT in those cases, or to just REturn.
553BH
LD A,(HL)
Fetch the value held in the memory location pointed to by Register Pair HL and store it into Register A. HL should be pointing to the Floppy Disk Controller Status, so this fetches the status of the drive.
553CH
BIT 1,A
Test Bit Number 1 of Register A, which is the INDEX register. Z FLAG will be set if that bit is 0, and NZ FLAG will be set if that bit is 1.
553EH
If the Z FLAG (Zero) has been set, then there is no index found, so JUMP to 5538H to move Bit 1 to Bit 0, and Bit 0 (the BUSY status) to the CARRY FLAG, and to then test the CARRY FLAG.
5540H
LD A,(BC)
Fetch the value held in the memory location pointed to by Register Pair BC (which is that block of code above) and store it into Register A.
5541H
LD (DE),A
Store the value held in Register A from the above table to the Floppy Drive by writing it to 37EFH (held in Register Pair DE).
5542H
INC BC
INCrement the value stored in Register Pair BC by 1 to point to the next byte in the above block of code.
5543H
KEEP WRITING via a JUMP BACK to 553BH.

5546H – Jumped here from 5539H if the INDEX/BUSY status isn’t quite right to either declare “TRANSFER RATE TOO FAST,” “MOTOR FAST,” “MOTOR SLOW,” and HALT in those cases, or to just REturn.

5546H
LD A,(HL)
Fetch the value from the Floppy Disk Controller Command/Status (pointed to by Register Pair HL) and store it into Register A.
5547H
LD (HL),D0H
Store the value held in D0H into the memory location pointed to by Register Pair HL. This will send a D0H (1101 0000): Reset; puts FDC in mode 1 (INTRQ; “000” terminate command without interrupt).
5549H
LD HL,5A29H
Let Register Pair HL equal 5A29H to point to the message 0AH + “CAN’T FORMAT, DISK TRANSFER RATE TOO FAST!” + 0DH
554CH
BIT 2,A
Test Bit Number 2 of Register A to see if the disk was at TRACK 0 or not (1=Yes, 0=No). Z FLAG will be set if that bit is 0, and NZ FLAG will be set if that bit is 1.
554EH
If the disk is NOT at Track 0 then the NZ FLAG (Not Zero) will have been set, JUMP to 56ADH to display HIT ENTER TO CONTINUE, loop until an ENTER is hit, and then HALT the system.

If the disk WAS at Track 0 despite the issues, then we need to figure out if it was too fast or too slow and if neither, then this routine RETurns. To do this, various numbers are added together to see if the CARRY FLAG trips or not.
Throughout all this math, A, B, and C never change. DE takes on its initial value at 5555H with an EX DE, HL and then stays the same the entire routine as well. Only HL and the flags change.

5551H
LD HL,A100H
Let Register Pair HL equal A100H.
5554H
ADD HL,BC
LET Register Pair HL = Register Pair HL + Register BC. The Carry Flag will be affected.
5555H
EX DE,HL
EXchange the value stored in Register Pair HL with the value stored in Register Pair DE.
5556H
LD HL,F413H
Let Register Pair HL equal F413H.
5559H
ADD HL,DE
LET Register Pair HL = Register Pair HL + Register DE. The Carry Flag will be affected.
555AH
LD HL,5A55H
Let Register Pair HL equal 5A55H to point to the message 0AH + “CAN’T FORMAT, MOTOR SPEED TOO SLOW!” + 0DH
555DH
If the NC FLAG (No Carry) has been set, JUMP to 56ADH to display HIT ENTER TO CONTINUE, loop until an ENTER is hit, and then HALT the system.

If we are here, then there is still something wrong with the INDEX/BUSY timing, but it wasn’t because the motor was too slow …

5560H
LD HL,F397H
Let Register Pair HL equal F397H.
5563H
ADD HL,DE
LET Register Pair HL = Register Pair HL + Register DE. The Carry Flag will be affected.
5564H
LD HL,5A7AH
Let Register Pair HL equal 5A7AH to point to the message 0AH + “CAN’T FORMAT, MOTOR SPEED TOO FAST!” + 0DH
5567H
If the C FLAG (Carry) has been set, JUMP to 56ADH to display HIT ENTER TO CONTINUE, loop until an ENTER is hit, and then HALT the system.
556AH
RET
RETurn to the caller.

556BH – Last Routine of FORMAT. This routine verifies the format, writes out the directory, and finished up.

We are done formatting, so now we need to display a CARRIAGE RETURN to move off of the “FORMATTING TRACK nn” overwriting message.

556BH
LD A,0DH
Let Register A equal 0DH (ASCII: CARRIAGE RETURN).
556DH
GOSUB to 0033H to display the character held in Register A at the current cursor position.

The next routine verifies the tracks.

5570H
LD D,00H
Let Register D equal 00H.
5572H
LD L,D
Copy the contents of Register D into Register L.
5573H
LD H,5CH
Let Register H equal 5CH, which MSB of the in-RAM representation of the GAT table of the disk being formatted. At this point, HL now points to the in-RAM GAT
5575H
LD A,(HL)
Fetch the byte from the in-RAM GAT (pointed to by Register Pair HL) and store it into Register A.
5576H
INC A
INCrement the value stored in Register A by 1 to make it easier to test to see if it was FFH or not.
5577H
If it was FFH, then the Z FLAG (Zero) will have been set, so JUMP to 55BDH.
557AH
LD A,D
If it wasn’t FFH then copy the contents of Register D into Register A.
557BH
GOSUB to 5726H to to set Registers C and B to the ASCII bumber corresponding to Register A (Tens Digit in ASCII to C and Ones Digit in ASCII to B).
557EH
LD (5AB0H),BC
Store the value held in Register Pair BC into memory location 5AB0H which is the xx of the “VERIFYING TRACK xx, SECTOR yy” message.
5582H
LD E,00H
Let Register E equal 00H.
5584H
PUSH DE
Temporarily save the contents of Register Pair DE to the top of the stack.
5585H
LD A,D
Copy the contents of Register D into Register A.
5586H
GOSUB to 5767H to send a nnH to the disk drive select latch address and RETurn.
5589H
LD A,E
Copy the contents of Register E into Register A.
558AH
GOSUB to 5726H to to set Registers C and B to the ASCII bumber corresponding to Register A (Tens Digit in ASCII to C and Ones Digit in ASCII to B).
558DH
LD (5ABBH),BC
Store the value held in Register Pair BC into memory location 5ABBH which is the yy of the “VERIFYING TRACK xx, SECTOR yy” message.
5591H
LD HL,5A9FH
Let Register Pair HL equal 5A9FH to point to the message 1DH + “VERIFYING TRACK xx, SECTOR yy” + 03H
5594H
GOSUB to 429AH (part of SYS0/SYS) to send the message pointed to by Register Pair HL to the video display.
5597H
POP DE
Restore DE from the stack.
5598H
LD BC,5D00H
Let Register Pair BC equal 5D00H, which will be a buffer for the READ SECTOR subroutine about to be called.
559BH
GOSUB to 42AAH to read a sector from the disk. D must hold the track, E must hold the sector, and BC must point to the start of the memory buffer to hold the sector data. On exit, Register A holds the FDC Status.
559EH
LD HL,5ABEH
Let Register Pair HL equal 5ABEH to point to the message “: NOT FOUND! TRACK LOCKED OUT!” + 0DH.
55A1H
BIT 4,A
Test Bit Number 4 of Register A which would be the FDC status of “RECORD NOT FOUND” if high. Z FLAG will be set if that bit is 0, and NZ FLAG will be set if that bit is 1.
55A3H
If the NZ FLAG (Not Zero) has been set, JUMP to 5719H to display the message pointed to by Register Pair HL, put a FFH into the in-RAM GAT at 5Cnn (nn = the contents of Register D), and then JUMP to 55BDH.
55A6H
LD HL,5ADDH
Let Register Pair HL equal 5ADDH to point to the message “: CRC ERROR! TRACK LOCKED OUT!” + 0DH
55A9H
BIT 3,A
Test Bit Number 3 of Register A which would be the FDC status of “CRC ERROR” if high. Z FLAG will be set if that bit is 0, and NZ FLAG will be set if that bit is 1.
55ABH
If the NZ FLAG (Not Zero) has been set, JUMP to 5719H to display the message pointed to by Register Pair HL, put a FFH into the in-RAM GAT at 5Cnn (nn = the contents of Register D), and then JUMP to 55BDH.
55AEH
LD HL,5AFCH
Let Register Pair HL equal 5AFCH to point to the message 0AH + “CAN’T VERIFY, DISK TRANSFER RATE TOO FAST!” + 0DH.
55B1H
BIT 2,A
Test Bit Number 2 of Register A which would be the FDC status of “LOST DATA” if high. Z FLAG will be set if that bit is 0, and NZ FLAG will be set if that bit is 1.
55B3H
If the NZ FLAG (Not Zero) has been set, JUMP to 56ADH to display HIT ENTER TO CONTINUE, loop until an ENTER is hit, and then HALT the system.
55B6H
INC E
INCrement the value stored in Register E by 1 to point to the next sector to be read.
55B7H
LD A,E
Copy the contents of Register E into Register A for testing.
55B8H
CP 0AH
Compare the value held in Register A against 0AH (Decimal: 10). If Register A equals 10, the Z FLAG is set; otherwise the NZ FLAG is set.
55BAH
If the NZ FLAG (Not Zero) has been set then we have not yet hit 10 sectors on the track, so JUMP BACK to 5584H.

While this can be a pass through, it is also the jump point if the byte in the in-RAM GAT was FFH

55BDH
INC D
INCrement the value stored in Register D by 1 to move to the next track.
55BEH
LD A,D
Copy the contents of Register D into Register A.
55BFH
CP 23H
Compare the value held in Register A against 23H (Decimal: 35). If Register A equals 35, the Z FLAG is set; otherwise the NZ FLAG is set.
55C1H
If the NZ FLAG (Not Zero) has been set, then we have not yet hit 35 tracks, so JUMP BACK to 5572H to keep reading.

At this point, we have verified all tracks, now lets make a duplicate copy of the GAT into 5C60H.

55C4H
LD HL,5C00H
Let Register Pair HL equal 5C00H, which is the source RAM area.
55C7H
LD DE,5C60H
Let Register Pair DE equal 5C60H, which is the DEstination RAM area.
55CAH
LD BC,0023H
Let Register Pair BC equal 0023H (Decimal: 35) to transfer 35 bytes of data; one byte for each track.
55CDH
LDIR
Transfers a byte of data from the memory location pointed to by HL to the memory location pointed to by DE. Then HL and DE are incremented and BC is decremented. If BC is not zero, this operation is repeated. Interrupts can trigger while this instruction is processing.
55CFH
LD HL,5B28H
Let Register Pair HL equal 5B28H to point to the message 0AH + “INITIALIZING SYSTEM INFORMATION” + 0DH.
55D2H
GOSUB to 429AH (part of SYS0/SYS) to send the message pointed to by Register Pair HL to the video display.

Next, set the BOOT GAT entry to “Sectors 0-4 Used” by turning on Bit 0 of the first entry in the GAT; thus changing the FCH (completely empty) to FDH (sectors 0-4 in use).

55D5H
LD HL,5C00H
Let Register Pair HL equal 5C00H to point to the first byte of the GAT.
55D8H
LD A,(HL)
Fetch the first byte of the GAT (held in the memory location pointed to by Register Pair HL) and store it into Register A.
55D9H
OR 01H
OR Register A against 01H, to turn on bit 0. This will change the FCH into FDH.
55DBH
LD (HL),A
Store the revised byte held in Register A into the memory location pointed to by Register Pair HL.

Next, set the DIRECTORY GAT entry to “all granules on track used” (FFH).

55DCH
LD A,(4202H)
Fetch the DIRECTORY TRACK NUMBER (which is stored at 4202H in TRSDOS v2.3) and put it into Register A.
55DFH
LD (57B6H),A
Store the value held in Register A into memory location 57B6H. 57B6H is in the pre-set code for the FPDE/FXDE entry for the DIR/SYS held at 57A0H-57BFH.
55E2H
LD L,A
Copy the contents of Register A into Register L to form an offset into the GAT in RAM for the chosen directory track.
55E3H
LD H,5CH
Let Register H equal 5CH, which MSB of the in-RAM representation of the GAT table of the disk being formatted.
55E5H
LD A,(HL)
Fetch the value held in the memory location pointed to by Register Pair HL and store it into Register A. This is the byte held in the GAT for DIR/SYS
55E6H
INC A
INCrement the value stored in Register A by 1 to help test to see if it was already FFH (meaning that the track had no available sectors to use).
55E7H
If the INC A triggered the Z FLAG (Zero), then it was already FFH (meaning that the track had no available sectors to use), which means that the chosen directory track had no room. With this, JUMP to 56D1H to display “CAN’T FORMAT, DIRECTORY TRACK FLAWED!”, prompt for an ENTER, and then HALT the system.
55EAH
LD (HL),FFH
Store the value held in FFH into the memory location pointed to by Register Pair HL. This puts a “all granules on track used” notation of FFH into the GAT for the track upon which the directory is to be placed.
55ECH
LD DE,0000H
Let Register Pair DE equal 0000H.
55EFH
LD BC,4200H
Let Register Pair BC equal 4200H / (Decimal: 16896).
NOTE: 4200H is the storage location for the [TAKEN FROM PAGE] System Sector Buffer Area
55F2H
LD A,A8H
Let Register A equal A8H for the next instruction so as to write a 0FBH DAM.
55F4H
GOSUB to 56BDH to put A8 or A9 into the OPCODE LD (HL),nnH at 56F7H, Save BC, send DE to the FDC Sector Register, Send a SEEK and a WRITE FBH or F8H, and JUMP to 5706H to write out some data.
55F7H
LD A,(37ECH)
Fetch the FDC’s status (which is mirrored to 37ECH) and store it into Register A.
55FAH
AND 60H
MASK the value of Register A against 60H (0110 0000). This has the effect of turning off bits 7, 4, 3, 2, 1, 0, leaving only bits 6, 5 active. Since this follows a write command, BIT 5 HIGH means WRITE FAULT and BIT 6 HIGH means WRITE PROTECTED.
55FCH
If the NZ FLAG (Not Zero) has been set, the one of those 2 errors occurred, and so JUMP to 56CBH to display “CAN’T INITIALIZE SYSTEM INFORMATION”, prompt for an ENTER, and then HALT the system.
55FFH
LD BC,5C00H
Let Register Pair BC equal 5C00H, which is the in-RAM representation of the GAT table of the disk being formatted.
5602H
LD A,(4202H)
Fetch the DIRECTORY TRACK NUMBER (which is stored at 4202H in TRSDOS v2.3) and put it into Register A.
5605H
LD D,A
Copy the contents of Register A into Register D.
5606H
LD E,00H
Let Register E equal 00H.
5608H
LD A,A9H
Let Register A equal A9H for the next instruction so as to write a 0F8H DAM.
560AH
GOSUB to 56BDH to put A8 or A9 into the OPCODE LD (HL),nnH at 56F7H, Save BC, send DE to the FDC Sector Register, Send a SEEK and a WRITE FBH or F8H, and JUMP to 5706H to write out some data.
560DH
LD A,(37ECH)
Fetch the FDC’s status (which is mirrored to 37ECH) and store it into Register A.
5610H
AND 60H
MASK the value of Register A against 60H (0110 0000). This has the effect of turning off bits 7, 4, 3, 2, 1, 0, leaving only bits 6, 5 active. Since this follows a write command, BIT 5 HIGH means WRITE FAULT and BIT 6 HIGH means WRITE PROTECTED.
5612H
CP 20H
Compare the value held in Register A against 0010 0000, which is BIT 5 of the status. If Bit 5 is 0, then the Z FLAG will be set, if Bit 5 is 1 (WRITE FAULT) then the NZ FLAG is set.
5614H
If the NZ FLAG (Not Zero) has been set then we have a WRITE FAULT so JUMP to 56CBH since to display “CAN’T INITIALIZE SYSTEM INFORMATION”, prompt for an ENTER, and then HALT the system.
5617H
LD HL,5D00H
Let Register Pair HL equal 5D00H, which will be the buffer.

Top of a loop to ZERO out 5D00H-5DFFH

561AH
LD (HL),00H
Store the value 00H into the memory location pointed to by Register Pair HL.
561CH
INC L
INCrement the value stored in Register L by 1.
561DH
If the NZ FLAG (Not Zero) has been set, meaning we didn’t yet get to FFH, LOOP BACK to 561AH to keep ZEROing and BUMPing.

Now that 5D00H-5DFFH has been ZEROed out, and HL is back to 5D00H, let’s start filling that buffer.

561FH
LD (HL),A2H
Store an A2H into (5D00H).
5621H
INC HL
INCrement the value stored in Register Pair HL by 1.
5622H
LD (HL),2CH
Store a 2CH into (5D01H).
5624H
DEC HL
DECrement the value stored in Register Pair HL by 1.
5625H
LD E,01H
Let Register E equal 01H.
5627H
LD BC,5D00H
Let Register Pair BC equal 5D00H, which will be the buffer.
562AH
LD A,A9H
Let Register A equal A9H for the next instruction so as to write a 0F8H DAM.
562CH
GOSUB to 56BDH to put A8 or A9 into the OPCODE LD (HL),nnH at 56F7H, Save BC, send DE to the FDC Sector Register, Send a SEEK and a WRITE FBH or F8H, and JUMP to 5706H to write out some data.
562FH
LD A,(37ECH)
Fetch the FDC’s status (which is mirrored to 37ECH) and store it into Register A.
5632H
AND 60H
MASK the value of Register A against 60H (0110 0000). This has the effect of turning off bits 7, 4, 3, 2, 1, 0, leaving only bits 6, 5 active. Since this follows a write command, BIT 5 HIGH means WRITE FAULT and BIT 6 HIGH means WRITE PROTECTED.
5634H
CP 20H
Compare the value held in Register A against 0010 0000, which is BIT 5 of the status. If Bit 5 is 0, then the Z FLAG will be set, if Bit 5 is 1 (WRITE FAULT) then the NZ FLAG is set.
5636H
If the NZ FLAG (Not Zero) has been set then we have a WRITE FAULT so JUMP to 56CBH since to display “CAN’T INITIALIZE SYSTEM INFORMATION”, prompt for an ENTER, and then HALT the system.

The next instructions move the BOOT/SYS FPDE entry to 5D00H and then send it to disk.

5639H
LD DE,5D00H
Let Register Pair DE equal 5D00H, which will be a buffer.
563CH
LD HL,5780H
Let Register Pair HL equal 5780H which is the area in RAM holding the literal code for the BOOT/SYS entry in the FPDE/FXDE area … Sector 1 Bytes 00-1F.
563FH
LD BC,0020H
Let Register Pair BC equal 0020H (Decimal: 32) to tranfer the 32 byte BOOT/SYS FPDE/FXDE entry to 5D00H.
5642H
LDIR
Transfers a byte of data from the memory location pointed to by HL to the memory location pointed to by DE. Then HL and DE are incremented and BC is decremented. If BC is not zero, this operation is repeated. Interrupts can trigger while this instruction is processing.
5644H
LD A,(4202H)
Fetch the DIRECTORY TRACK NUMBER (which is stored at 4202H in TRSDOS v2.3) and put it into Register A.
5647H
LD D,A
Copy the contents of Register A into Register D.
5648H
LD E,02H
Let Register E equal 02H. Now DE points to 1102H (if we are using the standard directory track location).
564AH
LD BC,5D00H
Let Register Pair BC equal 5D00H, which will be a buffer.
564DH
LD A,A9H
Let Register A equal A9H for the next instruction so as to write a 0F8H DAM.
564FH
GOSUB to 56BDH to put A8 or A9 into the OPCODE LD (HL),nnH at 56F7H, Save BC, send DE to the FDC Sector Register, Send a SEEK and a WRITE FBH or F8H, and JUMP to 5706H to write out some data.
5652H
LD A,(37ECH)
Fetch the FDC’s status (which is mirrored to 37ECH) and store it into Register A.
5655H
AND 60H
MASK the value of Register A against 60H (0110 0000). This has the effect of turning off bits 7, 4, 3, 2, 1, 0, leaving only bits 6, 5 active. Since this follows a write command, BIT 5 HIGH means WRITE FAULT and BIT 6 HIGH means WRITE PROTECTED.
5657H
CP 20H
Compare the value held in Register A against 0010 0000, which is BIT 5 of the status. If Bit 5 is 0, then the Z FLAG will be set, if Bit 5 is 1 (WRITE FAULT) then the NZ FLAG is set.
5659H
If the NZ FLAG (Not Zero) has been set then we have a WRITE FAULT so JUMP to 56CBH since to display “CAN’T INITIALIZE SYSTEM INFORMATION”, prompt for an ENTER, and then HALT the system.

The next instructions move the DIR/SYS FPDE entry to 5D00H and then send it to disk.

565CH
LD HL,57A0H
Let Register Pair HL equal 57A0H which contains the literal code for the DIR/SYS entry in the FPDE/FXDE area … Sector 2 Bytes 00-1F.
565FH
LD DE,5D00H
Let Register Pair DE equal 5D00H, which will be the buffer.
5662H
LD BC,0020H
Let Register Pair BC equal 0020H (Decimal: 32) to tranfer the 32 byte DIR/SYS FPDE/FXDE entry to 5D00H.
5665H
LDIR
Transfers a byte of data from the memory location pointed to by HL to the memory location pointed to by DE. Then HL and DE are incremented and BC is decremented. If BC is not zero, this operation is repeated. Interrupts can trigger while this instruction is processing.
5667H
LD A,(4202H)
Fetch the DIRECTORY TRACK NUMBER (which is stored at 4202H in TRSDOS v2.3) and put it into Register A.
566AH
LD D,A
Copy the contents of Register A into Register D.
566BH
LD E,03H
Let Register E equal 03H / (Binary:0000 0011) / (Decimal: 3).
566DH
LD BC,5D00H
Let Register Pair BC equal 5D00H, which will be the buffer used by the ROM to accept keyboard input and store the keys entered.
5670H
LD A,A9H
Let Register A equal A9H for the next instruction so as to write a 0F8H DAM.
5672H
GOSUB to 56BDH to put A8 or A9 into the OPCODE LD (HL),nnH at 56F7H, Save BC, send DE to the FDC Sector Register, Send a SEEK and a WRITE FBH or F8H, and JUMP to 5706H to write out some data.
5675H
LD A,(37ECH)
Fetch the FDC’s status (which is mirrored to 37ECH) and store it into Register A.
5678H
AND 60H
MASK the value of Register A against 60H (0110 0000). This has the effect of turning off bits 7, 4, 3, 2, 1, 0, leaving only bits 6, 5 active. Since this follows a write command, BIT 5 HIGH means WRITE FAULT and BIT 6 HIGH means WRITE PROTECTED.
567AH
CP 20H
Compare the value held in Register A against 0010 0000, which is BIT 5 of the status. If Bit 5 is 0, then the Z FLAG will be set, if Bit 5 is 1 (WRITE FAULT) then the NZ FLAG is set.
567CH
If the NZ FLAG (Not Zero) has been set then we have a WRITE FAULT so JUMP to 56CBH since to display “CAN’T INITIALIZE SYSTEM INFORMATION”, prompt for an ENTER, and then HALT the system.

The next instructions clear the 32 bytes from 5D00H, and writes out 4 (tracked in E) blank FPDE/FXDE entries..

567FH
LD HL,5D00H
Let Register Pair HL equal 5D00H, which will be the buffer used by the ROM to accept keyboard input and store the keys entered.
5682H
LD B,20H
Let Register BC equal 0020H (Decimal: 32) to allow for a 32 pass DJNZ Loop (32 bytes being the size of a FPDE/FXDE entry).
5684H
LD (HL),00H
Store the value 00H into the memory location pointed to by Register Pair HL.
5686H
INC HL
INCrement the value stored in Register Pair HL by 1.
5687H
LOOP back to 5684H, reducing Register B each time, and continue to LOOP until Register B has been reduced to ZERO, in which case, continue with the next instruction.
5689H
LD A,(4202H)
Fetch the DIRECTORY TRACK NUMBER (which is stored at 4202H in TRSDOS v2.3) and put it into Register A.
568CH
LD D,A
Copy the contents of Register A into Register D.
568DH
LD E,04H
Let Register E equal 04H for 4 loop passes.
568FH
LD BC,5D00H
Let Register Pair BC equal 5D00H, which will be the buffer used by the ROM to accept keyboard input and store the keys entered.
5692H
LD A,A9H
Let Register A equal A9H for the next instruction so as to write a 0F8H DAM.
5694H
GOSUB to 56BDH to put A8 or A9 into the OPCODE LD (HL),nnH at 56F7H, Save BC, send DE to the FDC Sector Register, Send a SEEK and a WRITE FBH or F8H, and JUMP to 5706H to write out some data.
5697H
LD A,(37ECH)
Fetch the FDC’s status (which is mirrored to 37ECH) and store it into Register A.
569AH
AND 60H
MASK the value of Register A against 60H (0110 0000). This has the effect of turning off bits 7, 4, 3, 2, 1, 0, leaving only bits 6, 5 active. Since this follows a write command, BIT 5 HIGH means WRITE FAULT and BIT 6 HIGH means WRITE PROTECTED.
569CH
CP 20H
Compare the value held in Register A against 0010 0000, which is BIT 5 of the status. If Bit 5 is 0, then the Z FLAG will be set, if Bit 5 is 1 (WRITE FAULT) then the NZ FLAG is set.
569EH
If the NZ FLAG (Not Zero) has been set then we have a WRITE FAULT so JUMP to 56CBH since to display “CAN’T INITIALIZE SYSTEM INFORMATION”, prompt for an ENTER, and then HALT the system.
56A1H
INC E
INCrement the value stored in Register E by 1 to note that the FPDE/FXDE was written.
56A2H
LD A,E
Copy the contents of Register E into Register A.
56A3H
CP 0AH
Compare the value held in Register A against 0AH (Decimal: 10) for a total of 10 sectors in the directory track.
56A5H
If the NZ FLAG (Not Zero) has been set, JUMP to 568FH to write the next sector.
56A7H
GOSUB to 5754H to send a RESTORE/LOAD HEAD to the Floppy Drive and then keep checking the floppy drive controller status until the drive is not BUSY, at which point the routine RETurns.
56AAH
LD HL,5B6DH
Let Register Pair HL equal 5B6DH to point to the message 0AH + “FORMATTING COMPLETE” + 0DH

56ADH – Can be a pass through OR Jumped here if the drive is not doing what was desired. Will display “HIT ENTER TO CONTINUE” and then HALT the system if ENTER is hit.

56ADH
GOSUB to 429AH (part of SYS0/SYS) to send the message pointed to by Register Pair HL to the video display.
56B0H
LD HL,5B82H
Let Register Pair HL equal 5B82H to point to the message 0AH + 0AH + “HIT ‘ENTER’ TO CONTINUE” + 0DH
56B3H
GOSUB to 429AH (part of SYS0/SYS) to send the message pointed to by Register Pair HL to the video display.
56B6H
LD A,(3840H)
Fetch the value held in memory location 3840H and store it into Register A.
NOTE: 3840H is the value held at Keyboard Row 7 – which is ENTER, CLEAR, BREAK, UP, DOWN, LEFT, RIGHT, SPACE.
56B9H
RRCA
Make it easier to test for ENTER by rotating the bits in A right (i.e., higher bit moves lower), with Bit 0 being copied to both the CARRY FLAG and Bit 7.
56BAH
If the NC FLAG (No Carry) has been set, the ENTER was not hit, so LOOP BACK to 56B6H to keep checking for the keypress.
56BCH
HALT
Kill the system

56BDH – Subroutine to Put A8 or A9 into the OPCODE LD (HL),nnH at 56F7H, Save BC, send DE to the FDC Sector Register, Send a SEEK and a WRITE FBH or F8H, and JUMP to 5706H to write out some data.

56BDH
GOSUB to 56D7H to put the contents of Register A into the OPCODE LD (HL),nnH at 56F7H, Save BC, send DE to the FDC Sector Register, Send a SEEK and a WRITE FBH or F8H, and JUMP to 5706H to write out some data.
56C0H
If the NZ FLAG (Not Zero) has been set, JUMP to 56CBH (since the drive is not doing what was desired) to display “CAN’T INITIALIZE SYSTEM INFORMATION”, prompt for an ENTER, and then HALT the system.
56C2H
PUSH BC
Save the contents of Register Pair BC to the top of the stack.
56C3H
LD BC,5D00H
Let Register Pair BC equal 5D00H, which will be a buffer.
56C6H
GOSUB to 42AAH to read a sector from the disk. D must hold the track, E must hold the sector, and BC must point to the start of the memory buffer to hold the sector data. On exit, Register A holds the FDC Status.
56C9H
POP BC
Put the value held at the top of the STACK into Register Pair BC, and then remove the entry from the stack.
56CAH
RET Z
If the Z FLAG (Zero) has been set, RETurn to the caller.

56CBH – Display “CAN’T INITIALIZE SYSTEM INFORMATION”, prompt for an ENTER, and then HALT the system.

56CBH
LD HL,5B49H
Let Register Pair HL equal 5B49H to point to the message “CAN’T INITIALIZE SYSTEM INFORMATION” + 0DH.
56CEH
JUMP to 56ADH to display HIT ENTER TO CONTINUE, loop until an ENTER is hit, and then HALT the system.

56D1H – Display “CAN’T FORMAT, DIRECTORY TRACK FLAWED!”, prompt for an ENTER, and then HALT the system.

56D1H
LD HL,59EEH
Let Register Pair HL equal 59EEH to point to the message “CAN’T FORMAT, DIRECTORY TRACK FLAWED!” + 0DH
56D4H
JUMP to 56ADH to display HIT ENTER TO CONTINUE, loop until an ENTER is hit, and then HALT the system.

56D7H – Routine to put the contents of Register A into the OPCODE LD (HL),nnH at 56F7H, Save BC, send DE to the FDC Sector Register, Send a SEEK and a WRITE FBH or F8H, and JUMP to 5706H to write out some data.

56D7H
LD (56F8H),A
Store the value held in Register A into the OPCODE LD (HL),nnH at 56F7H.
56DAH
PUSH BC
Save the contents of Register Pair BC to the top of the stack.
56DBH
GOSUB to 56E2H to select the drive, send a seek and a write of FBH or F8H, and then JUMP to 5706H to write out sector data . If the Z FLAG is set, the routine will POP HL and RETurn.
56DEH
POP HL
Put the value held at the top of the STACK into Register Pair HL, and then remove the entry from the stack.
56DFH
RET Z
If the Z FLAG (Zero) has been set, RETurn to the caller.
56E0H
LD B,H
Copy the contents of Register H into Register B.
56E1H
LD C,L
Copy the contents of Register L into Register C.

This is the SUBROUTINE call from the prior routine, but is also a pass through. If this was a subroutine, the Z/NZ flag is important.

56E2H
LD (37EEH),DE
Store the value held in Register Pair DE into memory location 37EEH, which is the Floppy Disk Controller’s Sector Register.
56E6H
PUSH DE
Save the contents of Register Pair DE to the top of the stack.
56E7H
GOSUB to 5767H to send a nnH to the disk drive select latch address and RETurn.
56EAH
LD HL,37ECH
Let Register Pair HL equal 37ECH / (Decimal: 14316).
NOTE: 37ECH is the Floppy Disk Controller’s Command Status Register.
56EDH
LD (HL),1BH
Store the value 1BH (Binary:0001 1011) into the memory location pointed to by Register Pair HL. This instructs the FDC TO: SEEK (0001), Head Load At The Beginning (1), Turn OFF VERIFY (0), 30 ms stepping (11)
56EFH-56F2H
PUSH AF
POP AF
PUSH AF
POP AF
Wait 4 instruction cycles to let the FDC process the command.
56F3H
LD A,(HL)
Fetch the Disk Controller’s Command Status and store it into Register A.
56F4H
RRCA
Rotate the bits in A right (i.e., higher bit moves lower), with Bit 0 being copied to both the CARRY FLAG and Bit 7. This puts BIT 0, which is the BUSY/NOT BUSY flag (1=Busy), into the CARRY FLAG
56F5H
If BIT 0 was 1 then the C FLAG (Carry) will be been set, meaning the FDC returned “BUSY” so LOOP BACK to 56F3H to poll again.
56F7H
LD (HL),nnH
Send the value nnH to the FDC. This nnH is set at multiple locations to either A8H (1010 1000) or A9H (1010 1001). Those correspond to: Write Sector (101), Single Record (0), Compare Side 1 (1), no 15ms delay (0), disable side compare (1), and then nn. For A8 it is WRITE 0FBH and for A9 it is WRITE 0F8H.
56F9H
LD DE,37EFH
Let Register Pair DE equal 37EFH to point to the Floppy Disk Controller’s Data Register.
56FCH-56FFH
PUSH BC
POP BC
PUSH BC
POP BC
Wait 4 instruction cycles to let the FDC process the command.
5700H
DI
Disable Interrupts.
5701H
Continue via a JUMP to 5706H.

5703H – Routine to, on entry, test Bit 0 and if it is 0 JUMP to 5711 to isolate bits 2-6 at (HL), POP DE, and either exit the loop vis a RET then or write a bunch of stuff to the disk.

5703H
RRCA
Rotate the bits in A right (i.e., higher bit moves lower), with Bit 0 being copied to both the CARRY FLAG and Bit 7.
5704H
The NC FLAG is now equal to what BIT 0 was. So if Bit 0 was 0 then the NC FLAG (No Carry) will have been set. In this case, JUMP out of this routine to the next one at 5711H.
5706H
LD A,(HL)
Fetch the Disk Controller’s Command Status (pointed to by HL) and store it into Register A.
5707H
BIT 1,A
Test to see if the FDC is busy (Bit Number 1) of Register A. Z FLAG will be set if that bit is 0, and NZ FLAG will be set if that bit is 1.
5709H
If Bit 1 was 0 then the Z FLAG (Zero) will have been set, in which case LOOP BACK to the top of this routine at 5703H.
570BH
LD A,(BC)
Fetch the value held in the memory location pointed to by Register Pair BC and store it into Register A.
570CH
LD (DE),A
Store the value held in Register A into the Floppy Disk Controller’s Data Register (held in Register Pair DE).
570DH
INC BC
INCrement the value stored in Register Pair BC by 1.
570EH
JUMP to 5706H.

5711H – Continuation of the routine at 5703H by isolating bits 2-6 of (HL), POPping DE, and RETurning if those bits were all 0. If not, put a D0H at (HL) and RETurn.

5711H
LD A,(HL)
Fetch the value held in the memory location pointed to by Register Pair HL and store it into Register A.
5712H
AND 7CH
MASK the value of Register A against 7CH (0111 1100). This has the effect of turning off bits 7, 1, 0, leaving only bits 6, 5, 4, 3, 2 active.
5714H
POP DE
Put the value held at the top of the STACK into Register Pair DE, and then remove the entry from the stack.
5715H
RET Z
If the Z FLAG (Zero) has been set, RETurn to the caller.
5716H
LD (HL),D0H
Store the value held in D0H into the memory location pointed to by Register Pair HL.
5718H
RET
RETurn to the caller.

5719H – Displays the message pointed to by Register Pair HL and then puts a FFH into the in-RAM GAT at 5Cnn (nn = the contents of Register D) before JUMPing to 55BDH.

5719H
PUSH DE
Temporarily save DE to the STACK.
571AH
GOSUB to 429AH (part of SYS0/SYS) to send the message pointed to by Register Pair HL to the video display.
571DH
POP DE
Restore DE from the STACK.
571EH
LD L,D
Copy the contents of Register D into Register L.
571FH
LD H,5CH
Let Register H equal 5CH, which MSB of the in-RAM representation of the GAT table of the disk being formatted.
5721H
LD (HL),FFH
Store the value held in FFH into the memory location pointed to by Register Pair HL.
5723H
JUMP to 55BDH to continue.

5726H – SUBROUTINE to Set Registers C and B to the ASCII Number corresponding to Register A (Tens Digit in ASCII to C and Ones Digit in ASCII to B).

5726H
LD C,30H
Let Register C equal 30H / (Binary:0011 0000) / (Decimal: 48) / (ASCII: 0).
5728H
SUB 0AH
SUBtract the value 0AH (Decimal: 10) from Register A. The Carry Flag will be affected.
572AH
If the C FLAG (Carry) has been set, then the subtraction of 10 from A went negative, so JUMP to 572FH.
572CH
INC C
INCrement the value stored in Register C by 1 since the subtraction didn’t go negative.
572DH
JUMP to 5728H to keep subtracting 10 and bumping Register C.
572FH
ADD 3AH
At this point A is negative, so LET Register A = Register A + 3AH to turn Register A into the ASCII Equivalent of the Ones Digit.
5731H
LD B,A
Copy the contents of Register A into Register B.
5732H
RET
RETurn to the caller.

5733H – SUBroutine to parse a memory buffer pointed to by Register Pair HL and accumulate the number into Register E.

5733H
LD E,00H
Let Register E equal 00H. Register E will be tallying up the numbers.
5735H
LD A,(HL)
Fetch the value held in the memory location pointed to by Register Pair HL and store it into Register A.
5736H
INC HL
INCrement the value stored in Register Pair HL by 1.
5737H
CP 30H
Compare the value held in Register A against 30H (ASCII: 0). Results:
  • If Register A equals 0, the Z FLAG is set.
  • If A < 0, the CARRY FLAG will be set.
  • if A >= 0, the NO CARRY FLAG will be set.
5739H
RET C
If the C FLAG (Carry) has been set then we have an invalid character (one which is lower than “0”) so RETurn to the caller.
573AH
CP 3AH
Compare the value held in Register A against 3AH (ASCII: :). Results:
  • If Register A equals :, the Z FLAG is set.
  • If A < :, the CARRY FLAG will be set.
  • if A >= :, the NO CARRY FLAG will be set.
573CH
RET NC
If the NC FLAG (No Carry) has been set then we have an invalid character (one which is greater than “:”) so RETurn to the caller.

If we are here, then A is an ASCII character from “0” through “9”.

573DH
SUB 30H
SUBtract the value 30H from Register A. Note: Subtracting 30H from from Register A will convert an ASCII number ‘0’-‘9’ to its decimal equivalent (i.e., 6 in ASCII is 36H in Hex; so 36H-30H = 6). The Carry Flag will be affected.
573FH
LD B,A
Copy the contents of Register A into Register B so that we can do math on A but still know what A was originally, since we will need that.
5740H
LD A,E
Copy the contents of Register E (which is accumulating the digits) into Register A.
5741H
ADD A,A
LET Register A = Register A + Register A. A is now A * 2.
5742H
ADD A,A
LET Register A = Register A + Register A. A is now A * 4.
5743H
ADD A,E
LET Register A = Register A + Register E. A is now A * 5.
5744H
ADD A,A
LET Register A = Register A + Register A. A is now A * 10, meaning that A has moved into the tens or hundreds digits.
5745H
ADD A,B
LET Register A = Register A + Register B. NOW we can add the original number into the ones place.
5746H
LD E,A
Preserve the accumulated number into Register E.
5747H
JUMP BACK to 5735H and keep going until we have a character which is less than “0” or more than “9”.

5749H – Set C = FFH and then do ‘put the value held in Register C into (HL) and then BUMP HL by 1’ Register B times.

5749H
LD C,FFH
Let Register C equal FFH / (Binary:1111 1111) / (Decimal: 255).

574BH – Do ‘put the value held in Register C into (HL) and then BUMP HL by 1’ Register B times.

574BH
GOSUB to 5751H to store the value held in Register C into (HL) and then BUMP HL by 1.
574EH
LOOP back to 574BH, reducing Register B each time, and continue to LOOP until Register B has been reduced to ZERO, in which case, continue with the next instruction.
5750H
RET
RETurn to the caller.

5751H – Put C into (HL) and then BUMP HL by 1.

5751H
LD (HL),C
Store the value held in Register C into the memory location pointed to by Register Pair HL.
5752H
INC HL
INCrement the value stored in Register Pair HL by 1.
5753H
RET
RETurn to the caller.

5754H – Subroutine to send a RESTORE/LOAD HEAD to the Floppy Drive and then keep checking the floppy drive controller status until the drive is not BUSY.

5754H
GOSUB to 5767H to send a nnH to the disk drive select latch address and RETurn.
5757H
LD A,0BH
Let Register A equal 0BH (Binary:0000 1011) to represent RESTORE (0000), Load Head at the Beginning (1), No Verify (0), 30 ms stepping rate (11).
5759H
LD (37ECH),A
Send the command held in Register A to the FDC (37ECH is the Floppy Disk Controller’s Command Register).
575CH-575FH
PUSH AF
POP AF
PUSH AF
POP AF
Waste some time to let the disk drive controller have enough time to process the command … Save the contents of Register Pair AF to the top of the stack.
5760H
LD A,(37ECH)
Fetch the FDC’s status (which is mirrored to 37ECH) and store it into Register A.
5763H
RRCA
Test Bit 0 (i.e., “BUSY”) by first rotating the bits in A right (i.e., higher bit moves lower), with Bit 0 being copied to both the CARRY FLAG and Bit 7.
5764H
If the C FLAG (Carry), which used to be Bit 0, has been set, then the drive is BUSY, so LOOP BACK to 5760H to poll the status again.
5766H
RET
RETurn to the caller.

5767H – Send a nnH to the disk drive select latch address and RETurn.

5767H
LD A,00H
Let Register A equal nnH. nnH is changed by the code.
5769H
LD (37E1H),A
Store the value held in Register A into memory location 37E1H which is the Disk Drive Select Latch Address.
576CH
RET
RETurn to the caller.

576DH – STORAGE LOCATION

576DH
00H
Storage location for the TRACK BEING FORMATTED

5780H-579FH – Literal Code for the BOOT/SYS entry in the FPDE/FXDE area … Sector 1 Bytes 00-1F

5780H
5E00 0000 0042 4F4F 5420 2020 2053 5953
5790H
607F 1FB2 0500 0000 FFFF 0000 0000 0000

57A0H-57BFH – Literal Code for the DIR/SYS entry in the FPDE/FXDE area … Sector 2 Bytes 00-1F

57A0H
5D00 0000 0044 4952 2020 2020 2053 5953
57B0H
A71D F9E5 0A00 1101 FFFF 0000 0000 0000

57C0H – MESSAGE STORAGE AREA

57C0-57E7
“FORMAT INVALID DURING PROGRAM CHAINING!” + 0DH
57E8-580D
1C + 1F + “TRSDOS DISK FORMATTER PROGRAM 2.3” + 0AH + 0DH
580E-582A
“WHICH DRIVE IS TO BE USED?” + 03H
582B-583B
“DISKETTE NAME ? ” + 03H
583C-5857
“CREATION DATE (MM/DD/YY) ? ” + 03H
5858-586A
“MASTER PASSWORD ? ” + 03H
586B-587B
“DRIVE NOT READY” + 0DH
587C-5895
“WRITE PROTECTED DISKETTE!”+ 0DH
5896-58AA
“DRIVE NOT IN SYSTEM!” +0DH
58AB-58C0
“NO DISKETTE IN DRIVE!”+0DH
58C1-58DA
“DOOR NOT CLOSED ON DRIVE!” + 0DH
58DB-58FC
“DISKETTE UNUSABLE! HARD-SECTORED!” + 0DH
58FD-5925
“DISKETTE CONTAINS DATA, FORMAT OR NOT? ” + 03H
5926-594B
“DO YOU WANT TO LOCK OUT ANY TRACKS? ” + 03H
594C-5962
“WHICH TRACKS (1-34)? ” + 03H
5963-5978
“INVALID TRACK NUMBER!” + 0DH
5979-5997
“FORMAT THE LOCKED OUT TRACKS? ” + 03H
5998-59C8
“CAN’T FORMAT, NO TRACKS AVAILABLE FOR DIRECTORY!” + 0DH
59C9-59ED
“DIRECTORY WILL BE PLACED ON TRACK 00” + 0DH
59EE-5A13
“CAN’T FORMAT, DIRECTORY TRACK FLAWED!” + 0DH
5A14-5A28
1DH + “FORMATTING TRACK 00” + 03H
5A29-5A54
0AH + “CAN’T FORMAT, DISK TRANSFER RATE TOO FAST!” + 0DH
5A55-5A79
0AH + “CAN’T FORMAT, MOTOR SPEED TOO SLOW!” + 0DH
5A7A-5A9E
0AH + “CAN’T FORMAT, MOTOR SPEED TOO FAST!” + 0DH
5A9F-5ABD
1DH + “VERIFYING TRACK 00, SECTOR 00” + 03H
5ABE-5ADC
“: NOT FOUND! TRACK LOCKED OUT!” + 0DH
5ADD-5AFB
“: CRC ERROR! TRACK LOCKED OUT!” + 0DH
5AFC-5B27
0AH + “CAN’T VERIFY, DISK TRANSFER RATE TOO FAST!” + 0DH
5B28-5B48
0AH + “INITIALIZING SYSTEM INFORMATION” + 0DH
5B49-5B6C
“CAN’T INITIALIZE SYSTEM INFORMATION” + 0DH
5B6D-5B81
0AH + “FORMATTING COMPLETE” + 0DH
5B82-5B9B
0AH + 0AH + “HIT ‘ENTER’ TO CONTINUE” + 0DH

5B9CH – Display “DISKETTE CONTAINS DATA, FORMAT OR NOT?” message and get a “Y” or “N” from the user. Jump to 56B0H for a NO and RETurn for a YES.

5B9CH
LD HL,58FDH
Let Register Pair HL equal 58FDH to point to the message “DISKETTE CONTAINS DATA, FORMAT OR NOT? ” + 03H
5B9FH
GOSUB to 429AH (part of SYS0/SYS) to send the message pointed to by Register Pair HL to the video display.
5BA2H
LD HL,5D00H
Let Register Pair HL equal 5D00H, which will be the buffer used by the ROM to accept keyboard input and store the keys entered.
5BA5H
LD B,01H
Let Register B equal 01H to indicate to the ROM routine that we want 1 character from the user.
5BA7H
GOSUB to 0040H.
NOTE: 0040H is the Model I ROM routine to wait for keyboard input of B characters and put store the character at (HL).
5BAAH
LD A,(HL)
Fetch the key typed by the user (held in the memory location pointed to by Register Pair HL) and store it into Register A.
5BABH
CP 4EH
Compare the value held in Register A against 4EH (ASCII: N). If the user typed “N” then the Z FLAG will be set.
5BADH
If the user type “N” then the Z FLAG (Zero) will have been set, JUMP to 5BC0H to delay for BC * 14.66 milliseconds and JUMP to 56B0H to display “HIT ENTER TO CONTINUE” and then HALT the system if ENTER is hit.
5BB0H
CP 59H
Compare the value held in Register A against 59H (ASCII: Y). If the user typed anything other than “Y” then the NZ FLAG will be set.
5BB2H
If the NZ FLAG (Not Zero) has been set, then we didn’t get either a “Y” or an “N” in response, so try again via a JUMP to 5B9CH.
5BB5H
NOP
No Operation (Do Nothing).
5BB6H
GOSUB to 5767H to send a 00H to the disk drive select latch address and RETurn.
5BB9H
LD BC,8000H
Let Register Pair BC equal 8000H.
5BBCH
GOSUB to 0060H to delay for the length of BC * 14.66 microseconds and RETurn.
5BBFH
RET
RETurn to the caller.

5BC0H – Delay for BC * 14.66 milliseconds and JUMP to 56B0H.

5BC0H
LD BC,1000H
Let Register Pair BC equal 1000H.
5BC3H
GOSUB to 0060H to delay for the length of BC * 14.66 microseconds and RETurn.
5BC6H
JUMP to 56B0H.

5CCBH – MESSAGE STORAGE AREA

5CCBH
“!”
5CCCH-5CCFH
00H 00H 00H 00H
5CD0H
” ” (8 Spaces)
5CD8H
“MM/DD/YY” + 0DH
5CE1H-5CFFH
31 Spaces

5E00H-5EFFH – Literal Code for the BOOT sector of a TRSDOS v2.3 Disk

5E00H
00FE 00F3 31FC 4121 E242 CD9A 423E 0132
5E10H
E137 3A02 4257 1E04 0100 4DCD AA42 2070
5E20H
3A00 4DE6 1021 E542 2869 D92A 164D 557C
5E30H
0707 07E6 0767 0707 845F 01FF 4DD9 CD75
5E40H
423D 2017 CD75 4247 CD75 426F 05CD 7542
5E50H
6705 28EA CD75 4277 2318 F63D 280B CD75
5E60H
4247 CD75 4210 FB18 D5CD 7542 CD75 426F
5E70H
CD75 4267 E9D9 0C20 14C5 3E01 32B6 37CD
5E80H
AA42 200C C11C 7BD6 0A20 025F 140A D9C9
5E90H
21F1 42CD 9A42 CD40 0076 E57E FE03 2808
5EA0H
CD33 0023 FE0D 20F3 E1C9 C5CD B242 E1C8
5EB0H
444D ED53 EE37 21EC 3736 1BF5 F1F5 F17E
5EC0H
0F38 FC36 88D5 11EF 37C5 C118 0B0F 300A
5ED0H
7ECB 4F28 F81A 0203 18F6 7EE6 5CD1 C836
5EE0H
D0C9 1C1F 0317 E84E 4F20 5359 5354 454D
5EF0H
0D17 E844 4953 4B20 4552 524F 520D EB5F

Leave a Reply

Your email address will not be published. Required fields are marked *