Model I TRSDOS v2.3 SYS1/SYS Explained

This is a disassembly of TRSDOS v2.3’s SYS1/SYS file. SYS1/SYS is the command line interpreter and is based on the “option” passed to SYS1 when called.

4E00H-4E1EH – Test to see if options 10, 20, 30, 40, 50, or 60 were passed, and if so, handle. If not, RETURN.

4E00
AND 70H
Isolate the option by ANDing against 01110000, leaving only 10, 20, 30, 40, 50, and 60 as possible
4E02
CP l0H
Test for option 10H
4E04
If option 10H was found, JUMP to 4E1FH to read the next command and process
4E07
CP 20H
Test for option 20H
4E09
If option 20H was found, JUMP to 4E1FH to read the next command and process
4E0B
CP 30H
Test for option 30H
4E0D
If option 30H was found, JUMP to 4E4EH to reprocess the command line buffer
4E0F
CP 40H
Test for option 40H
4E11
If option 40H was found, JUMP to 4F56H to copy and edit the file name
4El4
CP 50H
Test for option 50H
4El6
If option 50H was found, JUMP to 4FC0H to add a suffix to the file name
4El9
CP 60H
Test for option 60H
4ElB
If option 50H was found, JUMP to 507DH to parse the command list
4ElE
RET
If we are here, then none of the valid opions were chosen, so RETURN

4ElFH-4E4DH – Process OPTIONs 10 and 20

4E1F
EI
Enable interrupts
4E20
LD SP,41FCH
Reset the STACK POINTER to point to 41FCH
4E23
LD HL,4359H
INSTRUCTION NOT USED
4E26
BIT 05H,(HL)
INSTRUCTION NOT USED
4E28
LD HL,(430FH)
Load Register Pair HL with the memory contents of 430FH. 430FH is the SYSTEM CONDITION FLAG for TRSDOS v2.3
4E2B
BIT 07H,(HL)
Check Bit 7 of the SYSTEM CONDITION FLAG. Bit 7 is set if DEBUG is active
4E2D
If Bit 7 was zero (off), then JUMP down to 4E34H
4E2F
LD A,0C3H
If we are here, DEBUG was active. We need to force a JUMP instruction into memory, so we load A with 0C3H which is the JUMP portion of a 3 byte JUMP OPCODE
4E31
LD (4315H),A
Put the “JUMP” OPCODE into memory location 4315H
4E34
BIT 05H,(HL)
Check Bit 5 of the SYSTEM CONDITION FLAG. Bit 5 is set if CHAINING is active
4E36
If Bit 5 was zero (off), then jump to 4E40H
4E38
LD A,(3840H)
If we are here, then CHAINING is active, so load Keyboard Row 0 from memory location 3840H
4E3B
AND 04H
AND the Keyboard Row 0 result against 04H (Binary: 00000100) to see if the BREAK key was pressed
4E3D
JP NZ,4030H
If the BREAK key was pressed, JUMP to 4030H to re-run SYS1/SYS with OPTION 2
4E40
LD HL,51B8H
Load Register Pair HL with the memory location for the DOS READY message
4E43
Use the message display routine at 4467H (from BOOT/SYS) to display the DOS READY message
4E46
LD HL,4318H
Load Register Pair HL with 4318H, which is the address of the command line buffer
4E49
LD B,3FH
Load Register B with 3FH (Decimal: 63) to represent how large the command line buffer can be
4E4B
CALL 0040H
GOSUB the ROM KEYBOARD INPUT routine at 0040H to get a command line

4E4EH-4E86H – Process OPTION 40

4E4E
LD BC,402DH
Load Register Pair with 402DH which is the RETURN address to SYS0/SYS
4E51
PUSH BC
Push Register Pair BC to the Stack
4E52
LD DE,4480H
Load Register Pair with 4480H which is the TRSDOS v2.3 system DCB
4E55
GOSUB to 4F56H to move the file name to the DCB
4E58
If 4F56H returned a NZ, an illegal character was found. In this case, JUMP forward to 4E87H
4E5B
LD A,(DE)
If we are here, no illegal characters were found, so load Register A with the memory contents of Register Pair DE (which is the command line)
4E5C
CP 2AH
Compare Register A against *
4E5E
If the first character in the command line (held in Register A) was a * then we have an error, so JUMP forward to 4E87H
4E61
PUSH HL
Store Register Pair HL in the stack
4E62
LD BC,4EA4H
Load Register Pair BC with 4EA4H. 4EA4H is the memory address for library commands held in SYS1/SYS
4E65
GOSUB a routine at 502AH to test first for BASIC2, DEBUG, and TRACE
4E68
If we are here then we were given a library command, so JUMP down to 4E84H to process that library command
4E6A
LD BC,4EBDH
If we are here, then we were given something other than a SYS1/SYS library command, so put the load address of the SYS6/SYS Library Commands (at 4EBDH) into Register Pair BC
4E6D
GOSUB a routine at 502AH to test against the list of SYS6/SYS library commands
4E70
If the command line matches a SYS6/SYS library command, then JUMP down to 4E84H to process
4E72
LD A,(430FH)
Load Register A with the system condition flag located at 430FH
4E75
RES 04H,A
Bit 04H of the system condition flag is SYS6/SYS LOADED. We won’t be needing SYS6/SYS at this point so clear that bit
4E77
LD (430FH),A
If we’re here, then the command was neither a SYS1 or SYS6 library command. This leaves us with a CMD file to process. First step, since we modified the system condition flag located at 430FH, update it
4E7A
LD HL,51B5H
Load Register Pair HL with the address of the CMD message stored at 51B5H
4E7D
GOSUB to 4FC0H to add /CMD suffix to a filename
4E80
POP HL
Restore Register Pair HL from the stack
4E81
JUMP to the routine to load and execute files
4E84
POP HL
Clear the STACK
4E85
PUSH DE
Push Register Pair DE (which is crrently holding the SYS1/SYS address for the DOS command) to the stack
4E86
RET
RETURN (which at this point could be either 514CH, 5162H, 5191H, or 4E90H [Jump to SYS6/SYS])

4E87H-4E8FH – Display the “WHAT” error message and wait for a new command to be entered.

4E87
LD HL,51C3H
Load Register Pair HL with the address for the “WHAT” message
4E8A
GOSUB to 4467H to display the “WHAT” message
4E8D
JUMP to 4030H to wait for the next command

4E90H-4EA3H – Set the system to load SYS6/SYS and JUMP to it.

4E90
LD A,(430FH)
Load Register A with the system condition flag located at 430FH
4E93
BIT 04H,A
Bit 04H of the system condition flag is SYS6/SYS LOADED. Check to see
4E95
If Bit 04H is set (and SYS6/SYS is loaded), JUMP to SYS6/SYS at 5200H
4E98
LD A,(430FH)
Load Register A with the system condition flag located at 430FH
4E9B
SET 04H,A
Bit 04H of the system condition flag is SYS6/SYS LOADED. Set that bit
4E9D
LD (430FH),A
Since we modified the system condition flag located at 430FH, update it
4EA0
LD A,88H
Load Register A with 088H which is the DOS overlay required for SYS6/SYS option “0”
4EA2
PUSH AF
Push Register Pair AF to the Stack
4EA3
RST 28H
Load and execute SYS6/SYS

4EA4H-4EBCH – Text String and Lookup Table for SYS1/SYS Library Commands

4EA4
DEFM ‘BASIC2’
Text for the “BASIC2” command
4EAA
DEFW 514CH
Addess of the “BASIC2” command in SYS1/SYS
4EAC
DEFM ‘DEBUG’
Text for the “DEBUG” command
4EB2
DEFW 5162H
Addess of the “DEBUG” command in SYS1/SYS
4EB4
DEFM ‘TRACE’
Text for the “TRACE” command
4EBA
DEFW 5191H
Addess of the “TRACE” command in SYS1/SYS
4EBC
DEFB 00H
Text sting terminator

4EBDH-4F55H – Text String and Lookup Table for SYS6/SYS Library Commands. These are all set to 6 characters in length to make a comparison against 6 characters.

4EBD
DEFM ‘APPEND’
Text for the “APPEND” command in SYS6/SYS
4EC3
DEFW 4E90H
Address of the command in SYS6/SYS
4EC6
DEFM ‘ATTRIB’
Text for the “ATTRIB” command in SYS6/SYS
4ECB
DEFW 4E90H
Address of the command in SYS6/SYS
4ECD
DEFM ‘AUTO ‘
Text for the “AUTO” command in SYS6/SYS
4ED3
DEFW 4E90H
Address of the command in SYS6/SYS
4ED5
DEFM ‘CLOCK ‘
Text for the “CLOCK” command in SYS6/SYS
4EDB
DEFW 4E90H
Address of the command in SYS6/SYS
4EDD
DEFM ‘COPY ‘
Text for the “COPY” command in SYS6/SYS
4EE3
DEFW 4E90H
Address of the command in SYS6/SYS
4EE5
DEFM ‘DATE ‘
Text for the “DATE” command in SYS6/SYS
4EEB
DEFW 4E90H
Address of the command in SYS6/SYS
4EED
DEFM ‘DEVICE’
Text for the “DEVICE” command in SYS6/SYS
4EF3
DEFW 4E90H
Address of the command in SYS6/SYS
4EF5
DEFM ‘DIR ‘
Text for the “DIR” command in SYS6/SYS
4EFB
DEFW 4E90H
Address of the command in SYS6/SYS
4EFD
DEFM ‘DUMP ‘
Text for the “DUMP” command in SYS6/SYS
4F03
DEFW 4E90H
Address of the command in SYS6/SYS
4F05
DEFM ‘FREE ‘
Text for the “FREE” command in SYS6/SYS
4F0B
DEFW 4E90H
Address of the command in SYS6/SYS
4F0D
DEFM ‘KILL ‘
Text for the “KILL” command in SYS6/SYS
4F13
DEFW 4E90H
Address of the command in SYS6/SYS
4Fl5
DEFM ‘LIB ‘
Text for the “LIB” command in SYS6/SYS
4FlB
DEFW 4E90H
Address of the command in SYS6/SYS
4FlD
DEFM ‘LIST ‘
Text for the “LIST” command in SYS6/SYS
4F23
DEFW 4E90H
Address of the command in SYS6/SYS
4F25
DEFM ‘LOAD ‘
Text for the “LOAD” command in SYS6/SYS
4F2B
DEFW 4E90H
Address of the command in SYS6/SYS
4F20
DEFM ‘PRINT ‘
Text for the “PRINT” command in SYS6/SYS
4F33
DEFW 4E90H
Address of the command in SYS6/SYS
4F35
DEFM ‘PROT ‘
Text for the “PROT” command in SYS6/SYS
4F3B
DEFW 4E90H
Address of the command in SYS6/SYS
4F3D
DEFM ‘RENAME’
Text for the “RENAME” command in SYS6/SYS
4F43
DEFW 4E90H
Address of the command in SYS6/SYS
4F45
DEFM ‘TIME ‘
Text for the “TIME” command in SYS6/SYS
4F4B
DEFW 4E90H
Address of the command in SYS6/SYS
4F4D
DEFM ‘VERIFY’
Text for the “VERIFY” command in SYS6/SYS
4F53
DEFW 4E90H
Address of the command in SYS6/SYS
4F55
DEFB 00H
Text string of a terminator

4F56H – Processor for Option 50. Option 50 is the COPY command. The SOURCE string is pointed to by HL. The DESTINATION DCB is pointed to by DE. B holds the number of characters in the HL string. Exit status is 0 if no errors.

4F56
PUSH DE
Save the DBC address which was set before entry to this routine
4F57
LD B,08H
Load Register B with the maximum number of characters for a filename (08)
4F59
GOSUB to 4FF4H to look for a /, ., ;, or , in the command string
4F5C
JR NZ,4F98H
If NZ is returned, then no characters were copied to the DCB. If that’s the case, JUMP to 4F98H
4F5E
CP 2FH
If we are here, characters were copied to the DCB. Need to check to see if it was a /
4F60
If there was no /, JUMP to 4F6BH
4F62
LD (DE),A
If there was a /, move it to the DCB held at the memory location pointed to by Register Pair DE
4F63
INC DE
Bump DE to point to the next memory location
4F64
LD B,03H
Load Register B with 03H, which is the maximum number of remaining characters there can be after a /
4F66
GOSUB to 4FF4H to move the number of characters held in B to the DCB. This would be the extension
4F69
If there was no extension, JUMP to 4FA5H
4F6B
CP 2EH
Check to see if there was a . for a password
4F6D
If there was no ., then JUMP to 4F78H
4F6F
LD (DE),A
If there was a ., move it to the DCB held at the memory location pointed to by Register Pair DE
4F70
INC DE
Bump DE to point to the next memory location
4F71
LD B,08H
Load Register B with 08H, which is the maximum password length
4F73
GOSUB to 4FF4H to move the number of characters held in B to the DCB. This would be the password
4F76
If there was no password, but there was a ., JUMP to 4FA5H
4F78
CP 3AH
Check to see if there was a : for a drive designation
4F7A
If there was no : JUMP to 4F85H
4F7C
LD (DE),A
If there was a :, move it to the DCB held at the memory location pointed to by Register Pair DE
4F7D
INC DE
Bump DE to point to the next memory location
4F7E
LD B,01H
Load Register B with 01H, which is the maximum drive number length
4F80
GOSUB to 4FF4H to move the number of characters held in B to the DCB. This would be the password
4F83
If there was no drive number following the :, JUMP to 4FA5H
4F85
LD C,A
Load Register C with the last character read (still held in Register A at the moment)
4F86
LD A,03H
Load Register A with an 03H representing the terminating character for a DCB list
4F88
LD (DE),A
Put the terminating character at the end of the DCB list (pointed to by DE)
4F89
XOR A
Clear all status flags
4F8A
LD A,C
Restore Register A with the last character read (held in Register C)
4F8B
POP DE
Restore the original DCB into DE
4F8C
PUSH DE
Push the original DCB into the stack
4F8D
LD BC,4FA7H
Load Register Pair BC with 4FA7H, which are the interim command phrases of TO, ON, and OVER
4F90
GOSUB to 502AH to look for a match against those phrases
4F93
POP DE
Restore the original DCB into DE
4F94
If TO, ON, or OVER were found, JUMP to 4F56H
4F96
XOR A
Clear all status flags (to show success)
4F97
RET
RETURN

4F98-4FA6 – Subroutine which is called if no characters were copied to the DCB. This checks for a “*”+2 characters, and copies them to the DCB

4F98
CP “*”
Test to see if the character is a *
4F9A
Jump to 4FA5H if the character is NOT a *
4F9C
LD (DE),A
If we are here, we have a * so first put the * into the DCB (pointed to by Register Pair DE)
4F9D
INC DE
Bump Register Pair DE to point to the next byte of the DCB
4F9E
LD B,02H
Since there are 2 characters in a DCB, set Register B so to set up to scan for 2 characters
4FA0
GOSUB to the routine which copies the next 2 characters to the DCB
4FA3
If 2 characters were copies, JUMP to 4F85H
4FA5
POP DE
Restore Register Pair DE with the routine callers DE
4FA6
RET
RETURN out of the subroutine

4FA7-4FBF – Parameter separator list of TO/ON/OVER. These are all set to 6 characters in length to make a comparison against 6 characters.

4FA7
DEFM ‘TO ‘
4FAD
DEFW 0000H
4FAF
DEFM ‘ON ‘
4FB5
DEFW 0000H
4FB7
DEFM ‘OVER ‘
4FBD
DEFW 000H
4FBF
DEFB 00H

4FC0-4FDAH – Process OPTION 50 by adding a /CMD suffix to the filename in the DCB by pushing the characters after the filename by 4 characters and putting it in, so long as the filename didn’t end with a /.

4FC0
PUSH DE
Put the DCB Address currently held in DE onto the Stack
4FC1
PUSH HL
Put the Appendage List currently held in HL onto the Stack
4FC2
EX DE,HL
Put the Appendage List into DE and the DCB Address into HL
4FC3
INC HL
Bump HL so that it points to the 2nd character in the DCB
4FC4
LF B,09H
We want to test for 9 characters maximum, so set Register B to 9
4FC6
LD A,(HL)
Get the current character in the DCB and put it in Register A
4FC7
CP “/”
Test to see if the current character in the DCB is a /
4FC9
Since CP returns Z set if A is /, JUMP to 4FD8H (meaning, do not add the /CMD) if it is a /
4FCB
Since CP returns C set if A is less than /, JUMP to 4FD8H (meaning, do not add the /CMD) since we have a special character
4FCD
CP “:”
Test to see if the current character in the DCB is a :
4FCF
Since CP returns C set if A is less than :, this means we have a number, so JUMP to 4FD5H
4FD1
CP “A”
Test to see if the current character in the DCB is a letter
4FD3
Since CP returns C set if A is less than A, this means we do not have a letter, so JUMP to 4FDBH to add the /CMD because we have found the end of the filename
4FD5
INC HL
If we are still here, we have a letter so we have to keep looking … so bump HL to the next character in the DCB ..
4FD6
… and loop back to 4FC6H until we exit because we found a /, a :, a number, or tested 9 characters
4FD8
POP HL
Restore the Appendage List to HL
4FD9
POP DE
Restore the DCB Address to DE
4FDA
RET
RETURN

4FDB-4FF3 – This subroutine adds /CMD after the filename but before the drive number

4FDB
LD BC,0000FH
Load Register Pair BC with the maximum length of a DCB – 15 characters
4FDE
ADD HL,BC
Since HL is holding the Appendage List, calculate the last byte which can be used
4FDF
LD D,H
Copy register Pair HL into Register Pair DE, so that DE now holds the last byte used in the DCB
4FE0
LD E,L
4FE1
INC DE
Move Register Pair DE forward 4 spaces to make room for /CMD
4FE2
INC DE
4FE3
INC DE
4FE4
INC DE
4F35
INC BC
Bump the number of bytes to move down currently held in Register Pair BC
4FE6
LDDR
Transfer the byte of data from (HL) to (DE), and then decrement HL, DE, and BC. Keep going until BC is 0
4FE8
POP HL
Restore the start address of “/CMD” to HL
4FE9
INC HL
Bump HL by 2 to skip to the end of the list
4FEA
INC HL
4FEB
LD C,03H
Since we need to move 3 characters in a LDDR, set Register C to 3
4FED
LDDR
Transfer the byte of data from (HL) to (DE), and then decrement HL, DE, and BC. Keep going until BC is 0
4FEF
LD A,”/”
Load Register A with a /
4FF1
LD (DE),A
Put the / into the memory location before the CMD
4FF2
POP DE
Restore the DCB into Register Pair DE
4FF3
RET
RETURN

4FF4-5029 – This subroutine checks the characters for a delimeter or a letter and fills the DCB with letters and a terminator.

4FF4
LD A,B
Put the number of characters to examine (currently held in Register B) into Register A
4FF5
LD (5026H),A
Save the number of characters to examine to memory location 5026H
4FF8
INC B
Bump Register B by 1 to deal with the DEC command at 5013H
4FF9
LD A,(HL)
Get the next character from the command line
4FFA
CP 03H
Check to see if an 03H terminator was found
4FFC
If we have a 03H then JUMP away to 5021H
4FFE
CP 0DH
Check to see if an 0DH terminator was found
5000
If we have a 0DH then JUMP away to 5021H
5002
INC HL
BUMP Register Pair HL to point to the next character from the command line
5003
CP “0”
Check to see if that character is special character (i.e., less than 0 in ASCII)
5005
Since CP returns C set if A is less than 0, JUMP away to 5021H
5007
CP “:”
Check to see if that character is a :
5009
Since CP returns C set if A is less than : (meaning that it is a number, since its greater than 30H (or we would have jumped away already) and less than a :), JUMP away to 5013H
500B
CP “A”
Check to see if that character is a A
500D
Since CP returns C set if A is less than A (meaning that it is between a : (or we would have jumped away already) and an A), JUMP away to 5021H
500F
CP “[“
Check to see if that character is a [
5011
Since CP returns C reset if A is greater than or equal to [ (meaning that it is above a Z), JUMP away to 5021H
5013
DEC B
Decrement the number of characters to still examine by 1 since we now have a good character
5014
So long as there are still more characters to check, JUMP forward to 501EH
5016
LD (DE),A
If we are here, all characters have been checked, so move to the DCB in case it is a filename
5017
XOR A
Zero out A and clear all flags
5018
LD (5026H),A
Put a zero into memory location 5026H holding the number of characters to check
501B
INC DE
BUMP Register Pair DE to point to the next entry in the DCB
501C
LOOP back to 4FF9H until terminators or the specified number of characters have been examined
501E
INC B
BUMP Register B to the count for the last character
501F
LOOP back to 4FF9H until terminators or the specified number of characters have been examined
5021
LD C,A
This is the jump location if an 03H or 0DH was found, so put the terminating character into Register C
5022
LD A,03H
Put a terminating character of 03H into Register A
5024
LD (DE),A
Put the terminating character into the DCB (so that the DCB is terminated with an 03H)
5025
LD A,00H
Put a 0 into Register A to set the number of characters counted
5027
OR A
Set the status flags for the count
5025
LD A,C
Put the terminating character back into Register A
5029
RET
RETURN

502A-504l – This subroutine compares the list held in BC (which could be TO/ON/OVER or the SYS6 library list) against the list pointed to by DE (4480H which is the TRSDOS v2.3 system DCB).

502A
PUSH HL
Save the input string list address to the stack
502B
LD H,B
Load Register Pair HL with the contents of Register Pair BC, which holds the table to search
502C
LD L,C
502D
LD C,01H
Load Register C with the number of characters to search. In this case, its 1
502F
LD A,(DE)
Load Register A with a character from the search list
5030
CP (HL)
Compare it against the character from the input field
503l
If they match, JUMP out of this subroutine to the next subroutine at 5042H
5033
PUSH BC
The characters do not match, we need to move to the next entry. First save the callers BC to the stack
5034
LD BC,0008H
Set Register Pair BC with the offset to go to the next entry, being 8
5037
ADD HL,BC
Calculate the next entry in the list by advancing HL by 8
5038
POP BC
Restore the Register Pair BC
5039
INC C
BUMP Register C to point to the first character of the next list
503A
LD A,(HL)
Put the first character of the next list into A
503B
OR A
Set the registers to check to see if we are at the end of the list yet
503C
If we are not at the end of the list, JUMP back and keep looking
503D
POP HL
If we are here, we reached the end of the list, so restore the input string list address from the Stack
503F
OR 01H
Check to see if it signals 01H meaning NO MATCH
504l
RET
RETURN

5042-5063 – This subroutine is called when the first character in a list matches, and if so, compares remainder of list.

5042
LD B,05H
Put the number of characters left to match into Register B. Since each entry is 6 characters, and we already read one, that leaves 5 more to test.
5044
PUSH HL
Save the input string address onto the Stack
5045
PUSH DE
Save the search list address onto the Stack
5046
INC DE
BUMP Register Pair DE to point to the next character in the input list
5047
INC HL
BUMP Register Pair HL to point to the next character in the comparison list
5048
LD A,(DE)
Fetch a character from the input list and put it into Register A
5049
CP 03H
Compare it to 03H to see if we have a terminator
504B
If we have a terminator, JUMP forward to 5074H
504D
CP 0DH
Compare it to 0DH to see if we have a terminator
504F
If we have a terminator, JUMP forward to 5074H
5051
CP (HL)
If we are here it isn’t a delimeter, so let’s check it against the comparison list
5052
If they do not match, its a bust so JUMP forward to 5064H to check for an ending byte
5054
If they do match, LOOP back and see if they keep matching
5056
POP DE
If we are here, there was a full match. Restore the 2nd character of the matching search list address from the Stack
5057
LD A,C
Load the number of lists searched (held in Register C) into Register A
5058
POP BC
Restore the starting address of the matched command into Register Pair BC
5059
LD HL,0006H
Put an offset of 06 (meaning the length of the command, since each tabel is set to have every entry at 6 characters) into Register Pair HL
505C
ADD HL,BC
Add the length of the command to the starting address of the command to determine the end of the command, and put that into HL
505D
LD C,A
Restore the list number from Register A back into Register C
505E
LD E,(HL)
Put the LSB of the matched command into Register E
505F
INC HL
Bump HL to now point to the MSB of the matched command
5060
LD D,(HL)
Put the MSB of the matched command into Register D
506l
POP HL
Restore the starting address of the input string into Register Pair HL
5062
XOR A
Set Register A to show a “GOOD” status
5063
RET
RETURN

5042-507C – This sub-subroutine is called when there is clealy no match, so it advances to the next entry.

5064
CP “0”
Compare the character held in Register A against a 0
5066
JR C,5074H
Since CP returns C set if A is less than 0 (meaning it is a special character), JUMP away to 5074H
5068
CP “:”
Compare the character held in Register A against a :
506A
JR C,5079H
Since CP returns C set if A is less than : (meaning that it is a number, since its greater than 0 (or we would have jumped away already) and less than a :), JUMP away to 5079H
506C
CP “A”
Compare the character held in Register A against an A
506E
JR C,5074H
Since CP returns C set if A is less than A (meaning that it is between a : (or we would have jumped away already) and an A), JUMP away to 5074H
5070
CP “[“
Compare the character held in Register A against a [
5072
JR C,5079H
Since CP returns C reset if A is greater than or equal to [ (meaning that it is above a Z), JUMP away to 5079H
5074
LD A,(HL)
Get the current character and put it into Register A
5075
CP ” “
Compare the character held in Register A against a space
5077
If it is a space, JUMP back to 5056H
5079
POP DE
If it isn’t a space, then clear the stack
507A
POP HL
Restore the input string address to Register Pair HL
507B
JUMP back to 5033H to move to the next entry and test against that one

507DH-508AH – Processor for Option 60 Parse routine.

507D
LD A,(HL)
Get the current character and put it into Register A
507E
CP 0DH
Compare it to 0DH to see if we have a terminator
5080
RET Z
If we have an 0DH terminator, RETURN out of the routing.
5081
CP “(“
Check the current character against an (
5053
If it is a (, JUMP forward to 508EH
5085
CP ” “
Check the current character against a space
5087
If it is a space, JUMP forward to 508BH
5089
OR A
Set the status flags
508A
RET
RETURN

508B-508CD – This subroutine is called from the OPTION 60 parse if a ” ” is found.

508B
INC HL
BUMP HL to point to the character after the ” “
508C
Jump back to the Option 60 routine, now pointing to the character after the ” “

508E-50A7 – This subroutine is called from the OPTION 60 parse if a ( is found.

508E
PUSH DE
Save the command list address to the Stack
508F
LD B,06H
We are going to copy 6 characters so load Register B with a 6
5091
LD DE,51AFH
Load Register DE with the buffer address of 51AFH
5094
INC HL
Bump HL to point to the first character after the (
5095
GOSUB to 4FF4H to copy 6 characters until a ) is found
5098
DEC HL
DECREMENT Register Pair HL to remove the terminating 03H from that GOSUB
5099
POP DE
Restore the caller’s Register Pair DE
509A
RET NZ
If there are no characters copied (meaning, an error), RETURN
599B
PUSH DE
If characters were copied, save the caller DE to the Stack
509C
LD B,D
Copy Register Pair DE to Register Pair BC in preparation for the 502AH routine (which compares against a table in memory held in BC)
509D
LD C,E
509E
LD DE,51AFH
Load Register DE with the buffer address of 51AFH
50A1
Look for the command in the the callers command list
50A4
JUMP to 50A8H if a match was found to continue processing
50A6
POP DE
If a match was NOT found, restore Register Pair DE from the Stack
50A7
RET
RETURN with the error status set

50A8-50C0 – This subroutine is called if a match was found in the prior routine

50A8
LD A,(HL)
Put the character from the input string into Register A
50A9
CP “=”
Compare the character held in Register A against an =
50AB
If it is an =, JUMP down to 50C1H
50AD
LD BC,0FFFFH
If it is not an =, fill BC with FFFFH to designate “NO PARAMETER”
50B0
LD A,C
Put the LSB of the address into Register A
50Bl
LD (DE),A
Put the LSB into the buffer
50B2
INC DE
BUMP DE to point to the next open space in the buffer
50B3
LD A,B
Put the MSB of the address into Register A
5084
LD (DE),A
Put the MSB into the buffer
5085
POP DE
Restore the routine callers command list address into Register Pair DE
50B6
LD A,(HL)
Put the character from the input string into Register A
50B7
CP “,”
Compare the character held in Register A against a ,
50B9
If it is a , then JUMP back to 508EH
50BB
CP “)”
Compare the character held in Register A against a )
5080
RET NZ
If it is not a ) then exit out of the routine
50BE
INC HL
BUMP Register Pair HL to point to the next character
50BF
XOR A
Set A and flags to a GOOD status in preparation of exiting the routine
50C0
RET
RETURN

50Cl-50D1 – This subroutine is called if an = was found

50Cl
INC HL
BUMP Register Pair HL to point to the first character after the =
50C2
LD A,(HL)
Get the next character and put it into Register A
50C3
CP “X”
Compare the character held in Register A against an X (which would signify a Hexidecimal number coming up)
50C5
If the character after the = is an X, JUMP down to 50D2H
50C7
CP “A”
Compare the character held in Register A against an A
50C9
Since CP returns C set if Register A is less than A (meaning that it is a number), JUMP down to 50DAH
50CB
If we are here then Register A is holding an alphabetic character, so GOSUB the routine at 50DFH to test for YES, NO, and OFF
50CE
If the return is Z (meaning a YES, NO, or OFF was found), JUMP back to 50B0H to RETURN to caller
50D0
If the return is NZ (meaning it is not YES, NO, or OFF), then we are in an error state so JUMP back to 506AH to return to caller

50D2-50D9 – This subroutine is called if a HEX VALUE was next

50D2
INC HL
BUMP Register Pair HL to point to the next character to point to the character following the X
50D3
GOSUB to 511FH to convert the ASCII character to BINARY
50D6
If the routine returns a ZERO, then there is NO ERROR, so jump to 50B0H to save the Hex value
50D8
Otherwise, there was an error, so JUMP back to 506AH to return to caller

50DA-50DE – This subroutine is called if a NUMBER (i.e., decimal value) was next

50DA
We have a number so GOSUB to 5104H to deal convert ASCII to BINARY.
50DD
JUMP back to 50B0H to RETURN to caller

50DF-5103 – This subroutine tests for YES, NO, or OFF as a parameter

50DF
LD BC,0000H
Set Register Pair BC to 0 in preparation of a return code
50E2
LD A,(HL)
Get the next character (initially the first character after the ()
50E3
CP “Y”
Check the current character against a Y
50E5
JUMP to 50F7H if it is a Y
50E7
CP “N”
Check the current character against an N
50E9
JUMP to 50FAH if it is a N
50EB
CP “O”
Check the current character against an O
50ED
RET NZ
If the current character is not an O then RETURN
50EE
INC HL
If the current characer is an O then move the pointer to the next character
50EF
LD A,(HL)
Put the next character into Register A
50F0
CP “F”
Check the current character against an F
50F2
If we are here then we have OF, so JUMP to 50FAH
50F4
CP “N”
Check the current character against an N
50F6
RET NZ
If we are here then we have ON, so RETURN
50F7
LD BC,0FFFFH
Set up for a return code of FFFFH in BC
50FA
INC HL
Bump to the next character
50FB
LD A,(HL)
Put the next character into Register A
50FC
CP “)”
Check the current character against an )
50FE
RET Z
If it is ) then RETURN
50FF
CP “,”
Check the current character against an ,
5101
RET Z
If it is , then RETURN
5102
LOOP back to 50FAH to keep checking for a ) or ,

5104-511E – This subroutine handles ASCII to BINARY conversion

5104
LD BC,0000H
Set Register Pair BC to 0 in preparation for math
LD A,(HL)
Get the next character
5108
SUB 30H
Subtract 30H which turns the ASCII CHARACTER into its DECIMAL equivalent
510A
RET C
If the C flag is set as a result of a SUB, a BORROW occurred. This means it wasn’t a digit after all, so RETURN
5l0B
CP 0AH
Test to see if the result of the subtraction is higher than 9
5l0D
RET NC
If the CP results in NC, the character was greater than 9 so RETURN
510E
PUSH HL
If we are here, then we have a number between 0 and 9, so save it to the Stack
5l0F
LD H,B
Copy HL to BC as a starting point for math
5110
LD L,C
5111
ADD HL,HL
Double it
5112
ADD HL,HL
Double that (so times 4)
5113
ADD HL,BC
Add the original value to it (so times 5)
5114
ADD HL,HL
Double that (so times 10)
5115
LD B,00H
Set up B to track prevent from the addition, by making Register Pair BC always be 00xx
5117
LD C,A
Put the current digit into Register C
5118
ADD HL,BC
Add this to the previous accumulated value
5119
LD B,H
Move the current value in Register Pair HL to Register Pair BC
511A
LD C,L
511B
POP HL
Restore the command string address from the Stack
SllC
INC HL
BUMP HL to point to the next character
511D
JUMP back to 5017H to loop until an END OF LINE is found

511F-513D – This subroutine also converts ASCII to BINARY. HL points to the character after the “X”

511F
LD BC,0000H
Set Register Pair BC to 0 in preparation for math
5122
LD A,(HL)
Put the current character into Register A
5123
CP 27H
Compare that character with an apostrophe
5125
RET NZ
If it is NOT an apostrophe then we have an error (because we had an X but no following apostrophe) and RETURN
5126
INC HL
Since we have an apostrophe, BUMP HL to point to the next character which should be a hex number since it follows X’
5127
LD A,(HL)
Put the next character into Register A
5128
SUB 30H
Subtract 30H which turns the ASCII CHARACTER into its DECIMAL equivalent
512A
If the C flag is set as a result of a SUB, a BORROW occurred. This would mean that we are at the end of the input string at this point so JUMP back to 5036H to signify that the characters do not match, we need to move to the next entry
512C
CP 0AH
At this point, we need to see if we have a valid hex digit of 0-F. First, compare that character for 0-9
512E
Since CP returns C set if Register A is less than 0AH (meaning that it is a number), JUMP down to 513EH to continue processing the hex number
5130
SUB 07H
Next we need to test for A-F (hex values) so we subtract 07
5132
CP 10H
Compare that against 10H to adjust the binary value
5134
Since CP returns C set if Register A is less than 10H (meaning that it A-F), JUMP down to 513EH to continue processing the hex number
5136
LD A,(HL)
Put the next character into Register A
5137
CP 27H
Compare that character with an apostrophe (which would be the END of the HEX designation)
5139
INC HL
BUMP HL to point to the next character
513A
RET Z
If the apostrophe was found, RETURN because we are done
513B
DEC HL
DECREMENT HL to back up to the illegal character
513C
XOR A
Set up for an ERROR response code
513D
RET
RETURN

513E-514B – This subroutine is part of the HEX routine and multiplies the current digit by 16 and adds it to the math accumulator.

513E
PUSH HL
Save the current input string to the Stack
513F
LD H,B
LD L,C
Move the current Hex binary value from BC to HL
5141
ADD HL,HL
Multiply by 2 (so * 2)
5142
ADD HL,HL
Multiply by 2 (so * 4)
5143
ADD HL,HL
Multiply by 2 (so * 8)
5144
ADD HL,HL
Multiply by 2 (so * 16)
5145
LD B,H
Put the MSB of the new value into Register B
5146
ADD A,L
Add the current Hex digit
5147
LD C,A
Put the resulting match into Register C as the LSB, so now BC has the current hex value
5148
POP HL
Restore the input string pointer from the Stack
5549
INC HL
BUMP HL to point to the next digit in the input string
514A
LOOP back to 5127H until a non-Hex number found

514C-5161 – BASIC2 Routine

514C
LD HL,06D2H
In preparation for a LDIR (which moves HL to DE until BC is reduced to 0), set up HL to point to the JUMP VECTORS and DCB’s ..
514F
LD DE,4000H
… and set up DE to point to 4000H where the vectors will be moved to
5152
LD BC,0036H
… and set up BC to move 36H (=54 Decimal) bytes
5155
LDIR
Do the block move to move those vectors and DCB’s to 4000H
5157
XOR A
Zero out Register A
5158
LD B,27H
Load Register B with 27H (=47 Decimal) bytes. Note: At this point Register Pair DE points to the byte after the vectors/DBC’s in RAM
515A
LD (DE),A
Load the memory location pointed to by Register Pair DE with a Zero
515B
INC DE
BUMP Register Pair DE
515C
LOOP back 2 instructions to keep zeroing out bytes 47 times
515E
DI
Disable interrupts
5l5F
Jump to the LEVEL II BASIC Warm Restart routine

5162-5183 – DEBUG Routine

5162
GOSUB to 510A0H to process the ON/OFF parameters of the DEBUG command
5165
LD HL,430FH
Put the system condition flag address (430FH) into HL
5168
DI
Disable interrupts to prevent anything from disturbing the loading of 4315H and 4316H values
5169
If DEBUG, OFF then JUMP to 5184H
5l6B
SET 07H,(HL)
If not, then set bit 7 of the system condition flag to on to signal that DEBUG is ON
5160
LD HL,400FH
Set HL to point to the DEBUG load vector
517B
LD A,0C3H
Load Register A with the JP Opcode
5172
LD (4316H),HL
Build a JP 400FH Opcode by loading 4316H with 400FH which was stored in Register Pair HL ..
5175
LD (4315H),A
… and loading 4315H with a JP Opcode stored in A
5178
LD A,0CDH
Load Register A with a CALL Opcode
517A
LD (4031H),HL
Build a CALL 400FH Opcode by loading 4031H with 400FH which was stored in Register Pair HL ..
517D
EI
Enable Interrupts
517E
LD (4030H),A
… and loading 4315H with a CALL Opcode stored in A
5181
We’re done so JUMP back to 4ElFH to read the next command and process

5184-5190 – DEBUG, OFF Routine

5184
RES 07H,(HL)
Reset bit 7 of the system condition flag to on to signal that DEBUG is OFF
5186
XOR A
Zero out Register A
5187
LD (4315H),A
Overwrite the JP Opcode that was set when DEBUG was turned on
518A
LD A,3EH
Now we are going to set up for a 3 byte Opcode, so we start by loading A with 3EH which is the first part of the 2 byte Opcode of LD A,n
518C
LD HL,0EFA3H
Next we are loading up EF and A3 which ultimately translates to LD,0A3H and RST 28H
518F
JUMP to 517AH to put A and HL into 4030H-4032H

5191-519D – TRACE Routine

5191
GOSUB to 51ABH to process the ON/OFF parameters of the TRACE command
5194
LD DE,4CD9H
Put the address of the TRACE, OFF routine from SYS0/SYS into Register Pair DE
5197
LD A,0BH
Put the index of the TRACE clock scan list in SYS0/SYS
5199
If we have a TRACE, ON (Z is set), JUMP to 4413H to add a TRACE to the clock scan list
519C
If we are here, we can assume TRACE, OFF, so JUMP to 4410H to remove it from the clock scan list

519F – Subroutine to look for a ( and if found then test for YES, NO, or OFF

519F
INC HLL
BUMP Register Pair HL to point to the next character in the input string
51A0
LD A,(HL)
Get the next character from the command line
51Al
CP 20H
Compare the character to a space
51A3
If the next characer is a space, ignore it by JUMPing to the top of this subroutine
51A5
CP “(“
Compare the character to a (
51A7
RET NZ
If the character is not a ( then RETURN
SlAB
INC HL
If the character is a ( then BUMP Register Pair HL to point to the next character in the input string
51A9
GOSUB to the routine to look for Y, N, OF or ON phrases. When that routine is over B will be 0 if Y, N, or OF. B will be FF if ON
51AC
LD A,B
Put the result of that subroutine into Register A for testing
51AD
OR A
Set the flags
51AE
RET
RETURN

51AF-51C8 – Table of some values

51AF
DEFM ‘ ‘
This is just a local buffer of 6 spaces for holding parsed command
51B5
DEFM ‘CMD’
51B8
DEFB 03H
Terminator
5189
DEFM ‘DOS READY’
51C2
DEFB 0DH
Terminator
51C3
DEFM ‘WHAT’
51C8
DEFB 0DH
Terminator