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

 
ORG 4E00H
4E00
AND 0F0H
MASK the value of Register A against 0F0H (1111 0000). This has the effect of turning off bits 3, 2, 1, and 0, leaving only bits 7, 6, 5, 4 active.
4E02
CP 90H
Compare the value held in Register A against 90H (1001 0000). Results: If Register A equals 90H, the Z FLAG is set; otherwise the NZ FLAG is set.
4E04
If the Z FLAG (Zero) is set then we are at DOS READY, so JUMP to 4E2EH.
4E07
CP 0A0H
Compare the value held in Register A against 0A0H (1010 0000). Results: If Register A equals 0A0H, the Z FLAG is set; otherwise the NZ FLAG is set.
4E09
If the Z FLAG (Zero) is set then we entered SYS01/SYS with a DOS ERROR so JUMP to 4E25H to display OPERATION ABORTED and then re-enter DOS.
4E0C
CP 0B0H
Compare the value held in Register A against 0B0H (1011 0000). Results: If Register A equals 0B0H, the Z FLAG is set; otherwise the NZ FLAG is set.
4E0E
If the Z FLAG (Zero) is set then we entered SYS01/SYS witha under COMDOS so JUMP to 4EC0H.
4E11
CP 0C0H
Compare the value held in Register A against 0C0H (1100 0000). Results: If Register A equals 0C0H, the Z FLAG is set; otherwise the NZ FLAG is set.
4E13
If the Z FLAG (Zero) is set then we entered SYS01/SYS with a SYNTAX CHECK CALL so JUMP to 4EE7H.
4E16
CP 0D0H
Compare the value held in Register A against 0D0H (1101 0000). Results: If Register A equals 0D0H, the Z FLAG is set; otherwise the NZ FLAG is set.
4E18
If the Z FLAG (Zero) is set then we entered SYS01/SYS with a PUTEXT CALL (i.e., assign a default extension to a filespec) so JUMP to 4F34H.
4E1B
CP 0E0H
Compare the value held in Register A against 0E0H (1110 0000). Results: If Register A equals 0E0H, the Z FLAG is set; otherwise the NZ FLAG is set.
4E1D
If the Z FLAG (Zero) is set then we entered SYS01/SYS with a PARSER CALL (i.e., evaluate a parameter string) so JUMP to 4FDBH.
4E20
CP 0F0H
Compare the value held in Register A against 0F0H (1111 0000). Results: If Register A equals 0F0H, the Z FLAG is set; otherwise the NZ FLAG is set.
4E22
If the Z FLAG (Zero) is set then we entered SYS01/SYS with a CMDDOS CALL so JUMP to 4EC4H.

4E25H – DOS Re-Entry for Non-DOS Errors. None of those parameters were passed.

4E25
LD SP,409FH
Set the STACK POINTER to 409FH.
4E28
LD HL,50A9H
LET Register Pair HL = 50A9H, which is the memory location of the OPERATION ABORTED error message.
4E2B
GOSUB to 021BH.
NOTE: 021BH will display the character at (HL) until a 03H is found.

4E2EH – DOS Re-Entry.

4E2E
EI
Enable Interrupts.
4E2F
LD SP,409FH
Set the STACK POINTER to 409FH.

Clear the command buffer via LDIR for 3F bytes (63 bytes).

4E32
LD HL,4225H
LET Register Pair HL = 4225H.
4E35
LD DE,4226H
LET Register Pair DE = 4226H.
4E38
LD BC,003FH
LET Register Pair BC = 003FH.
4E3B
LD (HL),00H
Store the value held in Register 00H into the memory location pointed to by Register Pair HL.
4E3D
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.
4E3F
LD HL,4030H
LET Register Pair HL = 4030H, as the routine in memory to run when the BREAK key is hit
4E42
LD (4204H),HL
Store the 4030H location (held in Register HL) into the memory location 4204H.
NOTE: 4203H-4205H is the three byte BREAK key vector used when BREAK is pressed. It is defaulted to JP 022EH, but this changes it to JP 4030H.
4E45
LD A,0C3H
LET Register A = 0C3H, which is the OPCODE for JP nn so as to handle bad request codes
4E47
LD (42AEH),A
Store the value held in Register A into the memory location 42AEH.
NOTE: 42AEH is in the overlay parsing area of RAM put there by SYS00/SYS, and specifically is for bad overlay requests.
4E4A
LD HL,509BH
LET Register Pair HL = 509BH, which is the memory location of the DOS READY error message.
4E4D
LD A,(4020H)
Fetch the value stored at memory location 4020H and put it into Register A.
NOTE: 4020H is the storage location for the CURSOR POSITION ON SCREEN (LSB, MSB order).
4E50
AND 3FH
Prepare to test to see if we are at the start of a new print line by first MASKing the value of Register A against 3FH (0011 1111). This has the effect of turning off bits 7, 6, leaving only bits 5, 4, 3, 2, 1, 0 active.
4E52
If the NZ FLAG (Not Zero) is set then we are NOT at a the beginning of a new print line, so skip the next instruction and JUMP to 4E55H.
4E54
INC HL
Bump the value stored in Register Pair HL by 1. This will skip the initial NEW LINE character in the message.
4E55
GOSUB to 021BH.
NOTE: 021BH will display the character at (HL) until a 03H is found.
4E58
LD A,(42B4H)
Fetch the value stored at memory location 42B4H (the program protected status byte) and put it into Register A.
4E5B
CP 55H
Compare the value held in Register A against 55H to see if the program was protected. Results: If Register A equals 55H, the Z FLAG is set; otherwise the NZ FLAG is set.
4E5D
If the NZ FLAG (Not Zero) is set, then the program was NOT protected, so JUMP to 4E75H.
4E5F
LD HL,(4411H)
Fetch the value stored at memory location 4411H and put it into Register HL.
NOTE: 4411H is the storage location for the MEMORY PROTECT address.
4E62
LD DE,5200H
LET Register Pair DE = 5200H, which is the start of free memory.
4E65
OR A
Clear the CARRY BIT.
4E66
SBC HL,DE
Determine the size of free memory by subtracting the value stored in Register Pair DE (Free Memory) and the carry flag from the value stored in Register Pair HL (Protected Memory).
4E68
DEC HL
DECrement the value stored in Register Pair HL by 1 to drop the amount of free memory by one byte.
4E69
4E6A
LD B,H
LD C,L
LET Register Pair BC = Register Pair HC.

4E6BH-4E73H – Clear free memory via LDIR.

4E6B
LD HL,5200H
LET Register Pair HL = 5200H.
4E6E
LD DE,5201H
LET Register Pair DE = 5201H.
4E71
LD (HL),00H
Store the value held in Register 00H into the memory location pointed to by Register Pair HL.
4E73
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.

4E75H-4E7CH – Display the 63 periods which represent the DOS command line.

4E75
LD B,3EH
LET Register B = 3EH (Decimal: 62).
4E77
LD A,2EH
LET Register A = 2EH (ASCII “.“).
4E79
GOSUB to 0033H.
NOTE: 0033H is the character print routine, to put the character held in Register A at the current cursor position.
4E7C
DJNZ 4E77H
LOOP back to 4E77H until Register B is ZERO.
4E7E
LD A,1DH
LET Register A = 1DH (Decimal: 29), for a “move to the start of the line” character.
4E80
GOSUB to 0033H.
NOTE: 0033H is the character print routine, to put the character held in Register A at the current cursor position.
4E83
XOR A
Set Register A to ZERO and clear all Flags.
4E84
LD (4214H),A
Store the value held in Register A into the memory location 4214H (the number of protected lines on the screen).
4E87
LD (42B4H),A
Store the value held in Register A into the memory location 42B4H (the program protect flag).
4E8A
LD (42FFH),A
Store the value held in Register A into the memory location 42FFH (the password skip flag).
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.
4E8D
DEC A
DECrement the value stored in Register A by 1.
4E8E
LD (427AH),A
Store the value held in Register A (which is a FFH) into the memory location 427AH (the EXECUTE FILE flag).

4E91H-4E9CH – Input up to 63 characters from the user into the command buffer.

4E91
LD HL,4225H
LET Register Pair HL = 4225H.
4E94
LD B,3FH
LET Register B = 3FH (Decimal: 63).
4E96
GOSUB to 0040H in the ROM.
NOTE: This routine gets a full line from the keyboard. The line is terminated by a carriage return or BREAK. Characters typed are echoed to the display. On entry, B must be the maximum length of line to be accepted and (HL) must be the storage buffer which should be set to B+1. On Exit, CARRY will be set if the BREAK key was hit, Register B will contain the number of characters entered, and (HL) will contain the line from the keyboard followed by the terminating character. Register paid DE is altered in this routine.
4E99
LD A,B
LET Register A = Register B.
4E9A
OR A
Since a LD command does not set any FLAGS, Set FLAGS based on the contents of Register A.
4E9B
If the Z FLAG (Zero) is set then there were no characters entered so JUMP back to 4E4AH.
4E9D
PUSH HL
Save Register HL to the top of the stack.
4E9E
PUSH BC
Save Register BC to the top of the stack.
4E9F
LD HL,(4020H)
Fetch the value stored at memory location 4020H and put it into Register HL.
NOTE: 4020H is the storage location for the CURSOR POSITION ON SCREEN.
4EA2
PUSH HL
Save Register HL (the cursor position) to the top of the stack.
4EA3
LD C,B
Set Register Pair BC to be the number of characters read it by first letting Register C = Register B.
4EA4
LD B,00H
and then letting Register B = 00H (0000 0000).
4EA6
ADD HL,BC
ADD the value held in Register Pair BC to Register Pair HL. The results are held in Register Pair HL.
4EA7
LD BC,0040H
LET Register Pair BC = 0040H (0000 0000 0100 0000).
4EAA
OR A
Set FLAGS based on the contents of Register A.
4EAB
SBC HL,BC
Subtracts the value stored in Register Pair BC and the carry flag from the value stored in Register Pair HL (End of Input).
4EAD
LD (4020H),HL
Store the value held in Register HL into the memory location 4020H.
NOTE: 4020H is the storage location for the CURSOR POSITION ON SCREEN.
4EB0
LD A,1EH
LET Register A = 1EH (Decimal: 30) to clear the rest of the line from the periods.
4EB2
GOSUB to 0033H.
NOTE: 0033H is the character print routine, to put the character held in Register A at the current cursor position.
4EB5
POP HL
Restore the cursor position. First, restore Register Pair HL from the top of the STACK.
4EB6
LD (4020H),HL
Store the value held in Register HL into the memory location 4020H.
NOTE: 4020H is the storage location for the CURSOR POSITION ON SCREEN.
4EB9
POP BC
Restore Register Pair BC from the top of the STACK.
4EBA
POP HL
Restore Register Pair HL from the top of the STACK.
4EBB
LD A,0C9H
Reset the bad request routine by first letting Register A = 0C9H.
4EBD
LD (42AEH),A
and then storing the value held in Register A into the memory location 42AEH.

4EC0H – MAIN ROUTINE “COMDOS” – Give DOS command and exit when done.

4EC0
LD BC,402DH
LET Register Pair BC = 402DH. Prepare to return to DOS entry.
4EC3
PUSH BC
Save Register BC to the top of the stack.

4EC4H – MAIN ROUTINE CMDDOS – Give DOS command and return to user.

4EC4
LD DE,4465H
LET Register Pair DE = 4465H to point to the DCB.
4EC7
GOSUB to 4EE7H to check the filespec on the input command for validity.
4ECA
If the NZ FLAG (Not Zero) is set, then that routine passed an error, so JUMP to 4EE2H.
4ECC
PUSH HL
Save Register HL (the pointer for the parameters) to the top of the stack.
4ECD
LD BC,50C9H
LET Register Pair BC = 50C9H (the pointer to the command table).
4ED0
GOSUB to 4F93H to find out which command was entered, if any.
4ED3
If the Z FLAG (Zero) is set then a command was found, so JUMP to 4EDFH to run it.
4ED5
LD HL,5098H
LET Register Pair HL = 5098H to point to the default extension of “CMD”.
4ED8
GOSUB to 4F34H, which assigns an extension, to add the “CMD” to the command.
4EDB
POP HL
Restore Register Pair HL (the pointer to the parameters) from the top of the STACK.
4EDC
JUMP to 4433H.
NOTE: 4433H is the DOS PROGRAM EXECUTOR routine. A LOAD is performed and then jumped to. Only Register Pair HL survives.

4EDFH – If a valid command was found …

4EDF
POP HL
Restore Register Pair HL (the pointer to the parameters) from the top of the STACK.
4EE0
PUSH DE
Save Register DE (the execution address) to the top of the stack.
4EE1
RET
RETurn to the caller.

4EE2H – Handle an error of an INVALID FILENAME.

4EE2
LD A,13H
LET Register A = 13H to set up for an INVALID FILENAME.
4EE4
JUMP to 4409H to process the DOS error.

4EE7H – SYNTAX – Check the Filespec for Validity.

4EE7H-4F15H – Get the filename, extension, password, and drive number and put them into the buffer pointed to by DE. Error out if the delimeter is present but the related item isn’t.

4EE7
PUSH DE
Save Register DE (the pointer to the DCB) to the top of the stack.
4EE8
LD B,08H
LET Register B = 08H to get up to 8 characters (i.e., get the filename).
4EEA
GOSUB to 4F68H to get the number of characters set out in Register B. HL is to point to the location from which the characters are being fetched.
4EED
If the NZ FLAG (Not Zero) is set then there was an error in that routine, meaning that the filename is bad (or missing), so JUMP to 4F29H (which simply restores the pointer to the DCB from the stack, and RETurns with the NZ FLAG).
4EEF
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.
4EF1
If the NZ FLAG (Not Zero) is set, then there is no extension so JUMP to 4EFCH.
4EF3
LD (DE),A
Store the value held in Register A (ASCII: /) into the memory location pointed to by Register Pair DE.
4EF4
INC DE
Bump the value stored in Register Pair DE by 1 to point to the space after the newly added /.
4EF5
LD B,03H
LET Register B = 03H to get up to 3 characters (i.e., get the extension).
4EF7
GOSUB to 4F68H to get the number of characters set out in Register B.
4EFA
If the NZ FLAG (Not Zero) is set then the extension was missing, so JUMP to 4F29H (which simply restores the pointer to the DCB from the stack, and RETurns with the NZ FLAG).
4EFC
CP 2EH
Compare the value held in Register A against 2EH (ASCII: .). Results: If Register A equals “.“, the Z FLAG is set; otherwise the NZ FLAG is set.
4EFE
If the NZ FLAG (Not Zero) is set, then there is no password so JUMP to 4F09H.
4F00
LD (DE),A
Store the value held in Register A (i.e., a .) into the memory location pointed to by Register Pair DE.
4F01
INC DE
Bump the value stored in Register Pair DE by 1 to point to the space after the newly added ..
4F02
LD B,08H
LET Register B = 08H to get up to 8 characters (i.e., get the password).
4F04
GOSUB to 4F68H to get the number of characters set out in Register B.
4F07
If the NZ FLAG (Not Zero) is set then the password was missing, so JUMP to 4F29H (which simply restores the pointer to the DCB from the stack, and RETurns with the NZ FLAG).
4F09
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.
4F0B
If the NZ FLAG (Not Zero) is set then there is no drive number so JUMP to 4F16H.
4F0D
LD (DE),A
Store the value held in Register A (ASCII: :) into the memory location pointed to by Register Pair DE.
4F0E
INC DE
Bump the value stored in Register Pair DE by 1 to point to the space after the newly added :.
4F0F
LD B,01H
LET Register B = 01H to get 1 characters (i.e., get the drive number).
4F11
GOSUB to 4F68H to get the number of characters set out in Register B.
4F14
If the NZ FLAG (Not Zero) is set then the drive number is missing, so JUMP to 4F29H (which simply restores the pointer to the DCB from the stack, and RETurns with the NZ FLAG).

4F16H – At this point, we have a syntactically valid filename, so we need to add a 03H terminator, reset BC to point to the first character of the DCB buffer for the filename.

4F16
LD C,A
LET Register C = Register A (the terminator character).
4F17
LD A,03H
LET Register A = 03H, which is the END OF FILESPEC delimeter.
4F19
LD (DE),A
Store the value held in Register A (i.e., the END OF FILESPEC delimeter) into the memory location pointed to by Register Pair DE (which is the DCB buffer for the filename).
4F1A
XOR A
Set Register A to ZERO and clear all Flags (which really is clearing the error flags).
4F1B
LD A,C
LET Register A = Register C (the terminator character)a.
4F1C
POP DE
Restore Register Pair DE from the top of the STACK so that DE now points to the beginning of the DCB buffer for the filename.
4F1D
PUSH DE
Save Register DE to the top of the stack.
4F1E
LD BC,4F2BH
LET Register Pair BC = 4F2BH, which is the memory storage location for the TO delimeter.
4F21
GOSUB to 4F93H to see if the next word is TO.
4F24
POP DE
Restore Register Pair DE from the top of the STACK so that DE now points to the beginning of the DCB buffer for the filename.
4F25
If the Z FLAG (Zero) is set, then we got a TO and need a second filespec so JUMP to 4EE7H.
4F27
XOR A
Set Register A to ZERO and clear all Flags to signal no error.
4F28
RET
RETurn to the caller.

4F29H – This routine is jumped to if we had a delimeter (/, ., :) but not the corresponding entry. The NZ FLAG is already set on entry, and is maintained.

4F29
POP DE
Restore Register Pair DE from the top of the STACK.
4F2A
RET
RETurn to the caller.

4F2BH – MESSAGE STORAGE AREA

4F2B
Storage
“TO “ (i.e., TO and 4 spaces)
4F31
00 00
No Execute Address
4F33
00
End of Table

4F34H – MAIN ROUTINE “PUTEXT” – Assign Default Extension to Filespec. HL Points to the Extension, and DE Points to the DCB buffer for the filename

4F34
PUSH DE
Save Register DE to the top of the stack.
4F35
PUSH HL
Save Register HL to the top of the stack.
4F36
EX DE,HL
EXchange the value stored in Register Pair HL with the value stored in Register Pair DE.
4F37
INC HL
Bump the value stored in Register Pair HL (the DCB buffer for the filename) by 1.
4F38
LD B,09H
LET Register B = 09H to be the maximum number of characters to examine.

Top of a loop of UP TO 9 characters to check for delimeters.

4F3A
LD A,(HL)
Fetch the value stored at memory location pointed to by Register Pair HL (the DCB buffer for the filename) and put it into Register A.
4F3B
CP 2FH
Compare the value held in Register A against 2FH (ASCII: /). Results:
  • If Register A equals /, the Z FLAG is set.
  • If A < /, the CARRY FLAG will be set.
  • if A >= /, the NO CARRY FLAG will be set.
4F3D
If the Z FLAG (Zero) is set then the delimter is a /, so we need to add an extension, which means we just exit by JUMPing to 4F4CH.
4F3F
If the C FLAG (CARRY FLAG) is set then A < /, meaning it is a ., JUMP to 4F4FH.
4F41
CP 3AH
Compare the value held in Register A against 3AH (ASCII: :). Results:
  • If Register A equals :, the Z FLAG is set.
  • If A < /, the CARRY FLAG will be set.
  • if A >= :, the NO CARRY FLAG will be set.
4F43
If the C FLAG (CARRY FLAG) is set then A < :, meaning it is a number, JUMP to 4F49H.
4F45
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.
4F47
If the C FLAG (CARRY FLAG) is set then A < A, meaning it is a :, JUMP to 4F4FH.
4F49
INC HL
Bump the value stored in Register Pair HL (the DCB buffer for the filename) by 1.
4F4A
DJNZ 4F3AH
LOOP back to 4F3AH until Register B is ZERO.

Bottom of the loop of UP TO 9 characters to check for delimeters.

4F4C
POP HL
Restore Register Pair HL from the top of the STACK.
4F4D
POP DE
Restore Register Pair DE from the top of the STACK.
4F4E
RET
RETurn to the caller.

4F4FH – Handle a Password or a Drivespec.

4F4FH-4F5AH – Move the 16 bytes starting at byte 15 (first password byte) to 19 bytes after the filename, so as to make room.

4F4F
LD BC,000FH
LET Register Pair BC = 000FH, for a move of 15 characters in the LDDR instruction, below.
4F52
ADD HL,BC
ADD the value held in Register Pair BC to Register Pair HL. The results are held in Register Pair HL.
4F53
LD D,H
LET Register D = Register H.
4F54
LD E,L
LET Register E = Register L.
4F55
INC DE
Bump the value stored in Register Pair DE by 1.
4F56
INC DE
Bump the value stored in Register Pair DE by 1.
4F57
INC DE
Bump the value stored in Register Pair DE by 1.
4F58
INC DE
Bump the value stored in Register Pair DE by 1.
4F59
INC BC
Bump the value stored in Register Pair BC by 1.
4F5A
LDDR
Transfers a byte of data from the memory location pointed to by HL to the memory location pointed to by DE. Then HL, DE, and BC are decremented. If BC is not zero, this operation is repeated. Interrupts can trigger while this instruction is processing.
4F5C
POP HL
Restore Register Pair HL (which would be the pointer to the EXTENSION in the DCB for the filename) from the top of the STACK.
4F5D
4F5E
INC HL
INC HL
Bump the value stored in Register Pair HL by 1 twice, so it points to the end of the EXTENSION in the DCB for the filename.
4F5F
LD C,03H
LET Register C = 03H for a 3 byte move in the below LDDR.
4F61
LDDR
Transfers a byte of data from the memory location pointed to by HL to the memory location pointed to by DE. Then HL, DE, and BC are decremented. If BC is not zero, this operation is repeated. Interrupts can trigger while this instruction is processing.
4F63
LD A,2FH
LET Register A = 2FH (ASCII: /).
4F65
LD (DE),A
Store the value held in Register A (a /)) into the memory location pointed to by Register Pair DE.
4F66
POP DE
Restore Register Pair DE (the DCB pointer to the filename) from the top of the STACK.
4F67
RET
RETurn to the caller.

4F68H – Fetch B number of characters from the memory location pointed to by Register Pair HL.

4F68
LD A,B
LET Register A = Register B (the number of characters we want to fetch).
4F69
LD (4F8FH),A
Store the value held in Register A (the number of characters we want to fetch) into the memory location 4F8FH.
4F6C
INC B
Bump the value stored in Register B by 1 since we are going to do a countdown loop.
4F6D
LD A,(HL)
Fetch the value stored at memory location pointed to by Register Pair HL and put it into Register A.
4F6E
CP 03H
Compare the value held in Register A against 03H (which is a BREAK). Results: If Register A equals BREAK, the Z FLAG is set; otherwise the NZ FLAG is set.
4F70
If the Z FLAG (Zero) is set then the BREAK was hit, so JUMP to 4F8AH to exit the routine.
4F72
CP 0DH
Compare the value held in Register A against 0DH (which is a ENTER). Results: If Register A equals ENTER, the Z FLAG is set; otherwise the NZ FLAG is set.
4F74
If the Z FLAG (Zero) is set then the ENTER was hit, so JUMP to 4F8AH to exit the routine.
4F76
INC HL
Bump the value stored in Register Pair HL by 1 to point to the next character.
4F77
GOSUB to 50BBH to test the character for an alpha-numeric character. Routine returns C FLAG is there was an error.
4F7A
If the C FLAG (CARRY FLAG) is set, then that routine exited with an error, so JUMP to 4F8AH to exit the routine.
4F7C
DEC B
DECrement the value stored in Register B by 1 to tick off that character from the loop.
4F7D
If the Z FLAG (Zero) is set then we don’t need to process any more characters, so JUMP to 4F87H to increment B by one and RETurn.
4F7F
LD (DE),A
Store the value held in Register A (the validated filename character) into the memory location pointed to by Register Pair DE.
4F80
XOR A
Set Register A to ZERO and clear all Flags to signify NO ERROR.
4F81
LD (4F8FH),A
Store the value held in Register A into the memory location 4F8FH to signify that we have a good FILESPEC.
4F84
INC DE
Bump the value stored in Register Pair DE by 1 to move to the next byte.
4F85
LOOP BACK to 4F6DH.

4F87H – Jumped to from 4F7DH if the character parsing routine ran out of LOOP.

4F87
INC B
Bump the value stored in Register B by 1.
4F88
JUMP to 4F6DH.

4F8AH – Jumped to from the “Fetch B Characters from HL and Validate” routine of 4F68H if we have an early exit (i.e., BREAK, ENTER, or a BAD CHARACTER).

4F8A
LD C,A
LET Register C = Register A (the character that caused the jump to this routine).
4F8B
LD A,03H
LET Register A = 03H, which would be the end-of-filespec delimeter.
4F8D
LD (DE),A
Store the end-of-filespec delimeter held in Register A into the memory location pointed to by Register Pair DE (which is the end of the DCB for the filename).
4F8E
LD A,nn
LET Register A = the value ascribed to it in instructions 4FC9H (the number of characters we want to fetch) and 4F81H (a 0 to signify that we have a good FILESPEC).
4F90
OR A
Since a LD command does not set any FLAGS, Set FLAGS based on the contents of Register A so as to set NZ or Z.
4F91
LD A,C
LET Register A = Register C (the terminator).
4F92
RET
RETurn to the caller.

4F93H – SUBroutine to scan a command table for a given command. On entry, BC to point to the command table of interest, and this routine just compares the first letter.

4F93
PUSH HL
Save Register HL to the top of the stack.
4F94
4F95
LD H,B
LD L,C
LET Register HL = Register BC.
4F96
LD C,01H
LET Register C = 01H to indicate command number 1 (this will track the command number which is found)
4F98
LD A,(DE)
Fetch the value stored at memory location pointed to by Register Pair DE and put it into Register A.
4F99
CP (HL)
Compare the value held in Register A (i.e., the value stored at the memory location of DE) against the value held in the memory location (HL). Results: If Register A equals (HL), the Z FLAG is set; otherwise the NZ FLAG is set.
4F9A
If the Z FLAG (Zero) is set then the character at (HL) matched the character at (DE), so JUMP to 4FABH to test the next 5 characters and see if they match too.

If we are here, then the character pointed to by DE didn’t match the character pointed to by (HL), so we need to keep looking.

4F9C
PUSH BC
Save Register BC to the top of the stack.
4F9D
LD BC,0008H
LET Register Pair BC = 0008, which is the length of each command.
4FA0
ADD HL,BC
ADD the value held in Register Pair BC to Register Pair HL, to move 1 command down and have HL point to that next command. The results are held in Register Pair HL.
4FA1
POP BC
Restore Register Pair BC from the top of the STACK.
4FA2
INC C
Bump the value stored in Register C by 1 to point to the next command.
4FA3
LD A,(HL)
Fetch the value stored at memory location pointed to by Register Pair HL (the next command) and put it into Register A.
4FA4
OR A
Since a LD command does not set any FLAGS, Set FLAGS based on the contents of Register A.
4FA5
If the NZ FLAG (Not Zero) is set then we still have more commands to go, so LOOP back to 4F98H.
4FA7
POP HL
If we’re here then we have hit the end of the table, so restore Register Pair HL from the top of the STACK.
4FA8
OR 01H
OR Register A against 01H to set the flag for “NOT FOUND”. This has the effect of turning on bits 0.
4FAA
RET
RETurn to the caller.

4FABH – Routine inside the SUBroutine to scan a command table for a given command. If the first letter of the command we want matches the first letter of the current command in the table, then we go here to check the rest of the characters to see if they match too.

4FAB
LD B,05H
LET Register B = 05H to set up to test the next 5 characters.

Top of a DJNZ loop of 5 iterations.

4FAD
PUSH HL
Save Register HL to the top of the stack.
4FAE
PUSH DE
Save Register DE to the top of the stack.
4FAF
INC DE
Bump the value stored in Register Pair DE by 1 so as to point to the next character to test.
4FB0
INC HL
Bump the value stored in Register Pair HL by 1 so as to point to the next character to test.
4FB1
LD A,(DE)
Fetch the value stored at memory location pointed to by Register Pair DE and put it into Register A.
4FB2
CP 03H
Compare the value held in Register A against 03H to check for a BREAK. Results: If Register A equals 03H, the Z FLAG is set; otherwise the NZ FLAG is set.
4FB4
If the Z FLAG (Zero) is set, meaning we got a BREAK, JUMP to 4FD2H.
4FB6
CP 0DH
Compare the value held in Register A against 0DH to check for an ENTER. Results: If Register A equals 0DH, the Z FLAG is set; otherwise the NZ FLAG is set.
4FB8
If the Z FLAG (Zero) is set, meaning we got an ENTER, JUMP to 4FD2H.
4FBA
CP (HL)
Compare the value held in Register A (the value stored at the memory location pointed to by DE) against the value held in the memory location (HL). Results: If Register A equals (HL), the Z FLAG is set; otherwise the NZ FLAG is set.
4FBB
If the NZ FLAG (Not Zero) is set then we don’t have a match, so this isn’t the right command. With this, JUMP back 4FCDH.
4FBD
DJNZ 4FAFH
LOOP back to 4FAFH until Register B is ZERO.

End of the DJNZ loop of 5 iterations.

4FBF
POP DE
Restore Register Pair DE from the top of the STACK.
4FC0
LD A,C
LET Register A = Register C (which was the counter for the command number).
4FC1
POP BC
Restore Register Pair BC (the table address) from the top of the STACK.
4FC2
LD HL,0006H
LET Register Pair HL = 0006H to move forward 6 characters to skip the command and land on the address of that command.
4FC5
ADD HL,BC
ADD the value held in Register Pair BC to Register Pair HL. The results are held in Register Pair HL.
4FC6
LD C,A
LET Register C = Register A (which was the counter for the command number).
4FC7
LD E,(HL)
Fetch the value stored at memory location pointed to by Register Pair HL (which would be the LSB of that command) and put it into Register E.
4FC8
INC HL
Bump the value stored in Register Pair HL by 1.
4FC9
LD D,(HL)
Fetch the value stored at memory location pointed to by Register Pair HL (which would be the MSB of that command) and put it into Register D.
4FCA
POP HL
Restore Register Pair HL (the paramter address) from the top of the STACK.
4FCB
XOR A
Set Register A to ZERO and clear all Flags to indicate NO ERROR.
4FCC
RET
RETurn to the caller.

4FCDH – Routine inside the SUBroutine to scan a command table for a given command. If the first letter of the command we were looking for and the table entry matched, but when we checked the rest of the characters they didn’t, we wind up here.

4FCD
GOSUB to 50BBH to test the character for an alpha-numeric character.
4FD0
If the NC FLAG (No Carry) is set, then the character was fine, so skip the next few instructions and JUMP to 4FD7H.
4FD2
LD A,(HL)
Fetch the value stored at memory location pointed to by Register Pair HL and put it into Register A.
4FD3
CP 20H
Compare the value held in Register A against 20H (ASCII: SPACE). Results: If Register A equals 20H, the Z FLAG is set; otherwise the NZ FLAG is set.
4FD5
If the Z FLAG (Zero) is set, meaning there was a space and we should stop processing, then we have a match so JUMP to 4FBFH.
4FD7
POP DE
Restore Register Pair DE from the top of the STACK.
4FD8
POP HL
Restore Register Pair HL from the top of the STACK.
4FD9
JUMP to 4F9CH to check the next table entry.

4FDBH – MAIN ROUTINE “PARSER” – Evaluate a parameter string.

4FDB
LD A,(HL)
Fetch the value stored at memory location pointed to by Register Pair HL and put it into Register A.
4FDC
CP 0DH
Compare the value held in Register A against 0DH (i.e., an ENTER). Results:
  • If Register A equals 0DH, the Z FLAG is set.
  • If A < 0DH, the CARRY FLAG will be set.
  • if A >= 0DH, the NO CARRY FLAG will be set.
4FDE
RET Z
If the Z FLAG (Zero) is set, RETurn to the caller.
4FDF
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.
4FE1
If the Z FLAG (Zero) is set, meaning we hit a (, JUMP to 4FECH.
4FE3
CP 20H
Compare the value held in Register A against 20H (ASCII: SPACE). Results: If Register A equals (ASCII: SPACE), the Z FLAG is set; otherwise the NZ FLAG is set.
4FE5
If the Z FLAG (Zero) is set then we have a SPACE, which we will want to ignore, so JUMP to 4FE9H.
4FE7
OR A
Set FLAGS based on the contents of Register A to indicate an error.
4FE8
RET
RETurn to the caller.

4FE9H – Part of the PARSER routine. If we hit a SPACE during our parsing we wind up here to skip it.

4FE9
INC HL
Bump the value stored in Register Pair HL by 1 to pass over the SPACE.
4FEA
JUMP BACK to the top of the PARSER routine at 4FDBH.

4FECH – Part of the PARSER routine. If we hit a ( during our parsing we wind up here.

4FEC
PUSH DE
Save Register DE (the table address) to the top of the stack.
4FED
LD B,06H
LET Register B = 06H so as to process up to 6 characters when we call 4F68H
4FEF
LD DE,5090H
LET Register Pair DE = 5090H, which is a byte storage area of memory.
4FF2
INC HL
Bump the value stored in Register Pair HL by 1 to point to the character after the (.
4FF3
GOSUB to 4F68H to get the number of characters set out in Register B. HL is to point to the location from which the characters are being fetched.
4FF6
DEC HL
DECrement the value stored in Register Pair HL by 1 to back up 1 character.
4FF7
POP DE
Restore Register Pair DE (the table address) from the top of the STACK.
4FF8
RET NZ
If the NZ FLAG (Not Zero) is set, then the CALL to 4F68H resulted in an error, so RETurn to the caller.
4FF9
PUSH DE
Save Register DE (the table address) to the top of the stack.
4FFA
4FFB
LD B,D
LD B,D
LET Register Pair BC = Register Pair DE.
4FFC
LD DE,5090H
LET Register Pair DE = 5090H, which is a byte storage area of memory.
4FFF
GOSUB to 4F93H to scan the table pointed at by Register Pair DE for a specific command.
5002
If the Z FLAG (Zero) is set then we found a match, so JUMP to 5006H.
5004
POP DE
Restore Register Pair DE (the table address) from the top of the STACK.
5005
RET
RETurn to the caller with an error (as the NZ FLAG is set, or we would have jumped away).

5006H – Part of the PARSER routine when we first hit a ( and then have a match.

5006
LD A,(HL)
Fetch the value stored at memory location pointed to by Register Pair HL and put it into Register A.
5007
CP 3DH
Compare the value held in Register A against 3DH (ASCII: =). Results: If Register A equals =, the Z FLAG is set; otherwise the NZ FLAG is set.
5009
If the Z FLAG (Zero) is set then we have an =, so JUMP to 5027H.
500B
LD BC,0FFFFH
LET Register Pair BC = 0FFFFH (0000 1111 1111 1111 1111).
500E
LD A,C
LET Register A = Register C.
500F
LD (DE),A
Store the value held in Register A into the memory location pointed to by Register Pair DE.
5010
INC DE
Bump the value stored in Register Pair DE by 1.
5011
LD A,B
LET Register A = Register B.
5012
LD (DE),A
Store the value held in Register A into the memory location pointed to by Register Pair DE.
5013
POP DE
Restore Register Pair DE from the top of the STACK.
5014
LD A,(HL)
Fetch the value stored at memory location pointed to by Register Pair HL and put it into Register A.
5015
CP 2CH
Compare the value held in Register A against 2CH. Results: If Register A equals 2CH, the Z FLAG is set; otherwise the NZ FLAG is set.
5017
If the Z FLAG (Zero) is set, JUMP to 4FECH.
5019
CP 0DH
Compare the value held in Register A against 0DH. Results: If Register A equals 0DH, the Z FLAG is set; otherwise the NZ FLAG is set.
501B
If the Z FLAG (Zero) is set, JUMP to 5024H.
501D
CP 03H
Compare the value held in Register A against 03H. Results: If Register A equals 03H, the Z FLAG is set; otherwise the NZ FLAG is set.
501F
If the Z FLAG (Zero) is set, JUMP to 5024H.
5021
CP 29H
Compare the value held in Register A against 29H. Results:
  • If Register A equals 29H, the Z FLAG is set.
  • If A < 29H, the CARRY FLAG will be set.
  • if A >= 29H, the NO CARRY FLAG will be set.
5023
RET NZ
If the NZ FLAG (Not Zero) is set, RETurn to the caller.
5024
INC HL
Bump the value stored in Register Pair HL by 1.
5025
XOR A
Set Register A to ZERO and clear all Flags.
5026
RET
RETurn to the caller.

5027H – Part of the PARSER routine when we first hit a ( and then have an =.

5027
INC HL
Bump the value stored in Register Pair HL by 1 to advance past the =.
5028
LD A,(HL)
Fetch the value stored at memory location pointed to by Register Pair HL (the first character after the =) and put it into Register A.
5029
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 < 41H, the CARRY FLAG will be set.
  • if A >= 41H, the NO CARRY FLAG will be set.
502B
If the C FLAG (CARRY FLAG) is set then A < A, so JUMP to 5034H.
502D
GOSUB to 5063H to evaluate an ON/OFF Flag by looking for an O and then N or F and then a Right Parenthesis or a Comma.
5030
If the Z FLAG (Zero) is set, JUMP to 500EH.
5032
JUMP to 5004H.

5034H – Part of the PARSER routine when we first hit a (, then an =, and then the characers is less than an A.

5034
PUSH DE
Save Register DE to the top of the stack.
5035
PUSH IX
Save Register IX to the top of the stack.
5037
PUSH HL
Save Register HL to the top of the stack.
5038
POP IX
Restore Register Pair IX from the top of the STACK (which was HL; the position in the input text).
503A
LD HL,0000H
LET Register Pair HL = 0000H as it will be used to total some numbers.
503D
LD A,(IX+00H)
Fetch the value stored at memory location IX+00H and put it into Register A (i.e., the next character).
5040
GOSUB to 50BBH to test to see if it is a valid alpha-numeric character. Routine returns CARRY FLAG set if the characters is not between 0-9 and A-Z.
5043
If the C FLAG (CARRY FLAG) is set, meaning we have a bad character, JUMP to 5059H.
5045
SUB 30H
SUBtract the value 30H from Register A, to turn the ASCII character 0-9 into the number 0-9.
5047
CP 0AH
Compare the value held in Register A against 0AH (meaning a hex number). Results:
  • If Register A equals 0AH, the Z FLAG is set.
  • If A < 0AH, the CARRY FLAG will be set.
  • if A >= 0AH, the NO CARRY FLAG will be set.
5049
If the C FLAG (CARRY FLAG) is set, meaning the character is < 0AH (i.e., not hex), skip over the next instruction and JUMP to 504DH.
504B
SUB 07H
SUBtract the value 07H from Register A to convert the hex value.
504D
INC IX
Bump the value stored in Register Pair IX by 1 to point to the next character.
504F
5050
5051
5052
ADD HL,HL
ADD HL,HL
ADD HL,HL
HL = HL * 16
5053
LD E,A
LET Register E = Register A (which is the hex value of the digit).
5054
LD D,00H
LET Register D = 00H so that we have a Register Pair equalling the hex value of the digit.
5056
ADD HL,DE
ADD the value held in Register Pair DE to Register Pair HL. The results are held in Register Pair HL.
5057
LOOP BACK to 503DH.

5059H – Part of the PARSER routine when we first hit a (, then an =, and then a characer less than A, but then we get a non-HEX number while parsing.

5059
505A
LD B,H
LD C,L
LET Register Pair BC = Register Pair HL (the hex value).
505B
PUSH IX
POP HL
Let Register Pair HL = Register Pair IX.
505E
POP IX
Restore Register Pair IX from the top of the STACK.
5060
POP DE
Restore Register Pair DE from the top of the STACK.
5061
JUMP to 500EH to store that value and continue.

5063H – Part of the PARSER routine when we first hit a ( and then have an =. Here we will look for “ON”, “OFF”, “)” or “,”.

5063
LD BC,0000H
LET Register Pair BC = 0000H to indicate that the ON/OFF FLAG is OFF
5066
LD A,(HL)
Fetch the value stored at memory location pointed to by Register Pair HL (the current character on the command line) and put it into Register A.
5067
CP 4FH
Compare the value held in Register A against 4FH (ASCII: O). Results:
  • If Register A equals O, the Z FLAG is set.
  • If A < O, the CARRY FLAG will be set.
  • if A >= O, the NO CARRY FLAG will be set.
5069
RET NZ
If the NZ FLAG (Not Zero) is set then we didn’t get an O, so we will never get ON or OFF – RETurn to the caller with NZ FLAG set.
506A
INC HL
Bump the value stored in Register Pair HL by 1 to point to the next character in the command line.
506B
LD A,(HL)
Fetch the value stored at memory location pointed to by Register Pair HL and put it into Register A.
506C
CP 46H
Compare the value held in Register A against 46H (ASCII: F). Results: If Register A equals F, the Z FLAG is set; otherwise the NZ FLAG is set.
506E
If the Z FLAG (Zero) is set then we have OF and don’t need to keep scanning, so JUMP DOWN to 5076H.
5070
CP 4EH
Compare the value held in Register A against 4EH (ASCII: N). Results:
  • If Register A equals (ASCII: N), the Z FLAG is set.
  • If A < 4EH, the CARRY FLAG will be set.
  • if A >= 4EH, the NO CARRY FLAG will be set.
5072
RET NZ
If the NZ FLAG (Not Zero) is set then we didn’t get an (ASCII: N), so we have a problem. RETurn to the caller with the NZ FLAG set.
5073
LD BC,0FFFFH
LET Register Pair BC = 0FFFFH to indicate that the ON/OFF Flag is ON
5076
INC HL
Bump the value stored in Register Pair HL by 1 to point to the next character in the command line.
5077
LD A,(HL)
Fetch the value stored at memory location pointed to by Register Pair HL and put it into Register A.
5078
CP 29H
Compare the value held in Register A against 29H (ASCII: )). Results:
  • If Register A equals ), the Z FLAG is set.
  • If A < 29H, the CARRY FLAG will be set.
  • if A >= 29H, the NO CARRY FLAG will be set.
507A
RET Z
If the Z FLAG (Zero) is set, meaning we got a ), RETurn to the caller with the Z FLAG set (i.e., no error).
507B
CP 2CH
Compare the value held in Register A against 2CH (ASCII: ,). Results:
  • If Register A equals ,, the Z FLAG is set.
  • If A < ,, the CARRY FLAG will be set.
  • if A >= ,, the NO CARRY FLAG will be set.
507D
RET Z
If the Z FLAG (Zero) is set, meaning we got a ,, RETurn to the caller with the Z FLAG set (i.e., no error).
507E
LOOP BACK to 5076H to keep reading characters until we get a ) or a ,.

5080H – Evaluate an ON / OFF Parameter.

5080
INC HL
Bump the value stored in Register Pair HL by 1 to point to the next character in the command line.
5081
LD A,(HL)
Fetch the value stored at memory location pointed to by Register Pair HL and put it into Register A.
5082
CP 20H
Compare the value held in Register A against 20H (ASCII: SPACE). Results: If Register A equals 20H, the Z FLAG is set; otherwise the NZ FLAG is set.
5084
If the Z FLAG (Zero) is set, meaning we got a SPACE, LOOP BACK to the top of this routine.
5086
CP 28H
Compare the value held in Register A against 28H (ASCII: (). Results:
  • If Register A equals (, the Z FLAG is set.
  • If A < (, the CARRY FLAG will be set.
  • if A >= (, the NO CARRY FLAG will be set.
5088
RET NZ
If the NZ FLAG (Not Zero) is set,, meaning no (, RETurn to the caller with “ON” having been chosen.
5089
INC HL
Bump the value stored in Register Pair HL by 1 by 1 to point to the next character in the command line.
508A
GOSUB to the prior routine 5063H to look for “ON”, “OFF”, “)” or “,”.
508D
LD A,B
LET Register A = Register B (the result from that subroutine).
508E
OR A
Since a LD command does not set any FLAGS, Set FLAGS based on the contents of Register A.
508F
RET
RETurn to the caller.

5090H – Byte Storage Area in RAM used by the PARSER routine.

5090
NOP
No Operation (Do Nothing).
5091
NOP
No Operation (Do Nothing).
5092
NOP
No Operation (Do Nothing).
5093
NOP
No Operation (Do Nothing).
5094
NOP
No Operation (Do Nothing).
5095
NOP
No Operation (Do Nothing).
5096
NOP
No Operation (Do Nothing).
5097
NOP
No Operation (Do Nothing).


5098H – Message Storeage Area.

5098
Message
“CMD”
509B
Message
0AH + “TRSDOS READY” + 0DH
50A9
Message
“OPERATION ABORTED” + 0DH


50BBH – Test for Valid Characters. The CARRY FLAG is set if there is an error.

50BB
CP 30H
Compare the value held in Register A against 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.
50BD
RET C
If the C FLAG (CARRY FLAG) is set then A >= 0, RETurn to the caller WITH an error.
50BE
CP 3AH
Compare the value held in Register A against : (i.e., 1 character higher than 9). Results:
  • If Register A equals :, the Z FLAG is set.
  • If A < :, the CARRY FLAG will be set.
  • if A >= :, the NO CARRY FLAG will be set.
50C0
CCF
Invert the state of the CARRY FLAG, since we want the CARRY FLAG to be set on an error.
50C1
RET NC
If the NC FLAG (No Carry) is set, meaning < :, RETurn to the caller with NO error.
50C2
CP 41H
Compare the value held in Register A against 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.
50C4
RET C
If the C FLAG (CARRY FLAG) is set then A, RETurn to the caller WITH an error.
50C5
CP 5BH
Compare the value held in Register A against [ (i.e., 1 character higher than Z). Results:
  • If Register A equals [, the Z FLAG is set.
  • If A < [, the CARRY FLAG will be set.
  • if A >= [, the NO CARRY FLAG will be set.
50C7
CCF
Invert the state of the CARRY FLAG, since we want the CARRY FLAG to be set on an error.
50C8
RET
RETurn to the caller WITH an error.

50C9H – Library Command Name Storage Area.

50C9
Message Storage
“APPEND”
50D1
Message Storage
“ATTRIB”
50D9
Message Storage
“AUTO “
50E1
Message Storage
“BACKUP”
50E9
Message Storage
“BUILD “
50F1
Message Storage
“CLEAR “
50F9
Message Storage
“CLOCK “
5101
Message Storage
“CLS “
5109
Message Storage
“COPY “
5111
Message Storage
“CREATE”
5119
Message Storage
“DATE “
5121
Message Storage
“DEBUG “
5129
Message Storage
“DIR “
5131
Message Storage
“DO “
5139
Message Storage
“DUAL “
5141
Message Storage
“DUMP “
5149
Message Storage
“ERROR “
5151
Message Storage
“FORMS “
5159
Message Storage
“FORMAT”
5161
Message Storage
“FREE “
5169
Message Storage
“HELP “
5171
Message Storage
“KILL “
5179
Message Storage
“LIB “
5181
Message Storage
“LIST “
5089
Message Storage
“LOAD “
5191
Message Storage
“MASTER”
5199
Message Storage
“PATCH “
51A1
Message Storage
“PAUSE “
51A9
Message Storage
“PROT “
51B1
Message Storage
“PURGE “
51B9
Message Storage
“RELO “
51C1
Message Storage
“RENAME”
51C9
Message Storage
“ROUTE “
51D1
Message Storage
“SETCOM”
51D9
Message Storage
“TAPE “
51E1
Message Storage
“TIME “
51E9
Message Storage
“WP “
51F1
Message Storage
00