2003H – UE ERROR entry point.

2003H2004H
LD E,26H
Load register E with the ERROR code for a ?UE ERROR.
2005H-2007H
Go to the Level II BASIC error routine and display the appropriate error message.

2008H-2038H – LEVEL II BASIC AUTO ROUTINE

2008H-200AH
LD DE,000AH
Load DE with a default starting line number of ten.
200BH
PUSH DE
Save the default stack line number in DE to the stack.
200CH-200DH
Jump down to 2025H if this is the end of the AUTO statement (meaning that no parameters were provided).
200EH-2010H
If we are here, then there were parameters after the AUTO statement so we need to gosub to 1E4FH to evaluate the line number at the current location of the BASIC program pointer in HL and return with the result in DE.
2011H
EX DE,HL
Since there is no such Z-80 command as EX (SP),DE we now need to do some swapping to get DE into (SP). First, exchange the value of the line number in DE with the value of the current BASIC program pointer in HL.
2012H
EX (SP),HL
Next, exchange the default line number (to the stack from the above push of DE) with the line number that the user provided (in HL).
2013H-2014H
Jump down to 2026H if this is the end of the AUTO statement (meaning that only 1 parameter was provided).
2015H
EX DE,HL
Load HL with the value of the current BASIC program pointer in DE.
2016H-2017H
RST 08H
2C
If we are here, then we have an AUTO command with one parameter (starting line number) and we have not finished with the command. Since the only valid addition to that would be a trailing ,, we need to test the current BASIC program pointer in HL for a COMMA (=2CH), by calling the COMPARE SYMBOL at RST 08H.

NOTE: The RST 08H routine compares the symbol in the input string pointed to by HL register to the value in the location following the RST 08 call.
  • If there is a match, control is returned to the next execution address (i.e, the RST 08H instruction + 2) with the next symbol in the A Register and HL incremented by one.
  • If the two characters do not match, a syntax error message is given and control returns to the Input Phase).
2018H
EX DE,HL
If we are here, then it matched (a ?SN ERROR would have occurred otherwise) so load DE with the value of the current BASIC program pointer in HL.
2019H-201BH
LD HL,(40E4H)
Load HL with the last AUTO increment value.
Note: 40E4H-40E5H holds AUTO increment.
201CH
EX DE,HL
Exchange the value of the current BASIC program pointer in DE with the last AUTO increment value in HL.
201DH-201EH
Jump to 2025H if this is the end of the BASIC statement (meaning, we got AUTO nn, but no further parameter).
201FH-2021H
If we are here, there was a second parameter so we gosub to 1E5AH.
NOTE:
  • The routine at 1E5A converts the ASCII string pointed to by HL to an integer deposited into DE. If the routine finds a non-numerica character, the conversion is stopped
2022H-2024H
If that prior gosub found a non-numeric character it aborted with a NZ, so if there is a NZ, jump to 1997H to show a ?SN ERROR.
2025H
EX DE,HL
Exchange the AUTO increment number in DE with the value of the current BASIC program pointer in HL.
2026H
LD A,H
Load register A with the MSB of the AUTO increment number in register H. (This is step 1 of a test to see if HL is zero)
2027H
OR L
Combine the LSB of the AUTO increment number in register L with the MSB of the AUTO increment number in register A. (This is step 2 of a test to see if HL is zero)
2028H-202AH
That all tested the value of HL to see if it was zero. If it was, jupm to 1E4AH to show a ?FC ERROR message.
202BH-202DH
LD (40E4H),HL
Save the value of the AUTO increment number in HL.
Note: 40E4H-40E5H holds AUTO increment.
202EH-2030H
LD (40E1H),A
Set the AUTO flag to non-zero. We know A is non-zero because we would have jumped 2 instruction ago if it was.
2031H
POP HL
Get the starting line number from the stack and put it in HL.
2032H-2034H
LD (40E2H),HL
Save the line number in HL as the next AUTO line number.
Note: 40E2H-40E3H holds Current BASIC line number.
2035H
POP BC
Clean up the stack.
2036H-2038H
Jump to the Level II BASIC command mode.

2039H-2066H – LEVEL II BASIC IF ROUTINE

2039H-203BH
Gosub to 2337H to evaluate the BASIC expression pointed to by HL and return with the result in REG 1.
203CH
LD A,(HL)
Load register A with the character at the location of the current BASIC program pointer in HL.
203DH-203EH
CP 2CH
Check to see if the character at the location of the current BASIC program pointer in register A is a ,.

Notes:

  • 2C is a , in ASCII
  • A CP will return Z if there is a match against Register A, and NZ if not a match against Register A.
203FH-2041H
If the character at the location of the current BASIC program pointer in register A is a , then go bump the value of the current BASIC program pointer in HL until it points to the next character.
2042H-2043H
CP CAH
Check to see if the character at the location of the current BASIC program pointer in register A is a THEN token

Notes:

  • CAH is a THEN token.
  • A CP will return Z if there is a match against Register A, and NZ if not a match against Register A.
2044H-2046H
If Z flag is set, the character at the location of the current BASIC program pointer in register A is a THEN token, so we need to bump the value of the current BASIC program pointer until it points to the next character.
2047H
DEC HL
Decrement the value of the current BASIC program pointer in HL so that we are still positioned at the THEN token.
2048H
PUSH HL
Save the value of the current BASIC program pointer to the stack.
2049H-204BH
Gosub to 0994H to see if the expression after the IF token was true or false.
204CH
POP HL
Restore the address of the current position in the current statement (from the stack) into HL.
204DH-204EH
Jump down to 2056H if the expression was false.
204FH
RST 10H
We need the next character in the BASIC program so call the EXAMINE NEXT SYMBOL routine at RST 10H.
NOTE:
  • The RST 10H routine loads the next character from the string pointed to by the HL register into the A-register and clears the CARRY flag if it is alphabetic, or sets it if is alphanumeric.
  • Blanks and control codes 09H and 0BH are ignored causing the following character to be loaded and tested.
  • The HL register will be incremented before loading any character therfore on the first call the HL register should contain the string address minus one.
  • The string must be terminated by a byte of zeros.
2050H-2052H
Jump to the GOTO routine if the character at the location of the current BASIC program pointer in HL is numeric.
2053H-2055H
Jump to the execution driver at 1D5FH to evaluate the rest of the statement string.
2056H-2057H
LD D,01H
Load register D with the scan counter (as we will need to count the number of times to scan to the end of line).
2058H-205AH
Go scan the BASIC statement.
205BH
OR A
Check to see if this is the end of the BASIC instruction.
205CH
RET Z
Return if this is the end of the BASIC statement.
205DH
RST 10H
We need the next character in the BASIC program so call the EXAMINE NEXT SYMBOL routine at RST 10H.
NOTE:
  • The RST 10H routine loads the next character from the string pointed to by the HL register into the A-register and clears the CARRY flag if it is alphabetic, or sets it if is alphanumeric.
  • Blanks and control codes 09H and 0BH are ignored causing the following character to be loaded and tested.
  • The HL register will be incremented before loading any character therfore on the first call the HL register should contain the string address minus one.
  • The string must be terminated by a byte of zeros.
205EH-205FH
CP 95H
Check to see if the character at the location of the current BASIC program pointer in register A is an ELSE token.

Notes:

  • 95H is a ELSE in ASCII
  • A CP will return Z if there is a match against Register A, and NZ if not a match against Register A.
2060H-2061H
Loop back to 2058H until an ELSE token is found.
2062H
DEC D
Decrement the value of the scan counter.
2063H-2064H
Loop back to 2058H until all of the ELSE tokens have been found.
2065H-2066H
Jump to 204FH to evaluate the rest of the expression.

2067H-206EH – LEVEL II BASIC LPRINT ROUTINE – FOR v1.0 ONLY

2067H-2068H
LD A,01H
Load register A with the output device code for the printer.
2069H-206BH
LD (409CH),A
Save the value in register A as the current output device type number.
  • Note: 409CH holds the current output device flag:
    • -1=cassette,
    • 0=video; or
    • 1=printer.
206CH-206EH
Jump to 209BH to analyze the rest of the statement.

206FH-2177H – LEVEL II BASIC PRINT@ ROUTINE – FOR v1.0 ONLY

206FH-2071H
Call the DOS exit link at 41CAH.
2072H-2073H
CP 40H
Check the character at the location of the current BASIC program pointer in register A to see if it’s an @.

Notes:

  • 40H is a @ in ASCII
  • A CP will return Z if there is a match against Register A, and NZ if not a match against Register A.
2074H-2075H
Jump to 208FH if the character at the location of the current BASIC program pointer in register A isn’t an @.
2076H-2078H
Gosub to 2B01H to evaluate the PRINT@ expression (which is at the location of the current BASIC program pointer in HL and return with the result in DE).
2079H-207AH
CP 04
Check to see if the location in DE is greater than 1023H. A CP will return Z if there is a match against Register A, and NZ if not a match against Register A.
207BH-207DH
JP NC,1E4AH
If that check resulted in no CARRY flag, jump to 1E4AH to show a ?FC error.
207EH
PUSH HL
Push the current code string address (held in HL) to the stack.
207FH-2081H
LD HL,3C00H
Load HL with the start of the display area.
2082H
ADD HL,DE
Add DE to HL so that HL now will be the start of the diplay area PLUS the PRINT@ offset position.
2083H-2085H
LD (4020H),HL
Store the cursor position of the screen address matching the PRINT@ position into the display DCB held in memory location 4020H.
  • 4020H-4021H: Holds the video memory address of the current cursor position.
2086H
LD A,E
E is the current position within the line.
2087H-2088H
AND 3FH
Make it not exceed 63 and then save it ….
2089H
LD (40A6H),A
… into the current cursor offset (which is held in 40A6H).
208CH
POP HL
Restore the code string address to HL
208DH
RST 08H
2C
At this point we have a PRINT@nnnn so the only valid next character is a , so we need to call RST 08H to check against 2C, the code for comma.

NOTE: The RST 08H routine compares the symbol in the input string pointed to by HL register to the value in the location following the RST 08 call.
  • If there is a match, control is returned to the next execution address (i.e, the RST 08H instruction + 2) with the next symbol in the A Register and HL incremented by one.
  • If the two characters do not match, a syntax error message is given and control returns to the Input Phase).
208FH
CP 23H
We also need to look for a # character

Notes:

  • 23H is a # in ASCII
  • A CP will return Z if there is a match against Register A, and NZ if not a match against Register A.
2091H
JR NZ,209BH
If it is not a # character (meaning this is not a PRINT#, jump to 209BH.
2093H
CALL 0284H
If we are here, we had a PRINT# so gosub to 0284H to analyze the rest of the string
2096H
LD A,80H
Set A to 80H (the write to cassette flag).
2098H
LD (409CH),A
Load the cassette flag at (409CH) with 80H.
209BH
DEC HL
Backspace over the previous symbol in the input stream.
209CH
RST 10H
Re-analyze the next character in the input stream.
209DH
CALL Z,20FEH
If that test resulted in a zero, gosub to 20FEH to print a carriage return/end of statement and then flush the line to the device.
20A0H
JP Z,2169H
Jump to 2169H to write the sync bytes and clear output.
20A3H
CP 0BFH
Compare the device flag.
  • NOTE: A CP will return Z if there is a match against Register A, and NZ if not a match against Register A.)
20A5H
JP Z,2CBDH
… and return to the execution driver.
20A8H
CP BCH
Test for a TAB token.

Notes:

  • BCH is a TAB in ASCII
  • A CP will return Z if there is a match against Register A, and NZ if not a match against Register A.
20AAH
JP Z,2137H
and if it is a TAB token (meaning the command is PRINT TAB, jump down to 2137H.
20ADH
PUSH HL
Continuing on a PRINT#, save the current position in the input stream into the stack.
20AEH
CP 2CH
Test for a ,.

Notes:

  • 2CH is a , in ASCII
  • A CP will return Z if there is a match against Register A, and NZ if not a match against Register A.
20B0H
JP Z,2108H
If there is a comma, jump down to 2108H to get the next item.
20B3H
CP 3BH
Since its not a comma, next we need to check for a ;.

Notes:

  • 3BH is a ; in ASCII
  • A CP will return Z if there is a match against Register A, and NZ if not a match against Register A.
20B5H
If it is a ;, jump down to 2164H to process.
20B8H
POP BC
It wasn’t a , or a ; so restore the current address in the input stream (from the stack) into BC.
20B9H
CALL 2337H
Get the address or value of the next item to be printed.
20BCH
PUSH HL
Save the address of the terminal symbol.
20BDH
RST 20H
Check its data type with a call to RST 20H.
NOTE: The RST 20H routine determines the type of the current value in REG 1 and returns a combination of STATUS flags and unique numeric values in the A Register according to the data mode flag (40AFH).

The results are returned as follows:
  • Integer = NZ/C/M/E and A is -1
  • String = Z/C/P/E and A is 0
  • Single Precision = NZ/C/P/O and A is 1
  • and Double Precision is NZ/NC/P/E and A is 5.
20BEH
JR Z,20F2H
If it is a string, jump down to 20F2H.
20C0H
CALL 0FBDH
Gosub to the routine at 0FBDH to convert the binary to ASCII and move to the print buffer.
20C3H
CALL 2865H
Gosub to the routine at 2865H to build a literal string pool entry for the ASCII number.
20C6H
CALL 41CDH
Gosub to a DOS exit if needed
20C9H
LD HL,(4121H)
Put the address of the current print string into HL.
20CCH
LD A,(409CH)
Get the output device type flag and put it into A.
  • Note: 409CH holds the current output device flag:
    • -1=cassette,
    • 0=video; or
    • 1=printer.
20CFH
OR A
Test the output device type flag.
20D0H
JP M,20E9H
If we writing to a cassette (i.e., PRINT#) jump to 20E9H.
20D3H
JR Z,20DDH
If, instead, we do NOT have a LPRINT, jump down to 20DDH.
20D5H-20D7H
LD A,(409BH)
If we are here, we have a LPRINT so load A with the current carriage position.
Note: 409BH holds the printer carriage position.
20D8H
ADD A,(HL)
Add the length of the string to be sent to the printer at the location of the memory pointer in HL to the current carriage position in register A.
20D9H-20DAH
CP 84H
Check to see if the adjusted length in register A is greater than 132.
  • NOTE: A CP will return Z if there is a match against Register A, and NZ if not a match against Register A.)
20DBH-20DCH
Jump forward to 20E6H.
20DDH-20DFH
LD A,(409DH)
Load register A with the video line size.
Note: 409DH holds the size of line on the video display.
20E0H
LD B,A
Load register B with the video line size in register A.
20E1H-20E3H
LD A,(40A6H)
Load register A with the current video line position.
Note: 40A6H holds the current cursor line position.
20E4H
ADD A,(HL)
Add the length of the string to be sent to the video display at the location of the memory pointer in HL to the value of the current video line position in register A.
20E5H
CP B
Check to see if the length in register A is greater than the video line length.
  • NOTE: A CP will return Z if there is a match against Register A, and NZ if not a match against Register A.)
20E6H-20E8H
If NC is set, the new line will overflow the buffer so send a carriage return to the current output device.
20E9H-20EBH
Go send the string to the current output device.
20ECH-20EDH
LD A,20H
Load register A with a space.
20EEH-20F0H
Go send the space in register A to the current output device.
20F1H
OR A
Check to see if register A is equal to zero.
20F2H-20F4H
If necessary go send the string to the current output device.
20F5H
POP HL
Restore the current code string to HL
20F6H-20F8H
For ROM v1.0 – Loop to 209BH until an end of statement code is found. Going to 209BH parses only for PRINT TAB or PRINT #, but not PRINT @, so it was not possible, under ROM v1.0, to have a PRINT@ appear later in a PRINT command than a PRINT TAB or PRINT #.
*20F6H-20F8H
For ROM v1.2 – Loop to 207CH until an end of statement code is found. Going all the way back to 207CH will also test for a PRINT @, thus permitting a PRINT @ to appear other than first.
20F9H-20FBH
LD A,(40A6H)
Load register A with the number of characters printed on the current line.
Note: 40A6H holds the current cursor line position.
20FCH
OR A
Check to see if any characters have been printed on the current line.
20FDH
RET Z
Return out of this routine if we are at the start of a line.

20FEH – This routine outputs a carriage return (0DH) to a device determined by flag stored at (409CH).

  • NOTE: This routine may be CALLed at 20F9H, in which case it will not perform the above action if the video display cursor is already positioned at the beginning of a line, as determined by checking the contents of the cursor position flag at 40A6H (if zero, cursor is at start of line). This routine CALLs the routine at 032AH and also CALLs a Disk BASIC link at 41D0H.
20FEH-20FFH
LD A,0DH
Otherwise, we need to skip to the next line so load register A with a carriage return.
2100H-2102H
Go send the carriage return in register A to the current output device.
2103H-2105H
Call the DOS link at 41D0H.
In NEWDOS 2.1, this is called when skipping to next line on a video during a BASIC output operation.
2106H
XOR A
Zero register A and the carry flags.
2107H
RET
Return back to the calling routine.

2108H – This is the jump point for a continuation of the PRINT# code.

2108H-210AH
Call the DOS link at 4103H.
In NEWDOS 2.1, this is called at the start of PRINT on cassette and during PRINT TAB.
210BH-210DH
LD A,(409CH)
Load register A with the value of the current output device flag..
  • Note: 409CH holds the current output device flag:
    • -1=cassette,
    • 0=video; or
    • 1=printer.
210EH
OR A
Test the value of the current output device flag in register A.
  • M will be set if the value in A is negative.
  • P will be set if the value in A is positive or zero.
210FH-2111H
Jump down a few instructions to 2119H if the printer or the video display is the current output device.
2112H-2113H
LD A,2CH
So now that we know the current device is cassette, we will load register A with a ,.
2114H-2116H
Send the , in register A to current output device. In this case, it is the cassette recorder because we otherwise would have jumped away at 210FH.
2117H-2118H
Jump forward to 2164H to fetch the next character from the code string.
2119H-211AH
We landed here from 210FH knowing that the current output device flag was either video or printer. Now we need to break that down too, so if the device flag is the video display, jump down to 2123H.
211BH-211DH
LD A,(409BH)
We’re here because the output device is a printer. First, load register A with the current carriage position.
Note: 409BH holds the printer carriage position.
211EH-211FH
CP 70H
Check to see if the current carriage position in register A is greater than 112.
  • NOTE: A CP will return Z if there is a match against Register A, and NZ if not a match against Register A.)
2120H-2122H
Jump forward a few instructions to 212BH.
2123H-2125H
LD A,(409EH)
We were jumped to this point because the output device is the video display. So load register A with the video line length.
Note: 409EH holds the size of line on the printer.
2126H
LD B,A
Load register B with the video line length in register A.
2127H-2129H
LD A,(40A6H)
Load register A with the current video line position.
Note: 40A6H holds the current cursor line position.
212AH
CP B
Test to see if there is room on this line by checking to see if the current video line position in register A is equal to the video line length in register B.
  • NOTE: A CP will return Z if there is a match against Register A, and NZ if not a match against Register A.)
212BH-212DH
If the NC is set, there is no room on the current line, so we need to gosub to 20FEH to print a carriage return on the current output device.
212EH-212FH
If this is the end of the line on the current output device jump forward to 2164H.
2130H-2131H
SUB 10H
Check to see if there are at least 16 spaces left on the current line for the current output device.
2132H-2133H
Loop back until there are at least 16 spaces left on the current line.
2134H
CPL
Figure the number of spaces to be sent to the current output device.
2135H-2136H
Jump to 215AH to print those spaces/blanks.

2137H – TAB logic.

  • This routine is the TAB function for video or printer (determined by flag at 409CH). On entry: E register contains desired TAB position, HL points to start of message to be displayed (or zero byte if no message). This routine does extensive string processing and may not be the most efficient method of achieving the desired result, particularly if it is desired only to tab over a number of spaces. Also, this routine CALLs several Disk BASIC links which may have to be “plugged”. 2169H – Reset device type flag at 409CH to zero (output to video display>, also turns off cassette drive if necessary. CALLs Disk BASIC link at 41BEH prior to return.
2137H-2139H
Gosub forward to 2B1BH to evaluate the tab number at the location of the current BASIC program pointer in HL and return with the result in register A.
213AH-213BH
AND 3FH
The results are in A so mask the tab number in register A so that it doesn’t exceed 63.
213CH
LD B,A
Load register B with the value of the tab number from register A.
213DH-213EH
RST 08H
29H
At this point, we have a TAB(nn, so the next character needs to be a ). Since the character at the location of the current BASIC program pointer in HL must be a “)”, call the COMPARE SYMBOL at RST 08H.

NOTE: The RST 08H routine compares the symbol in the input string pointed to by HL register to the value in the location following the RST 08 call.
  • If there is a match, control is returned to the next execution address (i.e, the RST 08H instruction + 2) with the next symbol in the A Register and HL incremented by one.
  • If the two characters do not match, a syntax error message is given and control returns to the Input Phase).
213FH
DEC HL
Decrement the value of the current BASIC program pointer in HL so that it points to the (.
  • To use a ROM call to locate the cursor at position n on the current display line, where n is an integer between 0 and 3FH, inclusive, first load the E register with the value of n and then load the HL register pair with the address of a zero byte in memory. Once that’s done CALL 213FH.
    • NOTE 1: The cursor position cannot be moved backward by this procedure. If n is not greater than the current cursor position on the line, no change will occur.
    • NOTE 2: To locate the cursor at a given position on the screen (the function of the PRINT@ command in BASIC), the simplest procedure is to modify the cursor position bytes, which are located at 4020H-4021H. The address contained in these memory cells is that of the position in video memory (3C00H-3FFFH) at which the (abstract) cursor resides. This cursor position controls subsequent printing via the subroutine at 28A7H
    • DISK SYSTEM CAUTION: The subroutine at 213FH has three exits to DISK BASIC, with RAM transfer points at 41BEH, 41C1H, and 41D3H. To use this routine safely, either be certain that DISK BASIC is in place, or have your assembly language program fill locations 41BEH, 41C1H, and 41D3H with RET’s (C9H), before calling the routine.
2140H
PUSH HL
Save the value of the current BASIC program pointer in HL to the stack.
2141H-2143H
Call the DOS link at 41DCH.
2144H-2146H
LD A,(409CH)
Load register A with the value of the current output device flag..
  • Note: 409CH holds the current output device flag:
    • -1=cassette,
    • 0=video; or
    • 1=printer.
2147H
OR A
Test the value of the current output device flag in register A.
2148H-214AH
Display a ?FC ERROR message if the current output device is the cassette recorder.
214BH-214DH
Jump forward a few instructions to 2153H if the current output device is the video display.
214EH-2150H
LD A,(409BH)
Since we have already jumped away if the current output device is to cassette or screen, if we are here we know that this is to go to the printer, so load register A with the current carriage position.
Note: 409BH holds the printer carriage position.
2151H-2152H
Jump over the next instruction (which is a video instruction).
2154H-2155H
LD A,(40A6H)
Load register A with the current video line position.
Note: 40A6H holds the current cursor line position.
2156H
CPL
When we land here, A holds either the current carriage position (printer) or the current line position (video). Regardless, complement (make negative) that value.
2157H
ADD A,E
Add the tab number in register B to the adjusted line position in register A so that A=-current position + tab.
2158H-2159H
Jump forward a few instructions to 2164H to skip over the actual TAB effectuation routine if the tab number in register B is less than the line position in register A.
215AH
INC A
Bump the number of spaces to be printed in register A.
215BH
LD B,A
Load register B with the number of spaces to be printed in register A.
215CH-215DH
LD A,20H
Load register A with a space.
215EH-2160H
Send the space in register A to the current output device.
2161H
DEC B
Decrement the value of the space counter in register B.
2162H-2163H
Loop back to 215EH until all of the spaces have been displayed/printed.
2164H
POP HL
Restore the position in of the current BASIC program pointer (from the stack) into HL.
2165H
RST 10H
We need the next character in the BASIC program so call the EXAMINE NEXT SYMBOL routine at RST 10H.
NOTE:
  • The RST 10H routine loads the next character from the string pointed to by the HL register into the A-register and clears the CARRY flag if it is alphabetic, or sets it if is alphanumeric.
  • Blanks and control codes 09H and 0BH are ignored causing the following character to be loaded and tested.
  • The HL register will be incremented before loading any character therfore on the first call the HL register should contain the string address minus one.
  • The string must be terminated by a byte of zeros.
2166H-2168H
Jump back to 20A0H to process the rest of the PRINT TAB statement.

2169H – This routine resets the device type flag at 409CH to zero (output to video display), also turns off cassette drive if necessary. CALLs Disk BASIC link at 41BEH prior to return.

2169H-216BH
LD A,(409CH)
If we land here, we need to turn off the cassette and reset the current output device to be video. To do this we first load register A with the current output device flag..
  • Note: 409CH holds the current output device flag:
    • -1=cassette,
    • 0=video; or
    • 1=printer.
216CH
OR A
Test the value of the current output device flag in register A. If the M flag is set, A was negative.
216DH-216FH
If the current output device flag is the cassette recorder, gosub to 01F8H to turn it off.
2170H
XOR A
Clear Register A (which will set A to 0) and clear the status flags.
2171H-2173H
LD (409CH),A
Save the value in register A (which is 0) as the current value of the output device flag.
  • Note: 409CH holds the current output device flag:
    • -1=cassette,
    • 0=video; or
    • 1=printer.
2174H-2176H
Call the DOS link at 41BEH.
In NEWDOS 2.1, this initializes the system output device.
2177H
RET
Return.

2178H-217EH – MESSAGE STORAGE LOCATION FOR REDO MESSAGE

2178H-217EH
“?REDO”
The ?REDO message is stored here.

217FH-2285H – LEVEL II BASIC INPUT AND READ ROUTINES

217FH-2181H
LD A,(40DEH)
Load register A with the read flag.
Note: 40DEH holds READ flag.
2182H
OR A
Check to see if the read flag is set.
2183H-2185H
If the read flag is set, go give a ?SN ERROR.
2186H-2188H
LD A,(40A9H)
Now we know the read flag is NOT set, so we need to load register A with the input type flag.
Note: 40A9H holds Cassette input flag.
2189H
OR A
Check to see if the cassette recorder is the current input device.
218AH-218BH
LD E,2AH
Load register E with the ?FD ERROR code.
218CH-218EH
If the current input device is the cassette recorder, go give a ?FD ERROR.
218FH
POP BC
Clean up the stack.
2190H-2192H
LD HL,2178H
Load HL with the starting address of the ?REDO message.
2193H-2195H
We need to display the ?REDO, so we call the WRITE MESSAGE routine at 28A7H.
NOTE:
  • The routine at 28A7 displays the message pointed to by HL on current system output device (usually video).
  • The string to be displayed must be terminated by a byte of machine zeros or a carriage return code 0D.
  • If terminated with a carriage return, control is returned to the caller after taking the DOS exit at 41D0H (JP 5B99H).
2196H-2198H
LD HL,(40E6H)
Get the value of the current BASIC program pointer in HL.
Note: 40E6H-40E7H holds Temporary storage location.
2199H
RET
Return out of this routine.

219AH – INPUT logic

219AH-219CH
Check to see if there is an illegal direct in the input statement.
219DH
LD A,(HL)
Load register A with the character at the location of the current BASIC program pointer in HL.
219EH-21A0H
Call the DOS link at 41D6H.
In NEWDOS 2.1 this is called at the beginning of INPUT processing.
21A1H-21A2H
SUB 23H
Check to see if the character at the location of the current BASIC program pointer in register A is a #.
21A3H-21A5H
LD (40A9H),A
Set the current input device flag for the cassette recorder.
Note: 40A9H holds cassette input flag.
21A6H
LD A,(HL)
Load register A with the character at the location of the current BASIC program pointer in HL.
21A7H-21A8H
Jump to 21C9H if there is keyboard input.
21A9H-21ABH
If we are here, then the input is coming from the cassette, so gosub to 0293H to read the cassette leader and find the sync byte.
21ACH
PUSH HL
Save the current BASIC program pointer in HL to the stack.
21ADH-21AEH
LD B,FAH
Load register B with the size of the input buffer.
21AFH-21B1H
LD HL,(40A7H)
Load HL with the starting address of the input buffer.
Note: 40A7H-40A8H holds the input Buffer pointer.
21B2H-21B4H
Calls the READ ONE BYTE FROM CASSETTE routine at 0235H (which reads one byte from the cassette drive specified in register A, and returns the byte in register A).
21B5H
LD (HL),A
Save the byte read from the cassette recorder in register A at the location of the input buffer pointer in HL.
21B6H
INC HL
Bump the value of the input buffer pointer in HL.
21B7H-21B8H
CP 0DH
Check to see if the character read from the cassette recorder in register A is a carriage return.

Notes:

  • 0DH is a ENTER in ASCII
  • A CP will return Z if there is a match against Register A, and NZ if not a match against Register A.
21B9H-21BAH
Jump out of this routine if the character read from the cassette recorder in register A is a carriage return.
21BBH-21BCH
DJNZ 21B2H
Loop back to 21B2H until the input buffer is full.
21BDH
DEC HL
Decrement the value of the input buffer pointer in HL.
21BEH-21BFH
LD (HL),00H
Save a zero at the location of the input buffer pointer in HL.
21C0H-21C2H
Gosub to 01F8H to put a 00H at the end of the tape and turn the cassette recorder off.
21C3H-21C5H
LD HL,(40A7H)
Load HL with the starting address of the input buffer.
Note: 40A7H-40A8H holds the input Buffer pointer.
21C6H
DEC HL
Decrement the value of the input buffer pointer in HL.
21C7H-21C8H
Jump to 21EBH to store a comma there so we can use the READ processing.
21C9H-21CBH
LD BC,21DBH
Load BC with a return address of 21DBH.
21CCH
PUSH BC
Save the value of the return address in BC to the stack.
21CDH-21CEH
CP 22H
Check to see if the character at the location of the current BASIC program pointer in register A is a quote.

Notes:

  • 22H is a " in ASCII
  • A CP will return Z if there is a match against Register A, and NZ if not a match against Register A.
21CFH
RET NZ
Return to 21DBH if the character at the location of the current BASIC program pointer in register A isn’t a quote.
21D0H-21D2H
Go set up pointers for the prompting message in the temporary string work area.
21D3H-21D4H
RST 08H
3B
Since the character at the location of the current BASIC program pointer in HL must be a “;”, call the COMPARE SYMBOL routine at RST 08H.

NOTE: The RST 08H routine compares the symbol in the input string pointed to by HL register to the value in the location following the RST 08 call.
  • If there is a match, control is returned to the next execution address (i.e, the RST 08H instruction + 2) with the next symbol in the A Register and HL incremented by one.
  • If the two characters do not match, a syntax error message is given and control returns to the Input Phase).
21D5H
PUSH HL
Save the value of the current BASIC program pointer in HL to the stack.
21D6H-21D8H
Go display the prompting message.
21D9H
POP HL
Restore the code string address (from the stack) into HL.
21DAH
RET
Return to 21DBH.
21DBH
PUSH HL
Save the value of the current BASIC program pointer in HL to the stack.
21DCH-21DEH
Print the ? prompt and get the input from the keyboard.
21DFH
POP BC
Get the value of the current BASIC program pointer from the stack and put it in BC.
21E0H-21E2H
Jump back to 1DBEH if the BREAK key was pressed.
21E3H
INC HL
Bump the value of the input buffer pointer in HL.
21E4H
LD A,(HL)
Load register A with the character at the location of the input buffer pointer in HL.
21E5H
OR A
Test the value of the character at the location of the input buffer pointer in register A.
21E6H
DEC HL
Decrement the value of the input buffer pointer in HL.
21E7H
PUSH BC
Save the value of the current BASIC program pointer in BC to the stack.
21E8H-21EAH
Jump if the character at the location of the input buffer pointer in register A is an end of the input character.
21EBH-21ECH
LD (HL),2CH
Save a comma at the location of the current input buffer pointer in HL.
21EDH-21EEH
Jump to 21F4H (which address uses a Z-80 trick).

21EFH – READ logic

21EFH
PUSH HL
Save the current BASIC program pointer in HL.
21F0H-21F2H
LD HL,(40FFH)
Load HL with the location of the last DATA statement read.
Note: 40FFH-4100H holds READ pointer.
21F3H-21F4H
OR AFH
Set register A to a non-zero value if entered from the READ routine and zero if entered from the INPUT routine.
21F5H-21F7H
LD (40DEH),A
Save the value of the input type flag in register A.
Note: 40DEH holds READ flag.
21F8H
EX (SP),HL
Exchange the start of the input pointer in HL with the current BASIC program pointer to the stack.
21F9H-21FAH
Skip over the next instruction.
21FBH-21FCH
RST 08H
2C
Since the character at the location of the current BASIC program pointer in HL must be a ,, call the COMPARE SYMBOL at RST 08H.

NOTE: The RST 08H routine compares the symbol in the input string pointed to by HL register to the value in the location following the RST 08 call.
  • If there is a match, control is returned to the next execution address (i.e, the RST 08H instruction + 2) with the next symbol in the A Register and HL incremented by one.
  • If the two characters do not match, a syntax error message is given and control returns to the Input Phase).
21FDH-21FFH
Call the FIND ADDRESS OF VARIABLE routine at 260DH which searches the Variable List Table for a variable name which matches the name in the string pointed to in HL, and return the address of that variable in DE (and if there is no variable, it creates it, zeroes it, and returns THAT location).
2200H
EX (SP),HL
Exchange the value of the current BASIC program pointer in HL with the start of the input buffer pointer to the stack.
2201H
PUSH DE
Save the variable’s address in DE to the stack.
2202H
LD A,(HL)
Load register A with the character at the location of the input buffer pointer in HL.
2203H-2204H
CP 2CH
Check to see if the character at the location of the input buffer pointer register A is a ,.
  • NOTE: A CP will return Z if there is a match against Register A, and NZ if not a match against Register A.)
2205H-2206H
Jump to 222DH if the character at the location of the input buffer pointer in register A is a ,.
2207H-2209H
LD A,(40DEH)
Load register A with the input type flag.
Note: 40DEH holds READ flag.
220AH
OR A
Check for READ or INPUT.
220BH-220DH
Jump to 2296H if the input type flag in register A indicates READ.
220EH-2210H
LD A,(40A9H)
Load register A with the value of the cassette input flag.
Note: 40A9H holds Cassette input flag.
2211H
OR A
Check to see if the input is from the cassette recorder.
2212H-2213H
LD E,06H
Load register E with an ?OD ERROR code.
2214H-2216H
Go to the Level II BASIC error routine and display an ?OD ERROR message if the input is from the cassette recorder.
2217H-2218H
LD A,3FH
Load register A with a “?”.
2219H-221BH
Gosub to 032AH which is a general purpose output routine that outputs a byte from the A register to video, tape or printer (based on what is in 409CH).
221CH-221EH
Go get the keyboard input.
221FH
POP DE
Get the address of the variable to be set from the stack and put it in DE.
2220H
POP BC
Get the value of the current BASIC program pointer from the stack and put it in BC.
2221H-2223H
Jump to 1DBEH if the BREAK key was pressed.
2224H
INC HL
Bump the value of the input buffer pointer in HL.
2225H
LD A,(HL)
Load register A with the character at the location of the input buffer pointer in HL.
2226H
OR A
Check to see if the character at the location of the input buffer pointer in register A is an end of the input character.
2227H
DEC HL
Decrement the value of the input buffer pointer in HL.
2228H
PUSH BC
Save the value of the current BASIC program pointer in BC to the stack.
2229H-222BH
Jump if the character at the location of the input buffer pointer in register A is an end of the input character.
222CH
PUSH DE
Save the variable’s address in DE to the stack.
222DH-222FH
Call the DOS link at 41DCH.
In NEWDOS 2.1, this is called during READ processing when a variable has been read.
2230H
RST 20H
We need to check the value of the current number type flag, so we call the TEST DATA MODE routine at RST 20H.
NOTE: The RST 20H routine determines the type of the current value in REG 1 and returns a combination of STATUS flags and unique numeric values in the A Register according to the data mode flag (40AFH).

The results are returned as follows:
  • Integer = NZ/C/M/E and A is -1
  • String = Z/C/P/E and A is 0
  • Single Precision = NZ/C/P/O and A is 1
  • and Double Precision is NZ/NC/P/E and A is 5.
2231H
PUSH AF
Save the number type of the variable to the stack.
2232H-2233H
If that test shows we do NOT have a STRING, jump to 224DH.
2234H
RST 10H
We need the next character in the BASIC program so call the EXAMINE NEXT SYMBOL routine at RST 10H.
NOTE:
  • The RST 10H routine loads the next character from the string pointed to by the HL register into the A-register and clears the CARRY flag if it is alphabetic, or sets it if is alphanumeric.
  • Blanks and control codes 09H and 0BH are ignored causing the following character to be loaded and tested.
  • The HL register will be incremented before loading any character therfore on the first call the HL register should contain the string address minus one.
  • The string must be terminated by a byte of zeros.
2235H
LD D,A
Load register D with the character at the location of the input buffer pointer in register A.
2236H
LD B,A
Load register B with the character at the location of the input buffer pointer in register A.
2237H-2238H
CP 22H
Check to see if the character at the location of the input buffer pointer in register A is a quote.
  • NOTE: A CP will return Z if there is a match against Register A, and NZ if not a match against Register A.)
2230H-223AH
Jump to 2240H if the character at the location of the input buffer pointer in register A is a quote.
223BH-223CH
LD D,3AH
Load D with the character :
223DH-223EH
LD B,2CH
Load register B with the character , (the scan character).
223FH
DEC HL
Decrement the value of the input buffer pointer in HL.
2240H-2242H
Go set up the pointers for the temporary string work area.
2243H
POP AF
Get the number type for the variable from the stack and put it in register A.
2244H
EX DE,HL
Load DE with the value of the input buffer pointer in HL.
2245H-2247H
LD HL,225AH
Load HL with the value of the return address.
2248H
EX (SP),HL
Exchange the value of the return address in HL with the value of the current BASIC program pointer to the stack.
2249H
PUSH DE
Save the value of the input buffer pointer in DE to the stack.
224AH-224CH
Go set the variable to the value of the string.
224DH
RST 10H
We need the next character in the BASIC program so call the EXAMINE NEXT SYMBOL routine at RST 10H.
NOTE:
  • The RST 10H routine loads the next character from the string pointed to by the HL register into the A-register and clears the CARRY flag if it is alphabetic, or sets it if is alphanumeric.
  • Blanks and control codes 09H and 0BH are ignored causing the following character to be loaded and tested.
  • The HL register will be incremented before loading any character therfore on the first call the HL register should contain the string address minus one.
  • The string must be terminated by a byte of zeros.
224EH
POP AF
Load register A with the number type for the variable to be set.
224FH
PUSH AF
Save the value in AF to the stack.
2250H-2252H
LD BC,2243H
Load BC with the value of the return address.
2253H
PUSH BC
Save the return address in BC to the stack.
2254H-2256H
If the current number type is integer or single precision, call the ASCII TO BINARY routine at 0E6C (which converts the ASCII string pointed to by HL to binary with the result in REG 1 and the mode flag will have changed).
2257H-2259H
If the current number type is double precision, jump to the ASCII TO DOUBLE routine at 0E65H.
  • NOTE: 0E65H converts the ASCII string pointed to by HL to its double precision equivalent; with output left in REG 1).
225AH
DEC HL
Decrement the value of the input buffer pointer in HL.
225BH
RST 10H
We need the next character in the BASIC program so call the EXAMINE NEXT SYMBOL routine at RST 10H.
NOTE:
  • The RST 10H routine loads the next character from the string pointed to by the HL register into the A-register and clears the CARRY flag if it is alphabetic, or sets it if is alphanumeric.
  • Blanks and control codes 09H and 0BH are ignored causing the following character to be loaded and tested.
  • The HL register will be incremented before loading any character therfore on the first call the HL register should contain the string address minus one.
  • The string must be terminated by a byte of zeros.
225CH-225DH
Jump to 2263H if the character at the location of the input buffer pointer in HL is an end of the input character.
225EH-225FH
CP 2CH
Check to see if the character at the location of the input buffer pointer in register A is a comma.
  • NOTE: A CP will return Z if there is a match against Register A, and NZ if not a match against Register A.)
2260H-2262H
Jump to 217FH if the character at the location of the input buffer pointer in register A isn’t a comma.
2263H
EX (SP),HL
Exchange the value of the input buffer pointer in HL with the value of the current BASIC program pointer to the stack.
2264H
DEC HL
Decrement the value of the current BASIC program pointer in HL.
2265H
RST 10H
We need the next character in the BASIC program so call the EXAMINE NEXT SYMBOL routine at RST 10H.
NOTE:
  • The RST 10H routine loads the next character from the string pointed to by the HL register into the A-register and clears the CARRY flag if it is alphabetic, or sets it if is alphanumeric.
  • Blanks and control codes 09H and 0BH are ignored causing the following character to be loaded and tested.
  • The HL register will be incremented before loading any character therfore on the first call the HL register should contain the string address minus one.
  • The string must be terminated by a byte of zeros.
2266H-2268H
Go examine the next variable if the character at the location of the current BASIC program pointer in HL isn’t an end of the BASIC statement character.
2269H
POP DE
Clean up the stack.

226AH-226EH – For ROM v1.0 – Test for FD Error
Removed in ROM v1.2 because this was not needed.

Note: There is no ROM call to this location; it operates only as passing down from the above routine. A FD ERROR means that bad file data was read as part of the READ command reading from cassette.

226AH-226CH
LD A,(40A9H)
Load register A with the error flag.
Note: 40A9H holds Cassette input flag.
226DH
OR A
Check to see if the error flag in register A indicates an error.
226EH
RET Z
Return to the BASIC interpreter if the error flag in register A doesn’t indicate an error.

*226AH-226EH – For ROM v1.2 – Replaced with NOPS

226FH-2271H
LD A,(40DEH)
Load register A with the value of the input type flag.
Note: 40DEH holds READ flag.
2272H
OR A
Check to see if the input type is READ or INPUT.
2273H
EX DE,HL
Load DE with the value of the current BASIC program pointer in HL.
2274H-2276H
Jump if the input type flag is set for READ .
2277H
PUSH DE
Save the current BASIC program pointer in DE to the stack.
2278H-227AH
Call the DOS link at 41DFH.
In NEWDOS 2.1 this is called at the end of READ processing.
227BH
OR (HL)
Check to see if this is the end of the input.
227CH-227EH
LD HL,2286H
Load HL with the starting address of the ?EXTRA IGNORED message.
227FH-2281H
We need to display the ?EXTRA IGNORED message, so we call the WRITE MESSAGE routine at 28A7H.
NOTE:
  • The routine at 28A7 displays the message pointed to by HL on current system output device (usually video).
  • The string to be displayed must be terminated by a byte of machine zeros or a carriage return code 0D.
  • If terminated with a carriage return, control is returned to the caller after taking the DOS exit at 41D0H (JP 5B99H).
2282H
POP HL
Get the value of the current BASIC program pointer from the stack and put it in HL.
2283H-2285H
Go turn off the cassette recorder and return to the BASIC interpreter.

2286H-2295H – MESSAGE STORAGE LOCATION

2286H-2295H
“?Extra ignored”
The EXTRA IGNORED message is stored here.

2296H-22B5H – FIND THE NEXT DATA STATEMENT ROUTINE

2296H-2298H
Go find the next DATA statement.
2299H
OR A
Check to see if this is the end of the BASIC line.
229AH-229BH
Jump to 22AEH if the BASIC statement is terminated with a :.
229CH
INC HL
Bump the value of the current BASIC program pointer in HL.
229DH
LD A,(HL)
Load register A with the LSB of the line address at the location of the current BASIC program pointer in HL.
229EH
INC HL
Bump the value of the current BASIC program pointer in HL.
229FH
OR (HL)
Combine the MSB of the line address at the location of the current BASIC program in HL with the LSB of the line address in register A.
22A0H-22A1H
LD E,06H
Load register E with an ?OD ERROR code.
22A2H-22A4H
Go to the Level II BASIC error routine and display an OD ERROR message if this is the end of the BASIC program.
22A5H
INC HL
Bump the value of the current BASIC program pointer in HL.
22A6H
LD E,(HL)
Load register E with the LSB of the BASIC line number at the location of the current BASIC program pointer in HL.
22A7H
INC HL
Bump the value of the current BASIC program pointer in HL.
22A8H
LD D,(HL)
Load register D with the MSB of the BASIC line number at the location of the current BASIC program pointer in HL.
22A9H
EX DE,HL
Exchange the value of the current BASIC program pointer in HL with the value of the BASIC line number in DE.
22AAH-22ACH
LD (40DAH),HL
Save the BASIC line number in HL.
Note: 40DAH-40DBH holds DATA line number.
22ADH
EX DE,HL
Exchange the value of the current BASIC program pointer in DE with the value of the BASIC line number in HL.
22AEH
RST 10H
We need the next character in the BASIC program so call the EXAMINE NEXT SYMBOL routine at RST 10H.
NOTE:
  • The RST 10H routine loads the next character from the string pointed to by the HL register into the A-register and clears the CARRY flag if it is alphabetic, or sets it if is alphanumeric.
  • Blanks and control codes 09H and 0BH are ignored causing the following character to be loaded and tested.
  • The HL register will be incremented before loading any character therfore on the first call the HL register should contain the string address minus one.
  • The string must be terminated by a byte of zeros.
22AFH-22B0H
CP 88H
Check to see if the character at the location of the current BASIC program pointer in register A is a DATA token.
  • NOTE: A CP will return Z if there is a match against Register A, and NZ if not a match against Register A.)
22B1H-22B2H
Jump to 2296H (=find the next DATA statement routine) if the character at the location of the current BASIC program pointer in register A isn’t a DATA token.
22B3H-22B5H
Now we know that the current BASIC program pointer is pointing to a DATA token, so jump to 222DH.

22B6H-2336H – LEVEL II BASIC NEXT ROUTINE

22B6H-22B8H
LD DE,0000H
Load DE with the default variable address.
22B9H-22BBH
To see if there is a variable which follows the NEXT token, call the FIND ADDRESS OF VARIABLE routine at 260DH which searches the Variable List Table for a variable name which matches the name in the string pointed to in HL, and return the address of that variable in DE (and if there is no variable, it creates it, zeroes it, and returns THAT location).
22BCH-22BEH
LD (40DFH),HL
Save the value of the current BASIC program pointer (contained in 40DFH) in HL.
Note: 40DFH-40E0H holds Used by DOS.
22BFH-22C1H
Go search the stack for the appropriate FOR push.
22C2H-22C4H
Display a NF ERROR message if the appropriate FOR push wasn’t found.
22C5H
LD SP,HL
Load the stack pointer with the value of the memory pointer in HL.
22C6H-22C8H
LD (40E8H),HL
Save the value in HL.
Note: 40E8H-40E9H holds Stack pointer pointer.
22C9H
PUSH DE
Save the variable’s address in DE to the stack.
22CAH
LD A,(HL)
Load register A with the value of the sign for the STEP value.
22CBH
INC HL
Bump the value of the memory pointer in HL.
22CCH
PUSH AF
Save the value of the sign for the STEP value in register A to the stack.
22CDH
PUSH DE
Save the variable’s address in DE to the stack.
22CEH
LD A,(HL)
Load register A with the number type flag for the STEP value.
22CFH
INC HL
Bump the value of the memory pointer in HL.
22D0H
OR A
Check the value of the number type flag for the STEP flag in register A.
22D1H-22D3H
Jump to 22EAH if the STEP value is an integer.
22D4H-22D6H
Call 09B1H (which moves a SINGLE PRECISION number pointed to by HL to REG 1).
22D7H
EX (SP),HL
Exchange the value of the variable’s address to the stack with the value of the memory pointer in HL.
22D8H
PUSH HL
Save the value of the variable’s address in HL to the stack.
22D9H-22DBH
Go add the sin le precision value at the location of the memory pomter in HL to the single precision STEP value in register pairs BC and DE. Return with the result in REG 1.
22DCH
POP HL
Get the value of the variable’s address from the stack and put it in HL.
22DDH-22DFH
Go move the single precision result from REG 1 to the variable’s address in HL.
22E0H
POP HL
Get the value of the memory pointer from the stack and put it in HL.
22E1H-22E3H
Call 09C2H (which loads a SINGLE PRECISION value pointed to by HL into register pairs BC and DE).
22E4H
PUSH HL
Save the value of the memory pointer in HL to the stack.
22E5H-22E7H
Call the SINGLE PRECISION COMPARISON routine at 0A0CH.

NOTE: The routine at 0A0CH algebraically compares the single precision value in BC/DE to the single precision value REG 1.
The results are stored in A as follows:
  • A=0 if REG 1 = BCDE
  • A=1 if REG 1>BCDE; and
  • A=FFH if REG 1<BCDE.
22E8H-22E9H
Jump forward to to 2313H.
22EAH
INC HL
We need to backspace the stack by 4 bytes to skip over the area which would hold the single precision TO value to do this we have to bump the value of the memory pointer in HL 4 times.
22EBH
INC HL
Bump the value of the memory pointer in HL.
22ECH
INC HL
Bump the value of the memory pointer in HL.
22EDH
INC HL
Bump the value of the memory pointer in HL.
22EEH
LD C,(HL)
Load register C with the LSB of the STEP value (held at the location of the memory pointer in HL).
22EFH
INC HL
Bump the value of the memory pointer in HL to be the MSB of the STEP value.
22F0H
LD B,(HL)
Load register B with the MSB of the STEP value at the location of the memory pointer in HL.
22F1H
INC HL
Bump the value of the memory pointer in HL so that it is the stack address of the TO limit.
22F2H
EX (SP),HL
Exchange HL and the value of the stack pointer so that HL will have the address of the index and the value at the stack pointer will have the ending address of the TO limit.
22F3H
LD E,(HL)
Load register E with the LSB of the index.
22F4H
INC HL
Bump the value of the memory pointer in HL to point to the MSB of the index.
22F5H
LD D,(HL)
Load register D with the MSB of the index.
22F6H
PUSH HL
Save the value of the memory pointer in HL to the stack.
22F7H
LD L,C
Load register L with the LSB of the STEP value in register C.
22F8H
LD H,B
Load register H with the MSB of the STEP value in register B.
22F9H-22FBH
With the STEP value in HL, call the INTEGER ADD routine at 0BD2H (which adds the integer value in DE to the integer in HL. The sum is left in HL and the orginal contents of DE are preserved. If overflow occurs (sum exceeds 2**15), both values are converted to single precision and then added. The result would be left in REG 1 and the mode flag would be updated).
22FCH-22FEH
LD A,(40AFH)
Load register A with the current value of the data type flag.
Note: 40AFH holds Current number type flag.
22FFH
CP 04H
Check to see if the current value in REG 1 is single precision.
  • NOTE: A CP will return Z if there is a match against Register A, and NZ if not a match against Register A.)
2301H-2303H
Show an ?OV ERROR message if the current value in REG 1 is single precision.
2304H
EX DE,HL
Load DE with the index as an integer (from HL).
2305H
POP HL
Restore the address of the index in the variable area to HL.
2306H
LD (HL),D
Save the MSB of the result in register D at the location of the memory pointer in HL.
2307H
DEC HL
Decrement the value of the memory pointer in reg­ ister pair HL.
2308H
LD (HL),E
Save the LSB of the result in register E at the location of the memory pointer in HL.
2309H
POP HL
Restore the address of the TO value in the FOR statement to HL.
230AH
PUSH DE
Save the index in DE to the stack.
230BH
LD E,(HL)
Load register E with the LSB of the TO value at the location of the memory pointer in HL.
230CH
INC HL
Bump the value of the memory pointer in HL to point to the MSB of the TO value.
230DH
LD D,(HL)
Load register D with the MSB of the TO value at the location of the memory pointer in HL.
230EH
INC HL
Bump the value of the memory pointer in HL so now it points to the line number.
230FH
EX (SP),HL
Swap the TO value at the memory location pointed to by the stack with the address of the binary line number for the FOR statement (now in HL).
2310H-2312H
We need to compare the new index to the limit so we call the INTEGER COMPARISON routine at 0A39H (which algebraically compares two integer values in DE and HL. The contents of DE and HL are left intact. The result of the comparison is left in the A register and status register as:
If DE > HL then A will be -1;
If DE < HL then A will b +1; and
If DE = HL then A will be 0.
2313H
POP HL
Restore the address of the binary line number of the FOR statement back into HL.
2314H
POP BC
Get the value of the sign from the stack and put it in BC.
2315H
SUB B
We need to see if the sign is the sign we expected so we subtract the value of the sign in register B from the value in register A.
2316H-2318H
Call 09C2H (which loads a SINGLE PRECISION value pointed to by HL into register pairs BC and DE).
2319H-231AH
Jump to 2324H if the index does not equal the TO limit (meaning the FOR … NEXT loop has not been completed).
231BH
EX DE,HL
Load HL with the BASIC line number of the FOR statement in DE.
231CH-231EH
LD (40A2H),HL
Save the BASIC line number in HL as the current BASIC line number.
  • Note: 40A2H-40A3H holds the current BASIC line number.
231FH
LD L,C
Load register L with the LSB of the current BASIC program pointer in register C.
2320H
LD H,B
Load register H with the MSB of the current BASIC program pointer in register B.
2321H-2323H
Jump to 1D1AH to continue execution and restore the FOR token and GAP for FOR
2324H
LD SP,HL
Restore the stack pointer – Start of expression evaluation
2325H-2327H
LD (40E8H),HL
Load HL with the value of the current BASIC program pointer.
Note: 40E8H-40E9H holds Stack pointer pointer.
2328H-232AH
LD HL,(40DFH)
Save the value of the current BASIC program pointer in HL.
Note: 40DFH-40E0H holds Used by DOS.
232BH
LD A,(HL)
Load register A with the next token (i.e., the character at the location of the current BASIC program pointer in HL).
232CH-232DH
CP 2CH
Check to see if the character at the location of the current BASIC program pointer in register A is a ,.
  • NOTE: A CP will return Z if there is a match against Register A, and NZ if not a match against Register A.)
232EH-2330H
Jump back to 1D1EH if the character at the location of the current BASIC program pointer in register A isn’t a ,.
2331H
RST 10H
We need the next character in the BASIC program so call the EXAMINE NEXT SYMBOL routine at RST 10H.
NOTE:
  • The RST 10H routine loads the next character from the string pointed to by the HL register into the A-register and clears the CARRY flag if it is alphabetic, or sets it if is alphanumeric.
  • Blanks and control codes 09H and 0BH are ignored causing the following character to be loaded and tested.
  • The HL register will be incremented before loading any character therfore on the first call the HL register should contain the string address minus one.
  • The string must be terminated by a byte of zeros.
2332H-2334H
Gosub to 22B9H to process NEXT.
2335H
RST 08H
28H
Since the character at the location of the current BASIC program pointer in HL must be a (, call the COMPARE SYMBOL routine at RST 08H.

NOTE: The RST 08H routine compares the symbol in the input string pointed to by HL register to the value in the location following the RST 08 call.
  • If there is a match, control is returned to the next execution address (i.e, the RST 08H instruction + 2) with the next symbol in the A Register and HL incremented by one.
  • If the two characters do not match, a syntax error message is given and control returns to the Input Phase).

2337H-27C8H – EVALUATE EXPRESSION

  • This routine evaluates a BASIC expression pointed to by the HL and stores the result in the ACC. The expression must be terminated with zero byte, comma, right bracket or colon. After execution, HL will point to the delimiter and, in the case of string expressions, the ACC will contain the address of the first of three bytes that contain string length and string address. Note that the stack is used frequently and the machine should be formatted for RUN mode in order to use this routine.
2337H
DEC HL
Decrement the value of the current BASIC program pointer in HL.
2338H-2339H
LD D,00H
Load register D with zero.
233AH
PUSH DE
Save the value in DE to the stack.
233BH-233CH
LD C,01H
Load register C with the number of bytes of memory required.
233DH-233FH
Go do a memory check.
2340H-2342H
Go get the value of the next part of the expression at the location of the current BASIC program pointer in HL.
2343H-2345H
LD (40F3H),HL
Save the value of the current BASIC program pointer (i.e., the next token) in HL.
Note: 40F3H-40F4H holds temporary storage location.
2346H-2348H
LD HL,(40F3H)
Load HL with the value of the current BASIC program pointer.
Note: 40F3H-40F4H holds temporary storage location.
2349H
POP BC
Get the last precedence value from the stack and put it in BC.
234AH
LD A,(HL)
Load register A with the character at the location of the current BASIC program pointer in HL.
234BH-234CH
LD D,00H
Load register D with zero.
234DH-234EH
SUB D4H
Check to see if the character at the location of the current BASIC program pointer in register A is an arithmetic or logical token (by subtracting 212 from it).
234FH-2350H
Jump to 2364H if the character at the location of the current BASIC program pointer in register A is +, -, *, /, , AND or OR.
2351H-2352H
CP 03H
Check to see if the character at the location of the current BASIC program pointer in register A is a >, =, or <.
  • NOTE: A CP will return Z if there is a match against Register A, and NZ if not a match against Register A.)
2353H-2354H
Jump if the character at the location of the current BASIC program pointer in register A isn’t a >, =, or <.
2355H-2356H
CP 01H
Set the Carry flag if >. Then test for <= or >=.
2357H
RLA
Adjust the value in register A to give > as 1, = as 2, or < as 4.
2358H
XOR D
Combine the current value in register A with the value of the last token examined to see if this is a legal combination of <= or => or illegal combination of <<, ==, or >>.
2359H
CP D
Check for an illegal combination of operators.
235AH
LD D,A
Load register D with the value in register A.
235BH-235DH
Display a ?SN ERROR if this is an illegal combination of operators.
235EH-2360H
LD (40D8H),HL
Save the address of the >, =, or < token (held in HL) to 40D8H.
Note: 40D8H-40D9H holds Temporary storage location.
2361H
RST 10H
We need the next token so call the EXAMINE NEXT SYMBOL routine at RST 10H.
NOTE:
  • The RST 10H routine loads the next character from the string pointed to by the HL register into the A-register and clears the CARRY flag if it is alphabetic, or sets it if is alphanumeric.
  • Blanks and control codes 09H and 0BH are ignored causing the following character to be loaded and tested.
  • The HL register will be incremented before loading any character therfore on the first call the HL register should contain the string address minus one.
  • The string must be terminated by a byte of zeros.
2362H-2363H
Jump back to 234DH.
2364H
LD A,D
Load register A with the value of the operator in register D.
2365H
OR A
Test the value of the operator in register A.
2366H-2368H
Jump if the operator in register A is >, =, or <.
2369H
LD A,(HL)
Load register A with the character at the location of the current BASIC program pointer in HL.
236AH-236CH
LD (40D8H),HL
Save the address of the current BASIC program pointer in HL (which is an arithmetic operator) to 40D8H.
Note: 40D8H-40D9H holds Temporary storage location.
236DH-236EH
SUB 0CDH
Check to see if the operator at the location of the current BASIC program pointer in register A is an arithmetic token.
236FH
RET C
Return if the character at the location of the current BASIC program pointer in register A isn’t an arithmetic token.
2370H-2371H
CP 07H
Check to see if the character at the location of the current BASIC program pointer in register A is a + to OR token.
2372H
RET NC
Return if the character at the location of the current BASIC program pointer in register A isn’t a + to OR token.
2373H
LD E,A
Load register E with the operator value in register A (which would be between 0 and 7).
E   Token
0   +
1   -
2   *
3   /
4   @@
5   AND
6   OR
2374H-2376H
LD A,(40AFH)
Load register A with the current value of the number type flag.
Note: 40AFH holds Current number type flag.

2377H – PRINT @ logic.

2377H-2378H
SUB 03H
Adjust the value of the number type flag to get a -1 if integer, 0 for a string, 1 for single precision, and 5 for double precision.
2379H
OR E
Combine the operator value in register E with the adjusted number type flag in register A.
237AH-237CH
Jump down to 298FH if the combination of the adjusted number type flag in register A and the operator value in register E indicates string addition.
237DH-237FH
LD HL,189AH
Load HL with the starting address of the table of precedence operator values.
2380H
ADD HL,DE
Add the value of the operator in DE to the table of precedence values pointer in HL.
2381H
LD A,B
Load register A with the precedence value for the last operator in register B.
2382H
LD D,(HL)
Load register D with the precedence value for the current operator.
2383H
CP D
Compare the precedence value for the current operator in register D with the precedence value for the last operator in register A.
2384H
RET NC
Return out of this routine if the precedence value for the current operator in register D is greater than the precedence value for the last operator in register A.
2385H
PUSH BC
Save the precedence value and the token for the last operator in BC to the stack.
2386H-2388H
LD BC,2346H
Load BC with the return address in case there is a break in precedence.
2389H
PUSH BC
Save the return address in BC to the stack.
238AH
LD A,D
Load register A with the precedence value for the current operator in register D.
238BH-238CH
CP 7FH
Check to see if the precedence value for the current operator in register A indicates an exponential operator.
238DH-238FH
Jump down to 23D4H if the precedence value for the current operator in register A indicates an exponential operator.
2390H-2391H
CP 51H
Check to see if the precedence value for the current operator in register A indicates a logical operator.
2392H-2394H
Jump if the precedence value for the current operator in register A indicates a logical operator.
2395H-2397H
LD HL,4121H
Load HL with the address of REG 1.
2398H
OR A
Clear the flags.
2399H-239BH
LD A,(40AFH)
Load register A with the current value of the number type flag.
Note: 40AFH holds Current number type flag.
239CH
DEC A
Adjust the current number type flag in register A.
239DH
DEC A
Adjust the current number type flag in register A.
239EH
DEC A
Adjust the current number type flag in register A. Now A will be -1=Integer, 0=String, 1=Single Precision, 5=Double Precision
239FH-23A1H
Display a ?TM ERROR if the current value in REG 1 is a string.
23A2H
LD C,(HL)
Get the value at the location of the memory pointer in HL and put it in register C.
23A3H
INC HL
Bump the value of the memory pointer in HL.
23A4H
LD B,(HL)
Load register B with the value at the location of the memory pointer in HL.
23A5H
PUSH BC
Save the value in BC to the stack.
23A6H-23A8H
Jump down to 23C5H if the current number type is an integer.
23A9H
INC HL
It’s not an integer, so lets get the rest of the value by bumping the value of the memory pointer in HL.
23AAH
LD C,(HL)
Load register C with the value at the location of the memory pointer in HL.
23ABH
INC HL
Bump the value of the memory pointer in HL.
23ACH
LD B,(HL)
Load register B with the value at the location of the memory pointer in HL.
23ADH
PUSH BC
Save the value in BC (the rest of the digit) to the stack.
23AEH
PUSH AF
Save the value in AF (the type – 3) to the stack.
23AFH
OR A
Reset the status flags so that we can test if the current number type is double precision.
23B0H-23B2H
Jump down to 23C4H if the current number type is single precision.
23B3H
POP AF
Clear the stack.
23B4H
INC HL
Bump the value of the memory pointer in HL.
23B5H-23B6H
Skip the next instruction if the current number type is single precision.
23B7H-23B9H
LD HL,411DH
Reset HL to start of REG 1.
Note: 411DH-4124H holds REG l.
23BAH
LD C,(HL)
Load register C with the rest of the double precision value (held at the location of the memory pointer in HL).
23BBH
INC HL
Bump the value of the memory pointer in HL.
23BCH
LD B,(HL)
Load register B with the next digit LSB (at the location of the memory pointer in HL).
23BDH
INC HL
Bump the value of the memory pointer in HL to the next digit.
23BEH
PUSH BC
Save the LSB/NMSB of the double precision value (held in BC) to the stack.
23BFH
LD C,(HL)
Load register C with the value at the location of the memory pointer in HL.
23C0H
INC HL
Bump the value of the memory pointer in HL.
23C1H
LD B,(HL)
Load register B with the value at the location of the memory pointer in HL.
23C2H
PUSH BC
Save the value in BC to the stack.
23C3H
LD B,0F1H
06 F1
Z-80 Trick to nullify the next opcode if passing through.
23C4H
POP AF
Clear the type -3 and the status push.
23C5H-23C6H
ADD A,03H
Adjust the number type in register A up 3.
23C7H
LD C,E
Load register C with the value of the current operator token in register E (0-7).
23C8H
LD B,A
Load register B with the number type flag in register A.
23C9H
PUSH BC
Save the value in BC to the stack.
23CAH-23CCH
LD BC,2406H
Load BC with the return address of 2406H.
23CDH
PUSH BC
Save the return address in BC to the stack.
23CEH-23D0H
LD HL,(40D8H)
Load HL with the value of the current BASIC program pointer.
Note: 40D8H-40D9H holds Temporary storage location.
23D1H-23D3H
Jump back to 233AH.
23D4H-23D6H
Call the CONVERT TO SINGLE PRECISION routine at 0AB1H (which converts the contents of REG 1 from integer or double precision into single precision).
23D7H-23D9H
Call 09A4 which moves the SINGLE PRECISION value in REG 1 to the stack (stored in LSB/MSB/Exponent order).
23DAH-23DCH
LD BC,13F2H
Load BC with the address of the exponential X^Y routine at 13F2H.
23DDH-23DEH
LD D,7FH
Load register D with the precedence value for an exponential operator.
23DFH-23E0H
Jump back to 23CDH to continue expression evaluation.
23E1H
PUSH DE
Save the precedence value and the operator token in DE to the stack.
23E2H-23E4H
Call the CONVERT TO INTEGER routine at 0A7FH (where the contents of REG 1 are converted from single or double precision to integer and deposited into HL).
23E5H
POP DE
Get the precedence value and the operator token from the stack and put it in DE.
23E6H
PUSH HL
Save the integer value in HL to the stack.
23E7H-23E9H
LD BC,25E9H
Load BC with a return address of 25E9H.
23EAH-23EBH
Jump back to 23CDH to continue the syntax analysis.
23ECH
LD A,B
Load register A with the precedence value for the last operator in register B.
23EDH-23EEH
CP 64H
Check to see if the last operator was a logical operator.
23EFH
RET NC
Return out of this routine if the last operator was a logical operator.
23F0H
PUSH BC
Save the precedence value and the operator token for the last operator in BC to the stack.
23F1H
PUSH DE
Save the precedence value and the token for the current operator from DE (either a 6, 5, or 3) to the stack.
23F2H-23F4H
LD DE,6404H
Load DE with the precedence value and the token for the new operator.
23F5H-23F7H
LD HL,25B8H
Load HL with the address of the routine to compare logical quantities …
23F8H
PUSH HL
and push it to the stack.
23F9H
RST 20H
We need to check the value of the current number type flag, so we call the TEST DATA MODE routine at RST 20H.
NOTE: The RST 20H routine determines the type of the current value in REG 1 and returns a combination of STATUS flags and unique numeric values in the A Register according to the data mode flag (40AFH).

The results are returned as follows:
  • Integer = NZ/C/M/E and A is -1
  • String = Z/C/P/E and A is 0
  • Single Precision = NZ/C/P/O and A is 1
  • and Double Precision is NZ/NC/P/E and A is 5.
23FAH-23FCH
If that test shows we do NOT have a STRING, jump back to 2395H.
23FDH-23FFH
LD HL,(4121H)
Load HL with the string address held at the memory location pointed to by REG 1.
2400H
PUSH HL
Save the string’s address in HL to the stack.
2401H-2303H
LD BC,258CH
Load BC with the address of the string comparison routine.
2404H-2405H
Jump back to 23CDH.
2406H
POP BC
Get the precedence value and the token for the last operator from the stack and put it in BC.
2407H
LD A,C
Load register A with the operator token in register C.
2408H-240AH
LD (40B0H),A
Save the operator token in register A.
Note: 40B0H holds Temporary storage location.
240BH
LD A,B
Load register A with the precedence value in register B.
240CH-240DH
CP 08H
Check the number type for the precedence value in register A.
240EH-240FH
Jump forward to 2438H if the number type in register A (the first operand) is double prec1sion.
2410H-2412H
LD A,(40AFH)
Load register A with the number type for the current result in REG 1.
Note: 40AFH holds Current number type flag.
2413H-2414H
CP 08H
Check to see if the current result in REG 1 is double precision.
2415H-2417H
Jump forward to 2460H if the current value in REG 1 is double precision.
2418H
LD D,A
Load register D with the current data type flag in register A.
2419H
LD A,B
Load register A with the precedence value for the last operator in register B.
241AH-241BH
CP 04H
Check to see if the number type for the precedence value in register A is single precision.
241CH-241EH
Jump forward to 2472H if the number type for the precedence value in register A is single precision.
241FH
LD A,D
Load register A with the number type flag for the value in REG 1.
2420H-2421H
CP 03H
Check to see if the current value in REG 1 is a string.
2422H-2424H
Display a ?TM ERROR message if the current value in REG 1 is a string.
2325H-2427H
Jump forward to 247CH if the current value in REG 1 is single precision.
2428H-242AH
LD HL,18BFH
Load HL with the starting address of the arithmetic jump table.
242BH-242CH
LD B,00H
Load register B with zero.
242DH
ADD HL,BC
Add the operator’s token in BC to the value of the arithmetic jump table pointer in HL.
242EH
ADD HL,BC
Add the operator’s token in BC to the value of the arithmetic jump table pointer in HL.
242FH
LD C,(HL)
Load register C with the LSB of the jump address at the location of the arithmetic jump table pointer in HL.
2430H
INC HL
Bump the value of the arithmetic jump table pointer in HL.
2431H
LD B,(HL)
Load register B with the MSB of the jump address at the location of the arithmetic jump table pointer in HL.
2432H
POP DE
Get the value for the previous result from the stack and put it in DE.
2433H-2435H
LD HL,(4121H)
Get the value for the current result from REG 1 and put it in HL.
2436H
PUSH BC
Save the arithmetic routine’s jump address in regis­ ter pair BC to the stack.
2437H
RET
Return.
2438H-243AH
Call the CONVERT TO DOUBLE PRECISION routine at 0ADBH (where the contents of REG 1 are converted from integer or single precision to double precision).
243BH-243DH
Go convert the current result in REG 1 to single precision.
243EH
POP HL
Get the value from the stack and put it in HL.
243FH-244lH
LD (411FH),HL
Save the value in HL near the end of REG 1.
2442H
POP HL
Get the value from the stack and put it in HL.
2443H-2445H
LD (411DH),HL
Save the value in HL in REG 1.
Note: 411DH-4124H holds REG l.
2446H
POP BC
Get the value from the stack and put it in BC.
2447H
POP DE
Get the value from the stack and put it in DE.
2448H-244AH
Call 09B4H (which moves the SINGLE PRECISION value in DC/DE into REG 1). This moves DE to (4121H) and BC to (4123H).
244BH-244DH
Convert the first value to double precision by calling the CONVERT TO DOUBLE PRECISION routine at 0ADBH (where the contents of REG 1 are converted from integer or single precision to double precision).
244EH-2450H
LD HL,18ABH
Load HL with the double precision arithmetic jump table’s starting address.
2451H-2453H
LD A,(40B0H)
Load register A with the operator token in register A.
Note: 40B0H holds Temporary storage location.
2454H
RLCA
Multiply the value of the operator token in register A by two.
2455H
PUSH BC
Save the value in BC to the stack so we can use it for 16 bit arithmetic.
2456H
LD C,A
Load register C with the adjusted value of the operator token in register A (i.e., 2 x token).
2457H-2458H
LD B,00H
Load register B with zero.
2459H
ADD HL,BC
Add the value of the adjusted operator token in BC (which is token value * 2) to 18ABH (which is the double precision arithmetic jump table’s starting address) in HL.
245AH
POP BC
Restore BC from the stack and put it in BC.
245BH
LD A,(HL)
Load register A with the LSB of the jump address at the location of the arithmetic jump table pointer in HL.
245CH
INC HL
Bump the value of the arithmetic jump table pointer in HL.
245DH
LD H,(HL)
Load register H with the MSB of the jump address at the location of the arithmetic jump table pointer in HL.
245EH
LD L,A
Load register L with the LSB of the jump address in register A.
245FH
JP (HL)
Jump to the arithmetic routine whose address is in HL.
2460H
PUSH BC
Save the precedence value and the operator token in BC to the stack.
2461H-2463H
Move the current result to the a storage area.
2464H
POP AF
Load register A with the value of the current number type flag.
2465H-2467H
LD (40AFH),A
Save the value of the current number type flag in register A.
Note: 40AFH holds Current number type flag.
2468H-2469H
CP 04H
Check to see if the current result in REG 1 is single precision.
246AH-246BH
Jump back to 2446H if the current result in REG 1 is single precision.
246CH
POP HL
Get the integer value from the stack and put it in HL.
246DH-246FH
LD (4121H),HL
Save the integer value in HL in REG 1.
2470H-2471H
Jump back to 244BH.
2472H-2474H
Call the CONVERT TO SINGLE PRECISION routine at 0AB1H (which converts the contents of REG 1 from integer or double precision into single precision).
2475H
POP BC
Get the value from the stack and put it in BC.
2476H
POP DE
Get the value from the stack and put it in DE.
2477H-2479H
LD HL,18B5H
Load HL with the starting address of the single precision arithmetic jump table.
247AH-247BH
Jump back to 2451H to perform the operation.
247CH
POP HL
Get the integer value from the stack and put it in HL.
247DH-247FH
Call 09A4 which moves the SINGLE PRECISION value in REG 1 to the stack (stored in LSB/MSB/Exponent order).
2480H-2482H
Go convert the integer value in HL to single precision.
2483H-2485H
Call 09BF which loads the SINGLE PRECISION value in REG 1 into BC/DE.
2486H
POP HL
Get the LSB/NMSB from the stack and put it in HL.
2487H-2489H
LD (4123H),HL
Save the value in HL in REG 1
248AH
POP HL
Get the MSB and exponent from the stack and put it in HL.
248BH-248DH
LD (4121H),HL
Save the value in HL in REG 1.
248EH-248FH
Jump back to 2477H to perform the operation.

2490H – Integer divide

  • (ACC=DE / HL) Result will be in single-precision (NTF=4) and will be in the ACC.
    Divides DE by HL. Both values are converted to single precision before the division is started. The quotient is left in REG l; the mode flag is updated. The orginal contents of the DE and HL register sets are lost.
  • Note: To use a ROM call to divide two integers store the dividend in the DE register pair, and store the divisor in HL and then CALL 2490H. The result is stored in single precision format (since it is not likely to be an integer) in 4121H-4124Hin approximately 5.1 milliseconds.
2490H
“IDIV”
PUSH HL
Save the integer value in HL to the stack.
2491H
EX DE,HL
We need to convert DE to SP so first do this swap to set up the variables for the call which follows.
2492H-2494H
Go convert the integer value in HL to single precision and return with the result in REG 1.
2495H
POP HL
Get the integer value from the stack and put it in HL.
2496H-2498H
Call 09A4 which moves the SINGLE PRECISION value in REG 1 to the stack (stored in LSB/MSB/Exponent order).
2499H-249BH
Go convert the integer value in HL to single precision and return with the result in REG 1.
249CH-249EH
Go do a single precision divide.
249FH
RST 10H
We need the next character in the BASIC program so call the EXAMINE NEXT SYMBOL routine at RST 10H.
NOTE:
  • The RST 10H routine loads the next character from the string pointed to by the HL register into the A-register and clears the CARRY flag if it is alphabetic, or sets it if is alphanumeric.
  • Blanks and control codes 09H and 0BH are ignored causing the following character to be loaded and tested.
  • The HL register will be incremented before loading any character therfore on the first call the HL register should contain the string address minus one.
  • The string must be terminated by a byte of zeros.
24A0H-24A1H
LD E,28H
Load register E with a ?MO ERROR code.
24A2H-24A4H
Display a ?MO ERROR if we are at the end of the string.
24A5H-24A7H
If the character at the location of the current BASIC program pointer in HL is numeric, call the ASCII TO BINARY routine at 0E6C (which converts the ASCII string pointed to by HL to binary with the result in REG 1 and the mode flag will have changed).
24A8H-24AAH
Check to see if the character at the location of the current BASIC program pointer in HL is alphabetic.
24ABH-24ADH
Jump if the character at the location of the current BASIC program pointer in HL is alphabetic.
24AEH-24AFH
CP 0CDH
Check to see if the character at the location of the current BASIC program pointer in register A is a + token.

Notes:

  • CDH is a + in ASCII
  • A CP will return Z if there is a match against Register A, and NZ if not a match against Register A.
24B0H-24B1H
Jump if the character at the location of the current BASIC program pointer in register A is a + token.
24B2H-24B3H
CP 2EH
Check to see if the character at the location of the current BASIC program pointer in register A is a decimal point.

Notes:

  • 2EH is a . in ASCII
  • A CP will return Z if there is a match against Register A, and NZ if not a match against Register A.
24B4H-24B6H
If the character at the location of the current BASIC program pointer in HL is a decimal point, call the ASCII TO BINARY routine at 0E6C (which converts the ASCII string pointed to by HL to binary with the result in REG 1 and the mode flag will have changed).
24B7H-24B8H
CP 0CEH
Check to see if the character at the location of the current BASIC program pointer in register A is a - token.

Notes:

  • CEH is a - in ASCII
  • A CP will return Z if there is a match against Register A, and NZ if not a match against Register A.
24B9H-24BBH
Jump to 2532H if the character at the location of the current BASIC program pointer in register A is a - token.
24BCH-24BDH
CP 22H
Check to see if the character at the location of the current BASIC program pointer in register A is a ".

Notes:

  • 22H is a " in ASCII
  • A CP will return Z if there is a match against Register A, and NZ if not a match against Register A.
24BEH-24C0H
Jump to 2866H if the character at the location of the current BASIC program pointer in register A is a ".
24C1H-24C2H
CP 0CBH
Check to see if the character at the location of the current BASIC program pointer in register A is a NOT token.

Notes:

  • CBH is a NOT token.
  • A CP will return Z if there is a match against Register A, and NZ if not a match against Register A.
24C3H-24C5H
Jump to 25C4H if the character at the location of the current BASIC program pointer in register A is a NOT token.
24C6H-24C7H
CP 26H
Check to see if the character at the location of the current BASIC program pointer in register A is a &.

Notes:

  • 26H is a & in ASCII
  • A CP will return Z if there is a match against Register A, and NZ if not a match against Register A.
24C8H-24CAH
Jump to 4194H (which is DOS) if the character at the location of the current BASIC program pointer in register A is a &.
24CBH-24CCH
CP 0C3H
Check to see if the character at the location of the current BASIC program pointer in register A is an ERR token.

Notes:

  • C3H is a ERR token.
  • A CP will return Z if there is a match against Register A, and NZ if not a match against Register A.
24CDH-24CEH
Jump to 24D9H if the character at the location of the current BASIC program pointer in register A isn’t an ERR token.
24CFH
RST 10H
We now need bump the value of the current BASIC program pointer until it points to the next character, call the EXAMINE NEXT SYMBOL routine at RST 10H.
NOTE:
  • The RST 10H routine loads the next character from the string pointed to by the HL register into the A-register and clears the CARRY flag if it is alphabetic, or sets it if is alphanumeric.
  • Blanks and control codes 09H and 0BH are ignored causing the following character to be loaded and tested.
  • The HL register will be incremented before loading any character therfore on the first call the HL register should contain the string address minus one.
  • The string must be terminated by a byte of zeros.
24D0H-24D2H
LD A,(409AH)
Load register A with the value of the current error number.
Note: 409AH holds the RESUME flag.
24D3H
PUSH HL
Save the value of the current BASIC program pointer in HL to the stack.
24D4H-24D6H
Go save the value of the current error number in register A (as an integer) as the current result in REG l.
24D7H
POP HL
Get the value of the current BASIC program pointer from the stack and put it in HL.
24D8H
RET
Return.
24D9H-24DAH
CP C2H
Check to see if the character at the location of the current BASIC program pointer in register A is a ERL token.
24DBH-24DCH
Jump to 24E7H if the character at the location of the current BASIC program pointer in register A isn’t an ERL token.
24DDH
RST 10H
We need the next character in the BASIC program so call the EXAMINE NEXT SYMBOL routine at RST 10H.
NOTE:
  • The RST 10H routine loads the next character from the string pointed to by the HL register into the A-register and clears the CARRY flag if it is alphabetic, or sets it if is alphanumeric.
  • Blanks and control codes 09H and 0BH are ignored causing the following character to be loaded and tested.
  • The HL register will be incremented before loading any character therfore on the first call the HL register should contain the string address minus one.
  • The string must be terminated by a byte of zeros.
24DEH
PUSH HL
Save the value of the current BASIC program pointer in HL to the stack.
24DFH-24ElH
LD HL,(40EAH)
Load HL with the current error line number.
Note: 40EAH-40EBH holds the line number with error.
24E2H-24E3H
Go save the error line number in HL as the current result in REG!.
24E5H
POP HL
Get the value of the current BASIC program pointer from the stack and put it in HL.
24E6H
RET
Return.

24E7H- VARPTR logic.

24E7H-24E8H
CP 0C0H
Check to see if the character at the location of the current BASIC program pointer in register A is a VARPTR token.
24E9H-24EAH
Jump back to 24FFH if the character at the location of the current BASIC program pointer in register A isn’t a VARPTR token.
24EBH
RST 10H
We need the next character in the BASIC program so call the EXAMINE NEXT SYMBOL routine at RST 10H.
NOTE:
  • The RST 10H routine loads the next character from the string pointed to by the HL register into the A-register and clears the CARRY flag if it is alphabetic, or sets it if is alphanumeric.
  • Blanks and control codes 09H and 0BH are ignored causing the following character to be loaded and tested.
  • The HL register will be incremented before loading any character therfore on the first call the HL register should contain the string address minus one.
  • The string must be terminated by a byte of zeros.
24ECH-24EDH
RST 08H28
Since the character at the location of the current BASIC program pointer in HL must be a (, call the COMPARE SYMBOL routine at RST 08H.

NOTE: The RST 08H routine compares the symbol in the input string pointed to by HL register to the value in the location following the RST 08 call.
  • If there is a match, control is returned to the next execution address (i.e, the RST 08H instruction + 2) with the next symbol in the A Register and HL incremented by one.
  • If the two characters do not match, a syntax error message is given and control returns to the Input Phase).
24EEH-24F0H
Jump to 24BCH to evaluate the variable name at the location of the current BASIC program pointer in HL.
24FlH-24F2H
RST 08H
29H
Since the character at the location of the current BASIC program pointer in HL must be a ), call the COMPARE SYMBOL routine which compares the symbol in the input string pointed to by HL register to the value in the location following the RST 08 call. If there is a match, control is returned to address of the RST 08 instruction + 2 with the next symbol in the A register and HL incremented by one. If the two characters do not match, a syntax error message is given and control returns to the Input Phase).
24F3H
PUSH HL
Save the value of the current BASIC program pointer in HL to the stack.
24F4H
EX DE,HL
Load HL with the variable’s address in DE.
24F5H
LD A,H
Load register A with MSB of the variable’s address in register H.
24F6H
OR L
Combine the LSB of the variable’s address in register L with the MSB of the variable’s address in register A. This type of pattern is used to check for something being zero.
24F7H-24F9H
Display a ?FC ERROR if the variable’s address in HL is equal to zero, meaning that the variable is undefined.
24FAH-24FCH
Save the variable’s address in HL as the current result in REG l.
24FDH
POP HL
Get the value of the current BASIC program pointer from the stack and put it in HL.
24FEH
RET
Return to the execution driver.

24FFH – Other Function Routine.

24FFH-2500H
CP 0C1H
Check to see if the character at the location of the current BASIC program pointer in register A is a USR token.
2501H-2503H
Jump to 27FEH if the character at the location of the current BASIC program pointer in register A is a USR token.
2504H-2505H
CP 0C5H
Check to see if the character at the location of the current BASIC program pointer in register A is a INSTR token
2506H-2508H
Jump to the DOS address of 419DH if the character at the location of the current BASIC program pointer in register A is an INSTR token.
2509H-250AH
CP 0C8H
Check to see if the character at the location of the current BASIC program pointer in register A is a MEM token.
250BH-250DH
If the character at the location of the current BASIC program pointer in register A is a MEM token, jump to the RETURN AMOUNT OF FREE MEMORY routine at 27C9H which computes the amount of memory remaining between the end of the variable list and the end of the stack and puts the result in REG 1 as a SINGLE PRECISION number.
250EH-250FH
CP 0C7H
Check to see if the character at the location of the current BASIC program pointer in register A is a TIME$ token.
2510H-2512H
Jump to the DOS address of 4176H if the character at the location of the current BASIC program pointer in register A is a TIME$ token.
2513H-2514H
CP 0C6H
Check to see if the character at the location of the current BASIC program pointer in register A is a POINT token.
2515H-2517H
Jump to 0132H if the character at the location of the current BASIC program pointer in register A is a POINT token.
2518H-2519H
CP 0C9H
Check to see if the character at the location of the current BASIC program pointer in register A is an INKEY$ token.
251AH-251CH
Jump to 019DH if the character at the location of the current BASIC program pointer in register A is an INKEY$ token.
251DH-251EH
CP 0C4H
Check to see if the character at the location of the current BASIC program pointer in register A is a STRING$ token.
241FH-2421H
Jump to 2A2FH if the character at the location of the current BASIC program pointer in register A is a STRING$ token.
2522H-2523H
CP 0BEH
Check to see if the character at the location of the current BASIC program pointer in register A is a FN token.
2524H-2526H
Jump to the DOS address of 4155H if the character at the location of the current BASIC program pointer in register A is a FN token.
2527H-2528H
SUB 0D7H
Check to see if the character at the location of the current BASIC program pointer in register A is a SGN to MID$ token.
2529H-252BH
Jump to 254EH if the character at the location of the current BASIC program pointer in register A is a SGN to MID$ token.
252CH-252EH
Gosub to 2335H to evaluate the expression at the location of the current BASIC program pointer in HL.
252FH-2530H
RST 08H
29H
Since the character at the location of the current BASIC program pointer in HL must be a ), call the COMPARE SYMBOL routine at RST 08H.

NOTE: The RST 08H routine compares the symbol in the input string pointed to by HL register to the value in the location following the RST 08 call.
  • If there is a match, control is returned to the next execution address (i.e, the RST 08H instruction + 2) with the next symbol in the A Register and HL incremented by one.
  • If the two characters do not match, a syntax error message is given and control returns to the Input Phase).
2531H
RET
Return out of this routine.

2532H – Binary Minus Routine.

2532H
LD D,7DH
Load register D with the precedence value.
2534H-2536H
Gosub to 233AH to evaluate the variable at the location of the current BASIC program pointer in HL.
2537H-2539H
LD HL,(40F3H)
Load HL with the value of the current BASIC program pointer.
Note: 40F3H-40F4H holds Temporary storage location.
253AH
PUSH HL
Save the value of the current BASIC program pointer in HL to the stack so we know where to continue.
253BH-253DH
Invert the sign of the current value in REG 1.
253EH
POP HL
Restore the code string address from the stack and put it in HL. We need this because we return here after executing functions SNG( to MID$(.
253FH
RET
Return to the expression evaluation.

2540H – This routine loads a variable to the ACC and sets the NTF. The HL must point to the ASCII variable name. After execution the HL will point to the character following the last character of the variable used. The value of the variable will be loaded in the ACC. For strings however (NTF=3), the ACC will contain the address of the first three bytes which contain the string length and string address (see Level II BASIC manual). Also note that if the variable cannot be found it will be created and given a value of zero.

2540H-2542H
Call the FIND ADDRESS OF VARIABLE routine at 260DH which searches the Variable List Table for a variable name which matches the name in the string pointed to in HL, and return the address of that variable in DE (and if there is no variable, it creates it, zeroes it, and returns THAT location).
2543H
PUSH HL
Save the value of the current BASIC program pointer in HL to the stack.
2544H
EX DE,HL
Move the address of the variable to HL.
2545H-2547H
LD (4121H),HL
Save the variable’s address in HL in REG 1.
2548H
RST 20H
We need to check the value of the current number type flag, so we call the TEST DATA MODE routine at RST 20H.
NOTE: The RST 20H routine determines the type of the current value in REG 1 and returns a combination of STATUS flags and unique numeric values in the A Register according to the data mode flag (40AFH).

The results are returned as follows:
  • Integer = NZ/C/M/E and A is -1
  • String = Z/C/P/E and A is 0
  • Single Precision = NZ/C/P/O and A is 1
  • and Double Precision is NZ/NC/P/E and A is 5.
2549H-254BH
If that test shows we do NOT have a STRING, call 09F7H to move data.
254CH
POP HL
Get the address of the next symbol in the input string from the stack and put it in HL.
254DH
RET
Return to the caller.

254EH – This routine is for SNG( to MID$(.

254EH-254FH
LD B,00H
Load register B with zero.
2550H
RLCA
Set A to be 2 * (token – D7H)
2551H
LD C,A
Save the new token.
2552H
PUSH BC
Save 0/2*(token-D7) on stack.
2553H
RST 10H
Get the next character from the tokenized string by calling RST 10H.
NOTE:
  • The RST 10H routine loads the next character from the string pointed to by the HL register into the A-register and clears the CARRY flag if it is alphabetic, or sets it if is alphanumeric.
  • Blanks and control codes 09H and 0BH are ignored causing the following character to be loaded and tested.
  • The HL register will be incremented before loading any character therfore on the first call the HL register should contain the string address minus one.
  • The string must be terminated by a byte of zeros.
2554H
LD A,C
Prepare to look for SGN( to CHR$( token.
2555H
CP 41H
Test for the adjusted token.
2557H
JR C,256FH
.Jump to 256FH if the token is SGN( to CHR$(. If not, it is a LEFT$MID$.
2559H
CALL 2335H
Otherwise, gosub to 2335H to evaluate the expression part of the calling sequence (which requires 2 or parameters).
255CH
RST 08H
2CH
Use RST 08H to test for a ,.
255EH
CALL 0AF4H
Gosub to 0AF4H to ensure the current variable is a string, otherwise it is an error.
2561H
EX DE,HL
Make sure the current variable is a string – DE is the current position in the program statement and HL is the address of the string.
2562H
LD HL,(4121H)
Load HL with the string address held at the memory location pointed to by REG 1.
2565H
EX (SP),HL
Put the string address to the stack.
2566H
PUSH HL
Save the 00 / 2*(token-D7H) to the stack.
2567H
EX DE,HL
Move the program statement position to HL.
2568H
CALL 2B1CH
Evaluate n portion of the string function.
256BH
EX DE,HL
Set DE to be the current position in the statement and set HL to be n.
256CH
EX (SP),HL
Move n to stack. HL will be 2 * (token – D7H).
256DH
JR 2583H
Jump down to 2583H to process the token.
256FH-2571H
The below is a single variable parameter call. First, GOSUB to 252CH to evaluate the expression at the location of the current BASIC program pointer in HL.
2572H
EX (SP),HL
Exchange the value of the current BASIC program pointer in HL with the operator value to the stack. HL will be 0 + 2 * (token – D7H).
2573H
LD A,L
Load register A with the operator token in register L. A will be 2 * (token – D7H).
2574H-2575H
CP 0CH
Check to see if the operator token in register A is SGN to SQR.
2576H-2577H
Jump down to 257FH if the operator token in register A is SGN to SQR.
2578H-2579H
CP 1BH
Check the value of the adjusted operator token in register A.
257AH
PUSH HL
Save the adjusted token (0 + 2*(token – D7H)) in HL to the stack.
257BH-257DH
If the operator token in register A is SQR to ATN, call the CONVERT TO SINGLE PRECISION routine at 0AB1H (which converts the contents of REG 1 [4121H] from integer or double precision into single precision).
257EH
POP HL
Restore the adjusted token from the stack and put it in HL.
257FH-2581H
LD DE,253EH
Load DE with a return address of 253EH for once the function is executed.
2582H
PUSH DE
Save the value of the return address in DE to the stack.
2583H-2585H
LD BC,1608H
Load BC with the SGN to MID$ jump table address.
2586H
ADD HL,BC
Add the jump table pointer in BC with the value of the operator token in HL.
2587H
LD C,(HL)
Load register C with the LSB of the jump address at the location of the jump table pointer in HL.
2588H
INC HL
Bump the value of the jump table pointer in HL.
2589H
LD H,(HL)
Load register H with the MSB of the jump address at the location of the jump table pointer in HL.
258AH
LD L,C
Load register L with the LSB of the jump address in register C.
258BH
JP (HL)
Jump to the calculated address (which is the SGNMID$ function) in HL.

258CH – This routine will do a relational comparison of two strings.
It will load A with the length of the first string and BC with the string’s address. Then it will load D with the length of the second string and HL with the string’s address.

258CH-258EH
Gosub to 29D7H to check to see if there is enough memory for the string.
258FH
LD A,(HL)
Load register A with the length of the string at the location of the string’s VARPTR in HL.
2590H
INC HL
Bump the value of the string’s VARPTR in HL so that HL points to the LSB of the string address.
2591H
LD C,(HL)
Load register C with the LSB of the string’s address at the location of the string’s VARPTR in HL.
2592H
INC HL
Bump the value of the string’s VARPTR in HL so that HL points to the MSB of the string address.
2594H
LD B,(HL)
Load register B with the MSB of the string’s address at the location of the string’s VARPTR in HL.
2595H
POP DE
Save the value of the string’s address in BC to the stack.
2596H
PUSH BC
Save the string’s length in register A to the stack.
2597H-2599H
PUSH AF
Load HL with the second string’s VARPTR.
259AH
POP DE
Get the length of the first string from the stack and put it in register D.
259BH
LD E,(HL)
Load register E with the second string’s length at the location of the second string’s VARPTR in HL.
259CH
INC HL
Bump the value of the second string’s VARPTR in HL.
259DH
LD C,(HL)
Load register C with the LSB of the second string’s address at the location of the second string’s VARPTR in HL.
259EH
INC HL
Bump the value of the second string’s VARPTR in HL.
259FH
LD B,(HL)
Load register B with the MSB of the second string’s address at the location of the second string’s VARPTR in HL.
25A0H
POP HL
Get the first string’s address from the stack and put it in HL.
25AlH
LD A,E
Load register A with the length of the second string in register E.
25A2H
OR D
Combine the first string’s length in register D with the second string’s length in register A.
25A3H
RET Z
Return out of the routine if there aren’t any characters left in either string to be compared.
25A4H
LD A,D
Load register A with the first string’s length in register D.
25A5H-25A6H
SUB 01H
Check to see if the first string’s length in register A is equal to zero.
25A7H
RET C
Return if there are no more characters in the first string to be compared.
25A8H
XOR A
Load register A with zero.
25A9H
CP E
Check to see if the second string’s length in register E is equal to zero.
25AAH
INC A
Bump the value in register A.
25ABH
RET NC
Return if there aren’t anymore characters in the second string to be compared.
25ACH
DEC D
Decrement the value of the first string’s length in register D.
25ADH
DEC E
Decrement the value of the second string’s length in register E.
25AEH
LD A,(BC)
Load register A with the character at the location of the second string pointer in BC.
25AFH
CP (HL)
Compare the character at the location of the second string pointer in register A with the character at the location of the first string pointer in HL.
25B0H
INC HL
Bump the value of the first string pointer in HL.
25BlH
INC BC
Bump the value of the second string pointer in BC.
25B2H-25B3H
Loop back to 25A1H to keep going if the characters match.
25B4H
CCF
Since they are not equal, reverse the CARRY flag so 960 will give a +1 or -1.
25B5H-25B7H
Jump back to 0960H.
25B8H
INC A
Bump the value of the current precedence value in register A.
25B9H
ADC A,A
Adjust the value of the current precedence value in register A. This will give a 1 with a NC if 0 or a 0 with C if FF.
25BAH
POP BC
Get the last operator value from the stack and put it in BC.
25BBH
AND B
Combine the precedence value in register B with the precedence value in register A.
25BCH-25BDH
ADD A,FFH
Adjust the value in register A. This will give a 0 if both are equal and a CARRY if they are unequal.
25BEH
SBC A,A
Check to see if the precedence values in registers A and B match. This will set A=0 if equal, and A+1 if unequal.
25BFH-25ClH
Call to 098DH. This will set the current value to 00 if A is positive, and to FF if A is negative.
If the values match, set the current result in zero. If they do not match, set the current result to -1.
25C2H-25CJH
Jump forward to 25D6H to continue with the expression evaluation.

25C4H – NOT Routine.

25C4H-25C5H
LD D,5AH
Load register D with the precedence value.
25C6H-25C8H
Go evaluate the expression.
25C9H-25CBH
Call the CONVERT TO INTEGER routine at 0A7FH (where the contents of REG 1 are converted from single or double precision to integer and deposited into HL).
25CCH
LD A,L
Load register A with the LSB of the integer value.
25CDH
CPL
Compliment the LSB of the integer value in register A.
25CEH
LD L,A
Load register L with the adjusted LSB of the integer value in register A.
25CFH
LD A,H
Load register A with the MSB of the integer value in register H.
25D0H
CPL
Compliment the MSB of the integer value in register A.
25DlH
LD H,A
Load register H with the adjusted MSB of the integer value in register A.
25D2H-25D4H
LD (4121H),HL
Save the complimented integer value in HL as the current result in REG 1
25D5H
POP BC
Clean up the stack.
25D6H-25D8H
Jump back to 2346H to continue with the expression evaluation.

25D9H – The RST 20H code is located here. – This is the TEST DATA MODE, which determines the type of the current value in REG 1 and returns a combination of STATUS flags and unique numeric values in the A Register according to the data mode flag (40AFH).
TYPE   CODE   ZERO   CARRY   NEG   PARITY   A-Register
INT     02     NZ      C      N      E         -1
STR     03      Z      C      P      E          0
SNG     04     NZ      C      P      O          1
DBL     08     NZ     NC      P      E          5

25D9H-25DBH
“TSTYP”
LD A,(40AFH)
Load register A with the current value of the number type flag.
Note: 40AFH holds Current number type flag.
25DCH-25DDH
CP 08H
Check to see if the current value in REG 1 is double precision (02=INT, 03=STR, 04=SNG, 08=DBL).
25DEH-25DFH
If that test shows that we have a DOUBLE PRECISION number, jump forward to 25E5H.
25E0H-25ElH
SUB 03H
If the number is not double precision, subtract 3.
25E2H
OR A
Set the status flags of the adjusted number type flag in register A.
24E3H
SCF
Set the Carry flag.
25E4H
RET
Return.
25E5H-25E6H
SUB 03H
We are dealing with a double precision number so adjust the value of the current number type flag in register A.
25E7H
OR A
Test the value of the current number type flag in register A, which will exit without the CARRY flag set.
25E8H
RET
Return.
25E9H
PUSH BC
B has he precision alue for the last operator. Save BC to the stack.
25EAH-25ECH
Call the CONVERT TO INTEGER routine at 0A7FH (where the contents of REG 1 are converted from single or double precision to integer and deposited into HL).
25EDH
POP AF
Get the operator value from the stack and put it in register A.
25EEH
POP DE
Get the return address from the stack and put it in DE.
25EFH-25F1H
LD BC,27FAH
Load BC with a return address of 27FAH.
25F2H
PUSH BC
Save the value of the return address in BC to the stack.
25F3H-25F4H
CP 46H
Check to see if the operator value in register A is an OR token. A CP returns Z if the test matches A and NZ otherwise.
25F5H-25F6H
Jump forward a few instructions to 25FDH (to the AND code) if the operator value in register A isn’t an OR token.

25F7H – OR logic.

25F7H
LD A,E
Load register A with the LSB of the first value in register E.
25F8H
OR L
Combine the LSB of the first value in register A with the LSB of the second value in register L.
25F9H
LD L,A
Load register L with the ORed value in register A.
25FAH
LD A,H
Load register A with the MSB of the second value in register H.
25FBH
OR D
Combine the MSB of the first value in register D with the MSB of the second value in register A.
25FCH
RET
Return to 27FAH (=convert the result to integer and return that integer calue to 2346H).

25FDH – AND logic.

25FDH
LD A,E
Load register A with the LSB of the first value in register E.
25FEH
AND L
Combine the LSB of the first value in register A with the LSB of the second value in register L.
25FFH
LD L,A
Load register L with the ANDed value in register A.
2600H
LD A,H
Load register A with the MSB of the second value in register H.
2601H
AND D
Combine the MSB of the first value in register D with the MSB of the second value in register A.
2602H
RET
Return to 27FAH (=Make the result an integer and return to 2346H).
2603H
DEC HL
Decrement the value of the BASIC program pointer in HL.
2604H
RST 10H
We need the next character in the BASIC program so call the EXAMINE NEXT SYMBOL routine at RST 10H.
NOTE:
  • The RST 10H routine loads the next character from the string pointed to by the HL register into the A-register and clears the CARRY flag if it is alphabetic, or sets it if is alphanumeric.
  • Blanks and control codes 09H and 0BH are ignored causing the following character to be loaded and tested.
  • The HL register will be incremented before loading any character therfore on the first call the HL register should contain the string address minus one.
  • The string must be terminated by a byte of zeros.
2605H
RET Z
Return if this is the end of the BASIC statement.
2606H-2607H
RST 08H
2CH
Since the character at the location of the current BASIC program pointer in HL must be a ,, call the COMPARE SYMBOL routine at RST 08H.

NOTE: The RST 08H routine compares the symbol in the input string pointed to by HL register to the value in the location following the RST 08 call.
  • If there is a match, control is returned to the next execution address (i.e, the RST 08H instruction + 2) with the next symbol in the A Register and HL incremented by one.
  • If the two characters do not match, a syntax error message is given and control returns to the Input Phase).

2608H – DIM logic.

2608H-260AH
LD BC,2603H
Load BC with a return address of 2603H.
260BH
PUSH BC
Save the return address of 2603H (in BC) to the stack.

260DH – This is the variable location and creation logic.

  • This routine will return the address of a variable in memory or create it if it is not found. In order to use this routine, the HL must point to the variable name (ASCII). Then, after execution, HL will point to the character following the variable name and the location of the variable will be returned in the DE register pair. For integer, single or doubleprecision (NTF=2, 4 or 8) the address returned in DE will be the same as for the VARPTR command under BASIC. (see Level II BASIC manual on VARPTR) For strings (NTF=3) however the address returned in DE will point to the first of three bytes containing the string length and string address.
    This entry point searches the Variable List Table (VLT) for a variable name which matches the name in the string pointed to by HL. If the variable exists, its address is returned in DE. If it is not defined, then it is created with an initial value ofzero and its address is returned in DE. Dimensioned and non-dimensioned variables may be located, and suffixs for data mode may be included in the name string. A byte of machine zeros must terminate the name string. All registers are used.
260CH-260DH
OR AFH
Reset the value in register A.
260EH-2610H
LD (40AEH),A
Save the value in register A as the current variable location/creation flag.
Note: 40AEH holds LOCATE/CREATE variable flag.
2611H
LD B,(HL)
Load register B with the first character of the variable name.
2612H-2614H
Gosub to 1E3DH to make sure the first character of the variable name is a letter.
2615H-2617H
Display a ?SN ERROR if the first character of the variable name isn’t a letter.
2618H
XOR A
Zero register A.
2619H
LD C,A
Zero register C.
261AH
RST 10H
We need the next character in the BASIC program so call the EXAMINE NEXT SYMBOL routine at RST 10H.
NOTE:
  • The RST 10H routine loads the next character from the string pointed to by the HL register into the A-register and clears the CARRY flag if it is alphabetic, or sets it if is alphanumeric.
  • Blanks and control codes 09H and 0BH are ignored causing the following character to be loaded and tested.
  • The HL register will be incremented before loading any character therfore on the first call the HL register should contain the string address minus one.
  • The string must be terminated by a byte of zeros.
261BH-261CH
Jump to 2622H if the character at the location of the current BASIC program pointer in register A is numeric.
261DH-261FH
Gosub to 1E3DH to check to see if the character at the location of the current BASIC program pointer is a letter.
2620H-2621H
Jump to 262BH if the character at the location of the current BASIC program pointer in register A isn’t a letter.
2622H
LD C,A
Load register C with the second character of the variable name in register A.
2623H
RST 10H
We now need bump the value of the current BASIC program pointer until it points to the next character, call the EXAMINE NEXT SYMBOL routine at RST 10H.
NOTE:
  • The RST 10H routine loads the next character from the string pointed to by the HL register into the A-register and clears the CARRY flag if it is alphabetic, or sets it if is alphanumeric.
  • Blanks and control codes 09H and 0BH are ignored causing the following character to be loaded and tested.
  • The HL register will be incremented before loading any character therfore on the first call the HL register should contain the string address minus one.
  • The string must be terminated by a byte of zeros.
2624H-2625H
Loop back one optcode until a nonnumeric character is found.
2626H-2628H
Go check to see if the character at the location of the current BASIC program pointer in HL is alphabetic.
2629H-262AH
Jump back to 2623H if the character at the location of the current BASIC program pointer in HL is alphabetic.
262BH-262DH
LD DE,2652H
Load DE with a return address of 2652H.
262EH
PUSH DE
Save the value of the return address in DE to the stack.
262FH-2630H
LD D,02H
Load register D with an integer number type flag.
2631H-2632H
CP 25H
Check to see if the character at the location of the current BASIC program pointer in register A is a %.
2633H
RET Z
Return if the character at the location of the current BASIC program pointer in register A is a %.
2634H
INC D
Bump register D so that it will be equal to a string number type flag (02=INT, 03=STR, 04=SNG, 08=DBL).
2635H-2636H
CP 24H
Check to see if the character at the location of the current BASIC program pointer in register A is a $.
2637H
RET Z
Return if the character at the location of current BASIC program pointer in register A is a $.
2638H
INC D
Bump register D so that it will be equal to a single precision number type flag (02=INT, 03=STR, 04=SNG, 08=DBL).
2639H-263AH
CP 21H
Check to see if the character at the location of the current BASIC program pointer in register A is a !.
263BH
RET Z
Return if the character at the location of the current BASIC program pointer in register A is a !.
263CH-263DH
LD D,08H
Load register D with a double precision number type flag. We have to do this because 04H (SNG) would bump to 05H if we just did another INC, but we need 08H for DBL.
263EH-263FH
CP 23H
Check to see if the character at the location of the current BASIC program pointer in register A is a #.
2640H
RET Z
Return if the character at the location of the current BASIC program pointer in register A is a #.
2641H
LD A,B
Load register A with the first character of the variable name in register B.
2642H-2643H
SUB 41H
Adjust the value of the first character of the variable name in register A so that it is in the range of 0 to 25.
2644H-2645H
AND 7FH
Make sure the sign bit in register A isn’t set by ANDing it against 0111 1111.
2646H
LD E,A
Load register E with the adjusted first character of the variable name in register A.
2647H-2648H
LD D,00H
Load register D with zero.
2649H
PUSH HL
Save the value of the current BASIC program pointer in HL to the stack.
264AH-264CH
LD HL,4101H
Load HL with the starting address of the variable declaration table.
NOTE: 4101H-411AH holds Variable Declaration Table.
264DH
ADD HL,DE
Add the value of the first character of the variable name in DE to the starting address of the variable declaration table in HL.
264EH
LD D,(HL)
Load register D with the number type value at the location of the variable declaration table pointer in HL.
264FH
POP HL
Get the value of the current BASIC program pointer from the stack and put it in HL.
2650H
DEC HL
Decrement the value of the current BASIC program pointer in HL.
2651H
RET
Return with data type in D.
2652H
LD A,D
Load register A with the value of the number type flag in register D.
2653H-2655H
LD (40AFH),A
Save the number type flag for the current variable name in register A.
NOTE: 40AFH holds Current number type flag.
2656H
RST 10H
We need the next character in the BASIC program so call the EXAMINE NEXT SYMBOL routine at RST 10H.
NOTE:
  • The RST 10H routine loads the next character from the string pointed to by the HL register into the A-register and clears the CARRY flag if it is alphabetic, or sets it if is alphanumeric.
  • Blanks and control codes 09H and 0BH are ignored causing the following character to be loaded and tested.
  • The HL register will be incremented before loading any character therfore on the first call the HL register should contain the string address minus one.
  • The string must be terminated by a byte of zeros.
2657H-2659H
LD A,(40DCH)
Load register A with the FOR flag.
Note: 40DCH holds FOR flag.
265AH
OR A
Test the value of the FOR flag in register A.
265BH-265DH
Jump to 2664H if a FOR statement is being processed.
265EH
LD A,(HL)
Re-fetch the next element of the code string by loading register A with the character at the location of the current BASIC program pointer in HL.
265FH-2660H
SUB 28H
Check to see if the character at the location of the current BASIC program pointer in register A is a (.
2661H-2663H
Jump to 26E9H if the character at the location of the current BASIC program pointer in register A is a ( (meaning, it is a subscripted variable).
2664H
XOR A
Zero register A.
2665H-2667H
LD (40DCH),A
Set the array flag to ‘no subscript’.
Note: 40DCH holds FOR flag.
2668H
PUSH HL
Save the value of the current BASIC program pointer in HL to the stack.
2669H
PUSH DE
Save the number type flag for the variable in DE to the stack.
266AH-266CH
LD HL,(40F9H)
Load HL with the value of the simple variables pointer.
  • Note: 40F9H-40FAH holds the starting address of the simple variable storage area.
266DH
EX DE,HL
Load DE with the simple variables pointer in HL. We don’t care what happens to HL.
266EH-2670H
LD HL,(40FBH)
Load HL with the array variables pointer.
  • Note: 40FBH-40FCH holds the starting address of the BASIC array variable storage area.
2671H
RST 18H
Now we need to compare the value of the simple variables pointer in DE with the array variables pointer in HL, so we call the COMPARE DE:HL routine at RST 10H.
NOTE:
  • The RST 10H routine loads the next character from the string pointed to by the HL register into the A-register and clears the CARRY flag if it is alphabetic, or sets it if is alphanumeric.
  • Blanks and control codes 09H and 0BH are ignored causing the following character to be loaded and tested.
  • The HL register will be incremented before loading any character therfore on the first call the HL register should contain the string address minus one.
  • The string must be terminated by a byte of zeros.
2672H
POP HL
Get the number type flag for the variable from stack and put it in HL.
2673H-2674H
Jump to 268EH if the simple variables pointer in DE is greater than or equal to the array variables pointer (meaning the variable wasn’t defined).
2675H
LD A,(DE)
Load register A with the number type flag for the variable at the location of the simple variables pointer in DE.
2676H
LD L,A
Load register L with the number type flag in register A.
2677H
CP H
Compare the number type flag for the variable in register H to the number type flag in register A.
2678H
INC DE
Bump the value of the current simple variables pointer in DE to the 2nd character name for this entry.
2679H-267AH
Jump to 2686H (i..e, the next variable in the list) if the number type flags don’t match.
267BH
LD A,(DE)
Since the type matches, compare the 2nd character of the name by loading register A with the first character of variable name at the location of the simple variables pointer in DE.
267CH
CP C
Compare the character at the location of the simple variables pointer in register A with the first character of the variable name in register C.
267DH-2637H
Jump to 2686H if the first characters of the variable names don’t match.
267FH
INC DE
Bump the value of the current simple variables pointer in DE.
2680H
LD A,(DE)
Load register A with the second character of the variable name at the location of the simple variables pointer in DE.
2681H
CP B
Compare the character at the location of the simple variables pointer in register A with the first character of the variable name in register B.
2682H-2684H
Jump to 26CCH if the character at the location of the simple variables pointer in register A matches the first character of the variable name in register B.
2685H-2686H
LD A,13H
Z-80 Trick to skip the next INC DE if continuing through.
2686H
INC DE
Bump to the next entry in the simple variable list part 1.
2687H
INC DE
Bump the value of the simple variables pointer in DE part 2.
2688H
PUSH HL
Save the number type flag for the variable in HL to the stack so that it can be re-loaded at 2672H.
2689H-268AH
LD H,00H
Load register H with zero.
268BH
ADD HL,DE
Add the value of the simple variables pointer in DE to the value of the number type flag in HL.
268CH-268DH
Loop back to 266DH.
268EH
LD A,H
Load register A with the number type flag for the variable in register H.
268FH
POP HL
Get the value of the current BASIC program pointer from the stack and put it in HL.
2690H
EX (SP),HL
Exchange the value of the current BASIC program pointer in HL with the value to the stack.
2691H
PUSH AF
Save the number type flag for the variable in register A to the stack.
2692H
PUSH DE
Save the start of the array variables pointer in DE to the stack.
2693H-2695H
LD DE,24F1H
Load DE with a VARPTR locator return address of 24F1H.
2696H
RST 18H
Now we need to compare the return address in DE with the return address in HL, so we call the COMPARE DE:HL routine at RST 10H.
NOTE:
  • The RST 10H routine loads the next character from the string pointed to by the HL register into the A-register and clears the CARRY flag if it is alphabetic, or sets it if is alphanumeric.
  • Blanks and control codes 09H and 0BH are ignored causing the following character to be loaded and tested.
  • The HL register will be incremented before loading any character therfore on the first call the HL register should contain the string address minus one.
  • The string must be terminated by a byte of zeros.
2697H-2698H
Jump forward to 26CFH if this routine is called from the VARPTR routine.
2699H-269BH
LD DE,2543H
Load DE with a return address of the find address of variables routine at 2543H.
269CH
RST 18H
We need to see if we were called from the ‘find address of variable’ routine so we need to compare the return address in DE with the return address in HL, so we call the COMPARE DE:HL routine at RST 10H.
NOTE:
  • The RST 10H routine loads the next character from the string pointed to by the HL register into the A-register and clears the CARRY flag if it is alphabetic, or sets it if is alphanumeric.
  • Blanks and control codes 09H and 0BH are ignored causing the following character to be loaded and tested.
  • The HL register will be incremented before loading any character therfore on the first call the HL register should contain the string address minus one.
  • The string must be terminated by a byte of zeros.
269DH
POP DE
Get the value of the array variables pointer from the stack and put it in DE.
269EH-269FH
Jump to 26D5H if this routine is called to locate the variables address.
26A0H
POP AF
Clear the stack and put the value of the number type flag for the variable from the stack and put it in register A.
26AlH
EX (SP),HL
Exchange the value of the current BASIC program pointer to the stack with the value of the return address in HL.
26A2H
PUSH HL
Save the value of the current BASIC program pointer in HL to the stack.
26A3H
PUSH BC
Save the variable’s name in BC to the stack.
26A4H
LD C,A
Load register C with the value of the number type flag for the variable in register A.
26A5H-26A6H
LD B,00H
Load register B with zero.
26A7H
PUSH BC
Save the variable’s number type flag in BC to the stack.
26A8H
INC BC
Bump the value of the variable’s number type flag in BC.
26A9H
INC BC
Bump the value of the variable’s number type flag in BC.
26AAH
INC BC
Bump the value of the variable’s number type flag in BC. Now that we are done bumping BC, we have the type + 3 (which is 3 bytes of overhead and a spare for the variable).
26ABH-26ADH
LD HL,(40FDH)
Load HL with the value of the free memory pointer.
Note: 40FDH-40FEH holds Free memory pointer.
26AEH
PUSH HL
Save the value of the free memory pointer in HL to the stack.
26AFH
ADD HL,BC
Add the value of the variable’s number type flag in BC to the value of the free memory pointer in HL.
26B0H
POP BC
Get the value of the free memory pointer from the stack and put it in BC.
26BlH
PUSH HL
Save the value of the new free memory pointer in HL to the stack.
26B2H-26B4H
Move the array variables up in memory.
26B5H
POP HL
Get the value of the new free memory pointer from the stack and put it in HL.
26B6H-26B8H
LD (40FDH),HL
Save the value of the new free memory pointer in HL to lock in that variable space.
NOTE: 40FDH-40FEH holds Free memory pointer.
26B9H
LD H,B
Load register H with the MSB of the new array variables pointer in register B.
26BAH
LD L,C
Load register L with the LSB of the new array variables pointer in register C.
26BBH-26BDH
LD (40FBH),HL
Save the value of the new array variables pointer in HL.
  • Note: 40FBH-40FCH holds the starting address of the BASIC array variable storage area.
26BEH
DEC HL
Decrement the value of the array variables pointer in HL.
26BFH-26C0H
LD (HL),00H
Zero the location of the memory pointer in HL.
26ClH
RST 18H
Now we need to check to see if the variable has been completely zeroed, so we call the COMPARE DE:HL routine at RST 10H.
NOTE:
  • The RST 10H routine loads the next character from the string pointed to by the HL register into the A-register and clears the CARRY flag if it is alphabetic, or sets it if is alphanumeric.
  • Blanks and control codes 09H and 0BH are ignored causing the following character to be loaded and tested.
  • The HL register will be incremented before loading any character therfore on the first call the HL register should contain the string address minus one.
  • The string must be terminated by a byte of zeros.
26C2H-26CJH
Loop back to 26BEH until the variable has been cleared.
26C4H
POP DE
Get the value of the variable’s number type flag from the stack and put it in DE.
26C5H
LD (HL),E
Save the value of the number type flag in register E at the location of the memory pointer in HL.
26C6H
INC HL
Bump the value of the memory pointer in HL.
26C7H
POP DE
Get the 2nd character of the variable’s name from the stack and put it in DE.
26C8H
LD (HL),E
Save the first character of the variable’s name in register E at the location of the memory pointer in HL.
26C9H
INC HL
Bump the value of the memory pointer in HL.
26CAH
LD (HL),D
Save the first character of the variable’s name in register D at the location of the memory pointer in HL.
26CBH
EX DE,HL
Load DE with the value of the variable pointer in HL.
26CCH
INC DE
Bump the value of the variable pointer in DE.
26CDH
POP HL
Get the value of the current BASIC program pointer from the stack and put it in HL.
26CEH
RET
Return.
26CFH
LD D,A
Load register D with the value of the current number type flag in register A.
26D0H
LD E,A
Load register E with the value of the current number type flag in register A.
26D1H
POP AF
Clean up the stack.
26D2H
POP AF
Clean up the stack.
26D3H
EX (SP),HL
Exchange the value of the return address in HL with the value of the current BASIC program pointer to the stack.
26D4H
RET
Return to the VARPTR routine.

26D5H – This routine is to locate a subscripted variable.

26D5H-26D7H
LD (4124H),A
Zero REG 1.
26D8H
POP BC
Clean up the stack.
26D9H
LD H,A
Zero register H.
26DAH
LD L,A
Zero register L.
26DBH-26DDH
LD (4121H),HL
Zero the string pointer location in REG 1.
26DEH
RST 20H
We need to check the value of the current number type flag, so we call the TEST DATA MODE routine at RST 20H.
NOTE: The RST 20H routine determines the type of the current value in REG 1 and returns a combination of STATUS flags and unique numeric values in the A Register according to the data mode flag (40AFH).

The results are returned as follows:
  • Integer = NZ/C/M/E and A is -1
  • String = Z/C/P/E and A is 0
  • Single Precision = NZ/C/P/O and A is 1
  • and Double Precision is NZ/NC/P/E and A is 5.
26DFH-26E0H
If that test shows we do NOT have a STRING, jump to 26E7H.
26E1H-26E3H
LD HL,1928H
Load HL with the starting address of the Level II BASIC READY message.
26E4H-26E6H
LD (4121H),HL
Save the value in HL as the current string pointer.
26E7H
POP HL
Get the value of the current BASIC program pointer from the stack and put it in HL.
26E8H
RET
Return.

26E9H – This routine locates the address of a subscripted variable.

  • On entry D = the type of variable, B = the 1st character of the variable name, C = the 2nd character of the variable name, and HL = the current position in the input string.
26E9H
PUSH HL
Save the value of the current BASIC program pointer in HL to the stack.
26EAH-26ECH
LD HL,(40AEH)
Load HL with the value of the locate/create flag.
Note: 40AEH holds LOCATE/CREATE variable flag and will be a 0 if in locate mode and anything other than zero if in create mode.
26EDH
EX (SP),HL
Exchange the value of the locate/create flag in HL with the value of the current BASIC program pointer to the stack.
26EEH
LD D,A
Zero register D.
26EFH
PUSH DE
Save the variable’s number type flag in DE to the stack.
26F0H
PUSH BC
Save the variable’s name in BC to the stack.
26FlH-26F3H
Go evaluate the array subscript at the location of the current BASIC program pointer in HL up to a ) or ,. Return with the binary value in DE.
26F4H
POP BC
Get the variable’s name from the stack (1st and 2nd character) and put it in BC.
26F5H
POP AF
Get the variable’s number type flag from the stack and put it in register A.
26F6H
EX DE,HL
Exchange the value of the array subscript in DE with the value of the current BASIC program pointer in HL.
26F7H
EX (SP),HL
Exchange the value of the array subscript in HL with the value of the locate/create flag to the stack.
26F8H
PUSH HL
Save the value of the locate/create flag in HL to the stack.
26F9H
EX DE,HL
Exchange the value of the locate/create flag in HL with the value of the current BASIC program pointer in DE.
26FAH
INC A
Bump the number of subscripts evaluated in register A.
26FBH
LD D,A
Load register D with the number of subscripts evaluated in register A.
26FCH
LD A,(HL)
Load register A with the character at the location of the current BASIC program pointer in HL.
26FDH-26FEH
CP 2CH
Check to see if the character at the location of the current BASIC program pointer in register A is a ,.
26FFH-2700H
Jump if the character at the location of the current BASIC program pointer in register A is a ,.
2701H-2702H
RST 08H
29H
Since the character at the location of the current BASIC program pointer in HL must be a ), call the COMPARE SYMBOL routine at RST 08H.

NOTE: The RST 08H routine compares the symbol in the input string pointed to by HL register to the value in the location following the RST 08 call.
  • If there is a match, control is returned to the next execution address (i.e, the RST 08H instruction + 2) with the next symbol in the A Register and HL incremented by one.
  • If the two characters do not match, a syntax error message is given and control returns to the Input Phase).
2703H-2705H
LD (40F3H),HL
Save the value of the current BASIC program pointer in HL.
2706H
POP HL
Get the value of the locate/ create flag from the stack and put it in HL.
NOTE: 40F3H-40F4H holds Temporary storage location.
2707H-2709H
LD (40AEH),HL
Save the value of the locate/create flag in HL.
NOTE: 40AEH holds LOCATE/CREATE variable flag.
270AH
PUSH DE
Save the number of subscripts evaluated in DE.
270BH-270DH
LD HL,(40FBH)
Load HL with the value of the array variables pointer.
  • Note: 40FBH-40FCH holds the starting address of the BASIC array variable storage area.
270EH-270FH
LD A,19H
Z-80 Trick to skip the next command of ADD HL, DE if falling through.
270FH
ADD HL,DE
Figure the end of the array. Note: 40FBH-40FCH holds the array variables pointer.
2710H
EX DE,HL
Load DE with the value of the array variables pointer in HL.
2711H-2713H
LD HL,(40FDH)
Load HL with the value of the free memory pointer.
Note: 40FDH-40FEH holds Free memory pointer.
2714H
EX DE,HL
Exchange the value of the free memory pointer in HL with the value of the array variables pointer in DE.
2715H
RST 18H
Now we need to compare the value of the free memory pointer in DE to the value of the array variables pointer in HL, so we call the COMPARE DE:HL routine at RST 10H.
NOTE:
  • The RST 10H routine loads the next character from the string pointed to by the HL register into the A-register and clears the CARRY flag if it is alphabetic, or sets it if is alphanumeric.
  • Blanks and control codes 09H and 0BH are ignored causing the following character to be loaded and tested.
  • The HL register will be incremented before loading any character therfore on the first call the HL register should contain the string address minus one.
  • The string must be terminated by a byte of zeros.
2716H-2718H
LD A,(40AFH)
Load register A with the value of the current number type flag.
Note: 40AFH holds Current number type flag.
2719H-271AH
Jump forward out of this loop to 2742H if the array variables pointer in HL is greater than or equal to the value of the free memory pointer in DE.
271BH
CP (HL)
Compare the value of the variable’s number type flag in register A with the value of the number type flag at the location of the array variables pointer in HL.
271CH
INC HL
Bump the value of the array variables pointer in HL.
271DH-271EH
Jump forward (but still in this loop) to 2727H if the number type flags don’t match.
271FH
LD A,(HL)
Load register A with the first character of the variable name at the location of the array variables pointer in HL.
2720H
CP C
Check to see if the first character of the variable at the location of the array variable pointer in register A matches the first character of the variable name in register C.
2721H
INC HL
Bump the value of the array variables pointer in HL.
2722H-2723H
Jump forward (but still in this loop) to 2728H if the first characters of the variable names don’t match.
2724H
LD A,(HL)
Load register A with the second character of the variable name at the location of the array variables pointer in HL.
2725H
CP B
Compare the second character of the variable name at the location of the array variables pointer in register A matches the second character of the variable name in register B.
2727H
LD A,23H
Bump the value of the array variables pointer in HL.
2728H
INC HL
Bump the value of the array variables pointer in HL.
2729H
LD E,(HL)
Load register E with the LSB of the offset to the next array at the location of the array variables pointer in HL.
272AH
INC HL
Bump the value of the array variables pointer in HL.
272BH
LD D,(HL)
Load register D with the MSB of the offset to the next array at the location of the array variables pointer in HL.
272CH
INC HL
Bump the value of the array variables pointer in HL.
272DH-272EH
Jump back to 270FH if the variables’ names don’t match.
272FH-2731H
LD A,(40AEH)
Load register A with the value of the locate/create flag.
Note: 40AEH holds LOCATE/CREATE variable flag.
2732H
OR A
Check the status of the locate/create flag in register A.
2733H-2734H
LD E,12H
Load register E with the ?DD ERROR code.
2735H-2737H
Display a ?DD ERROR message if the locate/create flag in register A indicates the create mode since that variable already exists.
2738H
POP AF
Get the number of subscripts evaluated from the stack and put it in register A.
2739H
SUB (HL)
Compare the number of subscripts evaluated in register A with the number of subscripts for the array at the location of the array variables pointer in HL (meaning, the number which was DIMmed).
273AH-273CH
Jump down to 2795H if the number of subscripts evaluated in register A matches the number of subscripts for the array at the location of the array variables pointer in HL.

273DH – BS ERROR entry point.

273DH-273EH
LD E,10H
Load register E with a ?BS ERROR code.
273FH-2741H
Display a ?BS ERROR message if the number of subscripts evaluated in register A doesn’t match the number of subscripts for the array at the location of the array variable pointer in HL.
2742H
LD (HL),A
Save the number of subscripts for the array in register A at the location of the array variables pointer in HL.
2743H
INC HL
Bump the value of the array variables pointer in HL so it points to the 2nd character in the variable name (since they are saved in last, first order).
2744H
LD E,A
Load register E with the number type flag for the current variable.
2745H-2746H
LD D,00H
Zero register D.
2747H
POP AF
Get the number of subscripts evaluated from the stack and put it in register A.
2748H
LD (HL),C
Save the second character of the variable’s name in register C at the location of the array variables pointer in HL.
2749H
INC HL
Bump the value of the array variables pointer in HL to now point to the 1st character in the variable name (since they are saved in last, first order).
274AH
LD (HL),B
Save the first character of the variable’s name in register B at the location of the array variables pointer in HL.
274BH
INC HL
Bump the value of the array variables pointer in HL to the LSB of the offset to the next entry.
274CH
LD C,A
Load register C with the number of subscripts evaluated in register A.
274DH-274FH
Figure the amount of memory space left between HL and the free memory.
2750H
INC HL
Bump the value of the array variables pointer in HL.
2751H
INC HL
Bump the value of the array variables pointer in HL. These 2 INC’s skip over the offset entry.
2752H-2754H
LD (40D8H),HL
Save the value of the array variables pointer in HL to 40D8H (which is the address of the maximum number of indices).
Note: 40D8H-40D9H holds temporary storage location.
2755H
LD (HL),C
Save the number of subscripts evaluated in register C (1, 2, or 3) at the location of the array variables pointer in HL.
2756H
INC HL
Bump the value of the array variables pointer in HL to point to the first subscript entry in the array table.
2757H-2759H
LD A,(40AEH)
Load register A with the value of the locate/create flag.
Note: 40AEH holds LOCATE/CREATE variable flag.
275AH
RLA
Set the CARRY flag to be 0 for locate and 1 for create.
275BH
LD A,C
Load register A with the number of subscripts evaluated in register C.
275CH-275EH
LD BC,000BH
Load BC with the default number of 11, which is the most entries an array can have without a DIM.
275FH-2760H
Jump forward to 2763H if the array is being created because it certainly wasn’t found.
2761H
POP BC
Get a subscript from the stack and put it in BC.
2762H
INC BC
Bump the value of the subscript in BC.
276JH
LD (HL),C
Save the LSB of the subscript’s value in register C at the location of the array variables pointer in HL.
2764H
INC HL
Bump the value of the array variables pointer in HL.
2765H
LD (HL),B
Save the MSB of the subscript’s value in register B at the location of the array variables pointer in HL.
2766H
INC HL
Bump the value of the array variables pointer in HL.
2767H
PUSH AF
Save the number of subscripts evaluated in register A to the stack.
2768H-276AH
Go multiply the size of the subscript by the value of the number type flag to determine the amount of memory necessary for the subscript.
276BH
POP AF
Get the number of subscripts evaluated from the stack and put it in register A.
276CH
DEC A
Check to see if there are anymore subscripts to be evaluated.
276DH-276EH
Jump back to 275CH if there are anymore subscripts to be evaluated.
276FH
PUSH AF
Save the number of subscripts to be evaluated in register A to the stack.
2770H
LD B,D
Load register B with the MSB of the array’s length in register D.
2771H
LD C,E
Load register C with the LSB of the array’s length in register E. Now BC = length of the array in bytes.
2772H
EX DE,HL
Load DE with the value of the array variables pointer in HL.
2773H
ADD HL,DE
Add the length of the array in HL to the value of the array variable pointer in DE.
2774H-2775H
Jump back to 273DH if overflow occurred.
2776H-2778H
Go check to see if there is enough memory for the array.
2779H-277BH
LD (40FDH),HL
Get the end of the array and put it in HL.
Note: 40FDH-40FEH holds free memory pointer.
277CH
DEC HL
Decrement the value of the array pointer in HL.
277DH-277EH
LD (HL),00H
Zero the location of the array pointer in HL.
277FH
RST 18H
Now we need to compare the array pointer in HL with the array variables pointer in DE, so we call the COMPARE DE:HL routine at RST 10H.
NOTE:
  • The RST 10H routine loads the next character from the string pointed to by the HL register into the A-register and clears the CARRY flag if it is alphabetic, or sets it if is alphanumeric.
  • Blanks and control codes 09H and 0BH are ignored causing the following character to be loaded and tested.
  • The HL register will be incremented before loading any character therfore on the first call the HL register should contain the string address minus one.
  • The string must be terminated by a byte of zeros.
2780H-2781H
Loop until the array has been cleared.
2782H
INC BC
Load BC with the array’s length in bytes plus one.
2783H
LD D,A
Zero register D.
2784H-2786H
LD HL,(40D8H)
Load HL with the array variables pointer (=the number of indices).
Note: 40D8H-40D9H holds Temporary storage location.
2787H
LD E,(HL)
Load register E with the number of subscripts for the array at the location of the array variables pointer in HL.
2788H
EX DE,HL
Exchange the value of the array variables pointer in HL with the number of subscripts for the array in DE.
2789H
ADD HL,HL
Multiply the number of subscripts for the array in HL by two.
278AH
ADD HL,BC
Add the length of the array in BC to the number of subscripts times two in HL.
278BH
EX DE,HL
Exchange the array’s length in HL with the array variables pointer in DE.
278CH
DEC HL
Decrement the value of the array variables pointer in HL.
278DH
DEC HL
Decrement the value of the array variables pointer in HL.
278EH
LD (HL),E
Save the LSB of the offset to the next array in register E at the location of the array variables pointer in HL.
278FH
INC HL
Bump the value of the array variables pointer in HL.
2790H
LD (HL),D
Save the MSB of the offset to the next array in register D at the location of the array variables pointer in HL.
2791H
INC HL
Bump the value of the array variables pointer in HL.
2792H
POP AF
Get the value of the locate/ create flag from the stack and put it in register A.
2793H-2794H
Jump forward to 27C5H if the array is being created.
2795H
LD B,A
Zero register B.
2796H
LD C,A
Zero register C.
2797H
LD A,(HL)
Load register A with the number of subscripts for the array at the location of the array variables pointer in HL.
2798H
INC HL
Bump the value of the array variables pointer in HL.
2799H
16H E1H
Z-80 Trick to hide the next instruction (POP HL) if proceeding downward.
279AH
POP HL
Get the array variables pointer from the stack and put it in HL.
279BH
LD E,(HL)
Load register E with the LSB of the subscript limit at the location of the array variables pointer in HL.
279CH
INC HL
Bump the value of the array variables pointer in HL.
279DH
LD D,(HL)
Load register D with the MSB of the subscript limit at the location of the array variables pointer in HL.
279EH
INC HL
Bump the value of the array variables pointer in HL.
279FH
EX (SP),HL
Exchange the value of the array variables pointer in HL with the subscript to the stack.
27A0H
PUSH AF
Save the number of subscripts for the array in register A to the stack.
27A1H
RST 18H
Now we need to compare the subscript limit in DE with the subscript for the array in HL, so we call the COMPARE DE:HL routine at RST 10H.
NOTE:
  • The RST 10H routine loads the next character from the string pointed to by the HL register into the A-register and clears the CARRY flag if it is alphabetic, or sets it if is alphanumeric.
  • Blanks and control codes 09H and 0BH are ignored causing the following character to be loaded and tested.
  • The HL register will be incremented before loading any character therfore on the first call the HL register should contain the string address minus one.
  • The string must be terminated by a byte of zeros.
27A2H-27A4H
Jump back to 273DH if the subscript for the array in HL is greater than the subscript limit in DE.
27A5H-27A7H
Multiply the previous subscript by the subscript limit.
27A8H
ADD HL,DE
Add the subscript limit for the array in DE to the array pointer in HL.
27A9H
POP AF
Get the number of subscripts for the array from the stack and put it in register A.
27AAH
DEC A
Check to see if there are anymore subscripts to be evaluated.
27ABH
LD B,H
Load register B with the MSB of the subscript pointer in register H.
27ACH
LD C,L
Load register C with the LSB of the subscript pointer in register L.
27ADH-27AEH
Loop back to 279AH until all of the subscripts have been evaluated.
27AFH-27B1H
LD A,(40AFH)
Get the number type flag for the current array.
NOTE: 40AFH holds Current number type flag.
27B2H
LD B,H
Load register B with the MSB of the subscript pointer in register H.
27B3H
LD C,L
Load register C with the LSB of the subscript pointer in register L.
27B4H
ADD HL,HL
Multiply the subscript pointer in HL by two.
27B5H-27B6H
SUB 04H
Check the value of the number type flag in register A.
27B7H-27B8H
Jump forward to 27BDH if the current number type is an integer or string.
27B9H
ADD HL,HL
It isn’t an integer or a string so once again multiply the subscript pointer in HL by two (so now it is multiplied by 4).
27BAH-27BBH
Jump forward to 27C2H if the current number type is single precision.
27BCH
ADD HL,HL
It must be double precision, so once again multiply the subscript pointer in HL by two (so now it is multiplied by 8).
27BDH
OR A
Set the flags.
27BEH-27C0H
Jump forward to 27C2H if the current number type isn’t a string.
27C1H
ADD HL,BC
The current number type is a string so add the value of the original subscript pointer in BC to the subscript pointer in HL.
27C2H
POP BC
Get the value of the array variables pointer from the stack and put it in BC.
27C3H
ADD HL,BC
Add the value of the array variables pointer in BC to the subscript pointer in HL.
27C4H
EX DE,HL
Load DE with the variable pointer in HL.
27C5H-27C7H
LD HL,(40F3H)
Get the value of the current BASIC program pointer and put it in HL.
Note: 40F3H-40F4H holds Temporary storage location.
27C8H
RET
Return.

27C9H-27D3H – LEVEL II BASIC MEM ROUTINE

  • This is the RETURN AMOUNT OF FREE MEMORY routine at 27C9H which computes the amount of memory remaining between the end of the variable list and the end of the stack and puts the result in REG 1 as a SINGLE PRECISION number.
27C9H
XOR A
Zero register A and the status flags.
27CAH
PUSH HL
Save the value of the current BASIC program pointer in HL to the stack.
27CBH-27CDH
LD (40AFH),A
Zero the number type flag.
NOTE: 40AFH holds Current number type flag.
27CEH-27D0H
Gosub to the FRE routine at 27D4H.
27D1H
POP HL
Get the value of the current BASIC program pointer from the stack and put it in HL.
27D2H
RST 10H
We need the next character in the BASIC program so call the EXAMINE NEXT SYMBOL routine at RST 10H.
NOTE:
  • The RST 10H routine loads the next character from the string pointed to by the HL register into the A-register and clears the CARRY flag if it is alphabetic, or sets it if is alphanumeric.
  • Blanks and control codes 09H and 0BH are ignored causing the following character to be loaded and tested.
  • The HL register will be incremented before loading any character therfore on the first call the HL register should contain the string address minus one.
  • The string must be terminated by a byte of zeros.
27D3H
RET
Return to BASIC.

27D4H-27F4H – LEVEL II BASIC FRE ROUTINE

27D4H-27D6H
LD HL,(40FDH)
Load HL with the start of free memory pointer.
NOTE: 40FDH-40FEH holds Free memory pointer.
27D7H
EX DE,HL
Load DE with the value of the free memory pointer in HL.
27D8H-27DAH
LD HL,0000H
Zero HL.
27DBH
ADD HL,SP
Add the value in HL (which is zero) to the current value of the stack pointer.
27DCH
RST 20H
We need to check the value of the current number type flag, so we call the TEST DATA MODE routine at RST 20H.
NOTE: The RST 20H routine determines the type of the current value in REG 1 and returns a combination of STATUS flags and unique numeric values in the A Register according to the data mode flag (40AFH).

The results are returned as follows:
  • Integer = NZ/C/M/E and A is -1
  • String = Z/C/P/E and A is 0
  • Single Precision = NZ/C/P/O and A is 1
  • and Double Precision is NZ/NC/P/E and A is 5.
27DDH-27DEH
If that test shows we do NOT have a STRING (meaning this was really a MEM call, jump to forward to 27ECH.
27DFH-27E1H
Get the address of the string into HL.
27E2H-27E1H
Go check to see how much string space remains.
27E5H-27E7H
LD HL,(40A0H)
Load HL with the start of string space pointer.
NOTE: 40A0H-40A1H holds the start of string space pointer.
27E8H
EX DE,HL
Load DE with the start of string space pointer in HL.
27E9H-27EBH
LD HL,(40D6H)
Load HL with the next available location in string space pointer.
NOTE: 40D6H-40D7H holds Next available location in string space pointer.
27ECH
LD A,L
Load register A with the LSB of the next available location in string space pointer in register L.
27EDH
SUB E
Subtract the LSB of the start of string space pointer in register E from the LSB of the next available location in string space pointer in register A.
27EEH
LD L,A
Load register L with the LSB of the amount of string space remaining in register A.
27EFH
LD A,H
Load register A with the MSB of the next available location in string space pointer in register H.
27F0H
SBC A,D
Subtract the MSB of the string space pointer in register D from the MSB of the next available location of string space pointer in register A.
27F1H
LD H,A
Load register H with the MSB of the amount of string space remaining in register A.
27F2H-27F4H
Jump to 0C66H to convert the difference between HL and DE to single precision and then RETurn out of the routine.

27F5H-27FDH – LEVEL II BASIC POS( ROUTINE

27F5H-27F7H
LD A,(40A6H)
Load register A with the current cursor line position.
Note: 40A6H holds the current cursor line position.
27F8H
LD L,A
Load register L with the value of the current cursor line position in register A.
27F9H
XOR A
Zero register A.
27FAH
LD H,A
Load register H with zero, so now HL is 00 / cursor position.
27FBH-27FDH
Jump to 0A9AH.

27FEH-2818H – LEVEL II BASIC USR(x) ROUTINE

27FEH-2800H
Go call the DOS link at 41A9H.
2801H
RST 10H
We need the next character so call the EXAMINE NEXT SYMBOL routine at RST 10H.
NOTE:
  • The RST 10H routine loads the next character from the string pointed to by the HL register into the A-register and clears the CARRY flag if it is alphabetic, or sets it if is alphanumeric.
  • Blanks and control codes 09H and 0BH are ignored causing the following character to be loaded and tested.
  • The HL register will be incremented before loading any character therfore on the first call the HL register should contain the string address minus one.
  • The string must be terminated by a byte of zeros.
2802H-2804H
Gosub to 252CH to evaluate the expression at the location of the current BASIC program pointer in HL and return with the result in REG 1.
2805H
PUSH HL
Save the value of the current BASIC program pointer in HL (=the address of the next element in the code string) to the stack.
2806H-2808H
LD HL,0890H
Load HL with the return address of 0890H which will clear the stack before returning to BASIC.
2809H
PUSH HL
Save the value of the return address in HL to the stack.
280AH-280CH
LD A,(40AFH)
Load register A with the value of the current number type flag.
Note: 40AFH holds Current number type flag.
280DH
PUSH AF
Save the value of the current number type flag in register A.
(02=INT, 03=STR, 04=SNG, 08=DBL).
280EH-280FH
CP 03H
Check to see if the current value in REG l is a string.
2810H-2812H
If the current result in REG l is a string then Gosub to 29DAH to get the string address into HL.
2813H
POP AF
Restore the number type flag into register A.
2814H
EX DE,HL
Load DE with the value of the string address in HL.
2815H-2817H
LD HL,(408EH)
Load HL with the starting address of the machine language subroutine.
  • Note: 408EH-408FH holds the entry address of a machine language program to be called by a USR command.
2818H
Jump to the address in HL.

2819H-2827H – CONVERSION ROUTINE
Usually called by LET to convert the result of arithmetic routines to the proper destination type.

2819H
PUSH HL
Save the value in HL to the stack.
281AH-281BH
AND 07H
Mask the value of the current number type flag in register A.
281CH-281EH
LD HL,18A1H
Load HL with the address of the arithmetic conversion routines.
281FH
LD C,A
Load register C with the value of the number type flag in register A.
(02=INT, 03=STR, 04=SNG, 08=DBL).
2820H-2821H
LD B,00H
Zero register B. Now BC holds 00 / type.
2822H
ADD HL,BC
Add the offset (of BC) to the base arithmetic conversion routines, to find the right jump point.
2823H-2825H
Gosub to 2586H to convert the current result in REG l to its proper number type.
2826H
POP HL
Get the value from the stack and put it in HL.
2827H
RET
Return.

2828H-2835H – Save the code string address
Usually called from the INPUT routine. On entry HL has the current line number in binary.

2828H
PUSH HL
Save the value of the current BASIC program pointer in HL to the stack.
2829H-282BH
LD HL,(40A2H)
Load HL with the value of the current BASIC line number.
  • Note: 40A2H-40A3H holds the current BASIC line number.
282CH
INC HL
Bump the value of the current BASIC line number in HL to enable us to test for a direct statement.
282DH
LD A,H
Load register A with the MSB of the current BASIC line number in register H.
282EH
OR L
Combine the LSB of the current BASIC line number in register L with the MSB of the current BASIC line number in register A.
282FH
POP HL
Get the value of the current BASIC program pointer from the stack and put it in HL.
2830H
RET NZ
Return if there is a line number (i.e., this isn’t the command mode).

2831H – ID ERROR entry point.

2831H-2832H
LD E,16H
Load register E with the ?ID ERROR code.
2833H-2835H
Display an ?ID ERROR if this is the command mode.

2836H-2856H – STRING ROUTINE – STR$ logic.

2836H-2838H
Gosub to 0FBDH to convert the current result in REG 1 to an ASCII string.
2839H-283BH
Go make a temporary string work area entry.
283CH-283EH
Load HL with the string’s VARPTR.
283FH-2841H
LD BC,2A2BH
Load BC with a return address of 2A2BH (which cleans the stack and then jumps to 2884H).
2842H
PUSH BC
Save the value of the return address in BC to the stack.
2843H
LD A,(HL)
Load register A with the string’s length at the location of the string’s VARPTR in HL.
2844H
INC HL
Bump the value of the string’s VARPTR in HL.
2845H
PUSH HL
Save the value of the string’s VARPTR in HL to the stack.
2846H-2848H
Gosub to 28BFH to test the remaining string area to make sure that the new string will fit.
2849H
POP HL
Reload HL with the string’s VARPTR.
284AH
LD C,(HL)
Load register C with the LSB of the string’s address at the location of the string’s VARPTR in HL.
284BH
INC HL
Bump the value of the string’s VARPTR in HL.
284CH
LD B,(HL)
Load register B with the MSB of the string’s address at the location of the string’s VARPTR in HL.
284DH-284FH
Gosub to 285AH to save the string’s length and the string’s address at 40D3H.
2850H
PUSH HL
Save the value in HL (which is 40D3H) to the stack.
2851H
LD L,A
Load register L with the string’s length (from register A).
2852H-2854H
Gosub to 29CEH to move the string from the temp area (of BC) to the string data area (in DE).
2855H
POP DE
Get the value from the stack (40D3H) and put it in DE.
2856H
RET
Return.

2857H-2864H – STRING ROUTINE

2857H-2859H
Gosub to 28BFH to make sure that there is enough string space remaining for the string. Get the address of the next string area in DE. Then save A and DE at 40D3H-40D5H.
285AH-285CH
LD HL,40D3H
Load HL with the address of the temporary string parameter storage area.
Note: 40D3H-40D5H holds Used for temporary string VARPTR’s.
285DH
PUSH HL
Save the address of the temporary string parameter area in HL to the stack.
285EH
LD (HL),A
Save the string’s length in register A at the location of the temporary string parameter storage pointer in HL.
285FH
INC HL
Bump the value of the temporary string parameter storage pointer in HL.
2860H
LD (HL),E
Save the LSB of the string’s address in register E at the location of the temporary string parameter storage pointer in HL.
2861H
INC HL
Bump the value of the temporary string parameter storage pointer in HL.
2862H
LD (HL),D
Save the MSB of the string’s address in register D at the location of the temporary string parameter storage pointer in HL.
2863H
POP HL
Get the address of the temporary string parameter storage area from the stack and put it in HL.
2864H
RET
Return.

2865H-28A5H – STRING ROUTINE
This is the quote routine. C will be a counter.

2865H
“CSVEC”
DEC HL
Decrement the value of the current BASIC program pointer in HL.
2866H-2867H
LD B,22H
Load register B with a " (which is really the opening search character).
2868H
LD D,B
Load register D with a " (which is really the ending search character).
2869H
PUSH HL
Save the address of the current BASIC program pointer in HL to the stack.
286AH-286BH
LD C,0FFH
Load register C with a -1.
286CH
INC HL
Bump the value of the current BASIC program pointer in HL to skip over that initial ".
286DH
LD A,(HL)
Load register A with the character at the location of the current BASIC program pointer in HL.
286EH
INC C
Bump the counter in register C.
286FH
OR A
Check to see if the character at the location of the current BASIC program pointer in register A is an end of the BASIC line character.
2870H-2871H
Jump to 2878H if the character at the location of the current BASIC program pointer in register A is an end of the BASIC line character.
2872H
CP D
Check to see if the character at the location of the current BASIC program pointer in register A is the same as the terminating character in register D.
2873H-2874H
Jump to 2878H if the character at the location of the current BASIC program pointer in register A is the same as the terminating character in register D.
2875H
CP B
Check to see if the character at the location of the current BASIC program point.er in register A is the same at the terminating character in register B.
2876H-2877H
Loop back to 286CH if the character at the location of the current BASIC program pointer in register A isn’t the same as the terminating character in register B.
2878H-2879H
CP 22H
Check to see if the character at the location of the current BASIC program pointer in register A is a quote.
287AH-287CH
If it was a quote, then gosub to 1D78H to bump the value of the current BASIC program pointer in HL until it points to the next character.
287DH
EX (SP),HL
Exchange the value of the current BASIC program pointer in HL with the string’s address to the stack.
287EH
INC HL
Bump the string’s address in HL until it points to the first character of the string.
287FH
EX DE,HL
Load DE with the string’s address in HL.
2880H
LD A,C
Load register A with the string’s length from register C.
2881H-2883H
Gosub to 285AH to save the string’s length and the string’s address into 40D3H.
2884H-2886H
LD DE,40D3H
Load DE with the address of the string parameter storage area.
Note: 40D3H-40D5H holds Used for temporary string VARPTR’s.
2887H-2888H
LD A,D5H
This seems to be garbage. Perhaps there is a jump to 2888 which would then be PUSH DE.
2889H-288BH
LD HL,(40B3H)
Load HL with the next available location in the temporary string work area in HL as the string’s VARPTR in REG 1.
Note: 40B3H-40B4H holds Next available location in the temporary string work area pointer.
288CH-288EH
LD (4121H),HL
Save the value of the next available location in the temporary string work area in HL as the string’s VARPTR in REG 1.
288FH-2890H
LD A,03H
Load register A with the string number type flag.
2891H-2893H
LD (40AFH),A
Save the value in register A as the current number type flag.
Note: 40AFH holds Current number type flag.
2894H-2896H
Add the length of the string to the next available location in the temporary string work area in HL.
2897H-2899H
LD DE,40D6H
Load DE with the ending address of the temporary string work area.
Note: 40D6H-40D7H holds Next available location in string space pointer.
289AH
RST 18H
Now we need to check to see if the updated temporary string work area location in HL isn’t greater than the ending address of the temporary string work area in DE, so we call the COMPARE DE:HL routine at RST 10H.
NOTE:
  • The RST 10H routine loads the next character from the string pointed to by the HL register into the A-register and clears the CARRY flag if it is alphabetic, or sets it if is alphanumeric.
  • Blanks and control codes 09H and 0BH are ignored causing the following character to be loaded and tested.
  • The HL register will be incremented before loading any character therfore on the first call the HL register should contain the string address minus one.
  • The string must be terminated by a byte of zeros.
289BH-289DH
LD (40B3H),HL
Save the updated string work area location in HL as the next available location in the temporary string work area.
Note: 40B3H-40B4H holds Next available location in the temporary string work area pointer.
289EH
POP HL
Get the value of the current BASIC program pointer from the stack and put it in HL.
289FH
LD A,(HL)
Load register A with the character at the location of the current BASIC program pointer in HL.
28A0H
RET NZ
Return if the updated temporary string work area location wasn’t beyond the end of the temporary string work area (meaning it overflowed, because if it overflowed …).

28A1H – ST ERROR entry point.

28A1H-28A2H
LD E,1EH
Load register E with a ?ST ERROR code.
28A3H-28A5H
Display a ?ST ERROR message if the temporary string work area has overflowed.

28A6H-28BEH – DISPLAY MESSAGE ROUTINE

28A6H
INC HL
Bump the value of the current BASIC program pointer in HL.

28A7H – This is a general purpose output routine. It will output data to the display, printer or cassette, depending on the contents of 409CH. (0=video, -1=tape, 1=printer). The address of the first character in the string to be output must be in the HL register pair, and the string must end with a zero byte or a quote (22H).
Note: 409CH holds the current output device flag: -1=cassette, 0=video and 1=printer.
This is the WRITE MESSAGE routine, which displays message pointed to by HL on current system output device (usually video). The string to be displayed must be terminated by a byte of machine zeros or a carriage return code 0D. If terminated with a carriage return, control is returned to the caller after taking the DOS exit at 41D0 (JP 5B99H). This subroutine uses th literal string pool table and the string area. It should not be called if the communications region and the string area are not properly maintained.

  • This routine has essentially the same effect as the routine at 2B75H, except that text may also end with a quotation mark (22H), creates string vector before output (destroys current contents of ACCUM, sets number type flag at 40AFH to 3 – see chapter two of this book), and also uses BC & DE registers. Depends heavily on BASIC string management routines (use of 2B75H or other routines may be preferable). If string contains a carriage return (ODH) character, a CALL will be made to the Disk BASIC link at 41DOH. Used by BASIC PRINT statement. This routine may also be entered at 28A6H, in which case the HL register pair will be incremented prior to beginning to output string.
  • To use a ROM call to display a string of characters starting at the current cursor position, and to update the cursor position,store the characters in consecutive memory locations, with a zero byte at the end, then load the HL register pair with the address of the first character of the string, and then CALL 28A7H.
    • EXAMPLE: Suppose that we have the following symbolic setup:
      TITL DEFM 'INSIDE LEVEL II'
      DEFB 0
      Then, the instructions:
      LD HL,TITL
      CALL 28A7H
      will cause “INSIDE LEVEL II” to be displayed at the current cursor position and the cursor position to be updated.

    • NOTE: If the subroutine at 28A7H is used by an assembly language program that is itself entered by a USR call, the return from the assembly language program may encounter the embarrassment of a TM error, with control passing to the Level II monitor. This occurs because the subroutine at 28A7H leaves a 3 in location 40AFH, while the USR structure requires a 2 in 40AFH upon returning. The malady is cured by storing a 2 in 40AFH before returning, or by jumping to 0A9AH instead of executing the simple RET. The problem would not occur in the first place if the assembly language program returns the value of an integer variable to the BASIC program, and it might not occur if some other ROM routine is called after the subroutine at 28A7H and before returning – if the other subroutine produces an integer output. DISK SYSTEM CAUTION: See the DISK SYSTEM CAUTION of Section 8.1 regarding the exits to DISK BASIC from the subroutine at 28A7H.
  • 28A7H-28A9H
    “DSTR”
    Go build a temporary string work area entry for the message at the location of the current BASIC program pointer in HL.
    28AAH-28ACH
    Gosub to 29DAH to load HL with the string’s VARPTR.
    28ADH-28AFH
    Go get the string’s length in register D and the string’s address in BC.
    28B0H
    INC D
    Bump the value of the string’s length in register D in preparation for the following loop which starts with a DEC D.
    28BlH
    DEC D
    Decrement the value of the string’s length in register D.
    28B2H
    RET Z
    Return if all of the characters in the string have been sent to the current output device.
    28B3H
    LD A,(BC)
    Load register A with the character at the location of the string pointer in BC.
    28B4H-28B6H
    Go send the character in register A to the current output device.
    28B7H-28B8H
    CP 0DH
    Check to see if the character in register A is a carriage return.
    28B9H-28BBH
    Jump to 2103H if the character in register A is a carriage return.
    28BCH
    INC BC
    Bump the value of the string pointer in BC.
    28BDH-28BEH
    Loop until all of the characters in the string have been sent to the current output device.

    28BFH-28D9H – STRING ROUTINE – Compute the amount of space remaining in the string area.

    28BFH
    OR A
    Set the flags.
    28C0H-28ClH
    0E F1
    Z-80 Trick.
    28ClH
    POP AF
    Get the string’s length from the stack and put it in register A.
    28C2H
    PUSH AF
    Save the length of the string in register A to the stack.
    28CJH-28C5H
    LD HL,(40A0H)
    Load HL with the start of the string space pointer.
    • Note: 40A0H-40A1H holds the start of string space pointer.
    28C6H
    EX DE,HL
    Move the start of the string space pointer into DE. We don’t care what happens to HL.
    28C7H-28C9H
    LD HL,(40D6H)
    Load HL with the next available location in string space pointer.
    Note: 40D6H-40D7H holds Next available location in string space pointer.
    28CAH
    CPL
    Complement the string’s length in register A so that it is negative.
    28CBH
    LD C,A
    Load register C with the negative string’s length in register A.
    28CCH-28CDH
    LD B,0FFH
    Load register B with a -1 so that BC will be the negative length of the string.
    28CEH
    ADD HL,BC
    Add the negative string’s length in BC to the next available location in string space pointer in HL.
    28CFH
    INC HL
    Bump the value of the adjusted next available location in string space pointer in HL.
    28D0H
    RST 18H
    Now we need to check to see if the adjusted next available location in string space pointer in HL is less than the start of string space pointer in DE, so we call the COMPARE DE:HL routine at RST 10H.
    NOTE:
    • The RST 10H routine loads the next character from the string pointed to by the HL register into the A-register and clears the CARRY flag if it is alphabetic, or sets it if is alphanumeric.
    • Blanks and control codes 09H and 0BH are ignored causing the following character to be loaded and tested.
    • The HL register will be incremented before loading any character therfore on the first call the HL register should contain the string address minus one.
    • The string must be terminated by a byte of zeros.
    28D1H-28D2H
    Jump forward to 28DAH if the adjusted next available location in string space pointer in HL is less than the start of string space pointer in DE.
    28D3H-28D5H
    LD (40D6H),HL
    Save the value in HL as the next available location in string space pointer.
    Note: 40D6H-40D7H holds Next available location in string space pointer.
    28D6H
    INC HL
    Bump the value of the next available location in string space pointer in HL.
    28D7H
    EX DE,HL
    Load DE with the next available location in string space pointer in HL.
    28D8H
    POP AF
    Get the string’s length from the stack and put it in register A.
    28D9H
    RET
    Return.

    28DAH-298EH – STRING ROUTINE

    28DAH
    POP AF
    Get the length of the string from the stack and put it in register A. This also gets the status flag to help us find out if reorganization has already been attempted.
    28DBH-28DCH
    LD E,1AH
    Load register E with an ?OS ERROR code.
    28DDH-28DFH
    Display a ?OS ERROR if there isn’t enough string space available for the string and we had already reorganized string space.
    28E0H
    CP A
    Set the flags.
    28ElH
    PUSH AF
    Save the string’s length in register A to the stack.
    28E2H-28E4H
    LD BC,28C1H
    Load BC with a return address of 28C1H (which would retry allocation).
    28E5H
    PUSH BC
    Save that return address to the stack.
    28E6H-28E8H
    LD HL,(40B1H)
    Load HL with the top of memory pointer.
    Note: 40B1H-40B2H holds MEMORY SIZE? pointer.
    28E9H-28EBH
    LD (40D6H),HL
    Save the top of BASIC memory pointer in HL as the next available location in string space pointer.
    Note: 40D6H-40D7H holds Next available location in string space pointer.
    28ECH-28EEH
    LD HL,0000H
    Zero HL.
    28EFH
    PUSH HL
    Save the value in HL to the stack.
    28F0H-28F2H
    LD HL,(40A0H)
    Load HL with the start of string space pointer.
    NOTE: 40A0H-40A1H holds the start of string space pointer.
    28F3H
    PUSH HL
    Save the start of string space pointer in HL to the stack.
    28F4H-28F6H
    LD HL,40B5H
    Load HL with the start of the temporary string work area pointer.
    Note: 40B5H-40D2H holds Temporary string work area.
    28F7H
    EX DE,HL
    Load DE with the start of the temporary string work area pointer in HL.
    28F8H-28FAH
    LD HL,(40B3H)
    Load HL with the next available location in the temporary string work area pointer.
    NOTE: 40B3H-40B4H holds Next available location in the temporary string work area pointer.
    28FBH
    EX DE,HL
    Exchange the start of the temporary string work area pointer in DE with the next available location in the temporary string work area pointer in HL.
    28FCH
    RST 18H
    We need to see if 40B3H is pointing to the first entry (40B5H) – if the start of the temporary string work area pointer in HL is the same as the next available location in the temporary string work area pointer, so we call the COMPARE DE:HL routine at RST 10H.
    NOTE:
    • The RST 10H routine loads the next character from the string pointed to by the HL register into the A-register and clears the CARRY flag if it is alphabetic, or sets it if is alphanumeric.
    • Blanks and control codes 09H and 0BH are ignored causing the following character to be loaded and tested.
    • The HL register will be incremented before loading any character therfore on the first call the HL register should contain the string address minus one.
    • The string must be terminated by a byte of zeros.
    28FDH-28FFH
    LD BC,28F7H
    Load BC with a return address of 28F7H.
    2900H-2902H
    Jump to 294AH if the temporary string work area isn’t empty.
    2903H
    LD HL,(40F9H)
    Load HL with the start of the simple variables pointer.
    NOTE: 40F9H-40FAH holds the starting address of the simple variable storage area.
    2906H
    EX DE,HL
    Load DE with the simple variables pointer in HL.
    2907H-2909H
    LD HL,(40FBH)
    Load HL with the start of the array variables pointer.
    • Note: 40FBH-40FCH holds the starting address of the BASIC array variable storage area.
    290AH
    EX DE,HL
    Exchange the value of the simple variables pointer in DE with the value of the array variables pointer in HL.
    290BH
    RST 18H
    Now we need to check to see if the simple variables pointer in HL is the same as the array variables pointer in DE, so we call the COMPARE DE:HL routine at RST 10H.
    NOTE:
    • The RST 10H routine loads the next character from the string pointed to by the HL register into the A-register and clears the CARRY flag if it is alphabetic, or sets it if is alphanumeric.
    • Blanks and control codes 09H and 0BH are ignored causing the following character to be loaded and tested.
    • The HL register will be incremented before loading any character therfore on the first call the HL register should contain the string address minus one.
    • The string must be terminated by a byte of zeros.
    290CH-290DH
    Jump forward to 2921H if the simple variables pointer in HL is the same as the array variables pointer in DE.
    290EH
    LD A,(HL)
    Load register A with the number type flag at the location of the simple variables pointer in HL.
    290FH
    INC HL
    Bump the value of the simple variables pointer in HL.
    2910H
    INC HL
    Bump the simple variables pointer in HL.
    2911H
    INC HL
    Bump the value of the simple variables pointer in HL.
    2912H-2913H
    CP 03H
    Check to see if the variable at the location of the simple variables pointer is a string.
    2914H-2915H
    Jump to 291AH if the variable at the location of the simple variables pointer in HL isn’t a string.
    2916H-2918H
    Gosub to 294BH to do string check.
    2919H
    XOR A
    Zero register A.
    29lAH
    LD E,A
    Zero register E.
    291BH-291CH
    LD D,00H
    Zero register D.
    29lDH
    ADD HL,DE
    Add the value of the number type flag in DE to the simple variables pointer in HL.
    291EH-291FH
    Loop back to 2906H until all of the simple variables have been checked.
    2920H
    POP BC
    Clean up the stack.
    2921H
    EX DE,HL
    Load DE with the value of the array variables pointer in HL.
    2922H-2924H
    LD HL,(40FDH)
    Load HL with the start of free memory pointer.
    Note: 40FDH-40FEH holds Free memory pointer.
    2925H
    EX DE,HL
    Exchange the value of the array variables pointer in DE with the value of the free memory pointer in HL.
    2926H
    RST 18H
    Now we need to check to see if the array variables pointer in HL is the same as the free memory pointer in DE, so we call the COMPARE DE:HL routine at RST 10H.
    NOTE:
    • The RST 10H routine loads the next character from the string pointed to by the HL register into the A-register and clears the CARRY flag if it is alphabetic, or sets it if is alphanumeric.
    • Blanks and control codes 09H and 0BH are ignored causing the following character to be loaded and tested.
    • The HL register will be incremented before loading any character therfore on the first call the HL register should contain the string address minus one.
    • The string must be terminated by a byte of zeros.
    2927H-2929H
    Jump if the array variables pointer in register HL is the same as the start of the free memory pointer in DE.
    292AH
    LD A,(HL)
    Load register A with the number type flag at the location of the array variables pointer in HL.
    292BH
    INC HL
    Bump the value of the array variables pointer in HL.
    292CH-292EH
    Call 09C2H (which loads a SINGLE PRECISION value pointed to by HL into register pairs BC and DE).
    292FH
    PUSH HL
    Save the value of the array variables pointer in reg­ ister pair HL to the stack.
    2930H
    ADD HL,BC
    Add the value of the offset to the next array in BC to the value of the array variables pointer in HL.
    2931H-2932H
    CP 03H
    Check to see if the array being examined is a string.
    2933H-2934H
    Jump if the array being examined isn’t a string.
    2935H-2937H
    LD (40D8H),HL
    Save the address of the next array in HL.
    Note: 40D8H-40D9H holds Temporary storage location.
    2938H
    POP HL
    Get the value of the array variables pointer from the stack and put it in HL.
    2939H
    LD C,(HL)
    Load register C with the number of subscripts for the array at the location of the array variables pointer in HL.
    293AH-293BH
    LD B,00H
    Zero register B.
    293CH
    ADD HL,BC
    Add the number of subscripts in the array in BC to the value of the array variables pointer in HL.
    293DH
    ADD HL,BC
    Add the number of subscripts in the array in BC to the value of the array variables pointer in HL.
    293EH
    INC HL
    Bump the value of the array variables pointer in HL.
    293FH
    EX DE,HL
    Load DE with the value of the array variables pointer in HL.
    2940H-2942H
    LD HL,(40D8H)
    Load HL with the address of the next array.
    Note: 40D8H-40D9H holds Temporary storage location.
    2943H
    EX DE,HL
    Exchange the value of the array variables pointer in DE with the address of the array in HL.
    2944H
    RST 18H
    Now we need to check to see if the array variables pointer in HL is the same as the address of the next array in DE, so we call the COMPARE DE:HL routine at RST 10H.
    NOTE:
    • The RST 10H routine loads the next character from the string pointed to by the HL register into the A-register and clears the CARRY flag if it is alphabetic, or sets it if is alphanumeric.
    • Blanks and control codes 09H and 0BH are ignored causing the following character to be loaded and tested.
    • The HL register will be incremented before loading any character therfore on the first call the HL register should contain the string address minus one.
    • The string must be terminated by a byte of zeros.
    2945H-2946H
    Jump to 2921H if the array variables pointer in HL is the same as the address of the next array in DE.
    2947H-2948H
    LD BC,293FH
    Load BC with a return address of 293FH.
    294AH
    PUSH BC
    Save the value in BC to the stack.
    294BH
    XOR A
    Zero register A.
    294CH
    OR (HL)
    Load register A with the length of the string at the location of the array variables pointer in HL.
    294DH
    INC HL
    Bump the value of the array variables pointer in HL.
    294EH
    LD E,(HL)
    Load register E with the LSB of the string’s address at the location of the array variables pointer in HL.
    294FH
    INC HL
    Bump the value of the array variables pointer in HL.
    2950H
    LD D,(HL)
    Load register D with the MSB of the string’s address at the location of the array variables pointer in HL.
    2951H
    INC HL
    Bump the value of the array variables pointer in HL.
    2952H
    RET Z
    Return if the string’s length in register A is equal to zero.
    2953H
    LD B,H
    Load register B with the MSB of the array variables pointer in register H.
    2954H
    LD C,L
    Load register C with the LSB of the array variables pointer in register L.
    2955H-2957H
    LD HL,(40D6H)
    Load HL with the location of the next available location in string space pointer.
    NOTE: 40D6H-40D7H holds Next available location in string space pointer.
    2958H
    RST 18H
    Now we need to check to see if the string’s address in DE is in string space, so we call the COMPARE DE:HL routine at RST 10H.
    NOTE:
    • The RST 10H routine loads the next character from the string pointed to by the HL register into the A-register and clears the CARRY flag if it is alphabetic, or sets it if is alphanumeric.
    • Blanks and control codes 09H and 0BH are ignored causing the following character to be loaded and tested.
    • The HL register will be incremented before loading any character therfore on the first call the HL register should contain the string address minus one.
    • The string must be terminated by a byte of zeros.
    2959H
    LD H,B
    Load register H with the MSB of the array variables pointer in register B.
    295AH
    LD L,C
    Load register L with the LSB of the array variables pointer in register C.
    295BH
    RET C
    Return if the string’s address in DE is in string space.
    295CH
    POP HL
    Get the return address from the stack and put it in HL.
    295DH
    EX (SP),HL
    Exchange the value of the return address in HL with the start of string space pointer to the stack.
    295EH
    RST 18H
    Now we need to check to see if the string’s address in DE is below the start of string space pointer in HL, so we call the COMPARE DE:HL routine at RST 10H.
    NOTE:
    • The RST 10H routine loads the next character from the string pointed to by the HL register into the A-register and clears the CARRY flag if it is alphabetic, or sets it if is alphanumeric.
    • Blanks and control codes 09H and 0BH are ignored causing the following character to be loaded and tested.
    • The HL register will be incremented before loading any character therfore on the first call the HL register should contain the string address minus one.
    • The string must be terminated by a byte of zeros.
    295FH
    EX (SP),HL
    Exchange the start of string space pointer in HL with the value of the return address to the stack.
    2960H
    PUSH HL
    Save the value of the return address in HL to the stack.
    2961H
    LD H,B
    Load register H with the MSB of the array variables pointer in register B.
    2962H
    LD L,C
    Load register L with the LSB of the array variables pointer in register C.
    2963H
    RET NC
    Return if the string’s address in DE is below the string space pointer.
    2964H
    POP BC
    Get the return address from the stack and put it in BC.
    2965H
    POP AF
    Clean up the stack.
    2966H
    POP AF
    Clean up the stack.
    2967H
    PUSH HL
    Save the value of the array variables pointer in HL to the stack.
    2968H
    PUSH DE
    Save the string’s address in DE to the stack.
    2969H
    PUSH BC
    Save the value of the return address in BC to the stack.
    296AH
    RET
    Return.
    296BH
    POP DE
    Load DE with the address of the last string put into the temporary string work area.
    296CH
    POP HL
    Get the temporary string work area pointer from the stack and put it in HL.
    296DH
    LD A,L
    Load register A with the LSB of the temporary string work area pointer in register L.
    296EH
    OR H
    Combine the MSB of the temporary string work area pointer in register H with the LSB of the temporary string work area pointer in register A.
    296FH
    RET Z
    Return if the temporary string work area is empty.
    2970H
    DEC HL
    Decrement the value of the temporary string work area pointer in HL.
    2971H
    LD B,(HL)
    Load register B with the MSB of the string’s address at the location of the temporary string work area pointer in HL.
    2972H
    DEC HL
    Decrement the value of the temporary string work area pointer in HL.
    2973H
    LD C,(HL)
    Load register C with the LSB of the string’s address at the location of the temporary string work area pointer in HL.
    2974H
    PUSH HL
    Save the value of the temporary string work area pointer in HL to the stack.
    2975H
    DEC HL
    Decrement the value of the temporary string work area pointer in HL.
    2976H
    LD L,(HL)
    Load register L with the string’s length at the location of the temporary string work area pointer in HL.
    2977H-2978H
    LD H,00H
    Zero register H.
    2979H
    ADD HL,BC
    Add the length of the string in HL to the string’s address in BC.
    297AH
    LD D,B
    Load register D with the MSB of the string’s address in register B.
    297BH
    LD E,C
    Load register E with the LSB of the string’s address in register C.
    297CH
    DEC HL
    Decrement the value of the string’s ending address in HL.
    297DH
    LD B,H
    Load register B with the MSB of the string’s ending address in register H.
    297EH
    LD C,L
    Load register C with the LSB of the string’s ending address in register L.
    297FH-2981H
    LD HL,(40D6H)
    Load HL with the next available location in string space pointer.
    NOTE: 40D6H-40D7H holds Next available location in string space pointer.
    2982H-2984H
    Move the string from the temporary storage location to string space.
    2985H
    POP HL
    Get the temporary string work area pointer from the stack and put it in HL.
    2986H
    LD (HL),C
    Save the LSB of the string’s address in register Cat the location of the temporary string work area pointer in HL.
    2987H
    INC HL
    Bump the value of the temporary string work area pointer in HL.
    2988H
    LD (HL),B
    Save the MSB of the string’s address in register B at the location of the temporary string work area pointer in HL.
    2989H
    LD L,C
    Load register L with the LSB of the string’s address in register C.
    298AH
    LD H,B
    Load register H with the MSB of the string’s address in register B.
    298BH
    DEC HL
    Decrement the string’s address in HL.
    298CH-298EH
    Jump to 28E9H.

    298FH-29C5H – STRING ADDITION ROUTINE – Concatenate two strings.

    298FH
    PUSH BC
    Save the operator value in BC to the stack.
    2990H
    PUSH HL
    Save the value of the current BASIC program pointer in HL to the stack.
    2991H-2993H
    LD HL,(4121H)
    Load HL with the first string’s VARPTR (from REG 1).
    2994H
    EX (SP),HL
    Exchange the value of the first string’s VARPTR in HL with the value of the current BASIC program to the stack.
    2995H-2997H
    Gosub to 249FH to evaluate the expression at the location of the current BASIC program pointer in HL.
    2998H
    EX (SP),HL
    Exchange the value of the current BASIC program pointer in HL with the value of the first string’s VARPTR to the stack.
    2999H-299BH
    Go make sure the current result in REG 1 is a string.
    299CH
    LD A,(HL)
    Load register A with the first string’s length at the location of the first string’s VARPTR in HL.
    299DH
    PUSH HL
    Save the value of the first string’s VARPTR in HL to the stack.
    299EH-29A0H
    LD HL,(4121H)
    Load HL with the second string’s VARPTR in REG 1.
    29A1H
    PUSH HL
    Save the second string’s VARPTR in HL to the stack.
    29A2H
    ADD A,(HL)
    Add the length of the second string at the location of the second string’s VARPTR in HL to the length of the first string in register A.
    29A3H-29A4H
    LD E,1CH
    Load register E with a ?LS ERROR code.
    29A5H-29A7H
    Display a ?LS ERROR message if the combined lengths of the strings is greater than 255.
    29A8H-29AAH
    Go make sure that there is enough string space for the new string.
    29ABH
    POP DE
    Get the second string’s VARPTR from the stack and put it in DE.
    29ACH-29AEH
    Go update the temporary string work area.
    29AFH
    EX (SP),HL
    Exchange the second string’s VARPTR in HL with the first string’s VARPTR to the stack.
    29B0H-29B2H
    Go update the temporary string work area.
    29B3H
    PUSH HL
    Save the value of the first string’s VARPTR in HL to the stack.
    29B4H-29B6H
    LD HL,(40D4H)
    Load HL with the second string’s address.
    29B7H
    EX DE,HL
    Load DE with the second string’s address in HL.
    29B8H-29BAH
    Go move the first string to its temporary storage location.
    29BBH-29BDH
    Go move the second string to its temporary storage location.
    29BEH-29C0H
    LD HL,2349H
    Load HL with the return address.
    29C1H
    EX (SP),HL
    Exchange the value of the return address in HL with the value of the current BASIC program pointer to the stack.
    29C2H
    PUSH HL
    Save the value of the current BASIC program pointer in HL to the stack.
    29C3H-29C5H
    Jump to 2884H.

    29C6H-29D6H – STRING ROUTINE – This will move strings using the stack.

    • On entry, the stack should have the count/source address and DE should have the destination address.
    29C6H
    POP HL
    Load HL with the value of the return address to the stack.
    29C7H
    EX (SP),HL
    Exchange the value of the return address in HL with the string’s VARPTR to the stack.

    29C8H – STRING MOVE ROUTINE
    On entry HL points to the string control block for the string to be moved, and DE contains the destination address. All registers are used. The string length and address are not moved. String control blocks have the format: X=String Length; ADDR = String Address.

    29C8H
    LD A,(HL)
    Load register A with the string’s length at the location of the string’s VARPTR in HL.
    29C9H
    INC HL
    Bump the value of the string’s VARPTR in HL.
    29CAH
    LD C,(HL)
    Load register C with the LSB of the string’s address at the location of the string’s VARPTR in HL.
    29CBH
    INC HL
    Bump the value of the string’s VARPTR in HL.
    29CCH
    LD B,(HL)
    Load register B with the MSB of the string’s address at the location of the string’s VARPTR in HL.
    29CDH
    LD L,A
    Load register L with the string’s length in register A.
    29CEH
    INC L
    Bump the value of the string’s length in register L.
    29CFH
    DEC L
    Decrement the value of the string’s length in register L.
    29D0H
    RET Z
    Return if all of the characters in the string have been moved.
    29D1H
    LD A,(BC)
    Load register A with the character at the location of the string pointer in BC.
    29D2H
    LD (DE),A
    Save the character in register A at the location of the string storage pointer in DE.
    29D3H
    INC BC
    Bump the value of the string pointer in BC.
    29D4H
    INC DE
    Bump the value of the string storage pointer in DE.
    29D5H-29D6H
    Loop until the string has been completely moved.

    29D7H-29F4H – STRING ROUTINE

    • This routine is a contination of VAL, FRE, and PRINT processing. A jump to here would include the need to get a string’s VARPTR and put it in HL.
    29D7H-29D9H
    Gosub to 0AF4H to make sure that the current result in REG l is a string.
    29DAH-29DCH
    LD HL,(4121H)
    Load HL with the string’s VARPTR in REG 1.
    29DDH
    EX DE,HL
    Load DE with the value of the string’s VARPTR in HL.
    29DEH-29E0H
    Check to see if the string is the last entry in the temporary string work area.
    29E1H
    EX DE,HL
    Load HL with the value of the string’s VARPTR in DE.
    29E2H
    RET NZ
    Return if the string isn’t the last entry in the temporary string work area.
    29E3H
    PUSH DE
    Save the value of the string’s VARPTR in DE to the stack.
    29E4H
    LD D,B
    Load register D with the MSB of the string’s address in register B.
    29E5H
    LD E,C
    Load register E with the LSB of the string’s address in register C.
    29E6H
    DEC DE
    Decrement the value of the string’s address in DE.
    29E7H
    LD C,(HL)
    Load register C with the string’s length at the location of the string’s VARPTR in HL.
    29E8H-29EAH
    LD HL,(40D6H)
    Load HL with the next available location in string space pointer.
    Note: 40D6H-40D7H holds Next available location in string space pointer.
    29EBH
    RST 18H
    We need to see if the current string is the last one defined in the string area by seeing if the string’s address in DE is the same as the next available location in string space pointer in HL, so we call the COMPARE DE:HL routine at RST 10H.
    NOTE:
    • The RST 10H routine loads the next character from the string pointed to by the HL register into the A-register and clears the CARRY flag if it is alphabetic, or sets it if is alphanumeric.
    • Blanks and control codes 09H and 0BH are ignored causing the following character to be loaded and tested.
    • The HL register will be incremented before loading any character therfore on the first call the HL register should contain the string address minus one.
    • The string must be terminated by a byte of zeros.
    29ECH-29EDH
    Jump forward to 29F3H if the string’s address in DE isn’t the same as the next available location in string space pointer in HL.
    29EEH
    LD B,A
    If is the last one defined then we need to update the current string pointer so first we load register B with the value in register A.
    29EFH
    ADD HL,BC
    Add the length of the string in BC to the next available location in string space pointer in HL.
    29E0H-29F2H
    LD (40D6H),HL
    Save the adjusted next available location in string space pointer in HL.
    Note: 40D6H-40D7H holds Next available location in string space pointer.
    29F3H
    POP HL
    Get the string’s VARPTR from the stack and put it in HL.
    29F4H
    RET
    Return.

    29F5H-2A02H – STRING ROUTINE

    29F5H-29F7H
    LD HL,(40B3H)
    Load HL with the temporary string work area pointer.
    Note: 40B3H-40B4H holds Next available location in the temporary string work area pointer.
    29F8H
    DEC HL
    Decrement the value of the temporary string work area pointer in HL which backs up two words.
    29F9H
    LD B,(HL)
    Load register B with the MSB of the string’s address at the location of the temporary string work area pointer in HL.
    29FAH
    DEC HL
    Decrement the value of the temporary string work area pointer in HL.
    29FBH
    LD C,(HL)
    Load register C with the LSB of the string’s address at the location of the temporary string work area pointer in HL.
    29FCH
    DEC HL
    Decrement the value of the temporary string work area pointer in HL.
    29FDH
    RST 18H
    Now we need to check to see if the string’s VARPTR in DE matches the temporary string work area pointer in HL, so we call the COMPARE DE:HL routine at RST 10H.
    NOTE:
    • The RST 10H routine loads the next character from the string pointed to by the HL register into the A-register and clears the CARRY flag if it is alphabetic, or sets it if is alphanumeric.
    • Blanks and control codes 09H and 0BH are ignored causing the following character to be loaded and tested.
    • The HL register will be incremented before loading any character therfore on the first call the HL register should contain the string address minus one.
    • The string must be terminated by a byte of zeros.
    29FEH
    RET NZ
    Return if the string’s VARPTR in DE doesn’t match the temporary string work area pointer in HL.
    29FFH-2A01H
    LD (40B3H),HL
    Save the value of the temporary string work area pointer in HL.
    Note: 40B3H-40B4H holds Next available location in the temporary string work area pointer.
    2A02H
    RET
    Return.

    2A03H-2A0EH – LEVEL II BASIC LEN ROUTINE

    2A03H-2A05H
    LD BC,27F8H
    Load BC with the return address of 27F8H.
    2A06H
    PUSH BC
    Save the return address of 27F8H (in BC) to the stack.
    2A07H-2A09H
    Gosub to 29D7H to get the string’s VARPTR and put it in HL.
    2A0AH
    XOR A
    Zero register A.
    2A0BH
    LD D,A
    Zero register D.
    2A0CH
    LD A,(HL)
    Load register A with the string’s length at the location of the string’s VARPTR in HL.
    2A0DH
    OR A
    Set the flags according to the string’s length in register A.
    2A0EH
    RET
    Return.

    2A0FH-2A1EH – LEVEL II BASIC ASC ROUTINE

    2A0FH-2A11H
    LD BC,27F8H
    Load BC with the return address of 27F8H.
    2A12H
    PUSH BC
    Save the return address of 27F8H (in BC) to the stack.
    2A13H-2A15H
    Gosub to 2A07H (which itself is a Gosub to 29D7H) to get string’s VARPTR into HL and the string’s length into register A.
    2A16H-2A18H
    Display a ?FC ERROR if the string’s length in register A is equal to zero.
    2A19H
    INC HL
    Bump the value of the string’s VARPTR in HL.
    2A1AH
    LD E,(HL)
    Load register E with the LSB of the string’s address at the location of the string’s VARPTR in HL.
    2A1BH
    INC HL
    Bump the value of the string’s VARPTR in HL.
    2A1CH
    LD D,(HL)
    Load register D with the MSB of the string’s address at the location of the string’s VARPTR in HL.
    2A1DH
    LD A,(DE)
    Load register A with the first character at the location of the string pointer in DE.
    2A1EH
    RET
    Return.

    2A1FH-2A2EH – LEVEL II BASIC CHR$ ROUTINE

    2A1FH-2A20H
    LD A,01H
    Load register A with the length of the string to be created.
    2A21H-2A23H
    Gosub to 2857H to save the string’s length in register A and value and set up the string’s address.
    2A24H-2A26H
    Gosub to 2B1FH to evaluate the expression at the location of the current BASIC program pointer in HL and return with the integer result in DE.
    2A27H-2A29H
    LD HL,(40D4H)
    Load HL with the temporary string’s address.
    2A2AH
    LD (HL),E
    Save the character in register E at the location of the string pointer in HL.
    2A2BH
    POP BC
    Clean up the stack.
    2A2CH-2A2EH
    Jump to 2884H.

    2A2FH-2A60H – LEVEL II BASIC STRING$ ROUTINE

    2A2FH
    RST 10H
    We have the STRING$ command, but now we need the next character so we call a RST 10H to bump the value of the current BASIC program pointer until it points to the next character, call the EXAMINE NEXT SYMBOL routine at RST 10H.
    NOTE:
    • The RST 10H routine loads the next character from the string pointed to by the HL register into the A-register and clears the CARRY flag if it is alphabetic, or sets it if is alphanumeric.
    • Blanks and control codes 09H and 0BH are ignored causing the following character to be loaded and tested.
    • The HL register will be incremented before loading any character therfore on the first call the HL register should contain the string address minus one.
    • The string must be terminated by a byte of zeros.
    2A30H-2A31H
    RST 08H
    28
    Since the character at the location of the current BASIC program pointer in HL must be a (, call the COMPARE SYMBOL routine at RST 08H.

    NOTE: The RST 08H routine compares the symbol in the input string pointed to by HL register to the value in the location following the RST 08 call.
    • If there is a match, control is returned to the next execution address (i.e, the RST 08H instruction + 2) with the next symbol in the A Register and HL incremented by one.
    • If the two characters do not match, a syntax error message is given and control returns to the Input Phase).
    2A32H-2A34H
    This will get the string length required (which we will call “N”) via a gosub to 2B1CH to evaluate the expression at the location of the current BASIC program pointer in HL and return with the integer result in DE.
    2A34H
    DEC HL
    Backspace the code string. This is a Z-80 trick because this code was part of the above call instruction.
    2A35H
    PUSH DE
    Save the string’s length (“N”) (currently in DE) to the stack.
    2A36H-2A37H
    RST 08
    2CH
    Now we have STRING$(nnn so the next character needs to be a ,. To test for the character at the location of the current BASIC program pointer in HL being a ,, call the COMPARE SYMBOL routine which compares the symbol in the input string pointed to by HL register to the value in the location following the RST 08 call. If there is a match, control is returned to address of the RST 08 instruction + 2 with the next symbol in the A register and HL incremented by one. If the two characters do not match, a syntax error message is given and control returns to the Input Phase).
    2A38H-2A3AH
    Now we have STRING$(xxx, and an expression so gosub to 2337H to evaluate the expression at the location of the current BASIC program pointer in HL and return with the result in REG 1.
    2A3BH-2A3CH
    RST 08H
    29H
    Now we have STRING$(nnn,X. Since the character at the location of the current BASIC program pointer in HL must be a ), call the COMPARE SYMBOL routine at RST 08H.

    NOTE: The RST 08H routine compares the symbol in the input string pointed to by HL register to the value in the location following the RST 08 call.
    • If there is a match, control is returned to the next execution address (i.e, the RST 08H instruction + 2) with the next symbol in the A Register and HL incremented by one.
    • If the two characters do not match, a syntax error message is given and control returns to the Input Phase).
    2A3DH
    EX (SP),HL
    We are now done with getting STRING$(nnn,X). Next we must exchange the value of the current BASIC program pointer in HL with the string’s length (“N”) in the stack.
    2A3EH
    PUSH HL
    Save the string’s length (“N”) in HL to the stack so that we can test it to make sure it is an integer.
    2A3FH
    RST 20H
    We need to check the value of the current data type flag, so we call the TEST DATA MODE routine at RST 20H.
    NOTE: The RST 20H routine determines the type of the current value in REG 1 and returns a combination of STATUS flags and unique numeric values in the A Register according to the data mode flag (40AFH).

    The results are returned as follows:
    • Integer = NZ/C/M/E and A is -1
    • String = Z/C/P/E and A is 0
    • Single Precision = NZ/C/P/O and A is 1
    • and Double Precision is NZ/NC/P/E and A is 5.
    2A40H-2A41H
    If that test shows “N” is a a STRING, jump to down to 2A47H.
    2A42H-2A44H
    We now know that “N” is at least a number, so we gosub to 2B1FH to convert the current result in REG 1 to an integer and return with the 8-bit result in register A.
    2A45H-2A46H
    Skip the next instruction (which would load the string address and 1st character) by jumping to 2A4AH.
    2A47H-2A49H
    Go get the first character in the string and return with it in register A. This is the character that will be repeated.
    2A4AH
    POP DE
    Get the “N” from the stack and put it in DE.
    2A4BH
    PUSH AF
    Save the character for the string (held in register A) to the stack.
    2A4CH
    PUSH AF
    and then save it to the stack again.
    2A4DH
    LD A,E
    Load register A with “N” (held in register E).
    2A4EH-2A4FH
    Gosub to 2857H to allocate N bytes in the temporary string work area .
    2A51H
    LD E,A
    Load register E with “N” (held in register A).
    2A52H
    POP AF
    Get the character for the string (“X”) from the stack and put it in register A.
    2A53H
    INC E
    To set the status flags we need to increase and then decrease E. First, bump the value of the string’s length in register E …
    2A54H
    DEC E
    … and then decrement the string’s length in register E.
    2A55H-2A56H
    If “N” was zero (so that the string is now complete), jump back to 2A2BH.
    2A57H-2A59H
    LD HL,(40D4H)
    If we are here, we have not finished building the STRING$ string so now we load HL with the string’s address and get ready to loop.
    2A5AH
    LD (HL),A
    Save the character in register A (“X”) at the location of the string pointer in HL.
    2A5BH
    INC HL
    Bump the value of the string pointer in HL.
    2A5CH
    DEC E
    Decrement the string’s length in register E.
    2A5DH-2A5EH
    Loop back to 2A5AH to keep filling (HL) until the string of X’s has been completed.
    2A5FH-2A60H
    Jump back to 2A2BH.

    2A61H-2A90H – LEVEL II BASIC LEFT$( ROUTINE – On entry, HL=address of LEFT$$, the stack = string address, stack+1 = n, and DE = code string address.

    2A61H-2A63H
    Go check the syntax. The character at the location of the current BASIC program pointer in HL must be a ).
    2A64H
    XOR A
    Zero register A.
    2A65H
    EX (SP),HL
    Exchange the value of the current BASIC program pointer in HL with the string’s VARPTR to the stack.
    2A66H
    LD C,A
    Zero register C.
    2A67H-2A68H
    3E E5
    Z-80 Trick. By adding a 3E at 2A67, it masks out 2A68H if passing through by making the Z-80 think the instruction is LD A,0E5H.
    2A68H
    LD H,A
    Load register H with the value in register A.
    2A69H
    PUSH HL
    Save the value of the string’s VARPTR in HL to the stack.
    2A6AH
    LD A,(HL)
    Load register A with the string’s length at the location of the string’s VARPTR in HL.
    2A6BH
    CP B
    Check to see if the new string’s length in register B is greater than the string’s length in register A.
    2A6CH-2A6DH
    Jump to 2A70H if the new string’s length in register B is greater than the string’s length in register A.
    2A6EH
    LD A,B
    Load register A with the new string’s length in register B.
    2A6FH-2A71H
    11 0E 00
    Z-80 Trick. This is a LD DE,000EH which is irrelevant and only executed if continuing through. If, however, one was to jump to 2A70H instead, a proper opcode would occur.
    2A70H-2A7lH
    LD C,00H
    Zero register C.
    2A72H
    PUSH BC
    Save the string’s length in BC to the stack.
    2A73H-2A75H
    Go see if there is enough string space for the new string.
    2A76H
    POP BC
    Get the new string’s length from the stack and put it in BC.
    2A77H
    POP HL
    Get the string’s VARPTR from the stack and put it in HL.
    2A78H
    PUSH HL
    Save the string’s VARPTR in HL to the stack.
    2A79H
    INC HL
    Bump the value of the string’s VARPTR in HL.
    2A7AH
    LD B,(HL)
    Load register B with the LSB of the string’s address at the location of the string’s VARPTR in HL.
    2A7BH
    INC HL
    Bump the value of the string’s VARPTR in HL.
    2A7CH
    LD H,(HL)
    Load register H with the MSB of the string’s address at the location of the string’s VARPTR in HL.
    2A7DH
    LD L,B
    Load register L with the LSB of the string’s address in register B.
    2A7EH-2A7FH
    LD B,00H
    Zero register B.
    2A80H
    ADD HL,BC
    Add the string’s length in BC to the string’s address in HL.
    2A81H
    LD B,H
    Load register B with the MSB of the string’s ending address in register H.
    2A82H
    LD C,L
    Load register C with the LSB of the string’s ending address in register L.
    2A83H-2A85H
    Go save the string’s length (held in A) and the string’s starting address (held in DE).
    2A86H
    LD L,A
    Load register L with the string’s length (i.e., the number of characters to move) held in register A.
    2A87H-2A89H
    Go move L characers frm BC to DE.
    2A8AH
    POP DE
    Clean up the stack.
    2A8BH-2A8DH
    Go update the temporary string work area.
    2A8EH-2A90H
    Jump to 2884H.

    2A91H-2A99H – LEVEL II BASIC RIGHT$ ROUTINE

    2A91H-2A93H
    Go check the syntax. The character at the location of the current BASIC program pointer in HL must be a ).
    2A94H
    POP DE
    Get the string’s VARPTR from the stack and put it in DE.
    2A95H
    PUSH DE
    Save the string’s VARPTR in DE to the stack.
    2A96H
    LD A,(DE)
    Load register A with the string’s length (held at the location of the string’s VARPTR in DE).
    2A97H
    SUB B
    Subtract the new string’s length in register B from the string’s length in register A to isolate the number of bytes.
    2A98H-2A99H
    Jump to the LEFT$( code.

    2A9AH-2AC4H – LEVEL II BASIC MID$ ROUTINE

    2A9AH
    EX DE,HL
    Load HL with the value of the current BASIC program pointer (held in DE).
    2A9BH
    LD A,(HL)
    Load register A with the terminal character, currently held at the location of the current BASIC program pointer in HL.
    2A9CH-2A9EH
    Gosub to 2AE2H to get the string’s position in register B and the string’s VARPTR in DE.
    2A9FH
    INC B
    We need to set the status flags to correspond to the position value so we first bump the value of the string’s position in register B …
    2AA0H
    DEC B
    … and then we decrement the value of the string’s position in register B.
    2AA1H-2AAJH
    If the starting position (held in B) is 0, display ?FC ERROR.
    2AA4H
    PUSH BC
    Save the value of the string’s starting position (held in register B) to the stack.
    2AA5H-2AA6H
    LD E,0FFH
    Load register E with the default string’s length of 256 in case no number of bytes are given.
    2AA7H-2AA8H
    CP 29H
    More syntax checking. Here we need to test for a ) at the location of the current BASIC program pointer.
    2AA9H-2AAAH
    Jump to 2AB0H if the character at the location of the current BASIC program pointer in register A is a ).
    2AABH-2AACH
    RST 08H
    2C
    If it wasn’t a ), it had best be a , so we need to test the character at the location of the current BASIC program pointer in HL by calling the COMPARE SYMBOL routine at RST 08H.

    NOTE: The RST 08H routine compares the symbol in the input string pointed to by HL register to the value in the location following the RST 08 call.
    • If there is a match, control is returned to the next execution address (i.e, the RST 08H instruction + 2) with the next symbol in the A Register and HL incremented by one.
    • If the two characters do not match, a syntax error message is given and control returns to the Input Phase).
    2AADH-2AAFH
    Go evaluate the expression at the location of the current BASIC program pointer in HL and return with the integer result in DE. Now the byte count is in DE as an integer.
    2ABOH-2AB1H
    RST 08H
    29H
    Since the character at the location of the current BASIC program pointer in HL must be a ), call the COMPARE SYMBOL routine at RST 08H.

    NOTE: The RST 08H routine compares the symbol in the input string pointed to by HL register to the value in the location following the RST 08 call.
    • If there is a match, control is returned to the next execution address (i.e, the RST 08H instruction + 2) with the next symbol in the A Register and HL incremented by one.
    • If the two characters do not match, a syntax error message is given and control returns to the Input Phase).
    2AB2H
    POP AF
    Get the value of the string’starting s position from the stack and put it in register A.
    2AB3H
    EX (SP),HL
    Exchange the value of the current BASIC program pointer in HL with the value of the string’s VARPTR to the stack.
    2AB4H-2AB6H
    LD BC,2A69H
    Load BC with 2A69H as the return address (which is in the LEFT$ routine).
    2AB7H
    PUSH BC
    Save the return address in BC to the stack.
    2AB8H
    DEC A
    Decrement the value of the string’s position in register A so that we have a starting position minus 1.
    2AB9H
    CP (HL)
    Compare the string’s length at the location of the string’s VARPTR in HL with the value of the string’s position in register A.
    2ABAH-2ABBH
    LD B,00H
    Zero register B.
    2ABCH
    RET NC
    Return if the string’s position in register A is greater than the string’s length at the location of the string’s VARPTR in HL.
    2ABDH
    LD C,A
    Load register C with the string’s position in register A.
    2ABEH
    LD A,(HL)
    Load register A with the string’s length at the location of the string’s VARPTR in HL.
    2ABFH
    SUB C
    Subtract the value of the string’s position in register C from the string’s length in register A.
    2AC0H
    CP E
    Compare the new string’s length in register E with the adjusted string’s length in register A.
    2AC1H
    LD B,A
    Load register B with the adjusted string’s length in register A.
    2AC2H
    RET C
    Return to 2A69H if the new string’s length in register E is greater than the string’s length in register A.
    2AC3H
    LD B,E
    Load register B with the new string’s length in register E.
    2AC4H
    RET
    Return to 2A69H.

    2AC5H-2ADEH – LEVEL II BASIC VAL ROUTINE

    2AC5H-2AC7H
    Go get the string’s length in register A and the string’s VARPTR in HL.
    2AC8H-2ACAH
    Jump to 27F8H if the string’s length in register A is equal to zero.
    2ACBH
    LD E,A
    Load register E with the string’s length at the location of the string’s VARPTR in HL.
    2ACCH
    INC HL
    Bump the value of the string’s VARPTR in HL.
    2ACDH
    LD A,(HL)
    Load register A with the LSB of the string’s address at the location of the string’s VARPTR in HL.
    2ACEH
    INC HL
    Bump the value of the string’s VARPTR in HL.
    2ACFH
    LD H,(HL)
    Load register H with the MSB of the string’s address at the location of the string’s VARPTR in HL.
    2ADOH
    LD L,A
    Load register L with the LSB of the string’s address in register A.
    2AD1H
    PUSH HL
    Save the value of the string’s address in HL to the stack.
    2AD2H
    ADD HL,DE
    Add the string’s length in DE to the string’s address in HL.
    2AD3H
    LD B,(HL)
    Load register B with the last character of the string at the location of the string pointer in HL.
    2AD4H
    LD (HL),D
    Save the zero in register D at the location of the string pointer in HL.
    2AD5H
    EX (SP),HL
    Exchange the string’s ending address in HL with the string’s address to the stack.
    2AD6H
    PUSH BC
    Save the last character of the string in register B to the stack.
    2AD7H
    LD A,(HL)
    Load register A with the character at the location of the string pointer in HL.
    2AD8H-2ADAH
    Call the ASCII TO DOUBLE routine at 0E65H (which converts the ASCII string pointed to by HL to its double precision equivalent; with output left in REG 1).
    2ADBH
    POP BC
    Get the last character of the string from the stack and put it in register B.
    2ADCH
    POP HL
    Get the string’s ending address from the stack and put it in HL.
    2ADDH
    LD (HL),B
    Save the character in register B at the location of the string pointer in HL.
    2ADEH
    RET
    Return.

    2ADFH-2A6H – STRING ROUTINE

    • This is called by LEFT$, MID$, and RIGHT$ to test for the ending “)” character. On entry, the stack has the string address, byte count, and return address. On exit the stack has the string address, DE and B each have the byte count.
    2ADFH
    EX DE,HL
    Load HL with the value of the current BASIC program pointer in DE.
    2AE0H-2AE1H
    RST 08H
    29H
    Since the character at the location of the current BASIC program pointer in HL must be a ), call the COMPARE SYMBOL routine at RST 08H.

    NOTE: The RST 08H routine compares the symbol in the input string pointed to by HL register to the value in the location following the RST 08 call.
    • If there is a match, control is returned to the next execution address (i.e, the RST 08H instruction + 2) with the next symbol in the A Register and HL incremented by one.
    • If the two characters do not match, a syntax error message is given and control returns to the Input Phase).
    2AE2H
    POP BC
    Get the return address from the stack and put it in BC.
    2AE3H
    POP DE
    Get the number of bytes to isolate from the string (from the stack) and put it in DE.
    2AE4H
    PUSH BC
    Save the return address in BC to the stack.
    2AE5H
    LD B,E
    Load register B with the number of bytes in register E.
    2AE6H
    RET
    Return.

    2AE7H- AEEH – DISK ROUTINE

    2AE7H-2AE8H
    CP 7AH
    Check to see if the character at the location of the current BASIC program pointer in register A is equal to 7AH (which is a lower case z).
    2AE9H-2AEBH
    Display a ?SN ERROR message if the character at the location of the current BASIC program pointer in register A isn’t equal to 7AH.
    2AECH-2AEEH
    Jump to the DOS link at 41D9H to let disk BASIC handle TABMID$.

    2AEFH-2AF7H – LEVEL II BASIC INP ROUTINE

    2AEFH-2AF1H
    Go evaluate the expression at the location of the current BASIC program pointer in HL and return with the port number in register A.
    2AF2H-2AF4H
    LD (4094H),A
    Save the value of the port number (from register A) into 4094H.
    2AF5H-2AF7H
    Go get the value from the port, execute an IN xx instruction, and return to the execution driver.
    Note: 4093H-4095H holds INP routine.

    2AF8H-2B00H – LEVEL II BASIC OUT ROUTINE

    2AF8H-2AFAH
    Go evaluate the expression at the location of the current BASIC program pointer in HL and return with the port number saved in memory.
    2AFBH-2AFDH
    Go evaluate the expression at the location of the current BASIC program pointer in HL and return with value to send to the port in register A.
    2AFEH-2B00H
    Go send the value in register A, execute an OUT xx instruction to the port, and return.
    Note: 4096H-4098H holds OUT routine.

    2B01H-2B0DH – EVALUATE EXPRESSION ROUTINE – This evaluates an expression and leaves the result in DE as an integer.

    2B01H
    RST 10H
    We need the next character in the BASIC program so call the EXAMINE NEXT SYMBOL routine at RST 10H.
    NOTE:
    • The RST 10H routine loads the next character from the string pointed to by the HL register into the A-register and clears the CARRY flag if it is alphabetic, or sets it if is alphanumeric.
    • Blanks and control codes 09H and 0BH are ignored causing the following character to be loaded and tested.
    • The HL register will be incremented before loading any character therfore on the first call the HL register should contain the string address minus one.
    • The string must be terminated by a byte of zeros.
    2B02H-2B04H
    Go evaluate the expression at the location of the current BASIC program pointer in HL and return with the result in REG 1.

    2B05H – This routine takes the value from the ACC, converts it to an integer value and places the result in the DE register pair. The Z flag will be set if the result in DE is smaller than or equal to 255 (FFH). (DE = INT (ACC)).

    2B05H
    PUSH HL
    Save the value of the current BASIC program pointer in HL to the stack.
    2B06H-2B08H
    Call the CONVERT TO INTEGER routine at 0A7FH (where the contents of REG 1 are converted from single or double precision to integer and deposited into HL).
    2B09H
    EX DE,HL
    Load DE with the integer result in HL.
    2B0AH
    POP HL
    Get the value of the current BASIC program pointer from the stack and put it in HL.
    2B0BH
    LD A,D
    Load register A with the MSB of the integer result in register D.
    2B0CH
    OR A
    Test the value of the MSB in register A.
    2B0DH
    RET
    Return.

    2B0EH-2Bl6H – EVALUATE EXPRESSION ROUTINE – OUT continues here

    2B0EH-2Bl0H
    Gosub to 2B1CH to evaluate the expression at the location of the current BASIC program pointer in HL and return with the 8-bit value in register A.
    2BllH-2Bl3H
    LD (4094H),A
    Save the 8-bit value in register A in the DOS address of 4094H.
    2Bl4H-2Bl6H
    LD (4097H),A
    Save the 8-bit value in register A in the DOS address of 4097H.

    2Bl7H-2BlAH – CHECK SYNTAX ROUTINE – This checks to see if the next character is a " and contnues on to 2B1CH if it is, and errors out if it isn’t.

    2Bl7H-2Bl8H
    RST 08H
    2E
    Since the character at the location of the current BASIC program pointer in HL must be a “,”, call the COMPARE SYMBOL routine at RST 08H.

    NOTE: The RST 08H routine compares the symbol in the input string pointed to by HL register to the value in the location following the RST 08 call.
    • If there is a match, control is returned to the next execution address (i.e, the RST 08H instruction + 2) with the next symbol in the A Register and HL incremented by one.
    • If the two characters do not match, a syntax error message is given and control returns to the Input Phase).
    2Bl9H-2BlAH
    Jump forward to 2B1CH.

    2BlBH-2B28H – EVALUATE EXPRESSION ROUTINE – This is called by PRINT TAB.

    2BlBH
    RST 10H
    We need the next character in the BASIC program so call the EXAMINE NEXT SYMBOL routine at RST 10H.
    NOTE:
    • The RST 10H routine loads the next character from the string pointed to by the HL register into the A-register and clears the CARRY flag if it is alphabetic, or sets it if is alphanumeric.
    • Blanks and control codes 09H and 0BH are ignored causing the following character to be loaded and tested.
    • The HL register will be incremented before loading any character therfore on the first call the HL register should contain the string address minus one.
    • The string must be terminated by a byte of zeros.

    2B1CH – This routine converts a numeric ASCII string pointed to by the HL into a hexadecimal value and places the result in the A register. If the result is larger than 255 (FFH) then an FC ERROR (Illegal function call) will be generated. After execution the HL will point to the delimiter. If the delimiter is a zero byte or a colon (3AH) then the Z flag will be set. Any other delimiter will cause the Z flag to be reset.

    2BlCH-2BlEH
    Gosub to 2337H to evaluate the expression at the location of the current BASIC program pointer in HL and return with the result in REG l.
    2BlFH-2B21H
    Gosub to 2B05H to convert the result in REG 1 to an integer and return with the integer result in DE.
    2B22H-2B24H
    If the result is greater than 255, display a ?FC ERROR message.
    2B25H
    DEC HL
    Decrement the value of the current BASIC program pointer in HL.
    2B26H
    RST 10H
    We need the next character in the BASIC program so call the EXAMINE NEXT SYMBOL routine at RST 10H.
    NOTE:
    • The RST 10H routine loads the next character from the string pointed to by the HL register into the A-register and clears the CARRY flag if it is alphabetic, or sets it if is alphanumeric.
    • Blanks and control codes 09H and 0BH are ignored causing the following character to be loaded and tested.
    • The HL register will be incremented before loading any character therfore on the first call the HL register should contain the string address minus one.
    • The string must be terminated by a byte of zeros.
    2B27H
    LD A,E
    Load register A with the 8-bit result in register E.
    2B28H
    RET
    Return.

    2B29H-2B2DH – LEVEL II BASIC LLIST ROUTINE

    • This routine sets the output device flag to PRINTER and then flows through to the LIST comman.
    2B29H-2B2AH
    LD A,01H
    Load register A with the printer output device code.
    2B2BH-2B2DH
    LD (409CH),A
    Save the value in register A as the current output device flag.
    Note: 409CH holds the current output device flag: -1=cassette, 0=video and 1=printer.

    2B2EH-2B74H – LEVEL II BASIC LIST ROUTINE.

    • On entry the stack has the return address, then the first basic line number to be listed, then the last basic line number to be listed.
    2B2EH
    POP BC
    Get the return address from the stack and put it in BC.
    2B2FH-2B31H
    Go evaluate the range of line numbers given at the location of the current BASIC program pointer in HL.
    2B32H
    PUSH BC
    Save the address of the first BASIC line (held in BC) to the stack.
    2B33H-2B35H
    LD HL,FFFFH
    Load HL with a -1. This is because the below loop starts with a INC HL, so as to turn the first line number into 0.
    2B36H-2B38H
    LD (40A2H),HL
    Save the value in HL as the current BASIC line number.
    • Note: 40A2H-40A3H holds the current BASIC line number.
    2B39H
    POP HL
    Get the address of the first BASIC line to be listed (from the stack) and put it in HL.
    2B3AH
    POP DE
    Get the value of the last BASIC line number to be listed (from the stack) and put it in DE.
    2B3BH
    LD C,(HL)
    Load register C with the LSB of the next BASIC line pointer at the location of the memory pointer in HL.
    2B3CH
    INC HL
    Bump the value of the memory pointer in HL.
    2B3DH
    LD B,(HL)
    Load register B with the MSB of the next BASIC line pointer at the location of the memory pointer in HL.
    2B3EH
    INC HL
    Bump the value of the memory pointer in HL.
    2B3FH
    LD A,B
    Load register A with the MSB of the next BASIC line pointer in register B.
    2B40H
    OR C
    Combine the LSB of the next BASIC line pointer in register C with the MSB of the next BASIC line pointer in register A. This will let us test for the end of the BASIC program.
    2B4lH-2B43H
    Jump to 1A19H if this is the end of the BASIC program.
    2B44H-2B46H
    Go call the DOS link at 41DFH.
    In NEWDOS 2.1, this is called from LIST processing.
    2B47H-2B49H
    Go scan the keyboard to see if the BREAK key or the shift-@ key was pressed.
    2B4AH
    PUSH BC
    Save the address of the next BASIC line in BC to the stack.
    2B4BH
    LD C,(HL)
    Load register C with the LSB of the BASIC line number at the location of the memory pointer in HL.
    2B4CH
    INC HL
    Bump the value of the memory pointer in HL.
    2B4DH
    LD B,(HL)
    Load register B with the MSB of the BASIC line number at the location of the memory pointer in HL.
    2B4EH
    INC HL
    Bump the value of the memory pointer in HL.
    2B4FH
    PUSH BC
    Save the BASIC line number in BC to the stack.
    2B50H
    EX (SP),HL
    Exchange the value of the memory pointer in HL with the value of the BASIC line number to the stack.
    2B51H
    EX DE,HL
    Exchange the value of the BASIC line number in HL with the value of the last BASIC line number in DE.
    2B52H
    RST 18H
    Now we need to compare the BASIC line number in DE with the last BASIC line number in HL, so we call the COMPARE DE:HL routine at RST 10H.
    NOTE:
    • The RST 10H routine loads the next character from the string pointed to by the HL register into the A-register and clears the CARRY flag if it is alphabetic, or sets it if is alphanumeric.
    • Blanks and control codes 09H and 0BH are ignored causing the following character to be loaded and tested.
    • The HL register will be incremented before loading any character therfore on the first call the HL register should contain the string address minus one.
    • The string must be terminated by a byte of zeros.
    2B53H
    POP BC
    Get the value of the memory pointer from the stack and put it in BC.
    2B54H-2B56H
    Jump to 1A18H if the BASIC line number in DE is greater than the last BASIC line number in HL.
    2B57H
    EX (SP),HL
    Exchange the value of the last BASIC line number in HL with the address of the next BASIC line to the stack.
    2B58H
    PUSH HL
    Save the address of the next BASIC line in HL to the stack.
    2B59H
    PUSH BC
    Save the memory pointer in BC to the stack.
    2B5AH
    EX DE,HL
    Load HL with the BASIC line number in DE.
    2B5BH-2B5DH
    LD (40ECH),HL
    Save the BASIC line number in HL.
    Note: 40ECH-40EDH holds EDIT line number.
    2B5EH-2B60H
    Call the HL TO ASCII routine at 0FAFH (which converts the value in the HL (assumed to be an integer) to ASCII and display it at the current cursor position on the video screen) to display the current BASIC line number.
    2B61H-2B62H
    LD A,20H
    Load register A with a space.
    2B63H
    POP HL
    Get the value of the memory pointer from the stack and put it in HL.
    2B64H-2B66H
    Go send the space in register A to the current output device.
    2B67H-2B69H
    Gosub to 2B7EH move the BASIC line at the location of the memory pointer in HL into the input buffer and untokenize the BASIC line.
    2B6AH-2B6CH
    LD HL,(40A7H)
    Load HL with the starting address of the input buffer.
    Note: 40A7H-40A8H holds the input Buffer pointer.
    2B6DH-2B6FH
    Since we need to send the BASIC line in the input buffer to the current output device we call the PRINT MESSAGE routine at 2B75H which writes string pointed to by HL to the current output device.
    2B70H-2B72H
    Go send a carriage return to the current output device.
    2B73H-2B74H
    Loop back to 2B33H until the listing is complete.

    2B75H-2B7DH – DISPLAY MESSAGE ROUTINE

    • This is the PRINT MESSAGE routine which writes string pointed to by HL to the current output device. String must be terminated by a byte of zeros. This call is different from 28A7H because it does not use the literal string pool area, but it does use the same display routine and it takes the same DOS Exit at 41C1H. Uses all registers. This routine can be called without loading the BASIC utility, if a C9H (RET) is stored in 41ClH.

    This routine outputs a string to device indicated by device type flag stored at 409CH. String must end with zero byte. On entry, HL registers must point to address of start of string. Calls routine at 032AH.

    2B75H
    LD A,(HL)
    Load register A with the character at the location of the memory pointer in HL.
    2B76H
    OR A
    Check to see if the character in register A is an end of the string character (00H).
    2B77H
    RET Z
    Return if the character in register A is an end of the string character.
    2B78H-2B7AH
    Go send the character in register A to the current output device.
    2B7BH
    INC HL
    Bump the value of the memory pointer in HL.
    2B7CH-2B7DH
    Loop back to 2B75H until all of the characters have been sent to the current output device.

    2B7EH-2BC5H – UNTOKENIZE ROUTINE

    • This routine is called by LIST and EDIT. It moves the line pointed to by HL to the input buffer area and then expands each token into the appropriate key word.
    2B7EH
    PUSH HL
    Save the BASIC line pointer in HL to the stack.
    2B7FH-2B81H
    LD HL,(40A7H)
    Load HL with the starting address of the input buffer.
    Note: 40A7H-40A8H holds the input Buffer pointer.
    2B82H
    LD B,H
    Load register B with the MSB of the input buffer pointer in register H.
    2B8JH
    LD C,L
    Load register C with the LSB of the input buffer pointer in register L.
    2B84H
    POP HL
    Get the value of the BASIC line pointer from the stack and put it in HL.
    2B85H-2B86H
    LD D,FFH
    Load register D with the maximum length of an untokenized line.
    2B87H-2B88H
    Jump forward to 2B8CH into the middle of the move/expand code.
    2B89H
    INC BC
    Bump the value of the input buffer pointer in BC.
    2B8AH
    DEC D
    Decrement the character count in register D.
    2B8BH
    RET Z
    Return if 256 characters have been moved into the input buffer.
    2B8CH
    LD A,(HL)
    Load register A with the character at the location of the BASIC line pointer in HL.
    2B8DH
    OR A
    Set the status flags to enable us to check to see if the character in register A is an end of the BASIC line character.
    2B8EH
    INC HL
    Bump the value of the BASIC line pointer in HL to the next character in the code string.
    2B8FH
    LD (BC),A
    Save the character at the location of the input buffer pointer (held in register A)to the memory location held by BC.
    2B90H
    RET Z
    Return if the character in register A is an end of the BASIC line character.
    2B91H-2B93H
    Jump back to 2B89H if the character in register A isn’t a BASIC token.
    2B94H-2B95H
    CP FBH
    Check to see if the character in register A is a ' token.
    2B96H-2B97H
    Jump forward to 2BA0H if the character in register A isn’t a ' token.
    2B98H
    DEC BC
    The next bunch of opcodes is to backspace the expanded buffer pointer by 4 and then adjust the count of characters in the buffer. First, decrement the value of the input buffer pointer in BC.
    2B99H
    DEC BC
    Decrement the value of the input buffer pointer in BC.
    2B9AH
    DEC BC
    Decrement the value of the input buffer pointer in BC.
    2B9BH
    DEC BC
    Decrement the value of the input buffer pointer in BC.
    2B9CH
    INC D
    Bump the value of the character counter in register D.
    2B9DH
    INC D
    Bump the value of the character counter in register D.
    2B9EH
    INC D
    Bump the value of the character counter in register D.
    2B9FH
    INC D
    Bump the value of the character counter in register D.
    2BA0H-2BA1H
    CP 95H
    Check to see if the character in register A is an ELSE token.
    2BA2H-2BA4H
    If it was an ELSE we need to backspace the expanded buffer pointer so … go back to 0B24H to decrement the value of the input buffer pointer if the character in register A is an ELSE token.
    2BA5H-2BA6H
    SUB 7FH
    Subtract 7F to get the number of the entry we are looking for in token list.
    2BA7H
    PUSH HL
    Save the value of the BASIC line pointer in HL to the stack.
    2BA8H
    LD E,A
    Load register E with the character in register A.
    2BA9H-2BABH
    LD HL,1650H
    Load HL with the starting address of the reserved words list.
    2BACH
    LD A,(HL)
    Load register A with the character at the location of the reserved words list pointer in HL.
    2BADH
    OR A
    Test the value of the character in register A.
    2BAEH
    INC HL
    Bump the value of the reserved words list pointer in HL.
    2BAFH-2BB1H
    Jump back to 2BACH if the character at the location of the reserved words pointer in register A doesn’t have bit 7 set.
    2BB2H
    DEC E
    Decrement the value of the token in register E.
    2BB3H-2BB4H
    Jump back to 2BACH if this isn’t the reserved word for the token.
    2BB5H-2BB6H
    AND 7FH
    Reset bit 7 of the character in register A by ANDing it against 0111 1111.
    2BB7H
    LD (BC),A
    Save the character in register A at the location of the input buffer pointer in BC.
    2BB8H
    INC BC
    Bump the value of the input buffer pointer in BC.
    2BB9H
    DEC D
    Decrement the value of the character counter in register D.
    2BBAH-2BBCH
    Jump back to 28D8H if the maximum number of characters have been put into the input buffer.
    2BBDH
    LD A,(HL)
    Load register A with the character at the location of the reserved words pointer in HL.
    2BBEH
    INC HL
    Bump the reserved words pointer in HL.
    2BBFH
    OR A
    Test the value of the character in register A.
    2BC0H-2BC2H
    Jump back to 2BB7H if bit 7 of the character in register A isn’t set.
    2BC3H
    POP HL
    Get the value of the BASIC line pointer from the stack and put it in HL.
    2BC4H-2BC5H
    Jump back to 2B8CH.
    2BC6H-2BF4H
    LEVEL II BASIC DELETE ROUTINE
    2BC6H-2BC8H
    Gosub to 1B10H to evaluate the line numbers at the location of the current BASIC program pointer in HL.
    2BC9H
    POP DE
    Get the value of the last BASIC line number to be deleted (in binary) from the stack and put it in DE.
    2BCAH
    PUSH BC
    Save the address of the first BASIC line to be deleted in BC to the stack.
    2BCBH
    PUSH BC
    Save the address of the first BASIC line to be deleted in BC to the stack AGAIN!.
    2BCCH-2BCEH
    Gosub to 1B2CH to the SEARCH FOR LINE NUMBER routine which looks for the line number specified in DE so as to get the address of the last line to be deleted.Returns C/Z with the line found in BC, NC/Z with line number is too large and HL/BC having the next available location, or NC/NZ with line number not found, and BC has the first available one after that.
    2BCFH-2BD0H
    Goto 2BD6H to show a ?FC ERROR if the SEARCH FOR LINE NUMBER routine returns a NC, that means that the line searched for (in this case, the last line to be deleted) does not exist; and if that’s the case, jump to 2BDH6.
    2BD1H
    LD D,H
    Load register D with the MSB of the last BASIC line’s address in register H.
    2BD2H
    LD E,L
    Load register E with the LSB of the last BASIC line’s address in register L.
    2BD3H
    EX (SP),HL
    Exchange the last BASIC line’s address in HL with the first BASIC line’s address to the stack.
    2BD4H
    PUSH HL
    Save the first BASIC line’s address in HL to the stack.
    2BD5H
    RST 18H
    Now we need to check to see if the first BASIC line’s address in HL is greater than or equal to the last BASIC line’s address in DE, so we call the COMPARE DE:HL routine at RST 10H.
    NOTE:
    • The RST 10H routine loads the next character from the string pointed to by the HL register into the A-register and clears the CARRY flag if it is alphabetic, or sets it if is alphanumeric.
    • Blanks and control codes 09H and 0BH are ignored causing the following character to be loaded and tested.
    • The HL register will be incremented before loading any character therfore on the first call the HL register should contain the string address minus one.
    • The string must be terminated by a byte of zeros.
    2BD6H-2BD8H
    Display a ?FC ERROR message if the first BASIC lines address in HL is greater than or equal to the last BASIC line’s address in DE.
    2BD9H-2BDBH
    LD HL,1929H
    Load HL with the starting address of the BASIC READY message.
    2BDCH-2BDEH
    We need to display the Level II BASIC READY message, so we call the WRITE MESSAGE routine at 28A7H.
    NOTE:
    • The routine at 28A7 displays the message pointed to by HL on current system output device (usually video).
    • The string to be displayed must be terminated by a byte of machine zeros or a carriage return code 0D.
    • If terminated with a carriage return, control is returned to the caller after taking the DOS exit at 41D0H (JP 5B99H).
    2BDFH
    POP BC
    Get the first BASIC line’s address from the stack and put it in BC.
    2BE0H-2BE2H
    LD HL,1AE8H
    Load HL with the return address.
    2BE3H
    EX (SP),HL
    Exchange the value of the return address in HL with the value of the last BASIC line’s address to the stack.
    2BE4H
    EX DE,HL
    Load DE with the last BASIC line’s address in HL.
    2BE5H-2BE7H
    LD HL,(40F9H)
    Load HL with the end of the BASIC program pointer.
    • Note: 40F9H-40FAH holds the starting address of the simple variable storage area.
    2BE8H
    LD A,(DE)
    Load register A with the character at the location of the memory pointer in DE.
    2BE9H
    LD (BC),A
    Save the character in register A at the location of the memory pointer in BC.
    2BEAH
    INC BC
    Bump the value of the memory pointer in BC.
    2BEBH
    INC DE
    Bump the value of the memory pointer in DE.
    2BECH
    RST 18H
    Now we need to check to see if the memory pointer in DE equals the end of the BASIC program pointer in HL, so we call the COMPARE DE:HL routine at RST 10H.
    NOTE:
    • The RST 10H routine loads the next character from the string pointed to by the HL register into the A-register and clears the CARRY flag if it is alphabetic, or sets it if is alphanumeric.
    • Blanks and control codes 09H and 0BH are ignored causing the following character to be loaded and tested.
    • The HL register will be incremented before loading any character therfore on the first call the HL register should contain the string address minus one.
    • The string must be terminated by a byte of zeros.
    2BEDH-2BEEH
    Loop back to 2BE8H until the memory pointer in DE equals the end of the BASIC program pointer in HL.
    2BD3H
    EX (SP),HL
    Exchange the last BASIC line’s address in HL with the first BASIC line’s address to the stack.
    2BD4H
    PUSH HL
    Save the first BASIC line’s address in HL to the stack.
    2BD5H
    RST 18H
    Now we need to check to see if the first BASIC line’s address in HL is greater than or equal to the last BASIC line’s address in DE, so we call the COMPARE DE:HL routine at RST 10H.
    NOTE:
    • The RST 10H routine loads the next character from the string pointed to by the HL register into the A-register and clears the CARRY flag if it is alphabetic, or sets it if is alphanumeric.
    • Blanks and control codes 09H and 0BH are ignored causing the following character to be loaded and tested.
    • The HL register will be incremented before loading any character therfore on the first call the HL register should contain the string address minus one.
    • The string must be terminated by a byte of zeros.
    2BD6-2BD8H
    Display a ?FC ERROR if the first BASIC lines address in HL is greater than or equal to the last BASIC line’s address in DE.
    2BD9-2BDBH
    LD HL,1929H
    Load HL with the starting address of the BASIC READY message.
    2BDC-2BDEH
    We need to display the Level II BASIC READY message, so we call the WRITE MESSAGE routine at 28A7H.
    NOTE:
    • The routine at 28A7 displays the message pointed to by HL on current system output device (usually video).
    • The string to be displayed must be terminated by a byte of machine zeros or a carriage return code 0D.
    • If terminated with a carriage return, control is returned to the caller after taking the DOS exit at 41D0H (JP 5B99H).
    2BDFH
    POP BC
    Get the first BASIC line’s address from the stack and put it in BC.
    2BE0-2BE2H
    LD HL,1AE8H
    Load HL with the return address.
    2BE3H
    EX (SP),HL
    Exchange the value of the return address in HL with the value of the last BASIC line’s address to the stack.
    2BE4H
    EX DE,HL
    Load DE with the last BASIC line’s address in HL.
    2BE5-2BE7H
    LD HL,(40F9H)
    Load HL with the end of the BASIC program pointer.
    • Note: 40F9H-40FAH holds the starting address of the simple variable storage area.
    2BE8H
    LD A,(DE)
    Load register A with the character at the location of the memory pointer in DE.
    2BE9H
    LD (BC),A
    Save the character in register A at the location of the memory pointer in BC.
    2BEAH
    INC BC
    Bump the value of the memory pointer in BC.
    2BEBH
    INC DE
    Bump the value of the memory pointer in DE.
    2BECH
    RST 18H
    Now we need to check to see if the memory pointer in DE equals the end of the BASIC program pointer in HL, so we call the COMPARE DE:HL routine at RST 10H.
    NOTE:
    • The RST 10H routine loads the next character from the string pointed to by the HL register into the A-register and clears the CARRY flag if it is alphabetic, or sets it if is alphanumeric.
    • Blanks and control codes 09H and 0BH are ignored causing the following character to be loaded and tested.
    • The HL register will be incremented before loading any character therfore on the first call the HL register should contain the string address minus one.
    • The string must be terminated by a byte of zeros.
    2BED-2BEEH
    Loop until the memory pointer in DE equals the end of the BASIC program pointer in HL.
    2BEFH
    LD H,B
    Load register H with the MSB of the memory pointer in register B.
    2BF0H
    LD L,C
    Load register L with the LSB of the memory pointer in register C.
    2BF1-2BF3H
    LD (40F9H),HL
    Save the value in HL as the new end of the BASIC program pointer.
    • Note: 40F9H-40FAH holds the starting address of the simple variable storage area.
    2BF4H
    RET
    Return.

    2BF5-2C1EH – LEVEL II BASIC CSAVE ROUTINE

    2BF5-2BF7H
    Calls the WRITE LEADER routine at 0284H (which writes a Level II leader on the cassette unit set in register A).
    2BF8H
    2BFAH Go evaluate the rest of the CSAVE expression at the location of the current BASIC program pointer in HL and return with the result in REG l.
    2BFBH
    PUSH HL
    Save the value of the current BASIC program pointer in HL to the stack so we can get it back at the end of the routine.
    2BFC-2BFEH
    Go get the starting address of the filename into DE.
    2BFF-2C00H
    LD A,D3H
    Load register A with the filename header byte (=D3H which is a “S” with the sign bit on).
    2C01-2C03H
    the WRITE ONE BYTE TO CASSETTE routine at 0264H (which writes the byte in the A register to the cassette drive selected in the A register), which in this case the filename header byte.
    2C04-2C06H
    Go write the filename header byte in register A twice more.
    2C07H
    LD A,(DE)
    Load register A with the first character of the filename at the location of the filename pointer in DE.
    2C08-2C0AH
    the WRITE ONE BYTE TO CASSETTE routine at 0264H (which writes the byte in the A register to the cassette drive selected in the A register), which in this case is the filename.
    2C0B-2C0DH
    LD HL,(40A4H)
    Load HL with the start of the BASIC program pointer.
    • Note: 40A4H-40A5H holds the starting address of BASIC program text also known as the PROGRAM STATEMENT TABLE (PST).
    2C0EH
    EX DE,HL
    Load DE with the start of the BASIC program pointer in HL.
    2C0F-2C11H
    LD HL,(40F9H)
    Load HL with the end of the BASIC program pointer.
    • Note: 40F9H-40FAH holds the starting address of the simple variable storage area.
    2C12H
    LD A,(DE)
    We are going to loop from DE (start of program) to HL (end of program) now. Load register A with the character at the location of the memory pointer in DE.
    2C13H
    INC DE
    Bump the value of the memory pointer in DE.
    2C14-2C16H
    the WRITE ONE BYTE TO CASSETTE routine at 0264H (which writes the byte in the A register to the cassette drive selected in the A register).
    2C17H
    RST 18H
    Now we need to check to see if the memory pointer in DE is equal to the end of the BASIC program pointer in HL, so we call the COMPARE DE:HL routine at RST 10H.
    NOTE:
    • The RST 10H routine loads the next character from the string pointed to by the HL register into the A-register and clears the CARRY flag if it is alphabetic, or sets it if is alphanumeric.
    • Blanks and control codes 09H and 0BH are ignored causing the following character to be loaded and tested.
    • The HL register will be incremented before loading any character therfore on the first call the HL register should contain the string address minus one.
    • The string must be terminated by a byte of zeros.
    2C18-2C19H
    Loop back to 2C12H until the memory pointer in DE is equal to the end of the BASIC program pointer in HL.
    2C1A-2C1CH
    All done! Gosub 01F8H to turn the cassette recorder off.
    2C1DH
    POP HL
    Get the value of the current BASIC program pointer from the stack and put it in HL.
    2C1EH
    RET
    Return.

    2C1F-2CA4H – LEVEL II BASIC CLOAD ROUTINE – ROM v1.0

    2C1FH-2C21H
    Go turn on the cassette recorder.
    2C22H
    LD A,(HL)
    Load register A with the character at the location of the current BASIC program pointer in HL.
    2C23H-2C24H
    SUB 0B2H
    Check to see if the character at the location of the current BASIC program pointer in register A is a ?.
    2C25H-2C26H
    Jump to the CLOAD? routine at 2C29H if the character at the location of the current BASIC program pointer in register A is a ?.
    2C27H
    XOR A
    OK – So this is now a straight CLOAD. First, zero register A.
    2C28H
    01
    Z-80 Trick! The next instruction would set the flag for a CLOAD? which we don’t want if we are passing through because we need A to be 0, so 2C28H starts with a 01H which would be a meaningless LOAD statement and assumes that the following instruction at 2C29H is what to load it with, effectively skipping 2C29H. BUT, if you jump to 2C29H you get the actual XOR command and keep going.
    2C29H
    CPL
    Load register A with a -1 for CLOAD?. It will still be a 0 if this is CLOAD.
    2C2AH
    INC HL
    Bump the value of the current BASIC program pointer in HL until it points to the next character if CLOAD?.
    2C2BH
    PUSH AF
    Save the CLOAD/CLOAD? flag in register A to the stack.
    2C2CH
    DEC HL
    Decrement the value of the current BASIC program pointer in HL.
    2C2DH
    RST 10H
    We need the next character in the BASIC program so call the EXAMINE NEXT SYMBOL routine at RST 10H.
    NOTE:
    • The RST 10H routine loads the next character from the string pointed to by the HL register into the A-register and clears the CARRY flag if it is alphabetic, or sets it if is alphanumeric.
    • Blanks and control codes 09H and 0BH are ignored causing the following character to be loaded and tested.
    • The HL register will be incremented before loading any character therfore on the first call the HL register should contain the string address minus one.
    • The string must be terminated by a byte of zeros.
    2C2E-2C2FH
    LD A,00H
    Zero register A.
    2C30H-2C31H
    Jump if the character at the location of the current BASIC program pointer in HL is an end of the BASIC statement character.
    2C32H-2C34H
    To get the filename we need to gosub to 2337H to evaluate the expression at the location of the current BASIC program pointer in HL and return with the result in REG 1.
    2C35H-2C37H
    Go get the filename’s address in DE.
    2C38H
    LD A,(DE)
    Load register A with the first character of the filename at the location of the filename pointer in DE.
    2C39H
    LD L,A
    Load register L with the filename in register A.
    2C3AH
    POP AF
    Get the value of the CLOAD/CLOAD? flag from the stack and put it in register A.
    2C3BH
    OR A
    Test the value of the CLOAD/CLOAD? flag in register A.
    2C3CH
    LD H,A
    Load register H with the value of the CLOAD/CLOAD? flag in register A.
    2C3D-2C3FH
    LD (4121H),HL
    Save the value of the CLOAD/CLOAD? flag and the filename in HL in REG 1.
    2C40H-2C42H
    Call the NEW routine at 1B4D if it is a CLOAD.
    2C43H-2C45H
    LD HL,(4121H)
    Load HL with the CLOAD/CLOAD? flag and the filename in REG 1.

    *2C1F-2CA4H – LEVEL II BASIC CLOAD ROUTINE – ROM v1.2

    *2C1FH
    SUB 0B2H
    Test for CLOAD?
    *2C21H
    Jump to 2C25H if it is CLOAD?
    *2C23H
    XOR A
    Signal CLOAD (not CLOAD?)
    *2C24H
    LD BC,232FH
    CPL A=-1 if CLOAD?, 0000 if CLOAD
    *2C27H
    PUSH AF
    Increment HL to the filname of the CLOAD/CLOAD? flag
    *2C28H
    LD A,(HL)
    Set the next element from the code string, which should be the filename
    *2C29H
    OR A
    Set status flags
    *2C2AH
    If it is the EOL, jump to 2C33H
    *2C2CH
    Call 2337H to get the filename.
    *2C2FH
    Call 2A13H to get the address of the filename into DE
    *2C32H
    LD A,(DE)
    Get the filename
    *2C33H
    LD L,A
    Move the filename into Register L
    *2C34H
    POP AF
    Restore the CLOAD/CLOAD? flag
    *2C35H
    OR A
    Set the status register according to that flag
    *2C36H
    LD H,A
    H will now hold CLOAD/CLOAD? flag, and L will hold the filename
    *2C37H
    LD (4121H),HL
    Put the flag and filename into REG 1.
    *2C3AH
    If the flag is a CLOAD, call the NEW routine at 1B4DH.
    *2C3DH
    LD HL,0000H
    Cause the drive to be selected
    *2C40H
    Call 2093H to get the leader and sync byte from the cassette.
    *2C43H
    LD HL,(4121H)
    Restore the CLOAD/CLOAD? flag and filename

    Common code between ROM v1.0 and v1.2 continues here.

    2C46H
    EX DE,HL
    Load DE with the CLOAD/CLOAD? flag and load the filename into HL.
    2C47H-2C48H
    LD B,03H
    Load register B with the number of bytes for the filename header to match against (which is 3 … 3 S’s with the sign bit on).
    2C49H-2C4BH
    Calls the READ ONE BYTE FROM CASSETTE routine at 0235H (which reads one byte from the cassette drive specified in register A, and returns the byte in register A).
    2C4CH-2C4DH
    SUB 0D3H
    Check to see if the character in register A is a filename header byte.
    2C4EH-2C4FH
    Loop if the character in register A isn’t a filename header byte.
    2C50H-2C51H
    DJNZ 2C49H
    Loop back to 2C49H until three filename header bytes (3 S’s with the sign bit on) have been read.
    2C52H-2C54H
    Now that the header is out of the way, let’s start working on the filename. Gosub to 0235H to the READ ONE BYTE FROM CASSETTE (which reads one byte from the cassette drive specified in register A, and returns the byte in register A).
    2C55H
    INC E
    We need to test to see if a filename was even given so we have to increase and decrease E to set flags … Bump the value of the filename in register E.
    2C56H
    DEC E
    Decrement the value of the filename in register E.
    2C57H-2C58H
    Jump to 2C5CH if no filename was specified.
    2C59H
    CP E
    If we are here, then the user has supplied a filename which is held in Register E AND we have the first byte from the tape in Register A, so we need to compare the filename specified in register E with the character in register A.

    2CA5H – “BCD” message string.

    2C5AH-2C5BH
    Jump to 2C93H (to skip to the end of that file) if the filename specified in register E doesn’t match the byte read from tape in register A.
    2C5CH-2C5EH
    LD HL,(40A4H)
    If we are here, the filename on tape matches the filename given so lets start loading. Load HL with the start of the BASIC program pointer.
    • Note: 40A4H-40A5H holds the starting address of BASIC program text also known as the PROGRAM STATEMENT TABLE (PST).

    This loop is going to read a byte, compare it to the next byte in the program memory, jump away if it doesn’t match AND CLOAD? was chosen, write (or overwrite) that byte to memory, check for a zero, and loop back if no zero was found.

    2C5FH-2C60H
    LD B,03H
    Load register B with the number of zeros to look for to stop the load (which is 3).
    2C61H-2C63H
    Calls the READ ONE BYTE FROM CASSETTE routine at 0235H (which reads one byte from the cassette drive specified in register A, and returns the byte in register A).
    2C64H
    LD E,A
    Load register E with the character in register A.
    2C65H
    SUB (HL)
    Compare the character we just read from the tape (held in register A) with the character at the location of the memory pointer in HL by subtracting them.
    2C66H
    AND D
    Combine the subtracted result in register A with the value of the CLOAD/CLOAD? flag in register D.
    2C67-2C68H
    Jump to 2C8AH if CLOAD? was selected but the bytes don’t match.
    2C69H
    LD (HL),E
    At this point either CLOAD? was selected and the bytes match, or CLOAD was selected. Either way, save the character we read from the tape (held in register E) to the location of the memory pointer in HL.
    2C6A-2C6CH
    Go check for an ?OM ERROR.
    2C6DH
    LD A,(HL)
    Load register A with the character at the location of the memory pointer in HL.
    2C6EH
    OR A
    Check to see if the byte just read in register A is equal to zero.
    2C6FH
    INC HL
    Bump the value of the memory pointer in HL.
    2C70-2C71H
    Loop if the byte in register A isn’t equal to zero (meaning that it isn’t end of program or end of statement).
    2C72-2C74H
    Call the BLINK ASTERISK routine at 022CH which alternatively displays and clears an asterisk in the upper right hand corner of the video display.
    2C75-2C76H
    DJNZ 2C61H
    Do that loop until three zeros in a row have been read from the cassette recorder.
    2C77-2C79H
    LD (40F9H),HL
    By this point, HL will have been incremented all the way through the program. Save the value of the memory pointer in HL as the new end of the BASIC program pointer.
    • Note: 40F9H-40FAH holds the starting address of the simple variable storage area.
    2C7A-2C7CH
    LD HL,1929H
    Load HL with the starting address of the BASIC READY message.
    2C7D-2C7FH
    We need to display the Level II BASIC READY message, so we call the WRITE MESSAGE routine at 28A7H.
    NOTE:
    • The routine at 28A7 displays the message pointed to by HL on current system output device (usually video).
    • The string to be displayed must be terminated by a byte of machine zeros or a carriage return code 0D.
    • If terminated with a carriage return, control is returned to the caller after taking the DOS exit at 41D0H (JP 5B99H).
    2C80-2C82H
    Go turn off the cassette recorder.
    2C83-2C85H
    LD HL,(40A4H)
    Load HL with the start of the BASIC program pointer.
    • Note: 40A4H-40A5H holds the starting address of BASIC program text also known as the PROGRAM STATEMENT TABLE (PST).
    2C86H
    PUSH HL
    Save the start of the BASIC program pointer in HL to the stack.
    2C87-2C89H
    Jump to 1AE8H to reinitialize the BASIC interpreter and continue.
    2C8A-2C8CH
    LD HL,2CA5H
    Load HL with the starting address of the BAD message.
    2C8D-2C8FH
    We need to display the BAD message, so we call the WRITE MESSAGE routine at 28A7H.
    NOTE:
    • The routine at 28A7 displays the message pointed to by HL on current system output device (usually video).
    • The string to be displayed must be terminated by a byte of machine zeros or a carriage return code 0D.
    • If terminated with a carriage return, control is returned to the caller after taking the DOS exit at 41D0H (JP 5B99H).
    2C90-2C92H
    Jump to 1AE8H to reinitialize the BASIC interpreter and continue.
    2C93-2C95H
    LD (3C3EH),A
    Go display the filename on the video display.
    2C96-2C97H
    LD B,03H
    Load register B with the number of zeros to be found to stop the search.
    2C98-2C9AH
    Calls the READ ONE BYTE FROM CASSETTE routine at 0235H (which reads one byte from the cassette drive specified in register A, and returns the byte in register A).
    2C9BH
    OR A
    Check to see if the character in register A is equal to zero.
    2C9C-2C9DH
    Loop if the character in register A isn’t equal to zero.
    2C9E-2C9FH
    DJNZ 2C98H
    Loop until three zeros in a row have been read from the cassette recorder.
    2CA0-2CA2H
    Calls the READ CASSETTE LEADER routine at 0296 (which reads from the cassette recorder selected in register A until the end-of-leader marker of A5H is found; and flashes the cursor while doing this).
    2CA3-2CA4H
    Jump back to 2C47H.

    2CA5H-2CA9H – MESSAGE STORAGE LOCATION

    2CA5-2CA9H
    “BAD”
    The BAD message is stored here.

    2CAAH-2CB0H – LEVEL II BASIC PEEK ROUTINE – On entry, REG 1 to have the peek location, and on exit Reg 1 to have the peeked value.

    2CAAH-2CACH
    Call the CONVERT TO INTEGER routine at 0A7FH (where the contents of REG 1 are converted from single or double precision to integer and deposited into HL).
    2CADH
    LD A,(HL)
    Load register A with the value at the location of the memory pointer in HL.
    2CAEH-2CB0H
    Go save the 8-bit value in register A as the current result in REG 1.

    2CB1H-2CBCH – LEVEL II BASIC POKE ROUTINE

    2CB1H-2CB3H
    Go evaluate the expression at the location of the current BASIC program pointer in HL and return with the integer result in DE.
    2CB4H
    PUSH DE
    Save the address the user wants to POKE to (held in DE) to the stack.
    2CB5H-2CB6H
    RST 08H
    2EH
    Since the character at the location of the current BASIC program pointer in HL must be a ,, call the COMPARE SYMBOL routine at RST 08H.

    NOTE: The RST 08H routine compares the symbol in the input string pointed to by HL register to the value in the location following the RST 08 call.
    • If there is a match, control is returned to the next execution address (i.e, the RST 08H instruction + 2) with the next symbol in the A Register and HL incremented by one.
    • If the two characters do not match, a syntax error message is given and control returns to the Input Phase).
    2CB7H-2CB9H
    Gosub to 2B1CH to evaluate the expression at the location of the current BASIC program pointer in HL and return with the 8-bit value in register A.
    2CBAH
    POP DE
    Get the address the user wants to POKE to from the stack and put it in DE.
    2CBBH
    LD (DE),A
    Save the value the user wanted to poke (held in register A) in the location that the user wants to POKE to (held in DE).
    2CBCH
    RET
    Return.

    2CBDH-2E52H – LEVEL II BASIC USING ROUTINE

    2CBDH-2CBFH
    Go evaluate the string expression at the location of the current BASIC program pointer in HL.
    2CC0H-2CC2H
    Go make sure the expression that was just evaluated was a string.
    2CC3H-2CC4H
    RST 08H
    3BH
    Since the character at the location of the current BASIC program pointer in HL must be a “;”, call the COMPARE SYMBOL routine at RST 08H.

    NOTE: The RST 08H routine compares the symbol in the input string pointed to by HL register to the value in the location following the RST 08 call.
    • If there is a match, control is returned to the next execution address (i.e, the RST 08H instruction + 2) with the next symbol in the A Register and HL incremented by one.
    • If the two characters do not match, a syntax error message is given and control returns to the Input Phase).
    2CC5H
    EX DE,HL
    Load DE with the value of the current BASIC program pointer in HL.
    2CC6H-2CC8H
    LD HL,(4121H)
    Load HL with the USING string’s VARPTR.
    2CC9H-2CCAH
    Jump down to 2CD3H to continue.
    2CCBH-2CCDH
    LD A,(40DEH)
    Load register A with the value of the READ/INPUT flag.
    Note: 40DEH holds READ flag.
    2CCEH
    OR A
    Check to see if the READ/INPUT flag in register A indicates INPUT.
    2CCFH-2CD0H
    Jump down to 2CDDH if the READ/INPUT flag in register A indicates INPUT.
    2CD1H
    POP DE
    Restore the current BASIC program pointer (from the stack) into DE.
    2CD2H
    EX DE,HL
    Load HL with the value of the current BASIC program pointer in DE. D will wind up being the length of the string
    2CD3H
    PUSH HL
    Save the USING string’s VARPTR in HL to the stack.
    2CD4H
    XOR A
    Zero register A.
    2CD5H-2CD7H
    LD (40DEH),A
    Clear the READ/INPUT flag.
    Note: 40DEH holds READ flag.
    2CD8H
    CP D
    Check to see if the value in D is equal to zero (by checking it against A which was XOR’d to 0 above).
    2CD9H
    PUSH AF
    Save the value in AF (the difference) to the stack.
    2CDAH
    PUSH DE
    Save the value in DE (the address of the next input symbol from the code string) to the stack.
    2CDBH
    LD B,(HL)
    Load register B with the USING string’s length at the location of the USING string’s VARPTR in HL.
    2CDCH
    OR B
    Check to see if the USING string’s length in register B is equal to zero.
    2CDDH-2CDFH
    Display a ?FC ERROR if the USING string’s length in register B is equal to zero.
    2CE0H
    INC HL
    Bump the value of the USING string’s VARPTR in HL.
    2CE1H
    LD C,(HL)
    Load register C with the LSB of the USING string’s address at the location of the USING string’s VARPTR in HL.
    2CE2H
    INC HL
    Bump the value of the USING string’s VARPTR in HL.
    2CE3H
    LD H,(HL)
    Load register H with the MSB of the USING string’s address at the location of the USING string’s VARPTR in HL.
    2CE4H
    LD L,C
    Load register L with the LSB of the USING string’s address in register C.
    2CE5H-2CE6H
    Jump down to 2D03H to analyze the field description.
    2CE7H
    LD E,B
    Load register E with the USING string’s length in register B.
    2CE8H
    PUSH HL
    Save the value of the current USING string pointer in HL.
    2CE9H-2CEAH
    LD C,02H
    Load register C with the number of %’s substring length.
    2CEBH
    LD A,(HL)
    Load register A with the character at the location of the USING string pointer in HL.
    2CECH
    INC HL
    Bump the value of the USING string pointer in HL.
    2CEDH-2CEEH
    CP 25H
    Check to see if the character in register A is a %.
    2CEFH-2CF1H
    Jump down to 2E17H if the character in register A is a %.
    2CF2H-2CF3H
    CP 20H
    Check to see if the character in register A is a space.
    2CF4H-2CF5H
    Jump down a few opcodes to 2CF9H if the character in register A isn’t a space.
    2CF6H
    INC C
    Bump the % substring length in register C.
    2CF7H-2CF8H
    DJNZ 2CEBH
    Decrement the USING string’s length in register B.
    2CF9H
    POP HL
    At this point we have either exhausted the input or found a non-blank character. In either case … get the value of the USING string pointer from the stack and put it in HL.
    2CFAH
    LD B,E
    Load register B with the USING string’s length.
    2CFBH-2CFCH
    LD A,25H
    Load register A with a %.
    2CFDH-2CFFH
    Go print a + after printing a single % if necessary.
    2D00H-2D02H
    Go print the character in register A.
    2D03H
    XOR A
    Zero register A and clear the flags.
    2D04H
    LD E,A
    Zero register E.
    2D05H
    LD D,A
    Zero register D.
    2D06-2D08H
    Go print a leading + if necessary.
    2D09H
    LD D,A
    Zero register D.
    2D0AH
    LD A,(HL)
    Load register A with the character (i.e., the field description) at the location of the USING string pointer in HL.
    2D0BH
    INC HL
    Bump the value of the USING string pointer in HL.
    2D0C-2D0DH
    CP 21H
    Check to see if the character in register A is a !.
    2D0E-2D10H
    Jump if the character in register A is a !.
    2D11-2D12H
    CP 23H
    Check to see if the character in register A is a #.
    2D13-2D14H
    Jump if the character in register A is a #.
    2D15H
    DEC B
    Decrement the value of the string’s length in register B.
    2D16-2D18H
    Jump if this is the end of the USING string.
    2D19-2D1AH
    CP 2BH
    Check to see if the character in register A is a +.
    2D1B-2D1CH
    LD A,08H
    Set the flag in register A to force a leading +.
    2D1D-2D1EH
    Jump if the character in register A was a +.
    2D1FH
    DEC HL
    Decrement the value of the USING string pointer in HL.
    2D20H
    LD A,(HL)
    Load register A with the character at the location of the USING string pointer in HL.
    2D21H
    INC HL
    Bump the value of the USING string pointer in HL.
    2D22H-2D23H
    CP 2EH
    Check to see if the character in register A is a ..
    2D24H-2D25H
    Jump if the character in register A is a ..
    2D26H-2D27H
    CP 25H
    Check to see if the character in register A is a %.
    2D28H-2D29H
    Jump if the character in register A is a %.
    2D2AH
    CP (HL)
    Compare the character in register A with the character at the location of the USING string pointer in HL.
    2D2BH-2D2CH
    Jump if the character in register A isn’t equal to the character at the location of the USING string pointer in HL.
    2D2DH-2D2EH
    CP 24H
    Check to see if the character in register A is a $.
    2D2FH-2D30H
    Jump if the character in register A is a $.
    2D31H-2D32H
    CP 2AH
    Check to see if the character in register A is a *.
    2D33H-2D34H
    Jump if the character in register A isn’t a *.
    2D35H
    LD A,B
    Load register A with the USING string’s length in register B.
    2D36H-2D37H
    CP 02H
    Check to see if the USING string’s length in register A is at least two.
    2D38H
    INC HL
    Bump the value of the USING string pointer in HL.
    2D39H-2D3AH
    Jump to 2D3EH if the USING string’s length in register A isn’t at least two.
    2D3BH
    LD A,(HL)
    Load register A with the character at the location of the USING string pointer in HL.
    2D3CH-2D3DH
    CP 24H
    Check to see if the character in register A is a string.
    2D3EH-2D3FH
    LD A,20H
    Set the ** edit flag in register A.
    2D40H-2D41H
    Jump if the character in register A isn’t a $.
    2D42H
    DEC B
    Decrement the value of the USING string’s length in register.
    2D43H
    INC E
    Bump the number of characters to the left of the decimal point in register E.
    2D44H-2D45H
    FE AF
    Z-80 Trick to skip over a XOR A if passing through by processing it as a CP AFH.
    2D45H
    XOR A
    This is $ processing for PRINT USING.
    2D46H-2D47H
    ADD A,10H
    Mask the value of the edit flag in register A for leading $‘s.
    2D48H
    INC HL
    Bump the value of the USING string pointer in HL.
    2D49H
    INC E
    Bump the number of characters to the left of the decimal point in register E.
    2D4AH
    ADD A,D
    Combine the value of the edit flag in register D with the value of the edit flag in register A.
    2D4BH
    LD D,A
    Load register D with the value of the edit flag in register A.
    2D4CH
    INC E
    Bump the number of characters to the left of the decimal point in register E.
    2D4DH-2D4EH
    LD C,00H
    Zero the number of characters to the right of the decimal point in register C.
    2D4FH
    DEC B
    Decrement the value of the string’s length in register B.
    2D50H-2D51H
    Jump if this is the end of the string.
    2D52H
    LD A,(HL)
    Load register A with the character at the location of the USING string pointer in HL.
    2D53H
    INC HL
    Bump the value of the USING string pointer in HL.
    2D54H-2D55H
    CP 2EH
    Check to see if the character in register A is a ..
    2D56H-2D57H
    Jump if the character in register A is a ..
    2D58H-2D59H
    CP 23H
    Check to see if the character in register A is a #.
    2D5AH-2D
    5BH Jump if the character in register A is a #.
    2D5CH-2D5DH
    CP 2CH
    Check to see if the character in register A is a ,.
    2D5EH-2D5FH
    Jump if the character in register A isn’t a ,.
    2D60H
    LD A,D
    Load register A with the value of the edit flag in register D.
    2D61H-2D62H
    OR 40H
    Mask the edit flag in register A for ,.
    2D63H
    LD D,A
    Load register D with the value of the edit flag in register A.
    2D64H-2D65H
    Jump to 2D4CH.
    2D66H
    LD A,(HL)
    Load register A with the character at the location of the USING string pointer in HL.
    2D67H-2D68H
    CP 23H
    Check to see if the character in register A is a #.
    2D69H-2D6AH
    LD A,2EH
    Load register A with a decimal point.
    2D6BH-2D6CH
    Jump if the character in register A wasn’t a #.
    2D6DH-2D6EH
    LD C,01H
    Load register C with the number of characters to the right of the decimal point.
    2D6FH
    INC HL
    Bump the value of the USING string pointer in HL.
    2D70H
    INC C
    Bump the number of characters to the right of the decimal point in register C.
    2D71H
    DEC B
    Decrement the value of the string’s length in register B.
    2D72H-2D73H
    Jump if this is the end of the string.
    2D74H
    LD A,(HL)
    Load register A with the character at the location of the USING string pointer in HL.
    2D75H
    INC HL
    Bump the value of the USING string pointer in HL.
    2D76H-2D77H
    CP 23H
    Check to see if the character in register A is a #.
    2D78H-2D79H
    Jump if the character in register A is a #.
    2D7AH
    PUSH DE
    Save the value of the edit flag and the count of the characters to the left of the decimal point in DE to the stack.
    2D7BH-2D7DH
    LD DE,2D97H
    Load DE with the return address.
    2D7EH
    PUSH DE
    Save the value of the return address in DE to the stack.
    2D7FH
    LD D,H
    Load register D with the MSB of the USING string pointer m register H.
    2D80H
    LD E,L
    Load register E with the LSB of the USING string pointer in register L.
    2D81H-2D82H
    CP 5BH
    Check to see if the character in register A is an up arrow.
    2D83H
    RET NZ
    Return if the character in register A isn’t an up arrow.
    2D84H
    CP (HL)
    Check to see if the character at the location of the USING string pointer in HL is an up arrow.
    2D85H
    RET NZ
    Return to 2D97 if the character at the location of the USING string pointer in HL isn’t an up arrow (meaning we do not have a [[ format).
    2D86H
    INC HL
    Bump the value of the USING string pointer in HL.
    2D87H
    CP (HL)
    Check to see if there is a third up arrow at the location of the USING string pointer in HL.
    2D88H
    RET NZ
    Return to 2D97 if the character at the location of the USING string pointer in HL isn’t an up arrow (meaning we do not have a [[[ format).
    2D89H
    INC HL
    Bump the value of the USING string pointer in HL.
    2D8AH
    CP (HL)
    Check to see if the character at the location of the USING string pointer in HL is a fourth up arrow.
    2D8BH
    RET NZ
    Return to 2D97 if the character at the location of the USING string pointer in HL isn’t an up arrow (meaning we do not have a [[[[ format).
    2D8CH
    INC HL
    Bump the value of the USING string pointer in HL. If we are here we have a #.##[[[[ format.
    2D8DH
    LD A,B
    Load register A with the value of the USING string’s length in register B.
    2D8EH-2D8FH
    SUB 04H
    Check to see if there are at least 4 characters left in the USING string.
    2D90H
    RET C
    Return to 2D97 if there aren’t at least four characters left in the USING string.
    2D91H
    POP DE
    If there are at least 4 characters left, then clean up the stack.
    2D92H
    POP DE
    Get the edit flag and the count of the characters to the left of the decimal point from the stack and put it in DE.
    2D93H
    LD B,A
    Load register B with the USING string’s length in register A.
    2D94H
    INC D
    Set the exponential notation flag in register D.
    2D95H
    INC HL
    Bump the value of the USING string pointer in HL.
    2D96H
    CA
    Z-80 Trick! By putting the CA opcode here, the next 2 bytes are ignored if passing through, but remain in effect if jumped to.
    2D97H
    EX DE,HL
    (Ignored if passing through) Load HL with the value of the USING string pointer in DE.
    2D98H
    POP DE
    (Ignored if passing through) Get the edit flag and the count of the characters to the left of the decimal point from the stack and put it in DE.
    2D99H
    LD A,D
    Load register A with the value of the edit flag in register D.
    2D9AH
    DEC HL
    Decrement the value of the USING string pointer in HL.
    2D9BH
    INC E
    Bump the number of characters to the left of the decimal point in register E.
    2D9CH-2D9DH
    AND 08H
    Check to see if the sign flag is set in register A.
    2D9EH-2D9FH
    Jump to 2DB5H if the sign flag has already been processed.
    2DA0H
    DEC E
    Decrement the number of characters to the left of the decimal point in register E.
    2DA1H
    LD A,B
    Load register A with the USING string’s length in register B.
    2DA2H
    OR A
    Check to see if this is the end of the string.
    2DA3H-2DA4H
    Jump to 2DB5H if this is the end of the string.
    2DA5H
    LD A,(HL)
    Load register A with the character at the location of the USING string pointer in HL.
    2DA6H-2DA7H
    SUB 2DH
    Check to see if the character in register A is a – .
    2DA8H-2DA9H
    Jump to 2DB0H if the character in register A is a – .
    2DAAH-2DABH
    CP 0FEH
    Check to see if the character in register A is a +.
    2DACH-2DADH
    Jump to 2DB5H if the character in register A isn’t a +.
    2DAEH-2DAFH
    LD A,08H
    Set the edit flag for a + character.
    2DB0H-2DB1H
    ADD A,04H
    Set the edit flag for a – character.
    2DB2H
    ADD A,D
    Combine the value of the edit flag in register D with the value of the edit flag in register A.
    2DB3H
    LD D,A
    Load register D with the value of the edit flag in register A.
    2DB4H
    DEC B
    Decrement the value of the USING string’s length in register B.
    2DB5H
    POP HL
    Get the value of the current BASIC program pointer from the stack and put it in HL.
    2DB6H
    POP AF
    Load register A with the character at the location of the current BASIC program pointer in HL.
    2DB7H-2DB8H
    Jump if this is the end of the BASIC statement.
    2DB9H
    PUSH BC
    Save the count of the characters to the right of the decimal point and the USING string’s length in BC to the stack.
    2DBAH
    PUSH DE
    Save the edit flag and the number of characters to the left of the decimal point in DE to the stack.
    2DBBH-2DBDH
    Go evaluate the expression at the location of the current BASIC program pointer and return with the result in REG 1.
    2DBEH
    POP DE
    Get the edit flag and the number of characters to the left of the decimal point from the stack and put it in DE.
    2DBFH
    POP BC
    Get the number of characters to the right of the decimal point and the USING string’s length from the stack and put it in BC.
    2DC0H
    PUSH BC
    Save the number of characters to the right of the decimal point and the USING string’s length m BC to the stack.
    2DC1H
    PUSH HL
    Save the value of the current BASIC program pointer in HL to the stack.
    2DC2H
    LD B,E
    Load register B with the number of characters to the left of the decimal point in register E.
    2DC3H
    LD A,B
    Load register A with the number of characters to the left of the decimal point in register B.
    2DC4H
    ADD A,C
    Add the number of characters to the right of the decimal point in register C to the number of characters to the left of the decimal point in register A.
    2DC5H-2DC6H
    CP 19H
    Check to see if the total number of characters in register A is greater than 24.
    2DC7H-2DC9H
    Display a FC ERROR message if the total number of characters in register A is greater than 24.
    2DCAH
    LD A,D
    Load register A with the value of the edit flag in register D.
    2DCBH-2DCCH
    OR 80H
    Set the edit flag in register A.
    2DCDH-2DCFH
    Call the FLOATING TO ASCII routine at 0FBEH (whcih converts a single or double precision number in REG 1 to its ASCII equivalent which will be stored at the buffer pointed to by HL using the format codes in the A, B, and C registers.
    2DD0H-2DD2H
    We need to display the ASCII string, so we call the WRITE MESSAGE routine at 28A7H.
    NOTE:
    • The routine at 28A7 displays the message pointed to by HL on current system output device (usually video).
    • The string to be displayed must be terminated by a byte of machine zeros or a carriage return code 0D.
    • If terminated with a carriage return, control is returned to the caller after taking the DOS exit at 41D0H (JP 5B99H).
    2DD3H
    POP HL
    Get the value of the current BASIC program pointer from the stack and put it in HL.
    2DD4H
    DEC HL
    Decrement the value of the current BASIC program pointer in HL.
    2DD5H
    RST 10H
    We need the next character in the BASIC program so call the EXAMINE NEXT SYMBOL routine at RST 10H.
    NOTE:
    • The RST 10H routine loads the next character from the string pointed to by the HL register into the A-register and clears the CARRY flag if it is alphabetic, or sets it if is alphanumeric.
    • Blanks and control codes 09H and 0BH are ignored causing the following character to be loaded and tested.
    • The HL register will be incremented before loading any character therfore on the first call the HL register should contain the string address minus one.
    • The string must be terminated by a byte of zeros.
    2DD6H
    SCF
    Set the Carry flag.
    2DD7H-2DD8H
    Jump if the character at the location of the current BASIC program pointer in register A is an end of the BASIC statement character.
    2DD9H-2DDBH
    LD (40DEH),A
    Save the character at the location of the current BASIC program pointer in register A.
    Note: 40DEH holds READ flag.
    2DDCH-2DDDH
    CP 3BH
    Check to see if the character at the location of the current BASIC program pointer in register A is a semicolon.
    2DDEH-2DDFH
    Jump if the character at the location of the current BASIC program pointer in register A is a semicolon.
    2DE0H-2DE1H
    CP 2CH
    Check to see if the character at the location of the current BASIC program pointer in register A is a comma.
    2DE2H-2DE4H
    Go to the Level II BASIC error routine and display an SN ERROR message if the character at the location of the current BASIC program pointer in register A isn’t a comma.
    2DE5H
    RST 10H
    We need the next character in the BASIC program so call the EXAMINE NEXT SYMBOL routine at RST 10H.
    NOTE:
    • The RST 10H routine loads the next character from the string pointed to by the HL register into the A-register and clears the CARRY flag if it is alphabetic, or sets it if is alphanumeric.
    • Blanks and control codes 09H and 0BH are ignored causing the following character to be loaded and tested.
    • The HL register will be incremented before loading any character therfore on the first call the HL register should contain the string address minus one.
    • The string must be terminated by a byte of zeros.
    2DE6H
    POP BC
    Get the USING string’s length from the stack and put it in register B.
    2DE7H
    EX DE,HL
    Load DE with the value of the current BASIC program pointer in HL.
    2DE8H
    POP HL
    Get the USING string’s VARPTR from the stack and put it in HL.
    2DE9H
    PUSH HL
    Save the USING string’s VARPTR in HL to the stack.
    2DEAH
    PUSH AF
    Save the character at the location of the current BASIC program pointer in register A to the stack.
    2DEBH
    PUSH DE
    Save the value of the current BASIC program pointer in DE to the stack.
    2DECH
    LD A,(HL)
    Load register A with the USING string’s length at the location of the USING string’s VARPTR in HL.
    2DEDH
    SUB B
    Compare the USING string’s length in register B with the USING string’s length in register A.
    2DEEH
    INC HL
    Bump the value of the USING string’s VARPTR in HL.
    2DEFH
    LD C,(HL)
    Load register C with the LSB of the USING string’s address at the location of the USING string’s VARPTR in HL.
    2DF0H
    INC HL
    Bump the value of the USING string’s VARPTR in HL.
    2DF1H
    LD H,(HL)
    Load register H with the MSB of the USING string’s address at the location of the USING string’s VARPTR in HL.
    2DF2H
    LD L,C
    Load register L with the LSB of the USING string’s address in register C.
    2DF3H-2DF4H
    LD D,00H
    Zero register D.
    2DF5H
    LD E,A
    Load register E with the USING string’s offset in register A.
    2DF6H
    ADD HL,DE
    Add the USING string’s offset in DE to the USING string’s address in HL.
    2DF7H
    LD A,B
    Load register A with the USING string’s length in register B.
    2DF8H
    OR A
    Check to see if this is the end of the USING string.
    2DF9H-2DFBH
    Jump to 2D03H if this isn’t the end of the USING string.
    2DFCH-2DFDH
    Jump to 2E04H if this is the end of the USING string.
    2DFEH-2E00H
    Gosub to 2E49H print a + if necessary.
    2E01H-2E03H
    Go send the character in register A to the current output device.
    2E04H
    POP HL
    Get the value of the current BASIC program pointer from the stack and put it in HL.
    2E05H
    POP AF
    Get the character at the location of the current BASIC program pointer from the stack and put it in register A.
    2E06H-2E08H
    Jump back to 2CCBH if this isn’t the end of the BASIC statement.
    2E09H-2E0BH
    Gosub to 20FEH to send a carriage return to the current output device if necessary.
    2E0CH
    EX (SP),HL
    Exchange the value of the current BASIC program pointer in HL with the value of the USING string’s VARPTR to the stack.
    2E0DH-2E0FH
    Go get the USING string’s address in DE.
    2E10H
    POP HL
    Get the value of the current BASIC program pointer from the stack and put it in HL.
    2E11H-2E13H
    Return to 2169H.
    2E14H-2E15H
    LD C,01H
    Continue processing a ! in the USING format by loading register C with the number of characters to be printed.
    2E16H-2E17H
    3E F1
    Z-80 Trick. By putting a 3E in front of the F1 (which is POP AF, to clear the stack) that POP AF gets skipped if flowing down in the code.
    2E17H
    POP AF
    (Skipped if passing down) Clear the stack.
    2E18H
    DEC B
    Decrement the value of the string’s length in register B.
    2E19H-2E1BH
    Go print a + if register D is not zero.
    2E1CH
    POP HL
    Get the value of the current BASIC program pointer from the stack and put it in HL.
    2E1DH
    POP AF
    Get the character at the location of the current BASIC program pointer from the stack and put it in register A.
    2E1EH-2E1FH
    Jump back to 2E09H if the character at the location of the current BASIC program pointer in register A is an end of the BASIC statement character.
    2E20H
    PUSH BC
    Save the USING string’s length and the number of characters to be printed in BC to the stack.
    2E21H-2E23H
    Go evaluate the expression at the location of the current BASIC program pointer in HL and return with the result in REG 1
    2E24H-2E26H
    Go make sure the current result in REG 1 is a string.
    2E27H
    POP BC
    Get the USING string’s length and the number of characters to be printed from the stack and put it in BC.
    2E28H
    PUSH BC
    Save the USING string’s length and the number of characters to be printed in BC to the stack.
    2E29H
    PUSH HL
    Save the value of the current BASIC program pointer in HL to the stack.
    2E2AH-2E2CH
    LD HL,(4121H)
    Load HL with the string’s VARPTR in REG 1.
    2E2DH
    LD B,C
    Load register B with the number of characters to be printed in register C.
    2E2EH-2E2FH
    LD C,00H
    Zero register C.
    2E30H
    PUSH BC
    Save the length of the string to be printed in register B to the stack.
    2E31H-2E33H
    Go evaluate the string to be printed.
    2E34H-2E36H
    Go send the string to the current output device.
    2E37H-2E39H
    LD HL,(4121H)
    Load HL with the string’s VARPTR in REG 1.
    2E3AH
    POP AF
    Get the length of the string to be printed from the stack and put it in register A.
    2E3BH
    SUB (HL)
    Subtract the string’s length at the location of the string’s VARPTR in HL from the length of the string to be printed in register A.
    2EJCH
    LD B,A
    Load register B with the number of spaces to be printed in register A.
    2EJDH-2EJEH
    LD A,20H
    Load register A with a space.
    2E3FH
    INC B
    Bump the number of spaces in register B.

    This loop will print all the spaces needed and then jump to 2DD3H.

    2E40H
    DEC B
    Decrement the number of spaces in register B.
    2E41H-2E43H
    Jump back to 2DD3H if all of the spaces have been printed.
    2E44H-2E46H
    Go send a space to the current output device.
    2E47H-2E48H
    Jump back to 2E40H.
    2E49H
    PUSH AF
    Save the value in register A to the stack.
    2E4AH
    LD A,D
    Load register A with the value in register D.
    2E4BH
    OR A
    Check to see if register A is equal to zero.
    2E4CH-2E4DH
    LD A,2BH
    Load register A with a +.
    2E4EH-2E50H
    Go send a + to the current output device if register D is non-zero.
    2E51H
    POP AF
    Get the value from the stack and put it in register A.
    2E52H
    RET
    Return.

    2E53H-2FFAH – LEVEL II BASIC EDIT ROUTINE

    2E53H-2E55H
    LD (409AH),A
    Reset the error flag.
    Note: 409AH holds the RESUME flag.
    2E56H-2E58H
    LD HL,(40EAH)
    Load HL with the line number where the error occurred.
    Note: 40EAH-40EBH holds the line number with error.
    2E59H
    OR H
    OR register A with the MSB of the error line number in register H.
    2E5AH
    AND L
    Combine the LSB of the error line number in register L with the MSB of the error line number in register A. It will be FFH if execution had not begun.
    2E5BH
    INC A
    Bump the combined value of the error line number in register A. If execution had not begin, this will turn A from FFH into 00H
    2E5CH
    EX DE,HL
    Load DE with the line number with the error (held in HL).
    2E5DH
    RET Z
    If there was no line number, return if Level II BASIC.
    2E5EH-2E5FH
    Jump to 2E64H.

    Now that the above code is out of the way (it was the code which would enter EDIT if there was an error in a line number), let us actually process the EDIT command.

    2E60H-2E62H
    Get the first line number by calling 1E4FH – returns in in DE.
    2E63H
    RET NZ
    If the zero flag got set, there was no line number, so return.
    2E64H
    POP HL
    Clean up the stack.
    2E65H
    EX DE,HL
    Load HL with the line number to be edited in DE.
    2E66H-2E68H
    LD (40ECH),HL
    Save the value of the line number to be edited (in HL) to the memory location that cares about such things.
    Note: 40ECH-40EDH holds EDIT line number.
    2E69H
    EX DE,HL
    Load DE with the line number to be edited in HL.
    2E6AH-2E6CH
    Call the SEARCH FOR LINE NUMBER routine at 1B2CH which looks for the line number specified in DE. Returns C/Z with the line found in BC, NC/Z with line number is too large and HL/BC having the next available location, or NC/NZ with line number not found, and BC has the first available one after that.
    2E6DH-2E6FH
    If the BASIC line number doesn’t exist, display a ?UL ERROR.
    2E70H
    LD H,B
    At this point, the line number has been found. Load register H with the MSB of the memory pointer in register B.
    2E71H
    LD L,C
    Load register L with the LSB of the memory pointer in register C.
    2E72H
    INC HL
    Bump the value of the memory pointer in HL.
    2E73H
    INC HL
    Bump the value of the memory pointer in HL.
    2E74H
    LD C,(HL)
    Load register C with the LSB of the BASIC line number at the location of the memory pointer in HL.
    2E75H
    INC HL
    Bump the value of the memory pointer in HL.
    2E76H
    LD B,(HL)
    Load register B with the MSB of the BASIC line number at the location of the memory pointer in HL.
    2E77H
    INC HL
    Bump the value of the memory pointer in HL.
    2E78H
    PUSH BC
    Save the value of the BASIC line number in BC to the stack.
    2E79H-2E7BH
    Go move the BASIC line we are working on into the input buffer and expand it.
    2E7CH
    POP HL
    Get the value of the BASIC line number from the stack and put it in HL.
    2E7DH
    PUSH HL
    Save the value of the BASIC line number in HL to the stack.
    2E7EH-2E80H
    Convert the line number to ASCII and print it out by calling the HL TO ASCII routine at 0FAFH (which converts the value in the HL (assumed to be an integer) to ASCII and display it at the current cursor position on the video screen).
    2E81H-2E82H
    LD A,20H
    Load register A with a space.
    2E83H-2E85H
    Go display the space in register A.
    2E86H-2E88H
    LD HL,(40A7H)
    Load HL with the starting address of the expended version of the current line from the input buffer.
    Note: 40A7H-40A8H holds the input Buffer pointer.
    2E89H-2E8AH
    LD A,0EH
    Load register A with the “turn on the cursor” character.
    2E8BH-2E8DH
    Go turn on the cursor.
    2E8EH
    PUSH HL
    Save the value of the input buffer pointer (in HL) to the stack.
    2E8FH-2E90H
    LD C,FFH
    Load register C with the number of characters examined so far with FFH because the next line is going to INC it by 1 to make it 0.
    2E91H
    INC C
    Bump the number of characters examined so far in register C.
    2E92H
    LD A,(HL)
    Load register A with the character at the location of the input buffer pointer in HL.
    2E93H
    OR A
    Check to see if the character in register A is an end of the BASIC line character.
    2E94H
    INC HL
    Bump the value of the input buffer pointer in HL.
    2E95H-2E96H
    Loop back to 2E91H until the end of the BASIC line has been found.
    2E97H
    POP HL
    At this point, C will be the maximum number of characters in the line at issue. Put the start of the expended buffer into HL.
    2E98H
    LD B,A
    Zero register B. B will ultimately contain the count of characters inserted.
    2E99H-2E9AH
    LD D,00H
    Zero register D.
    2E9BH-2E9DH
    Go scan the keyboard.
    2D9EH-2E9FH
    SUB 30H
    We need to test to see if the character was alphabetic or alphanumeric so we subtract 30H from it.
    2EA0H-2EA1H
    Jump down to 2EB0H if the character in register A is alphabetic.
    2EA2H-2EA3H
    CP 0AH
    Check to see if the character is register A is numeric.
    2EA4H-2EA5H
    Jump to 2EB0H if the character in register A isn’t numeric.
    2EA6H
    LD E,A
    Load register E with the binary value of the character in register A.
    2EA7H
    LD A,D
    Load register A with the value in register D.
    2EA8H
    RLCA
    Multiply the value in register A by two (so now A has multiplied by 2).
    2EA9H
    RLCA
    Multiply the value in register A by two (so now A has multiplied by 4).
    2EAAH
    ADD A,D
    Add the value in register D to the value in register A (so now A has multiplied by 5).
    2EABH
    RLCA
    Multiply the value in register A by two (so now A has multiplied by 10).
    2EACH
    ADD A,E
    Add the value in register E to the value in register A.
    2EADH
    LD D,A
    Load register D with the value in register A.
    2EAEH-2EAFH
    Loop until a nonnumeric character is pressed.
    2EB0H
    PUSH HL
    Save the value of the input buffer pointer in HL to the stack.
    2EB1H-2EB3H
    LD HL,2E99H
    Load HL with the return address of 2E99H.
    2EB4H
    EX (SP),HL
    Exchange the value of the return address in HL with the value of the input buffer pointer to the stack.
    2EB5H
    DEC D
    We need to test if the command was preceded by a number so we need to set the flags by first … decrementing the numeric value in register D …
    2EB6H
    INC D
    … and then incrementing the numeric value in register D.
    2EB7H-2EB9H
    Jump to 2EBBH if a numeric value preceded the command (i.e., register D isn’t equal to zero).
    2EBAH
    INC D
    Load register D with a one.
    2EBBH-2EBCH
    CP 0D8H
    Check to see if the character in register A is a backspace character.
    2EBDH-2EBFH
    Jump if the character in register A is a backspace character.
    2EC0H-2EC1H
    CP 0DDH
    Check to see if the character in register A is a carriage return.
    2EC2H-2EC4H
    Jump if the character in register A is a carriage return.
    2EC5H-2EC6H
    CP 0F0H
    Check to see if the character in register A is a space.
    2EC7H-2EC8H
    Jump if the character in register A is a space.
    2EC9H-2ECAH
    CP 31H
    Check to see if the character in register A is lowercase.
    2ECBH-2ECCH
    Jump if the character in register A isn’t lowercase.
    2ECDH-2ECEH
    SUB 20H
    Convert the lowercase character in register A to uppercase.
    2ECFH-2ED0H
    CP 21H
    Check to see if the character in register A is a Q.
    2ED1H-2ED3H
    Jump if the character in register A is a Q.
    2ED4H-2ED5H
    CP 1CH
    Check to see if the character in register A is an L.
    2ED6H-2ED7H
    Jump if the character in register A is an L.
    2ED9H-2EDAH
    CP 23H
    Check to see if the character in register A is an S.
    2EDBH-2EDCH
    Jump if the character in register A is an S.
    2EDDH-2EDEH
    CP 19H
    Check to see if the character in register A is an I.
    2EDFH-2EE1H
    Jump if the character in register A is an I.
    2EE2H-2EE3H
    CP 14H
    Check to see if the character in register A is a D.
    2EE4H-2EE6H
    Jump if the character in register A is a D.
    2EE7H-2EE8H
    CP 13H
    Check to see if the character in register A is a C.
    2EE9H-2EEBH
    Jump if the character in register A is a C.
    2EECH-2EEDH
    CP 15H
    Check to see if the character in register A is an E.
    2EEEH-2EF0H
    Jump if the character in register A is an E.
    2EF1H-2EF2H
    CP 28H
    Check to see if the character in register A is an X.
    2EF3H-2EF5H
    Jump if the character in register A is an X.
    2EF6H-2EF7H
    CP 1BH
    Check to see if the character in register A is a K.
    2EF8H-2EF9H
    Jump if the character in register A is a K.
    2EFAH-2EFBH
    CP 18H
    Check to see if the character in register A is an H.
    2EFCH-2EFEH
    Jump if the character in register A is an H.
    2EFFH-2F00H
    CP 11H
    Check to see if the character in register A is an A.
    2F01H
    RET NZ
    Return if the character in register A isn’t an A.

    2F02H – EDIT Command – Cancel and Restore Logic.

    2F02H
    POP BC
    Clean up the stack.
    2F03H
    POP DE
    Get the BASIC line number from the stack and put it in DE.
    2F04H-2F06H
    Go print a carriage return on the video display if necessary.
    2F07H-2F09H
    Jump back to 2E65H to re-enter the EDIT routine.

    2F0AH – This routine prints a string of text to the display, printer or tape. it uses 032AH to do this. HL must point to the first character of the string. (409CH must be set before calling this routine, see 32AH). String must be delimited with a zero byte.
    Note: 409CH holds the current output device flag: -1=cassette, 0=video and 1=printer.

    2F0AH
    LD A,(HL)
    Load register A with the character at the location of the input buffer pointer in HL.
    2F0BH
    OR A
    Check to see if the character in register A is an end of the BASIC line character.
    2F0CH
    RET Z
    Return if the character in register A is an end of the BASIC line character.
    2F0DH
    INC B
    Bump the character position in register B.
    2F0EH-2F10H
    Go display the character in register A.
    2F11H
    INC HL
    Bump the value of the input buffer pointer in HL.
    2F12H
    DEC D
    Decrement the number of times to perform the operation in register D.
    2F13H-2F14H
    Loop until done.
    2F15H
    RET
    Return.

    2F16H – EDIT Command – KILL Logic.

    2F16H
    PUSH HL
    Save the value of the input buffer pointer in HL to the stack.
    2F17H-2F19H
    LD HL,2F5FH
    Load HL with the return address of 2F5FH (which will print the final !).
    2F1AH
    EX (SP),HL
    Exchange the value of the return address in HL with the value of the input buffer pointer to the stack.
    2F1BH
    SCF
    Set the KILL/SEARCH flag for KILL since CARRY flag signals KILL.
    2F1CH
    PUSH AF
    Save the KILL/SEARCH flag to the stack.
    2F1DH-2F1FH
    Go scan the keyboard for the character to locate.
    2F20H
    LD E,A
    Load register E with the character to locate in register A.
    2F21H
    POP AF
    Get the KILL/SEARCH flag from the stack.
    2F22H
    PUSH AF
    Save the KILL/SEARCH flag to the stack.
    2F23H-2F25H
    If KILL (because the CARRY flag was set) then gosub to 2F5FH to print a !.
    2F26H
    LD A,(HL)
    Load register A with the character at the location of the input buffer pointer in HL.
    2F27H
    OR A
    Check to see if the character in register A is an end of the BASIC line character.
    2F28H-2F2AH
    Jump down to 2F3EH if the character in register A is an end of the BASIC line character.
    2F2BH-2F2DH
    Go display the character in register A.
    2F2EH
    POP AF
    Get the KILL/SEARCH flag from the stack.
    2F2FH
    PUSH AF
    Save the KILL/SEARCH flag to the stack.
    2F30H-2F32H
    If the CARRY flag is set, that means we are in KILL mode so GOSUB to 2FA1H to delete the character from the input buffer.
    2F33H-2F34H
    Jump to 2F37H if KILL.
    2F35H
    INC HL
    If we are here, it must be SEARCH! So bump to the next character.
    2F36H
    INC B
    Bump the value of the character position counter in register B.
    2F37H
    LD A,(HL)
    Regardless of whether we are SEARCH or KILL, load register A with the character at the location of the current input buffer pointer in HL.
    2F38H
    CP E
    Check to see if the character in register A is the same as the character to be located in register E.
    2F39H-2F3AH
    Loop back to 2F26H until the character to be located is found.
    2F3BH
    DEC D
    Decrement the number of times to perform the operation in register D.
    2F3CH-2F3DH
    Loop until done.
    2F3EH
    POP AF
    Get the KILL/SEARCH flag from the stack.
    2F3FH
    RET
    Return.

    2F40H – EDIT Command – LIST Logic.

    2F40H-2F42H
    Since we need to display the line being edited we call the PRINT MESSAGE routine at 2B75H which writes string pointed to by HL to the current output device..
    2F43H-2F45H
    Go display a carriage return if necessary.
    2F46H
    POP BC
    Get the BASIC line number from the stack and put it in BC.
    2F47H-2F49H
    Jump to 2E7CH (to print the current line number and await the next EDIT command).

    2F4AH – EDIT Command – DELETE Logic.

    2F4AH
    LD A,(HL)
    Load register A with the character at the location of the input buffer pointer in HL.
    2F4BH
    OR A
    Check to see if the character in register A is an end of the BASIC line character.
    2F5CH
    RET Z
    Return if the character in register A is an end of the BASIC line character.
    2F4DH-2F4EH
    LD A,21H
    Load register A with an !.
    2F4FH-2F51H
    Go display the ! in register A.
    2F52H
    LD A,(HL)
    Load register A with the character at the location of the input buffer pointer in HL.
    2F53H
    OR A
    Check to see if the character in register A is an end of the BASIC line character.
    2F54H-2F5BH
    Jump to 2F5FH if the character in register A is an end of the BASIC line character.
    2F56H-2F58H
    Go display the character in register A.
    2F59H-2F5BH
    Go delete the character from the input buffer.
    2F5CH
    DEC D
    Decrement the number of times to perform the operation in register D.
    2F5DH-2F5EH
    Loop until done.
    2F5FH-2F60H
    LD A,21H
    Load register A with an !.
    2F61H-2F63H
    Go display the ! in register A.
    2F64H
    RET
    Return.

    2F65H – EDIT Command – CHANGE Logic.

    2F65H
    LD A,(HL)
    Load register A with the character at the location of the input buffer pointer in HL.
    2F66H
    OR A
    Check to see if the character in register A is an end of the BASIC line character.
    2F67H
    RET Z
    Return if the character in register A is an end of the BASIC line character.
    2F68H-2F6AH
    Go get the character to put in the input buffer from the keyboard.
    2F6BH
    LD (HL),A
    Save the character in register A at the memory location of the input buffer pointer in HL.
    2F6CH-2F6EH
    Go display the character in register A.
    2F6FH
    INC HL
    Bump the value of the input buffer pointer in HL.
    2F70H
    INC B
    Bump the character position in register B.
    2F71H
    DEC D
    Decrement the number of times to perform the operation in register D.
    2F72H-2F73H
    Loop until done.
    2F74H
    RET
    Return.

    2F75H – EDIT Command – HACK/INSERT Logic.

    2F75H-2F76H
    LD (HL),00H
    Zero the location of the input buffer pointer in HL.
    2F77H
    LD C,B
    Load register C with the character position in register B.
    2F78H-2F79H
    LD D,0FFH
    Load register D with the number of times to perform the operation.
    2F7AH-2F7CH
    Gosub to 2F0AH to display the register BASIC line if necessary.
    2F7DH-2F7FH
    Go get the character to be inserted from the keyboard.
    2F80H
    OR A
    Check to see if a key was pressed.
    2F81H-2F83h
    Loop back to 2F7DH until a key is pressed.
    2F84H-2F85H
    CP 08H
    Check to see if the character in register A is a backspace character.
    2F86H-2F87H
    Jump to 2F92H if the character in register A is a backspace character.
    2F88H-2F89H
    CP 0DH
    Check to see if the character in register A is a carriage return.
    2F8AH-2F8CH
    Jump to 2FE0H if the character in register A is a carriage return.
    2F8DH-2F8EH
    CP 1BH
    Check to see if the character in register A is a shift up arrow.
    2F8FH
    RET Z
    Return if the character in register A is shift up arrow.
    2F90H-2F91H
    Jump to 2FB0H to ass the new character to the current line.

    2F92H – EDIT Command – BACKSPACE CURSOR Logic.

    2F92H-2F93H
    LD A,08H
    Load register A with a backspace the cursor character.
    2F94H
    DEC B
    Decrement the character position in register B.
    2F95H
    INC B
    Bump the character position in register B.
    2F96H-2F97H
    Jump forward to 2FB7H if this is the first character of the BASIC line.
    2F98H-2F9AH
    Go backspace the cursor on the video display.
    2F9BH
    DEC HL
    Decrement the value of the input buffer pointer in HL.
    2F9CH
    DEC B
    Decrement the character position in register B.
    2F9DH-2F9FH
    LD DE,2F7DH
    Load DE with a return address of 2F7DH.
    2FA0H
    PUSH DE
    Save the value of the return address in DE to the stack.
    2FA1H
    PUSH HL
    Save the value of the input buffer pointer in HL to the stack.
    2FA2H
    DEC C
    Decrement the character position in register C.
    2FA3H
    LD A,(HL)
    Load register A with the character at the location of the input buffer pointer in HL.
    2FA4H
    OR A
    Check to see if the character in register A is an end of the BASIC line character.
    2FA5H
    SCF
    Set the Carry flag to signal that the character was deleted.
    2FA6H-2FA8H
    Jump to 0890H if the character in register A is an end of the BASIC line character.
    2FA9H
    INC HL
    Bump the value of the input buffer pointer in HL.
    2FAAH
    LD A,(HL)
    Load register A with the character at the location of the input buffer pointer in HL.
    2FABH
    DEC HL
    Decrement the value of the input buffer pointer in HL.
    2FACH
    LD (HL),A
    Save the character in register A at the location of the current input buffer pointer in HL.
    2FADH
    INC HL
    Bump the value of the input buffer pointer in HL.
    2FAEH-2FAFH
    Loop back to 2FA3H until the line has been moved down.

    2FB0H – EDIT Command – ADD A CHARACTER Logic.

    2FB0H
    PUSH AF
    Save the character to be inserted in register A to the stack.
    2FB1H
    LD A,C
    Load register A with the number of characters in the input buffer in register C.
    2FB2H-2FB3H
    CP FFH
    Check for the maximum BASIC line length.
    2FB4H-2FB5H
    Jump forward to 2FB9H if the maximum BASIC line length hasn’t been reached.
    2FB6H
    POP AF
    Get the character to be inserted from the stack and put it in register A.
    2FB7H-2FB8H
    Jump back to 2F7DH.
    2FB9H
    SUB B
    Subtract the character position in register B from the number of characters in the input buffer in register A. This should give the current byte position.
    2FBAH
    INC C
    Bump the number of characters in the input buffer in register C.
    2FBBH
    INC B
    Bump the character position in register B.
    2FBCH
    PUSH BC
    Save the character position and the number of characters in the input buffer in BC to the stack.
    2FBDH
    EX DE,HL
    Load DE with the input buffer pointer in HL.
    2FBEH
    LD L,A
    Load register L with the character count in register A.
    2FBFH-2FC0H
    LD H,00H
    Zero register H.
    2FC1H
    ADD HL,DE
    Add the value of the input buffer pointer in DE to the character count in HL.
    2FC2H
    LD B,H
    Load register B with the MSB of the end of the BASIC line pointer in register H.
    2FC3H
    LD C,L
    Load register C with the LSB of the end of the BASIC line pointer in register L.
    2FC4H
    INC HL
    Bump the value of the end of the BASIC line pointer in HL.
    2FC5H-2FC7H
    Go move the BASIC line up one character.
    2FC8H
    POP BC
    Get the character position and the number of characters in the input buffer from the stack and put it in BC.
    2FC9H
    POP AF
    Get the character to be inserted from the stack and put it in register A.
    2FCAH
    LD (HL),A
    Save the character in register A at the location of the current input buffer pointer in HL.
    2FCBH-2FCDH
    Go display the character in register A.
    2FCEH
    INC HL
    Bump the value of the input buffer pointer in HL.
    2FCFH-2FD1H
    Jump back to 2F7DH.

    2FD2H – EDIT Command – BACKSPACE Logic.

    2FD2H
    LD A,B
    Load register A with the number of times to backspace in register B.
    2FD3H
    OR A
    Check to see if this is the start of the BASIC line.
    2FD4H
    RET Z
    Return if this is the start of the BASIC line.
    2FD5H
    DEC B
    Decrement the character position in register B.
    2FD6H
    DEC HL
    Decrement the value of the input buffer pointer in HL.
    2FD7H-2FD8H
    LD A,08H
    Load register A with a backspace the cursor character.
    2FD9H-2FDBH
    Go backspace the cursor on the video display.
    2FDCH
    DEC D
    Decrement the number of times to perform the operation in register D.
    2FDDH-2FDEH
    Loop until done.
    2FDFH
    RET
    Return.
    2FE0H-2FE2H
    Since we need to display the rest of the BASIC line, we call the PRINT MESSAGE routine at 2B75H which writes string pointed to by HL to the current output device..
    2FE3H-2FESH
    Go display a carriage return if necessary.
    2FE6H
    POP BC
    Clean up the stack.
    2FE7H
    POP DE
    Get the BASIC line number (in binary) from the stack and put it in DE.
    2FE8H
    LD A,D
    Load register A with the MSB of the BASIC line number in register D.
    2FE9H
    AND E
    Combine the LSB of the BASIC line number in register E with the MSB of the BASIC line number in register A.
    2FEAH
    INC A
    Bump the combined BASIC line number in register A.
    2FEBH-2FEDH
    LD HL,(40A7H)
    Load HL with the starting address of the input buffer.
    Note: 40A7H-40A8H holds the input Buffer pointer.
    2FEEH
    DEC HL
    Decrement the value of the input buffer pointer in HL.
    2FEFH
    RET Z
    Return if this is the Level II BASIC command mode.
    2FF0H
    SCF
    Set the Carry flag to signal a BASIC program statement.
    2FF1H
    INC HL
    Bump the value of the input buffer pointer in HL.
    2FF2H
    PUSH AF
    Save the command mode flag in AF to the stack.
    2FF3H-2FF5H
    Jump to the Level II BASIC READY routine.
    2FF6H
    POP BC
    Clean up the stack.

    2FF7H – EDIT Command – QUIT Logic.

    2FF7H
    POP DE
    Get the BASIC line number from the stack and put it in DE.
    2FF8H-2FFAH
    Jump to the Level II BASIC READY routine.
    2FFBH-2FFFH
    NOP
    THE END OF THE LEVEL II BASIC ROMS
    2FFBH-2FFFH
    NOP
    Nothing here.
    *2FFBH-2FFCH
    SBC A,0C3H
    In ROM v1.2 this is just garbage.
    *2FFDH-2FFFH
    In ROM v1.2 this is just garbage.