TRS-80 DOS – TRSDOS v1.3 – SYS09/SYS Disassembled

General:

SYS09/SYS handles the COPY, DUAL, FORMS, KILL, MASTER, PATCH, RELO, ROUTE, SETCOM, and WP LIBrary Command.



Disassembly:

ORG 5200H
“BEGIN”
5200
LD A,55H
LET Register A = 55H (0101 0101).
5202
LD (42B4H),A
Store the value held in Register A into the memory location 42B4H.
NOTE: 42B4H is the storage location for the CLEAR RAM Flag.
5205
XOR A
Set Register A to ZERO and clear all Flags.
5206
LD (4414H),A
Clear the system flag by storing a 0 (held in Register A) into the memory location 4414H.
NOTE: 4414H is the storage location for the NUMBER OF THE OVERLAY CURRENTLY IN MEMORY.
5209
LD (42FFH),A
Clear the protection override flag by storing a 0 (held in Register A) into the memory location 42FFH.
NOTE: 42FFH is the storage location for whether a password check is skipped or undertaken in an OPEN command. If Bit 0 is set, the check is skipped.
520C
DEC A
DECrement the value stored in Register A by 1 so that Register A is now FFH.
520D
LD (427AH),A
Store the value held in Register A into the memory location 427AH. Putting a FFH (-1) here indicates that BASIC is not in RAM.
5210
PUSH HL
Save the POINTER TO THE COMMAND LINE in RAM (held in Register Pair HL) to the top of the stack.
5211
CALL GETTAB
     [5226H]
Get the address of the command via a GOSUB to 5226H.
5214
JR C,NOCMD
     [5218H]
If the C FLAG (Carry) has been set then the requested command is not one of the commands available in this overlay, so JUMP to 5218H.
5216
EX (SP),HL
EXchange the value stored in Register Pair HL (i.e., the POINTER TO THE COMMAND LINE in RAM) with the value stored at the top of the STACK (i.e., the command address).
5217
RET
RETurn to the caller.

5218H – Jumped to if the command requested is not one of the commands available in this overlay.

“NOCMD”
5218
POP HL
Put the value held at the top of the STACK into Register Pair HL, and then remove the entry from the stack.
“ERR”
5219
LD A,0BH
LET Register A = 0BH to indicate an illegal command parameter error.
521B
JR ERRX
   [5223H]
Report the error and abort via a JUMP to 5223H.

521DH – Jumped here if we are missing the parameter.

“ERR3”
521D
LD A,0AH
LET Register A = 0AH to indicate a missing parameter.
521F
JR ERRX
   [5223H]
Report the error and abort via a JUMP to 5223H.

5221H – Jumped here if we we were requested to do something to a drive which is not on the system.

“ERR9”
5221
LD A,02H
LET Register A = 02H to indicate the drive is not in the system.
“ERRX”
5223
JP 4409H
   [4409H]
JUMP to 4409H.
NOTE: 4409H is the SYS00/SYS routine to process DOS errors.

5226H – Routine to do a Table Lookup.

“GETTAB”
5226
LD HL,TABLE
LET Register Pair HL = 523EH, which points to the lookup table.
“GETTA1”
5229
LD A,(HL)
Fetch the table compare byte (i.e., the value stored at the memory location pointed to by Register Pair HL) and put it into A.
522A
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).
522B
JR NZ,522FH
      [522FH]
If the NZ FLAG (Not Zero) has been set then we are not at the end of the table yet, so JUMP to 522FH to look it up.
522D
SCF
If we are here, then we ran out of table entries, so turn the CARRY FLAG on to indicate an error.
522E
RET
RETurn to the caller.

522FH – Continuation of the Table Lookup – Jumped here if the table compare byte matched.

“GETTA2”
522F
CP C
Compare the value held in Register A against the value held in Register C. Results: If Register A equals the value held in Register C, the Z FLAG is set; otherwise the NZ FLAG is set.
5230
JR Z,GETTA3
     [5237H]
If the Z FLAG (Zero) has been set then we have a match! JUMP to 5237H to get the address.
5232
5233
5234
INC HL
INC HL
INC HL
If we’re here then we didn’t find a match, so we need to skip forward 3 bytes to the next entry.
5235
JR GETTA1
   [5229H]
Loop back to 5229H to read the next table compare byte.

5237H – Continuation of the Table Lookup – Jumped here to load HL with the address of the matched routine.

“GETTA3”
5237
INC HL
INCrement the value stored in Register Pair HL by 1, so that HL now points to the LSB of the desired command.
5238
LD E,(HL)
Fetch the LSB of the desired command (i.e., stored at the memory location pointed to by Register Pair HL) and put it into E.
5239
INC HL
INCrement the value stored in Register Pair HL by 1, so that HL now points to the MSB of the desired command.
523A
LD D,(HL)
Fetch the MSB of the desired command (i.e., stored at the memory location pointed to by Register Pair HL) and put it into D.
523B
EX DE,HL
EXchange the value stored in Register Pair HL (i.e., the POINTER TO THE COMMAND LINE in RAM) with the value stored in Register Pair DE (i.e., the address of matching command).
523C
OR A
Set FLAGS based on the contents of Register A (and, in all events, clear the CARRY FLAG).
523D
RET
RETurn to the caller with the CARRY FLAG off so that we indicate NO ERROR.

523EH – Command Lookup Table.

“TABLE”
523E
DEFB 09H
09H = COPY command
523F
DEFB 5DH 52H
.. 525DH
5241
DEFB 0FH
0FH = DUAL command
5242
DEFB 34H 5FH
.. 5F34H
5244
DEFB 12H
12H = FORMS command
5245
DEFB 1FH 5BH
.. 5B1FH
5247
DEFB 16H
16H = KILL command
5248
DEFB 69H 56H
.. 5669H
524A
DEFB 1AH
1AH = MASTER command
524B
DEFB 3EH 60H
.. 603EH
524D
DEFB 1BH
1BH = PATCH command
524E
DEFB 1BH 57H
.. 571BH
5250
DEFB 1FH
1FH = RELO command
5251
DEFB 14H 5AH
.. 5A14H
5253
DEFB 21H
21H = ROUTE command
5254
DEFB 9AH 5BH
.. 5B9AH
5256
DEFB 22H
22H = SETCOM command
5257
DEFB 75H 5CH
.. 5C75H
5259
DEFB 25H
25H = WP command
525A
DEFB D9H 5FH
.. 5FD9H
525C
DEFB 00H
END OF TABLE MARKER

525DH – MAIN ROUTINE — COPY COMMAND

“COPY”
525D
PUSH HL
Save the POINTER TO THE COMMAND LINE in RAM (held in Register Pair HL) to the top of the stack.
525E
LD HL,54D0H
LET Register Pair HL = 54D0H to point to the COPY0 routine in this overlay as a vector. This will also be set by the KILL command and will point somewhere else.
5261
LD (5649H),HL
Store the value held in Register HL into the memory location 5649H, which is in the middle of a CALL OPCODE. This will set that OPCODE to “COPY”. The alternative would be from the “KILL” routine, which would set this to a different address.
5264
POP HL
Restore the POINTER TO THE COMMAND LINE in RAM held at the top of the STACK into Register Pair HL, and then remove the entry from the stack.
5265
5266
LD D,H
LD E,L
LET Register Pair DE = Register Pair HL (i.e., the first filespec).
5267
LD A,(DE)
Fetch the next character of the first filespec (stored at the memory location pointed to by Register Pair DE) and put it into A.
5268
CP 2FH
Compare the value held in Register A against /, which is a wildcard. Results: If Register A equals /, the Z FLAG is set; otherwise the NZ FLAG is set.
526A
JP Z,SLANT
     [55B6H]
If the Z FLAG (Zero) has been set because we had a / then we know to copy everything; JUMP to 55B6H.
526D
CALL GETSYN
     [59BCH]
OTHERWISE … GOSUB to 59BCH to process the first filespec (i.e., set Register Pair DE to point to the SOURCE FILE DCB, check the syntax of the associated Filespec, and RETurn).
5270
JP NZ,ERR2
      [5219H]
If the NZ FLAG (Not Zero) has been set, then the CALL produced an error, so JUMP to 5219H to report an ILLEGAL COMMAND PARAMETER error, and ABORT.
“”
5273
PUSH DE
Save the contents of Register Pair DE (the pointer to the first filespec on the command line) to the top of the stack.
5274
LD DE,6194H
Let Register Pair DE equal 6194H to point to the DESTINATION FILE DCB.
5277
CALL 441CH
     [441CH]
GOSUB to 441CH to check the syntax of the second filespec.
NOTE: 441CH is the SYS00/SYS routine to CHECK THE SYNTAX OF A FILESPEC before for use. This RST 28H’s with a value of C1H so as to call ROUTINE 4 in OVERLAY 1.
527A
POP DE
Put the value held at the top of the STACK (the pointer to the first filespec on the command line) into Register Pair DE, and then remove the entry from the stack.
527B
JP Z,COPY9
     [54A8H]
If the Z FLAG (Zero) has been set then we were given a good filespec, so JUMP to 54A8H.
527E
CP 3AH
Compare the value held in Register A against 3AH (ASCII: :) to see if we were only given a drive number. Results: If Register A equals :, the Z FLAG is set; otherwise the NZ FLAG is set.
5280
JR Z,CHECK
     [528BH]
If the Z FLAG (Zero) has been set then we were only given a drive number, so JUMP to 528BH.
5282
CP 2EH
Compare the value held in Register A against 2EH (ASCII: .). Results: If Register A equals . then we were given a password, the Z FLAG is set; otherwise the NZ FLAG is set.
5284
JR Z,CHECK
     [528BH]
If the Z FLAG (Zero) has been set, then we were given only a password and drive number, so JUMP to 528BH.
5286
CP 2FH
Compare the value held in Register A against 2FH (ASCII: /). Results: If Register A equals / then we were given only an extension, password, and filename and the Z FLAG is set; otherwise the NZ FLAG is set.
5288
JP NZ,ERR2
      [5219H]
If the NZ FLAG (Not Zero) has been set then we weren’t given any of the above good parameters, so we have a problem, so JUMP to 5219H to report an ILLEGAL COMMAND PARAMETER error, and ABORT.

“CHECK”
528B
LD C,A
Copy the first character given for Filespec 2 (held in Register A) into Register C.
528C
LD B,00H
Set up Register B to be a counter by setting Register B to 00H.
528E
DEC HL
DECrement the value stored in Register Pair HL by 1 to point to the prior character.
“CHECK1”
528F
LD A,(DE)
Fetch the a character from Filespec 1 (held in the memory location pointed to by Register Pair DE) and store it into Register A.
5290
CP C
Compare the character from Filespec 2 (held in Register A) against the character from Filespec 1 (held in Register C). Results: If Register A equals the value held in Register C, the Z FLAG is set; otherwise the NZ FLAG is set.
5291
JR Z,CHECK2
     [529BH]
If first characters from each filespec match, the Z FLAG (Zero) will have been set. JUMP to 529BH.
5293
CP 03H
Compare the value held in Register A against 03H (i.e., EOF) to check for the end of the filename. Results: If Register A equals 03H, the Z FLAG is set; otherwise the NZ FLAG is set.
5295
JR Z,CHECK2
     [529BH]
If we reached the end of the filename, then the Z FLAG (Zero) will have been set. JUMP to 529BH.
5297
INC DE
Point Register Pair DE to the next character in Filespec 2 by bumping DE by 1.
5298
INC B
INCrement the counter stored in Register B by 1.
5299
JR CHECK1
   [528FH]
LOOP BACK to 528FH to check the next character.

529BH – Part of the COPY routine; jumped here if the filename characters match.

“CHECK2”
529B
DEC HL
DECrement the pointer to the characters in Filespec 2 (stored in Register Pair HL) by 1.
529C
DEC DE
DECrement the pointer to the characters in Filespec 1 (stored in Register Pair DE) by 1.
529D
LD A,(DE)
Fetch a character from Filespec 1 (held in the memory location pointed to by Register Pair DE) and store it into Register A.
529E
LD (HL),A
Store the character from Filespec 1 into the corresponding characters lot of Filespec 2 (the memory location pointed to by Register Pair HL).
529F
DJNZ 529BH
     [529BH]
LOOP back to 529BH, 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.
52A1
JR 5273H
   [5273H]
JUMP to 5273H to do another SYNTAX check.

52A3H – SUBROUTINE to bump the record number being processed and display that record number as being copied.

“DSPREC”
52A3
PUSH BC
Save the contents of Register Pair BC to the top of the stack.
52A4
PUSH DE
Save the contents of Register Pair DE to the top of the stack.
52A5
PUSH HL
Save the contents of Register Pair HL to the top of the stack.
52A6
LD HL,(RECCS)
Fetch the record number (held in memory location 52BAH) and store it into Register Pair HL.
52A9
INC HL
INCrement the record number (held in Register Pair HL) by 1.
52AA
LD (RECCS),HL
Store the bumped record number (held in Register Pair HL) into memory location 52BAH.
52AD
CALL ASCII
     [52BCH]
GOSUB to 52BCH to convert the new record number to ASCII and put it into the message “COPYING RECORD nnnnn“.
52B0
LD HL,52DCH
Let Register Pair HL equal 52DCH, so as to point to the message “COPYING RECORD nnnn“.
52B3
CALL 021BH
     [021BH]
GOSUB to 021BH.
NOTE: 021BH is the Model III ROM routine to display the character at (HL) until a 03H is found.
52B6
POP HL
Put the value held at the top of the STACK into Register Pair HL, and then remove the entry from the stack.
52B7
POP DE
Put the value held at the top of the STACK into Register Pair DE, and then remove the entry from the stack.
52B8
POP BC
Put the value held at the top of the STACK into Register Pair BC, and then remove the entry from the stack.
52B9
RET
RETurn to the caller.

52BAH – MESSAGE and STORAGE AREA.

“RECCS”
52BA
DEFB xx xx
Storage Area for the Record Number of the Record Currently Being Copied.

52BCH – Subroutine to convert the new record number to ASCII and put it into the message “COPYING RECORD nnnn“..

“ASCII”
52BC
CALL 0A9AH
     [0A9AH]
GOSUB to 0A9AH.
NOTE: 0A9AH is the Model III ROM routine to STORE AN INTEGER. The value in HL is put into the single precision number storage area of 4121H and is flagged as an INTEGER.
52BF
XOR A
Set Register A to ZERO and clear all Flags.
52C0
CALL 1034H
     [1034H]
GOSUB to 1034H.
NOTE: 1034H is the Model III ROM routine to initialize the buffer for an ASCII conversion. It checks the edit flag (at 40D8H), sets HL to point to a buffer at 4130H, and puts a space there.
52C3
OR (HL)
Set the NZ Flag.
52C4
CALL 0FD9H
     [0FD9H]
GOSUB to 0FD9H.
NOTE: 0FD9H is a routine which will convert the integer value in REG 1 (i.e., 4124H) to an ASCII string. Returns with register pair HL pointing to the result.
52C7
LD HL,4131H
Let Register Pair HL equal 4131H, to point to the ASCII converted number.
52CA
LD DE,RECNUM
Let Register Pair DE equal 52EDH, to point to the destination address in the message “COPYING RECORD nnnnn“.
52CD
LD B,05H
Let Register B equal 05H for a DJNZ loop of up to 5 characters.
“ASCII1”
52CF
LD A,(HL)
Fetch a converted character (held in the memory location pointed to by Register Pair HL) and store it into Register A.
52D0
CP 20H
Compare the value held in Register A against 20H (ASCII: SPACE). Results: If Register A equals SPACE, the Z FLAG is set; otherwise the NZ FLAG is set.
52D2
JR NZ,ASCII2
      [52D6H]
If it’s not a space (and the NZ FLAG [Not Zero] has been set) then we don’t need to fill it with zeroes, so skip over the next instruction.
52D4
LD A,30H
Let Register A equal 30H (ASCII: 0).
“ASCII2”
52D6
LD (DE),A
Store the ASCII character held in Register A into the memory location pointed to by Register Pair DE.
52D7
INC HL
INCrement the value stored in Register Pair HL by 1 to point to the next number to convert.
52D8
INC DE
INCrement the value stored in Register Pair DE by 1 to point to the next location in the message “COPYING RECORD nnnnn“.
52D9
DJNZ ASCII1
     [52CFH]
LOOP back to 52CFH, 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.
52DB
RET
RETurn to the caller.

52DCH – MESSAGE and STORAGE AREA.

“RECORD”
52DC
DEFM →
1DH + 1EH + ‘COPYING RECORD ‘“.
“RECNUM”
DEFM →
‘nnnnn’ + 03H“.

52F3H – Subroutine to display the message COPYING filespec 1 TO filespec 2.

“DISPLY”
52F3
LD HL,COPMSG
Let Register Pair HL equal 531AH to point to the message “COPYING“.
52F6
CALL 021BH
     [021BH]
GOSUB to 021BH.
NOTE: 021BH is the Model III ROM routine to display the character at (HL) until a 03H is found.
52F9
LD HL,S9DCB1
Let Register Pair HL equal 6162H which is the beginning of the SOURCE FILE DCB. This would then point to the text of FILESPEC 1.
52FC
CALL PRNTIT
     [5310H]
GOSUB to 5310H to display FILESPEC 1.
52FF
LD HL,TOO
Let Register Pair HL equal 5325H to point to the message “TO“.
5302
CALL 021BH
     [021BH]
GOSUB to 021BH.
NOTE: 021BH is the Model III ROM routine to display the character at (HL) until a 03H is found.
5305
LD HL,6194H
Let Register Pair DE equal 6194H to point to the DESTINATION FILE DCB, which starts with the filename.
5308
CALL PRNTIT
     [5310H]
GOSUB to 5310H to display FILESPEC 2.
530B
LD A,0DH
Let Register A equal 0DH (ASCII: CARRIAGE RETURN).
530D
JP 0033H
   [0033H]
JUMP to 0033H.
NOTE: 0033H is the Model III ROM character print routine; displays the character held in Register A at the current cursor position. Since this was JUMPED to instead of CALLed, the RET at the end of this ROM routine will then RETurn to the caller of this subroutine instead of returning to this place.

5310H – Subroutine of the Subroutine to display the message COPYING filespec 1 TO filespec 2. Parse the characters in the filespecs and display them.

“PRNTIT”
5310
LD A,(HL)
Fetch a charcter from the applicable filespec (held in the memory location pointed to by Register Pair HL) and store it into Register A.
5311
CP 21H
Compare the value held in Register A against / to see if we have reached the end of the filespec.
5313
RET C
If the character was a SPACE or lower, the C FLAG (Carry) has been set then we are at the end of the filespec so RETurn to the caller.
5314
CALL 0033H
     [0033H]
GOSUB to 0033H.
NOTE: 0033H is the Model III ROM character print routine; displays the character held in Register A at the current cursor position.
5317
INC HL
Point to the next character in the filespec by bumping Register Pair HL by 1.
5318
JR PRNTIT
   [5310H]
LOOP BACK to 5310H to keep displaying characters.

531AH – MESSAGE and STORAGE AREA.

“COPMSG”
531A
DEFM →

‘COPYING’ + 03H“.
“TOO”
5325
DEFM →

‘TO’ + 03H“.

532AH – Subroutine to display a flashing prompt of the message pointed to by Register Pair HL.

“S9WAIT”
532A
PUSH HL
Save the pointer to the message to be displayed (held in Register Pair HL) to the top of the stack.
532B
CALL 021BH
     [021BH]
GOSUB to 021BH.
NOTE: 021BH is the Model III ROM routine to display the character at (HL) until a 03H is found.
532E
POP HL
Restore the pointer to the message to be displayed (held at the top of the STACK) into Register Pair HL, and then remove the entry from the stack.
“LOOPY”
532F
LD BC,0256H
Let Register Pair BC equal 0256H to act as a timer.
“LOOPX”
5332
CALL 002BH
     [002BH]
GOSUB to 002BH.
NOTE: 002BH is the Model III ROM Keyboard scanning routine; Register A exits with the ASCII value for the key that was pressed or ZERO if no key was pressed.
5335
CP 0DH
Compare the value held in Register A against 0DH (ASCII: CARRIAGE RETURN). Results: If Register A equals CARRIAGE RETURN, the Z FLAG is set; otherwise the NZ FLAG is set.
5337
JR Z,LINOFF
     [534DH]
If we got a CARRIAGE RETURN from the user, the Z FLAG (Zero) will have been set; JUMP to 534DH.
“”
5339
DEC BC
DECrement the counter (stored in Register Pair BC) by 1.
533A
533A
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.
533C
JR NZ,LOOPX
      [5332H]
If the NZ FLAG (Not Zero) has been set, then we still have more counting to do, so LOOP BACK to 5332H.
533E
LD A,(FSFLAG)
Fetch the value of the flag held in memory location 54A7H and store it into Register A.
5341
XOR 01H
Toggle the flag.
5343
LD (FSFLAG),A
Store the toggled flag (held in Register A) back into memory location 54A7H.
5346
JR Z,SWAIT
     [532AH]
If the toggled flag hit 0, the Z FLAG (Zero) will have been set, JUMP to 532AH to redisplay.
5348
CALL LINOFF
     [534DH]
Otherwise we want to blank the line so it flashes via a GOSUB to 534DH.
534B
JR LOOPY
   [532FH]
Loop back to to 532FH.

534DH – Jump point in the subroutine to display a flashing prompt of the message pointed to by Register Pair HL. Jumped here if we got a CARRIAGE RETURN from the user.

“LINOFF”
534D
LD A,1DH
Let Register A equal 1DH (ASCII: Move cursor to start of line).
534F
CALL 0033H
     [0033H]
GOSUB to 0033H.
NOTE: 0033H is the Model III ROM character print routine; displays the character held in Register A at the current cursor position.
5352
LD A,1EH
Let Register A equal 1EH (ASCII: Clear to end of line).
5354
JP 0033H
   [0033H]
JUMP to 0033H.
NOTE: 0033H is the Model III ROM character print routine; displays the character held in Register A at the current cursor position. Since this was JUMPED to instead of CALLed, the RET at the end of this ROM routine will then RETurn to the caller of this subroutine instead of returning to this place.

5357H – Single Drive, Single File Copy Routine.

This routine finds out how much user ram is available, and reads the first file until EOF or memory full. Ask to swap disks and write until the file is written; swapping back if memory ran out before EOF.

“”
5357
LD HL,(4415H)
Fetch the address of the end of usable memory (held in memory location 4415H) and store it into Register Pair HL.
535A
LD DE,BUFER1
Let Register Pair DE equal 6300H to point to the READ FILE buffer.
535D
OR A
Set FLAGS based on the contents of Register A (and, in all events, clear the CARRY FLAG).
535E
SBC HL,DE
Determine the number of bytes left in RAM by subtracting the top of the buffer (6300H, stored in Register Pair DE) and the carry flag from the end of usable RAM (stored in Register Pair HL).
5360
LD DE,0100H
Let Register Pair DE equal 0100H (Decimal: 256), which is the size of 1 sector, to prepare for a division.
5363
LD B,00H
Let Register B equal 00H as B will be a counter of the number of blocks of available free RAM.
“LOOPZ”
5365
INC B
INCrement the block counter (stored in Register B) by 1.
5366
OR A
Set FLAGS based on the contents of Register A (and, in all events, clear the CARRY FLAG).
5367
SBC HL,DE
Do division by subtraction by subtracting (with carry) 256 (held in Register Pair DE) from the number of bytes of free RAM (held in Register Pair HL).
5369
JR NC,LOOPZ
      [5365H]
If that subtraction didn’t wind up going negative (so NC is set), then we can continue to divide, so JUMP to 5365H.
536B
LD A,B
Copy the number of blocks of free RAM (held in Register B) into Register A.
536C
DEC A
Round down by 1 block via a DECrement of Register A.
536D
LD (FLFAG),A
Store the number blocks of free RAM (held in Register A) into memory location 54A6H.
5370
LD HL,S9SRC
Let Register Pair HL equal 5487H, which is a pointer to the “1DH + “
‘Insert SOURCE Disk (ENTER) ‘ + 03H”
5373
CALL S9WAIT
     [532AH]
GOSUB to 532AH, which is the flashing prompt routine.
5376
CALL OPENIT
     [599BH]
We got the user response, so GOSUB to 599BH to open the source file.
5379
LD IX,S9DCB1
Let Special Index Register Pair IX equal 6162H which is the beginning of the SOURCE FILE DCB.
537D
RES 7,(IX+01H)
RESet (i.e., set as 0) BIT 7 of the value stored at the memory location pointed to by Register IX+01H so that the the LRL will be 256.
5381
LD A,(IX+09H)
Fetch the LRL (held in the memory location pointed to by Special Index Register Pair IX+09H) and store it into Register A.
Note: IX+09H = the position in the DCB for the LOGICAL RECORD LENGTH).
5384
LD (ADD1),A
Store the LRL (held in Register A) into memory location 56D5H.
5387
LD A,(IX+08H)
Fetch the byte of the EOF (held in the memory location pointed to by Special Index Register Pair IX+08H) and store it into Register A.
Note: IX+08H = the position in the DCB for the BYTE OFFSET IN THE SECTOR FOR LAST BYTE OF THE FILE).
538A
LD (56D6H),A
Store the byte of the EOF (held in Register A) into memory location 56D6H.
538D
XOR A
Set Register A to ZERO and clear all Flags, which also prepares to desginate a LRL of 256 (which is a force for FULL SECTOR I/O).
538E
LD (LRLCHG),A
Store the value held in Register A (i.e., a 0) into memory location 53A4H which is in the middle of a LD B,xx OPCODE.
5391
LD A,(IX+0CH)
Fetch the value held in the memory location pointed to by Special Index Register Pair IX+0CH and store it into Register A.
Note: IX+0CH = the position in the DCB for the NMSB OF THE LAST SECTOR TO READ/EOF)
5394
LD (56D7H),A
Store the value held in Register A into memory location 56D7H.
5397
LD A,(IX+0DH)
Fetch the value held in the memory location pointed to by Special Index Register Pair IX+0DH and store it into Register A.
Note: IX+0DH = the position in the DCB for the MSB OF THE LAST SECTOR TO READ/EOF)
539A
LD (56D8H),A
Store the value held in Register A into memory location 56D8H.
539D
LD HL,S9DES
Let Register Pair HL equal 5463H, which is a pointer to the “1DH + ‘Insert DESTINATION Disk (ENTER) ‘ + 03H” Message.
53A0
CALL S9WAIT
     [532AH]
GOSUB to 532AH, which is the flashing prompt routine.
53A3
LD B,LRLCHG
Let Register B equal the LRL placed here at 538EH.
53A5
LD DE,6194H
Let Register Pair DE equal 6194H to point to the DESTINATION FILE DCB.
53A8
LD HL,BUFER1
Let Register Pair HL equal 6300H to point to the beginning of the READ FILE buffer.
53AB
CALL 4420H
     [4420H]
GOSUB to 4420H.
NOTE: 4420H is the SYS00/SYS routine to INITIALIZE A FILE (i.e., CREATE or OPEN). This RST 28H’s with a value of A2H so as to call ROUTINE 2 in OVERLAY 2. Register HL needs to point to a RAM BUFFER for the DCB’s.
53AE
JP NZ,ERRX
      [5223H]
If the NZ FLAG (Not Zero) has been set, then that CALL returned an error; report the error and abort via a JUMP to 5223H.
“LOOPZ0”
53B1
LD HL,S9SRC
Let Register Pair HL equal 5487H, which is a pointer to the “1DH + “
‘Insert SOURCE Disk (ENTER) ‘ + 03H”
53B4
CALL S9WAIT
     [532AH]
GOSUB to 532AH, which is the flashing prompt routine.
53B7
LD HL,BUFER1
Let Register Pair HL equal 6300H to point to the beginning of the READ FILE buffer.
53BA
LD (6165H),HL
Store the pointer to the READ FILE BUFFER (held in Register Pair HL) into memory location 6165H, which is the DCB Buffer Address Location.
53BD
LD A,(FLFLAG)
Fetch the number of blocks of RAM (held in memory location 54A6H) and store it into Register A.
53C0
LD B,A
Copy the contents of Register A into Register B so that Register B can act as a DJNZ counter of blocks to read into RAM.
“LOOPZ1”
53C1
PUSH BC
Save the counter (held in Register Pair BC) to the top of the stack.
53C2
LD DE,S9DCB1
Let Register Pair DE equal 6162H which is the beginning of the SOURCE FILE DCB.
53C5
CALL 4436H
     [4436H]
Read 1 block via a GOSUB to 4436H.
NOTE: 4436H is the SYS00/SYS vector for ‘READ’, which reads the record that the disk drive is positioned over.
53C8
POP BC
Restore the counter from the top of the STACK into Register Pair BC, and then remove the entry from the stack.
53C9
JR Z,LOOPZ2
     [53D6H]
If the Z FLAG (Zero) has been set then there is no error, so JUMP to 53D6H.
53CB
CP 1CH
Compare the value held in Register A against 1CH (i.e., EOF ERROR). Results: If Register A equals 1CH, the Z FLAG is set; otherwise the NZ FLAG is set.
53CD
JR Z,GOGO
     [540EH]
If we have an EOF ERROR, then the Z FLAG (Zero) will have been set, BUT, we are done with the read anyway, so JUMP to 540EH.
53CF
CP 1DH
Compare the value held in Register A against 1DH (i.e., RECORD OUT OF RANGE ERROR). Results: If Register A equals 1DH, the Z FLAG is set; otherwise the NZ FLAG is set.
53D1
JR Z,GOGO
     [540EH]
If we have an RECORD OUT OF RANGE ERROR, then the Z FLAG (Zero) will have been set, BUT, we are done with the read anyway, so JUMP to 540EH.
53D3
JP ERRX
   [5223H]
If we’re here, then we have another error that we do care about; report the error and abort via a JUMP to 5223H.

53D6H – Continuation of SINGLE FILE, SINGLE DRIVE Copy – Jumped here when a block as successfully been read into the READ FILE BUFFER.

“LOOPZ2”
53D6
LD HL,(6165H)
Fetch the pointer to DCB Buffer Address in the READ FILE BUFFER (held at 6165H) into Register Pair HL.
53D9
LD DE,0100H
Let Register Pair DE equal 0100H (Decimal: 256), which is 1 block.
53DC
ADD HL,DE
Move to the next block of RAM in the READ BUFFER by bumping the READ BUFFER forward 256 bytes (1 block).
53DD
LD (6165H),HL
Store the newly bumped pointer to DCB Buffer Address in the the READ FILE BUFFER (held in Register Pair HL) into memory location 6165H, which is the DCB Buffer Address Location.
53E0
DJNZ LOOPZ1
     [53C1H]
LOOP back to 53C1H to keep reading until the buffer is full, 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, the READ RAM buffer has been filled, so now we need to write it to disk.

53E2
LD HL,S9DES
Let Register Pair HL equal 5463H, which is a pointer to the “1DH + ‘Insert DESTINATION Disk (ENTER) ‘ + 03H” Message.
53E5
CALL S9WAIT
     [532AH]
GOSUB to 532AH, which is the flashing prompt routine.
53E8
LD HL,BUFER1
Let Register Pair HL equal 6300H to point to the beginning of the READ FILE buffer.
53EB
LD (6165H),HL
Store the READ FILE buffer into the address for the read DCB buffer pointer, resetting it.
53EE
LD (6197H),HL
Store the DCB Buffer Address (held in Register Pair HL) into the DCB Buffer Address for the DESTINATION FILE BUFFER (held in 6197H).
53F1
LD A,(FLFLAG)
Fetch the buffer size in blocks (held in memory location 54A6H) and store it into Register A.
53F4
LD B,A
Copy the contents of Register A into Register B so that Register B can act as a DJNZ counter of blocks to read into RAM.
“LOOPZ3”
53F5
PUSH BC
Save the block counter (held in Register Pair BC) to the top of the stack.
53F6
LD DE,6194H
Let Register Pair DE equal 6194H to point to the DESTINATION FILE DCB.
53F9
CALL 443CH
     [443CH]
Write with Verify via a CALL to 443CH
NOTE: 443CH is the SYS00/SYS vector for ‘WRITE with VERIFY’, which will write verify a write with a retry count of 3. DE must point to the buffer to write.
53FC
POP BC
Restore the block counter (held at the top of the STACK) into Register Pair BC, and then remove the entry from the stack.
53FD
JP NZ,ERRX
      [5223H]
If the NZ FLAG (Not Zero) has been set, then that CALL returned an error; report the error and abort via a JUMP to 5223H.
5400
LD HL,(6197H)
LD HL,(6197H)
Fetch the DCB Buffer Address in the DESTINATION FILE BUFFER (held in memory location 6197H) and store it into Register Pair HL.
5403
LD DE,0100H
Let Register Pair DE equal 0100H (Decimal: 256), which is 1 block.
5406
ADD HL,DE
Bump the DCB Buffer Address in the the DESTINATION FILE BUFFER by 256 (which is 1 block) to point to the next block to write.
5407
LD (6197H),HL
LD (6197H),HL
Store the bumped DCB Buffer Address (held in Register Pair HL) into the DCB Buffer Address for the DESTINATION FILE BUFFER (held in 6197H).
540A
DJNZ LOOPZ3
     [53F5H]
LOOP back to 53F5H, 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.
540C
JR LOOPZ0
   [53B1H]
JUMP to 53B1H to move to the next read.

540EH – Continuation of SINGLE FILE, SINGLE DRIVE Copy – Jumped here to write out what we have if we had a (harmless) EOF error or Records Out of Range error.

“GOGO”
540E
LD A,(FLFLAG)
Fetch the size of the RAM buffer (in blocks) (held in memory location 54A6H) and store it into Register A.
5411
SUB B
LET Register A = the size of the RAM buffer (held in Register A) – the number of blocks we have actually read so far (held in Register B).
5412
LD B,A
Copy the contents of Register A into Register B so that B can act as a counter.
5413
PUSH BC
Save the block counter (held in Register Pair BC) to the top of the stack.
5414
LD HL,S9DES
Let Register Pair HL equal 5463H, which is a pointer to the “1DH + ‘Insert DESTINATION Disk (ENTER) ‘ + 03H” Message.
5417
CALL S9WAIT
     [532AH]
GOSUB to 532AH, which is the flashing prompt routine.
541A
LD HL,BUFER1
Let Register Pair HL equal 6300H to point to the beginning of the READ FILE buffer.
541D
LD (6197H),HL
LD (6197H),HL
Store the DCB Buffer Address (held in Register Pair HL) into the DCB Buffer Address for the DESTINATION FILE BUFFER (held in 6197H).
5420
POP BC
Restore the block counter (held at the top of the STACK) into Register Pair BC.
“GOGO1”
5421
PUSH BC
Save the block counter (held in Register Pair BC) to the top of the stack.
5422
LD DE,6194H
Let Register Pair DE equal 6194H to point to the DESTINATION FILE DCB (of 6194H).
5425
CALL 443CH
     [443CH]
Write with Verify via a CALL to 443CH
NOTE: 443CH is the SYS00/SYS vector for ‘WRITE with VERIFY’, which will write verify a write with a retry count of 3. DE must point to the buffer to write.
5428
POP BC
Restore the block counter (held at the top of the STACK) into Register Pair BC.
5429
JP NZ,ERRX
      [5223H]
If the NZ FLAG (Not Zero) has been set, then that CALL returned an error; report the error and abort via a JUMP to 5223H.
542C
LD HL,(6197H)
LD HL,(6197H)
Fetch the DCB Buffer Address in the DESTINATION FILE BUFFER (held in memory location 6197H) and store it into Register Pair HL.
542F
LD DE,0100H
Let Register Pair DE equal 0100H (Decimal: 256), which is 1 block.
5432
ADD HL,DE
Bump the DCB Buffer Address in the the DESTINATION FILE BUFFER by 256 (which is 1 block) to point to the next block of RAM to write.
5433
LD (6197H),HL
LD (6197H),HL
Store the bumped DCB Buffer Address (held in Register Pair HL) into the DCB Buffer Address for the DESTINATION FILE BUFFER (held in 6197H).
5436
DJNZ GOGO1
     [5421H]
LOOP back to 5421H, 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, the buffers have been written, but the EOF cannot simply be transferred because of the EOF / RECORD OUT OF RANGE error on the read, so we need to recalculate and set the appropriate EOF.

5438
LD IX,6194H
Let Special Index Register IX equal 6194H to point to the DESTINATION FILE DCB (of 6194H).
543C
LD A,(ADD1)
Fetch the LRL (held in memory location 56D5H) and store it into Register A.
543F
LD (IX+09H),A
Store the value held in Register A into the memory location pointed to by Special Index Register Pair IX+09H.
Note: IX+09H = the position in the DCB for the LOGICAL RECORD LENGTH).
5442
LD A,(56D6H)
Fetch the byte of EOF (held in memory location 56D6H) and store it into Register A.
5445
LD (IX+08H),A
Store the value held in Register A into the memory location pointed to by Special Index Register Pair IX+08H.
Note: IX+08H = the position in the DCB for the BYTE OFFSET IN THE SECTOR FOR LAST BYTE OF THE FILE).
5448
LD A,(56D7H)
Fetch the LSB of the SECTOR EOF (held in memory location 56D7H) and store it into Register A.
544B
LD (IX+0CH),A
Store the value held in Register A into the memory location pointed to by Special Index Register Pair IX+0CH.
Note: IX+0CH = the position in the DCB for the NMSB OF THE LAST SECTOR TO READ/EOF)
544E
LD A,(56D8H)
Fetch the MSB of the SECTOR EOF (held in memory location 56D8H) and store it into Register A.
5451
LD (IX+0DH),A
Store the value held in Register A into the memory location pointed to by Special Index Register Pair IX+0DH.
Note: IX+0DH = the position in the DCB for the MSB OF THE LAST SECTOR TO READ/EOF)
5454
LD DE,6194H
Let Register Pair DE equal 6194H to point to the DESTINATION FILE DCB (of 6194H).
5457
CALL 4428H
     [4428H]
GOSUB to 4428H to CLOSE the file
NOTE: 4428H is the SYS00/SYS routine to CLOSE A DISK FILE. This RST 28H’s with a value of 93H so as to call ROUTINE 1 in OVERLAY 3.
545A
LD HL,S9SRC
Let Register Pair HL equal 5487H, which is a pointer to the “1DH + “
‘Insert SOURCE Disk (ENTER) ‘ + 03H”
545D
CALL S9WAIT
     [532AH]
GOSUB to 532AH, which is the flashing prompt routine.
5460
JP CCLSE1
   [5551H]
JUMP to 5551H to close the file and exit.

5463H – MESSAGE and STORAGE AREA.

“DEF9DES”
5463
DEFM →
“1DH + ‘Insert DESTINATION Disk (ENTER) ‘ + 03H” Message.
“DEF9SRC”
5487
DEFM →
“1DH + “
‘Insert SOURCE Disk (ENTER) ‘ + 03H”.
“FLFLAG”
54A6
DEFB 00H
Number of blocks available in RAM to use for the copy.
“FSFLAG”
54A7
DEFB 00H
Toggle for the flash in the flashing message.

54B9H – SINGLE DRIVE COPY ROUTINE – See if the user has selected the drives to make this a single drive copy. This portion parses both for a drive number, and defaults to “0” if none.

“COPY9”
54A8
LD HL,S9DCB1
Let Register Pair HL equal 6162H which is the beginning of the SOURCE FILE DCB, and, in specific, the filespec (which appears at the beginning of the DCB).
54AB
LD B,18H
Let Register B equal 18H (Decimal: 24) for a count of 24, which is (1 more than) the number of characters in filename/ext.password:d.
“COP90”
54AD
LD A,(HL)
Fetch a character from filespec in the SOURCE FILE DCB (the memory location pointed to by Register Pair HL) and store it into Register A.
54AE
CP 3AH
Compare the value held in Register A against 3AH (ASCII: :) to test for a drivespec.
“”
54B0
INC HL
INCrement the pointer to the SOURCE FILE DCB (held in Register HL) by 1 to point to the next character.
54B1
JR Z,COP91
     [54B9H]
If we got a “:” then the Z FLAG (Zero) would have been set, so JUMP to 54B9H to test the drive.
54B3
DJNZ COP90
     [54ADH]
Parse the entire filespec portion of the SOURCE FILE DCB by LOOPing back to 54ADH, 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.
54B5
LD C,30H
Let Register C equal 30H (ASCII: 0) as a default drive.
54B7
JR COP910
   [54BAH]
JUMP to 54BAH to process the SOURCE FILE with a drive of “0” (i.e., skip the next instruction which sets Register C to something else).

54B9H – Continuation of the routine to see if the user has selected the drives to make this a single drive copy; jumped here if a we got a “:” in the SOURCE FILE DCB.

“COP91”
54B9
LD C,(HL)
Fetch a character from filespec held in the SOURCE FILE DCB (the memory location pointed to by Register Pair HL), which is hopefuly a drive number since it follows a “:”, into Register C.
“COP910”
54BA
LD HL,6194H
Let Register Pair HL equal 6194H to point to the DESTINATION FILE DCB, which will also point to the filespec in the DESTINATION FILE DCB.
54BD
LD B,18H
Let Register B equal 18H (Decimal: 24) for a count of 24, which is (1 more than) the number of characters in filename/ext.password:d.
“COP92”
54BF
LD A,(HL)
Fetch a character from the filespec of the DESTINATION FILE DCB (the memory location pointed to by Register Pair HL) and store it into Register A.
54C0
CP 3AH
Compare the value held in Register A against 3AH (ASCII: :) to test for a drivespec.
54C2
INC HL
INCrement the pointer to the DESTINATION FILE DCB (held in Register HL) 1 to the next character.
54C3
JR Z,COP93
     [54CBH]
If we got a “:” then the Z FLAG (Zero) would have been set, so JUMP to 54B9H to test the drive.
54C5
DJNZ COP92
     [54BFH]
Parse the entire filespec portion of the DESTINATION FILE DCB by LOOPing back to 54BFH, 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.
54C7
LD A,30H
Let Register A equal 30H (ASCII: 0) as a default drive.
54C9
JR COP930
   [54CCH]
JUMP to 54CCH to process the DESTINATION FILE with a drive of “0” (i.e., skip the next instruction which sets Register C to something else).

54CBH – Continuation of the routine to see if the user has selected the drives to make this a single drive copy; check the two drive numbers (held in A and C) to see if they match.

“COP93”
54CB
LD A,(HL)
Fetch a the drive number from the DESTINATION FILE DCB (the memory location pointed to by Register Pair HL) and store it into Register A.
“COP930”
54CC
CP C
Compare the drive number from the DESTINATION FILE DCB (held in Register a) against the drive number from the READ FILE DCB (held in Register C). Results: If Register A equals the value held in Register C, the Z FLAG is set; otherwise the NZ FLAG is set.
54CD
JP Z,SINGCP
     [5357H]
If they match, then the Z FLAG (Zero) will have been set; JUMP to 5357H to do a single drive copy.

54D0H – Dual Drive copy roputine.

“COPY0”
54D0
CALL DISPLY
     [52F3H]
GOSUB to 52F3H to display the message COPYING filespec 1 TO filespec 2.
54D3
LD HL,0FFFFH
Let Register Pair HL equal 0FFFFH (i.e., -1) to act as a counter.
54D6
LD (RECCS),HL
Store the value held in Register Pair HL into memory location 52BAH, which tracks the RECORD NUMBER BEING COPIED.
54D9
CALL OPENIT
     [599BH]
OPEN the file via a GOSUB to 599BH.
54DC
JP NZ,ERRX
      [5223H]
If the NZ FLAG (Not Zero) has been set, then that CALL returned an error; report the error and abort via a JUMP to 5223H.
54DF
LD B,LRLCH1
Let Register B equal the value put into 54E0H elsewhere, which, if 0, is a LRL of 256.
54E1
LD DE,6194H
Let Register Pair DE equal 6194H to point to the DESTINATION FILE DCB.
54E4
LD HL,6400H
Let Register Pair HL equal 6400H to point to the beginning of the DESTINATION FILE buffer.
54E7
CALL 4420H
     [4420H]
Create the destination file via a GOSUB to 4420H.
NOTE: 4420H is the SYS00/SYS routine to INITIALIZE A FILE (i.e., CREATE or OPEN). This RST 28H’s with a value of A2H so as to call ROUTINE 2 in OVERLAY 2. Register HL needs to point to a RAM BUFFER for the DCB’s.
54EA
JP NZ,ERRX
      [5223H]
If the NZ FLAG (Not Zero) has been set, then that CALL returned an error; report the error and abort via a JUMP to 5223H.
“CONTT”
54ED
CALL DSPREC
     [52A3H]
Display the record number via a GOSUB to 52A3H.
54F0
LD DE,S9DCB1
Let Register Pair DE equal equal 6162H which is the beginning of the SOURCE FILE DCB.
54F3
LD HL,6200H
Let Register Pair HL equal 6200H to point to the SOURCE FILE DCB at 6200H (which is used for non 256 LRL files).
54F6
CALL 4436H
     [4436H]
Read a record from the SOUCE FILE into the buffer pointed to by Register Pair HL via a GOSUB to 4436H.
NOTE: 4436H is the SYS00/SYS vector for ‘READ’, which reads the record that the disk drive is positioned over.
54F9
JR Z,NEXT
     [5506H]
If the Z FLAG (Zero) has been set then there was no error, so do the WRITE via a JUMP to 5506H.
54FB
CP 1CH
Compare the value held in Register A against 1CH (i.e., EOF ERROR). Results: If Register A equals 1CH, the Z FLAG is set; otherwise the NZ FLAG is set.
54FD
JR Z,DONE0
     [5525H]
If the Z FLAG (Zero) has been set we have an EOF error, but we are also done; so JUMP to 5525H.
54FF
CP 1DH
Compare the value held in Register A against 1DH (i.e., RECORD OUT OF RANGE ERROR). Results: If Register A equals 1DH, the Z FLAG is set; otherwise the NZ FLAG is set.
5501
JR Z,DONE0
     [5525H]
If the Z FLAG (Zero) has been set we have a RECORD OUT OF RANGE error, but we are also done, so JUMP to 5525H.
5503
JP ERRX
   [5223H]
If we’re here then we have an error we care about, so report the error and abort via a JUMP to 5223H.

5506H – Copy the READ FILE BUFFER to the DESTINATION FILE BUFFER, and WRITE.

“NEXT”
5506
LD A,(616BH)
Fetch the LRL of the SOURCE FILE (held in memory location 616BH) and store it into Register A.
5509
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).
550A
JR NZ,NEXTV
      [5517H]
If the NZ FLAG (Not Zero) has been set, then we do not have a LRL of 256, so JUMP to 5517H.
550C
LD HL,BUFER1
Let Register Pair HL equal 6300H to point to the beginning of the READ FILE buffer.
550F
LD DE,6400H
Let Register Pair DE equal 6400H to point to the beginning of the DESTINATION FILE buffer.
5512
LD BC,0100H
Let Register Pair DE equal 0100H (Decimal: 256) to prepare for a LDIR move of 256 bytes.
5515
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.
“NEXTV”
5517
LD DE,6194H
Let Register Pair DE equal 6194H to point to the DESTINATION FILE DCB.
551A
LD HL,6200H
Let Register Pair HL equal 6200H to point to buffer number 4 (which is used for non 256 LRL files).
551D
CALL 4439H
     [4439H]
Write out the record via a GOSUB to 4439H.
5520
JR Z,54EDH
     [54EDH]
If the Z FLAG (Zero) has been set then the write was successful, so do move via a LOOP BACK to 54EDH.
5522
JP ERRX
   [5223H]
Report the error and abort via a JUMP to 5223H.

5525H – The copy routine has completed but with a (harmless) EOF or RECORD OUT OF RANGE ERROR.

“DONE0”
5525
LD A,(616BH)
Fetch the LRL of the SOURCE FILE (held in memory location 616BH) and store it into Register A.
5528
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).
5529
JR NZ,DONE1
      [5542H]
If the NZ FLAG (Not Zero) has been set, then the LRL is not a standard 256 (i.e., we do not have a full sector), so JUMP to 5542H to deal with that.
552B
LD A,(616AH)
Fetch the EOF BYTE of the SOURCE FILE (held in memory location 616AH) and store it into Register A.
552E
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).
552F
JR Z,5542H
     [5542H]
If the Z FLAG (Zero) has been set, then the EOF is on the sector boundary and we don’t need to do any special math to calculate it, so continue via a JUMP to 5542H.

If we are here then we need to specially calculate the EOF.

5531
LD IX,6194H
Let Special Index Register IX equal 6194H to point to the DESTINATION FILE DCB.
5535
LD L,(IX+0CH)
Fetch the value held in the memory location pointed to by Special Index Register Pair IX+0CH and store it into Register L.
Note: IX+0CH = the position in the DCB for the LSB OF THE LAST SECTOR TO READ/EOF)
5538
LD H,(IX+0DH)
Fetch the value held in the memory location pointed to by Special Index Register Pair IX+0DH and store it into Register H.
Note: IX+0DH = the position in the DCB for the MSB OF THE LAST SECTOR TO READ/EOF)
553B
DEC HL
DECrement the value stored in Register Pair HL by 1 to back up the EOF one record.
553C
LD (IX+0CH),L
Store the adjusted EOF byte held in Register L into the memory location pointed to by Special Index Register Pair IX+0CH.
Note: IX+0CH = the position in the DCB for the NMSB OF THE LAST SECTOR TO READ/EOF)
553F
LD (IX+0DH),H
Store the adjusted EOF byte held in Register H into the memory location pointed to by Special Index Register Pair IX+0DH.
Note: IX+0DH = the position in the DCB for the MSB OF THE LAST SECTOR TO READ/EOF)
“DONE1”
5542
LD A,(616AH)
Fetch the EOF BYTE of the SOURCE FILE (held in memory location 616AH) and store it into Register A.
5545
LD (619CH),A
Store the the EOF BYTE of the SOURCE FILE (held in Register A) into the DESTINATION FILE DCB (held at memory location 619CH).
“CCLSE”
5548
LD DE,6194H
Let Register Pair DE equal 6194H to point to the DESTINATION FILE DCB.
554B
CALL 4428H
     [4428H]
GOSUB to 4428H to CLOSE the file
NOTE: 4428H is the SYS00/SYS routine to CLOSE A DISK FILE. This RST 28H’s with a value of 93H so as to call ROUTINE 1 in OVERLAY 3.
554E
JP NZ,ERRX
      [5223H]
If the NZ FLAG (Not Zero) has been set, then that CALL returned an error; report the error and abort via a JUMP to 5223H.
“CCLSE1”
5551
LD DE,S9DCB1
Let Register Pair DE equal equal 6162H which is the beginning of the SOURCE FILE DCB.
“CCLSE2”
5554
CALL 4428H
     [4428H]
GOSUB to 4428H to CLOSE the file
NOTE: 4428H is the SYS00/SYS routine to CLOSE A DISK FILE. This RST 28H’s with a value of 93H so as to call ROUTINE 1 in OVERLAY 3.
5557
JP NZ,ERRX
      [5223H]
If the NZ FLAG (Not Zero) has been set, then that CALL returned an error; report the error and abort via a JUMP to 5223H.
555A
RET
RETurn to the caller.

555BH – MESSAGE and STORAGE AREA.

“DRIVE1”
531A
DEFM “:0” + 0DH
Storage for the SOURCE DRIVESPEC.
“DRIVE2”
555E
DEFM “:1” + 0DH
Storage for the DESTINATION DRIVESPEC.
“ZSLANT”
5561
DEFM “/”
Storage for an extension (part 1). This would also be thhe wild-card extension.
“S9CMD”
5562
DEFM “BAS”
Storage for an extension (part 2).
“SAVE3”
5565
DEFW 00H 43H
Buffer Starting Address
“S9TRK”
5567
DEFB 00H
Storage for the current/desired sector number in the directory sector.

5568H – Read the Directory Track into a Buffer at 4300H.

“GETDIR”
5568
LD A,(DRIVE1 + 1)
Fetch the drive number (held in memory location 555CH) and store it into Register A.
556B
AND 0FH
MASK the value of Register A against 0FH (0000 1111) to leave only bits 3, 2, 1, 0 active; basically turning the ASCII into BINARY.
556D
LD C,A
Copy binary rendition of the drive number (held in Register A) into Register C.
556E
CALL 4B3EH
     [4B3EH]
Get the directory track via a GOSUB to 4B3EH.
NOTE: 4B3EH is the SYS00/SYS routine to identify the track number of the directory. Routine exits with the director track number in Register D.
5571
LD A,(S9TRK)
Fetch the directory sector we want to read (held in memory location 5567H) and store it into Register A.
5574
LD E,A
Copy the the directory sector we want to read (held in Register A) into Register E.
5575
LD HL,4300H
Let Register Pair HL equal 4300H, whiich will be a buffer.
5578
CALL 4675H
     [4675H]
GOSUB to 4675H of SYS00/SYS to position the drive head and read the requested sector into the buffer pointed to by Register Pair HL.
557B
RET
RETurn to the caller.

557CH – Routine to transfer B number of characters from (DE) to (IX), aborting if a SPACE is found.

“MOVE1”
557C
LD A,(DE)
Fetch a character held in the memory location pointed to by Register Pair DE and store it into Register A.
557D
CP 20H
Compare the value held in Register A against 20H (ASCII: SPACE).
557F
POP IY
In case there is a match, and we therefore have an illegal character, and we need to clear the return address from the top of the STACK.
5581
JP Z,ERR2
     [5219H]
If we got a SPACE, which is bad, the Z FLAG (Zero) will have been set, so JUMP to 5219H to report an ILLEGAL COMMAND PARAMETER error, and ABORT.
5584
PUSH IY
If we are here, then we didn’t get an illegal character, so put the return address back to the top of the stack.
5586
LD (IX),A
Store the character we read (held in Register A) into the memory location pointed to by Special Index Register Pair IX+00H.
Note: IX+00H = the position in the DCB for the TYPE of FCB byte. Bit 0: 1=Read Only, Bit 1: 1=Write Only, Bit 4: 1=The next 2 bytes are simply the address of another FCB, Bit 7=1: Then the next 50 bytes are the description of an open file.
5589
INC DE
INCrement the value stored in Register Pair DE by 1 to point to the next character to test.
558A
INC IX
INCrement the value stored in Special Index Register IX by 1 to move to the next area to save the character to.
558C
DJNZ MOVE1
     [557CH]
LOOP back to 557CH, 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.
558E
RET
RETurn to the caller.

558FH – Routine to copy a filename from the directory entry (pointed to by DE) into the DCB (pointed to HL); returns with Register C containing the number of characters in the filename.

“MOVE2”
558F
LD B,08H
Let Register B equal 08H as there are 8 characters in a filespec.
“MOVE20”
5591
LD A,(DE)
Fetch a character (held in the memory location pointed to by Register Pair DE) and store it into Register A.
5592
CP 20H
Compare the value held in Register A against 20H (ASCII: SPACE).
5594
RET Z
If we got a SPACE then we are done; so RETURN.
5595
LD (HL),A
If we are here, the character is good, so store the character (held in Register A) into the DCB (pointed to by Register Pair HL).
5596
INC C
INCrement the counter (Register C) by 1.
5597
INC HL
INCrement the pointer for the destination (stored in Register Pair HL) by 1.
5598
INC DE
INCrement the pointer for the source (stored in Register Pair DE) by 1.
5599
DJNZ MOVE20
     [5591H]
LOOP back to 5591H for up to 8 iterations, 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.
559B
RET
RETurn to the caller.

559CH – Routine to copy an extension from the directory entry (pointed to by DE) into the DCB (pointed to HL); returns with Register C containing the number of characters in the extension.

“MOVE3”
559C
LD B,04H
Let Register B equal 04H, which is the number of characters in an extension (including the delimeter).
“MOVE30”
559E
LD A,(DE)
Fetch a character (held in the memory location pointed to by Register Pair DE) and store it into Register A.
559F
LD (HL),A
Store the character (held in Register A) into the memory location pointed to by Register Pair HL.
55A0
INC C
INCrement the counter (Register C) by 1.
55A1
INC HL
INCrement the pointer for the destination (stored in Register Pair HL) by 1.
55A2
INC DE
INCrement the pointer for the source (stored in Register Pair DE) by 1.
55A3
DJNZ MOVE30
     [559EH]
LOOP back to 559EH for up to 4 iterations, 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.
55A5
RET
RETurn to the caller.

55A6H – Routine to the drivespec from the directory entry (pointed to by DE) into the DCB (pointed to HL).

“MOVE4”
55A6
LD B,03H
Let Register B equal 03H, for a count of 3 characters.
“MOVE40”
55A8
LD A,(DE)
Fetch a character (held in the memory location pointed to by Register Pair DE) and store it into Register A.
55A9
LD (HL),A
Store the character (held in Register A) into the memory location pointed to by Register Pair HL.
55AA
INC HL
INCrement the pointer for the destination (stored in Register Pair HL) by 1.
55AB
INC DE
INCrement the pointer for the source (stored in Register Pair DE) by 1.
55AC
DJNZ 55A8H
     [55A8H]
LOOP back to 55A8H for up to 3 iterations, 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.
55AE
RET
RETurn to the caller.

55AFH – Routine to Skip Spaces in DE and Point to the next Non-Blank Character.

“SKSP”
55AF
LD A,(DE)
Fetch a character (held in the memory location pointed to by Register Pair DE) and store it into Register A.
55B0
CP 20H
Compare the value held in Register A against 20H (ASCII: SPACE).
55B2
RET NZ
If the NZ FLAG (Not Zero) has been set, RETurn to the caller.
55B3
INC DE
INCrement the pointer for the source (stored in Register Pair DE) by 1.
55B4
JR SKSP
   [55AFH]
Loop back to 55AFH to keep parsing.

55B6H – This routine gets called if the user entered a wildcard copy command such as “COPY /EXT:x :x”.

“SLANT”
55B6
INC DE
INCrement the command line pointer (stored in Register Pair DE) by 1.
55B7
LD IX,S9CMD
Let Special Index Register Pair IX equal the extension storage area of 5562H.
55BB
LD B,03H
Let Register B equal 03H, the length of an extension without the “/” delimeter.
55BD
CALL MOVE1
     [557CH]
Transfer characters the number of characters held in Register B from (DE) to (IX), aborting if a SPACE is found via a GOSUB to 557CH.
55C0
LD A,(DE)
Fetch the next character from the COMMAND LINE (held in the memory location pointed to by Register Pair DE) and store it into Register A.
55C1
CP 3AH
Compare the value held in Register A against 3AH (ASCII: :). Results: If Register A equals :, the Z FLAG is set; otherwise the NZ FLAG is set.
55C3
JP NZ,ERR2
      [5219H]
If we got a “:” then are good; but if we didn’t then the NZ FLAG (Not Zero) will have been set, so JUMP to 5219H to report an ILLEGAL COMMAND PARAMETER error, and ABORT.
55C6
LD IX,DRIVE1
Let Special Index Register Pair IX point to the read drive save area.
55CA
LD B,02H
Let Register B equal 02H to move 2 characters (:d).
55CC
CALL MOVE1
     [557CH]
Get the SOURCE filespec by transfering characters the number of characters held in Register B from (DE) to (IX), aborting if a SPACE is found via a GOSUB to 557CH.
55CF
CALL SKSP
     [55AFH]
GOSUB to 55AFH to skip spaces pointed to by Register Pair DE and point to the next Non-Blank character pointed to by Register Pair DE.
55D2
CP 3AH
Compare the value held in Register A against 3AH (ASCII: :). Results: If Register A equals :, the Z FLAG is set; otherwise the NZ FLAG is set.
55D4
JP NZ,ERR2
      [5219H]
If we got a “:” then are good; but if we didn’t then the NZ FLAG (Not Zero) will have been set, so JUMP to 5219H to report an ILLEGAL COMMAND PARAMETER error, and ABORT.
55D7
LD IX,DRIVE2
Let Special Index Register Pair IX point to the destination drive save area.
55DB
LD B,02H
Let Register B equal 02H to move 2 characters (:d).
55DD
CALL MOVE1
     [557CH]
Transfer characters the number of characters held in Register B from (DE) to (IX), aborting if a SPACE is found via a GOSUB to 557CH.
55E0
LD A,(DRIVE2+1)
Fetch the 2nd character pointing to the destination drive save area (held in memory location 555FH) and store it into Register A.
55E3
CP 34H
Compare the value held in Register A against 34H (ASCII: 4). Results:
  • If Register A equals 4, the Z FLAG is set.
  • If A < 4, the CARRY FLAG will be set.
  • if A >= 4, the NO CARRY FLAG will be set.
55E5
JP NC,5221H
      [5221H]
If the destination drive is greater than or equal to A >= 4, we have a bad drive, and the If the NC FLAG (No Carry) will have been set, JUMP to 5221H to report the error “Drive not in System” and abort.

55E8H – Common Routine for COPY and KILL – Wild Card Search Routine.

“SLANT0”
55E8
LD A,03H
Let Register A equal 03H to point to the beginning of the directory, which is sector 3 of the directory track.
55EA
LD (S9TRK),A
Store the value held in Register A (i.e., 03H) into the memory location (5567H) which holds the directory sector we want to read.
55ED
LD A,(DRIVE1+1)
Fetch the READ DRIVE DRIVE NUMBER (held in memory location 555CH) and store it into Register A.
55F0
CP 34H
Compare the value held in Register A against 34H (ASCII: 4). Results:
  • If Register A equals 4, the Z FLAG is set.
  • If A < 4, the CARRY FLAG will be set.
  • if A >= 4, the NO CARRY FLAG will be set.
55F2
JP NC,5221H
      [5221H]
If the source drive is greater than or equal to A >= 4, we have a bad drive, and the If the NC FLAG (No Carry) will have been set, JUMP to 5221H to report the error “Drive not in System” and abort.
55F5
LD B,10H
Let Register B equal 10H (Decimal: 16), which is the number of directory records, so that Register B can act as a counter.
“TOTAL”
55F7
PUSH BC
Save the counter (held in Register Pair BC) to the top of the stack.
55F8
CALL GETDIR
     [5568H]
Read the Directory into 4300H via a GOSUB to 5568H.
55FB
LD DE,4300H
Let Register Pair DE equal 4300H to point to the start of the directory sector in RAM.
55FE
LD (SAVE3),DE
Store the buffer start pointer (held in Register Pair DE) into memory location 5565H.
“TOTAL0”
5602
LD A,(DE)
Fetch a character from directory (held in the memory location pointed to by Register Pair DE) and store it into Register A.
5603
CP 10H
Compare the value held in Register A against 10H (0001 0000) to see if it is protected in any way. Results: If Register A equals 10H, the Z FLAG is set; otherwise the NZ FLAG is set.
5605
JR NZ,TOTNXT
      [564EH]
If the file is protected, then the NZ FLAG (Not Zero) will have been set, so skip this file by JUMPing to 564EH.

If we are here, then the file CAN be copied or killed, next we need to see if the user supplied extension matches the filename’s extension.

5607
LD A,E
Copy the LSB of the directory pointer (held in Register E) into Register A.
5608
ADD A,0DH
LET Register A = Register A + 0DH so as to now point to the filename extension of the current file.
560A
LD E,A
Copy the poiner to the extent (held in Register A) back into Register E.
560B
LD HL,S9CMD
Let Register Pair HL point to the user requested filename extension held at 5562H.
560E
LD B,03H
Let Register B equal 03H to prepare for 3 characters, as we need to compare the user requested exension against the extension of the current file.
“TOTAL1”
5610
LD A,(DE)
Fetch a character from the file’s extension from the directory (held in the memory location pointed to by Register Pair DE) and store it into Register A.
5611
CP (HL)
Compare the character from the file’s extension from the directory (held in Register A) against the value requested by the user (held in the memory location pointed to by the value held in Register Pair HL). Results: If Register they match, the Z FLAG is set; otherwise the NZ FLAG is set.
5612
JP NZ,TOTNXT
      [564EH]
If the don’t match, then the NZ FLAG (Not Zero) will have been set, and we will want to skip this file by JUMP to 564EH.
5615
INC DE
INCrement the pointer to the character from the file’s extension from the directory (stored in Register Pair DE) by 1.
5616
INC HL
INCrement the pointer to the character from the user specified extension (stored in Register Pair HL) by 1.
5617
DJNZ TOTAL1
     [5610H]
Keep checking the 3 extension characters by LOOPing back to 5610H, 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.
5619
LD DE,(SAVE3)
If we’re here, the user extension matched the current filename in the directory’s extension so fetch the buffer pointer (held in memory location 5565H) and store it into Register Pair DE.
561D
LD A,E
Copy the LSB of the directory pointer (held in Register E) into Register A.
561E
ADD A,05H
LET Register A = Register A + 05H so as to point to the file’s filespec.
5620
LD E,A
Put the LSB of the directory pointer, now pointing to the name, back into Register E.
5621
LD C,00H
Let Register C equal 00H so that Register C can be a counter.
5623
LD HL,S9DCB1
Let Register Pair HL equal equal 6162H which is the beginning of the SOURCE FILE DCB.
5626
CALL MOVE2
     [558FH]
Copy a filename from the directory entry (pointed to by DE) into the DCB (pointed to HL) via a GOSUB to 558FH. Returns with Register C containing the number of characters in the filename.
5629
LD DE,ZSLANT
Let Register Pair DE equal 5561H, which is the pointer to the RAM SAVE area for the extension, starting with the “/”.
562C
CALL MOVE3
     [559CH]
Attach the extension to the file filename via a GOSUB to 559CH.
562F
PUSH BC
Save the counter/length of the filespec (held in Register Pair BC) to the top of the stack.
5630
LD DE,DRIVE1
Let Register Pair DE equal 555BH to point to the SOURCE FILE drivespec.
5633
CALL MOVE4
     [55A6H]
Attach the drivespec to the filename via a GOSUB to 55A6H.
5636
LD HL,S9DCB1
Let Register Pair HL equal equal 6162H which is the beginning of the SOURCE FILE DCB (which starts with the filename).
5639
LD DE,S9DCB2
Let Register Pair DE equal 6194H to point to the DESTINATION FILE DCB (which starts with the filename).
563C
POP BC
Fetch the counter/length of the filespec from the the top of the STACK into Register Pair BC, and then remove the entry from the stack.
563D
LD B,00H
In preparation for a LDIR, Register Pair BC needs to be set up. Right now only Register C is set up. So here we set Register B to equal 00H to set the MSB of the length so that BC is now the length of the filespec.
563F
LDIR
Copy the filespec from the SOURCE FILE DCB to the DESTINATION FILE DCB via LDIR, which 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.
5641
EX DE,HL
EXchange the value stored in Register Pair HL (i.e., the end of the filename in the SOURCE FILE DCB) with the value stored in Register Pair DE (i.e., the end of the filename in the DESTINATION FILE DCB).
5642
LD DE,DRIVE2
Let Register Pair DE equal the DESTINATION FILE DRIVESPEC (held in 555EH).
5645
CALL MOVE4
     [55A6H]
Attach the drivespec to the filename via a GOSUB to 55A6H.
5648
CALL COPY0
     [54D0H]
Copy/Kill (as set) the file via a GOSUB to 54D0H (COPY) or 5692H (KILL).
564B
CALL GETDIR
     [5568H]
Read the Directory into 4300H via a GOSUB to 5568H.
“TOTNXT”
564E
LD DE,(SAVE3)
Fetch the applicable buffer address for the current location in the directory sector (held in memory location 5565H) and store it into Register Pair DE.
5652
5653
5654
LD A,E
ADD A,30H
LD E,A
Advance 30 bytes in the buffer of the sector, thus moving to the next directory entry.
5656
LD (SAVE3),DE
Store the current location in the current directory sector (held in Register Pair DE) into memory location 5565H (which is a storage area for the current buffer address).
565A
CP 0F0H
Check for the end of directory sector location by comparing the first byte of the current directory sector entry (held in Register A) against 0F0H. Results:
  • If Register A equals 0F0H, the Z FLAG is set.
  • If A < 0F0H, the CARRY FLAG will be set.
  • if A >= 0F0H, the NO CARRY FLAG will be set.
565C
JR C,TOTAL0
     [5602H]
If A < 0F0H (meaning we are at the end of the directory sector) then the C FLAG (Carry) has been set, JUMP to 5602H to loop to the next sector.
565E
POP BC
Fetch the sector counter (held at the top of the STACK) into Register Pair BC, and then remove the entry from the stack.
565F
LD A,(S9TRK)
Fetch the sector number (held in memory location 5567H) and store it into Register A.
5662
INC A
INCrement the value stored in Register A by 1 so as to point to the next sector.
5663
LD (S9TRK),A
Store the bumped sector number (held in Register A) into memory location 5567H.
5666
DJNZ TOTAL
     [55F7H]
Process the entire directory track by LOOPing back to 55F7H, 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.
5668
RET
RETurn to the caller.

5669H – “KILL” Routine.

“S9KILL”
5669
566A
LD D,H
LD E,L
LET Register Pair DE = Register Pair HL (the pointer to the COMMAND LINE).
566B
LD A,(DE)
Fetch the first character held on the command line (in the memory location pointed to by Register Pair DE) and store it into Register A.
566C
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 is set.
566E
JR NZ,5697H
      [5697H]
If the first characer is NOT a /, then NZ FLAG (Not Zero) will have been set, and the user is NOT using a wildcard. JUMP to 5697H.

If we are here, then the user requested to KILL based on a WILDCARD.

5670
INC DE
INCrement the value stored in Register Pair DE by 1 to point to the second character from the COMMAND LINE.
5671
LD IX,S9CMD
Let Special Index Register Pair IX equal the extension storage area of 5562H.
5675
LD B,03H
Let Register B equal 03H to move 3 characters.
5677
CALL MOVE1
     [557CH]
Transfer characters the number of characters held in Register B from (DE) to (IX), aborting if a SPACE is found via a GOSUB to 557CH.
567A
LD A,(DE)
Fetch the next character from the COMMAND LINE (held in the memory location pointed to by Register Pair DE) and store it into Register A.
567B
CP 3AH
Compare the value held in Register A against 3AH (ASCII: :). Results: If Register A equals 3AH :, the Z FLAG is set; otherwise the NZ FLAG is set.
567D
JP NZ,ERR2
      [5219H]
We needed a :. If we didn’t get one, then the the NZ FLAG (Not Zero) will have been set, so JUMP to 5219H to report an ILLEGAL COMMAND PARAMETER error, and ABORT.
5680
LD IX,DRIVE1
Let Special Index Register Pair IX point to the SOURCE DRIVESPEC (555BH).
5684
LD B,02H
Let Register B equal 02H for a move of 2 drivespec characters.
5686
CALL MOVE1
     [557CH]
Transfer characters the number of characters held in Register B from (DE) to (IX), aborting if a SPACE is found via a GOSUB to 557CH.
5689
LD HL,KILLIT
Set the vector to the action in the directory entry loop routine to “KILL” by first letting Register Pair HL equal 5692H (which is in the middle of a multi-purporse CALL routine).
568C
LD (TOTCHG + 1),HL
Store the value held in Register HL into the memory location 5649H, which is in the middle of a CALL OPCODE. This will set that OPCODE to “KILL”. The alternative would be from the “COPY” routine, which would set this to a different address.
568F
JP SLANT0
   [55E8H]
Proceed to KILL the filed by JUMPing to 55E8H.

5692H – Continuation of the KILL ROUTINE.

“KILLIT”
5692
CALL GETDCB
     [59ADH]
GOSUB to 59ADH to set up for FULL SECTOR I/O and sets up registers B, DE, and HL for file action.
5695
JR KILL0
   [569DH]
JUMP to 569DH to kill the file.

5697H – Continuation of the KILL ROUTINE; display the KILLING message and kill the file.

“KILL1”
5697
CALL GETSYN
     [59BCH]
Process the filespec (i.e., set Register Pair DE to point to the SOURCE FILE DCB, check the syntax of the associated Filespec, and RETurn) via a GOSUB to 59BCH.
569A
JP NZ,ERR3
      [521DH]
If the NZ FLAG (Not Zero) has been set, then the CALL produced an error, so JUMP to 521DH.
“”
569D
PUSH HL
Save the contents of Register Pair HL to the top of the stack.
569E
PUSH DE
Save the contents of Register Pair DE to the top of the stack.
569F
LD HL,KILMSG
Let Register Pair HL equal 56BAH, to point to the message “‘KILLING ‘“.
56A2
CALL 021BH
     [021BH]
GOSUB to 021BH.
NOTE: 021BH is the Model III ROM routine to display the character at (HL) until a 03H is found.
56A5
LD HL,S9DCB1
Let Register Pair HL equal 6162H which is the beginning of the SOURCE FILE DCB, which is also the filespec.
56A8
CALL PRNTIT
     [5310H]
Display the filespec after the , to point to the message “‘KILLING ‘“. message via a GOSUB to 5310H.
56AB
POP DE
Put the value held at the top of the STACK into Register Pair DE, and then remove the entry from the stack.
56AC
POP HL
Put the value held at the top of the STACK into Register Pair HL, and then remove the entry from the stack.
56AD
CALL 4424H
     [4424H]
Open the file via a GOSUB to 4424H.
NOTE: 4424H is the SYS00/SYS routine to OPEN A DISK FILE for use. This RST 28H’s with a value of 92H so as to call ROUTINE 1 in OVERLAY 3.
56B0
JP NZ,ERRX
      [5223H]
If the NZ FLAG (Not Zero) has been set, then that CALL returned an error; report the error and abort via a JUMP to 5223H.
56B3
CALL 442CH
     [442CH]
Kill the file via a GOSUB to 442CH.
56B6
JP NZ,ERRX
      [5223H]
If the NZ FLAG (Not Zero) has been set, then that CALL returned an error; report the error and abort via a JUMP to 5223H.
56B9
RET
RETurn to the caller.

56BAH – MESSAGE and STORAGE AREA for KILL.

“KILMSG”
56BA
DEFM →
1DH + 1EH + ‘KILLING ‘ + 03H” Message.

56BAH – MESSAGE and STORAGE AREA for PATCH.

“ADDD”
56C5
DEFM →
“04H + ‘ADD=’” message, which is the address label for the PATCH command.
“FINDD”
56CA
DEFM →
“05H + ‘FIND=’” message, which is the find field label for the PATCH command.
“CHGG”
56D0
DEFM →
“04H + ‘CHG=’” message, which is the new record label for the PATCH command.
“ADD1”
56D5
DEFW 00H
Shared storage byte for either the logical record length (for COPY) or the patch address (for PATCH).
“?????”
56D6
DEFB 00H 00H 00H
Storage for 3 byte EOF
“?????”
56D7
DEFB 00H
Length of FIND FIELD in bytes
“FIND”
56D8
DEFS 32
FIND FIELD Storage Area. The first byte, like above, is the length of the data. The remaining 31 bytes is the data.
“CHAG99”
56F8
DEFS 32
CHANGE FIELD Storage Area. The first byte, like above, is the length of the data. The remaining 31 bytes is the data.
“FNDFLG”
5718
DEFB 00H
“Requested Address Found ” Flag
“ERNSAV”
5719
DEFB 00H
EOF Sector Number

571BH – PATCH Main Routine.

“PATCH”
571B
LD A,(HL)
Fetch the first character of the COMMAND LINE (held in the memory location pointed to by Register Pair HL) and store it into Register A.
571C
CP 2AH
Compare the value held in Register A against 2AH (ASCII: *). Results: If Register A equals *, the Z FLAG is set; otherwise the NZ FLAG is set.
571E
JP Z,HSYS
     [58FEH]
If the character was a *, then the Z FLAG (Zero) would have been set, and the user requested to patch a SYSTEM file; so JUMP to 58FEH.
5721
CALL GETSYN
     [59BCH]
If we are here, then the user wants to patch a user file (and a filename would be needed). Process the COMMAND LINE filename (i.e., set Register Pair DE to point to the SOURCE FILE DCB, check the syntax of the associated Filespec, and RETurn) via a GOSUB to 59BCH.
5724
JP NZ,ERR3
      [521DH]
If the NZ FLAG (Not Zero) has been set, then the CALL produced an error, so JUMP to 521DH.
“PAT0”
5727
CALL SKIPSP
     [5F8EH]
Get the next non-space COMMAND LINE character via a GOSUB to 5F8EH.
572A
CP 0DH
Compare the value held in Register A against 0DH (ASCII: CARRIAGE RETURN). Results: If Register A equals CARRIAGE RETURN, the Z FLAG is set; otherwise the NZ FLAG is set.
572C
JP Z,ERR3
     [521DH]
If the next character was an CARRIAGE RETURN then the Z FLAG (Zero) will have been set, and we didn’t get enough information. Exit with an error via a JUMP to 521DH.
572F
CP 28H
Compare the value held in Register A against 28H (ASCII: (). Results: If Register A equals (, the Z FLAG is set; otherwise the NZ FLAG is set.
5731
JP NZ,ERR2
      [5219H]
If the next character wasn’t a (, the NZ FLAG (Not Zero) will have been set, and we did not get the character we needed to proceed. JUMP to 5219H to report an ILLEGAL COMMAND PARAMETER error, and ABORT.
5734
INC HL
INCrement the value stored in Register Pair HL by 1 so as to point to the first character after the parenthesis.
5735
LD DE,ADDD
Point DE to the parameter table in RAM by setting Register Pair DE to equal 56C5H, which is the start of the PATCH routine lookup area, and points to the “ADD=” message.
5738
LD A,(DE)
That table is broken down into a byte for the length of the message, and then the message. Fetch the value held in the memory location pointed to by Register Pair DE, which will be the length of the “ADD=” label, and store it into Register A.
5739
573A
LD C,A
LD B,00H
Let Register Pair BC = the length of the “ADD=” label (which is 04H).
573C
INC DE
Point Register Pair DE to the next byte in the table (i.e., the beginning of the message “ADD=”).
573D
CALL COMPAR
     [5B70H]
Check to see if the command line paramter matches the label set in DE (in this case, checking to see if the user’s next command letters were “ADD=”) via a GOSUB to 5B70H.
5740
JP NZ,ERR2
      [5219H]
If the user didn’t have “ADD=” as the next characters the NZ FLAG (Not Zero) will have been set, so JUMP to 5219H to report an ILLEGAL COMMAND PARAMETER error, and ABORT.
5743
ADD HL,BC
Advance the pointer to the command line (i.e., Register Pair HL) to the end of that label by letting Register Pair HL = Register Pair HL (the current position on the COMMAND LINE) + Register BC (the length of the label we just checked).
5744
PUSH HL
We are now going to need to parse for a value, so save the contents of Register Pair HL (i.e., the pointer to the characters following the “ADD=” label on the command line) to the top of the stack.
5745
POP IX
Restore HL into Register Pair IX.
5747
LD HL,0000H
Let Register Pair HL equal 0000H as a base for math.
“PLOOP1”
574A
LD A,(IX+00H)
Fetch the first character of the address to be patched (held in the memory location pointed to by Special Index Register Pair IX+00H) and store it into Register A.
Note: IX+00H = the position in the DCB for the TYPE of FCB byte. Bit 0: 1=Read Only, Bit 1: 1=Write Only, Bit 4: 1=The next 2 bytes are simply the address of another FCB, Bit 7=1: Then the next 50 bytes are the description of an open file.

The next few instructions compare the character to 0, : (i.e., 1 above 9), A, and G (i.e., 1 above F) to make sure that it is in the range of a valid hex character.

574D
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.
574F
JR C,PLOOP3
     [5771H]
If A < 0 then the C FLAG (Carry) will have been set to indicate that the character was too low to be a valid hex character (i.e., it is below “0”), JUMP to 5771H.
5751
CP 3AH
Compare the value held in Register A against 3AH (1 more than ASCII: 9). Results:
  • If Register A equals 1 more than 9, the Z FLAG is set.
  • If A < 1 more than 9, the CARRY FLAG will be set.
  • if A >= 1 more than 9, the NO CARRY FLAG will be set.
5753
JR C,PLOOP2
     [575DH]
If A < 1 more than 9 then the C FLAG (Carry) will have been set to indicate that the character we got is less than “9” which is good, so JUMP to 575DH.
5755
CP 41H
Compare the value held in Register A against 41H (ASCII: A). Results:
  • If Register A equals A, the Z FLAG is set.
  • If A < A, the CARRY FLAG will be set.
  • if A >= A, the NO CARRY FLAG will be set.
5757
JR C,PLOOP3
     [5771H]
If A < A then the C FLAG (Carry) will have been set to indicate that the character was too low to be a valid hex character (i.e., it is below “A” and was not “0”-“9”, JUMP to 5771H.
5759
CP 47H
Compare the value held in Register A against 47H (ASCII: G). Results:
  • If Register A equals G, the Z FLAG is set.
  • If A < G, the CARRY FLAG will be set.
  • if A >= G, the NO CARRY FLAG will be set.
575B
JR NC,PLOOP3
      [5771H]
If A >= G then the NC FLAG (No Carry) will have been setto indicate that the character was too high to be a valid hex character (i.e., it is above “F”), JUMP to 5771H.

The next few instructions turn the validated hex character into decimal.

“PLOOP2”
575D
575E
575F
5760
ADD HL,HL
ADD HL,HL
ADD HL,HL
ADD HL,HL
Shift the old address four bits to the left
5761
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).
5763
CP 0AH
Compare the value held in Register A against 0AH (Decimal: 10). Results:
  • If Register A equals 10, the Z FLAG is set.
  • If A < 10, the CARRY FLAG will be set.
  • if A >= 10, the NO CARRY FLAG will be set.
5765
JR C,PLOP2
     [5769H]
If A < 10 then the C FLAG (Carry) will have been set and we are done converting the character, so JUMP to 5769H.
5767
SUB 07H
SUBtract the value 07H from Register A which will reduce an ASCII character in the range of “A”-“F” into 11-15.

The parameter character is now a decimal number held in Register A.

“”
5769
LD E,A
At this point, Register A now is the decimal equivalent of the 2 characters given. Copy the contents of Register A into Register E.
576A
LD D,00H
Let Register D equal 00H so that Register Pair DE = Register A.
576C
ADD HL,DE
LET Register Pair HL = the old character address value (held in Register Pair HL) + the new value (held in Register Pair DE).
576D
INC IX
INCrement the value stored in Special Index Register IX by 1 to point to the next digit/character in the ADD= field in the command line.
576F
JR PLOOP1
   [574AH]
LOOP BACK to 574AH until the end of the parameter is reached.

5771H – Continuation of the PATCH command. Jumped here if we were given an invalid hex character on the ADD= portion of the command line. A is holding the character from the COMMAND LINE which we know is NOT a valid hex character.

“PLOOP3”
5771
LD (ADD1),HL
Store the address (held in Register Pair HL) into the desingated memory location to hold the patch address (i.e., 56D5H).
5774
CP 2CH
Compare the value held in Register A against a ,. Results: If Register A equals ,, the Z FLAG is set; otherwise the NZ FLAG is set.
5776
JP NZ,ERR2
      [5219H]
If the current character is not a , then the NZ flag would have been set and we have an invalid character. JUMP to 5219H to report an ILLEGAL COMMAND PARAMETER error, and ABORT.
5779
PUSH IX
POP HL
Let Register Pair HL = Special Index Register IX (which is the command line).
577C
INC HL
Skip over the “,” on the command line by pointing to the next character on the COMMAND LINE by INCrementing the value stored in Register Pair HL by 1.
577D
LD DE,FINDD
Let Register Pair DE equal 56CAH, which is in the PATCH routine lookup area, and points to the “FIND=” message.
5780
LD A,(DE)
Fetch the first byte at that message, which is the length of the “FIND=” command (i.e., 5) and store it into Register A.
5781
INC DE
Move past the length byte to the message by INCrementing the value stored in Register Pair DE by 1. DE now points to the “FIND=” text.
5782
5783
LD C,A
LD B,00H
Set Register Pair BC = the length of the “FIND=” text (i.e., 5 characters)
5785
CALL COMPAR
     [5B70H]
Check to see if the command line parameter matches the label set in DE (in this case, checking to see if the user’s next command letters were “ADD=”) via a GOSUB to 5B70H.
5788
JP NZ,ERR2
      [5219H]
If the NZ FLAG (Not Zero) has been set, then the user label didn’t match the required “FIND=” label, which is bad, so JUMP to 5219H to report an ILLEGAL COMMAND PARAMETER error, and ABORT.
578B
ADD HL,BC
Advance Register Pair HL to the user provided value associated with a “FIND=” lead in by setting Register Pair HL = the current location on the COMMAND LINE (held in Register Pair HL) + the length of the text “FIND=” (held in Register BC).
578C
LD DE,FIND + 1
Let Register Pair DE equal 56D8H to point to the FIND FIELD storage buffer of 31 characters.
578F
CALL MOVLTH
     [58C0H]
Decode the FIND FIELD input via a GOSUB to 58C0H. Routine returns with DE pointing to the converted field and Register A holding the length of the field.
5792
LD (FIND),A
Store the length of the “FIND=” field (i.e., 5 characters; held in Register A) into memory location 56D7H.
5795
LD A,(HL)
Fetch the next character on the command line (in the memory location pointed to by Register Pair HL) and store it into Register A.
5796
CP 2CH
Compare the value held in Register A against a ,. Results: If Register A equals ,, the Z FLAG is set; otherwise the NZ FLAG is set.
5798
JP NZ,ERR2
      [5219H]
If the current character is not a , then the NZ flag would have been set and we have an invalid character. JUMP to 5219H to report an ILLEGAL COMMAND PARAMETER error, and ABORT.
579B
INC HL
If we’re here then we got the “,” and are still working on a valid command line. Point HL to the next character on the command line.
579C
LD DE,CHGG
Let Register Pair DE equal 56D0H, which is in the PATCH routine lookup area, and points to the “CHG=” message.
579F
LD A,(DE)
Fetch the first byte at that message, which is the length of the “CHG=” command (i.e., 4) and store it into Register A.
57A0
INC DE
INCrement the value stored in Register Pair DE by 1 to now point to the “CHG=” text.
57A1
57A2
LD C,A
LD B,00H
Set Register Pair BC = the length of the “CHG=” text (i.e., 4 characters)
57A4
CALL COMPAR
     [5B70H]
Check to see if the command line paramter matches the label set in DE (in this case, checking to see if the user’s next command letters were “ADD=”) via a GOSUB to 5B70H.
57A7
JP NZ,ERR2
      [5219H]
If the NZ FLAG (Not Zero) has been set, then the user label didn’t match the required “CHG=” label, which is bad, so JUMP to 5219H to report an ILLEGAL COMMAND PARAMETER error, and ABORT.
57AA
ADD HL,BC
Advance Register Pair HL to the user provided value associated with a “CHG=” lead in by setting Register Pair HL = the current location on the COMMAND LINE (held in Register Pair HL) + the length of the text “FIND=” (held in Register BC).
57AB
LD DE,CHAG99+1
Let Register Pair DE equal 56F8H to point to the CHANGE FIELD storage buffer of 31 characters.
57AE
CALL MOVLTH
     [58C0H]
Decode the CHANGE FIELD input via a GOSUB to 58C0H. Routine returns with DE pointing to the converted field and Register A holding the length of the field.
57B1
LD (CHAG99),A
Store the the length of the given change field (held in Register A after the CALL to 58C0H) into memory location 56F7H.
57B4
LD B,A
Let Register B = the length of the given change field (held in Register A after the CALL to 58C0H).
57B5
LD A,(FIND)
Fetch the length of the given find field (held in memory location 56D7H) and store it into Register A.
57B8
CP B
Check to see if the length of the FIND field (held in Register A) and the length of the CHANGE field (held in Register B) are the same. Results: If Register A equals the value held in Register B, the Z FLAG is set; otherwise the NZ FLAG is set.
57B9
JP NZ,ERR2
      [5219H]
If they FIND and CHG fields were not the same length, the NZ FLAG (Not Zero) will have been set. JUMP to 5219H to report an ILLEGAL COMMAND PARAMETER error, and ABORT.

If we are here, then we have the FIND field and the CHANGE fields stored and they are of matching length.

57BC
XOR A
Set Register A to ZERO and clear all Flags so that we can put a 00H into some memory locations.
57BD
LD (CHGFLG),A
Store the value held in Register A into memory location 5717H (which points to the CHANGE REQUIRED flag).
57C0
LD (FNDFLG),A
Store the value held in Register A into memory location 5718H (which points to the ADDRESS FOUND flag).
57C3
LD A,(SYSFLG)
Fetch the value held in memory location 599AH (i.e., the SYSTEM OVERLAY FLAG for the PATCH routine; NZ if system file being patched) and store it into Register A.
57C6
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).
57C7
JR NZ,PATL00
      [57D8H]
If patching file overlay system then we are going to want to skip the FILE OPEN portion of this routine, JUMP to 57D8H.
57C9
57CC
LD IYL, 0FFH
LD IYH, 42H
Open the file. First … Set the Special Index Register IY = 42FFH to point to the protection override flag.
57CF
DEC (IY+00H)
Turn off the password check by DECrementing the value stored in the memory location pointed to by Special Index Register IY+00H by 1.
57D2
CALL OPENIT
     [599BH]
OPEN the file via a GOSUB to 599BH.
57D5
JP NZ,ERRX
      [5223H]
If the NZ FLAG (Not Zero) has been set, then that CALL returned an error; report the error and abort via a JUMP to 5223H.
“PATL00”
57D8
LD A,(6163H)
Fetch the file status/protection byte (held in memory location 6163H) and store it into Register A.
57DB
AND 0F8H
MASK the value of Register A against 0F8H (1111 1000) to zero out the 3 bytes consisting of the access code, thus granting full access.
57DD
LD (6163H),A
Put the masked file status/protection byte back into memory location 6163H (where the options byte is stored).
57E0
LD HL,(6172H)
Fetch the first extent element (held in memory location 6172H) and store it into Register Pair HL.
57E3
LD A,L
The LSB of the extent element (i.e., Register L) is the track number, so copy the track number (held in Register L) into Register A.
57E4
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).
57E5
JR NZ,PATL01
      [57F3H]
If we are not at SYS00/SYS, then tne NZ flag will be set, so skip the next few command via a JUMP to 57F3H.
57E7
LD A,H
Let’s double check to make sure we aren’t at SYS00/SYS. First, copy the gran offset into the track (held in the MSB of the extent element; currently in Register H) into Register A.
57E8
AND 0E0H
MASK the value of Register A against 0E0H (1110 0000) to mask off the number of grans.
57EA
JR NZ,PATL01
      [57F3H]
If that is still not zero, then the user is not trying to patch OVERLAY 0 then the NZ FLAG (Not Zero) will have been set, so skip the next few command via a JUMP to 57F3H.
57EC
LD A,(616CH)
Fetch the “next sector” number (held in memory location 616CH) and store it into Register A.
57EF
INC A
INCrement the value stored in Register A by 1 so that Register A will never be 0 (and hence, will never patch the BOOT file).
57F0
LD (616CH),A
Store the bumped “next sector” (held in Register A) into the “next sector” memory location of 616CH.
“PATL01”
57F3
CALL REDIT
     [58B3H]
Read the first sector via a GOSUB to 58B3H.
57F6
LD BC,(616EH)
Fetch the EOF sector (head in memory location 616EH) and store it into Register Pair BC.
57FA
LD (5719H),BC
Store the EOF sector into memory location 5719H (which is the designated storage location of the EOF sector number).

Next, we need to get a block of data from the file.

“”
57FE
LD A,(HL)
Fetch the byte of data held in the buffer memory location pointed to by Register Pair HL and store it into Register A.
57FF
CP 01H
Compare the value held in Register A against 01H to see if it is a CODE BLOCK. Results: If Register A equals 01H, the Z FLAG is set; otherwise the NZ FLAG is set.
5801
JR Z,PATCHK
     [5816H]
If the Z FLAG (Zero) has been set, JUMP to 5816H to process a CODE BLOCK.
5803
CP 02H
Compare the value held in Register A against 02H to see if it is an EXECUTION ADDRESS. Results: If Register A equals 02H, the Z FLAG is set; otherwise the NZ FLAG is set.
5805
JP Z,PATEND
     [5897H]
If the Z FLAG (Zero) has been set, JUMP to 5897H to display the results of the Patch.
5808
CP 03H
Compare the value held in Register A against 03H to see if it is an END OF FILE CHARACTER. Results: If Register A equals BREAK, the Z FLAG is set; otherwise the NZ FLAG is set.
580A
JP Z,PATEND
     [5897H]
If the Z FLAG (Zero) has been set, JUMP to 5897H to display the results of the Patch.
580D
CP 21H
Compare the value held in Register A against 21H to see if it is a COMMENT BLOCK. Results:
  • If Register A equals 21H, the Z FLAG is set.
  • If A < 21H, the CARRY FLAG will be set.
  • if A >= 21H, the NO CARRY FLAG will be set.
580F
JR C,DLYLOP
     [5888H]
If the C FLAG (Carry) has been set, JUMP to 5888H to throw away the comment block.
5811
LD A,22H
If we haven’t jumped away, then we have an invalid block. Let Register A equal 22H to indicate an INVALID FILE FORMAT error.
5813
JP ERRX
   [5223H]
Report the error and abort via a JUMP to 5223H.

5816H – Continuation of the PATCH command. Read a CODE BLOCK from the file.

“PATCHK”
5816
INC HL
Point to the next byte in the buffer holding the CODE BLOCK of the file via a bump to Register Pair HL.
5817
LD B,(HL)
Fetch the next byte of the CODE BLOCK, which is the field size/character count, and put that into Register B.
5818
INC HL
Point to the next byte of the CODE BLOCK (the load address) in the file via a bump to Register Pair HL.
5819
LD E,(HL)
Fetch the next byte of the CODE BLOCK, which is the LSB of the LOAD ADDRESS, and put that into Register B.
581A
DEC B
DECrement the field size/character count (held in Register B) by 1 byte.
581B
INC HL
Fetch the next byte of the CODE BLOCK, which is the MSB of the LOAD ADDRESS, and put that into Register B.
581C
LD D,(HL)
Fetch the next byte of the CODE BLOCK, which is the data address MSB, and put that into Register B.
581D
DEC B
DECrement the field size/character count (held in Register B) by 1 byte.
581E
PUSH HL
Save the pointer in the buffer to the current location of the CODE BLOCK (held in Register Pair HL) to the top of the stack.
581F
PUSH DE
Save the LOAD ADDRESS (held in Register Pair DE) to the top of the stack.
5820
JR NZ,PATCH0
      [5825H]
If Register B isn’t zero then the NZ FLAG (Not Zero) will have been set, meaning we have more data to read so JUMP to 5825H.
5822
SCF
If we are here then we know the sector is length is not 0 and is not 256, we have an error, so SET the CARRY FLAG to indicate as much.
5823
JR PATCH1
   [5828H]
JUMP to 5828H to offset the address.

5825H – Continuation of the PATCH command read a CODE BLOCK routine; jumped here if there is more data to read in the code block than just the 3 bytes comprising the field size and data address.

The next few instructions are to set DE to be DE + the length of the field. This requires some math. First, work the LSB of Register Pair DE.

“PATCH0”
5825
5826
5827
LD A,E
ADD A,B
LD E,A
Let Register E = the data address LSB (which was already in E) plus the data field size – 2.
“PATCH1”
5828
5829
582B
LD A,D
ADC A,00H
LD D,A
Let Register D = the data address MSB (which was already in D) + 1 byte if the addition of the LSB produced a carry.
582C
LD HL,(ADD1)
Fetch the user requested patch address from its storage place (in memory location 56D5H) into Register Pair HL.
582F
OR A
Set FLAGS based on the contents of Register A (and, in all events, clear the CARRY FLAG, which we will need cleared for the next operation).
5830
SBC HL,DE
Subtracts the value stored in Register Pair DE (the size of the patch) and the carry flag from the value stored in Register Pair HL (the block to patch). This will tell us if the patch will be entirely within the single block.
5832
POP DE
Restore the address of the block from the top of the STACK into Register Pair DE, and then remove the entry from the stack.
5833
POP HL
Restore the field size from the top of the STACK into Register Pair HL, and then remove the entry from the stack.
5834
JR NC,DLYLO1
      [588AH]
If the NC FLAG (No Carry) has been set then the load address is too low; so JUMP to 588AH.
5836
PUSH HL
Save the field size (held in Register Pair HL) to the top of the stack.
5837
LD HL,(ADD1)
Fetch the patch address from its storage place (in memory location 56D5H) into Register Pair HL.
583A
OR A
Set FLAGS based on the contents of Register A (and, in all events, clear the CARRY FLAG).
583B
SBC HL,DE
Put the offset into the block inter Register Pair HL by subtracting the address of the block (stored in Register Pair DE) and the carry flag from the patch address (stored in Register Pair HL).
583D
LD B,L
Copy the LSB of the offset into the block (held in Register L) into Register B.
583E
POP HL
Restore the field size from the top of the STACK into Register Pair HL, and then remove the entry from the stack.
583F
JR C,DLYLO1
     [588AH]
If the subtraction triggered the CARRY FLAG, then we need to redo the math to see if we need to go BEFORE the current block. JUMP to 588AH.
5841
INC L
Bump Register L to point past the MSB of the LOAD ADDRESS by INCrementing the value stored in Register L by 1.
5842
OR 01H
Since the address has been found, we need to OR Register A against 01H (0000 0001), to force Register A to be anything but a 0 for the next instruction.
5844
LD (FNDFLG),A
Store a non-zero (held in Register A) into memory location 5718H (which points to the ADDRESS FOUND flag).
5847
LD A,B
Copy the byte count offset a/k/a the remaining length (held in Register B) into Register A.
5848
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).
5849
JR Z,PATCH3
     [5851H]
If the Z FLAG (Zero) has been set then we are finally at the data! JUMP to 5851H. Otherwise fall through to keep looping.
“PATCH2”
584B
INC L
If we didn’t jump away, then we are not yet at the data so point to the next byte by INCrementing the value stored in Register L by 1.
584C
CALL Z,REDIT
       [58B3H]
If the Z FLAG (Zero) has been set, meaning that L just spilled into the next sector and we ran out of buffer, GOSUB to 58B3H to read the next seector.
584F
DJNZ PATCH2
     [584BH]
Keep looping back to 584BH until we get to the requested address, 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.
“PATCH3”
5851
LD DE,FIND
Let Register Pair DE equal 56D7H, which is the pointer to the storage location for the LENGTH OF THE FIND FIELD.
5854
LD A,(DE)
Fetch the length of the find field from the memory location pointed to by Register Pair DE and store it into Register A.
5855
INC DE
INCrement the value stored in Register Pair DE by 1 so that it now points to the 31 byte storage location for the FIND FIELD.
5856
LD C,A
Copy the field length (held in Register A) into Register C.
5857
LD B,00H
Let Register B equal 00H so that Register Pair BC will hold the field length.
5859
CALL COMPAR
     [5B70H]
Check to see if we have found what we are looking for via a GOSUB to 5B70H.
585C
JP NZ,PATERR
      [59C2H]
If the NZ FLAG (Not Zero) has been set, then no match was found; JUMP to 59C2H to display a “STRING NOT FOUND” message and ABORT.
585F
LD DE,CHAG99+1
Let Register Pair DE equal 56F8H to point to the CHANGE FIELD storage buffer of 31 characters.
5862
CALL COMPAR
     [5B70H]
Check to see if a change is really needed via a GOSUB to 5B70H.
5865
JR Z,PATEND
     [5897H]
If the Z FLAG (Zero) has been set then what we wanted to check it to was actually what was there, so JUMP to 5897H to display the results of the patch.
5867
EX DE,HL
EXchange the value stored in Register Pair HL (i.e., the data location to be changed) with the value stored in Register Pair DE (i.e., the CHANGE FIELD storage buffer).
5868
LDIR
Move the new string into the old location via a LDIR instuction, which 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.
586A
OR 01H
We need a non-Zero put into the next memory location so OR Register A against 01H (0000 0001) to set the “CHANGE REQUIRED” flag to a non-zero number.
586C
LD (CHGFLG),A
Show that we have now made the requested change by storing the value held in Register A into memory location 5717H (which points to the CHANGE REQUIRED flag).
586F
LD A,(SYSFLG)
Fetch the value held in memory location 599AH (i.e., the SYSTEM OVERLAY FLAG for the PATCH routine; NZ if system file being patched) and store it into Register A.
5872
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).
5873
PUSH AF
Save the status flags from the check to see if this a SYSTEM FILE to the top of the stack.
5874
CALL NZ,CLOSYS
        [5963H]
If the NZ FLAG (Not Zero) has been set then we were working on a SYSTEM FILE, so we need to close it via a GOSUB to 5963H.
5877
POP AF
Restore the status flags into Register Pair AF, and then remove the entry from the stack.
5878
JR NZ,PATEND
      [5897H]
If the NZ FLAG (Not Zero) has been set then we were working on a SYSTEM FILE, so exit by JUMPing to 5897H to display the results of the patch.

If we are here, then we just patched a non-SYSTEM file.

587A
CALL GETDCB
     [59ADH]
Set up for FILE I/O via a GOSUB to 59ADH to set up for FILL SECTOR I/O and sets up registers B, DE, and HL.
587D
CALL 4445H
     [4445H]
Back up to the proper sector via a GOSUB to 4445H.
5880
CALL GETDCB
     [59ADH]
Set up for FILE I/O via a GOSUB to 59ADH to set up for FILL SECTOR I/O and sets up registers B, DE, and HL.
5883
CALL 443CH
     [443CH]
Write with Verify via a CALL to 443CH
NOTE: 443CH is the SYS00/SYS vector for ‘WRITE with VERIFY’, which will write verify a write with a retry count of 3. DE must point to the buffer to write.
5886
JR PATEND
   [5897H]
JUMP to 5897H to disply the results of the patch and finish.

5888H – Continuation of the PATCH command to deal with a COMMENT BLOCK.

“DLYLOP”
5888
INC HL
Bypass the NO-USE byte and point to the next byte by INCrementing the value stored in Register Pair HL by 1.
5889
LD B,(HL)
Fetch the length byte (held in the memory location pointed to by Register Pair HL) and store it into Register B.
“DLYLO1”
588A
INC L
Point to the next byte by INCrementing the value stored in Register Pair L by 1.
588B
CALL Z,REDIT
       [58B3H]
If the Z FLAG (Zero) has been set then we slipped to the next sector and ran out of buffer; so get the next sector via a GOSUB to 58B3H.
588E
DJNZ DLYLO1
     [588AH]
Skip the entire comment block (based on the field length byte) via a DJNZ LOOP back to 588AH, 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.
5890
INC L
Point to the next byte by INCrementing the value stored in Register Pair L by 1.
5891
CALL Z,REDIT
       [58B3H]
If the Z FLAG (Zero) has been set then we slipped to the next sector; so get the next sector via a GOSUB to 58B3H.
5894
JP PATLO0
   [57FEH]
JUMP to 57FEH to get the next block.

5897H – Continuation of the PATCH command to display the results of the Patch and exit.

“PATEND”
5897
LD A,(FNDFLG)
See if we found the address by fetching the “Requested Address Found” Flag from where it lives (memory location 5718H) and store it into Register A.
589A
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).
589B
JR NZ,PATEN1
      [58A3H]
If the NZ FLAG (Not Zero) has been set then we have found the requested address, so JUMP to 58A3H to see if we had to make a change.
589D
LD HL,NOFIND
Let Register Pair HL equal 59E4H to point to the message “SPECIFIED ADDRESS NOT FOUND“.
“PATEN0”
58A0
JP 021BH
   [021BH]
JUMP to 021BH.
NOTE: 021BH is the Model III ROM routine to display the character at (HL) until a 03H is found. Since this was JUMPED to instead of CALLed, the RET at the end of this ROM routine will then RETurn to the caller of this subroutine instead of returning to this place.

58A3H – Continuation of the PATCH command to display the results of the Patch if we have a match.

“PATEN1”
58A3
LD A,(CHGFLG)
See if we actually made a change by fetching the value held in memory location 5717H (which points to the CHANGE REQUIRED flag) into Register A.
58A6
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).
58A7
JR NZ,PATEN2
      [58AEH]
If the NZ FLAG (Not Zero) has been set, then the change field was NOT the same as the found field, which is bad; so skip via a JUMP to 58AEH.
58A9
LD HL,NOCHAG
Let Register Pair HL equal 59E4H to point to the message “NO CHANGE REQUIRED“.
58AC
JR PATEN0
   [58A0H]
JUMP to 58A0H to display the message pointed to by Register Pair HL and exit.

58AEH – Continuation of the PATCH command to display the results of a successful Patch.

“PATEN2”
58AE
LD HL,CHGMAD
Let Register Pair HL equal 59C8H to point to the message “PATCH MADE“.
58B1
JR PATEN0
   [58A0H]
JUMP to 58A0H to display the message pointed to by Register Pair HL and exit.

58B3H – Continuation of the PATCH command. Subroutine to read a sector.

“REDIT”
58B3
PUSH BC
Save the contents of Register Pair BC to the top of the stack.
58B4
CALL GETDCB
     [59ADH]
Set up for FILE I/O via a GOSUB to 59ADH to set up for FILL SECTOR I/O and sets up registers B, DE, and HL.
58B7
CALL 4436H
     [4436H]
GOSUB to 4436H.
NOTE: 4436H is the SYS00/SYS vector for ‘READ’, which reads the record that the disk drive is positioned over.
58BA
POP BC
Put the value held at the top of the STACK into Register Pair BC, and then remove the entry from the stack.
58BB
RET Z
If the Z FLAG (Zero) has been set then there was no error from that GOSUB, so RETurn to the caller.
“REDI0”
58BC
POP HL
If we are here, then there was an error in the read. Clear the stack.
58BD
JP ERRX
   [5223H]
Report the error and abort via a JUMP to 5223H.

58C0H – Part of the PATCH routine. This routine decodes an abitrary length hexadecimal field. It is called related to the FIND and CHG fields given by the user. HL points to the source, and DE points to the destination.

“MOVLTH”
58C0
LD B,00H
Let Register B equal 00H as it will be a length counter.
“MOVLT1”
58C2
LD A,(HL)
Fetch the character held in the memory location pointed to by Register Pair HL and store it into Register A.
58C3
CP 30H
Compare the value held in Register A against 30H to see if we got a character less than “0” (i.e., END OF STRING). Results:
  • If Register A equals 30H, the Z FLAG is set.
  • If A < 30H, the CARRY FLAG will be set.
  • if A >= 30H, the NO CARRY FLAG will be set.
58C5
JR C,MOVLT2
     [58D7H]
If the C FLAG (Carry) has been set then we are at the end of the string, so JUMP to 58D7H.
58C7
CALL TCONV
     [58DDH]
GOSUB to 58DDH to convert the value to HEX (which will sit in the the LEFT NYBBLE).
58CA
LD C,A
Copy the left nybble (held in Register A) into Register C.
58CB
INC HL
Point to the next character in the field by INCrementing the value stored in Register Pair HL by 1.
58CC
LD A,(HL)
Fetch the next character (held in the memory location pointed to by Register Pair HL) and store it into Register A.
58CD
CALL TCONV1
     [58E9H]
GOSUB to 58E9H to convert the value to HEX (which will sit in the RIGHT NYBBLE).
58D0
OR C
Combine the LEFT and RIGHT nybbles via an OR. The results are stored in Register A.
58D1
LD (DE),A
Store the combined/derived value (held in Register A) into the memory location pointed to by Register Pair DE.
58D2
INC DE
INCrement the destination pointer to the next slot.
58D3
INC HL
INCrement the source pointer to the next character.
58D4
INC B
INCrement the counter (stored in Register B) by 1.
58D5
JR MOVLT1
   [58C2H]
LOOP back to almost the top of this routine at 58C2H.

58D7H – Part of the PATCH routine’s subroutine which decodes an abitrary length hexadecimal field. Jumped here when we hit the END OF STRING (by virtue of a character below “0” being found).

“MOVLT2”
58D7
LD A,B
Copy the found field length (held in Register B as a counter) into Register A.
58D8
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).
58D9
JP Z,ERR3
     [521DH]
If the Z FLAG (Zero) has been set, the field length was zero and we were therefore missing a parameter, which is bad. JUMP to 521DH to exit with an error.
58DC
RET
RETurn to the caller.

58DDH – Convert a Byte Contaning a Hex Character to the High Nybble.

“TCONV”
58DD
CALL TCONV1
     [58E9H]
Get the value of the ASCII character via a GOSUB to 58E9H.
58E0
58E2
58E4
58E6
SLA A
SLA A
SLA A
SLA A
Shift the bits in Register A left FOUR positions (to the MSB), with new bits being filled in with a 0.
58E8
RET
RETurn to the caller.

58E9H – Convert a Byte Contaning a Hex Character to the Low Nybble a/k/a get the value of an ASCII character.

“TCONV1”
58E9
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).
58EB
JP C,ERR2
     [5219H]
If the C FLAG (Carry) has been set then the character is below “0”, so JUMP to 5219H to report an ILLEGAL COMMAND PARAMETER error, and ABORT.
58EE
CP 0AH
If we’re here then the character is not below “0”. Next compare the value held in Register A against 0AH (Decimal: 10). Results:
  • If Register A equals 10, the Z FLAG is set.
  • If A < 10, the CARRY FLAG will be set.
  • if A >= 10, the NO CARRY FLAG will be set.
58F0
RET C
If the C FLAG (Carry) has been set then the character is less than 10, so we are good! RETurn to the caller.
58F1
SUB 07H
If we’re here then the character is greater than 10. SUBtract the value 07H from Register A since there are 7 characters between “9” and “A”.
58F3
CP 0AH
Compare the value held in Register A against 0AH (Decimal: 10). Results:
  • If Register A equals 10, the Z FLAG is set.
  • If A < 10, the CARRY FLAG will be set.
  • if A >= 10, the NO CARRY FLAG will be set.
58F5
JP C,ERR2
     [5219H]
If the C FLAG (Carry) has been set then A < 10 which is too low to be an “A”-“F”, so JUMP to 5219H to report an ILLEGAL COMMAND PARAMETER error, and ABORT.
58F8
CP 10H
Compare the value held in Register A against 10H (Decimal: 16). Results:
  • If Register A equals 16, the Z FLAG is set.
  • If A < 16, the CARRY FLAG will be set.
  • if A >= 16, the NO CARRY FLAG will be set.
58FA
RET C
If If A < 16 the C FLAG (Carry) will have been set and we have a good character, RETurn to the caller.
58FB
JP ERR2
   [5219H]
JUMP to 5219H to report an ILLEGAL COMMAND PARAMETER error, and ABORT.

58FEH – PATCH routine for a SYSTEM/OVERLAY File.

“HSYS”
58FE
INC HL
INCrement the pointer to the COMMAND LINE (stored in Register Pair HL) by 1; this should be a value.
58FF
CALL HEXGET
     [597BH]
Get the overlay number (following the “*” we just got) via a GOSUB to 597BH. Response in Register Pair DE.
5902
PUSH DE
Save the overlay number from that GOSUB (held in Register Pair DE) to the top of the stack.
5903
CALL SKIPSP
     [5F8EH]
Get the next COMMAND LINE character (skipping spaces) via a GOSUB to 5F8EH.
5906
LD C,00H
Let Register C equal 00H for a default drivespec of 0.
5908
CP 3AH
Compare the value held in Register A against 3AH (ASCII: :). Results: If Register A equals :, the Z FLAG is set; otherwise the NZ FLAG is set.
590A
JR NZ,HSYS1
      [5915H]
If we did not get a : then we are not getting a drive number, so skip the next few instructions which would seek to interpret the command line for a drive number and JUMP to 5915H.
590C
INC HL
INCrement the pointer to the COMMAND LINE (stored in Register Pair HL) by 1 to point to the ASCII drive number.
590D
LD A,(HL)
Fetch the drive number (the next character from the COMMAND LINE; held in the memory location pointed to by Register Pair HL) and store it into Register A.
590E
INC HL
INCrement the pointer to the COMMAND LINE (stored in Register Pair HL) by 1 to move past the ASCII drive number.
590F
SUB 30H
SUBtract the value 30H from Register A (which is supposed to hold a drive number). 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).
5911
JP C,ERR2
     [5219H]
If the number is too low then the C FLAG (Carry) will have been set, so JUMP to 5219H to report an ILLEGAL COMMAND PARAMETER error, and ABORT.
5914
LD C,A
Copy the drive number in binary form (held in Register A) into Register C.
“HSYS1”
5915
EX (SP),HL
EXchange the value stored in Register Pair HL (the pointer to the current letter on the COMMAND LINE) with the value stored at the top of stack (i.e., the system overlay number).
5916
PUSH HL
Save the overlay number (held in Register Pair HL) to the top of the stack.
5917
PUSH BC
Save the drive number (held in Register Pair BC) to the top of the stack.
5918
LD HL,S9DCB1
Let Register Pair HL equal 6162H which is the beginning of the SOURCE FILE DCB.
591B
LD DE,S9DCB1+1
Let Register Pair DE equal the second byte of the SOURCE FILE DCB.
591E
LD BC,0031H
Let Register Pair BC equal 0031H for the size of a DCB (i.e., 49) bytes to move.
5921
LD (HL),00H
Store the value held in 00H into the memory location pointed to by Register Pair HL so that the LDIR will zero out everything.
5923
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.
5925
LD IX,S9DCB1
Let Special Index Register Pair IX equal 6162H which is the beginning of the SOURCE FILE DCB.
5929
LD (IX+00H),80H
Set IX+00H to 80H (1000 0000)to indicate that the file is open.
Note: IX+00H = the position in the DCB for the TYPE of FCB byte. Bit 0: 1=Read Only, Bit 1: 1=Write Only, Bit 4: 1=The next 2 bytes are simply the address of another FCB, Bit 7=1: Then the next 50 bytes are the description of an open file.
592D
LD (IX+0CH),0FFH
Store a 0FFH (i.e., indefinite) into the memory location pointed to by Special Index Register Pair IX+0CH.
Note: IX+0CH = the position in the DCB for the NMSB OF THE LAST SECTOR TO READ/EOF)
5931
LD (IX+0DH),0FFH
Store a 0FFH (i.e., indefinite) into the memory location pointed to by Special Index Register Pair IX+0DH.
Note: IX+0DH = the position in the DCB for the MSB OF THE LAST SECTOR TO READ/EOF)
5935
LD (IX+03H),00H
Store the value held in 00H into the memory location pointed to by Special Index Register Pair IX+03H.
Note: IX+03H = the position in the DCB for the LSB of the FILE BUFFER RAM ADDRESS).
5939
LD (IX+04H),63H
Store the value held in 63H into the memory location pointed to by Special Index Register Pair IX+04H.
Note: IX+04H = the position in the DCB for the MSB of the FILE BUFFER RAM ADDRESS).
593D
POP BC
Put the drive number (held at the top of the STACK) into Register Pair BC, and then remove the entry from the stack.
593E
LD (IX+06H),C
Store the drive number (held in Register C) into the memory location pointed to by Special Index Register Pair IX+06H.
Note: IX+06H = the position in the DCB for the DRIVE NUMBER).
5941
POP DE
Restore the overlay number from the top of the STACK into Register Pair DE, and then remove the entry from the stack.
5942
LD (IX+07H),E
Store the overlay number (held in Register E) into the memory location pointed to by Special Index Register Pair IX+07H.
Note: IX+07H = the position in the DCB for the LOGICAL FILE NUMBER [the directory entry number]).
5945
CALL RDHIT
     [4ABAH]
GOSUB to 4ABAH.
NOTE: 4ABAH is the SYS00/SYS routine to read the HIT sector into RAM.
5948
JP NZ,4409H
      [4409H]
If the NZ FLAG (Not Zero) has been set, then the CALL produced an error, so JUMP to 4409H.
NOTE: 4409H is the SYS00/SYS routine to process DOS errors.
594B
RLC E
Let the overlay number = the overlay number * 2 via a rotate, since each extent is 2 bytes long.
594D
LD A,0E0H
Let Register A equal 0E0H (1110 0000) to indicate an overlay.
594F
ADD A,E
LET Register A = Register A + Register E so that Register A now holds the overlay number * 2 AND the overlay designation bytes.
5950
5951
LD L,A
LD H,43H
Let Register Pair HL = 43xx where xx is the overlay number * 2, which is the extent element for the applicable overlay.
5953
LD D,(HL)
Fetch the MSB of the extent element (held in the memory location pointed to by Register Pair HL) and store it into Register D. Note that file extents are in MSB/LSB order.
5954
INC HL
INCrement the value stored in Register Pair HL by 1.
5955
LD E,(HL)
Fetch the LSB of the extent element (held in the memory location pointed to by Register Pair HL) and store it into Register D.
5956
LD (6172H),DE
Store the extent element (the value held in Register Pair DE) into the FCB at memory location 6172H.
595A
LD A,0FFH
Let Register A equal 0FFH to flag a system file.
595C
LD (SYSFLG),A
Put a 0FFH (held in Register A) into memory location 599AH (i.e., the SYSTEM OVERLAY FLAG for the PATCH routine; NZ if system file being patched) to mark the file as a SYSTEM FILE and store it into Register A.
595F
POP HL
Put the pointer to the COMMAND LINE back into Register Pair HL.
5960
JP PAT0
   [5727H]
JUMP to 5727H to continue the routine.

5963H – Patch File routine to update a system overlay file. The flags were preserved to the stack before this routine was called and are retrieved right after.

“CLOSYS”
5963
LD HL,(616CH)
Fetch “next” sector/record number from memory location 616CH and store it into Register Pair HL.
5966
DEC HL
Back up 1 record/sector by DECrementing the value stored in Register Pair HL by 1.
5967
LD (616CH),HL
Store the new “next” sector (held in Register Pair HL) into memory location 616CH.
596A
LD IX,S9DCB1
Let Special Index Register Pair IX equal 6162H which is the beginning of the SOURCE FILE DCB.
596E
CALL GETPDA
     [49D4H]
Find the track/sector number of the “next sector” via a GOSUB to 49D4H.
5971
LD HL,BUFER1
Let Register Pair HL equal 6300H to point to the beginning of the READ FILE buffer.
5974
CALL 45F7H
     [45F7H]
Write the sector at the “next” sector location via a GOSUB to 45F7H.
5977
JP NZ,4409H
      [4409H]
If the NZ FLAG (Not Zero) has been set, then the CALL produced an error, so JUMP to 4409H.
NOTE: 4409H is the SYS00/SYS routine to process DOS errors.
597A
RET
RETurn to the caller.

597BH – Evaluate the overlay number a/k/a Convert a Decimal String into a Binary Value.

“HEXGET”
597B
597C
LD B,H
LD C,L
Let BC = HL (i.e., the pointer to the COMMAND LINE).
597D
LD HL,0000H
Let Register Pair HL equal 0000H for upcoming math.
“HEXGE1”
5980
LD A,(BC)
Fetch the next character (which is hopefully a digit) on the command line (held in the memory location pointed to by Register Pair BC) and store it into Register A.
5981
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).
5983
JR C,HEXGE2
     [5996H]
If the C FLAG (Carry) has been set then the number fetched is below “0”, which is bad, so JUMP to 5996H.
5985
CP 0AH
Compare the value held in Register A against 0AH (Decimal: 10). Results:
  • If Register A equals 10, the Z FLAG is set.
  • If A < 10, the CARRY FLAG will be set.
  • if A >= 10, the NO CARRY FLAG will be set.
5987
JR NC,HEXGE2
      [5996H]
If the NC FLAG (No Carry) has been set then the character is too high, which is bad, so JUMP to 5996H.
5989
INC BC
Point to the next character on the COMMAND LINE by INCrementing the value stored in Register Pair BC by 1.
598A
598B
LD D,H
LD E,L
Let DE = the current math value of the number (held in Register Pair HL).
598C
598D
598E
598F
ADD HL,HL
ADD HL,HL
ADD HL,HL
ADD HL,HL
LET Register Pair HL = Register Pair HL * 10 to move the value previously held in HL into the tens digit position.
5990
5991
LD E,A
LD D,00H
Let Register Pair DE = 00nn where nn is the value of the next digit in binary.
5993
ADD HL,DE
LET Register Pair HL = original number but in the 10’s place (held in Register Pair HL) + other character in the 1’s place (held in Register DE).
5994
JR HEXGE1
   [5980H]
JUMP to 5980H to keep processing (and shifting nn to nn_).

5996H – Continuation of the above evaluation routine when the number found is less than 0 or more than 9.

“HEXGE2”
5996
EX DE,HL
EXchange the value stored in Register Pair HL (i.e., the converted number) with the value stored in Register Pair DE (irrelevant).
5997
5998
LD H,B
LD L,C
Let HL = BC (i.e., the pointer to the COMMAND LINE).
5999
RET
RETurn to the caller.

599AH – MESSAGE and STORAGE AREA.

“SYSFLG”
599A
DEFB 00H
Storage location for the System Overlay Flag. If NZ then the user wants to patch a SYSTEM OVERLAY file.

599BH – General Disk Routine. Open the disk file and preserve the LRL.

“OPENIT”
599B
CALL GETDCB
     [59ADH]
Set up for FILE I/O via a GOSUB to 59ADH to set up for FILL SECTOR I/O and sets up registers B, DE, and HL.
599E
CALL 4424H
     [4424H]
GOSUB to 4424H.
NOTE: 4424H is the SYS00/SYS routine to OPEN A DISK FILE for use. This RST 28H’s with a value of 92H so as to call ROUTINE 1 in OVERLAY 3.
59A1
PUSH AF
Save the contents of Register Pair AF (i.e., any error status from the OPEN) to the top of the stack.
59A2
LD A,(616BH)
Fetch the value held in memory location 616BH (i.e., the record length) and store it into Register A.
59A5
LD (LRLCHG),A
Store the value held in Register A into memory location 53A4H which is in the middle of a LD B,xx OPCODE.
59A8
LD (LRLCH1),A
Store the value held in Register A into memory location 54E0H.
59AB
POP AF
Restore the error status (held at the top of the STACK) into Register Pair AF, and then remove the entry from the stack.
59AC
RET
RETurn to the caller.

59ADH – General Disk Routine. Set up for full sector FILE I/O.

“GETDCB”
59AD
LD B,00H
Let Register B equal 00H to indicate FULL SECTOR FILE I/O / LRL of 256 bytes.
“GETDC1”
59AF
LD DE,S9DCB1
Let Register Pair DE equal 6162H which is the beginning of the SOURCE FILE DCB.
59B2
LD HL,BUFER1
Let Register Pair HL equal 6300H to point to the beginning of the READ FILE buffer.
59B5
RET
RETurn to the caller.

59B6H – General Disk Routine. Set up for full sector FILE I/O and Create A FiLE.

“INITIT”
59B6
CALL GETDCB
     [59ADH]
GOSUB to GOSUB to 59ADH to set up for FILL SECTOR I/O and sets up registers B, DE, and HL.
59B9
JP 4420H
   [4420H]
JUMP to 4420H.
NOTE: 4420H is the SYS00/SYS routine to INITIALIZE A FILE (i.e., CREATE or OPEN). This RST 28H’s with a value of A2H so as to call ROUTINE 2 in OVERLAY 2. Register HL needs to point to a RAM BUFFER for the DCB’s.

59BCH – General Disk Routine. Set Register Pair DE to point to the SOURCE FILE DCB, check the syntax of the associated Filespec, and RETurn.

“GETSYN”
59BC
LD DE,S9DCB1
Let Register Pair DE equal 6162H which is the beginning of the SOURCE FILE DCB.
59BF
JP 441CH
   [441CH]
JUMP to 441CH.
NOTE: 441CH is the SYS00/SYS routine to CHECK THE SYNTAX OF A FILESPEC before for use. This RST 28H’s with a value of C1H so as to call ROUTINE 4 in OVERLAY 1.

59C2H – Patch Error Routine. Display a STRING NOT FOUND message and ABORT.

“PATERR”
59C2
LD HL,NOFID1
Let Register Pair HL equal 59D3H to point to the message “STRING NOT FOUND“.
59C5
JP 021BH
   [021BH]
JUMP to 021BH.
NOTE: 021BH is the Model III ROM routine to display the character at (HL) until a 03H is found. Since this was JUMPED to instead of CALLed, the RET at the end of this ROM routine will then RETurn to the caller of this subroutine instead of returning to this place.

59C8H – MESSAGE and STORAGE AREA for the PATCH command.

“CHGMAD”
59C8
DEFM →
‘PATCH MADE’ + 0DH“.
“NOFID1”
59D3
DEFM →
‘STRING NOT FOUND’ + 0DH“.
“NOFIND”
59E4
DEFM →
‘CAN’T FIND SPECIFIED ADDRESS’ + 0DH“.
“NOCHAG”
5A01
DEFM →
‘NO CHANGE REQUIRED’ + 0DH“.

5A14H – “RELO” Routine. This routine ONLY updates t he LOAD FILE FORMAT ADDRESS, it does not “renum” the file.

“RELO”
5A14
LD DE,S9DCB
Let Register Pair DE equal 6130H, which is a pointer to the FILE CONTROL BLOCK.
5A17
CALL 441CH
     [441CH]
GOSUB to 441CH.
NOTE: 441CH is the SYS00/SYS routine to CHECK THE SYNTAX OF A FILESPEC before for use. This RST 28H’s with a value of C1H so as to call ROUTINE 4 in OVERLAY 1.
5A1A
JP NZ,ERR3
      [521DH]
If the NZ FLAG (Not Zero) has been set, then the CALL produced an error, so JUMP to JUMP to 521DH.
5A1D
LD DE,RLTABL
Let Register Pair DE equal 5B12H, which is a pointer to the table to be parsed.
5A20
CALL 4454H
     [4454H]
GOSUB to 4454H.
NOTE: 4454H is the DOS PARAMETER STRING PARSE routine. It decodes DOS LIBRARY parameters.
5A23
JP NZ,ERR2
      [5219H]
If the NZ FLAG (Not Zero) has been set, then the CALL produced an error, so JUMP to 5219H to report an ILLEGAL COMMAND PARAMETER error, and ABORT.
5A26
LD HL,(RLADD)
Let Register Pair HL equal the relocation address, which is a value placed into 5A27H elsewhere in this overlay.
5A29
PUSH HL
Save the relocation address (held in Register Pair HL) to the top of the stack.
5A2A
LD HL,BUFER1
Let Register Pair HL equal 6300H to point to the beginning of the READ FILE buffer.
5A2D
LD DE,S9DCB
Let Register Pair DE equal 6130H, which is a pointer to the FILE CONTROL BLOCK.
5A30
LD B,00H
Let Register B equal 00H for a LRL of 256 bytes.
5A32
CALL 4424H
     [4424H]
GOSUB to 4424H.
NOTE: 4424H is the SYS00/SYS routine to OPEN A DISK FILE for use. This RST 28H’s with a value of 92H so as to call ROUTINE 1 in OVERLAY 3.
5A35
JP NZ,EROR
      [5B04H]
If the NZ FLAG (Not Zero) has been set, then the CALL produced an error, so JUMP to 5B04H.
“LOOP2”
5A38
CALL ZREAD
     [5AFBH]
Read a byte via a GOSUB to 5AFBH.
5A3B
PUSH AF
Save the byte (held in Register Pair AF) to the top of the stack.
5A3C
CALL ZREAD
     [5AFBH]
Read a byte (which should be the number of bytes) via a GOSUB to 5AFBH.
5A3F
LD B,A
Copy the byte which was just read (held in Register A) into Register B, which will inform a DJNZ loop if the STALL routine is called because we hit a COMMENT FIELD.
5A40
POP AF
Put the first byte read (held at the top of the STACK) into Register Pair AF, and then remove the entry from the stack.
5A41
CP 05H
See if the first byte read was a COMMENT BYTE (i.e., 05H) by comparing the value held in Register A against 05H. Results: If Register A equals 05H, the Z FLAG is set; otherwise the NZ FLAG is set.
5A43
JP Z,STALL
     [5AF3H]
If we have a comment byte, then the Z FLAG (Zero) will have been set, JUMP to 5AF3H to skip past B number bytes in the COMMENT BLOCK.
5A46
CP 01H
See if the first byte read was a CODE BLOCK (i.e., 01H) by comparing the value held in Register A against 01H. Results: If Register A equals 01H, the Z FLAG is set; otherwise the NZ FLAG is set.
5A48
JR Z,LOOP0
     [5A4FH]
If we have a CODE BLOCK, then the Z FLAG (Zero) will have been set, JUMP to 5A4FH.
“LFERR”
5A4A
LD A,22H
If we haven’t jumped away, then we have an invalid block. Let Register A equal 22H to indicate an INVALID FILE FORMAT error.
5A4C
JP EROR
   [5B04H]
Exit via a JUMP to 5B04H.

5A4FH – Part of the RELO command. Jumped here if the character indicated a CODE BLOCK.

“LOOP0”
5A4F
CALL ZREAD
     [5AFBH]
Read a byte, which is the LSB of the address, via a GOSUB to 5AFBH.
5A52
LD L,A
Copy the LSB of the address (held in Register A) into Register L.
5A53
CALL ZREAD
     [5AFBH]
Read a byte, which is the MSB of the address, via a GOSUB to 5AFBH.
5A56
LD H,A
Copy the MSB of the address (held in Register A) into Register L.
5A57
EX DE,HL
EXchange the value stored in Register Pair HL (the address just read) with the value stored in Register Pair DE (irrelevant).
5A58
POP HL
Restore the relocation address (held at the top of the STACK) into Register Pair HL, and then remove the entry from the stack.
5A59
PUSH HL
Save the relocation address (held in Register Pair HL) to the top of the stack.
5A5A
OR A
Set FLAGS based on the contents of Register A (and, in all events, clear the CARRY FLAG).
5A5B
SBC HL,DE
Get the difference between the address in the code block and the requested address via a subtracts with carry which subtracts the value stored in Register Pair DE and the carry flag from the value stored in Register Pair HL.
5A5D
LD (5B1BH),HL
The result of that subtraction is in HL and is the offset. Store the offset (held in Register Pair HL) into memory location 5B1BH.
5A60
LD IY,BUFER2
Let Special Index Register Pair IY equal 6400H which will act as a buffer.
5A64
POP HL
Restore the relocation address (held at the top of the STACK) into Register Pair HL, and then remove the entry from the stack.
“LOOP3”
5A65
LD (IY+00H),01H
Store a CODE BLOCK indicator (i.e., 01H) into the memory location pointed to by Special Index Register Pair IY+00H.
5A69
INC IY
INCrement the value stored in Special Index Register IY by 1.
5A6B
LD (IY+00H),B
Store the character count (held in in Register B) into the memory location pointed to by Special Index Register Pair IY+00H.
5A6E
INC IY
INCrement the value stored in Special Index Register IY by 1.
5A70
LD (IY+00H),L
Store the LSB of the address (held in Register L) into the memory location pointed to by Special Index Register Pair IY+00H.
5A73
INC IY
INCrement the value stored in Special Index Register IY by 1.
5A75
LD (IY+00H),H
Store the MSB of the address (held in Register L) into the memory location pointed to by Special Index Register Pair IY+00H.
5A78
5A79
DEC B
DEC B
DECrement the value stored in Register B by 2 for the address.
5A7A
INC IY
INCrement the value stored in Special Index Register IY by 1.
“LOOP4”
5A7C
LD DE,S9DCB
Let Register Pair DE equal 6130H, which is a pointer to the FILE CONTROL BLOCK.
5A7F
CALL ZREAD
     [5AFBH]
Read a byte via a GOSUB to 5AFBH.
5A82
LD (IY+00H),A
Store the value held in Register A into the memory location pointed to by Special Index Register Pair IY+00H.
5A85
INC IY
INCrement the value stored in Special Index Register IY by 1.
5A87
DJNZ LOOP4
     [5A7CH]
LOOP back to 5A7CH, 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.
5A89
CALL ZREAD
     [5AFBH]
Read a byte, which will be the LOAD FILE HEADER, via a GOSUB to 5AFBH.
5A8C
CP 02H
Check to see if we are at the end of the record via receipt of an 02H by comparing the value held in Register A against 02H. Results: If Register A equals 02H, the Z FLAG is set; otherwise the NZ FLAG is set.
5A8E
JR Z,LOOP7
     [5AA9H]
If we fetched an 02H byte, then we are at the end of the record and the Z FLAG (Zero) will have set, JUMP to 5AA9H to exit.
5A90
CP 01H
See if the byte read was a CODE BLOCK (i.e., 01H) by comparing the value held in Register A against 01H. Results: If Register A equals 01H, the Z FLAG is set; otherwise the NZ FLAG is set.
5A92
JP NZ,LFERR
      [5A4AH]
If we did NOT fetch an 01H, then we have a problem and the NZ FLAG (Not Zero) will have been set, JUMP to 5A4AH.
5A95
CALL ZREAD
     [5AFBH]
Read a byte (the character count) via a GOSUB to 5AFBH.
5A98
LD B,A
Copy the character count (held in Register A) into Register B.
5A99
CALL ZREAD
     [5AFBH]
Read a byte, which is the LSB of the address, via a GOSUB to 5AFBH.
5A9C
LD L,A
Copy the LSB of the address (held in Register A) into Register L.
5A9D
CALL ZREAD
     [5AFBH]
Read a byte, which is the MSB of the address, via a GOSUB to 5AFBH.
5AA0
LD H,A
Copy the MSB of the address (held in Register A) into Register H.
5AA1
LD DE,(SAVE)
Fetch the offset value (held in memory location 5B1BH) and store it into Register Pair DE.
5AA5
ADD HL,DE
Add the offset to the load address by LETing Register Pair HL = Register Pair HL (load address) + Register DE (offset to the requested load address).
5AA6
JP LOOP3
   [5A65H]
Continue via a JUMP BACK to 5A65H.

5AA9H – Part of the RELO command. Jumped here if loop to read the characters in the prior routine hit an 02H to indicate END OF RECORD.

“LOOP7”
5AA9
LD (IY+00H),A
Store the value held in Register A (i.e., an 02H) into the memory location pointed to by Special Index Register Pair IY+00H.
5AAC
INC IY
INCrement the value stored in Special Index Register IY by 1.
5AAE
CALL ZREAD
     [5AFBH]
Read a byte (which will be an 02H) via a GOSUB to 5AFBH.
5AB1
CALL ZREAD
     [5AFBH]
Read a byte (the LSB of the entry address) via a GOSUB to 5AFBH.
5AB4
LD (IY+00H),02H
Store the lneght of the data which follows (i.e., 2 bytes) into the memory location pointed to by Special Index Register Pair IY+00H.
5AB8
INC IY
INCrement the value stored in Special Index Register IY by 1.
5ABA
LD (IY+00H),A
Store the LSB of the address (held in Register A) into the memory location pointed to by Special Index Register Pair IY+00H.
5ABD
INC IY
INCrement the value stored in Special Index Register IY by 1.
5ABF
CALL ZREAD
     [5AFBH]
Read a byte (the MSB of the entry address) via a GOSUB to 5AFBH.
5AC2
LD (IY+00H),A
Store the MSB of the address (held in Register A) into the memory location pointed to by Special Index Register Pair IY+00H.
5AC5
INC IY
INCrement the value stored in Special Index Register IY by 1.
5AC7
LD (SAVE1),IY
Store the value held in Special Index Register Pair IY (i.e., the end pointer) into memory location 5B1DH.
5ACB
LD DE,S9DCB
Let Register Pair DE equal 6130H, which is a pointer to the FILE CONTROL BLOCK.
5ACE
CALL 443FH
     [443FH]
GOSUB to 443FH.
NOTE: 443FH is the SYS00/SYS vector for ‘REWIND’, which will rewind the open file.
5AD1
JP NZ,EROR
      [5B04H]
If the NZ FLAG (Not Zero) has been set, then the CALL produced an error, so JUMP to JUMP to 5B04H.
5AD4
LD HL,(SAVE1)
Fetch the end pointer (held in memory location 5B1DH) and store it into Register Pair HL.
5AD7
LD DE,BUFER2
Let Register Pair DE equal 6400H which is a BUFFER in RAM for DATA.
5ADA
OR A
Set FLAGS based on the contents of Register A (and, in all events, clear the CARRY FLAG).
5ADB
SBC HL,DE
Determine the applicable number of bytes by subtracting the value stored in Register Pair DE (the buffer starting address) and the carry flag from the value stored in Register Pair HL (the end pointer).
5ADD
5ADE
LD B,H
LD C,L
Let Register Pair BC = the number of applicable bytes (held in Register Pair HL).
5ADF
EX DE,HL
EXchange the buffer address (stored in Register Pair HL) with the number of bytes (stored in Register Pair DE).
5AE0
LD DE,S9DCB
Let Register Pair DE equal 6130H, which is a pointer to the FILE CONTROL BLOCK.
“LOOP8”
5AE3
LD A,(HL)
Fetch the a character held in the memory location pointed to by Register Pair HL and store it into Register A.
5AE4
CALL ZWRITE
     [5B07H]
Write that character out via a GOSUB to 5B07H.
5AE7
INC HL
INCrement the buffer pointer (stored in Register Pair HL) by 1.
5AE8
DEC BC
DECrement the byte counter (stored in Register Pair BC) by 1.
5AE9
5AE9
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.
5AEB
JR NZ,LOOP8
      [5AE3H]
If the byte counter did NOT hit zero, then the NZ FLAG (Not Zero) will have been set, so LOOP BACK to 5AE3H.
5AED
CALL 4428H
     [4428H]
GOSUB to 4428H to CLOSE the file
NOTE: 4428H is the SYS00/SYS routine to CLOSE A DISK FILE. This RST 28H’s with a value of 93H so as to call ROUTINE 1 in OVERLAY 3.
5AF0
JP 402DH
   [402DH]
Return to DOS READY via a JUMP to the SYS00/SYS vector at 402DH.

5AF3H – Continuation of RELO Command. Jumped here if we need to skip over all the bytes in a COMMENT block. Requires Register B to contain the number of bytes in the COMMENT BLOCK to be skipped.

“STALL”
5AF3
CALL ZREAD
     [5AFBH]
Read a byte via a GOSUB to 5AFBH.
5AF6
DJNZ 5AF3H
     [5AF3H]
LOOP back to 5AF3H, 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.
5AF8
JP LOOP2
   [5A38H]
JUMP back into the applicable loop of the RELO routine – 5A38H.

5AFBH – Continuation of RELO Command. Thgis routine reads a byte and puts it into Register A.

“ZREAD”
5AFB
PUSH DE
Save the contents of Register Pair DE to the top of the stack.
5AFC
LD DE,S9DCB
Let Register Pair DE equal 6130H, which is a pointer to the FILE CONTROL BLOCK.
5AFF
CALL 0013H
     [0013H]
GOSUB to 0013H.
NOTE: 0013H is the Model III ROM routine to read a byte from an input device. Requires DE = starting address of DCB of device and on Exit Register A = byte received from device, Z set if device ready. Uses AF.
5B02
POP DE
Put the value held at the top of the STACK into Register Pair DE, and then remove the entry from the stack.
5B03
RET Z
If the Z FLAG (Zero) has been set, RETurn to the caller.

5B04H – Continuation of the RELO Command. Exit to the error handler.

“EROR”
5B04
JP 4409H
   [4409H]
JUMP to 4409H.
NOTE: 4409H is the SYS00/SYS routine to process DOS errors.

5B07H – Continuation of the RELO Command. Write a byte out.

“ZWRITE”
5B07
PUSH DE
Save the contents of Register Pair DE to the top of the stack.
5B08
LD DE,S9DCB
Let Register Pair DE equal 6130H, which is a pointer to the FILE CONTROL BLOCK.
5B0B
CALL 001BH
     [001BH]
GOSUB to 001BH.
NOTE: 001BH is the Model III ROM routine to write a byte to an output device. Requires Register A to contain the byte to output and Register Pair DE to be the starting address of DCB of device. On exit, Z set if device ready. Uses AF.
5B0E
POP DE
Put the value held at the top of the STACK into Register Pair DE, and then remove the entry from the stack.
5B0F
RET Z
If the Z FLAG (Zero) has been set, RETurn to the caller.
5B10
JR EROR
   [5B04H]
Exit to the exit handler via a JUMP to 5B04H.

5B12H – MESSAGE and STORAGE AREA for the RELO COMMAND.

“RLTABL”
5B12
DEFM ‘ADD ‘
 
 
DEFW RLADD
A 2 byte storage location to hold the relocation address
 
DEFB 00H
 
“SAVE” 
DEFS 2
General storage location of 2 bytes.
“SAVE1” 
DEFS 2
General storage location of 2 bytes.

5B1FH – Main Routine – “FORMS”.

“FORMS”
5B1F
LD BC,0000H
Let Register Pair BC equal 0000H for the next two instructions.
5B22
LD (CHAR),BC
Clear the PRINTER WIDTH flag by putting a 00H into memory location 5B44H.
5B26
LD (FLINE),BC
Clear the PAGE LENGTH flag by putting a 00H into memory location 5B51H.
5B2A
CALL SKIPSP
     [5F8EH]
Get the next non-space COMMAND LINE character via a GOSUB to 5F8EH.
5B2D
CP 0DH
Compare the value held in Register A against 0DH (ASCII: CARRIAGE RETURN). Results: If Register A equals CARRIAGE RETURN, the Z FLAG is set; otherwise the NZ FLAG is set.
5B2F
JR NZ,5B36H
      [5B36H]
If we did NOT get a CARRIAGE RETURN, then we got more than just the FORMS command alone as a command and the NZ FLAG (Not Zero) will have been set, JUMP to 5B36H.
5B31
LD A,0CH
Let Register A equal 0CH which is the FORM FEED.
5B33
JP 003BH
   [003BH]
JUMP to 003BH.
NOTE: 003BH is the Model III ROM routine to write the byte held in Register A to the printer, including waiting for the printer to be available OR getting a BREAK. Uses Register Pair DE. Since this was JUMPED to instead of CALLed, the RET at the end of this ROM routine will then RETurn to the caller of this subroutine instead of returning to this place.

5B36H – Continuation of the “FORMS” Routine. Jumped here if we determined that we actually got parameters on the COMMAND LINE.

“FORMS1”
5B36
LD DE,FORCOM
Let Register Pair DE equal 5B5FH which is a pointer to the table of valid FORMS parameters.
5B39
CALL 4454H
     [4454H]
GOSUB to 4454H.
NOTE: 4454H is the DOS PARAMETER STRING PARSE routine. It decodes DOS LIBRARY parameters.
5B3C
JP NZ,ERR2
      [5219H]
If the NZ FLAG (Not Zero) has been set, then the CALL produced an error, so JUMP to 5219H to report an ILLEGAL COMMAND PARAMETER error, and ABORT.
“FORMS2”
5B3F
LD IX,4025H
Let Special Index Register Pair IX equal 4025H, which is the PRINTER DCB.
5B43
LD HL,(CHAR)
Let Register Pair HL equal the LINE WIDTH, placed elsewhere in this overlay.
5B46
CALL CONVHX
     [6086H]
Convert the character held in Register Pair HL into hexadecimal via a GOSUB to 6086H.
5B49
5B49
LD A,H
OR L
Since the Z-80 cannot test Register Pair HL against zero, the common trick is to set Register A to equal to Register H, and then OR A against Register L. Only if both Register H and Register L were zero can the Z FLAG be set.
5B4B
JR Z,FORMS3
     [5B50H]
If the user didn’t select anything (and the result of the hexidecimal conversion was a 00) the Z FLAG (Zero) will have been set; JUMP to 5B50H to try lines per page.
5B4D
LD (IX+06H),L
Store the user count (held in Register L) into the memory location pointed to by Special Index Register Pair IX+06H.
Note: IX+06H = the position in the PRINTER DCB for LINE WIDTH.
“FORMS3”
5B50
LD HL,(FLINE)
Let Register Pair HL equal the PAGE LENGTH, placed elsewhere in this overlay.
5B53
CALL CONVHX
     [6086H]
Convert the character held in Register Pair HL into hexadecimal via a GOSUB to 6086H.
5B56
5B56
LD A,H
OR L
Since the Z-80 cannot test Register Pair HL against zero, the common trick is to set Register A to equal to Register H, and then OR A against Register L. Only if both Register H and Register L were zero can the Z FLAG be set.
5B58
RET Z
If there is no value held in HL then there is no line length to set, so exit via a RETurn to the caller.
5B59
INC L
INCrement the value stored in Register L by 1, to see if THAT produces a zero (which means it was FF, or INDEFINITE).
5B5A
RET Z
If the Z FLAG (Zero) is STILL set, exit via a RETurn to the caller.
5B5B
LD (IX+03H),L
Store the new lines per page value (held in Register L) into the memory location pointed to by Special Index Register Pair IX+03H.
Note: IX+03H = the position in the PRINTER DCB for LINES PER PAGE.
5B5E
RET
RETurn to the caller.

5B5FH – Continuation of the “FORMS” Routine. MESSAGE and BYTE STORAGE.

“FORCOM”
5B5F
DEFM ‘WIDTH ‘
 
 
DEFW CHAR
 
 
DEFM ‘LINES ‘
 
 
DEFW FLINE
 
 
DEFB 00H
End of Parameter List Terminator

5B70H – General Subroutine. Compare DE and HL Strings.

“COMPAR”
5B70
PUSH BC
Save the contents of Register Pair BC to the top of the stack.
5B71
PUSH DE
Save the contents of Register Pair DE to the top of the stack.
5B72
PUSH HL
Save the contents of Register Pair HL to the top of the stack.
“COMPA1”
5B73
LD A,(DE)
Fetch the value held in the memory location pointed to by Register Pair DE and store it into Register A.
5B74
CP (HL)
Compare the value held in Register A against the value held in the memory location pointed to by Register Pair HL. Results: If Register A equals the value held in Register HL, the Z FLAG is set; otherwise the NZ FLAG is set.
5B75
JR NZ,COMPA2
      [5B7CH]
If there is no match, then the NZ FLAG (Not Zero) will have been set, JUMP to 5B7CH.
5B77
LDI
Move to the 2nd character of both HL and DE via LDI command; which copies BC number of characters from (HL) to (DE), dropping BC each time. When BC hits 0, the PE flag is reset.
5B79
JP PE,COMPA1
      [5B73H]
LOOP BACK to 5B73H until finished.
“COMPA2”
5B7C
POP HL
Put the value held at the top of the STACK into Register Pair HL, and then remove the entry from the stack.
5B7D
POP DE
Put the value held at the top of the STACK into Register Pair DE, and then remove the entry from the stack.
5B7E
POP BC
Put the value held at the top of the STACK into Register Pair BC, and then remove the entry from the stack.
5B7F
RET
RETurn to the caller.

5B80H – Display “MESSAGE” + ” = “. HL must point to the message

“PDATA”
5B80
CALL 021BH
     [021BH]
GOSUB to 021BH.
NOTE: 021BH is the Model III ROM routine to display the character at (HL) until a 03H is found.
5B83
LD HL,S9EQU
Let Register Pair HL equal 5B96H to point to the message ” = “.
5B86
JP 021BH
   [021BH]
JUMP to 021BH.
NOTE: 021BH is the Model III ROM routine to display the character at (HL) until a 03H is found. Since this was JUMPED to instead of CALLed, the RET at the end of this ROM routine will then RETurn to the caller of this subroutine instead of returning to this place.

5B89H – Display “MESSAGE” + “, “. HL must point to the message

“PDATA1”
5B89
CALL 021BH
     [021BH]
GOSUB to 021BH.
NOTE: 021BH is the Model III ROM routine to display the character at (HL) until a 03H is found.
“PDATA2”
5B8C
LD A,PCHANG
Let Register A equal ,. Note, this can be changed to a different character if the routine is to display with a space instead of a comma.
5B8E
CALL 0033H
     [0033H]
GOSUB to 0033H.
NOTE: 0033H is the Model III ROM character print routine; displays the character held in Register A at the current cursor position.
5B91
LD A,20H
Let Register A equal SPACE.
5B93
JP 0033H
   [0033H]
JUMP to 0033H.
NOTE: 0033H is the Model III ROM character print routine; displays the character held in Register A at the current cursor position. Since this was JUMPED to instead of CALLed, the RET at the end of this ROM routine will then RETurn to the caller of this subroutine instead of returning to this place.

5B96H – MESSAGE AND STORAGE AREA.

“S9EQU”5B96
DEFM ” = ” +03H
 

5B9AH – NEW “ROUTE” COMMAND. This was deprecated, and the below 2 instructions just throw an error.

“ROUTE”
5B9A
LD A,1FH
Let Register A equal 1FH to point to the error PROGRAM NOT FOUND.
5B9C
JP 4409H
   [4409H]
JUMP to 4409H.
NOTE: 4409H is the SYS00/SYS routine to process DOS errors.

5B9AH – OLD “ROUTE” COMMAND. Before the ROUTE command was deprecated, the code was …

5B9A
LD A,(442FH)
Let Register A equal the contents of the memory location 442FH, which was the ROUTE/DUAL Flag.
5B9C
CP 80H
Check to see if the ROUTE/DUAL Flag at 442FH was 80H (meaning that ROUTE was active).
5B9F
JR Z,ROUTIT
     [5BA5H]
If the ROUTE command was already active, then the Z FLAG (Zero) will have been set, so JUMP to 5BA5H.
5BA1
OR A
Set FLAGS based on the contents of Register A (and, in all events, clear the CARRY FLAG).
5BA2
JP NZ,NOROTE
      [5C3AH]
If the DUAL command was already active, then the NZ FLAG (Zero) will have been set, so JUMP to 5C3AH.

If we are here then neither the ROUTE nor DUAL was set, so we need to actually process the command.

“ROUTIT”
5BA5
CALL SKIPSP
     [5F8EH]
Get the next non-space COMMAND LINE character via a GOSUB to 5F8EH.
5BA8
CP 20H
Compare the value held in Register A against 20H (ASCII: SPACE). Results:
  • If Register A equals SPACE, the Z FLAG is set.
  • If A < SPACE, the CARRY FLAG will be set.
  • if A >= SPACE, the NO CARRY FLAG will be set.
5BAA
JP C,0069H
     [0069H]
If the COMMAND LINE character is < SPACE, meaning we got no valid parameter when the command was called, the C FLAG (Carry) will have been set, JUMP to 0069H to initialize the drivers.
5BAD
CP 28H
Compare the value held in Register A against 28H (ASCII: (). Results: If Register A equals (, the Z FLAG is set; otherwise the NZ FLAG is set.
5BAF
JP NZ,ERR3
      [521DH]
If we are here, then we need a valid command line, which would necessitate that the next character is a (. If we did not get the (, then the NZ FLAG (Not Zero) will have been set, JUMP to 521DH to exit with an error.
5BB2
INC HL
Point to the next character on the command line, following the (, by INCrementing the value stored in Register Pair HL by 1.
“REROT”
5BB3
LD DE,S9SRC1
Let Register Pair DE equal 5C5DH, which points to the word “SOURCE”.
5BB6
LD A,(DE)
Fetch the parameter length (held in the memory location pointed to by Register Pair DE) and store it into Register A.
5BB7
5BB8
LD C,A
LD B,00H
Let Register Pair BC = the parameter length.
5BBA
INC DE
INCrement the value stored in Register Pair DE by 1 to now point to the word “SOURCE”.
5BBB
CALL COMPAR
     [5B70H]
Compare HL and DE to see if they match via a GOSUB to 5B70H.
5BBE
JR NZ,ROUTE5
      [5BF4H]
If they don’t match, then we didn’t get “SOURCE”. Maybe we got “DEST” so JUMP to 5BF4H.
5BC0
ADD HL,BC
Point Register Pair HL to the next parameter by advancing HL by BC bytes so now the COMMAND LINE Pointer points to the “=”.
5BC1
CALL GETTOK
     [5C10H]
Get the device name from the COMMAND LINE via a GOSUB to 5C10H.
5BC4
JP NZ,ERR2
      [5219H]
If the NZ FLAG (Not Zero) has been set, then the CALL produced an error (which would be that the parameter didn’t match any valid device), so JUMP to 5219H to report an ILLEGAL COMMAND PARAMETER error, and ABORT.
5BC7
PUSH HL
Save the position on the COMMAND LINE (held in Register Pair HL) to the top of the stack.
5BC8
EX DE,HL
EXchange the value stored in Register Pair HL (the position on the COMMAND LINE) with the value stored in Register Pair DE (the SOURCE name).
5BC9
LD DE,4222H
Let Register Pair DE equal 4222H which points to the ROUTE DCB for the DESTINATION name.
“ROUTE1”
5BCC
LD BC,0002H
Let Register Pair BC equal 0002H since there are 2 characters in a valid ROUTE source/destination.
5BCF
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.
5BD1
POP HL
Restore the position on the COMMAND LINE from the top of the stack into Register Pair HL, and then remove the entry from the stack.
5BD2
5BD3
INC HL
INC HL
Skip the 2 character device name on the COMMAND LINE by INCrementing the value stored in Register Pair HL by 2.
“ROUTE2”
5BD4
LD A,(HL)
Fetch the next character on the COMMAND LINE from the memory location pointed to by Register Pair HL and store it into Register A.
5BD5
CP 20H
Compare the value held in Register A against 20H (ASCII: SPACE). Results: If Register A equals SPACE, the Z FLAG is set; otherwise the NZ FLAG is set.
5BD7
JR Z,ROUTE4
     [5BF1H]
If we got a SPACE then we need to keep looking for the next valid character on the COMMAND LINE and the Z FLAG (Zero) will have been set, JUMP to 5BF1H to point the next character on the COMMAND LINE and then JUMP to 5BD4H.
5BD9
CP ‘,’
Compare the value held in Register A against ,. Results: If Register A equals ,, the Z FLAG is set; otherwise the NZ FLAG is set.
5BDB
JR Z,ROUTE4
     [5BF1H]
If we got a , then we need to keep looking for the next valid character on the COMMAND LINE and the Z FLAG (Zero) will have been set, JUMP to 5BF1H to point the next character on the COMMAND LINE and then JUMP to 5BD4H.
5BDD
CP 29H
Compare the value held in Register A against 29H (ASCII: )). Results: If Register A equals ), the Z FLAG is set; otherwise the NZ FLAG is set.
5BDF
JR Z,ROUTE3
     [5BE5H]
If we got a ) then we are at the end of the command and the Z FLAG (Zero) will have been set, JUMP to 5BE5H.
5BE1
CP 0DH
Compare the value held in Register A against 0DH (ASCII: CARRIAGE RETURN). Results: If Register A equals CARRIAGE RETURN, the Z FLAG is set; otherwise the NZ FLAG is set.
5BE3
JR NZ,REROT
      [5BB3H]
If the next character was NOT a CARRIAGE RETURN then we have more COMMAND LINE to search. JUMP to 5BB3H.
“ROUTE3”
5BE5
LD A,80H
Let Register A equal 80H, which is the ROUTE/DUAL FLAG for “ROUTE ACTIVE”.
5BE7
LD (442FH),A
Store the value held in Register A into memory location 442FH, which is the ROUTE/DUAL FLAG.
5BEA
CALL 006CH
     [006CH]
GOSUB to 006CH to route the devices.
5BED
JP NZ,ERR2
      [5219H]
If the NZ FLAG (Not Zero) has been set, then the CALL produced an error, so JUMP to 5219H to report an ILLEGAL COMMAND PARAMETER error, and ABORT.
5BF0
RET
RETurn to the caller.

5BF1H – ROUTINE inside the ROUTE COMMAND. Move the pointer to the current character on the COMMAND LINE by 1 and then JUMP to 5BD4H.

“ROUTE4”
5BF1
INC HL
Point to the next character on the command line by INCrementing the value stored in Register Pair HL by 1.
5BF2
JR ROUTE2
   [5BD4H]
JUMP BACK to 5BD4H.

5BF4H – ROUTINE inside the ROUTE COMMAND. Process the DESTINATION.

“ROUTE5”
5BF4
LD DE,S9DES1
Let Register Pair DE equal 5C64H, which points to the word “DESTIN”.
5BF7
LD A,(DE)
Fetch the parameter length (held in the memory location pointed to by Register Pair DE) and store it into Register A.
5BF8
5BF9
LD C,A
LD B,00H
Let Register Pair BC = the parameter length.
5BFB
INC DE
INCrement the value stored in Register Pair DE by 1 to now point to the word “DESTIN”.
5BFC
CALL COMPAR
     [5B70H]
Compare HL and DE to see if they match via a GOSUB to 5B70H.
5BFF
JP NZ,ERR2
      [5219H]
If they don’t match, then we didn’t get the correct parameter and the NZ FLAG (Not Zero) will have been set, so JUMP to 5219H to report an ILLEGAL COMMAND PARAMETER error, and ABORT.
5C02
ADD HL,BC
Point Register Pair HL to the next COMMAND LINE character after DESTIN by advancing HL by BC bytes.
5C03
CALL GETTOK
     [5C10H]
Get the device name from the COMMAND LINE via a GOSUB to 5C10H.
5C06
JP NZ,ERR2
      [5219H]
If the NZ FLAG (Not Zero) has been set, then the CALL produced an error, so JUMP to 5219H to report an ILLEGAL COMMAND PARAMETER error, and ABORT.
5C09
PUSH HL
Save the position on the COMMAND LINE (held in Register Pair HL) to the top of the stack.
5C0A
EX DE,HL
EXchange the value stored in Register Pair HL (the position on the COMMAND LINE) with the value stored in Register Pair DE (the DESTINATION name).
5C0B
LD DE,4220H
Let Register Pair DE equal 4220H which points to the ROUTE DCB for the DESTINATION name.
5C0E
JR ROUTE1
   [5BCCH]
JUMP into the prior routine to move the bytes and then keep polling the COMMAND LINE.

5C10H – Continuation of the ROUTE routine; process the actual source/destination device code.

“GETTOK”
5C10
LD A,(HL)
Fetch the next character from the command line (held in the memory location pointed to by Register Pair HL) and store it into Register A.
5C11
CP 3DH
Compare the value held in Register A against 3DH (ASCII: =).
5C13
RET NZ
If the next character was NOT a (ASCII: =), the NZ FLAG (Not Zero) will have been set, RETurn to the caller.
5C14
INC HL
Point to the next character on the command line, following the =, by INCrementing the value stored in Register Pair HL by 1.
5C15
LD DE,DO1
Let Register Pair DE equal 5C6BH, which points to the word “DO” (meaning the DISPLAY).
5C18
LD BC,0002H
Let Register Pair BC equal 0002H.
5C1B
CALL COMPAR
     [5B70H]
Compare HL and DE to see if they match via a GOSUB to 5B70H.
5C1E
RET Z
If command line pointed to “DO” then the Z FLAG (Zero) will have been set, RETurn to the caller.
5C1F
LD DE,KB1
Let Register Pair DE equal 5C6DH, which points to the word “KB” (meaning the KEYBOARD).
5C22
CALL COMPAR
     [5B70H]
Compare HL and DE to see if they match via a GOSUB to 5B70H.
5C25
RET Z
If command line pointed to “KB” then the Z FLAG (Zero) will have been set, RETurn to the caller.
5C26
LD DE,PR1
Let Register Pair DE equal 5C6FH, which points to the word “PR” (meaning the PRINTER).
5C29
CALL COMPAR
     [5B70H]
Compare HL and DE to see if they match via a GOSUB to 5B70H.
5C2C
RET Z
If command line pointed to “PR” then the Z FLAG (Zero) will have been set, RETurn to the caller.
5C2D
LD DE,RO1
Let Register Pair DE equal 5C71H, which points to the word “RO” (meaning the RS-232 OUT).
5C30
CALL COMPAR
     [5B70H]
Compare HL and DE to see if they match via a GOSUB to 5B70H.
5C33
RET Z
If command line pointed to “RO” then the Z FLAG (Zero) will have been set, RETurn to the caller.
5C34
LD DE,RI1
Let Register Pair DE equal 5C73H, which points to the word “RI” (meaning the RS-232 IN).
5C37
JP 5B70H
   [5B70H]
Compare HL and DE to see if they match via a JUMP (not GOSUB) to 5B70H.

5C3AH – Abort out of the ROUTE command via a “CAN’T ROUTE” Error.

“NOROTE”
5C3A
LD HL,RTMSG
Let Register Pair HL equal 5C40H, which points to the message “CAN’T ROUTE”.
5C3D
JP 021BH
   [021BH]
JUMP to 021BH.
NOTE: 021BH is the Model III ROM routine to display the character at (HL) until a 03H is found. Since this was JUMPED to instead of CALLed, the RET at the end of this ROM routine will then RETurn to the caller of this subroutine instead of returning to this place.

5C40H – MESSAGE and BYTE STORAGE AREA for the ROUTE COMMEND.

“RTMSG”
5C40
DEFM →
CAN’T ROUTE WHILE DUAL IS ON“.
“S9SRC1”
5C5D
DEFB 06H
Byte count for the word “SOURCE”.
5C5E
DEFM “SOURCE”
 
“S9DES1”
5C64
DEFB 06H
Byte count for the word “DESTIN”.
5C65
DEFM “DESTIN”
 
“DO1”
5C6B
DEFM “DO”
 
“KB1”
5C6D
DEFM “KB”
 
“PR1”
5C6F
DEFM “PR”
 
“RO1”
5C71
DEFM “RO”
 
“RI1”
5C73
DEFM “RI”
 

5C75H – “SETCOM” Command – Configure the RS-232.

“SETCOM”
5C75
CALL SKIPSP
     [5F8EH]
Get the next non-space COMMAND LINE character via a GOSUB to 5F8EH.
5C78
CP 20H
Compare the value held in Register A against 20H (ASCII: SPACE). Results:
  • If Register A equals SPACE, the Z FLAG is set.
  • If A < SPACE, the CARRY FLAG will be set.
  • if A >= SPACE, the NO CARRY FLAG will be set.
5C7A
JP NC,SETCO1
      [5D1FH]
If the character from the command line is >= SPACE, meaning we have an ALPHANUMERIC character, then the NC FLAG (No Carry) will have been set, JUMP to 5D1FH.
5C7D
LD A,(41F9H)
Fetch the value held in memory location 41F9H (which is where the RS-232 configuration is stored) and store it into Register A.
5C80
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).
5C81
JP Z,SETOFF
     [5D09H]
If the RS-232 Configuration Byte is zero, then the RS-232 is disabled; JUMP to 5D09H.
5C84
LD HL,BAUDMG
Let Register Pair HL equal 5E9FH, which is the pointer to the “BAUD = ” message.
5C87
CALL PDATA
     [5B80H]
GOSUB to 5B80H to display the “BAUD = ” message.
5C8A
LD A,(41F8H)
Fetch the value held in memory location 41F8H (which is where the RS-232 BAUD RATE is stored) and store it into Register A.
5C8D
AND 0FH
MASK the value of Register A against 0FH (0000 1111). This has the effect of leaving only bits 3, 2, 1, 0 active, which hold the RECEIVE BAUD RATE.
5C8F
ADD A,A
LET Register A = Register A * 2, because each entry in the table is 2 bytes.
5C90
5C91
LD C,A
LD B,00H
Let Register Pair BC = The doubled, masked, RS-232 Baud Rate (held in Register A).
5C93
LD HL,TABLE2
Let Register Pair HL equal 5E81H, which is the top of the BAUD RATE LOOKUP TABLE (which is a table of JUMP points, based on position, to the ASCII renditions of a BAUD Rate).
5C96
ADD HL,BC
Move HL down the BAUD RATE LOOKUP TABLE by the OFFSET held in Register Pair BC.
5C97
LD E,(HL)
Fetch the LSB of the location of the Baud Rate Text (held in the memory location pointed to by Register Pair HL) and store it into Register E.
5C98
INC HL
INCrement the value stored in Register Pair HL by 1 to as to point to the next byte of the BAUD RATE LOOKUP TABLE.
5C99
LD D,(HL)
Fetch the MSB of the location of the Baud Rate Text (held in the memory location pointed to by Register Pair HL) and store it into Register E.
5C9A
EX DE,HL
EXchange the value stored in Register Pair HL (currently pointing to the 2nd byte of the 2 byte address for the BAUD RATE LOOKUP TABLE) with the value stored in Register Pair DE (the address of the desired BAUD RATE text).
5C9B
CALL PDATA1
     [5B89H]
Display the baud rate and a comma via a GOSUB to 5B89H.
5C9E
LD HL,UARTMG
Let Register Pair HL equal 5EA4H, which is a pointer to the message “WORD = “.
5CA1
CALL PDATA
     [5B80H]
Display the message “WORD = ” via a GOSUB to 5B80H.
5CA4
LD A,(41F9H)
Fetch the value held in memory location 41F9H (which is where the RS-232 Configuration Byte is stored) and store it into Register A.
5CA7
AND 60H
MASK the value of Register A against 60H (0110 0000) leaving only bits 6 and 5 active.
5CA9
5CAA
5CAB
RLCA
RLCA
RLCA
Rotate the bits in A left (with Bit 7 going into Bit 0) three times so that the 2 bytes of the WORD code are in Bits 1 and 0.
5CAC
ADD A,A
LET Register A = Register A * 2, because each entry in the table is 2 bytes.
5CAD
5CAE
LD C,A
LD B,00H
Let Register Pair BC = The doubled, masked, RS-232 Word Length(held in Register A).
5CB0
LD HL,TABLE1
Let Register Pair HL equal 5E79H, which is the top of the WORD LENGTH LOOKUP TABLE (which is a table of JUMP points, based on position, to the ASCII renditions of the WORD LENGTH).
5CB3
ADD HL,BC
Let Register Pair HL = the top of the lookup table (Register Pair HL) + an offset (Register BC).
5CB4
LD E,(HL)
LD E,(HL)
Fetch the LSB of the location of the WORD LENGTH LOOKUP TABLE (held in the memory location pointed to by Register Pair HL) and store it into Register E.
5CB5
INC HL
INCrement the value stored in Register Pair HL by 1 to as to point to the next byte of the WORD LENGTH LOOKUP TABLE.
5CB6
LD D,(HL)
Fetch the MSB of the location of the WORD LENGTH LOOKUP TABLE (held in the memory location pointed to by Register Pair HL) and store it into Register E.
5CB7
EX DE,HL
EXchange the value stored in Register Pair HL (currently pointing to the 2nd byte of the 2 byte address for the WORD LENGTH LOOKUP TABLE) with the value stored in Register Pair DE (the address of the desired WORD LENGTH text).
5CB8
CALL PDATA1
     [5B89H]
Display the word length and a comma via a GOSUB to 5B89H.
5CBB
LD HL,STOPMG
Let Register Pair HL equal 5EA9H, which is a pointer to the message “STOP = “.
5CBE
CALL PDATA
     [5B80H]
Display the message “STOP = ” via a GOSUB to 5B80H.
5CC1
LD A,(41F9H)
Fetch the value held in memory location 41F9H (which is where the RS-232 configuration is stored) and store it into Register A.
5CC4
BIT 4,A
Test Bit Number 4 (which is the STOP bit) of Register A. Z FLAG will be set if that bit is 0, and NZ FLAG will be set if that bit is 1.
5CC6
LD A,31H
Let Register A equal 31H (ASCII: 1).
5CC8
JR Z,5CCBH
     [5CCBH]
If the Z FLAG (Zero) has been set, then there is ONE stop bit, so skip the next instrution (which sets up for a display of “2”) and JUMP to 5CCBH.
5CCA
INC A
INCrement the value stored in Register A by 1 to now be a 2.
“SETNO1”
5CCB
CALL 0033H
     [0033H]
GOSUB to 0033H.
NOTE: 0033H is the Model III ROM character print routine; displays the character held in Register A at the current cursor position.
5CCE
CALL PDATA2
     [5B8CH]
Display a “,” via a GOSUB to 5B8CH.
5CD1
LD HL,PARTMG
Let Register Pair HL equal 5EAEH, which is a pointer to the message “PARITY = “.
5CD4
CALL PDATA
     [5B80H]
Display the message “PARITY = ” via a GOSUB to 5B80H.
5CD7
LD A,(41F9H)
Fetch the value held in memory location 41F9H (which is where the RS-232 Configuration Byte is stored) and store it into Register A.
5CDA
LD HL,5EB5H
Let Register Pair HL equal 5EB5H, which is a pointer to the message “NONE”.
5CDD
BIT 3,A
Test Bit Number 3 of Register A to determine the PARITY status. Z FLAG will be set if that bit is 0 (which will mean PARITY IS ON), and NZ FLAG will be set if that bit is 1 (which will mean PARITY IS OFF).
5CDF
JP NZ,S9NOT3
      [5CECH]
If Parity is OFF then the NZ FLAG (Not Zero) will have been set. No need to determine ODD or EVEN so skip over all that via a JUMP to 5CECH.
“S9NOT2”
5CE2
LD HL,ODD
Let Register Pair HL equal 5EBAH, which is a pointer to the message “ODD”.
5CE5
BIT 7,A
Test Bit Number 7 of Register A to determine if the PARITY is odd or even. Z FLAG will be set if that bit is 0 (meaning ODD PARITY), and NZ FLAG will be set if that bit is 1 (meaning EVEN PARITY).
5CE7
JR Z,5CECH
     [5CECH]
If Bit 7 was 0, then we have ODD PARITY and the Z FLAG (Zero) will have been set. No need to determine EVEN parity, so skip over that via a JUMP to 5CECH.
5CE9
LD HL,5EBEH
Let Register Pair HL equal 5EBEH, which is a pointer to the message “EVEN”.
“S9NOT3”
5CEC
CALL PDATA1
     [5B89H]
Display the message pointed to by Register Pair HL (either NONE, ODD, or EVEN) and a “,” via a GOSUB to 5B89H.
5CEF
LD A,20H
Let Register A equal 20H (ASCII: SPACE).
5CF1
LD (5B8DH),A
Store the value held in Register A into memory location 5B8DH, which is where the “,” has been for all the prior calls.
5CF4
LD A,(41FAH)
Fetch the value held in memory location 41FAH (which is the RS-232 WAIT FLAG location) and store it into Register A. 0=Wait, 1=No Wait.
5CF7
LD HL,WAITS
Let Register Pair HL equal 5EC3H, which is a pointer to the message “WAIT”.
5CFA
OR A
Set FLAGS based on the contents of Register A (and, in all events, clear the CARRY FLAG).
5CFB
JR NZ,S9NOT4
      [5D00H]
If the byte means we have a WAIT then the NZ FLAG (Not Zero) will have been set, JUMP to 5D00H.
5CFD
LD HL,NWAITS
Let Register Pair HL equal 5EC8H, which is a pointer to the message “NO WAIT”.
“S9NOT4”
5D00
CALL PDATA1
     [5B89H]
Display the WAIT STATUS, whatever it is, via a GOSUB to 5B89H.
5D03
LD HL,SMODE
Let Register Pair HL equal 5ED0H, which is a pointer to the message “MODE”.
5D06
JP PDATA1
   [5B89H]
Display the message “MODE” and RETurn via a JUMP to 5B89H.

5D09H – SETCOM Routine – Turn the RS-232 Off.

“SETOFF”
5D09
XOR A
Set Register A to ZERO and clear all Flags.
5D0A
LD (41F8H),A
Zero out the BAUD RATE by storing the value held in Register A into memory location 41F8H (RS-232 Baud Rate).
5D0D
LD (41F9H),A
Zero out the UART CONFIGURATION by storing the value held in Register A into memory location 41F9H (RS-232 Configuration Byte).
5D10
DEC A
DECrement the value stored in Register A by 1 to now be FFH.
5D11
LD (41FAH),A
Enbale WAIT MODE by storing a FFH (held in Register A) into memory location 41FAH (RS-232 Wait Flag).
5D14
LD HL,RSOFF
Let Register Pair HL equal 5F22H, which is a pointer to the message “RS-232 IS OFF”.
“SETOUT”
5D17
PUSH HL
Save the pointer to the message “RS-232 IS OFF” (held in Register Pair HL) to the top of the stack.
5D18
CALL 005AH
     [005AH]
GOSUB to 005AH, which is the Model III ROM routine to Initialize the RS-232-C Interface.
5D1B
POP HL
Restore the pointer to the message “RS-232 IS OFF” (held top of the stack) into Register Pair HL, and then remove the entry from the stack.
5D1C
JP 021BH
   [021BH]
JUMP to 021BH.
NOTE: 021BH is the Model III ROM routine to display the character at (HL) until a 03H is found. Since this was JUMPED to instead of CALLed, the RET at the end of this ROM routine will then RETurn to the caller of this subroutine instead of returning to this place.

5D1FH – SETCOM Routine – Set up the RS-232 Channel.

“SETCO1”
5D1F
CP 28H
Check to see if we are at the start of a parameter list by comparing the value held in Register A against 28H (ASCII: (). Results: If Register A equals (, the Z FLAG is set; otherwise the NZ FLAG is set.
5D21
JP NZ,ERR2
      [5219H]
If Register A does NOT equal (, then we have a bad character, so JUMP to 5219H to report an ILLEGAL COMMAND PARAMETER error, and ABORT.
5D24
INC HL
Point HL to the next character (the one following the “(“) on the COMMAND LINE by INCrementing the value stored in Register Pair HL by 1.
5D25
LD A,(HL)
Fetch the next character on the COMMAND LINE (held in the memory location pointed to by Register Pair HL) and store it into Register A.
5D26
CP 29H
Compare the value held in Register A against 29H (ASCII: )). Results: If Register A equals 29H ), the Z FLAG is set; otherwise the NZ FLAG is set.
5D28
JR NZ,SETVAL
      [5D3DH]
If we didn’t get a “)” then the NZ FLAG (Not Zero) will have been set, set the values by JUMPing to 5D3DH.
5D2A
LD A,0A4H
Let Register A equal 0A4H (1010 0100). This would be Even Parity, Word Length = 7, 1 Stop Bit, Parity On, Send Break Signal, Request to Send On, Data Terminal Ready.
5D2C
LD (41F9H),A
Store the bit pattern 1010 0100 (held in Register A) into memory location 41F9H.
5D2F
LD A,55H
Let Register A equal 55H (0101 0101).
5D31
LD (41F8H),A
Store the bit pattern 0101 0101 (held in Register A) into memory location 41F8H to set the SEND and RECEIVE BAUD RATE to 300.
5D34
LD (41FAH),A
Store the bit pattern 0101 0101 (held in Register A) into memory location 41FAH to turn on the WAIT FLAG.
5D37
CALL 005AH
     [005AH]
GOSUB to 005AH, which is the Model III ROM routine to Initialize the RS-232-C Interface.
5D3A
JP SHOTEL
   [5C84H]
JUMP back to the RS-232 display status at 5C84H.

5D3DH – SETCOM Routine – Set up the RS-232 Channel – Jumped to if we didn’t get an OPEN PARENTHESIS when we expected it.

“SETVAL”
5D3D
DEC HL
Back HL up to point to the (ASCII: () on the COMMAND LINE.
5D3E
LD DE,SETSWT
Let Register Pair DE equal 5E11H which is the PARSER TABLE for valid SETCOM commands.
5D41
CALL 4454H
     [4454H]
GOSUB to 4454H.
NOTE: 4454H is the DOS PARAMETER STRING PARSE routine. It decodes DOS LIBRARY parameters.
5D44
JP NZ,ERR2
      [5219H]
If the NZ FLAG (Not Zero) has been set, then the CALL produced an error, so JUMP to 5219H to report an ILLEGAL COMMAND PARAMETER error, and ABORT.
5D47
LD HL,(SOFF)
Fetch the value held in memory location 5E03H (the RS-232 ON/OFF FLAG) and store it into Register Pair HL.
5D4A
5D4A
LD A,H
OR L
Since the Z-80 cannot test Register Pair HL against zero, the common trick is to set Register A to equal to Register H, and then OR A against Register L. Only if both Register H and Register L were zero can the Z FLAG be set.
5D4C
JR NZ,SETOFF
      [5D09H]
If RS-232 is off, then the NZ FLAG (Not Zero) will have been set, JUMP to 5D09H.
5D4E
LD HL,(5E0DH)
Fetch the value held in memory location 5E0DH (the WAIT FLAG) and store it into Register Pair HL.
5D51
5D51
LD A,H
OR L
Since the Z-80 cannot test Register Pair HL against zero, the common trick is to set Register A to equal to Register H, and then OR A against Register L. Only if both Register H and Register L were zero can the Z FLAG be set.
5D53
JR Z,SETVA1
     [5D5AH]
If the WAIT FLAG is on, then the Z FLAG (Zero) will have been set, JUMP to 5D5AH.
“SETWAT”
5D55
LD (WAIT),A
Store the value held in Register A into memory location 41FAH (which is the storage location for is the storage location for the RS-232 Wait Flag. 0=Wait, 1=No Wait).
5D58
JR SETVA2
   [5D64H]
Set the value and continue by JUMPing to 5D64H.

5D5AH – SETCOM Routine – Reset WAIT Mode.

“SETVA1”
5D5A
LD HL,(SSWAIT)
Fetch the value held in memory location 5E0FH (the “NO WAIT” FLAG) and store it into Register Pair HL.
5D5D
5D5D
LD A,H
OR L
Since the Z-80 cannot test Register Pair HL against zero, the common trick is to set Register A to equal to Register H, and then OR A against Register L. Only if both Register H and Register L were zero can the Z FLAG be set.
5D5F
JR Z,SETVA2
     [5D64H]
If it is already ZERO JUMP to 5D64H.
5D61
XOR A
Set Register A to ZERO and clear all Flags.
5D62
JR SETWAT
   [5D55H]
JUMP to 5D55H to continue.

5D64H – SETCOM Routine – Set the Baud Rate and Stop Bits.

“SETVA2”
5D64
LD BC,(SBAUD)
Fetch the value held in memory location 5E05H (the BAUD RATE FLAG) and store it into Register Pair BC.
5D68
5D68
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.
5D6A
JR Z,SETVA4
     [5D86H]
If the BAUD RATE is already ZERO, JUMP to 5D86H.
5D6C
LD HL,BADTAB
Let Register Pair HL equal 5E4AH, which is the top of the BAUD RATE LOOKUP TABLE.
“SETVA3”
5D6F
LD A,(HL)
Fetch the character in the BAUD RATE LOOKUP TABLE (held in the memory location pointed to by Register Pair HL) and store it into Register A.
5D70
CP 0FFH
Compare the value held in Register A against the end of table terminator byte (i.e., 0FFH). Results: If Register A equals 0FFH, the Z FLAG is set; otherwise the NZ FLAG is set.
5D72
JP Z,ERR2
     [5219H]
If we ran out of entries then the Z FLAG (Zero) will have been set, so JUMP to 5219H to report an ILLEGAL COMMAND PARAMETER error, and ABORT.
5D75
LD E,(HL)
Fetch the LSB of the 2 byte baud rate code (held in the memory location pointed to by Register Pair HL) and store it into Register E.
5D76
INC HL
INCrement the table pointer (stored in Register Pair HL) by 1. HL should now be pointing to the MSB of the baud rate code.
5D77
LD D,(HL)
Fetch the MSB of the 2 byte baud rate code (held in the memory location pointed to by Register Pair HL) and store it into Register E.
5D78
INC HL
INCrement the table pointer (stored in Register Pair HL) by 1. HL should now be pointing to the value associated with that baud rate.
5D79
INC HL
INCrement the value stored in Register Pair HL by 1. HL should now be pointing to the LSB of the next baud rate in the table.
5D7A
OR A
Set FLAGS based on the contents of Register A (and, in all events, clear the CARRY FLAG).
5D7B
EX DE,HL
EXchange the value stored in Register Pair HL (the pointer to the next entry in the BAUD RATE TABLE) with the value stored in Register Pair DE (the last decoded baud rate).
5D7C
SBC HL,BC
Check to see if the table entry matches what the user entered via subtracting the value stored in Register Pair BC and the carry flag from the value stored in Register Pair HL.
5D7E
EX DE,HL
EXchange the value stored in Register Pair HL (the last decoded baud rate) with the value stored in Register Pair DE (the pointer to the next entry in the BAUD RATE TABLE).
5D7F
JR NZ,SETVA3
      [5D6FH]
If there was no match, then the NZ FLAG (Not Zero) will have been set, JUMP to 5D6FH to look at the next entry in the table.
5D81
DEC HL
DECrement the value stored in Register Pair HL by 1 to now point to the value associated with the match (which is the BAUD RATE in the table entry).
5D82
LD A,(HL)
Fetch the value held in the memory location pointed to by Register Pair HL and store it into Register A.
5D83
LD (41F8H),A
Store the value from the table which matched the selected baud rate (held in Register A) into memory location 41F8H (which is the Model III storage location for the TRANSMIT and RECEIVE Baud Rate).
“SETVA4”
5D86
LD HL,(SSTOP)
Fetch the value held in memory location 5E09H (i.e., the NUMBER OF STOP BITS) and store it into Register Pair HL.
5D89
5D89
LD A,H
OR L
Since the Z-80 cannot test Register Pair HL against zero, the common trick is to set Register A to equal to Register H, and then OR A against Register L. Only if both Register H and Register L were zero can the Z FLAG be set.
5D8B
JR Z,SETVA5
     [5D96H]
If the Z FLAG (Zero) has been set, then no stop bits were given, so JUMP to 5D96H to continue.
5D8D
DEC L
Start testing to see if ONE stop bit was given by DECrementing the LSB of the STOP BIT value stored in Register L by 1.
5D8E
LD B,10H
Let Register B equal a mask of 10H (0001 0000).
5D90
CALL Z,UNSET
       [5DFAH]
If Register L was already at 0, then we had ONE STOP BIT, and we need to clear that bit via a GOSUB to 5DFAH.
5D93
CALL NZ,SETBYT
        [5DF1H]
If result from that GOSUB set the NZ FLAG -or- Register L was not already at 0, then we have two stop bits, and we need to set that bit via a GOSUB to 5DF1H.
“SETVA5”
5D96
LD HL,(SPAR)
Fetch the value held in memory location 5E0BH (i.e., the PARITY) and store it into Register Pair HL.
5D99
5D99
LD A,H
OR L
Since the Z-80 cannot test Register Pair HL against zero, the common trick is to set Register A to equal to Register H, and then OR A against Register L. Only if both Register H and Register L were zero can the Z FLAG be set.
5D9B
LD B,08H
Let Register B equal a mask of 08H (0000 1000).
5D9D
JR Z,SETVA6
     [5DB5H]
If the PARITY was already at 0, JUMP to 5DB5H.
5D9F
LD A,L
Copy the Parity Value (held in Register L) into Register A.
5DA0
CP 03H
Compare the value held in Register A against 03H. Results: If Register A equals 03H (Parity = NONE), the Z FLAG is set; otherwise the NZ FLAG is set.
5DA2
JR NZ,SETV50
      [5DA9H]
If the NO PARITY set has NOT been set, the NZ FLAG (Not Zero) will have been set, JUMP to 5DA9H to set the parity.
5DA4
CALL SETBYT
     [5DF1H]
GOSUB to 5DF1H to set the Parity = NONE bit.
5DA7
JR SETVA6
   [5DB5H]
JUMP to 5DB5H to continue.

5DA9H – SETCOM Routine – Set the Parity and Word Length.

“SETV50”
5DA9
CALL UNSET
     [5DFAH]
Reset the PARITY BIT via a GOSUB to 5DFAH.
5DAC
DEC L
Check to see if the PARITY was set to ODD by DECrementing the value stored in Register L by 1 so bt the parity type (odd or even).
5DAD
LD B,80H
Let Register B equal a mask of 80H (1000 0000).
5DAF
CALL Z,UNSET
       [5DFAH]
If the DEC resulted in a 0, then clear the bit via a GOSUB to 5DFAH.
5DB2
CALL NZ,SETBYT
        [5DF1H]
If the NZ FLAG (Not Zero) has been set, then set the bit via a GOSUB to 5DF1H.
“SETVA6”
5DB5
LD HL,(SWORD)
Fetch the WORD LENGTH (held in memory location 5E07H) and store it into Register Pair HL.
5DB8
5DB8
LD A,H
OR L
Since the Z-80 cannot test Register Pair HL against zero, the common trick is to set Register A to equal to Register H, and then OR A against Register L. Only if both Register H and Register L were zero can the Z FLAG be set.
5DBA
JR Z,SETVA9
     [5DE1H]
If the WORD LENGTH storage location was a 0, JUMP to 5DE1H.
5DBC
LD B,60H
Let Register B equal a mask of 60H (0110 0000).
5DBE
CALL UNSET
     [5DFAH]
Clear the word length bits via a GOSUB to 5DFAH.
5DC1
LD A,L
Copy the contents of Register L (the length) into Register A.
5DC2
SUB 05H
SUBtract the value 05H from Register A to leave A in the range of 00-03.
5DC4
JP C,ERR2
     [5219H]
If the starting value was too low, then the C FLAG (Carry) has been set, so JUMP to 5219H to report an ILLEGAL COMMAND PARAMETER error, and ABORT.
5DC7
JR Z,SETVA9
     [5DE1H]
If the resulting value is 00, then we have 5 bits so JUMP to 5DE1H.
5DC9
LD L,A
Copy the subtracted contents of Register A back into Register L.
5DCA
DEC L
DECrement the value stored in Register L by 1. IF L is 0 then we have 6 bits.
5DCB
JR NZ,SETVA7
      [5DD1H]
If we have MORE than 6 bits, the NZ FLAG (Not Zero) will have been set, so JUMP to 5DD1H.
5DCD
LD B,40H
Let Register B equal a mask of 40H (0100 0000).
5DCF
JR SETVAA
   [5DDEH]
Set the mask of 6 bits via a JUMP to 5DDEH.

5DD1H – SETCOM Routine – Set the Word Length if 7 Bits.

“SETVA7”
5DD1
DEC L
DECrement the value stored in Register L by 1. IF L is 0 then we have 7 bits.
5DD2
JR NZ,SETVA8
      [5DD8H]
If we don’t have 7 bits the NZ FLAG (Not Zero) will have been set, JUMP to 5DD8H.
5DD4
LD B,20H
Let Register B equal a mask of 20H (0010 0000).
5DD6
JR SETVAA
   [5DDEH]
Set a mask of 7 bits via a JUMP to 5DDEH.

5DD8H – SETCOM Routine – Set the Word Length if 8 Bits.

“SETVA8”
5DD8
DEC L
DECrement the value stored in Register L by 1. IF L is 0 then we have 8 bits.
5DD9
JP NZ,ERR2
      [5219H]
If we don’t have 8 bits then the NZ FLAG (Not Zero) will have been set, so JUMP to 5219H to report an ILLEGAL COMMAND PARAMETER error, and ABORT.
5DDC
LD B,60H
Let Register B equal a mask of 60H (0110 0000).
“SETVAA”
5DDE
CALL SETBYT
     [5DF1H]
Set a mask of 8 bits via a GOSUB to 5DF1H.
“SETVA9”
5DE1
LD A,(41F9H)
Fetch the RS-232 Configuration Byte (in memory location 41F9H) and store it into Register A.
5DE4
AND 0FCH
MASK the value of Register A against 0FCH (1111 1100). This has the effect of turning off bits 1 (Request to Send) and 0 (Data Terminal Ready).
5DE6
OR 04H
OR Register A against 04H (0000 0100). This has the effect of turning on bit 2 (TRANSMIT = Enable).
5DE8
LD (41F9H),A
Store the revised value held in Register A into memory location 41F9H.
5DEB
CALL 005AH
     [005AH]
GOSUB to 005AH, which is the Model III ROM routine to Initialize the RS-232-C Interface.
5DEE
JP SHOTEL
   [5C84H]
Display the resulting revised RS-232 settings and RETurn via a JUMP to 5C84H.

5DF1H – SETCOM Routine – Set the configuration bits of the RS-232 based on the mask held in Register B.

“SETBYT”
5DF1
LD A,(41F9H)
Fetch the RS-232 Configuration Byte (held in memory location 41F9H) and store it into Register A.
5DF4
OR B
Apply the mask held in Reigster B via ORing Register B against Register A. The results are stored in Register A.
“SETBY1”
5DF5
LD (41F9H),A
Store the revised RS-232 Configuration Byte (value held in Register A) into memory location 41F9H.
5DF8
XOR A
Set Register A to ZERO and clear all Flags.
5DF9
RET
RETurn to the caller.

5DFAH – SETCOM Routine – Reset the configuration bits of the RS-232 based on the mask held in Register B.

“UNSET”
5DFA
LD A,B
Copy the mask (held in Register B on entry) into Register A.
5DFB
CPL
Reverse each bit in Register A (which is the same as NOT).
5DFC
LD B,A
Put the modified mask back into Register B.
5DFD
LD A,(41F9H)
Fetch the RS-232 Configuration Byte (held in memory location 41F9H) and store it into Register A.
5E00
AND B
MASK the value of Register A against the value held in Register B to turn off all the undesired bits.
5E01
JR SETBY1
   [5DF5H]
JUMP to 5DF5H to finish.

5E03H – MESSAGE and BYTE STORAGE for SETCOM.

“SOFF”
5E03
DEFW 0000H
RS-232 ON/OFF FLAG.
“SBAUD”
5E05
DEFW 0000H
BAUD RATE FLAG.
“SWORD”
5E07
DEFW 0000H
WORD LENGTH.
“SSTOP”
5E08
DEFW 0000H
NUMBER OF STOP BITS.
“SPAR”
5E0B
DEFW 0000H
PARITY SETTING.
“SWAIT”
5E0D
DEFW 0000H
“WAIT” FLAG.
“SSWAIT”
5E0F
DEFW 0000H
“NO WAIT” FLAG.

5E11H – PARSER TABLE for SETCOM.

“SETSWT”
5E11
DEFM “OFF “
 
5El9
DEFM “BAUD “
 
5E21
DEFM “WORD “
 
5E29
DEFM “STOP “
 
5E31
DEFM “PARITY”
 
5E39
DEFM “WAIT “
 
5E41
DEFM “NOWAIT”
 
5E49
DEFB 00H
Table Terminator

5E4AH – BAUD RATE TABLE for SETCOM.

“BADTAB”
5E4A
DEFB 50H 00H 00H
Baud Rate of 50
5E4D
DEFB 75H 00H 11H
Baud Rate of 75
5E50
DEFB 10H 01H 22H
Baud Rate of 110
5E53
DEFB 34H 01H 33H
Baud Rate of 134.5
5E56
DEFB 50H 01H 44H
Baud Rate of 150
5E59
DEFB 00H 03H 55H
Baud Rate of 300
5E5C
DEFB 00H 06H 66H
Baud Rate of 600
5E5F
DEFB 00H 12H 77H
Baud Rate of 1200
5E62
DEFB 00H 18H 88H
Baud Rate of 1800
5E65
DEFB 00H 20H 99H
Baud Rate of 2000
5E68
DEFB 00H 24H AAH
Baud Rate of 2400
5E6B
DEFB 00H 36H BBH
Baud Rate of 3600
5E6E
DEFB 00H 48H CCH
Baud Rate of 4800
5E71
DEFB 00H 72H DDH
Baud Rate of 7200
5E74
DEFB 00H 96H EEH
Baud Rate of 9600
5E77
DEFB FFH FFH
End of Table Designator

5E79H – Word Length Text Pointer Table.

“TABLE1”
5E79
DEFW D6H 5EH
Pointer to the ASCII Text corresponding to a Word Length of 5
5E7B
DEFW D8H 5EH
Pointer to the ASCII Text corresponding to a Word Length of 6
5E7D
DEFW DAH 5EH
Pointer to the ASCII Text corresponding to a Word Length of 7
5E7F
DEFW DCH 5EH
Pointer to the ASCII Text corresponding to a Word Length of 8

5E81H – Baud Rate Text Pointer Table.

“TABLE2”
5E81
DEFW DEH 5EH
Pointer to the ASCII Text corresponding to a Baud Rate of 50
5E83
DEFW E1H 5EH
Pointer to the ASCII Text corresponding to a Baud Rate of 75
5E85
DEFW E4H 5EH
Pointer to the ASCII Text corresponding to a Baud Rate of 110
5E87
DEFW E8H 5EH
Pointer to the ASCII Text corresponding to a Baud Rate of 134.5
5E89
DEFW EEH 5EH
Pointer to the ASCII Text corresponding to a Baud Rate of 150
5E8B
DEFW F2H 5EH
Pointer to the ASCII Text corresponding to a Baud Rate of 300
5E8D
DEFW F6H 5EH
Pointer to the ASCII Text corresponding to a Baud Rate of 600
5E8F
DEFW FAH 5EH
Pointer to the ASCII Text corresponding to a Baud Rate of 1200
5E91
DEFW FFH 5EH
Pointer to the ASCII Text corresponding to a Baud Rate of 1800
5E93
DEFW 04H 5FH
Pointer to the ASCII Text corresponding to a Baud Rate of 2000
5E95
DEFW D9H 5FH
Pointer to the ASCII Text corresponding to a Baud Rate of 2400
5E97
DEFW 0EH 5FH
Pointer to the ASCII Text corresponding to a Baud Rate of 3600
5E99
DEFW 13H 5FH
Pointer to the ASCII Text corresponding to a Baud Rate of 4800
5E9B
DEFW 18H 5FH
Pointer to the ASCII Text corresponding to a Baud Rate of 7200
5E9E
DEFW 1DH 5FH
Pointer to the ASCII Text corresponding to a Baud Rate of 9600

5E9FH – MESSAGE DISPLAY for SETCOM CONFIGURATION.

“BAUDMG”
5E9F
DEFM “BAUD” + 03H
Configuration Element
“UARTMG”
5EA4
DEFM “WORD” + 03H
Configuration Element
“STOPMG”
5EA9
DEFM “STOP” + 03H
Configuration Element
“PARTMG”
5EAE
DEFM “PARITY” + 03H
Configuration Element
“NONE”
5EB5
DEFM “NONE” + 03H
Parity Classes
“ODD”
SEBA
DEFM “ODD” + 03H
Parity Classes
“EVEN”
5EBE
DEFM “EVEN” + 03H
Parity Classes
“WAITS”
5EC3
DEFM “WAIT” + 03H
Wait States
“NWAITS”
5EC8
DEFM “NO WAIT” + 03H
Wait States
“SMODE”
5ED0
DEFM “MODE” + 0DH
 
“S5”
5ED6
DEFM “5” + 03H
Word Length
“S6”
5ED8
DEFM “6” + 03H
Word Length
“S7”
SEDA
DEFM “7” + 03H
Word Length
“S8”
5EDC
DEFM “8” + 03H
Word Length
“S50”
5EDE
DEFM “50” + 03H
Baud Rate Table
“S75”
5EE1
DEFM “75” + 03H
Baud Rate Table
“S110”
5EE4
DEFM “110” + 03H
Baud Rate Table
“S134”
5EE8
DEFM “134.5” + 03H
Baud Rate Table
“S150”
SEEE
DEFM “150” + 03H
Baud Rate Table
“S300”
5EF2
DEFM “300” + 03H
Baud Rate Table
“S600”
5EF6
DEFM “600” + 03H
Baud Rate Table
“S1200”
SEFA
DEFM “1200” + 03H
Baud Rate Table
“S1800”
SEFF
DEFM “1800” + 03H
Baud Rate Table
“S2000”
5F04
DEFM “2000” + 03H
Baud Rate Table
“S2400”
5F09
DEFM “2400” + 03H
Baud Rate Table
“S3600”
SFOE
DEFM “3600” + 03H
Baud Rate Table
“S4800”
5Fl3
DEFM “4800” + 03H
Baud Rate Table
“S7200”
5Fl8
DEFM “7200” + 03H
Baud Rate Table
“S9600”
5FlD
DEFM “9600” + 03H
Baud Rate Table
“RSOFF”
5F22
DEFM “RS-232 IS NOW OFF” + 0DDH
Message.

5F34H – “DUAL” Routine – Output to BOTH the Printer and the Display

First, check to see if ROUTE is on.

“DUAL”
5F34
LD A,(442FH)
Fetch the DUAL status byte (held in memory location 442FH) and store it into Register A. 80H=ROUTE, FFH=DUAL, 00H=Neither.
5F37
CP 80H
Compare the value held in Register A against 80H. Results: If Register A equals 80H, the Z FLAG is set; otherwise the NZ FLAG is set.
5F39
JR Z,NODUAL
     [5F88H]
If A = 80H then ROUTE is active and the the Z FLAG (Zero) will have been set, JUMP to 5F88H.
5F3B
CALL CHKFLG
     [5081H]
Evaluate the DUAL parameter via a GOSUB to 5081H.
5F3E
JR Z,DUALOF
     [5F64H]
If the CALL returned with the Z FLAG set, the “OFF” parameter was provided; JUMP to 5F64H.

Next, check to see if DUAL is already on.

5F40
LD A,(442FH)
Fetch the DUAL status byte (held in memory location 442FH) and store it into Register A. 80H=ROUTE, FFH=DUAL, 00H=Neither.
5F43
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).
5F44
JR NZ,DUALON
      [5F5FH]
If the DUAL status was already on the NZ FLAG (Not Zero) will have been set, just display the DUAL ON message again via a JUMP to 5F5FH.

If we’re here, then we actually need to process the DUAL command.

5F46
DEC A
DECrement the value stored in Register A by 1 to go from the 00H to FFH.
5F47
LD (442FH),A
Store the FFH (DUAL mode ON) (held in Register A into memory location 442FH.
5F4A
LD HL,(401EH)
Fetch the video driver address (held in memory location 401EH) and store it into Register Pair HL.
5F4D
LD (4CE7H),HL
Store the video driver address (held in Register Pair HL) into the system memory location for DUAL’s video driver (i.e., 4CE7H).
5F50
LD HL,(4026H)
Fetch the printer driver address (held in memory location 4026H) and store it into Register Pair HL.
5F53
LD (4CF8H),HL
Store the printer driver address (held in Register Pair HL) into the system memory location for DUAL’s printer driver (i.e., 4CF8H).
5F56
LD HL,4CE1H
Let Register Pair HL equal 4CE1H, which is the code for the DUAL routine.
5F59
LD (401EH),HL
Store 4CE1H (held in Register Pair HL) into the DUAL routine’s video driver address (held at memory location 401EH).
5F5C
LD (4026H),HL
Store 4CE1H (held in Register Pair HL) into the DUAL routine’s printer driver address (held at memory location 4026H).
“DUALON”
5F5F
LD HL,5FD2H
Let Register Pair HL equal 5FD2H, to point to the message “ON”.
5F62
JR DULPRT
   [5F7DH]
JUMP to 5F7DH.

5F64H – “DUAL” Routine – Restore

“DUALOF”
5F64
LD A,(442FH)
Fetch the DUAL status byte (held in memory location 442FH) and store it into Register A. 80H=ROUTE, FFH=DUAL, 00H=Neither.
5F67
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).
5F68
JR Z,DUALO1
     [5F7AH]
If DUAL was already off (i.e., A was already 00), then there is nothing to process, so just display the DUAL OFF message via a JUMP to 5F7AH.

If we are here, then we need to process a DUAL OFF command.

5F6A
LD HL,(4CE7H)
Copy the video driver address (held in memory location 4CE7H for safe keeping) in Register Pair HL.
5F6D
LD (401EH),HL
Store the backed-up video driver address (held in HL) and into the video driver address (held in memory location 401EH).
5F70
LD HL,(4CF8H)
Copy the printer driver address (held in memory location 4CF8H for safe keeping) in Register Pair HL.
5F73
LD (4026H),HL
Store the backed-up printer driver address (held in HL) and into the printer driver address (held in memory location 4026H).
5F76
XOR A
Set Register A to ZERO and clear all Flags.
5F77
LD (442FH),A
Set the DUAL status byte (held in memory location 442FH) and to 00H. 80H=ROUTE, FFH=DUAL, 00H=Neither.
“DUALO1”
5F7A
LD HL,5FD5H
Let Register Pair HL equal 5FD5H, to point to the message “OFF”.
“DULPRT”
5F7D
PUSH HL
Save the contents of Register Pair HL to the top of the stack.
5F7E
LD HL,DULMSG
Let Register Pair HL equal 5FC5H, to point to the message “DUAL IS NOW “.
5F81
CALL 021BH
     [021BH]
GOSUB to 021BH.
NOTE: 021BH is the Model III ROM routine to display the character at (HL) until a 03H is found.
5F84
POP HL
Put the value held at the top of the STACK into Register Pair HL, and then remove the entry from the stack.
5F85
JP 021BH
   [021BH]
JUMP to 021BH.
NOTE: 021BH is the Model III ROM routine to display the character at (HL) until a 03H is found. Since this was JUMPED to instead of CALLed, the RET at the end of this ROM routine will then RETurn to the caller of this subroutine instead of returning to this place.

5F88H – “DUAL” Routine – Abort if DUAL is engaged while ROUTE is engaged.

“NODUAL”
5F88
LD HL,NODMSG
Let Register Pair HL equal 5F95H, to point to the message “CAN’T ACTIVATE DUAL WHILE ROUTE IS IN OPERATION“.
5F8B
JP 021BH
   [021BH]
JUMP to 021BH.
NOTE: 021BH is the Model III ROM routine to display the character at (HL) until a 03H is found. Since this was JUMPED to instead of CALLed, the RET at the end of this ROM routine will then RETurn to the caller of this subroutine instead of returning to this place.

5F8EH – Get the next COMMAND LINE character.

“SKIPSP”
5F8E
LD A,(HL)
Fetch the value held in the memory location pointed to by Register Pair HL and store it into Register A.
5F8F
CP 20H
Compare the value held in Register A against 20H (0010 0000) / (Decimal: 32)(ASCII: SPACE).
5F91
RET NZ
If the NZ FLAG (Not Zero) has been set, RETurn to the caller.
“SKIPS1”
5F92
INC HL
INCrement the value stored in Register Pair HL by 1.
5F93
JR SKIPSP
   [5F8EH]
Loop back to the top of this routine.

5F95H – MESSAGE and BYTE STORAGE for DUAL.

“NODMSG”
5F95
DEFM →
CAN’T ACTIVATE DUAL WHILE ROUTE IS IN OPERATION“.
“DULMSG”
5FC5
DEFM →
‘DUAL IS NOW’ + 03H“.
“ON”
5FD2
DEFM →
‘ON’ + 0DH“.
“OFF”
5FD5
DEFM →
‘OFF’ + 0DH“.

5FD9H – “WP” Routine – Set a drive as write protected.

“WPROT”
5FD9
CALL SKIPSP
     [5F8EH]
Get the next non-space COMMAND LINE character via a GOSUB to 5F8EH.
5FDC
CP 0DH
Compare the value held in Register A against 0DH (ASCII: CARRIAGE RETURN). Results: If Register A equals CARRIAGE RETURN, the Z FLAG is set; otherwise the NZ FLAG is set.
5FDE
JR NZ,WPROT1
      [5FE4H]
If there were parameters on the COMMAND LINE (which would be a drive number) the NZ FLAG (Not Zero) will have been set, so skip over the next 2 instructions which set the value if no disk drive is given.
5FE0
LD A,0FFH
Let Register A equal 0FFH.
5FE2
JR WPROT3
   [600CH]
JUMP to 600CH to set the drive number held in Register A into the middle of an opcode in SYS00/SYS which checks for write protect against FFH before permitting a write.

5FE4H – “WP” Routine – Jumped here if there were parameters given.

“WPROT1”
5FE4
LD DE,WPSW
Let Register Pair DE equal 6010H to point to the COMMAND PARSER TABLE for the WP COMMAND.
5FE7
CALL 4454H
     [4454H]
GOSUB to 4454H.
NOTE: 4454H is the DOS PARAMETER STRING PARSE routine. It decodes DOS LIBRARY parameters.
5FEA
JP NZ,ERR2
      [5219H]
If the NZ FLAG (Not Zero) has been set, then the CALL produced an error, so JUMP to 5219H to report an ILLEGAL COMMAND PARAMETER error, and ABORT.
5FED
LD BC,(WPDRV)
Let Register Pair BC equal the drive number (which was put into 5FEE-5FEFH elsewhere in the overlay).
5FF0
LD A,(4413H)
Fetch the maximum number of drives in the system (held in memory location 4413H) and store it into Register A.
5FF3
CP C
Compare the drive number given (held in Register C) against the highest drive number on the system (held in Register A). Results:
  • If Register A equals the value held in Register C, the Z FLAG is set.
  • If A < C, the CARRY FLAG will be set.
  • if A >= C, the NO CARRY FLAG will be set.
5FF4
JP C,ERR9
     [5221H]
If the requested drive number (in C) is equal to or higher than the highest drive number (in A) the C FLAG (Carry) will have been set, JUMP to 5221H with an error.
5FF7
LD A,C
Copy the requested drive number from Register C into Register A.
5FF8
ADD A,30H
LET Register A = Register A + 30H. Note: Adding 30H to from Register A will convert decimal number 0-9 into its ASCII equivalent (i.e., 6 + 30H = 36H, which, in ASCII, is 6.
5FFA
LD (WPDR),A
Store the value held in Register A into memory location 6024H which is in the middle of the “DISK DRIVE _ IS NOW” message.
5FFD
PUSH BC
Save the drive number (held in Register Pair BC) to the top of the stack.
5FFE
LD HL,WPDMSG
Let Register Pair HL equal 6019H, which is the message “DISK DRIVE _ IS NOW” + 03H.
6001
CALL 021BH
     [021BH]
GOSUB to 021BH.
NOTE: 021BH is the Model III ROM routine to display the character at (HL) until a 03H is found.
6004
LD HL,FINMSG
Let Register Pair HL equal 602EH, which is the message “WRITE PROTECTED”.
6007
CALL 021BH
     [021BH]
GOSUB to 021BH.
NOTE: 021BH is the Model III ROM routine to display the character at (HL) until a 03H is found.
600A
POP BC
Restore the drive number from the top of the STACK into Register Pair BC, and then remove the entry from the stack.
600B
LD A,C
Copy the drive number from Register C into Register A.
“WPROT3”
600C
LD (45F8H),A
Store the value held in Register A into memory location 45F8H which in the middle of an opcode in the SYS00/SYS routine which checks for write protect before doing a write.
600F
RET
RETurn to the caller.

6010H – PARSER TABLE for WP COMMAND.

“WPSW”
6010
DEFM “DRIVE “
 
6016
DEFW EEH 5FH
This is the memory address in the middle of a LD BC,(____) OPCODE where the disk drive number is stored
6018
DEFB 00H
End of Table Delimiter.
“WPDMSG”
6019
DEFM →
‘DISK DRIVE 0 IS NOW ‘ + 03H“. Note that the “0” is “WPDR”
“FINMSG”
602E
DEFM →
‘WRITE PROTECTED ‘“.

603EH – “MASTER” Routine. This routine re-assigns the master drive number.

“MASTER”
603E
CALL SKIPSP
     [5F8EH]
Get the next non-space COMMAND LINE character via a GOSUB to 5F8EH.
6041
CP 0DH
Compare the value held in Register A against 0DH (ASCII: CARRIAGE RETURN). Results: If Register A equals CARRIAGE RETURN then we got the command but no parameters (i.e., just typed in MASTER), the Z FLAG is set; otherwise the NZ FLAG is set.
6043
JR NZ,6048H
      [6048H]
If parameters (which would be a drive number) were given, then the NZ FLAG (Not Zero) will have been set, so skip over the next 2 instructions which put in a default drive number.
6045
XOR A
Set Register A to ZERO and clear all Flags, thus setting Register A to a default of DRIVE 0.
6046
JR 6071H
   [6071H]
JUMP to 6071H to put a 0 into the system storage location of the MASTER DRIVE NUMBER.

6048H – “MASTER” Routine – Jumped here if there were parameters given.

“MAST1”
6048
LD DE,WPSW
Let Register Pair DE equal 6010H which is the parser table for the WP command, focusing on the drive number.
604B
CALL 4454H
     [4454H]
GOSUB to 4454H.
NOTE: 4454H is the DOS PARAMETER STRING PARSE routine. It decodes DOS LIBRARY parameters.
604E
JP NZ,ERR2
      [5219H]
If the NZ FLAG (Not Zero) has been set, then the CALL produced an error, so JUMP to 5219H to report an ILLEGAL COMMAND PARAMETER error, and ABORT.
6051
LD BC,(WPDRV)
Fetch the drive number (held in memory location 5FEEH) and store it into Register Pair BC.
6055
LD A,(4413H)
Fetch the maximum number of drives in the system (held in memory location 4413H) and store it into Register A.
6058
CP C
Compare the drive number given (held in Register C) against the highest drive number on the system (held in Register A). Results:
  • If Register A equals the value held in Register C, the Z FLAG is set.
  • If A < C, the CARRY FLAG will be set.
  • if A >= C, the NO CARRY FLAG will be set.
6059
JP C,5221H
     [5221H]
If the requested drive number (in C) is equal to or higher than the highest drive number (in A) the C FLAG (Carry) will have been set, JUMP to 5221H with an error.
605C
LD A,C
Copy the requested drive number from Register C into Register A.
605D
ADD A,30H
LET Register A = Register A + 30H. Note: Adding 30H to from Register A will convert decimal number 0-9 into its ASCII equivalent (i.e., 6 + 30H = 36H, which, in ASCII, is 6.
605F
LD (WPDR),A
Store the value held in Register A into memory location 6024H which is in the middle of the “DISK DRIVE _ IS NOW” message.
6062
PUSH BC
Save the drive number (held in Register Pair BC) to the top of the stack.
6063
LD HL,WPDMSG
Let Register Pair HL equal 6019H, which is the message “DISK DRIVE _ IS NOW” + 03H.
6066
CALL 021BH
     [021BH]
GOSUB to 021BH.
NOTE: 021BH is the Model III ROM routine to display the character at (HL) until a 03H is found.
6069
LD HL,MSTMSG
Let Register Pair HL equal 6075H, which is the pointer to the message “THE MASTER DRIVE”.
606C
CALL 021BH
     [021BH]
GOSUB to 021BH.
NOTE: 021BH is the Model III ROM routine to display the character at (HL) until a 03H is found.
606F
POP BC
Restore the drive number from the top of the STACK into Register Pair BC, and then remove the entry from the stack.
6070
LD A,C
Copy the drive number from Register C into Register A.
“MAST2”
6071
LD (42B3H),A
Store the disk drive (held in Register A) into memory location 42B3H which is the storage location for the MASTER DRIVE NUMBER.
6074
RET
RETurn to the caller.

6075H – MESSAGE and BYTE STORAGE for MASTER.

“MSTMSG”
6075
DEFM →
‘THE MASTER DRIVE’ + 0DH“.

6086H – Convert Binary Coded Decimal into a Binary Value. On Entry HL = a hex value and On Exit HL = the decimal value.

“CONVHX”
6086
EX DE,HL
EXchange the value stored in Register Pair HL (the number to convert) with the value stored in Register Pair DE (irrelevant).
6087
LD A,D
Copy the MSB of the number to convert (held in Register D) into Register A.
6088
CALL SHIFT
     [60B5H]
Rotate Register A left 4 times to the HIGH NYBBLE via a GOSUB to 60B5H.
608B
608C
LD L,A
LD H,00H
Let Register Pair HL = the high nybble of the MSB of the requested value (held in Register A).
608E
608F
PUSH HL
POP BC
Let BC = the high nybble of the MSB of the requested value (held in Register Pair HL).
“”
6090
CALL ADDHL
     [60B0H]
Multiply the high nybble of the MSB by 10 via a GOSUB to 60B0H.

Now the high nybble of the MSB has been shifted over to the 10’s spot, so that the low nybble of the MSB can occupy the 1’s spot.

6093
LD A,0FH
Let Register A equal a mask of 0FH (0000 1111).
6095
AND D
MASK the value of Register A against the MSB of the number to convert (held in Register D) to isolate the low nybble.
6096
LD C,A
Let Register C = the low nybble of the MSB of the requested value (held in Register A).
6097
ADD HL,BC
LET Register Pair HL = 10 * the High Nybble of the MSB + the Low Nybble of the MSB.
6098
6099
PUSH HL
POP BC
LET Register Pair BC = 10 * the High Nybble of the MSB + the Low Nybble of the MSB.
609A
CALL ADDHL
     [60B0H]
Multiply that by 10 via a GOSUB to 60B0H (results in HL).

Now the converted MSB has been shifted over to the 10’s spot, so that the LSB can occupy the 1’s spot.

609D
LD A,E
Copy the LSB of the number to convert (held in Register D) into Register A.
609E
CALL SHIFT
     [60B5H]
Rotate Register A left 4 times to the LOW NYBBLE via a GOSUB to 60B5H.
60A1
60A2
LD C,A
LD B,00H
Let BC = the high nybble of the LSB of the requested value (held in Register Pair HL).
60A4
ADD HL,BC
LET Register Pair HL = the prior total (held in Register Pair HL) + the high nybble of the LSB (held in Register BC).
60A5
60A6
PUSH HL
PUSH HL
POP BC
LET Register Pair BC = 10 * that total.

Now the high nybble of the LSB has been added to the converted MSB.

60A7
CALL ADDHL
     [60B0H]
Multiply that by 10 via a GOSUB to 60B0H (results in HL).

Now everything has been pushed over one level, leaving just the 1’s spot empty.

60AA
LD A,0FH
Let Register A equal a mask of 0FH (0000 1111).
60AC
AND E
MASK the value of Register A against the LSB of the number to convert (held in Register E) to isolate the low nybble of the LSB.
60AD
LD C,A
Let Register Pair BC = the low nybble of the LSB of the value to convert.
60AE
ADD HL,BC
LET Register Pair HL = Register Pair HL + Register BC.
60AF
RET
RETurn to the caller.

60B0H – Routine to Multiply HL by 10. Requires HL = BC.

“ADDHL”
60B0
ADD HL,HL
LET Register Pair HL = Register Pair HL + Register HL.
60B1
ADD HL,HL
LET Register Pair HL = Register Pair HL + Register HL.
60B2
ADD HL,BC
LET Register Pair HL = Register Pair HL + Register BC.
60B3
ADD HL,HL
LET Register Pair HL = Register Pair HL + Register HL.
60B4
RET
RETurn to the caller.

60B5H – Get the high nybble.

“SHIFT”
60B5
60B7
60B9
60BB
SRL A
SRL A
SRL A
SRL A
60BD
RET
RETurn to the caller.
 
END 5200H

MISC – STORAGE BYTES.

S9DCB
6130
DEFS 50
Storage of 50 bytes, which is the length of a disk DCB
S9DCB1
6162
DEFS 50
Storage of 50 bytes, which is the length of a disk DCB
S9DCB2
6194
DEFS 50
Storage of 50 bytes, which is the length of a disk DCB
BUFER1
6300
DEFS 256
Storage of 256 bytes
BUFER2
6400
DEFS 256
Storage of 256 bytes