2003 – UE ERROR entry point.
2003-2004LD E,26HLoad register E with the ERROR code for a ?UE ERROR.
2008-2038 – LEVEL II BASIC AUTO ROUTINE
2008-200ALD DE,000AHLoad DE with a default starting line number of ten.
200BPUSH DESave the default stack line number in DE to the stack.
200C-200DJump down to 2025H if this is the end of the AUTO statement (meaning that no parameters were provided).
200E-2010If 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.
2011EX DE,HLSince 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.
2012EX (SP),HLNext, exchange the default line number (to the stack from the above push of DE) with the line number that the user provided (in HL).
2013-2014Jump down to 2026H if this is the end of the AUTO statement (meaning that only 1 parameter was provided).
2015EX DE,HLLoad HL with the value of the current BASIC program pointer in DE.
2016-2017RST 08H
2CIf 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).
2018EX DE,HLIf 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.
2019-201BLD HL,(40E4H)Load HL with the last AUTO increment value.
Note: 40E4H-40E5H holds AUTO increment.
201CEX DE,HLExchange the value of the current BASIC program pointer in DE with the last AUTO increment value in HL.
201D-201EJump to 2025H if this is the end of the BASIC statement (meaning, we got AUTO nn, but no further parameter).
201F-2021If 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
2022-2024If 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.
2025EX DE,HLExchange the AUTO increment number in DE with the value of the current BASIC program pointer in HL.
LD A,HLoad 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)
2027OR LCombine 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)
2028-202AThat all tested the value of HL to see if it was zero. If it was, jupm to 1E4AH to show a ?FC ERROR message.
202B-202DLD (40E4H),HLSave the value of the AUTO increment number in HL.
Note: 40E4H-40E5H holds AUTO increment.
202E-2030LD (40E1H),ASet the AUTO flag to non-zero. We know A is non-zero because we would have jumped 2 instruction ago if it was.
2031POP HLGet the starting line number from the stack and put it in HL.
2032-2034LD (40E2H),HLSave the line number in HL as the next AUTO line number.
Note: 40E2H-40E3H holds Current BASIC line number.
2035POP BCClean up the stack.
2039-2066 – LEVEL II BASIC IF ROUTINE
2039-203BGOSUB to 2337H to evaluate the BASIC expression pointed to by HL and return with the result in REG 1.
203CLD A,(HL)Load register A with the character at the location of the current BASIC program pointer in HL.
203D-203ECP 2CHCheck 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.
203F-2041If 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.
2042-2043CP CAHCheck 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.
2044-2046If 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.
2047DEC HLDecrement the value of the current BASIC program pointer in HL so that we are still positioned at the THEN token.
2048PUSH HLSave the value of the current BASIC program pointer to the stack.
204CPOP HLRestore the address of the current position in the current statement (from the stack) into HL.
204FRST 10HWe 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.
2050-2052Jump to the GOTO routine if the character at the location of the current BASIC program pointer in HL is numeric.
2053-2055Jump to the execution driver at 1D5FH to evaluate the rest of the statement string.
LD D,01HLoad register D with the scan counter (as we will need to count the number of times to scan to the end of line).
205BOR ACheck to see if this is the end of the BASIC instruction.
205CRET ZReturn if this is the end of the BASIC statement.
RST 10HWe 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.
205E-205FCP 95HCheck 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.
2062DEC DDecrement the value of the scan counter.
2067-206E – LEVEL II BASIC LPRINT ROUTINE
2067-2068LD A,01HLoad register A with the output device code for the printer.
2069-206BLD (409CH),ASave 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.
*206C-206ESkip a few instructions and pick up at 207CH.
Differences between M1 and M3 ROMs: All of the changes from 206DH – 20F7H first appeared in the “new” ROMs of the Model I. The changes were made to allow the use of multiple @’s in a PRINT statement.
206F-2177 – LEVEL II BASIC PRINT ROUTINE
*2072-2073CP ‘#’Check the character at the location of the current BASIC program pointer in register A to see if it’s an #.
*2079-207BLD (409CH),ALoad the memory location at 409CH with A, to route output to cassette.
*207DRST 10HWe need to check for the end of the statement as 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.
*2084OR 20HWith this MASK, we are getting readh to check to see if it was a @.
*2086CP 60HCompare against a “‘” (which is actually a @ on the TRS-80).
*208AGOSUB 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).
*208DCheck 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.
*2092PUSH HLPush the current code string address (held in HL) to the stack.
*2093LD HL,3C00HLoad HL with the start of the display area.
*2096ADD HL,DEAdd DE to HL so that HL now will be the start of the diplay area PLUS the PRINT@ offset position.
*2097LD (4020H),HLStore 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.
*209ALD A,EE is the current position within the line.
*209BAND 3FHMake it not exceed 63 and then save it ….
*209DLD (40A6H),A… into the current cursor offset (which is held in 40A6H).
*20A0POP HLRestore the code string address to HL
*20A2RST 08H
2CAt 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).
*20A5LD A,(HL)
2CPut the next token (held in the memory location pointed to by HL) into A.
*20A6-20A7CP 0BFHCompare 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.)
*20AB-20ACCP BCHTest 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.
*20B0PUSH HLContinuing on a PRINT#, save the current position in the input stream into the stack.
*20B1-20B2CP 2CHTest 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.
*20B5-20B6CP 3BHSince 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.
*20BCEX (SP),HLSwap (SP) for HL to restore the position.
20BDRST 20HCheck 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.
20C0GOSUB to the routine at 0FBDH to convert the binary to ASCII and move to the print buffer.
20C3GOSUB to the routine at 2865H to build a literal string pool entry for the ASCII number.
20C9LD HL,(4121H)Put the address of the current print string into HL.
20CCLD 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.
20CFOR ATest the output device type flag.
20D5-20D7LD 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.
20D8ADD 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.
20D9-20DACP 84HCheck 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.)
20DD-20DFLD A,(409DH)Load register A with the video line size.
Note: 409DH holds the size of line on the video display.
20E0LD B,ALoad register B with the video line size in register A.
20E1-20E3LD A,(40A6H)Load register A with the current video line position.
Note: 40A6H holds the current cursor line position.
20E4ADD 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.
20E5CP BCheck 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.)
If NC is set, the new line will overflow the buffer so send a carriage return to the current output device.
20EC-20EDLD A,20HLoad register A with a space.
20F1OR ACheck to see if register A is equal to zero.
20F5POP HLRestore the current code string to HL
20F6-20F8Loop 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.
20F9-20FBLD A,(40A6H)Load register A with the number of characters printed on the current line.
Note: 40A6H holds the current cursor line position.
20FCOR ACheck to see if any characters have been printed on the current line.
20FDRET ZReturn out of this routine if we are at the start of a line.
20FE – 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.
20FE-20FFLD A,0DHOtherwise, we need to skip to the next line so load register A with a carriage return.
2103-2105Call 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.
2106XOR AZero register A and the carry flags.
2107RETReturn back to the calling routine.
2108 – This is the jump point for a continuation of the PRINT# code.
2108-210ACall the DOS link at 4103H.
In NEWDOS 2.1, this is called at the start of PRINT on cassette and during PRINT TAB.
210B-210DLD 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.
210EOR ATest 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.
210F-2111Jump down a few instructions to 2119H if the printer or the video display is the current output device.
2112-2113LD A,2CHSo now that we know the current device is cassette, we will load register A with a ,.
2114-2116Send 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.
2119-211AWe 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.
211B-211DLD 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.
211E-211FCP 70HCheck 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.)
2123-2125LD 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.
2126LD B,ALoad register B with the video line length in register A.
2127-2129LD A,(40A6H)Load register A with the current video line position.
Note: 40A6H holds the current cursor line position.
212ACP BTest 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.)
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.
If this is the end of the line on the current output device jump forward to 2164H.
2130-2131SUB 10HCheck to see if there are at least 16 spaces left on the current line for the current output device.
2134CPLFigure the number of spaces to be sent to the current output device.
2137 – 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”. 2169 – 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.
2137-2139GOSUB 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.
213A-213BAND 3FHThe results are in A so mask the tab number in register A so that it doesn’t exceed 63.
Difference between M1 and M3 ROMs: This also first appeared in the “new” ROMs of the Model I, as part of an AND 7FH instruction located at 213AH. In the original version the instruction was AND 3FH. The operand of the instruction sets the maximum argument for the TAB function, thus the early TRS-80’s could only handle a maximum TAB (63) while the latest Models can go as high as TAB (127).
213CLD B,ALoad register B with the value of the tab number from register A.
213D-213ERST 08H
29At 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).
213FDEC HLDecrement 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.
2144-2146LD 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.
2147OR ATest the value of the current output device flag in register A.
2148-214ADisplay a ?FC ERROR message if the current output device is the cassette recorder.
214B-214DJump forward a few instructions to 2153H if the current output device is the video display.
214E-2150LD 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.
2154-2155LD A,(40A6H)Load register A with the current video line position.
Note: 40A6H holds the current cursor line position.
2156CPLWhen we land here, A holds either the current carriage position (printer) or the current line position (video). Regardless, complement (make negative) that value.
2157ADD A,EAdd the tab number in register B to the adjusted line position in register A so that A=-current position + tab.
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.
215AINC ABump the number of spaces to be printed in register A.
215BLD B,ALoad register B with the number of spaces to be printed in register A.
215C-215DLD A,20HLoad register A with a space.
2161DEC BDecrement the value of the space counter in register B.
2165RST 10HWe 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.
*2166-2168Jump back to 2081H to process the rest of the PRINT TAB statement.
Difference between M1 and M3 ROMs: This corrects a jump back into the revised PRINT command routine.
2169 – 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.
2169-216BLD 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.
216COR ATest the value of the current output device flag in register A. If the M flag is set, A was negative.
216D-216FIf the current output device flag is the cassette recorder, GOSUB to 01F8H to turn it off.
2170XOR AClear Register A (which will set A to 0) and clear the status flags.
2171-2173LD (409CH),ASave 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.
2174-2176Call the DOS link at 41BEH.
In NEWDOS 2.1, this initializes the system output device.
2177RETReturn.
2178-217E – MESSAGE STORAGE LOCATION FOR REDO MESSAGE
2178-217E“?REDO”The ?REDO message is stored here.
217F-2285 – LEVEL II BASIC INPUT AND READ ROUTINES
217F-2181LD A,(40DEH)Load register A with the read flag.
Note: 40DEH holds READ flag.
2182OR ACheck to see if the read flag is set.
2186-2188LD 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.
2189OR ACheck to see if the cassette recorder is the current input device.
218A-218BLD E,2AHLoad register E with the ?FD ERROR code.
218FPOP BCClean up the stack.
2190-2192LD HL,2178HLoad HL with the starting address of the ?REDO message.
2193-2195We 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).
2196-2198LD HL,(40E6H)Get the value of the current BASIC program pointer in HL.
Note: 40E6H-40E7H holds Temporary storage location.
2199RETReturn out of this routine.
219A – INPUT logic
219DLD A,(HL)Load register A with the character at the location of the current BASIC program pointer in HL.
219E-21A0Call the DOS link at 41D6H.
In NEWDOS 2.1 this is called at the beginning of INPUT processing.
21A1-21A2SUB 23HCheck to see if the character at the location of the current BASIC program pointer in register A is a #.
21A3-21A5LD (40A9H),ASet the current input device flag for the cassette recorder.
Note: 40A9H holds cassette input flag.
21A6LD A,(HL)Load register A with the character at the location of the current BASIC program pointer in HL.
21A9-21ABIf 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.
21ACPUSH HLSave the current BASIC program pointer in HL to the stack.
21AD-21AELD B,FAHLoad register B with the size of the input buffer.
21AF-21B1LD HL,(40A7H)Load HL with the starting address of the input buffer.
Note: 40A7H-40A8H holds the input Buffer pointer.
21B2-21B4Calls 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).
21B5LD (HL),ASave the byte read from the cassette recorder in register A at the location of the input buffer pointer in HL.
21B6INC HLBump the value of the input buffer pointer in HL.
21B7-21B8CP 0DHCheck 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.
21B9-21BAJump out of this routine if the character read from the cassette recorder in register A is a carriage return.
21BE-21BFLD (HL),00HSave a zero at the location of the input buffer pointer in HL.
21C0-21C2GOSUB to 01F8H to put a 00H at the end of the tape and turn the cassette recorder off.
21C3-21C5LD HL,(40A7H)Load HL with the starting address of the input buffer.
Note: 40A7H-40A8H holds the input Buffer pointer.
21C6DEC HLDecrement the value of the input buffer pointer in HL.
21CCPUSH BCSave the value of the return address in BC to the stack.
21CD-21CECP 22HCheck 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.
21CFReturn to 21DBH if the character at the location of the current BASIC program pointer in register A isn’t a quote.
21D3-21D4RST 08H
3BSince 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).
21D5PUSH HLSave the value of the current BASIC program pointer in HL to the stack.
21D9POP HLRestore the code string address (from the stack) into HL.
21DFPOP BCGet the value of the current BASIC program pointer from the stack and put it in BC.
21E3INC HLBump the value of the input buffer pointer in HL.
21E4LD A,(HL)Load register A with the character at the location of the input buffer pointer in HL.
21E5OR ATest the value of the character at the location of the input buffer pointer in register A.
21E6DEC HLDecrement the value of the input buffer pointer in HL.
21E7PUSH BCSave the value of the current BASIC program pointer in BC to the stack.
21E8-21EAJump if the character at the location of the input buffer pointer in register A is an end of the input character.
21EB-21ECLD (HL),2CHSave a comma at the location of the current input buffer pointer in HL.
21EF – READ logic
21EFPUSH HLSave the current BASIC program pointer in HL.
21F0-21F2LD HL,(40FFH)Load HL with the location of the last DATA statement read.
Note: 40FFH-4100H holds READ pointer.
21F3-21F4OR AFHSet register A to a non-zero value if entered from the READ routine and zero if entered from the INPUT routine.
21F5-21F7LD (40DEH),ASave the value of the input type flag in register A.
Note: 40DEH holds READ flag.
21F8EX (SP),HLExchange the start of the input pointer in HL with the current BASIC program pointer to the stack.
21FB-21FCRST 08H
2CSince 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).
21FD-21FFCall 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).
2200EX (SP),HLExchange the value of the current BASIC program pointer in HL with the start of the input buffer pointer to the stack.
2201PUSH DESave the variable’s address in DE to the stack.
2202LD A,(HL)Load register A with the character at the location of the input buffer pointer in HL.
2203-2204CP 2CHCheck 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.)
2205-2206Jump to 222DH if the character at the location of the input buffer pointer in register A is a ,.
2207-2209LD A,(40DEH)Load register A with the input type flag.
Note: 40DEH holds READ flag.
220AOR ACheck for READ or INPUT.
220E-2210LD A,(40A9H)Load register A with the value of the cassette input flag.
Note: 40A9H holds Cassette input flag.
2211OR ACheck to see if the input is from the cassette recorder.
2212-2213LD E,06HLoad register E with an ?OD ERROR code.
2214-2216Go to the Level II BASIC error routine and display an ?OD ERROR message if the input is from the cassette recorder.
2217-2218LD A,3FHLoad register A with a “?”.
2219-221BGOSUB 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).
221FPOP DEGet the address of the variable to be set from the stack and put it in DE.
2220POP BCGet the value of the current BASIC program pointer from the stack and put it in BC.
2224INC HLBump the value of the input buffer pointer in HL.
2225LD A,(HL)Load register A with the character at the location of the input buffer pointer in HL.
2226OR ACheck to see if the character at the location of the input buffer pointer in register A is an end of the input character.
2227DEC HLDecrement the value of the input buffer pointer in HL.
2228PUSH BCSave the value of the current BASIC program pointer in BC to the stack.
2229-222BJump if the character at the location of the input buffer pointer in register A is an end of the input character.
222CPUSH DESave the variable’s address in DE to the stack.
222D-222FCall the DOS link at 41DCH.
In NEWDOS 2.1, this is called during READ processing when a variable has been read.
2230RST 20HWe 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.
2231PUSH AFSave the number type of the variable to the stack.
2234RST 10HWe 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.
2235LD D,ALoad register D with the character at the location of the input buffer pointer in register A.
2236LD B,ALoad register B with the character at the location of the input buffer pointer in register A.
2237-2238CP 22HCheck 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.)
2230-223AJump to 2240H if the character at the location of the input buffer pointer in register A is a quote.
223B-223CLD D,3AHLoad D with the character :.
223D-223ELD B,2CHLoad register B with the character , (the scan character).
223FDEC HLDecrement the value of the input buffer pointer in HL.
2243POP AFGet the number type for the variable from the stack and put it in register A.
2244EX DE,HLLoad DE with the value of the input buffer pointer in HL.
2245-2247LD HL,225AHLoad HL with the value of the return address.
2248EX (SP),HLExchange the value of the return address in HL with the value of the current BASIC program pointer to the stack.
2249PUSH DESave the value of the input buffer pointer in DE to the stack.
RST 10HWe 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.
224EPOP AFLoad register A with the number type for the variable to be set.
224FPUSH AFSave the value in AF to the stack.
2253PUSH BCSave the return address in BC to the stack.
2254-2256If 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).
2257-2259If 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).
225ADEC HLDecrement the value of the input buffer pointer in HL.
225BRST 10HWe 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.
225C-225DJump to 2263H if the character at the location of the input buffer pointer in HL is an end of the input character.
225E-225FCP 2CHCheck 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.)
2260-2262Jump to 217FH if the character at the location of the input buffer pointer in register A isn’t a comma.
2263EX (SP),HLExchange the value of the input buffer pointer in HL with the value of the current BASIC program pointer to the stack.
2264DEC HLDecrement the value of the current BASIC program pointer in HL.
2265RST 10HWe 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.
2266-2268Go 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.
2269POP DEClean up the stack.
226A-226E – For ROM v1.2 – Replaced with NOPS
226F-2271LD A,(40DEH)Load register A with the value of the input type flag.
Note: 40DEH holds READ flag.
2272OR ACheck to see if the input type is READ or INPUT.
2273EX DE,HLLoad DE with the value of the current BASIC program pointer in HL.
2277PUSH DESave the current BASIC program pointer in DE to the stack.
2278-227ACall the DOS link at 41DFH.
In NEWDOS 2.1 this is called at the end of READ processing.
227BOR (HL)Check to see if this is the end of the input.
227C-227ELD HL,2286HLoad HL with the starting address of the ?EXTRA IGNORED message.
227F-2281We 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).
2282POP HLGet the value of the current BASIC program pointer from the stack and put it in HL.
2286-2295 – MESSAGE STORAGE LOCATION
2286-2295“?Extra ignored”The EXTRA IGNORED message is stored here.
2296-22B5 – FIND THE NEXT DATA STATEMENT ROUTINE
2299OR ACheck to see if this is the end of the BASIC line.
229CINC HLBump the value of the current BASIC program pointer in HL.
229DLD A,(HL)Load register A with the LSB of the line address at the location of the current BASIC program pointer in HL.
229EINC HLBump the value of the current BASIC program pointer in HL.
229FOR (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.
22A0-22A1LD E,06HLoad register E with an ?OD ERROR code.
22A2-22A4Go to the Level II BASIC error routine and display an OD ERROR message if this is the end of the BASIC program.
22A5INC HLBump the value of the current BASIC program pointer in HL.
22A6LD E,(HL)Load register E with the LSB of the BASIC line number at the location of the current BASIC program pointer in HL.
22A7INC HLBump the value of the current BASIC program pointer in HL.
22A8LD D,(HL)Load register D with the MSB of the BASIC line number at the location of the current BASIC program pointer in HL.
22A9EX DE,HLExchange the value of the current BASIC program pointer in HL with the value of the BASIC line number in DE.
22AA-22ACLD (40DAH),HLSave the BASIC line number in HL.
Note: 40DAH-40DBH holds DATA line number.
22ADEX DE,HLExchange the value of the current BASIC program pointer in DE with the value of the BASIC line number in HL.
22AERST 10HWe 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.
22AF-22B0CP 88HCheck 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.)
22B1-22B2Jump 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.
22B3-22B5Now we know that the current BASIC program pointer is pointing to a DATA token, so jump to 222DH.
22B6-2336 – LEVEL II BASIC NEXT ROUTINE
22B6-22B8LD DE,0000HLoad DE with the default variable address.
22B9-22BBTo 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).
22BC-22BELD (40DFH),HLSave the value of the current BASIC program pointer (contained in 40DFH) in HL.
Note: 40DFH-40E0H holds Used by DOS.
22C5LD SP,HLLoad the stack pointer with the value of the memory pointer in HL.
22C6-22C8LD (40E8H),HLSave the value in HL.
Note: 40E8H-40E9H holds Stack pointer pointer.
22C9PUSH DESave the variable’s address in DE to the stack.
22CALD A,(HL)Load register A with the value of the sign for the STEP value.
22CBINC HLBump the value of the memory pointer in HL.
22CCPUSH AFSave the value of the sign for the STEP value in register A to the stack.
22CDPUSH DESave the variable’s address in DE to the stack.
22CELD A,(HL)Load register A with the number type flag for the STEP value.
22CFINC HLBump the value of the memory pointer in HL.
22D0OR ACheck the value of the number type flag for the STEP flag in register A.
22D7EX (SP),HLExchange the value of the variable’s address to the stack with the value of the memory pointer in HL.
22D8PUSH HLSave the value of the variable’s address in HL to the stack.
22D9-22DBGo 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.
22DCPOP HLGet the value of the variable’s address from the stack and put it in HL.
22E0POP HLGet the value of the memory pointer from the stack and put it in HL.
22E1-22E3Call 09C2H (which loads a SINGLE PRECISION value pointed to by HL into register pairs BC and DE).
22E4PUSH HLSave the value of the memory pointer in HL to the stack.
22E5-22E7Call 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.
22EAINC HLWe 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.
22EBINC HLBump the value of the memory pointer in HL.
22ECINC HLBump the value of the memory pointer in HL.
22EDINC HLBump the value of the memory pointer in HL.
22EELD C,(HL)Load register C with the LSB of the STEP value (held at the location of the memory pointer in HL).
22EFINC HLBump the value of the memory pointer in HL to be the MSB of the STEP value.
22F0LD B,(HL)Load register B with the MSB of the STEP value at the location of the memory pointer in HL.
22F1INC HLBump the value of the memory pointer in HL so that it is the stack address of the TO limit.
22F2EX (SP),HLExchange 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.
22F3LD E,(HL)Load register E with the LSB of the index.
22F4INC HLBump the value of the memory pointer in HL to point to the MSB of the index.
22F5LD D,(HL)Load register D with the MSB of the index.
22F6PUSH HLSave the value of the memory pointer in HL to the stack.
22F7LD L,CLoad register L with the LSB of the STEP value in register C.
22F8LD H,BLoad register H with the MSB of the STEP value in register B.
22F9-22FBWith 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).
22FC-22FELD A,(40AFH)Load register A with the current value of the data type flag.
Note: 40AFH holds Current number type flag.
22FFCP 04HCheck 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.)
2304EX DE,HLLoad DE with the index as an integer (from HL).
2305POP HLRestore the address of the index in the variable area to HL.
2306LD (HL),DSave the MSB of the result in register D at the location of the memory pointer in HL.
2307DEC HLDecrement the value of the memory pointer in reg� ister pair HL.
2308LD (HL),ESave the LSB of the result in register E at the location of the memory pointer in HL.
2309POP HLRestore the address of the TO value in the FOR statement to HL.
230APUSH DESave the index in DE to the stack.
230BLD E,(HL)Load register E with the LSB of the TO value at the location of the memory pointer in HL.
230CINC HLBump the value of the memory pointer in HL to point to the MSB of the TO value.
230DLD D,(HL)Load register D with the MSB of the TO value at the location of the memory pointer in HL.
230EINC HLBump the value of the memory pointer in HL so now it points to the line number.
230FEX (SP),HLSwap 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).
2310-2312We 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.
2314POP BCGet the value of the sign from the stack and put it in BC.
2315SUB BWe 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.
2316-2318Call 09C2H (which loads a SINGLE PRECISION value pointed to by HL into register pairs BC and DE).
2319-231AJump to 2324H if the index does not equal the TO limit (meaning the FOR … NEXT loop has not been completed).
231BEX DE,HLLoad HL with the BASIC line number of the FOR statement in DE.
231C-231ELD (40A2H),HLSave the BASIC line number in HL as the current BASIC line number.
- Note: 40A2H-40A3H holds the current BASIC line number.
231FLD L,CLoad register L with the LSB of the current BASIC program pointer in register C.
2320LD H,BLoad register H with the MSB of the current BASIC program pointer in register B.
2324LD SP,HLRestore the stack pointer – Start of expression evaluation
2325-2327LD (40E8H),HLLoad HL with the value of the current BASIC program pointer.
Note: 40E8H-40E9H holds Stack pointer pointer.
2328-232ALD HL,(40DFH)Save the value of the current BASIC program pointer in HL.
Note: 40DFH-40E0H holds Used by DOS.
232BLD A,(HL)Load register A with the next token (i.e., the character at the location of the current BASIC program pointer in HL).
232C-232DCP 2CHCheck 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.)
232E-2330Jump back to 1D1EH if the character at the location of the current BASIC program pointer in register A isn’t a ,.
2331RST 10HWe 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.
2335RST 08H
28Since 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).
2337-27C8 – 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.
2337DEC HLDecrement the value of the current BASIC program pointer in HL.
2338-2339LD D,00HLoad register D with zero.
233APUSH DESave the value in DE to the stack.
233B-233CLD C,01HLoad register C with the number of bytes of memory required.
2340-2342Go get the value of the next part of the expression at the location of the current BASIC program pointer in HL.
2343-2345LD (40F3H),HLSave the value of the current BASIC program pointer (i.e., the next token) in HL.
Note: 40F3H-40F4H holds temporary storage location.
2346-2348LD HL,(40F3H)Load HL with the value of the current BASIC program pointer.
Note: 40F3H-40F4H holds temporary storage location.
2349POP BCGet the last precedence value from the stack and put it in BC.
234ALD A,(HL)Load register A with the character at the location of the current BASIC program pointer in HL.
234B-234CLD D,00HLoad register D with zero.
234D-234ESUB D4HCheck 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).
Jump to 2364H if the character at the location of the current BASIC program pointer in register A is +, –, *, /, ?, AND or OR.
2351-2352CP 03HCheck 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.)
Jump if the character at the location of the current BASIC program pointer in register A isn’t a >, =, or <.
2355-2356CP 01HSet the Carry flag if >. Then test for <= or >=.
2357RLAAdjust the value in register A to give > as 1, = as 2, or < as 4.
2358XOR DCombine 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 >>.
2359CP DCheck for an illegal combination of operators.
235ALD D,ALoad register D with the value in register A.
235E-2360LD (40D8H),HLSave the address of the >, =, or < token (held in HL) to 40D8H.
Note: 40D8H-40D9H holds Temporary storage location.
2361RST 10HWe 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.
2364LD A,DLoad register A with the value of the operator in register D.
2365OR ATest the value of the operator in register A.
2369LD A,(HL)Load register A with the character at the location of the current BASIC program pointer in HL.
236A-236CLD (40D8H),HLSave the address of the current BASIC program pointer in HL (which is an arithmetic operator) to 40D8H.
Note: 40D8H-40D9H holds Temporary storage location.
236D-236ESUB 0CDHCheck to see if the operator at the location of the current BASIC program pointer in register A is an arithmetic token.
236FRET CReturn if the character at the location of the current BASIC program pointer in register A isn’t an arithmetic token.
CP 07HCheck to see if the character at the location of the current BASIC program pointer in register A is a + to OR token.
2372RET NCReturn if the character at the location of the current BASIC program pointer in register A isn’t a + to OR token.
LD E,ALoad 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
2374-2376LD A,(40AFH)Load register A with the current value of the number type flag.
Note: 40AFH holds Current number type flag.
2377 – PRINT @ logic.
2377-2378SUB 03HAdjust 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.
2379OR ECombine the operator value in register E with the adjusted number type flag in register A.
237A-237CJump 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.
237D-237FLD HL,189AHLoad HL with the starting address of the table of precedence operator values.
2380ADD HL,DEAdd the value of the operator in DE to the table of precedence values pointer in HL.
2381LD A,BLoad register A with the precedence value for the last operator in register B.
2382LD D,(HL)Load register D with the precedence value for the current operator.
2383CP DCompare the precedence value for the current operator in register D with the precedence value for the last operator in register A.
2384RET NCReturn 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.
2389PUSH BCSave the return address in BC to the stack.
238ALD A,DLoad register A with the precedence value for the current operator in register D.
238B-238CCP 7FHCheck to see if the precedence value for the current operator in register A indicates an exponential operator.
238D-238FJump down to 23D4H if the precedence value for the current operator in register A indicates an exponential operator.
2390-2391CP 51HCheck to see if the precedence value for the current operator in register A indicates a logical operator.
Jump if the precedence value for the current operator in register A indicates a logical operator.
2395-2397LD HL,4121HLoad HL with the address of REG 1.
2398OR AClear the flags.
2399-239BLD A,(40AFH)Load register A with the current value of the number type flag.
Note: 40AFH holds Current number type flag.
239CDEC AAdjust the current number type flag in register A.
239DDEC AAdjust the current number type flag in register A.
239EDEC AAdjust the current number type flag in register A. Now A will be -1=Integer, 0=String, 1=Single Precision, 5=Double Precision
23A2LD C,(HL)Get the value at the location of the memory pointer in HL and put it in register C.
23A3INC HLBump the value of the memory pointer in HL.
23A4LD B,(HL)Load register B with the value at the location of the memory pointer in HL.
23A5PUSH BCSave the value in BC to the stack.
23A9INC HLIt’s not an integer, so lets get the rest of the value by bumping the value of the memory pointer in HL.
23AALD C,(HL)Load register C with the value at the location of the memory pointer in HL.
23ABINC HLBump the value of the memory pointer in HL.
23ACLD B,(HL)Load register B with the value at the location of the memory pointer in HL.
23ADPUSH BCSave the value in BC (the rest of the digit) to the stack.
23AEPUSH AFSave the value in AF (the type – 3) to the stack.
23AFOR AReset the status flags so that we can test if the current number type is double precision.
23B3POP AFClear the stack.
23B4INC HLBump the value of the memory pointer in HL.
23B7-23B9LD HL,411DHReset HL to start of REG 1.
Note: 411DH-4124H holds REG l.
23BALD C,(HL)Load register C with the rest of the double precision value (held at the location of the memory pointer in HL).
23BBINC HLBump the value of the memory pointer in HL.
23BCLD B,(HL)Load register B with the next digit LSB (at the location of the memory pointer in HL).
23BDINC HLBump the value of the memory pointer in HL to the next digit.
23BEPUSH BCSave the LSB/NMSB of the double precision value (held in BC) to the stack.
23BFLD C,(HL)Load register C with the value at the location of the memory pointer in HL.
23C0INC HLBump the value of the memory pointer in HL.
23C1LD B,(HL)Load register B with the value at the location of the memory pointer in HL.
23C2PUSH BCSave the value in BC to the stack.
23C3LD B,0F1H
06 F1Z-80 Trick to nullify the next opcode if passing through.
23C4POP AFClear the type -3 and the status push.
23C7LD C,ELoad register C with the value of the current operator token in register E (0-7).
23C8LD B,ALoad register B with the number type flag in register A.
23C9PUSH BCSave the value in BC to the stack.
23CDPUSH BCSave the return address in BC to the stack.
23CE-23D0LD HL,(40D8H)Load HL with the value of the current BASIC program pointer.
Note: 40D8H-40D9H holds Temporary storage location.
23D4-23D6Call the CONVERT TO SINGLE PRECISION routine at 0AB1H (which converts the contents of REG 1 from integer or double precision into single precision).
23D7-23D9Call 09A4 which moves the SINGLE PRECISION value in REG 1 to the stack (stored in LSB/MSB/Exponent order).
23DA-23DCLD BC,13F2HLoad BC with the address of the exponential X^Y routine at 13F2H.
23DD-23DELD D,7FHLoad register D with the precedence value for an exponential operator.
23E1PUSH DESave the precedence value and the operator token in DE to the stack.
23E2-23E4Call 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).
23E5POP DEGet the precedence value and the operator token from the stack and put it in DE.
23E6PUSH HLSave the integer value in HL to the stack.
23ECLD A,BLoad register A with the precedence value for the last operator in register B.
23ED-23EECP 64HCheck to see if the last operator was a logical operator.
23EFRET NCReturn out of this routine if the last operator was a logical operator.
PUSH BCSave the precedence value and the operator token for the last operator in BC to the stack.
23F1PUSH DESave the precedence value and the token for the current operator from DE (either a 6, 5, or 3) to the stack.
23F2-23F4LD DE,6404HLoad DE with the precedence value and the token for the new operator.
23F5-23F7LD HL,25B8HLoad HL with the address of the routine to compare logical quantities …
23F8PUSH HLand push it to the stack.
23F9RST 20HWe 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.
23FD-23FFLD HL,(4121H)Load HL with the string address held at the memory location pointed to by REG 1.
2400PUSH HLSave the string’s address in HL to the stack.
2406POP BCGet the precedence value and the token for the last operator from the stack and put it in BC.
2407LD A,CLoad register A with the operator token in register C.
2408-240ALD (40B0H),ASave the operator token in register A.
Note: 40B0H holds Temporary storage location.
240BLD A,BLoad register A with the precedence value in register B.
240C-240DCP 08HCheck the number type for the precedence value in register A.
240E-240FJump forward to 2438H if the number type in register A (the first operand) is double prec1sion.
2410-2412LD A,(40AFH)Load register A with the number type for the current result in REG 1.
Note: 40AFH holds Current number type flag.
2413-2414CP 08HCheck to see if the current result in REG 1 is double precision.
2418LD D,ALoad register D with the current data type flag in register A.
2419LD A,BLoad register A with the precedence value for the last operator in register B.
241A-241BCP 04HCheck to see if the number type for the precedence value in register A is single precision.
241C-241EJump forward to 2472H if the number type for the precedence value in register A is single precision.
241FLD A,DLoad register A with the number type flag for the value in REG 1.
2420-2421CP 03HCheck to see if the current value in REG 1 is a string.
2428-242ALD HL,18BFHLoad HL with the starting address of the arithmetic jump table.
242B-242CLD B,00HLoad register B with zero.
242DADD HL,BCAdd the operator’s token in BC to the value of the arithmetic jump table pointer in HL.
242EADD HL,BCAdd the operator’s token in BC to the value of the arithmetic jump table pointer in HL.
242FLD C,(HL)Load register C with the LSB of the jump address at the location of the arithmetic jump table pointer in HL.
2430INC HLBump the value of the arithmetic jump table pointer in HL.
2431LD B,(HL)Load register B with the MSB of the jump address at the location of the arithmetic jump table pointer in HL.
2432POP DEGet the value for the previous result from the stack and put it in DE.
2433-2435LD HL,(4121H)Get the value for the current result from REG 1 and put it in HL.
2436PUSH BCSave the arithmetic routine’s jump address in regis� ter pair BC to the stack.
2437RETReturn.
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).
243EPOP HLGet the value from the stack and put it in HL.
243F-244lLD (411FH),HLSave the value in HL near the end of REG 1.
2442POP HLGet the value from the stack and put it in HL.
2443-2445LD (411DH),HLSave the value in HL in REG 1.
Note: 411DH-4124H holds REG l.
2446POP BCGet the value from the stack and put it in BC.
2447POP DEGet the value from the stack and put it in DE.
2448-244ACall 09B4H (which moves the SINGLE PRECISION value in DC/DE into REG 1). This moves DE to (4121H) and BC to (4123H).
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).
244E-2450LD HL,18ABHLoad HL with the double precision arithmetic jump table’s starting address.
2451-2453LD A,(40B0H)Load register A with the operator token in register A.
Note: 40B0H holds Temporary storage location.
2454RLCAMultiply the value of the operator token in register A by two.
2455PUSH BCSave the value in BC to the stack so we can use it for 16 bit arithmetic.
2456LD C,ALoad register C with the adjusted value of the operator token in register A (i.e., 2 x token).
2457-2458LD B,00HLoad register B with zero.
2459Add 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.
245APOP BCRestore BC from the stack and put it in BC.
245BLD A,(HL)Load register A with the LSB of the jump address at the location of the arithmetic jump table pointer in HL.
245CINC HLBump the value of the arithmetic jump table pointer in HL.
245DLD H,(HL)Load register H with the MSB of the jump address at the location of the arithmetic jump table pointer in HL.
245ELD L,ALoad register L with the LSB of the jump address in register A.
245FJP (HL)Jump to the arithmetic routine whose address is in HL.
2460PUSH BCSave the precedence value and the operator token in BC to the stack.
2464POP AFLoad register A with the value of the current number type flag.
2465-2467LD (40AFH),ASave the value of the current number type flag in register A.
Note: 40AFH holds Current number type flag.
2468-2469CP 04HCheck to see if the current result in REG 1 is single precision.
246CPOP HLGet the integer value from the stack and put it in HL.
246D-246FLD (4121H),HLSave the integer value in HL in REG 1.
2472-2474Call the CONVERT TO SINGLE PRECISION routine at 0AB1H (which converts the contents of REG 1 from integer or double precision into single precision).
2475POP BCGet the value from the stack and put it in BC.
2476POP DEGet the value from the stack and put it in DE.
2477-2479LD HL,18B5HLoad HL with the starting address of the single precision arithmetic jump table.
247CPOP HLGet the integer value from the stack and put it in HL.
247D-247FCall 09A4 which moves the SINGLE PRECISION value in REG 1 to the stack (stored in LSB/MSB/Exponent order).
2486POP HLGet the LSB/NMSB from the stack and put it in HL.
2487-2489LD (4123H),HLSave the value in HL in REG 1
248APOP HLGet the MSB and exponent from the stack and put it in HL.
248B-248DLD (4121H),HLSave the value in HL in REG 1.
2490 – 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.
2491EX DE,HLWe need to convert DE to SP so first do this swap to set up the variables for the call which follows.
2492-2494Go convert the integer value in HL to single precision and return with the result in REG 1.
2495POP HLGet the integer value from the stack and put it in HL.
2496-2498Call 09A4 which moves the SINGLE PRECISION value in REG 1 to the stack (stored in LSB/MSB/Exponent order).
2499-249BGo convert the integer value in HL to single precision and return with the result in REG 1.
249FRST 10HWe 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.
24A0-24A1LD E,28HLoad register E with a ?MO ERROR code.
24A5-24A7If 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).
24A8-24AACheck to see if the character at the location of the current BASIC program pointer in HL is alphabetic.
Jump if the character at the location of the current BASIC program pointer in HL is alphabetic.
24AE-24AFCP 0CDHCheck 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.
24B0-24B1Jump if the character at the location of the current BASIC program pointer in register A is a + token.
24B2-24B3CP 2EHCheck 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.
24B4-24B6If 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).
24B7-24B8CP 0CEHCheck 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.
24B9-24BBJump to 2532H if the character at the location of the current BASIC program pointer in register A is a – token.
24BC-24BDCP 22HCheck 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.
24BE-24C0Jump to 2866H if the character at the location of the current BASIC program pointer in register A is a “.
24C1-24C2CP 0CBHCheck 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.
24C3-24C5Jump to 25C4H if the character at the location of the current BASIC program pointer in register A is a NOT token.
24C6-24C7CP 26HCheck 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.
24C8-24CAJump to 4194H (which is DOS) if the character at the location of the current BASIC program pointer in register A is a &.
24CB-24CCCP 0C3HCheck 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.
24CD-24CEJump to 24D9H if the character at the location of the current BASIC program pointer in register A isn’t an ERR token.
24CFRST 10HWe 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.
24D0-24D2LD A,(409AH)Load register A with the value of the current error number.
Note: 409AH holds the RESUME flag.
24D3PUSH HLSave the value of the current BASIC program pointer in HL to the stack.
24D4-24D6Go save the value of the current error number in register A (as an integer) as the current result in REG l.
24D7POP HLGet the value of the current BASIC program pointer from the stack and put it in HL.
24D8RETReturn.
CP C2HCheck to see if the character at the location of the current BASIC program pointer in register A is a ERL token.
24DB-24DCJump to 24E7H if the character at the location of the current BASIC program pointer in register A isn’t an ERL token.
24DDRST 10HWe 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.
24DEPUSH HLSave the value of the current BASIC program pointer in HL to the stack.
24DF-24ElLD HL,(40EAH)Load HL with the current error line number.
Note: 40EAH-40EBH holds the line number with error.
24E5POP HLGet the value of the current BASIC program pointer from the stack and put it in HL.
24E6RETReturn.
24E7-24FEVARPTR logic.
24E7-24E8CP 0C0HCheck to see if the character at the location of the current BASIC program pointer in register A is a VARPTR token.
24E9-24EAJump back to 24FFH if the character at the location of the current BASIC program pointer in register A isn’t a VARPTR token.
24EBRST 10HWe 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.
24EC-24EDRST 08H
28Since 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).
24EE-24F0Jump to 24BCH to evaluate the variable name at the location of the current BASIC program pointer in HL.
24Fl-24F2RST 08H
29Since 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).
24F3PUSH HLSave the value of the current BASIC program pointer in HL to the stack.
24F4EX DE,HLLoad HL with the variable’s address in DE.
24F5LD A,HLoad register A with MSB of the variable’s address in register H.
24F6OR LCombine 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.
24F7-24F9Display a ?FC ERROR if the variable’s address in HL is equal to zero, meaning that the variable is undefined.
24FDPOP HLGet the value of the current BASIC program pointer from the stack and put it in HL.
24FERETReturn to the execution driver.
24FF – Other Function Routine.
24FF-2500CP 0C1HCheck to see if the character at the location of the current BASIC program pointer in register A is a USR token.
2501-2503Jump to 27FEH if the character at the location of the current BASIC program pointer in register A is a USR token.
2504-2505CP 0C5HCheck to see if the character at the location of the current BASIC program pointer in register A is a INSTR token
2506-2508Jump 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.
2509-250ACP 0C8HCheck to see if the character at the location of the current BASIC program pointer in register A is a MEM token.
250B-250DIf 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.
250E-250FCP 0C7HCheck to see if the character at the location of the current BASIC program pointer in register A is a TIME$ token.
2510-2512Jump 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.
2513-2514CP 0C6HCheck to see if the character at the location of the current BASIC program pointer in register A is a POINT token.
2515-2517Jump to 0132H if the character at the location of the current BASIC program pointer in register A is a POINT token.
2518-2519CP 0C9HCheck to see if the character at the location of the current BASIC program pointer in register A is an INKEY$ token.
251A-251CJump to 019DH if the character at the location of the current BASIC program pointer in register A is an INKEY$ token.
251D-251ECP 0C4HCheck to see if the character at the location of the current BASIC program pointer in register A is a STRING$ token.
241F-2421Jump to 2A2FH if the character at the location of the current BASIC program pointer in register A is a STRING$ token.
2522-2523CP 0BEHCheck to see if the character at the location of the current BASIC program pointer in register A is a FN token.
2524-2526Jump 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.
2527-2528SUB 0D7HCheck to see if the character at the location of the current BASIC program pointer in register A is a SGN to MID$ token.
Jump to 254EH if the character at the location of the current BASIC program pointer in register A is a SGN to MID$ token.
252C-252EGOSUB to 2335H to evaluate the expression at the location of the current BASIC program pointer in HL.
252F-2530RST 08H
29Since 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).
2531RETReturn out of this routine.
2532 – Binary Minus Routine.
2532LD D,7DHLoad register D with the precedence value.
2534-2536GOSUB to 233AH to evaluate the variable at the location of the current BASIC program pointer in HL.
2537-2539LD HL,(40F3H)Load HL with the value of the current BASIC program pointer.
Note: 40F3H-40F4H holds Temporary storage location.
253APUSH HLSave the value of the current BASIC program pointer in HL to the stack so we know where to continue.
253EPOP HLRestore 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$(.
253FRETReturn to the expression evaluation.
2540 – 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.
2540-2542Call 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).
2543PUSH HLSave the value of the current BASIC program pointer in HL to the stack.
2544EX DE,HLMove the address of the variable to HL.
2545-2547LD (4121H),HLSave the variable’s address in HL in REG 1.
2548RST 20HWe 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.
254CPOP HLGet the address of the next symbol in the input string from the stack and put it in HL.
254DRETReturn to the caller.
254E – This routine is for SNG( to MID$(.
254E-254FLD B,00HLoad register B with zero.
2550RLCASet A to be 2 * (token – D7H)
2551LD C,ASave the new token.
2552PUSH BCSave 0/2*(token-D7) on stack.
2553RST 10HGet 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.
2554LD A,CPrepare to look for SGN( to CHR$( token.
2555CP 41HTest for the adjusted token.
2559Otherwise, GOSUB to 2335H to evaluate the expression part of the calling sequence (which requires 2 or parameters).
255CRST 08H
2CUse RST 08H to test for a ,.
2561EX DE,HLMake sure the current variable is a string – DE is the current position in the program statement and HL is the address of the string.
2562LD HL,(4121H)Load HL with the string address held at the memory location pointed to by REG 1.
2565EX (SP),HLPut the string address to the stack.
2566PUSH HLSave the 00 / 2*(token-D7H) to the stack.
2567EX DE,HLMove the program statement position to HL.
256BEX DE,HLSet DE to be the current position in the statement and set HL to be n.
256CEX (SP),HLMove n to stack. HL will be 2 * (token – D7H).
256F-2571The 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.
2572EX (SP),HLExchange the value of the current BASIC program pointer in HL with the operator value to the stack. HL will be 0 + 2 * (token – D7H).
2573LD A,LLoad register A with the operator token in register L. A will be 2 * (token – D7H).
2574-2575CP 0CHCheck to see if the operator token in register A is SGN to SQR.
2578-2579CP 1BHCheck the value of the adjusted operator token in register A.
257APUSH HLSave the adjusted token (0 + 2*(token – D7H)) in HL to the stack.
257B-257DIf 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).
257EPOP HLRestore the adjusted token from the stack and put it in HL.
257F-2581LD DE,253EHLoad DE with a return address of 253EH for once the function is executed.
2582PUSH DESave the value of the return address in DE to the stack.
2583-2585LD BC,1608HLoad BC with the SGN to MID$ jump table address.
2586ADD HL,BCAdd the jump table pointer in BC with the value of the operator token in HL.
2587LD C,(HL)Load register C with the LSB of the jump address at the location of the jump table pointer in HL.
2588INC HLBump the value of the jump table pointer in HL.
2589LD H,(HL)Load register H with the MSB of the jump address at the location of the jump table pointer in HL.
258ALD L,CLoad register L with the LSB of the jump address in register C.
258BJP (HL)Jump to the calculated address (which is the SGN–MID$ function) in HL.
258C – 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.
258FLD A,(HL)Load register A with the length of the string at the location of the string’s VARPTR in HL.
2590INC HLBump the value of the string’s VARPTR in HL so that HL points to the LSB of the string address.
2591LD C,(HL)Load register C with the LSB of the string’s address at the location of the string’s VARPTR in HL.
2592INC HLBump the value of the string’s VARPTR in HL so that HL points to the MSB of the string address.
2594LD B,(HL)Load register B with the MSB of the string’s address at the location of the string’s VARPTR in HL.
2595POP DESave the value of the string’s address in BC to the stack.
2596PUSH BCSave the string’s length in register A to the stack.
2597-2599PUSH AFLoad HL with the second string’s VARPTR.
259APOP DEGet the length of the first string from the stack and put it in register D.
259BLD E,(HL)Load register E with the second string’s length at the location of the second string’s VARPTR in HL.
259CINC HLBump the value of the second string’s VARPTR in HL.
259DLD 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.
259EINC HLBump the value of the second string’s VARPTR in HL.
259FLD 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.
25A0POP HLGet the first string’s address from the stack and put it in HL.
25AlLD A,ELoad register A with the length of the second string in register E.
25A2OR DCombine the first string’s length in register D with the second string’s length in register A.
25A3RET ZReturn out of the routine if there aren’t any characters left in either string to be compared.
25A5-25A6SUB 01HCheck to see if the first string’s length in register A is equal to zero.
25A7RET CReturn if there are no more characters in the first string to be compared.
25A9CP ECheck to see if the second string’s length in register E is equal to zero.
25AAINC ABump the value in register A.
25ABRET NCReturn if there aren’t anymore characters in the second string to be compared.
25ADDEC EDecrement the value of the second string’s length in register E.
25AELD A,(BC)Load register A with the character at the location of the second string pointer in BC.
25AFCP (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.
25B0INC HLBump the value of the first string pointer in HL.
25BlINC BCBump the value of the second string pointer in BC.
25B4CCFSince they are not equal, reverse the CARRY flag so 960 will give a +1 or -1.
25B8INC ABump the value of the current precedence value in register A.
25B9ADC A,AAdjust 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.
25BAPOP BCGet the last operator value from the stack and put it in BC.
25BBAND BCombine the precedence value in register B with the precedence value in register A.
25BC-25BDADD A,FFHAdjust the value in register A. This will give a 0 if both are equal and a CARRY if they are unequal.
25BESBC A,ACheck to see if the precedence values in registers A and B match. This will set A=0 if equal, and A+1 if unequal.
25BF-25ClCall 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.
25C4 – NOT Routine.
25C4-25C5LD D,5AHLoad register D with the precedence value.
25C9-25CBCall 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).
25CCLD A,LLoad register A with the LSB of the integer value.
25CDCPLCompliment the LSB of the integer value in register A.
25CELD L,ALoad register L with the adjusted LSB of the integer value in register A.
25CFLD A,HLoad register A with the MSB of the integer value in register H.
25D0CPLCompliment the MSB of the integer value in register A.
25DlLD H,ALoad register H with the adjusted MSB of the integer value in register A.
25D2-25D4LD (4121H),HLSave the complimented integer value in HL as the current result in REG 1
25D5POP BCClean up the stack.
25D9 – 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
25D9-25DBH
“TSTYP”LD A,(40AFH)Load register A with the current value of the number type flag.
Note: 40AFH holds Current number type flag.
25DC-25DDCP 08HCheck to see if the current value in REG 1 is double precision (02=INT, 03=STR, 04=SNG, 08=DBL).
If that test shows that we have a DOUBLE PRECISION number, jump forward to 25E5H.
25E0-25ElSUB 03HIf the number is not double precision, subtract 3.
25E2OR ASet the status flags of the adjusted number type flag in register A.
24E3SCFSet the Carry flag.
25E4RETReturn.
SUB 03HWe are dealing with a double precision number so adjust the value of the current number type flag in register A.
25E7OR ATest the value of the current number type flag in register A, which will exit without the CARRY flag set.
25E8RETReturn.
25EA-25ECCall 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).
25EDPOP AFGet the operator value from the stack and put it in register A.
25EEPOP DEGet the return address from the stack and put it in DE.
25F2PUSH BCSave the value of the return address in BC to the stack.
25F3-25F4CP 46HCheck 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.
25F5-25F6Jump forward a few instructions to 25FDH (to the AND code) if the operator value in register A isn’t an OR token.
25F7 – OR logic.
25F7LD A,ELoad register A with the LSB of the first value in register E.
25F8OR LCombine the LSB of the first value in register A with the LSB of the second value in register L.
25F9LD L,ALoad register L with the ORed value in register A.
25FALD A,HLoad register A with the MSB of the second value in register H.
25FBOR DCombine the MSB of the first value in register D with the MSB of the second value in register A.
25FD – AND logic.
25FDLD A,ELoad register A with the LSB of the first value in register E.
25FEAND LCombine the LSB of the first value in register A with the LSB of the second value in register L.
25FFLD L,ALoad register L with the ANDed value in register A.
2600LD A,HLoad register A with the MSB of the second value in register H.
2601AND DCombine the MSB of the first value in register D with the MSB of the second value in register A.
2604RST 10HWe 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.
2605RET ZReturn if this is the end of the BASIC statement.
RST 08H
2CSince 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).
2608 – DIM logic.
2608-260ALD BC,2603HLoad BC with a return address of 2603H.
260D – 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.
260C-260DOR AFHReset the value in register A.
260E-2610LD (40AEH),ASave the value in register A as the current variable location/creation flag.
Note: 40AEH holds LOCATE/CREATE variable flag.
2611LD B,(HL)Load register B with the first character of the variable name.
2612-2614GOSUB to 1E3DH to make sure the first character of the variable name is a letter.
2618XOR AZero register A.
2619LD C,AZero register C.
261ARST 10HWe 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.
Jump to 2622H if the character at the location of the current BASIC program pointer in register A is numeric.
261D-261FGOSUB to 1E3DH to check to see if the character at the location of the current BASIC program pointer is a letter.
Jump to 262BH if the character at the location of the current BASIC program pointer in register A isn’t a letter.
2622LD C,ALoad register C with the second character of the variable name in register A.
+ 2623RST 10HWe 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.
2626-2628Go check to see if the character at the location of the current BASIC program pointer in HL is alphabetic.
Jump back to 2623H if the character at the location of the current BASIC program pointer in HL is alphabetic.
262B-262DLD DE,2652HLoad DE with a return address of 2652H.
262EPUSH DESave the value of the return address in DE to the stack.
262F-2630LD D,02HLoad register D with an integer number type flag.
2631-2632CP 25HCheck to see if the character at the location of the current BASIC program pointer in register A is a %.
2633RET ZReturn if the character at the location of the current BASIC program pointer in register A is a %.
INC DBump register D so that it will be equal to a string number type flag (02=INT, 03=STR, 04=SNG, 08=DBL).
2635-2636CP 24HCheck to see if the character at the location of the current BASIC program pointer in register A is a $.
2637RET ZReturn if the character at the location of current BASIC program pointer in register A is a $.
INC DBump register D so that it will be equal to a single precision number type flag (02=INT, 03=STR, 04=SNG, 08=DBL).
2639-263ACP 21HCheck to see if the character at the location of the current BASIC program pointer in register A is a !.
263BRET ZReturn if the character at the location of the current BASIC program pointer in register A is a !.
LD D,08HLoad 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.
263E-263FCP 23HCheck to see if the character at the location of the current BASIC program pointer in register A is a #.
2640RET ZReturn if the character at the location of the current BASIC program pointer in register A is a #.
2642-2643SUB 41HAdjust the value of the first character of the variable name in register A so that it is in the range of 0 to 25.
2644-2645AND 7FHMake sure the sign bit in register A isn’t set by ANDing it against 0111 1111.
2646LD E,ALoad register E with the adjusted first character of the variable name in register A.
2647-2648LD D,00HLoad register D with zero.
2649PUSH HLSave the value of the current BASIC program pointer in HL to the stack.
264A-264CLD HL,4101HLoad HL with the starting address of the variable declaration table.
NOTE: 4101H-411AH holds Variable Declaration Table.
264DADD HL,DEAdd the value of the first character of the variable name in DE to the starting address of the variable declaration table in HL.
264ELD D,(HL)Load register D with the number type value at the location of the variable declaration table pointer in HL.
264FPOP HLGet the value of the current BASIC program pointer from the stack and put it in HL.
2650DEC HLDecrement the value of the current BASIC program pointer in HL.
2651RETReturn with data type in D.
2653-2655LD (40AFH),ASave the number type flag for the current variable name in register A.
NOTE: 40AFH holds Current number type flag.
2656RST 10HWe 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.
2657-2659LD A,(40DCH)Load register A with the FOR flag.
Note: 40DCH holds FOR flag.
265AOR ATest the value of the FOR flag in register A.
265ELD 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.
265F-2660SUB 28HCheck to see if the character at the location of the current BASIC program pointer in register A is a (.
2661-2663Jump 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).
2664XOR AZero register A.
2665-2667LD (40DCH),ASet the array flag to ‘no subscript’.
Note: 40DCH holds FOR flag.
2668PUSH HLSave the value of the current BASIC program pointer in HL to the stack.
2669PUSH DESave the number type flag for the variable in DE to the stack.
266A-266CLD 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.
266DEX DE,HLLoad DE with the simple variables pointer in HL. We don’t care what happens to HL.
266E-2670LD HL,(40FBH)Load HL with the array variables pointer.
- Note: 40FBH-40FCH holds the starting address of the BASIC array variable storage area.
2671RST 18HNow 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.
2672POP HLGet the number type flag for the variable from stack and put it in HL.
2673-2674Jump 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).
2675LD A,(DE)Load register A with the number type flag for the variable at the location of the simple variables pointer in DE.
2676LD L,ALoad register L with the number type flag in register A.
2677CP HCompare the number type flag for the variable in register H to the number type flag in register A.
2678INC DEBump the value of the current simple variables pointer in DE to the 2nd character name for this entry.
2679-267AJump to 2686H (i..e, the next variable in the list) if the number type flags don’t match.
267BLD 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.
267CCP CCompare the character at the location of the simple variables pointer in register A with the first character of the variable name in register C.
267FINC DEBump the value of the current simple variables pointer in DE.
2680LD A,(DE)Load register A with the second character of the variable name at the location of the simple variables pointer in DE.
2681CP BCompare the character at the location of the simple variables pointer in register A with the first character of the variable name in register B.
2682-2684Jump 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.
2685-2686LD A,13HZ-80 Trick to skip the next INC DE if continuing through.
2686INC DEBump to the next entry in the simple variable list part 1.
2687INC DEBump the value of the simple variables pointer in DE part 2.
2688Save the number type flag for the variable in HL to the stack so that it can be re-loaded at 2672H.
2689-268ALD H,00HLoad register H with zero.
268BADD HL,DEAdd the value of the simple variables pointer in DE to the value of the number type flag in HL.
268ELD A,HLoad register A with the number type flag for the variable in register H.
268FPOP HLGet the value of the current BASIC program pointer from the stack and put it in HL.
2690EX (SP),HLExchange the value of the current BASIC program pointer in HL with the value to the stack.
2691PUSH AFSave the number type flag for the variable in register A to the stack.
2692PUSH DESave the start of the array variables pointer in DE to the stack.
2693-2695LD DE,24F1HLoad DE with a VARPTR locator return address of 24F1H.
2696RST 18HNow 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.
2699-269BLD DE,2543HLoad DE with a return address of the find address of variables routine at 2543H.
269CRST 18HWe 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.
269DPOP DEGet the value of the array variables pointer from the stack and put it in DE.
26A0POP AFClear the stack and put the value of the number type flag for the variable from the stack and put it in register A.
26AlEX (SP),HLExchange the value of the current BASIC program pointer to the stack with the value of the return address in HL.
26A2PUSH HLSave the value of the current BASIC program pointer in HL to the stack.
26A3PUSH BCSave the variable’s name in BC to the stack.
26A4LD C,ALoad register C with the value of the number type flag for the variable in register A.
26A5-26A6LD B,00HLoad register B with zero.
26A7PUSH BCSave the variable’s number type flag in BC to the stack.
26A8INC BCBump the value of the variable’s number type flag in BC.
26A9INC BCBump the value of the variable’s number type flag in BC.
26AAINC BCBump 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).
26AB-26ADLD HL,(40FDH)Load HL with the value of the free memory pointer.
Note: 40FDH-40FEH holds Free memory pointer.
26AEPUSH HLSave the value of the free memory pointer in HL to the stack.
26AFADD HL,BCAdd the value of the variable’s number type flag in BC to the value of the free memory pointer in HL.
26B0POP BCGet the value of the free memory pointer from the stack and put it in BC.
26BlPUSH HLSave the value of the new free memory pointer in HL to the stack.
26B5POP HLGet the value of the new free memory pointer from the stack and put it in HL.
26B6-26B8LD (40FDH),HLSave the value of the new free memory pointer in HL to lock in that variable space.
NOTE: 40FDH-40FEH holds Free memory pointer.
26B9LD H,BLoad register H with the MSB of the new array variables pointer in register B.
26BALD L,CLoad register L with the LSB of the new array variables pointer in register C.
26BB-26BDLD (40FBH),HLSave the value of the new array variables pointer in HL.
- Note: 40FBH-40FCH holds the starting address of the BASIC array variable storage area.
26BEDEC HLDecrement the value of the array variables pointer in HL.
26BF-26C0LD (HL),00HZero the location of the memory pointer in HL.
26ClRST 18HNow 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.
26C4POP DEGet the value of the variable’s number type flag from the stack and put it in DE.
26C5LD (HL),ESave the value of the number type flag in register E at the location of the memory pointer in HL.
26C6INC HLBump the value of the memory pointer in HL.
26C7POP DEGet the 2nd character of the variable’s name from the stack and put it in DE.
26C8LD (HL),ESave the first character of the variable’s name in register E at the location of the memory pointer in HL.
26C9INC HLBump the value of the memory pointer in HL.
26CALD (HL),DSave the first character of the variable’s name in register D at the location of the memory pointer in HL.
26CBEX DE,HLLoad DE with the value of the variable pointer in HL.
26CCINC DEBump the value of the variable pointer in DE.
26CDPOP HLGet the value of the current BASIC program pointer from the stack and put it in HL.
26CERETReturn.
26D0LD E,ALoad register E with the value of the current number type flag in register A.
26D1POP AFClean up the stack.
26D2POP AFClean up the stack.
26D3EX (SP),HLExchange the value of the return address in HL with the value of the current BASIC program pointer to the stack.
26D4RETReturn to the VARPTR routine.
26D5 – This routine is to locate a subscripted variable.
26D5-26D7LD (4124H),AZero REG 1.
26D8POP BCClean up the stack.
26D9LD H,AZero register H.
26DALD L,AZero register L.
26DB-26DDLD (4121H),HLZero the string pointer location in REG 1.
26DERST 20HWe 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.
26E1-26E3LD HL,1928HLoad HL with the starting address of the Level II BASIC READY message.
26E4-26E6LD (4121H),HLSave the value in HL as the current string pointer.
26E7POP HLGet the value of the current BASIC program pointer from the stack and put it in HL.
26E8RETReturn.
26E9 – 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.
26E9PUSH HLSave the value of the current BASIC program pointer in HL to the stack.
26EA-26ECLD 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.
26EDEX (SP),HLExchange the value of the locate/create flag in HL with the value of the current BASIC program pointer to the stack.
26EELD D,AZero register D.
26EFPUSH DESave the variable’s number type flag in DE to the stack.
26F0PUSH BCSave the variable’s name in BC to the stack.
26Fl-26F3Go 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.
26F4POP BCGet the variable’s name from the stack (1st and 2nd character) and put it in BC.
26F5POP AFGet the variable’s number type flag from the stack and put it in register A.
26F6EX DE,HLExchange the value of the array subscript in DE with the value of the current BASIC program pointer in HL.
26F7EX (SP),HLExchange the value of the array subscript in HL with the value of the locate/create flag to the stack.
26F8PUSH HLSave the value of the locate/create flag in HL to the stack.
26F9EX DE,HLExchange the value of the locate/create flag in HL with the value of the current BASIC program pointer in DE.
26FAINC ABump the number of subscripts evaluated in register A.
26FBLD D,ALoad register D with the number of subscripts evaluated in register A.
26FCLD A,(HL)Load register A with the character at the location of the current BASIC program pointer in HL.
26FD-26FECP 2CHCheck to see if the character at the location of the current BASIC program pointer in register A is a ,.
26FF-2700Jump if the character at the location of the current BASIC program pointer in register A is a ,.
2701-2702RST 08H
29Since 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).
2703-2705LD (40F3H),HLSave the value of the current BASIC program pointer in HL.
2706Get the value of the locate/ create flag from the stack and put it in HL.
NOTE: 40F3H-40F4H holds Temporary storage location.
2707-2709LD (40AEH),HLSave the value of the locate/create flag in HL.
NOTE: 40AEH holds LOCATE/CREATE variable flag.
270APUSH DESave the number of subscripts evaluated in DE.
270B-270DLD 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.
270E-270FLD A,19HZ-80 Trick to skip the next command of ADD HL, DE if falling through.
2710EX DE,HLLoad DE with the value of the array variables pointer in HL.
2711-2713LD HL,(40FDH)Load HL with the value of the free memory pointer.
Note: 40FDH-40FEH holds Free memory pointer.
2714EX DE,HLExchange the value of the free memory pointer in HL with the value of the array variables pointer in DE.
2715RST 18HNow 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.
2716-2718LD A,(40AFH)Load register A with the value of the current number type flag.
Note: 40AFH holds Current number type flag.
2719-271AJump 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.
271BCP (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.
271CINC HLBump the value of the array variables pointer in HL.
271D-271EJump forward (but still in this loop) to 2727H if the number type flags don’t match.
271FLD A,(HL)Load register A with the first character of the variable name at the location of the array variables pointer in HL.
2720CP CCheck 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.
2721INC HLBump the value of the array variables pointer in HL.
2722-2723Jump forward (but still in this loop) to 2728H if the first characters of the variable names don’t match.
2724LD A,(HL)Load register A with the second character of the variable name at the location of the array variables pointer in HL.
2725CP BCompare 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.
2727LD A,23HBump the value of the array variables pointer in HL.
2728INC HLBump the value of the array variables pointer in HL.
2729LD 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.
272AINC HLBump the value of the array variables pointer in HL.
272BLD 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.
272CINC HLBump the value of the array variables pointer in HL.
272F-2731LD A,(40AEH)Load register A with the value of the locate/create flag.
Note: 40AEH holds LOCATE/CREATE variable flag.
2732OR ACheck the status of the locate/create flag in register A.
2733-2734LD E,12HLoad register E with the ?DD ERROR code.
2735-2737Display a ?DD ERROR message if the locate/create flag in register A indicates the create mode since that variable already exists.
2738POP AFGet the number of subscripts evaluated from the stack and put it in register A.
2739SUB (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).
273A-273CJump 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.
273D – BS ERROR entry point.
273D-273ELD E,10HLoad register E with a ?BS ERROR code.
273F-2741Display 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.
2742LD (HL),ASave the number of subscripts for the array in register A at the location of the array variables pointer in HL.
2743INC HLBump 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).
2744LD E,ALoad register E with the number type flag for the current variable.
2745-2746LD D,00HZero register D.
2747POP AFGet the number of subscripts evaluated from the stack and put it in register A.
2748LD (HL),CSave the second character of the variable’s name in register C at the location of the array variables pointer in HL.
2749INC HLBump 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).
274ALD (HL),BSave the first character of the variable’s name in register B at the location of the array variables pointer in HL.
274BINC HLBump the value of the array variables pointer in HL to the LSB of the offset to the next entry.
274CLD C,ALoad register C with the number of subscripts evaluated in register A.
2750INC HLBump the value of the array variables pointer in HL.
2751INC HLBump the value of the array variables pointer in HL. These 2 INC’s skip over the offset entry.
2752-2754LD (40D8H),HLSave 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.
2755LD (HL),CSave the number of subscripts evaluated in register C (1, 2, or 3) at the location of the array variables pointer in HL.
2756INC HLBump the value of the array variables pointer in HL to point to the first subscript entry in the array table.
2757-2759LD A,(40AEH)Load register A with the value of the locate/create flag.
Note: 40AEH holds LOCATE/CREATE variable flag.
275ARLASet the CARRY flag to be 0 for locate and 1 for create.
275BLD A,CLoad register A with the number of subscripts evaluated in register C.
275C-275ELD BC,000BHLoad BC with the default number of 11, which is the most entries an array can have without a DIM.
Jump forward to 2763H if the array is being created because it certainly wasn’t found.
2761POP BCGet a subscript from the stack and put it in BC.
2762INC BCBump the value of the subscript in BC.
276JLD (HL),CSave the LSB of the subscript’s value in register C at the location of the array variables pointer in HL.
2764INC HLBump the value of the array variables pointer in HL.
2765LD (HL),BSave the MSB of the subscript’s value in register B at the location of the array variables pointer in HL.
2766INC HLBump the value of the array variables pointer in HL.
2767PUSH AFSave the number of subscripts evaluated in register A to the stack.
2768-276AGo multiply the size of the subscript by the value of the number type flag to determine the amount of memory necessary for the subscript.
276BPOP AFGet the number of subscripts evaluated from the stack and put it in register A.
276CDEC ACheck to see if there are anymore subscripts to be evaluated.
276FPUSH AFSave the number of subscripts to be evaluated in register A to the stack.
2770LD B,DLoad register B with the MSB of the array’s length in register D.
2771LD C,ELoad register C with the LSB of the array’s length in register E. Now BC = length of the array in bytes.
2772EX DE,HLLoad DE with the value of the array variables pointer in HL.
2773ADD HL,DEAdd the length of the array in HL to the value of the array variable pointer in DE.
2779-277BLD (40FDH),HLGet the end of the array and put it in HL.
Note: 40FDH-40FEH holds free memory pointer.
277CDEC HLDecrement the value of the array pointer in HL.
277D-277ELD (HL),00HZero the location of the array pointer in HL.
277FRST 18HNow 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.
2782INC BCLoad BC with the array’s length in bytes plus one.
2783LD D,AZero register D.
2784-2786LD HL,(40D8H)Load HL with the array variables pointer (=the number of indices).
Note: 40D8H-40D9H holds Temporary storage location.
2787LD E,(HL)Load register E with the number of subscripts for the array at the location of the array variables pointer in HL.
2788EX DE,HLExchange the value of the array variables pointer in HL with the number of subscripts for the array in DE.
2789ADD HL,HLMultiply the number of subscripts for the array in HL by two.
278AADD HL,BCAdd the length of the array in BC to the number of subscripts times two in HL.
278BEX DE,HLExchange the array’s length in HL with the array variables pointer in DE.
278CDEC HLDecrement the value of the array variables pointer in HL.
278DDEC HLDecrement the value of the array variables pointer in HL.
278ELD (HL),ESave the LSB of the offset to the next array in register E at the location of the array variables pointer in HL.
278FINC HLBump the value of the array variables pointer in HL.
2790LD (HL),DSave the MSB of the offset to the next array in register D at the location of the array variables pointer in HL.
2791INC HLBump the value of the array variables pointer in HL.
2792POP AFGet the value of the locate/ create flag from the stack and put it in register A.
2795LD B,AZero register B.
2796LD C,AZero register C.
2797LD A,(HL)Load register A with the number of subscripts for the array at the location of the array variables pointer in HL.
2798INC HLBump the value of the array variables pointer in HL.
279916H E1Z-80 Trick to hide the next instruction (POP HL) if proceeding downward.
279APOP HLGet the array variables pointer from the stack and put it in HL.
279BLD E,(HL)Load register E with the LSB of the subscript limit at the location of the array variables pointer in HL.
279CINC HLBump the value of the array variables pointer in HL.
279DLD D,(HL)Load register D with the MSB of the subscript limit at the location of the array variables pointer in HL.
279EINC HLBump the value of the array variables pointer in HL.
279FEX (SP),HLExchange the value of the array variables pointer in HL with the subscript to the stack.
27A0PUSH AFSave the number of subscripts for the array in register A to the stack.
27A1RST 18HNow 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.
Jump back to 273DH if the subscript for the array in HL is greater than the subscript limit in DE.
27A8ADD HL,DEAdd the subscript limit for the array in DE to the array pointer in HL.
27A9POP AFGet the number of subscripts for the array from the stack and put it in register A.
27AADEC ACheck to see if there are anymore subscripts to be evaluated.
27ABLD B,HLoad register B with the MSB of the subscript pointer in register H.
27ACLD C,LLoad register C with the LSB of the subscript pointer in register L.
27AF-27B1LD A,(40AFH)Get the number type flag for the current array.
NOTE: 40AFH holds Current number type flag.
27B2LD B,HLoad register B with the MSB of the subscript pointer in register H.
27B3LD C,LLoad register C with the LSB of the subscript pointer in register L.
27B4ADD HL,HLMultiply the subscript pointer in HL by two.
27B5-27B6SUB 04HCheck the value of the number type flag in register A.
27B9ADD HL,HLIt 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).
27BCADD HL,HLIt must be double precision, so once again multiply the subscript pointer in HL by two (so now it is multiplied by 8).
27BDOR ASet the flags.
27C1ADD HL,BCThe current number type is a string so add the value of the original subscript pointer in BC to the subscript pointer in HL.
27C2POP BCGet the value of the array variables pointer from the stack and put it in BC.
27C3ADD HL,BCAdd the value of the array variables pointer in BC to the subscript pointer in HL.
27C4EX DE,HLLoad DE with the variable pointer in HL.
27C5-27C7LD HL,(40F3H)Get the value of the current BASIC program pointer and put it in HL.
Note: 40F3H-40F4H holds Temporary storage location.
27C8RETReturn.
27C9-27D3 – 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.
27CAPUSH HLSave the value of the current BASIC program pointer in HL to the stack.
27CB-27CDLD (40AFH),AZero the number type flag.
NOTE: 40AFH holds Current number type flag.
27D1POP HLGet the value of the current BASIC program pointer from the stack and put it in HL.
27D2RST 10HWe 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.
27D3RETReturn to BASIC.
27D4-27F4 – LEVEL II BASIC FRE ROUTINE
27D4-27D6LD HL,(40FDH)Load HL with the start of free memory pointer.
NOTE: 40FDH-40FEH holds Free memory pointer.
27D7EX DE,HLLoad DE with the value of the free memory pointer in HL.
27D8-27DALD HL,0000HZero HL.
27DBADD HL,SPAdd the value in HL (which is zero) to the current value of the stack pointer.
27DCRST 20HWe 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.
27DD-27DEIf that test shows we do NOT have a STRING (meaning this was really a MEM call, jump to forward to 27ECH.
27E5-27E7LD HL,(40A0H)Load HL with the start of string space pointer.
NOTE: 40A0H-40A1H holds the start of string space pointer.
27E8EX DE,HLLoad DE with the start of string space pointer in HL.
27E9-27EBLD HL,(40D6H)Load HL with the next available location in string space pointer.
NOTE: 40D6H-40D7H holds Next available location in string space pointer.
27ECLD A,LLoad register A with the LSB of the next available location in string space pointer in register L.
27EDSUB ESubtract 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.
27EELD L,ALoad register L with the LSB of the amount of string space remaining in register A.
27EFLD A,HLoad register A with the MSB of the next available location in string space pointer in register H.
27F0SBC A,DSubtract 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.
27F1LD H,ALoad register H with the MSB of the amount of string space remaining in register A.
27F2-27F4Jump to 0C66H to convert the difference between HL and DE to single precision and then RETurn out of the routine.
27F5-27FD – LEVEL II BASIC POS( ROUTINE
27F5-27F7LD A,(40A6H)Load register A with the current cursor line position.
Note: 40A6H holds the current cursor line position.
27F8LD L,ALoad register L with the value of the current cursor line position in register A.
27F9XOR AZero register A.
27FALD H,ALoad register H with zero, so now HL is 00 / cursor position.
27FE-2818 – LEVEL II BASIC USR(x) ROUTINE
2801RST 10HWe 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.
2802-2804GOSUB 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.
2805PUSH HLSave the value of the current BASIC program pointer in HL (=the address of the next element in the code string) to the stack.
2806-2808LD HL,0890HLoad HL with the return address of 0890H which will clear the stack before returning to BASIC.
2809PUSH HLSave the value of the return address in HL to the stack.
280A-280CLD A,(40AFH)Load register A with the value of the current number type flag.
Note: 40AFH holds Current number type flag.
280DPUSH AFSave the value of the current number type flag in register A.
(02=INT, 03=STR, 04=SNG, 08=DBL).
280E-280FCP 03HCheck to see if the current value in REG l is a string.
2810-2812If the current result in REG l is a string then GOSUB to 29DAH to get the string address into HL.
2813POP AFRestore the number type flag into register A.
2814EX DE,HLLoad DE with the value of the string address in HL.
2815-2817LD 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.
2818JP (HL)Jump to the address in HL.
2819-2827 – CONVERSION ROUTINE
Usually called by LET to convert the result of arithmetic routines to the proper destination type.
2819PUSH HLSave the value in HL to the stack.
281A-281BAND 07HMask the value of the current number type flag in register A.
281C-281ELD HL,18A1HLoad HL with the address of the arithmetic conversion routines.
281FLD C,ALoad register C with the value of the number type flag in register A.
(02=INT, 03=STR, 04=SNG, 08=DBL).
2820-2821LD B,00HZero register B. Now BC holds 00 / type.
2822ADD HL,BCAdd the offset (of BC) to the base arithmetic conversion routines, to find the right jump point.
2826POP HLGet the value from the stack and put it in HL.
2827RETReturn.
2828-2835 – Save the code string address
Usually called from the INPUT routine. On entry HL has the current line number in binary.
2828PUSH HLSave the value of the current BASIC program pointer in HL to the stack.
2829-282BLD HL,(40A2H)Load HL with the value of the current BASIC line number.
- Note: 40A2H-40A3H holds the current BASIC line number.
282CINC HLBump the value of the current BASIC line number in HL to enable us to test for a direct statement.
282DLD A,HLoad register A with the MSB of the current BASIC line number in register H.
282EOR LCombine the LSB of the current BASIC line number in register L with the MSB of the current BASIC line number in register A.
282FPOP HLGet the value of the current BASIC program pointer from the stack and put it in HL.
2830RET NZReturn if there is a line number (i.e., this isn’t the command mode).
2831 – ID ERROR entry point.
2831-2832LD E,16HLoad register E with the ?ID ERROR code.
2836-2856 – STRING ROUTINE – STR$ logic.
LD BC,2A2BHLoad BC with a return address of 2A2BH (which cleans the stack and then jumps to 2884H).
2842PUSH BCSave the value of the return address in BC to the stack.
2843LD A,(HL)Load register A with the string’s length at the location of the string’s VARPTR in HL.
2844INC HLBump the value of the string’s VARPTR in HL.
2845PUSH HLSave the value of the string’s VARPTR in HL to the stack.
2846-2848GOSUB to 28BFH to test the remaining string area to make sure that the new string will fit.
2849POP HLReload HL with the string’s VARPTR.
284ALD C,(HL)Load register C with the LSB of the string’s address at the location of the string’s VARPTR in HL.
284BINC HLBump the value of the string’s VARPTR in HL.
284CLD B,(HL)Load register B with the MSB of the string’s address at the location of the string’s VARPTR in HL.
2851LD L,ALoad register L with the string’s length (from register A).
2852-2854GOSUB to 29CEH to move the string from the temp area (of BC) to the string data area (in DE).
2855POP DEGet the value from the stack (40D3H) and put it in DE.
2856RETReturn.
2857-2864 – STRING ROUTINE – Set Up a String. A needs to hold the length of the string to be created.
2857-2859GOSUB 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.
285A-285CLD HL,40D3HLoad HL with the address of the temporary string parameter storage area.
Note: 40D3H-40D5H holds Used for temporary string VARPTR’s.
285DPUSH HLSave the address of the temporary string parameter area in HL to the stack.
285ELD (HL),ASave the string’s length in register A at the location of the temporary string parameter storage pointer in HL.
285FINC HLBump the value of the temporary string parameter storage pointer in HL.
2860LD (HL),ESave the LSB of the string’s address in register E at the location of the temporary string parameter storage pointer in HL.
2861INC HLBump the value of the temporary string parameter storage pointer in HL.
2862LD (HL),DSave the MSB of the string’s address in register D at the location of the temporary string parameter storage pointer in HL.
2863POP HLGet the address of the temporary string parameter storage area from the stack and put it in HL.
2864RETReturn.
2865-28A5 – STRING ROUTINE
This is the quote routine. C will be a counter.
2865H
“CSVEC”DEC HLDecrement the value of the current BASIC program pointer in HL.
2866-2867LD B,22HLoad register B with a “ (which is really the opening search character).
2868LD D,BLoad register D with a “ (which is really the ending search character).
2869PUSH HLSave the address of the current BASIC program pointer in HL to the stack.
286A-286BLD C,0FFHLoad register C with a -1.
286CINC HLBump the value of the current BASIC program pointer in HL to skip over that initial “.
286DLD A,(HL)Load register A with the character at the location of the current BASIC program pointer in HL.
286EINC CBump the counter in register C.
286FOR ACheck 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.
2870-2871Jump 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.
2872CP DCheck 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.
2873-2874Jump 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.
2875CP BCheck 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.
2876-2877Loop 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.
2878-2879CP 22HCheck to see if the character at the location of the current BASIC program pointer in register A is a quote.
287A-287CIf 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.
287DEX (SP),HLExchange the value of the current BASIC program pointer in HL with the string’s address to the stack.
287EINC HLBump the string’s address in HL until it points to the first character of the string.
287FEX DE,HLLoad DE with the string’s address in HL.
2880LD A,CLoad register A with the string’s length from register C.
2884-2886LD DE,40D3HLoad DE with the address of the string parameter storage area.
Note: 40D3H-40D5H holds Used for temporary string VARPTR’s.
2887-2888LD A,D5HThis seems to be garbage. Perhaps there is a jump to 2888 which would then be PUSH DE.
2889-288BLD 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.
288C-288ELD (4121H),HLSave the value of the next available location in the temporary string work area in HL as the string’s VARPTR in REG 1.
288F-2890LD A,03HLoad register A with the string number type flag.
2891-2893LD (40AFH),ASave the value in register A as the current number type flag.
Note: 40AFH holds Current number type flag.
2894-2896Add the length of the string to the next available location in the temporary string work area in HL.
2897-2899LD DE,40D6HLoad DE with the ending address of the temporary string work area.
Note: 40D6H-40D7H holds Next available location in string space pointer.
289ARST 18HNow 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.
289B-289DLD (40B3H),HLSave 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.
289EPOP HLGet the value of the current BASIC program pointer from the stack and put it in HL.
289FLD A,(HL)Load register A with the character at the location of the current BASIC program pointer in HL.
28A0RET NZReturn 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 …).
28A1 – ST ERROR entry point.
28A1-28A2LD E,1EHLoad register E with a ?ST ERROR code.
28A6-28BE – DISPLAY MESSAGE ROUTINE
28A6INC HLBump the value of the current BASIC program pointer in HL.
28A7 – 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.
28A7-28A9H
“DSTR”Go build a temporary string work area entry for the message at the location of the current BASIC program pointer in HL.
28B0INC DBump the value of the string’s length in register D in preparation for the following loop which starts with a DEC D.
28BlDEC DDecrement the value of the string’s length in register D.
28B2RET ZReturn if all of the characters in the string have been sent to the current output device.
28B7-28B8CP 0DHCheck to see if the character in register A is a carriage return.
28BCINC BCBump the value of the string pointer in BC.
28BD-28BELoop until all of the characters in the string have been sent to the current output device.
28BF-28D9 – STRING ROUTINE – Compute the amount of space remaining in the string area.
28BFOR ASet the flags.
28C0-28Cl0E F1Z-80 Trick.
28ClPOP AFGet the string’s length from the stack and put it in register A.
28C2PUSH AFSave the length of the string in register A to the stack.
28C3-28C5LD HL,(40A0H)Load HL with the start of the string space pointer.
- Note: 40A0H-40A1H holds the start of string space pointer.
28C6EX DE,HLMove the start of the string space pointer into DE. We don’t care what happens to HL.
28C7-28C9LD HL,(40D6H)Load HL with the next available location in string space pointer.
Note: 40D6H-40D7H holds Next available location in string space pointer.
28CACPLComplement the string’s length in register A so that it is negative.
28CBLD C,ALoad register C with the negative string’s length in register A.
28CC-28CDLD B,0FFHLoad register B with a -1 so that BC will be the negative length of the string.
28CEADD HL,BCAdd the negative string’s length in BC to the next available location in string space pointer in HL.
28CFINC HLBump the value of the adjusted next available location in string space pointer in HL.
28D0RST 18HNow 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.
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.
28D3-28D5LD (40D6H),HLSave the value in HL as the next available location in string space pointer.
Note: 40D6H-40D7H holds Next available location in string space pointer.
28D6INC HLBump the value of the next available location in string space pointer in HL.
28D7EX DE,HLLoad DE with the next available location in string space pointer in HL.
28D8POP AFGet the string’s length from the stack and put it in register A.
28D9RETReturn.
28DA-298E – STRING ROUTINE
28DAPOP AFGet 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.
28DB-28DCLD E,1AHLoad register E with an ?OS ERROR code.
28DD-28DFDisplay a ?OS ERROR if there isn’t enough string space available for the string and we had already reorganized string space.
28E0CP ASet the flags.
28ElPUSH AFSave the string’s length in register A to the stack.
28E5PUSH BCSave that return address to the stack.
28E6-28E8LD HL,(40B1H)Load HL with the top of memory pointer.
Note: 40B1H-40B2H holds MEMORY SIZE? pointer.
28E9-28EBLD (40D6H),HLSave 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.
28EC-28EELD HL,0000HZero HL.
28EFPUSH HLSave the value in HL to the stack.
28F0-28F2LD HL,(40A0H)Load HL with the start of string space pointer.
NOTE: 40A0H-40A1H holds the start of string space pointer.
28F3PUSH HLSave the start of string space pointer in HL to the stack.
28F4-28F6LD HL,40B5HLoad HL with the start of the temporary string work area pointer.
Note: 40B5H-40D2H holds Temporary string work area.
28F7EX DE,HLLoad DE with the start of the temporary string work area pointer in HL.
28F8-28FALD 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.
28FBEX DE,HLExchange 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.
28FCWe 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.
2903LD 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.
2906EX DE,HLLoad DE with the simple variables pointer in HL.
2907-2909LD 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.
290AEX DE,HLExchange the value of the simple variables pointer in DE with the value of the array variables pointer in HL.
290BRST 18HNow 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.
290C-290DJump forward to 2921H if the simple variables pointer in HL is the same as the array variables pointer in DE.
290ELD A,(HL)Load register A with the number type flag at the location of the simple variables pointer in HL.
290FINC HLBump the value of the simple variables pointer in HL.
2910INC HLBump the simple variables pointer in HL.
2911INC HLBump the value of the simple variables pointer in HL.
2912-2913CP 03HCheck to see if the variable at the location of the simple variables pointer is a string.
2914-2915Jump to 291AH if the variable at the location of the simple variables pointer in HL isn’t a string.
2919XOR AZero register A.
29lALD E,AZero register E.
291B-291CLD D,00HZero register D.
29lDADD HL,DEAdd the value of the number type flag in DE to the simple variables pointer in HL.
2920POP BCClean up the stack.
2921EX DE,HLLoad DE with the value of the array variables pointer in HL.
2922-2924LD HL,(40FDH)Load HL with the start of free memory pointer.
Note: 40FDH-40FEH holds Free memory pointer.
2925EX DE,HLExchange the value of the array variables pointer in DE with the value of the free memory pointer in HL.
2926RST 18HNow 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.
2927-2929Jump if the array variables pointer in register HL is the same as the start of the free memory pointer in DE.
292ALD A,(HL)Load register A with the number type flag at the location of the array variables pointer in HL.
292BINC HLBump the value of the array variables pointer in HL.
292C-292ECall 09C2H (which loads a SINGLE PRECISION value pointed to by HL into register pairs BC and DE).
292FPUSH HLSave the value of the array variables pointer in reg� ister pair HL to the stack.
2930ADD HL,BCAdd the value of the offset to the next array in BC to the value of the array variables pointer in HL.
2931-2932CP 03HCheck to see if the array being examined is a string.
2935-2937LD (40D8H),HLSave the address of the next array in HL.
Note: 40D8H-40D9H holds Temporary storage location.
2938POP HLGet the value of the array variables pointer from the stack and put it in HL.
2939LD C,(HL)Load register C with the number of subscripts for the array at the location of the array variables pointer in HL.
293A-293BLD B,00HZero register B.
293CADD HL,BCAdd the number of subscripts in the array in BC to the value of the array variables pointer in HL.
293DADD HL,BCAdd the number of subscripts in the array in BC to the value of the array variables pointer in HL.
293EINC HLBump the value of the array variables pointer in HL.
293FEX DE,HLLoad DE with the value of the array variables pointer in HL.
2940-2942LD HL,(40D8H)Load HL with the address of the next array.
Note: 40D8H-40D9H holds Temporary storage location.
2943EX DE,HLExchange the value of the array variables pointer in DE with the address of the array in HL.
2944RST 18HNow 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.
2945-2946Jump to 2921H if the array variables pointer in HL is the same as the address of the next array in DE.
294APUSH BCSave the value in BC to the stack.
294BXOR AZero register A.
294COR (HL)Load register A with the length of the string at the location of the array variables pointer in HL.
294DINC HLBump the value of the array variables pointer in HL.
294ELD E,(HL)Load register E with the LSB of the string’s address at the location of the array variables pointer in HL.
294FINC HLBump the value of the array variables pointer in HL.
2950LD D,(HL)Load register D with the MSB of the string’s address at the location of the array variables pointer in HL.
2951INC HLBump the value of the array variables pointer in HL.
2952RET ZReturn if the string’s length in register A is equal to zero.
2954LD C,LLoad register C with the LSB of the array variables pointer in register L.
2955-2957LD 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.
2958RST 18HNow 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.
2959LD H,BLoad register H with the MSB of the array variables pointer in register B.
295ALD L,CLoad register L with the LSB of the array variables pointer in register C.
295BRET CReturn if the string’s address in DE is in string space.
295DEX (SP),HLExchange the value of the return address in HL with the start of string space pointer to the stack.
295ERST 18HNow 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.
295FEX (SP),HLExchange the start of string space pointer in HL with the value of the return address to the stack.
2960PUSH HLSave the value of the return address in HL to the stack.
2961LD H,BLoad register H with the MSB of the array variables pointer in register B.
2962LD L,CLoad register L with the LSB of the array variables pointer in register C.
2963RET NCReturn if the string’s address in DE is below the string space pointer.
2965POP AFClean up the stack.
2966POP AFClean up the stack.
2967PUSH HLSave the value of the array variables pointer in HL to the stack.
2968PUSH DESave the string’s address in DE to the stack.
2969PUSH BCSave the value of the return address in BC to the stack.
296ARETReturn.
296CPOP HLGet the temporary string work area pointer from the stack and put it in HL.
296DLD A,LLoad register A with the LSB of the temporary string work area pointer in register L.
296EOR HCombine 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.
296FRET ZReturn if the temporary string work area is empty.
2971LD 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.
2972DEC HLDecrement the value of the temporary string work area pointer in HL.
2973LD 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.
2974PUSH HLSave the value of the temporary string work area pointer in HL to the stack.
2975DEC HLDecrement the value of the temporary string work area pointer in HL.
2976LD L,(HL)Load register L with the string’s length at the location of the temporary string work area pointer in HL.
2977-2978LD H,00HZero register H.
2979ADD HL,BCAdd the length of the string in HL to the string’s address in BC.
297ALD D,BLoad register D with the MSB of the string’s address in register B.
297BLD E,CLoad register E with the LSB of the string’s address in register C.
297CDEC HLDecrement the value of the string’s ending address in HL.
297DLD B,HLoad register B with the MSB of the string’s ending address in register H.
297ELD C,LLoad register C with the LSB of the string’s ending address in register L.
297F-2981LD HL,(40D6H)Load HL with the next available location in string space pointer.
NOTE: 40D6H-40D7H holds Next available location in string space pointer.
2985POP HLGet the temporary string work area pointer from the stack and put it in HL.
2986LD (HL),CSave the LSB of the string’s address in register Cat the location of the temporary string work area pointer in HL.
2987INC HLBump the value of the temporary string work area pointer in HL.
2988LD (HL),BSave the MSB of the string’s address in register B at the location of the temporary string work area pointer in HL.
2989LD L,CLoad register L with the LSB of the string’s address in register C.
298ALD H,BLoad register H with the MSB of the string’s address in register B.
298BDEC HLDecrement the string’s address in HL.
298F-29C5 – STRING ADDITION ROUTINE – Concatenate two strings.
298FPUSH BCSave the operator value in BC to the stack.
2990PUSH HLSave the value of the current BASIC program pointer in HL to the stack.
2991-2993LD HL,(4121H)Load HL with the first string’s VARPTR (from REG 1).
2994EX (SP),HLExchange the value of the first string’s VARPTR in HL with the value of the current BASIC program to the stack.
2995-2997GOSUB to 249FH to evaluate the expression at the location of the current BASIC program pointer in HL.
2998EX (SP),HLExchange the value of the current BASIC program pointer in HL with the value of the first string’s VARPTR to the stack.
299CLD A,(HL)Load register A with the first string’s length at the location of the first string’s VARPTR in HL.
299DPUSH HLSave the value of the first string’s VARPTR in HL to the stack.
299E-29A0LD HL,(4121H)Load HL with the second string’s VARPTR in REG 1.
29A1PUSH HLSave the second string’s VARPTR in HL to the stack.
29A2ADD 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.
29A3-29A4LD E,1CHLoad register E with a ?LS ERROR code.
29A5-29A7Display a ?LS ERROR message if the combined lengths of the strings is greater than 255.
29ABPOP DEGet the second string’s VARPTR from the stack and put it in DE.
29AFEX (SP),HLExchange the second string’s VARPTR in HL with the first string’s VARPTR to the stack.
29B3PUSH HLSave the value of the first string’s VARPTR in HL to the stack.
29B4-29B6LD HL,(40D4H)Load HL with the second string’s address.
29B7EX DE,HLLoad DE with the second string’s address in HL.
29BE-29C0LD HL,2349HLoad HL with the return address.
29C1EX (SP),HLExchange the value of the return address in HL with the value of the current BASIC program pointer to the stack.
29C2PUSH HLSave the value of the current BASIC program pointer in HL to the stack.
29C6-29D6 – 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.
29C6POP HLLoad HL with the value of the return address to the stack.
29C7EX (SP),HLExchange the value of the return address in HL with the string’s VARPTR to the stack.
29C8 – 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.
29C8LD A,(HL)Load register A with the string’s length at the location of the string’s VARPTR in HL.
29C9INC HLBump the value of the string’s VARPTR in HL.
29CALD C,(HL)Load register C with the LSB of the string’s address at the location of the string’s VARPTR in HL.
29CBINC HLBump the value of the string’s VARPTR in HL.
29CCLD B,(HL)Load register B with the MSB of the string’s address at the location of the string’s VARPTR in HL.
29CDLD L,ALoad register L with the string’s length in register A.
29CEINC LBump the value of the string’s length in register L.
29CFDEC LDecrement the value of the string’s length in register L.
29D0RET ZReturn if all of the characters in the string have been moved.
29D2LD (DE),ASave the character in register A at the location of the string storage pointer in DE.
29D3INC BCBump the value of the string pointer in BC.
29D4INC DEBump the value of the string storage pointer in DE.
29D7-29F4 – 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.
29DDEX DE,HLLoad DE with the value of the string’s VARPTR in HL.
29E1EX DE,HLLoad HL with the value of the string’s VARPTR in DE.
29E2RET NZReturn if the string isn’t the last entry in the temporary string work area.
29E4LD D,BLoad register D with the MSB of the string’s address in register B.
29E5LD E,CLoad register E with the LSB of the string’s address in register C.
29E6DEC DEDecrement the value of the string’s address in DE.
29E7LD C,(HL)Load register C with the string’s length at the location of the string’s VARPTR in HL.
29E8-29EALD HL,(40D6H)Load HL with the next available location in string space pointer.
Note: 40D6H-40D7H holds Next available location in string space pointer.
29EBRST 18HWe 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.
29EC-29EDJump 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.
29EELD B,AIf 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.
29EFADD HL,BCAdd the length of the string in BC to the next available location in string space pointer in HL.
29E0-29F2LD (40D6H),HLSave the adjusted next available location in string space pointer in HL.
Note: 40D6H-40D7H holds Next available location in string space pointer.
29F3POP HLGet the string’s VARPTR from the stack and put it in HL.
29F4RETReturn.
29F5-2A02 – STRING ROUTINE
29F5-29F7LD 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.
29F8DEC HLDecrement the value of the temporary string work area pointer in HL which backs up two words.
29F9LD 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.
29FADEC HLDecrement the value of the temporary string work area pointer in HL.
29FBLD 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.
29FCDEC HLDecrement the value of the temporary string work area pointer in HL.
29FDRST 18HNow 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.
29FERET NZReturn if the string’s VARPTR in DE doesn’t match the temporary string work area pointer in HL.
LD (40B3H),HLSave 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.
2A02RETReturn.
2A03-2A0E – LEVEL II BASIC LEN ROUTINE
2A0AXOR AZero register A.
2A0BLD D,AZero register D.
2A0CLD A,(HL)Load register A with the string’s length at the location of the string’s VARPTR in HL.
2A0DOR ASet the flags according to the string’s length in register A.
2A0ERETReturn.
2A0F-2A1E – LEVEL II BASIC ASC ROUTINE
2A13-2A15GOSUB to 2A07H (which itself is a GOSUB to 29D7H) to get string’s VARPTR into HL and the string’s length into register A.
2A19INC HLBump the value of the string’s VARPTR in HL.
2A1ALD E,(HL)Load register E with the LSB of the string’s address at the location of the string’s VARPTR in HL.
2A1BINC HLBump the value of the string’s VARPTR in HL.
2A1CLD D,(HL)Load register D with the MSB of the string’s address at the location of the string’s VARPTR in HL.
2A1DLD A,(DE)Load register A with the first character at the location of the string pointer in DE.
2A1ERETReturn.
2A1F-2A2E – LEVEL II BASIC CHR$ ROUTINE
2A1F-2A20LD A,01HLoad register A with the length of the string to be created.
2A21-2A23GOSUB to 2857H to save the string’s length in register A and value and set up the string’s address.
2A24-2A26GOSUB 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.
2A27-2A29LD HL,(40D4H)Load HL with the temporary string’s address.
2A2ALD (HL),ESave the character in register E at the location of the string pointer in HL.
2A2BPOP BCClean up the stack.
2A2F-2A60 – LEVEL II BASIC STRING$ ROUTINE
2A2FRST 10HWe 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.
2A30-2A31RST 08H
28Since 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).
2A32-2A34This 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.
2A34DEC HLBackspace the code string. This is a Z-80 trick because this code was part of the above call instruction.
2A35PUSH DESave the string’s length (“N”) (currently in DE) to the stack.
2A36-2A37RST 08
2CNow 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).
2A38-2A3ANow 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.
2A3B-2A3CRST 08H
29Now 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).
2A3DEX (SP),HLWe 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.
2A3EPUSH HLSave the string’s length (“N”) in HL to the stack so that we can test it to make sure it is an integer.
2A3FRST 20HWe 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.
2A42-2A44We 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.
2A45-2A46Skip the next instruction (which would load the string address and 1st character) by jumping to 2A4AH.
2A47-2A49Go get the first character in the string and return with it in register A. This is the character that will be repeated.
2A4APOP DEGet the “N” from the stack and put it in DE.
2A4BPUSH AFSave the character for the string (held in register A) to the stack.
2A4CPUSH AFand then save it to the stack again.
2A4DLD A,ELoad register A with “N” (held in register E).
2A51LD E,ALoad register E with “N” (held in register A).
2A52POP AFGet the character for the string (“X”) from the stack and put it in register A.
2A53INC ETo set the status flags we need to increase and then decrease E. First, bump the value of the string’s length in register E …
2A54DEC E… and then decrement the string’s length in register E.
2A57-2A59LD 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.
2A5ALD (HL),ASave the character in register A (“X”) at the location of the string pointer in HL.
2A5BINC HLBump the value of the string pointer in HL.
2A5CDEC EDecrement the string’s length in register E.
2A5D-2A5ELoop back to 2A5AH to keep filling (HL) until the string of X’s has been completed.
2A61-2A90 – LEVEL II BASIC LEFT$( ROUTINE – On entry, HL=address of LEFT$$, the stack = string address, stack+1 = n, and DE = code string address.
2A61-2A63Go check the syntax. The character at the location of the current BASIC program pointer in HL must be a ).
2A64XOR AZero register A.
2A65EX (SP),HLExchange the value of the current BASIC program pointer in HL with the string’s VARPTR to the stack.
2A66LD C,AZero register C.
2A67-2A683E E5Z-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.
2A68LD H,ALoad register H with the value in register A.
2A69PUSH HLSave the value of the string’s VARPTR in HL to the stack.
2A6ALD A,(HL)Load register A with the string’s length at the location of the string’s VARPTR in HL.
2A6BCP BCheck to see if the new string’s length in register B is greater than the string’s length in register A.
Jump to 2A70H if the new string’s length in register B is greater than the string’s length in register A.
2A6ELD A,BLoad register A with the new string’s length in register B.
2A6F-2A7111 0E 00Z-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.
2A70-2A7lLD C,00HZero register C.
2A72PUSH BCSave the string’s length in BC to the stack.
2A76POP BCGet the new string’s length from the stack and put it in BC.
2A77POP HLGet the string’s VARPTR from the stack and put it in HL.
2A78PUSH HLSave the string’s VARPTR in HL to the stack.
2A79INC HLBump the value of the string’s VARPTR in HL.
2A7ALD B,(HL)Load register B with the LSB of the string’s address at the location of the string’s VARPTR in HL.
2A7BINC HLBump the value of the string’s VARPTR in HL.
2A7CLD H,(HL)Load register H with the MSB of the string’s address at the location of the string’s VARPTR in HL.
2A7DLD L,BLoad register L with the LSB of the string’s address in register B.
2A7E-2A7FLD B,00HZero register B.
2A80ADD HL,BCAdd the string’s length in BC to the string’s address in HL.
2A81LD B,HLoad register B with the MSB of the string’s ending address in register H.
2A82LD C,LLoad register C with the LSB of the string’s ending address in register L.
2A83-2A85Go save the string’s length (held in A) and the string’s starting address (held in DE).
2A86LD L,ALoad register L with the string’s length (i.e., the number of characters to move) held in register A.
2A8APOP DEClean up the stack.
2A91-2A99 – LEVEL II BASIC RIGHT$ ROUTINE
2A91-2A93Go check the syntax. The character at the location of the current BASIC program pointer in HL must be a ).
2A94POP DEGet the string’s VARPTR from the stack and put it in DE.
2A95PUSH DESave the string’s VARPTR in DE to the stack.
2A96LD A,(DE)Load register A with the string’s length (held at the location of the string’s VARPTR in DE).
2A97SUB BSubtract the new string’s length in register B from the string’s length in register A to isolate the number of bytes.
2A9A-2AC4 – LEVEL II BASIC MID$ ROUTINE
2A9AEX DE,HLLoad HL with the value of the current BASIC program pointer (held in DE).
2A9BLD A,(HL)Load register A with the terminal character, currently held at the location of the current BASIC program pointer in HL.
2A9C-2A9EGOSUB to 2AE2H to get the string’s position in register B and the string’s VARPTR in DE.
2A9FINC BWe 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 …
2AA0DEC B… and then we decrement the value of the string’s position in register B.
2AA4PUSH BCSave the value of the string’s starting position (held in register B) to the stack.
2AA5-2AA6LD E,0FFHLoad register E with the default string’s length of 256 in case no number of bytes are given.
2AA7-2AA8CP 29HMore syntax checking. Here we need to test for a ) at the location of the current BASIC program pointer.
2AA9-2AAAJump to 2AB0H if the character at the location of the current BASIC program pointer in register A is a ).
2AAB-2AACRST 08H
2CIf 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).
2AAD-2AAFGo 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.
2ABO-2AB1RST 08H
29Since 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).
2AB2POP AFGet the value of the string’starting s position from the stack and put it in register A.
2AB3EX (SP),HLExchange the value of the current BASIC program pointer in HL with the value of the string’s VARPTR to the stack.
2AB7PUSH BCSave the return address in BC to the stack.
2AB8DEC ADecrement the value of the string’s position in register A so that we have a starting position minus 1.
2AB9CP (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.
2ABA-2ABBLD B,00HZero register B.
2ABCRET NCReturn 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.
2ABELD A,(HL)Load register A with the string’s length at the location of the string’s VARPTR in HL.
2ABFSUB CSubtract the value of the string’s position in register C from the string’s length in register A.
2AC0CP ECompare the new string’s length in register E with the adjusted string’s length in register A.
2AC1LD B,ALoad register B with the adjusted string’s length in register A.
2AC2Return to 2A69H if the new string’s length in register E is greater than the string’s length in register A.
2AC5-2ADE – LEVEL II BASIC VAL ROUTINE
2ACBLD E,ALoad register E with the string’s length at the location of the string’s VARPTR in HL.
2ACCINC HLBump the value of the string’s VARPTR in HL.
2ACDLD A,(HL)Load register A with the LSB of the string’s address at the location of the string’s VARPTR in HL.
2ACEINC HLBump the value of the string’s VARPTR in HL.
2ACFLD H,(HL)Load register H with the MSB of the string’s address at the location of the string’s VARPTR in HL.
2ADOLD L,ALoad register L with the LSB of the string’s address in register A.
2AD1PUSH HLSave the value of the string’s address in HL to the stack.
2AD2ADD HL,DEAdd the string’s length in DE to the string’s address in HL.
2AD3LD B,(HL)Load register B with the last character of the string at the location of the string pointer in HL.
2AD4LD (HL),DSave the zero in register D at the location of the string pointer in HL.
2AD5EX (SP),HLExchange the string’s ending address in HL with the string’s address to the stack.
2AD6PUSH BCSave the last character of the string in register B to the stack.
2AD7LD A,(HL)Load register A with the character at the location of the string pointer in HL.
2AD8-2ADACall 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).
2ADBPOP BCGet the last character of the string from the stack and put it in register B.
2ADCPOP HLGet the string’s ending address from the stack and put it in HL.
2ADDLD (HL),BSave the character in register B at the location of the string pointer in HL.
2ADERETReturn.
2ADF-2A6 – 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.
2ADFEX DE,HLLoad HL with the value of the current BASIC program pointer in DE.
2AE0-2AE1RST 08H
29Since 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).
2AE2POP BCGet the return address from the stack and put it in BC.
2AE3POP DEGet the number of bytes to isolate from the string (from the stack) and put it in DE.
2AE4PUSH BCSave the return address in BC to the stack.
2AE5LD B,ELoad register B with the number of bytes in register E.
2AE6RETReturn.
2AE7H- AEE – DISK ROUTINE
2AE7-2AE8CP 7AHCheck 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).
2AE9-2AEBDisplay a ?SN ERROR message if the character at the location of the current BASIC program pointer in register A isn’t equal to 7AH.
2AEF-2AF7 – LEVEL II BASIC INP ROUTINE
2AEF-2AF1Go evaluate the expression at the location of the current BASIC program pointer in HL and return with the port number in register A.
2AF2-2AF4LD (4094H),ASave the value of the port number (from register A) into 4094H.
2AF5-2AF7Go get the value from the port, execute an IN xx instruction, and return to the execution driver.
Note: 4093H-4095H holds INP routine.
2AF8-2B00 – LEVEL II BASIC OUT ROUTINE
2AF8-2AFAGo evaluate the expression at the location of the current BASIC program pointer in HL and return with the port number saved in memory.
2AFB-2AFDGo 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.
2AFE-2B00Go send the value in register A, execute an OUT xx instruction to the port, and return.
Note: 4096H-4098H holds OUT routine.
2B01-2B0D – EVALUATE EXPRESSION ROUTINE – This evaluates an expression and leaves the result in DE as an integer.
2B01RST 10HWe 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.
2B02-2B04Go evaluate the expression at the location of the current BASIC program pointer in HL and return with the result in REG 1.
2B05 – 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)).
2B05PUSH HLSave the value of the current BASIC program pointer in HL to the stack.
2B06-2B08Call 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).
2B09EX DE,HLLoad DE with the integer result in HL.
2B0APOP HLGet the value of the current BASIC program pointer from the stack and put it in HL.
2B0BLD A,DLoad register A with the MSB of the integer result in register D.
2B0COR ATest the value of the MSB in register A.
2B0DRETReturn.
2B0E-2Bl6 – EVALUATE EXPRESSION ROUTINE – OUT continues here
2B0E-2Bl0GOSUB 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.
2Bll-2Bl3LD (4094H),ASave the 8-bit value in register A in the DOS address of 4094H.
2Bl4-2Bl6LD (4097H),ASave the 8-bit value in register A in the DOS address of 4097H.
2Bl7-2BlA – 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.
2B17-2B18RST 08H
2ESince 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).
2BlB-2B28 – EVALUATE EXPRESSION ROUTINE – This is called by PRINT TAB.
2B1BRST 10HWe 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.
2B1C – 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.
2B1C-2B1EGOSUB 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.
2B1F-2B21GOSUB to 2B05H to convert the result in REG 1 to an integer and return with the integer result in DE.
2B25DEC HLDecrement the value of the current BASIC program pointer in HL.
2B26RST 10HWe 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.
2B27LD A,ELoad register A with the 8-bit result in register E.
2B28RETReturn.
2B29-2B2D – LEVEL II BASIC LLIST ROUTINE
This routine sets the output device flag to PRINTER and then flows through to the LIST command.
2B29-2B2ALD A,01HLoad register A with the printer output device code.
2B2B-2B2DLD (409CH),ASave 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.2B2E-2B74 – 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.
2B2EPOP BCGet the return address from the stack and put it in BC.
2B2F-2B31Go evaluate the range of line numbers given at the location of the current BASIC program pointer in HL.
2B32PUSH BCSave the address of the first BASIC line (held in BC) to the stack.
2B33-2B35LD HL,FFFFHLoad 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.
2B36-2B38LD (40A2H),HLSave the value in HL as the current BASIC line number.
- Note: 40A2H-40A3H holds the current BASIC line number.
2B39POP HLGet the address of the first BASIC line to be listed (from the stack) and put it in HL.
2B3APOP DEGet the value of the last BASIC line number to be listed (from the stack) and put it in DE.
2B3BLD C,(HL)Load register C with the LSB of the next BASIC line pointer at the location of the memory pointer in HL.
2B3CINC HLBump the value of the memory pointer in HL.
2B3DLD B,(HL)Load register B with the MSB of the next BASIC line pointer at the location of the memory pointer in HL.
2B3EINC HLBump the value of the memory pointer in HL.
2B3FLD A,BLoad register A with the MSB of the next BASIC line pointer in register B.
2B40OR CCombine 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.
2B44-2B46Go call the DOS link at 41DFH.
In NEWDOS 2.1, this is called from LIST processing.
2B4APUSH BCSave the address of the next BASIC line in BC to the stack.
2B4BLD C,(HL)Load register C with the LSB of the BASIC line number at the location of the memory pointer in HL.
2B4CINC HLBump the value of the memory pointer in HL.
2B4DLD B,(HL)Load register B with the MSB of the BASIC line number at the location of the memory pointer in HL.
2B4EINC HLBump the value of the memory pointer in HL.
2B4FPUSH BCSave the BASIC line number in BC to the stack.
2B50EX (SP),HLExchange the value of the memory pointer in HL with the value of the BASIC line number to the stack.
2B51EX DE,HLExchange the value of the BASIC line number in HL with the value of the last BASIC line number in DE.
2B52RST 18HNow 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.
2B53POP BCGet the value of the memory pointer from the stack and put it in BC.
2B54-2B56Jump to 1A18H if the BASIC line number in DE is greater than the last BASIC line number in HL.
2B57EX (SP),HLExchange the value of the last BASIC line number in HL with the address of the next BASIC line to the stack.
2B58PUSH HLSave the address of the next BASIC line in HL to the stack.
2B59PUSH BCSave the memory pointer in BC to the stack.
2B5AEX DE,HLLoad HL with the BASIC line number in DE.
2B5B-2B5DLD (40ECH),HLSave the BASIC line number in HL.
Note: 40ECH-40EDH holds EDIT line number.
2B5E-2B60Call 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.
2B61-2B62LD A,20HLoad register A with a space.
2B63POP HLGet the value of the memory pointer from the stack and put it in HL.
2B67-2B69GOSUB to 2B7EH move the BASIC line at the location of the memory pointer in HL into the input buffer and untokenize the BASIC line.
2B6A-2B6CLD HL,(40A7H)Load HL with the starting address of the input buffer.
Note: 40A7H-40A8H holds the input Buffer pointer.
2B6D-2B6FSince 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.
2B75-2B7D – 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 41C1H.
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.
2B75LD A,(HL)Load register A with the character at the location of the memory pointer in HL.
2B76OR ACheck to see if the character in register A is an end of the string character (00H).
2B77RET ZReturn if the character in register A is an end of the string character.
2B7BINC HLBump the value of the memory pointer in HL.
2B7C-2B7DLoop back to 2B75H until all of the characters have been sent to the current output device.
2B7E-2BC5 – 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.
2B7EPUSH HLSave the BASIC line pointer in HL to the stack.
2B7F-2B81LD HL,(40A7H)Load HL with the starting address of the input buffer.
Note: 40A7H-40A8H holds the input Buffer pointer.
2B82LD B,HLoad register B with the MSB of the input buffer pointer in register H.
2B83LD C,LLoad register C with the LSB of the input buffer pointer in register L.
2B84POP HLGet the value of the BASIC line pointer from the stack and put it in HL.
*2B85-2B87JUMP to 069AH to clear A and all flags, load the data flag (at 409FH) with 0, load D with 255 (a buffer), and JUMP to 2B8DH.
Difference between M1 and M3 ROMs: This change is to the LIST command. JP 069AH in the Model III replaces LD D,0FFH followed by JR 2B8CH in the Model I.
*2B88NOPNo Operation
2B89INC BCBump the value of the input buffer pointer in BC.
2B8ADEC DDecrement the character count in register D.
2B8BRET ZReturn if 256 characters have been moved into the input buffer.
INC HLMove one byte forward in the text.
Difference between M1 and M3 ROMs: Another change to LIST. In the Model I three instructions occupied this area: LD A,(HL); OR A; INC HL. In the Model III the INC HL instruction is moved to the beginning of the three.
OR ASet the status flags to enable us to check to see if the character in register A is an end of the BASIC line character.
2B8FLD (BC),ASave the character at the location of the input buffer pointer (held in register A) to the memory location held by BC.
2B90RET ZReturn if the character in register A is an end of the BASIC line character.
Difference between M1 and M3 ROMs: The final change to LIST – a JP P,2B89H instruction in the Model I is changed to a JP 302DH instruction in the Model III.
2B98DEC BCThe 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.
2B99DEC BCDecrement the value of the input buffer pointer in BC.
2B9ADEC BCDecrement the value of the input buffer pointer in BC.
2B9BDEC BCDecrement the value of the input buffer pointer in BC.
2B9CINC DBump the value of the character counter in register D.
2B9DINC DBump the value of the character counter in register D.
2B9EINC DBump the value of the character counter in register D.
2B9FINC DBump the value of the character counter in register D.
2BA0-2BA1CP 95HCheck to see if the character in register A is an ELSE token.
2BA2-2BA4If 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.
2BA5-2BA6SUB 7FHSubtract 7F to get the number of the entry we are looking for in token list.
2BA7PUSH HLSave the value of the BASIC line pointer in HL to the stack.
2BA8LD E,ALoad register E with the character in register A.
2BA9-2BABLD HL,1650HLoad HL with the starting address of the reserved words list.
2BACLD A,(HL)Load register A with the character at the location of the reserved words list pointer in HL.
2BADOR ATest the value of the character in register A.
2BAEINC HLBump the value of the reserved words list pointer in HL.
2BAF-2BB1Jump back to 2BACH if the character at the location of the reserved words pointer in register A doesn’t have bit 7 set.
2BB2DEC EDecrement the value of the token in register E.
2BB5-2BB6AND 7FHReset bit 7 of the character in register A by ANDing it against 0111 1111.
2BB7LD (BC),ASave the character in register A at the location of the input buffer pointer in BC.
2BB8INC BCBump the value of the input buffer pointer in BC.
2BB9DEC DDecrement the value of the character counter in register D.
2BBA-2BBCJump back to 28D8H if the maximum number of characters have been put into the input buffer.
2BBDLD A,(HL)Load register A with the character at the location of the reserved words pointer in HL.
2BBEINC HLBump the reserved words pointer in HL.
2BBFOR ATest the value of the character in register A.
2BC3POP HLGet the value of the BASIC line pointer from the stack and put it in HL.
2BC6-2BF4LEVEL II BASIC DELETE ROUTINE
2BC6-2BC8GOSUB to 1B10H to evaluate the line numbers at the location of the current BASIC program pointer in HL.
2BC9POP DEGet the value of the last BASIC line number to be deleted (in binary) from the stack and put it in DE.
2BCAPUSH BCSave the address of the first BASIC line to be deleted in BC to the stack.
2BCBPUSH BCSave the address of the first BASIC line to be deleted in BC to the stack AGAIN!.
2BCC-2BCEGOSUB 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.
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.
2BD1LD D,HLoad register D with the MSB of the last BASIC line’s address in register H.
2BD2LD E,LLoad register E with the LSB of the last BASIC line’s address in register L.
2BD3EX (SP),HLExchange the last BASIC line’s address in HL with the first BASIC line’s address to the stack.
2BD4PUSH HLSave the first BASIC line’s address in HL to the stack.
2BD5RST 18HNow 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-2BD8Display 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.
2BD9-2BDBLD HL,1929HLoad HL with the starting address of the BASIC READY message.
2BDC-2BDEWe 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).
2BDFPOP BCGet the first BASIC line’s address from the stack and put it in BC.
2BE0-2BE2LD HL,1AE8HLoad HL with the return address.
2BE3EX (SP),HLExchange the value of the return address in HL with the value of the last BASIC line’s address to the stack.
2BE4EX DE,HLLoad DE with the last BASIC line’s address in HL.
2BE5-2BE7LD 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.
2BE8LD A,(DE)Load register A with the character at the location of the memory pointer in DE.
2BE9LD (BC),ASave the character in register A at the location of the memory pointer in BC.
2BEAINC BCBump the value of the memory pointer in BC.
2BEBINC DEBump the value of the memory pointer in DE.
2BECRST 18HNow 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-2BEELoop back to 2BE8H until the memory pointer in DE equals the end of the BASIC program pointer in HL.
2BD3EX (SP),HLExchange the last BASIC line’s address in HL with the first BASIC line’s address to the stack.
2BD4PUSH HLSave the first BASIC line’s address in HL to the stack.
2BD5RST 18HNow 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-2BD8Display 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-2BDBLD HL,1929HLoad HL with the starting address of the BASIC READY message.
2BDC-2BDEWe 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).
2BDFPOP BCGet the first BASIC line’s address from the stack and put it in BC.
2BE0-2BE2LD HL,1AE8HLoad HL with the return address.
2BE3EX (SP),HLExchange the value of the return address in HL with the value of the last BASIC line’s address to the stack.
2BE4EX DE,HLLoad DE with the last BASIC line’s address in HL.
2BE5-2BE7LD 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.
2BE8LD A,(DE)Load register A with the character at the location of the memory pointer in DE.
2BE9LD (BC),ASave the character in register A at the location of the memory pointer in BC.
2BEAINC BCBump the value of the memory pointer in BC.
2BEBINC DEBump the value of the memory pointer in DE.
2BECRST 18HNow 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-2BEELoop until the memory pointer in DE equals the end of the BASIC program pointer in HL.
2BEFLD H,BLoad register H with the MSB of the memory pointer in register B.
2BF0LD L,CLoad register L with the LSB of the memory pointer in register C.
2BF1-2BF3LD (40F9H),HLSave 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.
2BF4RETReturn.
2BF5-2C1E – LEVEL II BASIC CSAVE ROUTINE
2BF5-2BF7Calls the WRITE LEADER routine at 0284H (which writes a Level II leader on the cassette unit set in register A).
2BF82BFAH 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.
2BFBPUSH HLSave 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.
2BFF-2C00LD A,D3HLoad register A with the filename header byte (=D3H which is a “S” with the sign bit on).
2C01-2C03the 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.
2C07LD A,(DE)Load register A with the first character of the filename at the location of the filename pointer in DE.
2C08-2C0Athe 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-2C0DLD 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).
2C0EEX DE,HLLoad DE with the start of the BASIC program pointer in HL.
2C0F-2C11LD 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.
2C12LD 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.
2C13INC DEBump the value of the memory pointer in DE.
2C14-2C16the 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).
2C17RST 18HNow 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-2C19Loop back to 2C12H until the memory pointer in DE is equal to the end of the BASIC program pointer in HL.
2C1DPOP HLGet the value of the current BASIC program pointer from the stack and put it in HL.
2C1ERETReturn.
2C1F-2CA4 – LEVEL II BASIC CLOAD ROUTINE
Difference between M1 and M3 ROMs:Another change that originated in the “new” ROM Model I modified the CLOAD command (changed the order of portions of the CLOAD routine, disallowed CLOAD from cassette drive #2, etc.).
2C1FSUB 0B2HTest for CLOAD?
2C23XOR ASignal CLOAD (not CLOAD?)
2C27PUSH AFIncrement HL to the filname of the CLOAD/CLOAD? flag
2C28LD A,(HL)Set the next element from the code string, which should be the filename
2C29OR ASet status flags
2C32LD A,(DE)Get the filename
2C33LD L,AMove the filename into Register L
2C34POP AFRestore the CLOAD/CLOAD? flag
2C35OR ASet the status register according to that flag
2C36LD H,AH will now hold CLOAD/CLOAD? flag, and L will hold the filename
2C37LD (4121H),HLPut the flag and filename into REG 1.
2C3DLD HL,0000HCause the drive to be selected
2C43LD HL,(4121H)Restore the CLOAD/CLOAD? flag and filename
2C46EX DE,HLLoad DE with the CLOAD/CLOAD? flag and load the filename into HL.
2C47-2C48LD B,03HLoad 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).
2C49-2C4BCalls 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).
2C4C-2C4DSUB 0D3HCheck to see if the character in register A is a filename header byte.
2C50-2C51Loop back to 2C49H until three filename header bytes (3 S’s with the sign bit on) have been read.
2C52-2C54Now 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).
2C55INC EWe 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.
2C56DEC EDecrement the value of the filename in register E.
2C59CP EIf 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.
2CA5 – “BCD” message string.
2C5A-2C5BJump 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.
2C5C-2C5ELD 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.
2C5F-2C60LD B,03HLoad register B with the number of zeros to look for to stop the load (which is 3).
2C61-2C63Calls 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).
2C64LD E,ALoad register E with the character in register A.
2C65SUB (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.
2C66AND DCombine the subtracted result in register A with the value of the CLOAD/CLOAD? flag in register D.
2C69LD (HL),EAt 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.
2C6DLD A,(HL)Load register A with the character at the location of the memory pointer in HL.
2C6EOR ACheck to see if the byte just read in register A is equal to zero.
2C6FINC HLBump the value of the memory pointer in HL.
2C70-2C71Loop if the byte in register A isn’t equal to zero (meaning that it isn’t end of program or end of statement).
2C72-2C74Call the BLINK ASTERISK routine at 022CH which alternatively displays and clears an asterisk in the upper right hand corner of the video display.
2C75-2C76Do that loop until three zeros in a row have been read from the cassette recorder.
2C77-2C79LD (40F9H),HLBy 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-2C7CGOSUB to 01F8H to turn off the tape.
Difference between M1 and M3 ROMs: Also part of CLOAD, this change turns off the tape before printing READY on the video display. In the Model I, the code from 2C7AH – 2C82H consisted of the instructions LD HL,1929H; CALL 28A7H, CALL 01F8H. In the Model III the CALL to 01F8H has been moved to the beginning of these instructions.
*2C7D-2C7FLD HL,1929HLoad HL with the starting address of the BASIC READY message.
*2C80-2C82We 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).
2C83-2C85LD 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).
2C86PUSH HLSave the start of the BASIC program pointer in HL to the stack.
*2C8A-2C8CGOSUB to 31BDH to reset the cassette I/O.
Difference between M1 and M3 ROMs: This is part of the CLOAD? routine used when a bad byte has been read from the tape. In the Model I, a LD HL, 2CA5H instruction is found here (loads HL with the starting address of the “BAD” message), while the Model III uses a CALL 31BDH instruction, which does some housekeeping in addition to pointing HL to the “BAD” message.
2C8D-2C8FWe 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).
2C93-2C95LD (3C3EH),AGo display the filename on the video display.
2C96-2C97LD B,03HLoad register B with the number of zeros to be found to stop the search.
2C98-2C9ACalls 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).
2C9BOR ACheck to see if the character in register A is equal to zero.
2CA0-2CA2Calls 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).
2CA5-2CA9 – MESSAGE STORAGE LOCATION
2CA5-2CA9“BAD”The BAD message is stored here.
2CAA-2CB0 – LEVEL II BASIC PEEK ROUTINE – On entry, REG 1 to have the peek location, and on exit Reg 1 to have the peeked value.
2CAA-2CACCall 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).
2CADLD A,(HL)Load register A with the value at the location of the memory pointer in HL.
2CB1-2CBC – LEVEL II BASIC POKE ROUTINE
2CB1-2CB3Go evaluate the expression at the location of the current BASIC program pointer in HL and return with the integer result in DE.
2CB4PUSH DESave the address the user wants to POKE to (held in DE) to the stack.
2CB5-2CB6RST 08H
2ESince 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).
2CB7-2CB9GOSUB 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.
2CBAPOP DEGet the address the user wants to POKE to from the stack and put it in DE.
2CBBLD (DE),ASave the value the user wanted to poke (held in register A) in the location that the user wants to POKE to (held in DE).
2CBCRETReturn.
2CBD-2E52 – LEVEL II BASIC USING ROUTINE
2CBD-2CBFGo evaluate the string expression at the location of the current BASIC program pointer in HL.
2CC3-2CC4RST 08H
3BSince 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).
2CC5EX DE,HLLoad DE with the value of the current BASIC program pointer in HL.
2CC6-2CC8LD HL,(4121H)Load HL with the USING string’s VARPTR.
2CCB-2CCDLD A,(40DEH)Load register A with the value of the READ/INPUT flag.
Note: 40DEH holds READ flag.
2CCEOR ACheck to see if the READ/INPUT flag in register A indicates INPUT.
2CD1POP DERestore the current BASIC program pointer (from the stack) into DE.
2CD2EX DE,HLLoad HL with the value of the current BASIC program pointer in DE. D will wind up being the length of the string
2CD3PUSH HLSave the USING string’s VARPTR in HL to the stack.
2CD4XOR AZero register A.
2CD5-2CD7LD (40DEH),AClear the READ/INPUT flag.
Note: 40DEH holds READ flag.
2CD8CP DCheck to see if the value in D is equal to zero (by checking it against A which was XOR’d to 0 above).
2CD9PUSH AFSave the value in AF (the difference) to the stack.
2CDAPUSH DESave the value in DE (the address of the next input symbol from the code string) to the stack.
2CDBLD B,(HL)Load register B with the USING string’s length at the location of the USING string’s VARPTR in HL.
2CDCOR BCheck to see if the USING string’s length in register B is equal to zero.
2CE0INC HLBump the value of the USING string’s VARPTR in HL.
2CE1LD 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.
2CE2INC HLBump the value of the USING string’s VARPTR in HL.
2CE3LD 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.
2CE4LD L,CLoad register L with the LSB of the USING string’s address in register C.
2CE7LD E,BLoad register E with the USING string’s length in register B.
2CE8PUSH HLSave the value of the current USING string pointer in HL.
2CE9-2CEALD C,02HLoad register C with the number of %’s substring length.
2CEBLD A,(HL)Load register A with the character at the location of the USING string pointer in HL.
2CECINC HLBump the value of the USING string pointer in HL.
2CED-2CEECP 25HCheck to see if the character in register A is a %.
2CF2-2CF3CP 20HCheck to see if the character in register A is a space.
2CF6INC CBump the % substring length in register C.
2CF9POP HLAt 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.
2CFALD B,ELoad register B with the USING string’s length.
2CFB-2CFCLD A,25HLoad register A with a %.
2D03XOR AZero register A and clear the flags.
2D04LD E,AZero register E.
2D05LD D,AZero register D.
2D09LD D,AZero register D.
2D0ALD A,(HL)Load register A with the character (i.e., the field description) at the location of the USING string pointer in HL.
2D0BINC HLBump the value of the USING string pointer in HL.
2D0C-2D0DCP 21HCheck to see if the character in register A is a !.
2D11-2D12CP 23HCheck to see if the character in register A is a #.
2D15DEC BDecrement the value of the string’s length in register B.
2D19-2D1ACP 2BHCheck to see if the character in register A is a +.
2D1B-2D1CLD A,08HSet the flag in register A to force a leading +.
2D1FDEC HLDecrement the value of the USING string pointer in HL.
2D20LD A,(HL)Load register A with the character at the location of the USING string pointer in HL.
2D21INC HLBump the value of the USING string pointer in HL.
2D22-2D23CP 2EHCheck to see if the character in register A is a ..
2D26-2D27CP 25HCheck to see if the character in register A is a %.
2D2ACP (HL)Compare the character in register A with the character at the location of the USING string pointer in HL.
2D2B-2D2CJump if the character in register A isn’t equal to the character at the location of the USING string pointer in HL.
2D2D-2D2ECP 24HCheck to see if the character in register A is a $.
2D31-2D32CP 2AHCheck to see if the character in register A is a *.
2D35LD A,BLoad register A with the USING string’s length in register B.
2D36-2D37CP 02HCheck to see if the USING string’s length in register A is at least two.
2D38INC HLBump the value of the USING string pointer in HL.
2D3BLD A,(HL)Load register A with the character at the location of the USING string pointer in HL.
2D3C-2D3DCP 24HCheck to see if the character in register A is a string.
2D3E-2D3FLD A,20HSet the ** edit flag in register A.
2D42DEC BDecrement the value of the USING string’s length in register.
2D43INC EBump the number of characters to the left of the decimal point in register E.
2D44-2D45FE AFZ-80 Trick to skip over a XOR A if passing through by processing it as a CP AFH.
2D45XOR AThis is $ processing for PRINT USING.
2D46-2D47ADD A,10HMask the value of the edit flag in register A for leading $‘s.
2D48INC HLBump the value of the USING string pointer in HL.
2D49INC EBump the number of characters to the left of the decimal point in register E.
2D4AADD A,DCombine the value of the edit flag in register D with the value of the edit flag in register A.
2D4BLD D,ALoad register D with the value of the edit flag in register A.
2D4CINC EBump the number of characters to the left of the decimal point in register E.
2D4D-2D4ELD C,00HZero the number of characters to the right of the decimal point in register C.
2D4FDEC BDecrement the value of the string’s length in register B.
2D52LD A,(HL)Load register A with the character at the location of the USING string pointer in HL.
2D53INC HLBump the value of the USING string pointer in HL.
2D54-2D55CP 2EHCheck to see if the character in register A is a ..
2D58-2D59CP 23HCheck to see if the character in register A is a #.
2D5C-2D5DCP 2CHCheck to see if the character in register A is a ,.
2D60LD A,DLoad register A with the value of the edit flag in register D.
2D61-2D62OR 40HMask the edit flag in register A for ,.
2D63LD D,ALoad register D with the value of the edit flag in register A.
2D66LD A,(HL)Load register A with the character at the location of the USING string pointer in HL.
2D67-2D68CP 23HCheck to see if the character in register A is a #.
2D69-2D6ALD A,2EHLoad register A with a decimal point.
2D6D-2D6ELD C,01HLoad register C with the number of characters to the right of the decimal point.
2D6FINC HLBump the value of the USING string pointer in HL.
2D70INC CBump the number of characters to the right of the decimal point in register C.
2D71DEC BDecrement the value of the string’s length in register B.
2D74LD A,(HL)Load register A with the character at the location of the USING string pointer in HL.
2D75INC HLBump the value of the USING string pointer in HL.
2D76-2D77CP 23HCheck to see if the character in register A is a #.
2D7APUSH DESave the value of the edit flag and the count of the characters to the left of the decimal point in DE to the stack.
2D7B-2D7DLD DE,2D97HLoad DE with the return address.
2D7EPUSH DESave the value of the return address in DE to the stack.
2D7FLD D,HLoad register D with the MSB of the USING string pointer m register H.
2D80LD E,LLoad register E with the LSB of the USING string pointer in register L.
2D81-2D82CP 5BHCheck to see if the character in register A is an up arrow.
2D83RET NZReturn if the character in register A isn’t an up arrow.
CP (HL)Check to see if the character at the location of the USING string pointer in HL is an up arrow.
2D85RET NZReturn 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).
2D87CP (HL)Check to see if there is a third up arrow at the location of the USING string pointer in HL.
2D88RET NZReturn 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).
2D8ACP (HL)Check to see if the character at the location of the USING string pointer in HL is a fourth up arrow.
2D8BRET NZReturn 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).
INC HLBump the value of the USING string pointer in HL. If we are here we have a #.##[[[[ format.
2D8DLD A,BLoad register A with the value of the USING string’s length in register B.
2D8E-2D8FSUB 04HCheck to see if there are at least 4 characters left in the USING string.
2D90RET CReturn to 2D97 if there aren’t at least four characters left in the USING string.
2D92POP DEGet the edit flag and the count of the characters to the left of the decimal point from the stack and put it in DE.
2D93LD B,ALoad register B with the USING string’s length in register A.
2D94INC DSet the exponential notation flag in register D.
2D95INC HLBump the value of the USING string pointer in HL.
2D96CAZ-80 Trick! By putting the CA opcode here, the next 2 bytes are ignored if passing through, but remain in effect if jumped to.
2D97EX DE,HL(Ignored if passing through) Load HL with the value of the USING string pointer in DE.
2D98POP 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.
2D99LD A,DLoad register A with the value of the edit flag in register D.
2D9ADEC HLDecrement the value of the USING string pointer in HL.
2D9BINC EBump the number of characters to the left of the decimal point in register E.
2D9C-2D9DAND 08HCheck to see if the sign flag is set in register A.
2DA0DEC EDecrement the number of characters to the left of the decimal point in register E.
2DA1LD A,BLoad register A with the USING string’s length in register B.
2DA2OR ACheck to see if this is the end of the string.
2DA5LD A,(HL)Load register A with the character at the location of the USING string pointer in HL.
2DA6-2DA7SUB 2DHCheck to see if the character in register A is a – .
2DAA-2DABCP 0FEHCheck to see if the character in register A is a +.
2DAE-2DAFLD A,08HSet the edit flag for a + character.
2DB0-2DB1ADD A,04HSet the edit flag for a – character.
2DB2ADD A,DCombine the value of the edit flag in register D with the value of the edit flag in register A.
2DB3LD D,ALoad register D with the value of the edit flag in register A.
2DB4DEC BDecrement the value of the USING string’s length in register B.
2DB5POP HLGet the value of the current BASIC program pointer from the stack and put it in HL.
2DB6POP AFLoad register A with the character at the location of the current BASIC program pointer in HL.
2DB9PUSH BCSave the count of the characters to the right of the decimal point and the USING string’s length in BC to the stack.
2DBAPUSH DESave the edit flag and the number of characters to the left of the decimal point in DE to the stack.
2DBB-2DBDGo evaluate the expression at the location of the current BASIC program pointer and return with the result in REG 1.
2DBEPOP DEGet the edit flag and the number of characters to the left of the decimal point from the stack and put it in DE.
2DBFPOP BCGet 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.
2DC0PUSH BCSave the number of characters to the right of the decimal point and the USING string’s length m BC to the stack.
2DC1PUSH HLSave the value of the current BASIC program pointer in HL to the stack.
2DC2LD B,ELoad register B with the number of characters to the left of the decimal point in register E.
2DC3LD A,BLoad register A with the number of characters to the left of the decimal point in register B.
2DC4ADD A,CAdd 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.
2DC5-2DC6CP 19HCheck to see if the total number of characters in register A is greater than 24.
2DC7-2DC9Display a FC ERROR message if the total number of characters in register A is greater than 24.
2DCALD A,DLoad register A with the value of the edit flag in register D.
2DCB-2DCCOR 80HSet the edit flag in register A.
2DCD-2DCFCall 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.
2DD0-2DD2We 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).
2DD3POP HLGet the value of the current BASIC program pointer from the stack and put it in HL.
2DD4DEC HLDecrement the value of the current BASIC program pointer in HL.
2DD5RST 10HWe 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.
2DD6SCFSet the Carry flag.
2DD7-2DD8Jump if the character at the location of the current BASIC program pointer in register A is an end of the BASIC statement character.
2DD9-2DDBLD (40DEH),ASave the character at the location of the current BASIC program pointer in register A.
Note: 40DEH holds READ flag.
2DDC-2DDDCP 3BHCheck to see if the character at the location of the current BASIC program pointer in register A is a semicolon.
2DDE-2DDFJump if the character at the location of the current BASIC program pointer in register A is a semicolon.
2DE0-2DE1CP 2CHCheck to see if the character at the location of the current BASIC program pointer in register A is a comma.
2DE2-2DE4Go 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.
2DE5RST 10HWe 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.
2DE6POP BCGet the USING string’s length from the stack and put it in register B.
2DE7EX DE,HLLoad DE with the value of the current BASIC program pointer in HL.
2DE8POP HLGet the USING string’s VARPTR from the stack and put it in HL.
2DE9PUSH HLSave the USING string’s VARPTR in HL to the stack.
2DEAPUSH AFSave the character at the location of the current BASIC program pointer in register A to the stack.
2DEBPUSH DESave the value of the current BASIC program pointer in DE to the stack.
2DECLD A,(HL)Load register A with the USING string’s length at the location of the USING string’s VARPTR in HL.
2DEDSUB BCompare the USING string’s length in register B with the USING string’s length in register A.
2DEEINC HLBump the value of the USING string’s VARPTR in HL.
2DEFLD 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.
2DF0INC HLBump the value of the USING string’s VARPTR in HL.
2DF1LD 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.
2DF2LD L,CLoad register L with the LSB of the USING string’s address in register C.
2DF3-2DF4LD D,00HZero register D.
2DF5LD E,ALoad register E with the USING string’s offset in register A.
2DF6ADD HL,DEAdd the USING string’s offset in DE to the USING string’s address in HL.
2DF7LD A,BLoad register A with the USING string’s length in register B.
2DF8OR ACheck to see if this is the end of the USING string.
2E04POP HLGet the value of the current BASIC program pointer from the stack and put it in HL.
2E05POP AFGet the character at the location of the current BASIC program pointer from the stack and put it in register A.
GOSUB to 20FEH to send a carriage return to the current output device if necessary.
2E0CEX (SP),HLExchange the value of the current BASIC program pointer in HL with the value of the USING string’s VARPTR to the stack.
2E10POP HLGet the value of the current BASIC program pointer from the stack and put it in HL.
LD C,01HContinue processing a ! in the USING format by loading register C with the number of characters to be printed.
2E16-2E173E F1Z-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.
2E17POP AF(Skipped if passing down) Clear the stack.
2E18DEC BDecrement the value of the string’s length in register B.
2E1CPOP HLGet the value of the current BASIC program pointer from the stack and put it in HL.
2E1DPOP AFGet the character at the location of the current BASIC program pointer from the stack and put it in register A.
2E1E-2E1FJump 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.
2E20PUSH BCSave the USING string’s length and the number of characters to be printed in BC to the stack.
2E21-2E23Go evaluate the expression at the location of the current BASIC program pointer in HL and return with the result in REG 1
2E27POP BCGet the USING string’s length and the number of characters to be printed from the stack and put it in BC.
2E28PUSH BCSave the USING string’s length and the number of characters to be printed in BC to the stack.
2E29PUSH HLSave the value of the current BASIC program pointer in HL to the stack.
2E2A-2E2CLD HL,(4121H)Load HL with the string’s VARPTR in REG 1.
2E2DLD B,CLoad register B with the number of characters to be printed in register C.
2E2E-2E2FLD C,00HZero register C.
2E30PUSH BCSave the length of the string to be printed in register B to the stack.
2E37-2E39LD HL,(4121H)Load HL with the string’s VARPTR in REG 1.
2E3APOP AFGet the length of the string to be printed from the stack and put it in register A.
2E3BSUB (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.
2EJCLD B,ALoad register B with the number of spaces to be printed in register A.
2EJD-2EJELD A,20HLoad register A with a space.
2E3FINC BBump the number of spaces in register B.This loop will print all the spaces needed and then jump to 2DD3H.
2E49PUSH AFSave the value in register A to the stack.
2E4ALD A,DLoad register A with the value in register D.
2E4BOR ACheck to see if register A is equal to zero.
2E4C-2E4DLD A,2BHLoad register A with a +.
2E51POP AFGet the value from the stack and put it in register A.
2E52RETReturn.
2E53-2FFA – LEVEL II BASIC EDIT ROUTINE
2E53-2E55LD (409AH),AReset the error flag.
Note: 409AH holds the RESUME flag.
2E56-2E58LD HL,(40EAH)Load HL with the line number where the error occurred.
Note: 40EAH-40EBH holds the line number with error.
2E59OR HOR register A with the MSB of the error line number in register H.
2E5AAND LCombine 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.
2E5BINC ABump the combined value of the error line number in register A. If execution had not begin, this will turn A from FFH into 00H
2E5CEX DE,HLLoad DE with the line number with the error (held in HL).
2E5DRET ZIf there was no line number, return if Level II BASIC.
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.
2E63RET NZIf the zero flag got set, there was no line number, so return.
2E65EX DE,HLLoad HL with the line number to be edited in DE.
2E66-2E68LD (40ECH),HLSave 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.
2E69EX DE,HLLoad DE with the line number to be edited in HL.
2E6A-2E6CCall 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.
2E70LD H,BAt this point, the line number has been found. Load register H with the MSB of the memory pointer in register B.
2E71LD L,CLoad register L with the LSB of the memory pointer in register C.
2E72INC HLBump the value of the memory pointer in HL.
2E73INC HLBump the value of the memory pointer in HL.
2E74LD C,(HL)Load register C with the LSB of the BASIC line number at the location of the memory pointer in HL.
2E75INC HLBump the value of the memory pointer in HL.
2E76LD B,(HL)Load register B with the MSB of the BASIC line number at the location of the memory pointer in HL.
2E77INC HLBump the value of the memory pointer in HL.
2E78PUSH BCSave the value of the BASIC line number in BC to the stack.
2E7CPOP HLGet the value of the BASIC line number from the stack and put it in HL.
2E7DPUSH HLSave the value of the BASIC line number in HL to the stack.
2E7E-2E80Convert 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).
2E81-2E82LD A,20HLoad register A with a space.
2E86-2E88LD 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.
2E89-2E8ALD A,0EHLoad register A with the “turn on the cursor” character.
2E8EPUSH HLSave the value of the input buffer pointer (in HL) to the stack.
2E8F-2E90LD C,FFHLoad 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.
2E91INC CBump the number of characters examined so far in register C.
2E92LD A,(HL)Load register A with the character at the location of the input buffer pointer in HL.
2E93OR ACheck to see if the character in register A is an end of the BASIC line character.
2E94INC HLBump the value of the input buffer pointer in HL.
2E97POP HLAt this point, C will be the maximum number of characters in the line at issue. Put the start of the expended buffer into HL.
2E98LD B,AZero register B. B will ultimately contain the count of characters inserted.
2E99-2E9ALD D,00HZero register D.
2D9E-2E9FSUB 30HWe need to test to see if the character was alphabetic or alphanumeric so we subtract 30H from it.
2EA2-2EA3CP 0AHCheck to see if the character is register A is numeric.
2EA6LD E,ALoad register E with the binary value of the character in register A.
2EA7LD A,DLoad register A with the value in register D.
2EA8RLCAMultiply the value in register A by two (so now A has multiplied by 2).
2EA9RLCAMultiply the value in register A by two (so now A has multiplied by 4).
2EAAADD A,DAdd the value in register D to the value in register A (so now A has multiplied by 5).
2EABRLCAMultiply the value in register A by two (so now A has multiplied by 10).
2EACADD A,EAdd the value in register E to the value in register A.
2EADLD D,ALoad register D with the value in register A.
2EB0PUSH HLSave the value of the input buffer pointer in HL to the stack.
2EB1-2EB3LD HL,2E99HLoad HL with the return address of 2E99H.
2EB4EX (SP),HLExchange the value of the return address in HL with the value of the input buffer pointer to the stack.
2EB5DEC DWe 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 …
2EB6INC D… and then incrementing the numeric value in register D.
2EB7-2EB9Jump to 2EBBH if a numeric value preceded the command (i.e., register D isn’t equal to zero).
2EBAINC DLoad register D with a one.
2EBB-2EBCCP 0D8HCheck to see if the character in register A is a backspace character.
2EC0-2EC1CP 0DDHCheck to see if the character in register A is a carriage return.
2EC5-2EC6CP 0F0HCheck to see if the character in register A is a space.
2EC9-2ECACP 31HCheck to see if the character in register A is lowercase.
2ECD-2ECESUB 20HConvert the lowercase character in register A to uppercase.
2ECF-2ED0CP 21HCheck to see if the character in register A is a Q.
2ED4-2ED5CP 1CHCheck to see if the character in register A is an L.
2ED9-2EDACP 23HCheck to see if the character in register A is an S.
2EDD-2EDECP 19HCheck to see if the character in register A is an I.
2EE2-2EE3CP 14HCheck to see if the character in register A is a D.
2EE7-2EE8CP 13HCheck to see if the character in register A is a C.
2EEC-2EEDCP 15HCheck to see if the character in register A is an E.
2EF1-2EF2CP 28HCheck to see if the character in register A is an X.
2EF6-2EF7CP 1BHCheck to see if the character in register A is a K.
2EFA-2EFBCP 18HCheck to see if the character in register A is an H.
2EFF-2F00CP 11HCheck to see if the character in register A is an A.
2F01RET NZReturn if the character in register A isn’t an A.
2F02 – EDIT Command – Cancel and Restore Logic.
2F03POP DEGet the BASIC line number from the stack and put it in DE.
2F0A – 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.
2F0ALD A,(HL)Load register A with the character at the location of the input buffer pointer in HL.
2F0BOR ACheck to see if the character in register A is an end of the BASIC line character.
2F0CRET ZReturn if the character in register A is an end of the BASIC line character.
2F11INC HLBump the value of the input buffer pointer in HL.
2F12DEC DDecrement the number of times to perform the operation in register D.
2F15RETReturn.
2F16 – EDIT Command – KILL Logic.
2F16PUSH HLSave the value of the input buffer pointer in HL to the stack.
2F17-2F19LD HL,2F5FHLoad HL with the return address of 2F5FH (which will print the final !).
2F1AEX (SP),HLExchange the value of the return address in HL with the value of the input buffer pointer to the stack.
2F1BSCFSet the KILL/SEARCH flag for KILL since CARRY flag signals KILL.
2F1CPUSH AFSave the KILL/SEARCH flag to the stack.
2F20LD E,ALoad register E with the character to locate in register A.
2F21POP AFGet the KILL/SEARCH flag from the stack.
2F22PUSH AFSave the KILL/SEARCH flag to the stack.
2F26LD A,(HL)Load register A with the character at the location of the input buffer pointer in HL.
2F27OR ACheck to see if the character in register A is an end of the BASIC line character.
2F28-2F2AJump down to 2F3EH if the character in register A is an end of the BASIC line character.
2F2EPOP AFGet the KILL/SEARCH flag from the stack.
2F2FPUSH AFSave the KILL/SEARCH flag to the stack.
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.
2F35INC HLIf we are here, it must be SEARCH! So bump to the next character.
2F36INC BBump the value of the character position counter in register B.
2F37LD 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.
2F38CP ECheck to see if the character in register A is the same as the character to be located in register E.
2F3BDEC DDecrement the number of times to perform the operation in register D.
2F3EPOP AFGet the KILL/SEARCH flag from the stack.
2F3FRETReturn.
2F40 – EDIT Command – LIST Logic.
2F40-2F42Since 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..
2F46POP BCGet the BASIC line number from the stack and put it in BC.
2F4A – EDIT Command – DELETE Logic.
2F4ALD A,(HL)Load register A with the character at the location of the input buffer pointer in HL.
2F4BOR ACheck to see if the character in register A is an end of the BASIC line character.
2F5CRET ZReturn if the character in register A is an end of the BASIC line character.
2F52LD A,(HL)Load register A with the character at the location of the input buffer pointer in HL.
2F53OR ACheck to see if the character in register A is an end of the BASIC line character.
2F54-2F5BJump to 2F5FH if the character in register A is an end of the BASIC line character.
2F5CDEC DDecrement the number of times to perform the operation in register D.
2F5F-2F60LD A,21HLoad register A with an !.
2F64RETReturn.
2F65 – EDIT Command – CHANGE Logic.
2F65LD A,(HL)Load register A with the character at the location of the input buffer pointer in HL.
2F66OR ACheck to see if the character in register A is an end of the BASIC line character.
2F67RET ZReturn if the character in register A is an end of the BASIC line character.
2F6BLD (HL),ASave the character in register A at the memory location of the input buffer pointer in HL.
2F6FINC HLBump the value of the input buffer pointer in HL.
2F70INC BBump the character position in register B.
2F71DEC DDecrement the number of times to perform the operation in register D.
2F74RETReturn.
2F75 – EDIT Command – HACK/INSERT Logic.
2F75-2F76LD (HL),00HZero the location of the input buffer pointer in HL.
2F77LD C,BLoad register C with the character position in register B.
2F78-2F79LD D,0FFHLoad register D with the number of times to perform the operation.
2F80OR ACheck to see if a key was pressed.
2F84-2F85CP 08HCheck to see if the character in register A is a backspace character.
2F88-2F89CP 0DHCheck to see if the character in register A is a carriage return.
2F8D-2F8ECP 1BHCheck to see if the character in register A is a shift up arrow.
2F8FRET ZReturn if the character in register A is shift up arrow.
2F92 – EDIT Command – BACKSPACE CURSOR Logic.
2F92-2F93LD A,08HLoad register A with a backspace the cursor character.
2F94DEC BDecrement the character position in register B.
2F95INC BBump the character position in register B.
2F9BDEC HLDecrement the value of the input buffer pointer in HL.
2F9CDEC BDecrement the character position in register B.
2F9D-2F9FLD DE,2F7DHLoad DE with a return address of 2F7DH.
2FA0PUSH DESave the value of the return address in DE to the stack.
2FA1PUSH HLSave the value of the input buffer pointer in HL to the stack.
2FA2DEC CDecrement the character position in register C.
2FA3LD A,(HL)Load register A with the character at the location of the input buffer pointer in HL.
2FA4OR ACheck to see if the character in register A is an end of the BASIC line character.
2FA5SCFSet the Carry flag to signal that the character was deleted.
2FA6-2FA8Jump to 0890H if the character in register A is an end of the BASIC line character.
2FA9INC HLBump the value of the input buffer pointer in HL.
2FAALD A,(HL)Load register A with the character at the location of the input buffer pointer in HL.
2FABDEC HLDecrement the value of the input buffer pointer in HL.
2FACLD (HL),ASave the character in register A at the location of the current input buffer pointer in HL.
2FADINC HLBump the value of the input buffer pointer in HL.
2FB0 – EDIT Command – ADD A CHARACTER Logic.
2FB0PUSH AFSave the character to be inserted in register A to the stack.
2FB1LD A,CLoad register A with the number of characters in the input buffer in register C.
2FB2-2FB3CP FFHCheck for the maximum BASIC line length.
2FB6POP AFGet the character to be inserted from the stack and put it in register A.
2FB9SUB BSubtract 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.
2FBAINC CBump the number of characters in the input buffer in register C.
2FBBINC BBump the character position in register B.
2FBCPUSH BCSave the character position and the number of characters in the input buffer in BC to the stack.
2FBDEX DE,HLLoad DE with the input buffer pointer in HL.
2FBELD L,ALoad register L with the character count in register A.
2FBF-2FC0LD H,00HZero register H.
2FC1ADD HL,DEAdd the value of the input buffer pointer in DE to the character count in HL.
2FC2LD B,HLoad register B with the MSB of the end of the BASIC line pointer in register H.
2FC3LD C,LLoad register C with the LSB of the end of the BASIC line pointer in register L.
2FC4INC HLBump the value of the end of the BASIC line pointer in HL.
2FC8POP BCGet the character position and the number of characters in the input buffer from the stack and put it in BC.
2FC9POP AFGet the character to be inserted from the stack and put it in register A.
2FCALD (HL),ASave the character in register A at the location of the current input buffer pointer in HL.
2FCEINC HLBump the value of the input buffer pointer in HL.
2FD2 – EDIT Command – BACKSPACE Logic.
2FD2LD A,BLoad register A with the number of times to backspace in register B.
2FD3OR ACheck to see if this is the start of the BASIC line.
2FD4RET ZReturn if this is the start of the BASIC line.
2FD6DEC HLDecrement the value of the input buffer pointer in HL.
2FD7-2FD8LD A,08HLoad register A with a backspace the cursor character.
2FDCDEC DDecrement the number of times to perform the operation in register D.
2FDFRETReturn.
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..
2FE6POP BCClean up the stack.
2FE7POP DEGet the BASIC line number (in binary) from the stack and put it in DE.
2FE8LD A,DLoad register A with the MSB of the BASIC line number in register D.
2FE9AND ECombine the LSB of the BASIC line number in register E with the MSB of the BASIC line number in register A.
2FEAINC ABump the combined BASIC line number in register A.
2FEB-2FEDLD HL,(40A7H)Load HL with the starting address of the input buffer.
Note: 40A7H-40A8H holds the input Buffer pointer.
2FEEDEC HLDecrement the value of the input buffer pointer in HL.
2FEFRET ZReturn if this is the Level II BASIC command mode.
2FF1INC HLBump the value of the input buffer pointer in HL.
2FF2PUSH AFSave the command mode flag in AF to the stack.
2FF6 – EDIT Command – QUIT Logic.
2FF6POP BCClean up the stack.
2FF7POP DEGet the BASIC line number from the stack and put it in DE.
2FFB-2FFFDEC3C344B2Garbage Code.
2008-2038 – LEVEL II BASIC AUTO ROUTINE
2C
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).
Note: 40E4H-40E5H holds AUTO increment.
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
Note: 40E4H-40E5H holds AUTO increment.
Note: 40E2H-40E3H holds Current BASIC line number.
2039-2066 – LEVEL II BASIC IF ROUTINE
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.
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.
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.
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.
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.
2067-206E – LEVEL II BASIC LPRINT ROUTINE
- Note: 409CH holds the current output device flag:
- -1=cassette,
- 0=video; or
- 1=printer.
Differences between M1 and M3 ROMs: All of the changes from 206DH – 20F7H first appeared in the “new” ROMs of the Model I. The changes were made to allow the use of multiple @’s in a PRINT statement.
206F-2177 – LEVEL II BASIC PRINT ROUTINE
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.
- 4020H-4021H: Holds the video memory address of the current cursor position.
2C
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).
2C
- NOTE: A CP will return Z if there is a match against Register A, and NZ if not a match against Register A.)
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.
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.
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.
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.
- Note: 409CH holds the current output device flag:
- -1=cassette,
- 0=video; or
- 1=printer.
Note: 409BH holds the printer carriage position.
- NOTE: A CP will return Z if there is a match against Register A, and NZ if not a match against Register A.)
Note: 409DH holds the size of line on the video display.
Note: 40A6H holds the current cursor line position.
- NOTE: A CP will return Z if there is a match against Register A, and NZ if not a match against Register A.)
Note: 40A6H holds the current cursor line position.
20FE – 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.
In NEWDOS 2.1, this is called when skipping to next line on a video during a BASIC output operation.
2108 – This is the jump point for a continuation of the PRINT# code.
In NEWDOS 2.1, this is called at the start of PRINT on cassette and during PRINT TAB.
- Note: 409CH holds the current output device flag:
- -1=cassette,
- 0=video; or
- 1=printer.
- M will be set if the value in A is negative.
- P will be set if the value in A is positive or zero.
Note: 409BH holds the printer carriage position.
- NOTE: A CP will return Z if there is a match against Register A, and NZ if not a match against Register A.)
Note: 409EH holds the size of line on the printer.
Note: 40A6H holds the current cursor line position.
- NOTE: A CP will return Z if there is a match against Register A, and NZ if not a match against Register A.)
2137 – 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”. 2169 – 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.
Difference between M1 and M3 ROMs: This also first appeared in the “new” ROMs of the Model I, as part of an AND 7FH instruction located at 213AH. In the original version the instruction was AND 3FH. The operand of the instruction sets the maximum argument for the TAB function, thus the early TRS-80’s could only handle a maximum TAB (63) while the latest Models can go as high as TAB (127).
29
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).
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.
- Note: 409CH holds the current output device flag:
- -1=cassette,
- 0=video; or
- 1=printer.
Note: 409BH holds the printer carriage position.
Note: 40A6H holds the current cursor line position.
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.
Difference between M1 and M3 ROMs: This corrects a jump back into the revised PRINT command routine.
2169 – 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.
- Note: 409CH holds the current output device flag:
- -1=cassette,
- 0=video; or
- 1=printer.
- Note: 409CH holds the current output device flag:
- -1=cassette,
- 0=video; or
- 1=printer.
In NEWDOS 2.1, this initializes the system output device.
2178-217E – MESSAGE STORAGE LOCATION FOR REDO MESSAGE
217F-2285 – LEVEL II BASIC INPUT AND READ ROUTINES
Note: 40DEH holds READ flag.
Note: 40A9H holds Cassette input flag.
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).
Note: 40E6H-40E7H holds Temporary storage location.
219A – INPUT logic
In NEWDOS 2.1 this is called at the beginning of INPUT processing.
Note: 40A9H holds cassette input flag.
Note: 40A7H-40A8H holds the input Buffer pointer.
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.
Note: 40A7H-40A8H holds the input Buffer pointer.
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.
3B
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).
21EF – READ logic
Note: 40FFH-4100H holds READ pointer.
Note: 40DEH holds READ flag.
2C
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).
- NOTE: A CP will return Z if there is a match against Register A, and NZ if not a match against Register A.)
Note: 40DEH holds READ flag.
Note: 40A9H holds Cassette input flag.
In NEWDOS 2.1, this is called during READ processing when a variable has been read.
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.
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.
- NOTE: A CP will return Z if there is a match against Register A, and NZ if not a match against Register A.)
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.
- NOTE: 0E65H converts the ASCII string pointed to by HL to its double precision equivalent; with output left in REG 1).
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.
- NOTE: A CP will return Z if there is a match against Register A, and NZ if not a match against Register A.)
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.
226A-226E – For ROM v1.2 – Replaced with NOPS
Note: 40DEH holds READ flag.
In NEWDOS 2.1 this is called at the end of READ processing.
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).
2286-2295 – MESSAGE STORAGE LOCATION
2296-22B5 – FIND THE NEXT DATA STATEMENT ROUTINE
Note: 40DAH-40DBH holds DATA line number.
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.
- NOTE: A CP will return Z if there is a match against Register A, and NZ if not a match against Register A.)
22B6-2336 – LEVEL II BASIC NEXT ROUTINE
Note: 40DFH-40E0H holds Used by DOS.
Note: 40E8H-40E9H holds Stack pointer pointer.
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.
Note: 40AFH holds Current number type flag.
- NOTE: A CP will return Z if there is a match against Register A, and NZ if not a match against Register A.)
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.
- Note: 40A2H-40A3H holds the current BASIC line number.
Note: 40E8H-40E9H holds Stack pointer pointer.
Note: 40DFH-40E0H holds Used by DOS.
- NOTE: A CP will return Z if there is a match against Register A, and NZ if not a match against Register A.)
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.
28
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).
2337-27C8 – 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.
Note: 40F3H-40F4H holds temporary storage location.
Note: 40F3H-40F4H holds temporary storage location.
- NOTE: A CP will return Z if there is a match against Register A, and NZ if not a match against Register A.)
Note: 40D8H-40D9H holds Temporary storage location.
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.
Note: 40D8H-40D9H holds Temporary storage location.
E Token
0 +
1 –
2 *
3 /
4 @@
5 AND
6 OR
Note: 40AFH holds Current number type flag.
2377 – PRINT @ logic.
Note: 40AFH holds Current number type flag.
Note: 411DH-4124H holds REG l.
06 F1
Note: 40D8H-40D9H holds Temporary storage location.
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.
Note: 40B0H holds Temporary storage location.
Note: 40AFH holds Current number type flag.
Note: 411DH-4124H holds REG l.
Note: 40B0H holds Temporary storage location.
Note: 40AFH holds Current number type flag.
2490 – 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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
Note: 409AH holds the RESUME flag.
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.
Note: 40EAH-40EBH holds the line number with error.
24E7-24FEVARPTR logic.
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.
28
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).
29
24FF – Other Function Routine.
29
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).
2532 – Binary Minus Routine.
Note: 40F3H-40F4H holds Temporary storage location.
2540 – 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.
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.
254E – This routine is for SNG( to MID$(.
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.
2C
258C – 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.
If the values match, set the current result in zero. If they do not match, set the current result to -1.
25C4 – NOT Routine.
25D9 – 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
25D9-25DBH
“TSTYP”LD A,(40AFH)Load register A with the current value of the number type flag.
Note: 40AFH holds Current number type flag.
25DC-25DDCP 08HCheck to see if the current value in REG 1 is double precision (02=INT, 03=STR, 04=SNG, 08=DBL).
If that test shows that we have a DOUBLE PRECISION number, jump forward to 25E5H.
25E0-25ElSUB 03HIf the number is not double precision, subtract 3.
25E2OR ASet the status flags of the adjusted number type flag in register A.
24E3SCFSet the Carry flag.
25E4RETReturn.
SUB 03HWe are dealing with a double precision number so adjust the value of the current number type flag in register A.
25E7OR ATest the value of the current number type flag in register A, which will exit without the CARRY flag set.
25E8RETReturn.
25EA-25ECCall 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).
25EDPOP AFGet the operator value from the stack and put it in register A.
25EEPOP DEGet the return address from the stack and put it in DE.
25F2PUSH BCSave the value of the return address in BC to the stack.
25F3-25F4CP 46HCheck 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.
25F5-25F6Jump forward a few instructions to 25FDH (to the AND code) if the operator value in register A isn’t an OR token.
25F7 – OR logic.
25F7LD A,ELoad register A with the LSB of the first value in register E.
25F8OR LCombine the LSB of the first value in register A with the LSB of the second value in register L.
25F9LD L,ALoad register L with the ORed value in register A.
25FALD A,HLoad register A with the MSB of the second value in register H.
25FBOR DCombine the MSB of the first value in register D with the MSB of the second value in register A.
25FD – AND logic.
25FDLD A,ELoad register A with the LSB of the first value in register E.
25FEAND LCombine the LSB of the first value in register A with the LSB of the second value in register L.
25FFLD L,ALoad register L with the ANDed value in register A.
2600LD A,HLoad register A with the MSB of the second value in register H.
2601AND DCombine the MSB of the first value in register D with the MSB of the second value in register A.
2604RST 10HWe 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.
2605RET ZReturn if this is the end of the BASIC statement.
RST 08H
2CSince 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).
2608 – DIM logic.
2608-260ALD BC,2603HLoad BC with a return address of 2603H.
260D – 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.
260C-260DOR AFHReset the value in register A.
260E-2610LD (40AEH),ASave the value in register A as the current variable location/creation flag.
Note: 40AEH holds LOCATE/CREATE variable flag.
2611LD B,(HL)Load register B with the first character of the variable name.
2612-2614GOSUB to 1E3DH to make sure the first character of the variable name is a letter.
2618XOR AZero register A.
2619LD C,AZero register C.
261ARST 10HWe 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.
Jump to 2622H if the character at the location of the current BASIC program pointer in register A is numeric.
261D-261FGOSUB to 1E3DH to check to see if the character at the location of the current BASIC program pointer is a letter.
Jump to 262BH if the character at the location of the current BASIC program pointer in register A isn’t a letter.
2622LD C,ALoad register C with the second character of the variable name in register A.
+ 2623RST 10HWe 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.
2626-2628Go check to see if the character at the location of the current BASIC program pointer in HL is alphabetic.
Jump back to 2623H if the character at the location of the current BASIC program pointer in HL is alphabetic.
262B-262DLD DE,2652HLoad DE with a return address of 2652H.
262EPUSH DESave the value of the return address in DE to the stack.
262F-2630LD D,02HLoad register D with an integer number type flag.
2631-2632CP 25HCheck to see if the character at the location of the current BASIC program pointer in register A is a %.
2633RET ZReturn if the character at the location of the current BASIC program pointer in register A is a %.
INC DBump register D so that it will be equal to a string number type flag (02=INT, 03=STR, 04=SNG, 08=DBL).
2635-2636CP 24HCheck to see if the character at the location of the current BASIC program pointer in register A is a $.
2637RET ZReturn if the character at the location of current BASIC program pointer in register A is a $.
INC DBump register D so that it will be equal to a single precision number type flag (02=INT, 03=STR, 04=SNG, 08=DBL).
2639-263ACP 21HCheck to see if the character at the location of the current BASIC program pointer in register A is a !.
263BRET ZReturn if the character at the location of the current BASIC program pointer in register A is a !.
LD D,08HLoad 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.
263E-263FCP 23HCheck to see if the character at the location of the current BASIC program pointer in register A is a #.
2640RET ZReturn if the character at the location of the current BASIC program pointer in register A is a #.
2642-2643SUB 41HAdjust the value of the first character of the variable name in register A so that it is in the range of 0 to 25.
2644-2645AND 7FHMake sure the sign bit in register A isn’t set by ANDing it against 0111 1111.
2646LD E,ALoad register E with the adjusted first character of the variable name in register A.
2647-2648LD D,00HLoad register D with zero.
2649PUSH HLSave the value of the current BASIC program pointer in HL to the stack.
264A-264CLD HL,4101HLoad HL with the starting address of the variable declaration table.
NOTE: 4101H-411AH holds Variable Declaration Table.
264DADD HL,DEAdd the value of the first character of the variable name in DE to the starting address of the variable declaration table in HL.
264ELD D,(HL)Load register D with the number type value at the location of the variable declaration table pointer in HL.
264FPOP HLGet the value of the current BASIC program pointer from the stack and put it in HL.
2650DEC HLDecrement the value of the current BASIC program pointer in HL.
2651RETReturn with data type in D.
2653-2655LD (40AFH),ASave the number type flag for the current variable name in register A.
NOTE: 40AFH holds Current number type flag.
2656RST 10HWe 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.
2657-2659LD A,(40DCH)Load register A with the FOR flag.
Note: 40DCH holds FOR flag.
265AOR ATest the value of the FOR flag in register A.
265ELD 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.
265F-2660SUB 28HCheck to see if the character at the location of the current BASIC program pointer in register A is a (.
2661-2663Jump 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).
2664XOR AZero register A.
2665-2667LD (40DCH),ASet the array flag to ‘no subscript’.
Note: 40DCH holds FOR flag.
2668PUSH HLSave the value of the current BASIC program pointer in HL to the stack.
2669PUSH DESave the number type flag for the variable in DE to the stack.
266A-266CLD 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.
266DEX DE,HLLoad DE with the simple variables pointer in HL. We don’t care what happens to HL.
266E-2670LD HL,(40FBH)Load HL with the array variables pointer.
- Note: 40FBH-40FCH holds the starting address of the BASIC array variable storage area.
2671RST 18HNow 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.
2672POP HLGet the number type flag for the variable from stack and put it in HL.
2673-2674Jump 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).
2675LD A,(DE)Load register A with the number type flag for the variable at the location of the simple variables pointer in DE.
2676LD L,ALoad register L with the number type flag in register A.
2677CP HCompare the number type flag for the variable in register H to the number type flag in register A.
2678INC DEBump the value of the current simple variables pointer in DE to the 2nd character name for this entry.
2679-267AJump to 2686H (i..e, the next variable in the list) if the number type flags don’t match.
267BLD 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.
267CCP CCompare the character at the location of the simple variables pointer in register A with the first character of the variable name in register C.
267FINC DEBump the value of the current simple variables pointer in DE.
2680LD A,(DE)Load register A with the second character of the variable name at the location of the simple variables pointer in DE.
2681CP BCompare the character at the location of the simple variables pointer in register A with the first character of the variable name in register B.
2682-2684Jump 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.
2685-2686LD A,13HZ-80 Trick to skip the next INC DE if continuing through.
2686INC DEBump to the next entry in the simple variable list part 1.
2687INC DEBump the value of the simple variables pointer in DE part 2.
2688Save the number type flag for the variable in HL to the stack so that it can be re-loaded at 2672H.
2689-268ALD H,00HLoad register H with zero.
268BADD HL,DEAdd the value of the simple variables pointer in DE to the value of the number type flag in HL.
268ELD A,HLoad register A with the number type flag for the variable in register H.
268FPOP HLGet the value of the current BASIC program pointer from the stack and put it in HL.
2690EX (SP),HLExchange the value of the current BASIC program pointer in HL with the value to the stack.
2691PUSH AFSave the number type flag for the variable in register A to the stack.
2692PUSH DESave the start of the array variables pointer in DE to the stack.
2693-2695LD DE,24F1HLoad DE with a VARPTR locator return address of 24F1H.
2696RST 18HNow 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.
2699-269BLD DE,2543HLoad DE with a return address of the find address of variables routine at 2543H.
269CRST 18HWe 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.
269DPOP DEGet the value of the array variables pointer from the stack and put it in DE.
26A0POP AFClear the stack and put the value of the number type flag for the variable from the stack and put it in register A.
26AlEX (SP),HLExchange the value of the current BASIC program pointer to the stack with the value of the return address in HL.
26A2PUSH HLSave the value of the current BASIC program pointer in HL to the stack.
26A3PUSH BCSave the variable’s name in BC to the stack.
26A4LD C,ALoad register C with the value of the number type flag for the variable in register A.
26A5-26A6LD B,00HLoad register B with zero.
26A7PUSH BCSave the variable’s number type flag in BC to the stack.
26A8INC BCBump the value of the variable’s number type flag in BC.
26A9INC BCBump the value of the variable’s number type flag in BC.
26AAINC BCBump 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).
26AB-26ADLD HL,(40FDH)Load HL with the value of the free memory pointer.
Note: 40FDH-40FEH holds Free memory pointer.
26AEPUSH HLSave the value of the free memory pointer in HL to the stack.
26AFADD HL,BCAdd the value of the variable’s number type flag in BC to the value of the free memory pointer in HL.
26B0POP BCGet the value of the free memory pointer from the stack and put it in BC.
26BlPUSH HLSave the value of the new free memory pointer in HL to the stack.
26B5POP HLGet the value of the new free memory pointer from the stack and put it in HL.
26B6-26B8LD (40FDH),HLSave the value of the new free memory pointer in HL to lock in that variable space.
NOTE: 40FDH-40FEH holds Free memory pointer.
26B9LD H,BLoad register H with the MSB of the new array variables pointer in register B.
26BALD L,CLoad register L with the LSB of the new array variables pointer in register C.
26BB-26BDLD (40FBH),HLSave the value of the new array variables pointer in HL.
- Note: 40FBH-40FCH holds the starting address of the BASIC array variable storage area.
26BEDEC HLDecrement the value of the array variables pointer in HL.
26BF-26C0LD (HL),00HZero the location of the memory pointer in HL.
26ClRST 18HNow 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.
26C4POP DEGet the value of the variable’s number type flag from the stack and put it in DE.
26C5LD (HL),ESave the value of the number type flag in register E at the location of the memory pointer in HL.
26C6INC HLBump the value of the memory pointer in HL.
26C7POP DEGet the 2nd character of the variable’s name from the stack and put it in DE.
26C8LD (HL),ESave the first character of the variable’s name in register E at the location of the memory pointer in HL.
26C9INC HLBump the value of the memory pointer in HL.
26CALD (HL),DSave the first character of the variable’s name in register D at the location of the memory pointer in HL.
26CBEX DE,HLLoad DE with the value of the variable pointer in HL.
26CCINC DEBump the value of the variable pointer in DE.
26CDPOP HLGet the value of the current BASIC program pointer from the stack and put it in HL.
26CERETReturn.
26D0LD E,ALoad register E with the value of the current number type flag in register A.
26D1POP AFClean up the stack.
26D2POP AFClean up the stack.
26D3EX (SP),HLExchange the value of the return address in HL with the value of the current BASIC program pointer to the stack.
26D4RETReturn to the VARPTR routine.
26D5 – This routine is to locate a subscripted variable.
26D5-26D7LD (4124H),AZero REG 1.
26D8POP BCClean up the stack.
26D9LD H,AZero register H.
26DALD L,AZero register L.
26DB-26DDLD (4121H),HLZero the string pointer location in REG 1.
26DERST 20HWe 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.
26E1-26E3LD HL,1928HLoad HL with the starting address of the Level II BASIC READY message.
26E4-26E6LD (4121H),HLSave the value in HL as the current string pointer.
26E7POP HLGet the value of the current BASIC program pointer from the stack and put it in HL.
26E8RETReturn.
26E9 – 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.
26E9PUSH HLSave the value of the current BASIC program pointer in HL to the stack.
26EA-26ECLD 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.
26EDEX (SP),HLExchange the value of the locate/create flag in HL with the value of the current BASIC program pointer to the stack.
26EELD D,AZero register D.
26EFPUSH DESave the variable’s number type flag in DE to the stack.
26F0PUSH BCSave the variable’s name in BC to the stack.
26Fl-26F3Go 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.
26F4POP BCGet the variable’s name from the stack (1st and 2nd character) and put it in BC.
26F5POP AFGet the variable’s number type flag from the stack and put it in register A.
26F6EX DE,HLExchange the value of the array subscript in DE with the value of the current BASIC program pointer in HL.
26F7EX (SP),HLExchange the value of the array subscript in HL with the value of the locate/create flag to the stack.
26F8PUSH HLSave the value of the locate/create flag in HL to the stack.
26F9EX DE,HLExchange the value of the locate/create flag in HL with the value of the current BASIC program pointer in DE.
26FAINC ABump the number of subscripts evaluated in register A.
26FBLD D,ALoad register D with the number of subscripts evaluated in register A.
26FCLD A,(HL)Load register A with the character at the location of the current BASIC program pointer in HL.
26FD-26FECP 2CHCheck to see if the character at the location of the current BASIC program pointer in register A is a ,.
26FF-2700Jump if the character at the location of the current BASIC program pointer in register A is a ,.
2701-2702RST 08H
29Since 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).
2703-2705LD (40F3H),HLSave the value of the current BASIC program pointer in HL.
2706Get the value of the locate/ create flag from the stack and put it in HL.
NOTE: 40F3H-40F4H holds Temporary storage location.
2707-2709LD (40AEH),HLSave the value of the locate/create flag in HL.
NOTE: 40AEH holds LOCATE/CREATE variable flag.
270APUSH DESave the number of subscripts evaluated in DE.
270B-270DLD 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.
270E-270FLD A,19HZ-80 Trick to skip the next command of ADD HL, DE if falling through.
2710EX DE,HLLoad DE with the value of the array variables pointer in HL.
2711-2713LD HL,(40FDH)Load HL with the value of the free memory pointer.
Note: 40FDH-40FEH holds Free memory pointer.
2714EX DE,HLExchange the value of the free memory pointer in HL with the value of the array variables pointer in DE.
2715RST 18HNow 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.
2716-2718LD A,(40AFH)Load register A with the value of the current number type flag.
Note: 40AFH holds Current number type flag.
2719-271AJump 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.
271BCP (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.
271CINC HLBump the value of the array variables pointer in HL.
271D-271EJump forward (but still in this loop) to 2727H if the number type flags don’t match.
271FLD A,(HL)Load register A with the first character of the variable name at the location of the array variables pointer in HL.
2720CP CCheck 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.
2721INC HLBump the value of the array variables pointer in HL.
2722-2723Jump forward (but still in this loop) to 2728H if the first characters of the variable names don’t match.
2724LD A,(HL)Load register A with the second character of the variable name at the location of the array variables pointer in HL.
2725CP BCompare 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.
2727LD A,23HBump the value of the array variables pointer in HL.
2728INC HLBump the value of the array variables pointer in HL.
2729LD 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.
272AINC HLBump the value of the array variables pointer in HL.
272BLD 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.
272CINC HLBump the value of the array variables pointer in HL.
272F-2731LD A,(40AEH)Load register A with the value of the locate/create flag.
Note: 40AEH holds LOCATE/CREATE variable flag.
2732OR ACheck the status of the locate/create flag in register A.
2733-2734LD E,12HLoad register E with the ?DD ERROR code.
2735-2737Display a ?DD ERROR message if the locate/create flag in register A indicates the create mode since that variable already exists.
2738POP AFGet the number of subscripts evaluated from the stack and put it in register A.
2739SUB (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).
273A-273CJump 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.
273D – BS ERROR entry point.
273D-273ELD E,10HLoad register E with a ?BS ERROR code.
273F-2741Display 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.
2742LD (HL),ASave the number of subscripts for the array in register A at the location of the array variables pointer in HL.
2743INC HLBump 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).
2744LD E,ALoad register E with the number type flag for the current variable.
2745-2746LD D,00HZero register D.
2747POP AFGet the number of subscripts evaluated from the stack and put it in register A.
2748LD (HL),CSave the second character of the variable’s name in register C at the location of the array variables pointer in HL.
2749INC HLBump 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).
274ALD (HL),BSave the first character of the variable’s name in register B at the location of the array variables pointer in HL.
274BINC HLBump the value of the array variables pointer in HL to the LSB of the offset to the next entry.
274CLD C,ALoad register C with the number of subscripts evaluated in register A.
2750INC HLBump the value of the array variables pointer in HL.
2751INC HLBump the value of the array variables pointer in HL. These 2 INC’s skip over the offset entry.
2752-2754LD (40D8H),HLSave 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.
2755LD (HL),CSave the number of subscripts evaluated in register C (1, 2, or 3) at the location of the array variables pointer in HL.
2756INC HLBump the value of the array variables pointer in HL to point to the first subscript entry in the array table.
2757-2759LD A,(40AEH)Load register A with the value of the locate/create flag.
Note: 40AEH holds LOCATE/CREATE variable flag.
275ARLASet the CARRY flag to be 0 for locate and 1 for create.
275BLD A,CLoad register A with the number of subscripts evaluated in register C.
275C-275ELD BC,000BHLoad BC with the default number of 11, which is the most entries an array can have without a DIM.
Jump forward to 2763H if the array is being created because it certainly wasn’t found.
2761POP BCGet a subscript from the stack and put it in BC.
2762INC BCBump the value of the subscript in BC.
276JLD (HL),CSave the LSB of the subscript’s value in register C at the location of the array variables pointer in HL.
2764INC HLBump the value of the array variables pointer in HL.
2765LD (HL),BSave the MSB of the subscript’s value in register B at the location of the array variables pointer in HL.
2766INC HLBump the value of the array variables pointer in HL.
2767PUSH AFSave the number of subscripts evaluated in register A to the stack.
2768-276AGo multiply the size of the subscript by the value of the number type flag to determine the amount of memory necessary for the subscript.
276BPOP AFGet the number of subscripts evaluated from the stack and put it in register A.
276CDEC ACheck to see if there are anymore subscripts to be evaluated.
276FPUSH AFSave the number of subscripts to be evaluated in register A to the stack.
2770LD B,DLoad register B with the MSB of the array’s length in register D.
2771LD C,ELoad register C with the LSB of the array’s length in register E. Now BC = length of the array in bytes.
2772EX DE,HLLoad DE with the value of the array variables pointer in HL.
2773ADD HL,DEAdd the length of the array in HL to the value of the array variable pointer in DE.
2779-277BLD (40FDH),HLGet the end of the array and put it in HL.
Note: 40FDH-40FEH holds free memory pointer.
277CDEC HLDecrement the value of the array pointer in HL.
277D-277ELD (HL),00HZero the location of the array pointer in HL.
277FRST 18HNow 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.
2782INC BCLoad BC with the array’s length in bytes plus one.
2783LD D,AZero register D.
2784-2786LD HL,(40D8H)Load HL with the array variables pointer (=the number of indices).
Note: 40D8H-40D9H holds Temporary storage location.
2787LD E,(HL)Load register E with the number of subscripts for the array at the location of the array variables pointer in HL.
2788EX DE,HLExchange the value of the array variables pointer in HL with the number of subscripts for the array in DE.
2789ADD HL,HLMultiply the number of subscripts for the array in HL by two.
278AADD HL,BCAdd the length of the array in BC to the number of subscripts times two in HL.
278BEX DE,HLExchange the array’s length in HL with the array variables pointer in DE.
278CDEC HLDecrement the value of the array variables pointer in HL.
278DDEC HLDecrement the value of the array variables pointer in HL.
278ELD (HL),ESave the LSB of the offset to the next array in register E at the location of the array variables pointer in HL.
278FINC HLBump the value of the array variables pointer in HL.
2790LD (HL),DSave the MSB of the offset to the next array in register D at the location of the array variables pointer in HL.
2791INC HLBump the value of the array variables pointer in HL.
2792POP AFGet the value of the locate/ create flag from the stack and put it in register A.
2795LD B,AZero register B.
2796LD C,AZero register C.
2797LD A,(HL)Load register A with the number of subscripts for the array at the location of the array variables pointer in HL.
2798INC HLBump the value of the array variables pointer in HL.
279916H E1Z-80 Trick to hide the next instruction (POP HL) if proceeding downward.
279APOP HLGet the array variables pointer from the stack and put it in HL.
279BLD E,(HL)Load register E with the LSB of the subscript limit at the location of the array variables pointer in HL.
279CINC HLBump the value of the array variables pointer in HL.
279DLD D,(HL)Load register D with the MSB of the subscript limit at the location of the array variables pointer in HL.
279EINC HLBump the value of the array variables pointer in HL.
279FEX (SP),HLExchange the value of the array variables pointer in HL with the subscript to the stack.
27A0PUSH AFSave the number of subscripts for the array in register A to the stack.
27A1RST 18HNow 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.
Jump back to 273DH if the subscript for the array in HL is greater than the subscript limit in DE.
27A8ADD HL,DEAdd the subscript limit for the array in DE to the array pointer in HL.
27A9POP AFGet the number of subscripts for the array from the stack and put it in register A.
27AADEC ACheck to see if there are anymore subscripts to be evaluated.
27ABLD B,HLoad register B with the MSB of the subscript pointer in register H.
27ACLD C,LLoad register C with the LSB of the subscript pointer in register L.
27AF-27B1LD A,(40AFH)Get the number type flag for the current array.
NOTE: 40AFH holds Current number type flag.
27B2LD B,HLoad register B with the MSB of the subscript pointer in register H.
27B3LD C,LLoad register C with the LSB of the subscript pointer in register L.
27B4ADD HL,HLMultiply the subscript pointer in HL by two.
27B5-27B6SUB 04HCheck the value of the number type flag in register A.
27B9ADD HL,HLIt 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).
27BCADD HL,HLIt must be double precision, so once again multiply the subscript pointer in HL by two (so now it is multiplied by 8).
27BDOR ASet the flags.
27C1ADD HL,BCThe current number type is a string so add the value of the original subscript pointer in BC to the subscript pointer in HL.
27C2POP BCGet the value of the array variables pointer from the stack and put it in BC.
27C3ADD HL,BCAdd the value of the array variables pointer in BC to the subscript pointer in HL.
27C4EX DE,HLLoad DE with the variable pointer in HL.
27C5-27C7LD HL,(40F3H)Get the value of the current BASIC program pointer and put it in HL.
Note: 40F3H-40F4H holds Temporary storage location.
27C8RETReturn.
27C9-27D3 – 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.
27CAPUSH HLSave the value of the current BASIC program pointer in HL to the stack.
27CB-27CDLD (40AFH),AZero the number type flag.
NOTE: 40AFH holds Current number type flag.
27D1POP HLGet the value of the current BASIC program pointer from the stack and put it in HL.
27D2RST 10HWe 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.
27D3RETReturn to BASIC.
27D4-27F4 – LEVEL II BASIC FRE ROUTINE
27D4-27D6LD HL,(40FDH)Load HL with the start of free memory pointer.
NOTE: 40FDH-40FEH holds Free memory pointer.
27D7EX DE,HLLoad DE with the value of the free memory pointer in HL.
27D8-27DALD HL,0000HZero HL.
27DBADD HL,SPAdd the value in HL (which is zero) to the current value of the stack pointer.
27DCRST 20HWe 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.
27DD-27DEIf that test shows we do NOT have a STRING (meaning this was really a MEM call, jump to forward to 27ECH.
27E5-27E7LD HL,(40A0H)Load HL with the start of string space pointer.
NOTE: 40A0H-40A1H holds the start of string space pointer.
27E8EX DE,HLLoad DE with the start of string space pointer in HL.
27E9-27EBLD HL,(40D6H)Load HL with the next available location in string space pointer.
NOTE: 40D6H-40D7H holds Next available location in string space pointer.
27ECLD A,LLoad register A with the LSB of the next available location in string space pointer in register L.
27EDSUB ESubtract 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.
27EELD L,ALoad register L with the LSB of the amount of string space remaining in register A.
27EFLD A,HLoad register A with the MSB of the next available location in string space pointer in register H.
27F0SBC A,DSubtract 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.
27F1LD H,ALoad register H with the MSB of the amount of string space remaining in register A.
27F2-27F4Jump to 0C66H to convert the difference between HL and DE to single precision and then RETurn out of the routine.
27F5-27FD – LEVEL II BASIC POS( ROUTINE
27F5-27F7LD A,(40A6H)Load register A with the current cursor line position.
Note: 40A6H holds the current cursor line position.
27F8LD L,ALoad register L with the value of the current cursor line position in register A.
27F9XOR AZero register A.
27FALD H,ALoad register H with zero, so now HL is 00 / cursor position.
27FE-2818 – LEVEL II BASIC USR(x) ROUTINE
2801RST 10HWe 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.
2802-2804GOSUB 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.
2805PUSH HLSave the value of the current BASIC program pointer in HL (=the address of the next element in the code string) to the stack.
2806-2808LD HL,0890HLoad HL with the return address of 0890H which will clear the stack before returning to BASIC.
2809PUSH HLSave the value of the return address in HL to the stack.
280A-280CLD A,(40AFH)Load register A with the value of the current number type flag.
Note: 40AFH holds Current number type flag.
280DPUSH AFSave the value of the current number type flag in register A.
(02=INT, 03=STR, 04=SNG, 08=DBL).
280E-280FCP 03HCheck to see if the current value in REG l is a string.
2810-2812If the current result in REG l is a string then GOSUB to 29DAH to get the string address into HL.
2813POP AFRestore the number type flag into register A.
2814EX DE,HLLoad DE with the value of the string address in HL.
2815-2817LD 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.
2818JP (HL)Jump to the address in HL.
2819-2827 – CONVERSION ROUTINE
Usually called by LET to convert the result of arithmetic routines to the proper destination type.
2819PUSH HLSave the value in HL to the stack.
281A-281BAND 07HMask the value of the current number type flag in register A.
281C-281ELD HL,18A1HLoad HL with the address of the arithmetic conversion routines.
281FLD C,ALoad register C with the value of the number type flag in register A.
(02=INT, 03=STR, 04=SNG, 08=DBL).
2820-2821LD B,00HZero register B. Now BC holds 00 / type.
2822ADD HL,BCAdd the offset (of BC) to the base arithmetic conversion routines, to find the right jump point.
2826POP HLGet the value from the stack and put it in HL.
2827RETReturn.
2828-2835 – Save the code string address
Usually called from the INPUT routine. On entry HL has the current line number in binary.
2828PUSH HLSave the value of the current BASIC program pointer in HL to the stack.
2829-282BLD HL,(40A2H)Load HL with the value of the current BASIC line number.
- Note: 40A2H-40A3H holds the current BASIC line number.
282CINC HLBump the value of the current BASIC line number in HL to enable us to test for a direct statement.
282DLD A,HLoad register A with the MSB of the current BASIC line number in register H.
282EOR LCombine the LSB of the current BASIC line number in register L with the MSB of the current BASIC line number in register A.
282FPOP HLGet the value of the current BASIC program pointer from the stack and put it in HL.
2830RET NZReturn if there is a line number (i.e., this isn’t the command mode).
2831 – ID ERROR entry point.
2831-2832LD E,16HLoad register E with the ?ID ERROR code.
2836-2856 – STRING ROUTINE – STR$ logic.
LD BC,2A2BHLoad BC with a return address of 2A2BH (which cleans the stack and then jumps to 2884H).
2842PUSH BCSave the value of the return address in BC to the stack.
2843LD A,(HL)Load register A with the string’s length at the location of the string’s VARPTR in HL.
2844INC HLBump the value of the string’s VARPTR in HL.
2845PUSH HLSave the value of the string’s VARPTR in HL to the stack.
2846-2848GOSUB to 28BFH to test the remaining string area to make sure that the new string will fit.
2849POP HLReload HL with the string’s VARPTR.
284ALD C,(HL)Load register C with the LSB of the string’s address at the location of the string’s VARPTR in HL.
284BINC HLBump the value of the string’s VARPTR in HL.
284CLD B,(HL)Load register B with the MSB of the string’s address at the location of the string’s VARPTR in HL.
2851LD L,ALoad register L with the string’s length (from register A).
2852-2854GOSUB to 29CEH to move the string from the temp area (of BC) to the string data area (in DE).
2855POP DEGet the value from the stack (40D3H) and put it in DE.
2856RETReturn.
2857-2864 – STRING ROUTINE – Set Up a String. A needs to hold the length of the string to be created.
2857-2859GOSUB 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.
285A-285CLD HL,40D3HLoad HL with the address of the temporary string parameter storage area.
Note: 40D3H-40D5H holds Used for temporary string VARPTR’s.
285DPUSH HLSave the address of the temporary string parameter area in HL to the stack.
285ELD (HL),ASave the string’s length in register A at the location of the temporary string parameter storage pointer in HL.
285FINC HLBump the value of the temporary string parameter storage pointer in HL.
2860LD (HL),ESave the LSB of the string’s address in register E at the location of the temporary string parameter storage pointer in HL.
2861INC HLBump the value of the temporary string parameter storage pointer in HL.
2862LD (HL),DSave the MSB of the string’s address in register D at the location of the temporary string parameter storage pointer in HL.
2863POP HLGet the address of the temporary string parameter storage area from the stack and put it in HL.
2864RETReturn.
2865-28A5 – STRING ROUTINE
This is the quote routine. C will be a counter.
2865H
“CSVEC”DEC HLDecrement the value of the current BASIC program pointer in HL.
2866-2867LD B,22HLoad register B with a “ (which is really the opening search character).
2868LD D,BLoad register D with a “ (which is really the ending search character).
2869PUSH HLSave the address of the current BASIC program pointer in HL to the stack.
286A-286BLD C,0FFHLoad register C with a -1.
286CINC HLBump the value of the current BASIC program pointer in HL to skip over that initial “.
286DLD A,(HL)Load register A with the character at the location of the current BASIC program pointer in HL.
286EINC CBump the counter in register C.
286FOR ACheck 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.
2870-2871Jump 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.
2872CP DCheck 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.
2873-2874Jump 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.
2875CP BCheck 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.
2876-2877Loop 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.
2878-2879CP 22HCheck to see if the character at the location of the current BASIC program pointer in register A is a quote.
287A-287CIf 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.
287DEX (SP),HLExchange the value of the current BASIC program pointer in HL with the string’s address to the stack.
287EINC HLBump the string’s address in HL until it points to the first character of the string.
287FEX DE,HLLoad DE with the string’s address in HL.
2880LD A,CLoad register A with the string’s length from register C.
2884-2886LD DE,40D3HLoad DE with the address of the string parameter storage area.
Note: 40D3H-40D5H holds Used for temporary string VARPTR’s.
2887-2888LD A,D5HThis seems to be garbage. Perhaps there is a jump to 2888 which would then be PUSH DE.
2889-288BLD 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.
288C-288ELD (4121H),HLSave the value of the next available location in the temporary string work area in HL as the string’s VARPTR in REG 1.
288F-2890LD A,03HLoad register A with the string number type flag.
2891-2893LD (40AFH),ASave the value in register A as the current number type flag.
Note: 40AFH holds Current number type flag.
2894-2896Add the length of the string to the next available location in the temporary string work area in HL.
2897-2899LD DE,40D6HLoad DE with the ending address of the temporary string work area.
Note: 40D6H-40D7H holds Next available location in string space pointer.
289ARST 18HNow 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.
289B-289DLD (40B3H),HLSave 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.
289EPOP HLGet the value of the current BASIC program pointer from the stack and put it in HL.
289FLD A,(HL)Load register A with the character at the location of the current BASIC program pointer in HL.
28A0RET NZReturn 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 …).
28A1 – ST ERROR entry point.
28A1-28A2LD E,1EHLoad register E with a ?ST ERROR code.
28A6-28BE – DISPLAY MESSAGE ROUTINE
28A6INC HLBump the value of the current BASIC program pointer in HL.
28A7 – 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.
28A7-28A9H
“DSTR”Go build a temporary string work area entry for the message at the location of the current BASIC program pointer in HL.
28B0INC DBump the value of the string’s length in register D in preparation for the following loop which starts with a DEC D.
28BlDEC DDecrement the value of the string’s length in register D.
28B2RET ZReturn if all of the characters in the string have been sent to the current output device.
28B7-28B8CP 0DHCheck to see if the character in register A is a carriage return.
28BCINC BCBump the value of the string pointer in BC.
28BD-28BELoop until all of the characters in the string have been sent to the current output device.
28BF-28D9 – STRING ROUTINE – Compute the amount of space remaining in the string area.
28BFOR ASet the flags.
28C0-28Cl0E F1Z-80 Trick.
28ClPOP AFGet the string’s length from the stack and put it in register A.
28C2PUSH AFSave the length of the string in register A to the stack.
28C3-28C5LD HL,(40A0H)Load HL with the start of the string space pointer.
- Note: 40A0H-40A1H holds the start of string space pointer.
28C6EX DE,HLMove the start of the string space pointer into DE. We don’t care what happens to HL.
28C7-28C9LD HL,(40D6H)Load HL with the next available location in string space pointer.
Note: 40D6H-40D7H holds Next available location in string space pointer.
28CACPLComplement the string’s length in register A so that it is negative.
28CBLD C,ALoad register C with the negative string’s length in register A.
28CC-28CDLD B,0FFHLoad register B with a -1 so that BC will be the negative length of the string.
28CEADD HL,BCAdd the negative string’s length in BC to the next available location in string space pointer in HL.
28CFINC HLBump the value of the adjusted next available location in string space pointer in HL.
28D0RST 18HNow 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.
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.
28D3-28D5LD (40D6H),HLSave the value in HL as the next available location in string space pointer.
Note: 40D6H-40D7H holds Next available location in string space pointer.
28D6INC HLBump the value of the next available location in string space pointer in HL.
28D7EX DE,HLLoad DE with the next available location in string space pointer in HL.
28D8POP AFGet the string’s length from the stack and put it in register A.
28D9RETReturn.
28DA-298E – STRING ROUTINE
28DAPOP AFGet 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.
28DB-28DCLD E,1AHLoad register E with an ?OS ERROR code.
28DD-28DFDisplay a ?OS ERROR if there isn’t enough string space available for the string and we had already reorganized string space.
28E0CP ASet the flags.
28ElPUSH AFSave the string’s length in register A to the stack.
28E5PUSH BCSave that return address to the stack.
28E6-28E8LD HL,(40B1H)Load HL with the top of memory pointer.
Note: 40B1H-40B2H holds MEMORY SIZE? pointer.
28E9-28EBLD (40D6H),HLSave 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.
28EC-28EELD HL,0000HZero HL.
28EFPUSH HLSave the value in HL to the stack.
28F0-28F2LD HL,(40A0H)Load HL with the start of string space pointer.
NOTE: 40A0H-40A1H holds the start of string space pointer.
28F3PUSH HLSave the start of string space pointer in HL to the stack.
28F4-28F6LD HL,40B5HLoad HL with the start of the temporary string work area pointer.
Note: 40B5H-40D2H holds Temporary string work area.
28F7EX DE,HLLoad DE with the start of the temporary string work area pointer in HL.
28F8-28FALD 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.
28FBEX DE,HLExchange 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.
28FCWe 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.
2903LD 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.
2906EX DE,HLLoad DE with the simple variables pointer in HL.
2907-2909LD 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.
290AEX DE,HLExchange the value of the simple variables pointer in DE with the value of the array variables pointer in HL.
290BRST 18HNow 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.
290C-290DJump forward to 2921H if the simple variables pointer in HL is the same as the array variables pointer in DE.
290ELD A,(HL)Load register A with the number type flag at the location of the simple variables pointer in HL.
290FINC HLBump the value of the simple variables pointer in HL.
2910INC HLBump the simple variables pointer in HL.
2911INC HLBump the value of the simple variables pointer in HL.
2912-2913CP 03HCheck to see if the variable at the location of the simple variables pointer is a string.
2914-2915Jump to 291AH if the variable at the location of the simple variables pointer in HL isn’t a string.
2919XOR AZero register A.
29lALD E,AZero register E.
291B-291CLD D,00HZero register D.
29lDADD HL,DEAdd the value of the number type flag in DE to the simple variables pointer in HL.
2920POP BCClean up the stack.
2921EX DE,HLLoad DE with the value of the array variables pointer in HL.
2922-2924LD HL,(40FDH)Load HL with the start of free memory pointer.
Note: 40FDH-40FEH holds Free memory pointer.
2925EX DE,HLExchange the value of the array variables pointer in DE with the value of the free memory pointer in HL.
2926RST 18HNow 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.
2927-2929Jump if the array variables pointer in register HL is the same as the start of the free memory pointer in DE.
292ALD A,(HL)Load register A with the number type flag at the location of the array variables pointer in HL.
292BINC HLBump the value of the array variables pointer in HL.
292C-292ECall 09C2H (which loads a SINGLE PRECISION value pointed to by HL into register pairs BC and DE).
292FPUSH HLSave the value of the array variables pointer in reg� ister pair HL to the stack.
2930ADD HL,BCAdd the value of the offset to the next array in BC to the value of the array variables pointer in HL.
2931-2932CP 03HCheck to see if the array being examined is a string.
2935-2937LD (40D8H),HLSave the address of the next array in HL.
Note: 40D8H-40D9H holds Temporary storage location.
2938POP HLGet the value of the array variables pointer from the stack and put it in HL.
2939LD C,(HL)Load register C with the number of subscripts for the array at the location of the array variables pointer in HL.
293A-293BLD B,00HZero register B.
293CADD HL,BCAdd the number of subscripts in the array in BC to the value of the array variables pointer in HL.
293DADD HL,BCAdd the number of subscripts in the array in BC to the value of the array variables pointer in HL.
293EINC HLBump the value of the array variables pointer in HL.
293FEX DE,HLLoad DE with the value of the array variables pointer in HL.
2940-2942LD HL,(40D8H)Load HL with the address of the next array.
Note: 40D8H-40D9H holds Temporary storage location.
2943EX DE,HLExchange the value of the array variables pointer in DE with the address of the array in HL.
2944RST 18HNow 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.
2945-2946Jump to 2921H if the array variables pointer in HL is the same as the address of the next array in DE.
294APUSH BCSave the value in BC to the stack.
294BXOR AZero register A.
294COR (HL)Load register A with the length of the string at the location of the array variables pointer in HL.
294DINC HLBump the value of the array variables pointer in HL.
294ELD E,(HL)Load register E with the LSB of the string’s address at the location of the array variables pointer in HL.
294FINC HLBump the value of the array variables pointer in HL.
2950LD D,(HL)Load register D with the MSB of the string’s address at the location of the array variables pointer in HL.
2951INC HLBump the value of the array variables pointer in HL.
2952RET ZReturn if the string’s length in register A is equal to zero.
2954LD C,LLoad register C with the LSB of the array variables pointer in register L.
2955-2957LD 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.
2958RST 18HNow 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.
2959LD H,BLoad register H with the MSB of the array variables pointer in register B.
295ALD L,CLoad register L with the LSB of the array variables pointer in register C.
295BRET CReturn if the string’s address in DE is in string space.
295DEX (SP),HLExchange the value of the return address in HL with the start of string space pointer to the stack.
295ERST 18HNow 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.
295FEX (SP),HLExchange the start of string space pointer in HL with the value of the return address to the stack.
2960PUSH HLSave the value of the return address in HL to the stack.
2961LD H,BLoad register H with the MSB of the array variables pointer in register B.
2962LD L,CLoad register L with the LSB of the array variables pointer in register C.
2963RET NCReturn if the string’s address in DE is below the string space pointer.
2965POP AFClean up the stack.
2966POP AFClean up the stack.
2967PUSH HLSave the value of the array variables pointer in HL to the stack.
2968PUSH DESave the string’s address in DE to the stack.
2969PUSH BCSave the value of the return address in BC to the stack.
296ARETReturn.
296CPOP HLGet the temporary string work area pointer from the stack and put it in HL.
296DLD A,LLoad register A with the LSB of the temporary string work area pointer in register L.
296EOR HCombine 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.
296FRET ZReturn if the temporary string work area is empty.
2971LD 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.
2972DEC HLDecrement the value of the temporary string work area pointer in HL.
2973LD 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.
2974PUSH HLSave the value of the temporary string work area pointer in HL to the stack.
2975DEC HLDecrement the value of the temporary string work area pointer in HL.
2976LD L,(HL)Load register L with the string’s length at the location of the temporary string work area pointer in HL.
2977-2978LD H,00HZero register H.
2979ADD HL,BCAdd the length of the string in HL to the string’s address in BC.
297ALD D,BLoad register D with the MSB of the string’s address in register B.
297BLD E,CLoad register E with the LSB of the string’s address in register C.
297CDEC HLDecrement the value of the string’s ending address in HL.
297DLD B,HLoad register B with the MSB of the string’s ending address in register H.
297ELD C,LLoad register C with the LSB of the string’s ending address in register L.
297F-2981LD HL,(40D6H)Load HL with the next available location in string space pointer.
NOTE: 40D6H-40D7H holds Next available location in string space pointer.
2985POP HLGet the temporary string work area pointer from the stack and put it in HL.
2986LD (HL),CSave the LSB of the string’s address in register Cat the location of the temporary string work area pointer in HL.
2987INC HLBump the value of the temporary string work area pointer in HL.
2988LD (HL),BSave the MSB of the string’s address in register B at the location of the temporary string work area pointer in HL.
2989LD L,CLoad register L with the LSB of the string’s address in register C.
298ALD H,BLoad register H with the MSB of the string’s address in register B.
298BDEC HLDecrement the string’s address in HL.
298F-29C5 – STRING ADDITION ROUTINE – Concatenate two strings.
298FPUSH BCSave the operator value in BC to the stack.
2990PUSH HLSave the value of the current BASIC program pointer in HL to the stack.
2991-2993LD HL,(4121H)Load HL with the first string’s VARPTR (from REG 1).
2994EX (SP),HLExchange the value of the first string’s VARPTR in HL with the value of the current BASIC program to the stack.
2995-2997GOSUB to 249FH to evaluate the expression at the location of the current BASIC program pointer in HL.
2998EX (SP),HLExchange the value of the current BASIC program pointer in HL with the value of the first string’s VARPTR to the stack.
299CLD A,(HL)Load register A with the first string’s length at the location of the first string’s VARPTR in HL.
299DPUSH HLSave the value of the first string’s VARPTR in HL to the stack.
299E-29A0LD HL,(4121H)Load HL with the second string’s VARPTR in REG 1.
29A1PUSH HLSave the second string’s VARPTR in HL to the stack.
29A2ADD 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.
29A3-29A4LD E,1CHLoad register E with a ?LS ERROR code.
29A5-29A7Display a ?LS ERROR message if the combined lengths of the strings is greater than 255.
29ABPOP DEGet the second string’s VARPTR from the stack and put it in DE.
29AFEX (SP),HLExchange the second string’s VARPTR in HL with the first string’s VARPTR to the stack.
29B3PUSH HLSave the value of the first string’s VARPTR in HL to the stack.
29B4-29B6LD HL,(40D4H)Load HL with the second string’s address.
29B7EX DE,HLLoad DE with the second string’s address in HL.
29BE-29C0LD HL,2349HLoad HL with the return address.
29C1EX (SP),HLExchange the value of the return address in HL with the value of the current BASIC program pointer to the stack.
29C2PUSH HLSave the value of the current BASIC program pointer in HL to the stack.
29C6-29D6 – 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.
29C6POP HLLoad HL with the value of the return address to the stack.
29C7EX (SP),HLExchange the value of the return address in HL with the string’s VARPTR to the stack.
29C8 – 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.
29C8LD A,(HL)Load register A with the string’s length at the location of the string’s VARPTR in HL.
29C9INC HLBump the value of the string’s VARPTR in HL.
29CALD C,(HL)Load register C with the LSB of the string’s address at the location of the string’s VARPTR in HL.
29CBINC HLBump the value of the string’s VARPTR in HL.
29CCLD B,(HL)Load register B with the MSB of the string’s address at the location of the string’s VARPTR in HL.
29CDLD L,ALoad register L with the string’s length in register A.
29CEINC LBump the value of the string’s length in register L.
29CFDEC LDecrement the value of the string’s length in register L.
29D0RET ZReturn if all of the characters in the string have been moved.
29D2LD (DE),ASave the character in register A at the location of the string storage pointer in DE.
29D3INC BCBump the value of the string pointer in BC.
29D4INC DEBump the value of the string storage pointer in DE.
29D7-29F4 – 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.
29DDEX DE,HLLoad DE with the value of the string’s VARPTR in HL.
29E1EX DE,HLLoad HL with the value of the string’s VARPTR in DE.
29E2RET NZReturn if the string isn’t the last entry in the temporary string work area.
29E4LD D,BLoad register D with the MSB of the string’s address in register B.
29E5LD E,CLoad register E with the LSB of the string’s address in register C.
29E6DEC DEDecrement the value of the string’s address in DE.
29E7LD C,(HL)Load register C with the string’s length at the location of the string’s VARPTR in HL.
29E8-29EALD HL,(40D6H)Load HL with the next available location in string space pointer.
Note: 40D6H-40D7H holds Next available location in string space pointer.
29EBRST 18HWe 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.
29EC-29EDJump 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.
29EELD B,AIf 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.
29EFADD HL,BCAdd the length of the string in BC to the next available location in string space pointer in HL.
29E0-29F2LD (40D6H),HLSave the adjusted next available location in string space pointer in HL.
Note: 40D6H-40D7H holds Next available location in string space pointer.
29F3POP HLGet the string’s VARPTR from the stack and put it in HL.
29F4RETReturn.
29F5-2A02 – STRING ROUTINE
29F5-29F7LD 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.
29F8DEC HLDecrement the value of the temporary string work area pointer in HL which backs up two words.
29F9LD 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.
29FADEC HLDecrement the value of the temporary string work area pointer in HL.
29FBLD 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.
29FCDEC HLDecrement the value of the temporary string work area pointer in HL.
29FDRST 18HNow 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.
29FERET NZReturn if the string’s VARPTR in DE doesn’t match the temporary string work area pointer in HL.
LD (40B3H),HLSave 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.
2A02RETReturn.
2A03-2A0E – LEVEL II BASIC LEN ROUTINE
2A0AXOR AZero register A.
2A0BLD D,AZero register D.
2A0CLD A,(HL)Load register A with the string’s length at the location of the string’s VARPTR in HL.
2A0DOR ASet the flags according to the string’s length in register A.
2A0ERETReturn.
2A0F-2A1E – LEVEL II BASIC ASC ROUTINE
2A13-2A15GOSUB to 2A07H (which itself is a GOSUB to 29D7H) to get string’s VARPTR into HL and the string’s length into register A.
2A19INC HLBump the value of the string’s VARPTR in HL.
2A1ALD E,(HL)Load register E with the LSB of the string’s address at the location of the string’s VARPTR in HL.
2A1BINC HLBump the value of the string’s VARPTR in HL.
2A1CLD D,(HL)Load register D with the MSB of the string’s address at the location of the string’s VARPTR in HL.
2A1DLD A,(DE)Load register A with the first character at the location of the string pointer in DE.
2A1ERETReturn.
2A1F-2A2E – LEVEL II BASIC CHR$ ROUTINE
2A1F-2A20LD A,01HLoad register A with the length of the string to be created.
2A21-2A23GOSUB to 2857H to save the string’s length in register A and value and set up the string’s address.
2A24-2A26GOSUB 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.
2A27-2A29LD HL,(40D4H)Load HL with the temporary string’s address.
2A2ALD (HL),ESave the character in register E at the location of the string pointer in HL.
2A2BPOP BCClean up the stack.
2A2F-2A60 – LEVEL II BASIC STRING$ ROUTINE
2A2FRST 10HWe 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.
2A30-2A31RST 08H
28Since 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).
2A32-2A34This 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.
2A34DEC HLBackspace the code string. This is a Z-80 trick because this code was part of the above call instruction.
2A35PUSH DESave the string’s length (“N”) (currently in DE) to the stack.
2A36-2A37RST 08
2CNow 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).
2A38-2A3ANow 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.
2A3B-2A3CRST 08H
29Now 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).
2A3DEX (SP),HLWe 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.
2A3EPUSH HLSave the string’s length (“N”) in HL to the stack so that we can test it to make sure it is an integer.
2A3FRST 20HWe 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.
2A42-2A44We 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.
2A45-2A46Skip the next instruction (which would load the string address and 1st character) by jumping to 2A4AH.
2A47-2A49Go get the first character in the string and return with it in register A. This is the character that will be repeated.
2A4APOP DEGet the “N” from the stack and put it in DE.
2A4BPUSH AFSave the character for the string (held in register A) to the stack.
2A4CPUSH AFand then save it to the stack again.
2A4DLD A,ELoad register A with “N” (held in register E).
2A51LD E,ALoad register E with “N” (held in register A).
2A52POP AFGet the character for the string (“X”) from the stack and put it in register A.
2A53INC ETo set the status flags we need to increase and then decrease E. First, bump the value of the string’s length in register E …
2A54DEC E… and then decrement the string’s length in register E.
2A57-2A59LD 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.
2A5ALD (HL),ASave the character in register A (“X”) at the location of the string pointer in HL.
2A5BINC HLBump the value of the string pointer in HL.
2A5CDEC EDecrement the string’s length in register E.
2A5D-2A5ELoop back to 2A5AH to keep filling (HL) until the string of X’s has been completed.
2A61-2A90 – LEVEL II BASIC LEFT$( ROUTINE – On entry, HL=address of LEFT$$, the stack = string address, stack+1 = n, and DE = code string address.
2A61-2A63Go check the syntax. The character at the location of the current BASIC program pointer in HL must be a ).
2A64XOR AZero register A.
2A65EX (SP),HLExchange the value of the current BASIC program pointer in HL with the string’s VARPTR to the stack.
2A66LD C,AZero register C.
2A67-2A683E E5Z-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.
2A68LD H,ALoad register H with the value in register A.
2A69PUSH HLSave the value of the string’s VARPTR in HL to the stack.
2A6ALD A,(HL)Load register A with the string’s length at the location of the string’s VARPTR in HL.
2A6BCP BCheck to see if the new string’s length in register B is greater than the string’s length in register A.
Jump to 2A70H if the new string’s length in register B is greater than the string’s length in register A.
2A6ELD A,BLoad register A with the new string’s length in register B.
2A6F-2A7111 0E 00Z-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.
2A70-2A7lLD C,00HZero register C.
2A72PUSH BCSave the string’s length in BC to the stack.
2A76POP BCGet the new string’s length from the stack and put it in BC.
2A77POP HLGet the string’s VARPTR from the stack and put it in HL.
2A78PUSH HLSave the string’s VARPTR in HL to the stack.
2A79INC HLBump the value of the string’s VARPTR in HL.
2A7ALD B,(HL)Load register B with the LSB of the string’s address at the location of the string’s VARPTR in HL.
2A7BINC HLBump the value of the string’s VARPTR in HL.
2A7CLD H,(HL)Load register H with the MSB of the string’s address at the location of the string’s VARPTR in HL.
2A7DLD L,BLoad register L with the LSB of the string’s address in register B.
2A7E-2A7FLD B,00HZero register B.
2A80ADD HL,BCAdd the string’s length in BC to the string’s address in HL.
2A81LD B,HLoad register B with the MSB of the string’s ending address in register H.
2A82LD C,LLoad register C with the LSB of the string’s ending address in register L.
2A83-2A85Go save the string’s length (held in A) and the string’s starting address (held in DE).
2A86LD L,ALoad register L with the string’s length (i.e., the number of characters to move) held in register A.
2A8APOP DEClean up the stack.
2A91-2A99 – LEVEL II BASIC RIGHT$ ROUTINE
2A91-2A93Go check the syntax. The character at the location of the current BASIC program pointer in HL must be a ).
2A94POP DEGet the string’s VARPTR from the stack and put it in DE.
2A95PUSH DESave the string’s VARPTR in DE to the stack.
2A96LD A,(DE)Load register A with the string’s length (held at the location of the string’s VARPTR in DE).
2A97SUB BSubtract the new string’s length in register B from the string’s length in register A to isolate the number of bytes.
2A9A-2AC4 – LEVEL II BASIC MID$ ROUTINE
2A9AEX DE,HLLoad HL with the value of the current BASIC program pointer (held in DE).
2A9BLD A,(HL)Load register A with the terminal character, currently held at the location of the current BASIC program pointer in HL.
2A9C-2A9EGOSUB to 2AE2H to get the string’s position in register B and the string’s VARPTR in DE.
2A9FINC BWe 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 …
2AA0DEC B… and then we decrement the value of the string’s position in register B.
2AA4PUSH BCSave the value of the string’s starting position (held in register B) to the stack.
2AA5-2AA6LD E,0FFHLoad register E with the default string’s length of 256 in case no number of bytes are given.
2AA7-2AA8CP 29HMore syntax checking. Here we need to test for a ) at the location of the current BASIC program pointer.
2AA9-2AAAJump to 2AB0H if the character at the location of the current BASIC program pointer in register A is a ).
2AAB-2AACRST 08H
2CIf 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).
2AAD-2AAFGo 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.
2ABO-2AB1RST 08H
29Since 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).
2AB2POP AFGet the value of the string’starting s position from the stack and put it in register A.
2AB3EX (SP),HLExchange the value of the current BASIC program pointer in HL with the value of the string’s VARPTR to the stack.
2AB7PUSH BCSave the return address in BC to the stack.
2AB8DEC ADecrement the value of the string’s position in register A so that we have a starting position minus 1.
2AB9CP (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.
2ABA-2ABBLD B,00HZero register B.
2ABCRET NCReturn 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.
2ABELD A,(HL)Load register A with the string’s length at the location of the string’s VARPTR in HL.
2ABFSUB CSubtract the value of the string’s position in register C from the string’s length in register A.
2AC0CP ECompare the new string’s length in register E with the adjusted string’s length in register A.
2AC1LD B,ALoad register B with the adjusted string’s length in register A.
2AC2Return to 2A69H if the new string’s length in register E is greater than the string’s length in register A.
2AC5-2ADE – LEVEL II BASIC VAL ROUTINE
2ACBLD E,ALoad register E with the string’s length at the location of the string’s VARPTR in HL.
2ACCINC HLBump the value of the string’s VARPTR in HL.
2ACDLD A,(HL)Load register A with the LSB of the string’s address at the location of the string’s VARPTR in HL.
2ACEINC HLBump the value of the string’s VARPTR in HL.
2ACFLD H,(HL)Load register H with the MSB of the string’s address at the location of the string’s VARPTR in HL.
2ADOLD L,ALoad register L with the LSB of the string’s address in register A.
2AD1PUSH HLSave the value of the string’s address in HL to the stack.
2AD2ADD HL,DEAdd the string’s length in DE to the string’s address in HL.
2AD3LD B,(HL)Load register B with the last character of the string at the location of the string pointer in HL.
2AD4LD (HL),DSave the zero in register D at the location of the string pointer in HL.
2AD5EX (SP),HLExchange the string’s ending address in HL with the string’s address to the stack.
2AD6PUSH BCSave the last character of the string in register B to the stack.
2AD7LD A,(HL)Load register A with the character at the location of the string pointer in HL.
2AD8-2ADACall 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).
2ADBPOP BCGet the last character of the string from the stack and put it in register B.
2ADCPOP HLGet the string’s ending address from the stack and put it in HL.
2ADDLD (HL),BSave the character in register B at the location of the string pointer in HL.
2ADERETReturn.
2ADF-2A6 – 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.
2ADFEX DE,HLLoad HL with the value of the current BASIC program pointer in DE.
2AE0-2AE1RST 08H
29Since 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).
2AE2POP BCGet the return address from the stack and put it in BC.
2AE3POP DEGet the number of bytes to isolate from the string (from the stack) and put it in DE.
2AE4PUSH BCSave the return address in BC to the stack.
2AE5LD B,ELoad register B with the number of bytes in register E.
2AE6RETReturn.
2AE7H- AEE – DISK ROUTINE
2AE7-2AE8CP 7AHCheck 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).
2AE9-2AEBDisplay a ?SN ERROR message if the character at the location of the current BASIC program pointer in register A isn’t equal to 7AH.
2AEF-2AF7 – LEVEL II BASIC INP ROUTINE
2AEF-2AF1Go evaluate the expression at the location of the current BASIC program pointer in HL and return with the port number in register A.
2AF2-2AF4LD (4094H),ASave the value of the port number (from register A) into 4094H.
2AF5-2AF7Go get the value from the port, execute an IN xx instruction, and return to the execution driver.
Note: 4093H-4095H holds INP routine.
2AF8-2B00 – LEVEL II BASIC OUT ROUTINE
2AF8-2AFAGo evaluate the expression at the location of the current BASIC program pointer in HL and return with the port number saved in memory.
2AFB-2AFDGo 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.
2AFE-2B00Go send the value in register A, execute an OUT xx instruction to the port, and return.
Note: 4096H-4098H holds OUT routine.
2B01-2B0D – EVALUATE EXPRESSION ROUTINE – This evaluates an expression and leaves the result in DE as an integer.
2B01RST 10HWe 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.
2B02-2B04Go evaluate the expression at the location of the current BASIC program pointer in HL and return with the result in REG 1.
2B05 – 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)).
2B05PUSH HLSave the value of the current BASIC program pointer in HL to the stack.
2B06-2B08Call 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).
2B09EX DE,HLLoad DE with the integer result in HL.
2B0APOP HLGet the value of the current BASIC program pointer from the stack and put it in HL.
2B0BLD A,DLoad register A with the MSB of the integer result in register D.
2B0COR ATest the value of the MSB in register A.
2B0DRETReturn.
2B0E-2Bl6 – EVALUATE EXPRESSION ROUTINE – OUT continues here
2B0E-2Bl0GOSUB 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.
2Bll-2Bl3LD (4094H),ASave the 8-bit value in register A in the DOS address of 4094H.
2Bl4-2Bl6LD (4097H),ASave the 8-bit value in register A in the DOS address of 4097H.
2Bl7-2BlA – 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.
2B17-2B18RST 08H
2ESince 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).
2BlB-2B28 – EVALUATE EXPRESSION ROUTINE – This is called by PRINT TAB.
2B1BRST 10HWe 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.
2B1C – 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.
2B1C-2B1EGOSUB 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.
2B1F-2B21GOSUB to 2B05H to convert the result in REG 1 to an integer and return with the integer result in DE.
2B25DEC HLDecrement the value of the current BASIC program pointer in HL.
2B26RST 10HWe 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.
2B27LD A,ELoad register A with the 8-bit result in register E.
2B28RETReturn.
2B29-2B2D – LEVEL II BASIC LLIST ROUTINE
This routine sets the output device flag to PRINTER and then flows through to the LIST command.
2B29-2B2ALD A,01HLoad register A with the printer output device code.
2B2B-2B2DLD (409CH),ASave 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.2B2E-2B74 – 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.
2B2EPOP BCGet the return address from the stack and put it in BC.
2B2F-2B31Go evaluate the range of line numbers given at the location of the current BASIC program pointer in HL.
2B32PUSH BCSave the address of the first BASIC line (held in BC) to the stack.
2B33-2B35LD HL,FFFFHLoad 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.
2B36-2B38LD (40A2H),HLSave the value in HL as the current BASIC line number.
- Note: 40A2H-40A3H holds the current BASIC line number.
2B39POP HLGet the address of the first BASIC line to be listed (from the stack) and put it in HL.
2B3APOP DEGet the value of the last BASIC line number to be listed (from the stack) and put it in DE.
2B3BLD C,(HL)Load register C with the LSB of the next BASIC line pointer at the location of the memory pointer in HL.
2B3CINC HLBump the value of the memory pointer in HL.
2B3DLD B,(HL)Load register B with the MSB of the next BASIC line pointer at the location of the memory pointer in HL.
2B3EINC HLBump the value of the memory pointer in HL.
2B3FLD A,BLoad register A with the MSB of the next BASIC line pointer in register B.
2B40OR CCombine 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.
2B44-2B46Go call the DOS link at 41DFH.
In NEWDOS 2.1, this is called from LIST processing.
2B4APUSH BCSave the address of the next BASIC line in BC to the stack.
2B4BLD C,(HL)Load register C with the LSB of the BASIC line number at the location of the memory pointer in HL.
2B4CINC HLBump the value of the memory pointer in HL.
2B4DLD B,(HL)Load register B with the MSB of the BASIC line number at the location of the memory pointer in HL.
2B4EINC HLBump the value of the memory pointer in HL.
2B4FPUSH BCSave the BASIC line number in BC to the stack.
2B50EX (SP),HLExchange the value of the memory pointer in HL with the value of the BASIC line number to the stack.
2B51EX DE,HLExchange the value of the BASIC line number in HL with the value of the last BASIC line number in DE.
2B52RST 18HNow 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.
2B53POP BCGet the value of the memory pointer from the stack and put it in BC.
2B54-2B56Jump to 1A18H if the BASIC line number in DE is greater than the last BASIC line number in HL.
2B57EX (SP),HLExchange the value of the last BASIC line number in HL with the address of the next BASIC line to the stack.
2B58PUSH HLSave the address of the next BASIC line in HL to the stack.
2B59PUSH BCSave the memory pointer in BC to the stack.
2B5AEX DE,HLLoad HL with the BASIC line number in DE.
2B5B-2B5DLD (40ECH),HLSave the BASIC line number in HL.
Note: 40ECH-40EDH holds EDIT line number.
2B5E-2B60Call 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.
2B61-2B62LD A,20HLoad register A with a space.
2B63POP HLGet the value of the memory pointer from the stack and put it in HL.
2B67-2B69GOSUB to 2B7EH move the BASIC line at the location of the memory pointer in HL into the input buffer and untokenize the BASIC line.
2B6A-2B6CLD HL,(40A7H)Load HL with the starting address of the input buffer.
Note: 40A7H-40A8H holds the input Buffer pointer.
2B6D-2B6FSince 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.
2B75-2B7D – 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 41C1H.
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.
2B75LD A,(HL)Load register A with the character at the location of the memory pointer in HL.
2B76OR ACheck to see if the character in register A is an end of the string character (00H).
2B77RET ZReturn if the character in register A is an end of the string character.
2B7BINC HLBump the value of the memory pointer in HL.
2B7C-2B7DLoop back to 2B75H until all of the characters have been sent to the current output device.
2B7E-2BC5 – 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.
2B7EPUSH HLSave the BASIC line pointer in HL to the stack.
2B7F-2B81LD HL,(40A7H)Load HL with the starting address of the input buffer.
Note: 40A7H-40A8H holds the input Buffer pointer.
2B82LD B,HLoad register B with the MSB of the input buffer pointer in register H.
2B83LD C,LLoad register C with the LSB of the input buffer pointer in register L.
2B84POP HLGet the value of the BASIC line pointer from the stack and put it in HL.
*2B85-2B87JUMP to 069AH to clear A and all flags, load the data flag (at 409FH) with 0, load D with 255 (a buffer), and JUMP to 2B8DH.
Difference between M1 and M3 ROMs: This change is to the LIST command. JP 069AH in the Model III replaces LD D,0FFH followed by JR 2B8CH in the Model I.
*2B88NOPNo Operation
2B89INC BCBump the value of the input buffer pointer in BC.
2B8ADEC DDecrement the character count in register D.
2B8BRET ZReturn if 256 characters have been moved into the input buffer.
INC HLMove one byte forward in the text.
Difference between M1 and M3 ROMs: Another change to LIST. In the Model I three instructions occupied this area: LD A,(HL); OR A; INC HL. In the Model III the INC HL instruction is moved to the beginning of the three.
OR ASet the status flags to enable us to check to see if the character in register A is an end of the BASIC line character.
2B8FLD (BC),ASave the character at the location of the input buffer pointer (held in register A) to the memory location held by BC.
2B90RET ZReturn if the character in register A is an end of the BASIC line character.
Difference between M1 and M3 ROMs: The final change to LIST – a JP P,2B89H instruction in the Model I is changed to a JP 302DH instruction in the Model III.
2B98DEC BCThe 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.
2B99DEC BCDecrement the value of the input buffer pointer in BC.
2B9ADEC BCDecrement the value of the input buffer pointer in BC.
2B9BDEC BCDecrement the value of the input buffer pointer in BC.
2B9CINC DBump the value of the character counter in register D.
2B9DINC DBump the value of the character counter in register D.
2B9EINC DBump the value of the character counter in register D.
2B9FINC DBump the value of the character counter in register D.
2BA0-2BA1CP 95HCheck to see if the character in register A is an ELSE token.
2BA2-2BA4If 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.
2BA5-2BA6SUB 7FHSubtract 7F to get the number of the entry we are looking for in token list.
2BA7PUSH HLSave the value of the BASIC line pointer in HL to the stack.
2BA8LD E,ALoad register E with the character in register A.
2BA9-2BABLD HL,1650HLoad HL with the starting address of the reserved words list.
2BACLD A,(HL)Load register A with the character at the location of the reserved words list pointer in HL.
2BADOR ATest the value of the character in register A.
2BAEINC HLBump the value of the reserved words list pointer in HL.
2BAF-2BB1Jump back to 2BACH if the character at the location of the reserved words pointer in register A doesn’t have bit 7 set.
2BB2DEC EDecrement the value of the token in register E.
2BB5-2BB6AND 7FHReset bit 7 of the character in register A by ANDing it against 0111 1111.
2BB7LD (BC),ASave the character in register A at the location of the input buffer pointer in BC.
2BB8INC BCBump the value of the input buffer pointer in BC.
2BB9DEC DDecrement the value of the character counter in register D.
2BBA-2BBCJump back to 28D8H if the maximum number of characters have been put into the input buffer.
2BBDLD A,(HL)Load register A with the character at the location of the reserved words pointer in HL.
2BBEINC HLBump the reserved words pointer in HL.
2BBFOR ATest the value of the character in register A.
2BC3POP HLGet the value of the BASIC line pointer from the stack and put it in HL.
2BC6-2BF4LEVEL II BASIC DELETE ROUTINE
2BC6-2BC8GOSUB to 1B10H to evaluate the line numbers at the location of the current BASIC program pointer in HL.
2BC9POP DEGet the value of the last BASIC line number to be deleted (in binary) from the stack and put it in DE.
2BCAPUSH BCSave the address of the first BASIC line to be deleted in BC to the stack.
2BCBPUSH BCSave the address of the first BASIC line to be deleted in BC to the stack AGAIN!.
2BCC-2BCEGOSUB 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.
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.
2BD1LD D,HLoad register D with the MSB of the last BASIC line’s address in register H.
2BD2LD E,LLoad register E with the LSB of the last BASIC line’s address in register L.
2BD3EX (SP),HLExchange the last BASIC line’s address in HL with the first BASIC line’s address to the stack.
2BD4PUSH HLSave the first BASIC line’s address in HL to the stack.
2BD5RST 18HNow 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-2BD8Display 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.
2BD9-2BDBLD HL,1929HLoad HL with the starting address of the BASIC READY message.
2BDC-2BDEWe 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).
2BDFPOP BCGet the first BASIC line’s address from the stack and put it in BC.
2BE0-2BE2LD HL,1AE8HLoad HL with the return address.
2BE3EX (SP),HLExchange the value of the return address in HL with the value of the last BASIC line’s address to the stack.
2BE4EX DE,HLLoad DE with the last BASIC line’s address in HL.
2BE5-2BE7LD 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.
2BE8LD A,(DE)Load register A with the character at the location of the memory pointer in DE.
2BE9LD (BC),ASave the character in register A at the location of the memory pointer in BC.
2BEAINC BCBump the value of the memory pointer in BC.
2BEBINC DEBump the value of the memory pointer in DE.
2BECRST 18HNow 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-2BEELoop back to 2BE8H until the memory pointer in DE equals the end of the BASIC program pointer in HL.
2BD3EX (SP),HLExchange the last BASIC line’s address in HL with the first BASIC line’s address to the stack.
2BD4PUSH HLSave the first BASIC line’s address in HL to the stack.
2BD5RST 18HNow 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-2BD8Display 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-2BDBLD HL,1929HLoad HL with the starting address of the BASIC READY message.
2BDC-2BDEWe 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).
2BDFPOP BCGet the first BASIC line’s address from the stack and put it in BC.
2BE0-2BE2LD HL,1AE8HLoad HL with the return address.
2BE3EX (SP),HLExchange the value of the return address in HL with the value of the last BASIC line’s address to the stack.
2BE4EX DE,HLLoad DE with the last BASIC line’s address in HL.
2BE5-2BE7LD 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.
2BE8LD A,(DE)Load register A with the character at the location of the memory pointer in DE.
2BE9LD (BC),ASave the character in register A at the location of the memory pointer in BC.
2BEAINC BCBump the value of the memory pointer in BC.
2BEBINC DEBump the value of the memory pointer in DE.
2BECRST 18HNow 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-2BEELoop until the memory pointer in DE equals the end of the BASIC program pointer in HL.
2BEFLD H,BLoad register H with the MSB of the memory pointer in register B.
2BF0LD L,CLoad register L with the LSB of the memory pointer in register C.
2BF1-2BF3LD (40F9H),HLSave 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.
2BF4RETReturn.
2BF5-2C1E – LEVEL II BASIC CSAVE ROUTINE
2BF5-2BF7Calls the WRITE LEADER routine at 0284H (which writes a Level II leader on the cassette unit set in register A).
2BF82BFAH 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.
2BFBPUSH HLSave 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.
2BFF-2C00LD A,D3HLoad register A with the filename header byte (=D3H which is a “S” with the sign bit on).
2C01-2C03the 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.
2C07LD A,(DE)Load register A with the first character of the filename at the location of the filename pointer in DE.
2C08-2C0Athe 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-2C0DLD 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).
2C0EEX DE,HLLoad DE with the start of the BASIC program pointer in HL.
2C0F-2C11LD 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.
2C12LD 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.
2C13INC DEBump the value of the memory pointer in DE.
2C14-2C16the 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).
2C17RST 18HNow 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-2C19Loop back to 2C12H until the memory pointer in DE is equal to the end of the BASIC program pointer in HL.
2C1DPOP HLGet the value of the current BASIC program pointer from the stack and put it in HL.
2C1ERETReturn.
2C1F-2CA4 – LEVEL II BASIC CLOAD ROUTINE
Difference between M1 and M3 ROMs:Another change that originated in the “new” ROM Model I modified the CLOAD command (changed the order of portions of the CLOAD routine, disallowed CLOAD from cassette drive #2, etc.).
2C1FSUB 0B2HTest for CLOAD?
2C23XOR ASignal CLOAD (not CLOAD?)
2C27PUSH AFIncrement HL to the filname of the CLOAD/CLOAD? flag
2C28LD A,(HL)Set the next element from the code string, which should be the filename
2C29OR ASet status flags
2C32LD A,(DE)Get the filename
2C33LD L,AMove the filename into Register L
2C34POP AFRestore the CLOAD/CLOAD? flag
2C35OR ASet the status register according to that flag
2C36LD H,AH will now hold CLOAD/CLOAD? flag, and L will hold the filename
2C37LD (4121H),HLPut the flag and filename into REG 1.
2C3DLD HL,0000HCause the drive to be selected
2C43LD HL,(4121H)Restore the CLOAD/CLOAD? flag and filename
2C46EX DE,HLLoad DE with the CLOAD/CLOAD? flag and load the filename into HL.
2C47-2C48LD B,03HLoad 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).
2C49-2C4BCalls 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).
2C4C-2C4DSUB 0D3HCheck to see if the character in register A is a filename header byte.
2C50-2C51Loop back to 2C49H until three filename header bytes (3 S’s with the sign bit on) have been read.
2C52-2C54Now 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).
2C55INC EWe 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.
2C56DEC EDecrement the value of the filename in register E.
2C59CP EIf 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.
2CA5 – “BCD” message string.
2C5A-2C5BJump 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.
2C5C-2C5ELD 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.
2C5F-2C60LD B,03HLoad register B with the number of zeros to look for to stop the load (which is 3).
2C61-2C63Calls 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).
2C64LD E,ALoad register E with the character in register A.
2C65SUB (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.
2C66AND DCombine the subtracted result in register A with the value of the CLOAD/CLOAD? flag in register D.
2C69LD (HL),EAt 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.
2C6DLD A,(HL)Load register A with the character at the location of the memory pointer in HL.
2C6EOR ACheck to see if the byte just read in register A is equal to zero.
2C6FINC HLBump the value of the memory pointer in HL.
2C70-2C71Loop if the byte in register A isn’t equal to zero (meaning that it isn’t end of program or end of statement).
2C72-2C74Call the BLINK ASTERISK routine at 022CH which alternatively displays and clears an asterisk in the upper right hand corner of the video display.
2C75-2C76Do that loop until three zeros in a row have been read from the cassette recorder.
2C77-2C79LD (40F9H),HLBy 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-2C7CGOSUB to 01F8H to turn off the tape.
Difference between M1 and M3 ROMs: Also part of CLOAD, this change turns off the tape before printing READY on the video display. In the Model I, the code from 2C7AH – 2C82H consisted of the instructions LD HL,1929H; CALL 28A7H, CALL 01F8H. In the Model III the CALL to 01F8H has been moved to the beginning of these instructions.
*2C7D-2C7FLD HL,1929HLoad HL with the starting address of the BASIC READY message.
*2C80-2C82We 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).
2C83-2C85LD 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).
2C86PUSH HLSave the start of the BASIC program pointer in HL to the stack.
*2C8A-2C8CGOSUB to 31BDH to reset the cassette I/O.
Difference between M1 and M3 ROMs: This is part of the CLOAD? routine used when a bad byte has been read from the tape. In the Model I, a LD HL, 2CA5H instruction is found here (loads HL with the starting address of the “BAD” message), while the Model III uses a CALL 31BDH instruction, which does some housekeeping in addition to pointing HL to the “BAD” message.
2C8D-2C8FWe 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).
2C93-2C95LD (3C3EH),AGo display the filename on the video display.
2C96-2C97LD B,03HLoad register B with the number of zeros to be found to stop the search.
2C98-2C9ACalls 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).
2C9BOR ACheck to see if the character in register A is equal to zero.
2CA0-2CA2Calls 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).
2CA5-2CA9 – MESSAGE STORAGE LOCATION
2CA5-2CA9“BAD”The BAD message is stored here.
2CAA-2CB0 – LEVEL II BASIC PEEK ROUTINE – On entry, REG 1 to have the peek location, and on exit Reg 1 to have the peeked value.
2CAA-2CACCall 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).
2CADLD A,(HL)Load register A with the value at the location of the memory pointer in HL.
2CB1-2CBC – LEVEL II BASIC POKE ROUTINE
2CB1-2CB3Go evaluate the expression at the location of the current BASIC program pointer in HL and return with the integer result in DE.
2CB4PUSH DESave the address the user wants to POKE to (held in DE) to the stack.
2CB5-2CB6RST 08H
2ESince 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).
2CB7-2CB9GOSUB 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.
2CBAPOP DEGet the address the user wants to POKE to from the stack and put it in DE.
2CBBLD (DE),ASave the value the user wanted to poke (held in register A) in the location that the user wants to POKE to (held in DE).
2CBCRETReturn.
2CBD-2E52 – LEVEL II BASIC USING ROUTINE
2CBD-2CBFGo evaluate the string expression at the location of the current BASIC program pointer in HL.
2CC3-2CC4RST 08H
3BSince 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).
2CC5EX DE,HLLoad DE with the value of the current BASIC program pointer in HL.
2CC6-2CC8LD HL,(4121H)Load HL with the USING string’s VARPTR.
2CCB-2CCDLD A,(40DEH)Load register A with the value of the READ/INPUT flag.
Note: 40DEH holds READ flag.
2CCEOR ACheck to see if the READ/INPUT flag in register A indicates INPUT.
2CD1POP DERestore the current BASIC program pointer (from the stack) into DE.
2CD2EX DE,HLLoad HL with the value of the current BASIC program pointer in DE. D will wind up being the length of the string
2CD3PUSH HLSave the USING string’s VARPTR in HL to the stack.
2CD4XOR AZero register A.
2CD5-2CD7LD (40DEH),AClear the READ/INPUT flag.
Note: 40DEH holds READ flag.
2CD8CP DCheck to see if the value in D is equal to zero (by checking it against A which was XOR’d to 0 above).
2CD9PUSH AFSave the value in AF (the difference) to the stack.
2CDAPUSH DESave the value in DE (the address of the next input symbol from the code string) to the stack.
2CDBLD B,(HL)Load register B with the USING string’s length at the location of the USING string’s VARPTR in HL.
2CDCOR BCheck to see if the USING string’s length in register B is equal to zero.
2CE0INC HLBump the value of the USING string’s VARPTR in HL.
2CE1LD 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.
2CE2INC HLBump the value of the USING string’s VARPTR in HL.
2CE3LD 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.
2CE4LD L,CLoad register L with the LSB of the USING string’s address in register C.
2CE7LD E,BLoad register E with the USING string’s length in register B.
2CE8PUSH HLSave the value of the current USING string pointer in HL.
2CE9-2CEALD C,02HLoad register C with the number of %’s substring length.
2CEBLD A,(HL)Load register A with the character at the location of the USING string pointer in HL.
2CECINC HLBump the value of the USING string pointer in HL.
2CED-2CEECP 25HCheck to see if the character in register A is a %.
2CF2-2CF3CP 20HCheck to see if the character in register A is a space.
2CF6INC CBump the % substring length in register C.
2CF9POP HLAt 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.
2CFALD B,ELoad register B with the USING string’s length.
2CFB-2CFCLD A,25HLoad register A with a %.
2D03XOR AZero register A and clear the flags.
2D04LD E,AZero register E.
2D05LD D,AZero register D.
2D09LD D,AZero register D.
2D0ALD A,(HL)Load register A with the character (i.e., the field description) at the location of the USING string pointer in HL.
2D0BINC HLBump the value of the USING string pointer in HL.
2D0C-2D0DCP 21HCheck to see if the character in register A is a !.
2D11-2D12CP 23HCheck to see if the character in register A is a #.
2D15DEC BDecrement the value of the string’s length in register B.
2D19-2D1ACP 2BHCheck to see if the character in register A is a +.
2D1B-2D1CLD A,08HSet the flag in register A to force a leading +.
2D1FDEC HLDecrement the value of the USING string pointer in HL.
2D20LD A,(HL)Load register A with the character at the location of the USING string pointer in HL.
2D21INC HLBump the value of the USING string pointer in HL.
2D22-2D23CP 2EHCheck to see if the character in register A is a ..
2D26-2D27CP 25HCheck to see if the character in register A is a %.
2D2ACP (HL)Compare the character in register A with the character at the location of the USING string pointer in HL.
2D2B-2D2CJump if the character in register A isn’t equal to the character at the location of the USING string pointer in HL.
2D2D-2D2ECP 24HCheck to see if the character in register A is a $.
2D31-2D32CP 2AHCheck to see if the character in register A is a *.
2D35LD A,BLoad register A with the USING string’s length in register B.
2D36-2D37CP 02HCheck to see if the USING string’s length in register A is at least two.
2D38INC HLBump the value of the USING string pointer in HL.
2D3BLD A,(HL)Load register A with the character at the location of the USING string pointer in HL.
2D3C-2D3DCP 24HCheck to see if the character in register A is a string.
2D3E-2D3FLD A,20HSet the ** edit flag in register A.
2D42DEC BDecrement the value of the USING string’s length in register.
2D43INC EBump the number of characters to the left of the decimal point in register E.
2D44-2D45FE AFZ-80 Trick to skip over a XOR A if passing through by processing it as a CP AFH.
2D45XOR AThis is $ processing for PRINT USING.
2D46-2D47ADD A,10HMask the value of the edit flag in register A for leading $‘s.
2D48INC HLBump the value of the USING string pointer in HL.
2D49INC EBump the number of characters to the left of the decimal point in register E.
2D4AADD A,DCombine the value of the edit flag in register D with the value of the edit flag in register A.
2D4BLD D,ALoad register D with the value of the edit flag in register A.
2D4CINC EBump the number of characters to the left of the decimal point in register E.
2D4D-2D4ELD C,00HZero the number of characters to the right of the decimal point in register C.
2D4FDEC BDecrement the value of the string’s length in register B.
2D52LD A,(HL)Load register A with the character at the location of the USING string pointer in HL.
2D53INC HLBump the value of the USING string pointer in HL.
2D54-2D55CP 2EHCheck to see if the character in register A is a ..
2D58-2D59CP 23HCheck to see if the character in register A is a #.
2D5C-2D5DCP 2CHCheck to see if the character in register A is a ,.
2D60LD A,DLoad register A with the value of the edit flag in register D.
2D61-2D62OR 40HMask the edit flag in register A for ,.
2D63LD D,ALoad register D with the value of the edit flag in register A.
2D66LD A,(HL)Load register A with the character at the location of the USING string pointer in HL.
2D67-2D68CP 23HCheck to see if the character in register A is a #.
2D69-2D6ALD A,2EHLoad register A with a decimal point.
2D6D-2D6ELD C,01HLoad register C with the number of characters to the right of the decimal point.
2D6FINC HLBump the value of the USING string pointer in HL.
2D70INC CBump the number of characters to the right of the decimal point in register C.
2D71DEC BDecrement the value of the string’s length in register B.
2D74LD A,(HL)Load register A with the character at the location of the USING string pointer in HL.
2D75INC HLBump the value of the USING string pointer in HL.
2D76-2D77CP 23HCheck to see if the character in register A is a #.
2D7APUSH DESave the value of the edit flag and the count of the characters to the left of the decimal point in DE to the stack.
2D7B-2D7DLD DE,2D97HLoad DE with the return address.
2D7EPUSH DESave the value of the return address in DE to the stack.
2D7FLD D,HLoad register D with the MSB of the USING string pointer m register H.
2D80LD E,LLoad register E with the LSB of the USING string pointer in register L.
2D81-2D82CP 5BHCheck to see if the character in register A is an up arrow.
2D83RET NZReturn if the character in register A isn’t an up arrow.
CP (HL)Check to see if the character at the location of the USING string pointer in HL is an up arrow.
2D85RET NZReturn 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).
2D87CP (HL)Check to see if there is a third up arrow at the location of the USING string pointer in HL.
2D88RET NZReturn 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).
2D8ACP (HL)Check to see if the character at the location of the USING string pointer in HL is a fourth up arrow.
2D8BRET NZReturn 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).
INC HLBump the value of the USING string pointer in HL. If we are here we have a #.##[[[[ format.
2D8DLD A,BLoad register A with the value of the USING string’s length in register B.
2D8E-2D8FSUB 04HCheck to see if there are at least 4 characters left in the USING string.
2D90RET CReturn to 2D97 if there aren’t at least four characters left in the USING string.
2D92POP DEGet the edit flag and the count of the characters to the left of the decimal point from the stack and put it in DE.
2D93LD B,ALoad register B with the USING string’s length in register A.
2D94INC DSet the exponential notation flag in register D.
2D95INC HLBump the value of the USING string pointer in HL.
2D96CAZ-80 Trick! By putting the CA opcode here, the next 2 bytes are ignored if passing through, but remain in effect if jumped to.
2D97EX DE,HL(Ignored if passing through) Load HL with the value of the USING string pointer in DE.
2D98POP 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.
2D99LD A,DLoad register A with the value of the edit flag in register D.
2D9ADEC HLDecrement the value of the USING string pointer in HL.
2D9BINC EBump the number of characters to the left of the decimal point in register E.
2D9C-2D9DAND 08HCheck to see if the sign flag is set in register A.
2DA0DEC EDecrement the number of characters to the left of the decimal point in register E.
2DA1LD A,BLoad register A with the USING string’s length in register B.
2DA2OR ACheck to see if this is the end of the string.
2DA5LD A,(HL)Load register A with the character at the location of the USING string pointer in HL.
2DA6-2DA7SUB 2DHCheck to see if the character in register A is a – .
2DAA-2DABCP 0FEHCheck to see if the character in register A is a +.
2DAE-2DAFLD A,08HSet the edit flag for a + character.
2DB0-2DB1ADD A,04HSet the edit flag for a – character.
2DB2ADD A,DCombine the value of the edit flag in register D with the value of the edit flag in register A.
2DB3LD D,ALoad register D with the value of the edit flag in register A.
2DB4DEC BDecrement the value of the USING string’s length in register B.
2DB5POP HLGet the value of the current BASIC program pointer from the stack and put it in HL.
2DB6POP AFLoad register A with the character at the location of the current BASIC program pointer in HL.
2DB9PUSH BCSave the count of the characters to the right of the decimal point and the USING string’s length in BC to the stack.
2DBAPUSH DESave the edit flag and the number of characters to the left of the decimal point in DE to the stack.
2DBB-2DBDGo evaluate the expression at the location of the current BASIC program pointer and return with the result in REG 1.
2DBEPOP DEGet the edit flag and the number of characters to the left of the decimal point from the stack and put it in DE.
2DBFPOP BCGet 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.
2DC0PUSH BCSave the number of characters to the right of the decimal point and the USING string’s length m BC to the stack.
2DC1PUSH HLSave the value of the current BASIC program pointer in HL to the stack.
2DC2LD B,ELoad register B with the number of characters to the left of the decimal point in register E.
2DC3LD A,BLoad register A with the number of characters to the left of the decimal point in register B.
2DC4ADD A,CAdd 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.
2DC5-2DC6CP 19HCheck to see if the total number of characters in register A is greater than 24.
2DC7-2DC9Display a FC ERROR message if the total number of characters in register A is greater than 24.
2DCALD A,DLoad register A with the value of the edit flag in register D.
2DCB-2DCCOR 80HSet the edit flag in register A.
2DCD-2DCFCall 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.
2DD0-2DD2We 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).
2DD3POP HLGet the value of the current BASIC program pointer from the stack and put it in HL.
2DD4DEC HLDecrement the value of the current BASIC program pointer in HL.
2DD5RST 10HWe 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.
2DD6SCFSet the Carry flag.
2DD7-2DD8Jump if the character at the location of the current BASIC program pointer in register A is an end of the BASIC statement character.
2DD9-2DDBLD (40DEH),ASave the character at the location of the current BASIC program pointer in register A.
Note: 40DEH holds READ flag.
2DDC-2DDDCP 3BHCheck to see if the character at the location of the current BASIC program pointer in register A is a semicolon.
2DDE-2DDFJump if the character at the location of the current BASIC program pointer in register A is a semicolon.
2DE0-2DE1CP 2CHCheck to see if the character at the location of the current BASIC program pointer in register A is a comma.
2DE2-2DE4Go 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.
2DE5RST 10HWe 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.
2DE6POP BCGet the USING string’s length from the stack and put it in register B.
2DE7EX DE,HLLoad DE with the value of the current BASIC program pointer in HL.
2DE8POP HLGet the USING string’s VARPTR from the stack and put it in HL.
2DE9PUSH HLSave the USING string’s VARPTR in HL to the stack.
2DEAPUSH AFSave the character at the location of the current BASIC program pointer in register A to the stack.
2DEBPUSH DESave the value of the current BASIC program pointer in DE to the stack.
2DECLD A,(HL)Load register A with the USING string’s length at the location of the USING string’s VARPTR in HL.
2DEDSUB BCompare the USING string’s length in register B with the USING string’s length in register A.
2DEEINC HLBump the value of the USING string’s VARPTR in HL.
2DEFLD 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.
2DF0INC HLBump the value of the USING string’s VARPTR in HL.
2DF1LD 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.
2DF2LD L,CLoad register L with the LSB of the USING string’s address in register C.
2DF3-2DF4LD D,00HZero register D.
2DF5LD E,ALoad register E with the USING string’s offset in register A.
2DF6ADD HL,DEAdd the USING string’s offset in DE to the USING string’s address in HL.
2DF7LD A,BLoad register A with the USING string’s length in register B.
2DF8OR ACheck to see if this is the end of the USING string.
2E04POP HLGet the value of the current BASIC program pointer from the stack and put it in HL.
2E05POP AFGet the character at the location of the current BASIC program pointer from the stack and put it in register A.
GOSUB to 20FEH to send a carriage return to the current output device if necessary.
2E0CEX (SP),HLExchange the value of the current BASIC program pointer in HL with the value of the USING string’s VARPTR to the stack.
2E10POP HLGet the value of the current BASIC program pointer from the stack and put it in HL.
LD C,01HContinue processing a ! in the USING format by loading register C with the number of characters to be printed.
2E16-2E173E F1Z-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.
2E17POP AF(Skipped if passing down) Clear the stack.
2E18DEC BDecrement the value of the string’s length in register B.
2E1CPOP HLGet the value of the current BASIC program pointer from the stack and put it in HL.
2E1DPOP AFGet the character at the location of the current BASIC program pointer from the stack and put it in register A.
2E1E-2E1FJump 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.
2E20PUSH BCSave the USING string’s length and the number of characters to be printed in BC to the stack.
2E21-2E23Go evaluate the expression at the location of the current BASIC program pointer in HL and return with the result in REG 1
2E27POP BCGet the USING string’s length and the number of characters to be printed from the stack and put it in BC.
2E28PUSH BCSave the USING string’s length and the number of characters to be printed in BC to the stack.
2E29PUSH HLSave the value of the current BASIC program pointer in HL to the stack.
2E2A-2E2CLD HL,(4121H)Load HL with the string’s VARPTR in REG 1.
2E2DLD B,CLoad register B with the number of characters to be printed in register C.
2E2E-2E2FLD C,00HZero register C.
2E30PUSH BCSave the length of the string to be printed in register B to the stack.
2E37-2E39LD HL,(4121H)Load HL with the string’s VARPTR in REG 1.
2E3APOP AFGet the length of the string to be printed from the stack and put it in register A.
2E3BSUB (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.
2EJCLD B,ALoad register B with the number of spaces to be printed in register A.
2EJD-2EJELD A,20HLoad register A with a space.
2E3FINC BBump the number of spaces in register B.This loop will print all the spaces needed and then jump to 2DD3H.
2E49PUSH AFSave the value in register A to the stack.
2E4ALD A,DLoad register A with the value in register D.
2E4BOR ACheck to see if register A is equal to zero.
2E4C-2E4DLD A,2BHLoad register A with a +.
2E51POP AFGet the value from the stack and put it in register A.
2E52RETReturn.
2E53-2FFA – LEVEL II BASIC EDIT ROUTINE
2E53-2E55LD (409AH),AReset the error flag.
Note: 409AH holds the RESUME flag.
2E56-2E58LD HL,(40EAH)Load HL with the line number where the error occurred.
Note: 40EAH-40EBH holds the line number with error.
2E59OR HOR register A with the MSB of the error line number in register H.
2E5AAND LCombine 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.
2E5BINC ABump the combined value of the error line number in register A. If execution had not begin, this will turn A from FFH into 00H
2E5CEX DE,HLLoad DE with the line number with the error (held in HL).
2E5DRET ZIf there was no line number, return if Level II BASIC.
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.
2E63RET NZIf the zero flag got set, there was no line number, so return.
2E65EX DE,HLLoad HL with the line number to be edited in DE.
2E66-2E68LD (40ECH),HLSave 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.
2E69EX DE,HLLoad DE with the line number to be edited in HL.
2E6A-2E6CCall 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.
2E70LD H,BAt this point, the line number has been found. Load register H with the MSB of the memory pointer in register B.
2E71LD L,CLoad register L with the LSB of the memory pointer in register C.
2E72INC HLBump the value of the memory pointer in HL.
2E73INC HLBump the value of the memory pointer in HL.
2E74LD C,(HL)Load register C with the LSB of the BASIC line number at the location of the memory pointer in HL.
2E75INC HLBump the value of the memory pointer in HL.
2E76LD B,(HL)Load register B with the MSB of the BASIC line number at the location of the memory pointer in HL.
2E77INC HLBump the value of the memory pointer in HL.
2E78PUSH BCSave the value of the BASIC line number in BC to the stack.
2E7CPOP HLGet the value of the BASIC line number from the stack and put it in HL.
2E7DPUSH HLSave the value of the BASIC line number in HL to the stack.
2E7E-2E80Convert 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).
2E81-2E82LD A,20HLoad register A with a space.
2E86-2E88LD 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.
2E89-2E8ALD A,0EHLoad register A with the “turn on the cursor” character.
2E8EPUSH HLSave the value of the input buffer pointer (in HL) to the stack.
2E8F-2E90LD C,FFHLoad 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.
2E91INC CBump the number of characters examined so far in register C.
2E92LD A,(HL)Load register A with the character at the location of the input buffer pointer in HL.
2E93OR ACheck to see if the character in register A is an end of the BASIC line character.
2E94INC HLBump the value of the input buffer pointer in HL.
2E97POP HLAt this point, C will be the maximum number of characters in the line at issue. Put the start of the expended buffer into HL.
2E98LD B,AZero register B. B will ultimately contain the count of characters inserted.
2E99-2E9ALD D,00HZero register D.
2D9E-2E9FSUB 30HWe need to test to see if the character was alphabetic or alphanumeric so we subtract 30H from it.
2EA2-2EA3CP 0AHCheck to see if the character is register A is numeric.
2EA6LD E,ALoad register E with the binary value of the character in register A.
2EA7LD A,DLoad register A with the value in register D.
2EA8RLCAMultiply the value in register A by two (so now A has multiplied by 2).
2EA9RLCAMultiply the value in register A by two (so now A has multiplied by 4).
2EAAADD A,DAdd the value in register D to the value in register A (so now A has multiplied by 5).
2EABRLCAMultiply the value in register A by two (so now A has multiplied by 10).
2EACADD A,EAdd the value in register E to the value in register A.
2EADLD D,ALoad register D with the value in register A.
2EB0PUSH HLSave the value of the input buffer pointer in HL to the stack.
2EB1-2EB3LD HL,2E99HLoad HL with the return address of 2E99H.
2EB4EX (SP),HLExchange the value of the return address in HL with the value of the input buffer pointer to the stack.
2EB5DEC DWe 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 …
2EB6INC D… and then incrementing the numeric value in register D.
2EB7-2EB9Jump to 2EBBH if a numeric value preceded the command (i.e., register D isn’t equal to zero).
2EBAINC DLoad register D with a one.
2EBB-2EBCCP 0D8HCheck to see if the character in register A is a backspace character.
2EC0-2EC1CP 0DDHCheck to see if the character in register A is a carriage return.
2EC5-2EC6CP 0F0HCheck to see if the character in register A is a space.
2EC9-2ECACP 31HCheck to see if the character in register A is lowercase.
2ECD-2ECESUB 20HConvert the lowercase character in register A to uppercase.
2ECF-2ED0CP 21HCheck to see if the character in register A is a Q.
2ED4-2ED5CP 1CHCheck to see if the character in register A is an L.
2ED9-2EDACP 23HCheck to see if the character in register A is an S.
2EDD-2EDECP 19HCheck to see if the character in register A is an I.
2EE2-2EE3CP 14HCheck to see if the character in register A is a D.
2EE7-2EE8CP 13HCheck to see if the character in register A is a C.
2EEC-2EEDCP 15HCheck to see if the character in register A is an E.
2EF1-2EF2CP 28HCheck to see if the character in register A is an X.
2EF6-2EF7CP 1BHCheck to see if the character in register A is a K.
2EFA-2EFBCP 18HCheck to see if the character in register A is an H.
2EFF-2F00CP 11HCheck to see if the character in register A is an A.
2F01RET NZReturn if the character in register A isn’t an A.
2F02 – EDIT Command – Cancel and Restore Logic.
2F03POP DEGet the BASIC line number from the stack and put it in DE.
2F0A – 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.
2F0ALD A,(HL)Load register A with the character at the location of the input buffer pointer in HL.
2F0BOR ACheck to see if the character in register A is an end of the BASIC line character.
2F0CRET ZReturn if the character in register A is an end of the BASIC line character.
2F11INC HLBump the value of the input buffer pointer in HL.
2F12DEC DDecrement the number of times to perform the operation in register D.
2F15RETReturn.
2F16 – EDIT Command – KILL Logic.
2F16PUSH HLSave the value of the input buffer pointer in HL to the stack.
2F17-2F19LD HL,2F5FHLoad HL with the return address of 2F5FH (which will print the final !).
2F1AEX (SP),HLExchange the value of the return address in HL with the value of the input buffer pointer to the stack.
2F1BSCFSet the KILL/SEARCH flag for KILL since CARRY flag signals KILL.
2F1CPUSH AFSave the KILL/SEARCH flag to the stack.
2F20LD E,ALoad register E with the character to locate in register A.
2F21POP AFGet the KILL/SEARCH flag from the stack.
2F22PUSH AFSave the KILL/SEARCH flag to the stack.
2F26LD A,(HL)Load register A with the character at the location of the input buffer pointer in HL.
2F27OR ACheck to see if the character in register A is an end of the BASIC line character.
2F28-2F2AJump down to 2F3EH if the character in register A is an end of the BASIC line character.
2F2EPOP AFGet the KILL/SEARCH flag from the stack.
2F2FPUSH AFSave the KILL/SEARCH flag to the stack.
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.
2F35INC HLIf we are here, it must be SEARCH! So bump to the next character.
2F36INC BBump the value of the character position counter in register B.
2F37LD 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.
2F38CP ECheck to see if the character in register A is the same as the character to be located in register E.
2F3BDEC DDecrement the number of times to perform the operation in register D.
2F3EPOP AFGet the KILL/SEARCH flag from the stack.
2F3FRETReturn.
2F40 – EDIT Command – LIST Logic.
2F40-2F42Since 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..
2F46POP BCGet the BASIC line number from the stack and put it in BC.
2F4A – EDIT Command – DELETE Logic.
2F4ALD A,(HL)Load register A with the character at the location of the input buffer pointer in HL.
2F4BOR ACheck to see if the character in register A is an end of the BASIC line character.
2F5CRET ZReturn if the character in register A is an end of the BASIC line character.
2F52LD A,(HL)Load register A with the character at the location of the input buffer pointer in HL.
2F53OR ACheck to see if the character in register A is an end of the BASIC line character.
2F54-2F5BJump to 2F5FH if the character in register A is an end of the BASIC line character.
2F5CDEC DDecrement the number of times to perform the operation in register D.
2F5F-2F60LD A,21HLoad register A with an !.
2F64RETReturn.
2F65 – EDIT Command – CHANGE Logic.
2F65LD A,(HL)Load register A with the character at the location of the input buffer pointer in HL.
2F66OR ACheck to see if the character in register A is an end of the BASIC line character.
2F67RET ZReturn if the character in register A is an end of the BASIC line character.
2F6BLD (HL),ASave the character in register A at the memory location of the input buffer pointer in HL.
2F6FINC HLBump the value of the input buffer pointer in HL.
2F70INC BBump the character position in register B.
2F71DEC DDecrement the number of times to perform the operation in register D.
2F74RETReturn.
2F75 – EDIT Command – HACK/INSERT Logic.
2F75-2F76LD (HL),00HZero the location of the input buffer pointer in HL.
2F77LD C,BLoad register C with the character position in register B.
2F78-2F79LD D,0FFHLoad register D with the number of times to perform the operation.
2F80OR ACheck to see if a key was pressed.
2F84-2F85CP 08HCheck to see if the character in register A is a backspace character.
2F88-2F89CP 0DHCheck to see if the character in register A is a carriage return.
2F8D-2F8ECP 1BHCheck to see if the character in register A is a shift up arrow.
2F8FRET ZReturn if the character in register A is shift up arrow.
2F92 – EDIT Command – BACKSPACE CURSOR Logic.
2F92-2F93LD A,08HLoad register A with a backspace the cursor character.
2F94DEC BDecrement the character position in register B.
2F95INC BBump the character position in register B.
2F9BDEC HLDecrement the value of the input buffer pointer in HL.
2F9CDEC BDecrement the character position in register B.
2F9D-2F9FLD DE,2F7DHLoad DE with a return address of 2F7DH.
2FA0PUSH DESave the value of the return address in DE to the stack.
2FA1PUSH HLSave the value of the input buffer pointer in HL to the stack.
2FA2DEC CDecrement the character position in register C.
2FA3LD A,(HL)Load register A with the character at the location of the input buffer pointer in HL.
2FA4OR ACheck to see if the character in register A is an end of the BASIC line character.
2FA5SCFSet the Carry flag to signal that the character was deleted.
2FA6-2FA8Jump to 0890H if the character in register A is an end of the BASIC line character.
2FA9INC HLBump the value of the input buffer pointer in HL.
2FAALD A,(HL)Load register A with the character at the location of the input buffer pointer in HL.
2FABDEC HLDecrement the value of the input buffer pointer in HL.
2FACLD (HL),ASave the character in register A at the location of the current input buffer pointer in HL.
2FADINC HLBump the value of the input buffer pointer in HL.
2FB0 – EDIT Command – ADD A CHARACTER Logic.
2FB0PUSH AFSave the character to be inserted in register A to the stack.
2FB1LD A,CLoad register A with the number of characters in the input buffer in register C.
2FB2-2FB3CP FFHCheck for the maximum BASIC line length.
2FB6POP AFGet the character to be inserted from the stack and put it in register A.
2FB9SUB BSubtract 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.
2FBAINC CBump the number of characters in the input buffer in register C.
2FBBINC BBump the character position in register B.
2FBCPUSH BCSave the character position and the number of characters in the input buffer in BC to the stack.
2FBDEX DE,HLLoad DE with the input buffer pointer in HL.
2FBELD L,ALoad register L with the character count in register A.
2FBF-2FC0LD H,00HZero register H.
2FC1ADD HL,DEAdd the value of the input buffer pointer in DE to the character count in HL.
2FC2LD B,HLoad register B with the MSB of the end of the BASIC line pointer in register H.
2FC3LD C,LLoad register C with the LSB of the end of the BASIC line pointer in register L.
2FC4INC HLBump the value of the end of the BASIC line pointer in HL.
2FC8POP BCGet the character position and the number of characters in the input buffer from the stack and put it in BC.
2FC9POP AFGet the character to be inserted from the stack and put it in register A.
2FCALD (HL),ASave the character in register A at the location of the current input buffer pointer in HL.
2FCEINC HLBump the value of the input buffer pointer in HL.
2FD2 – EDIT Command – BACKSPACE Logic.
2FD2LD A,BLoad register A with the number of times to backspace in register B.
2FD3OR ACheck to see if this is the start of the BASIC line.
2FD4RET ZReturn if this is the start of the BASIC line.
2FD6DEC HLDecrement the value of the input buffer pointer in HL.
2FD7-2FD8LD A,08HLoad register A with a backspace the cursor character.
2FDCDEC DDecrement the number of times to perform the operation in register D.
2FDFRETReturn.
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..
2FE6POP BCClean up the stack.
2FE7POP DEGet the BASIC line number (in binary) from the stack and put it in DE.
2FE8LD A,DLoad register A with the MSB of the BASIC line number in register D.
2FE9AND ECombine the LSB of the BASIC line number in register E with the MSB of the BASIC line number in register A.
2FEAINC ABump the combined BASIC line number in register A.
2FEB-2FEDLD HL,(40A7H)Load HL with the starting address of the input buffer.
Note: 40A7H-40A8H holds the input Buffer pointer.
2FEEDEC HLDecrement the value of the input buffer pointer in HL.
2FEFRET ZReturn if this is the Level II BASIC command mode.
2FF1INC HLBump the value of the input buffer pointer in HL.
2FF2PUSH AFSave the command mode flag in AF to the stack.
2FF6 – EDIT Command – QUIT Logic.
2FF6POP BCClean up the stack.
2FF7POP DEGet the BASIC line number from the stack and put it in DE.
2FFB-2FFFDEC3C344B2Garbage Code.
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
“TSTYP”
Note: 40AFH holds Current number type flag.
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.
2C
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).
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.
Note: 40AEH holds LOCATE/CREATE variable flag.
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.
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.
NOTE: 4101H-411AH holds Variable Declaration Table.
NOTE: 40AFH holds Current number type flag.
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.
Note: 40DCH holds FOR flag.
Note: 40DCH holds FOR flag.
- Note: 40F9H-40FAH holds the starting address of the simple variable storage area.
- Note: 40FBH-40FCH holds the starting address of the BASIC array variable storage area.
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.
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.
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.
Note: 40FDH-40FEH holds Free memory pointer.
NOTE: 40FDH-40FEH holds Free memory pointer.
- Note: 40FBH-40FCH holds the starting address of the BASIC array variable storage area.
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.
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.
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.
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.
29
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).
NOTE: 40F3H-40F4H holds Temporary storage location.
NOTE: 40AEH holds LOCATE/CREATE variable flag.
- Note: 40FBH-40FCH holds the starting address of the BASIC array variable storage area.
Note: 40FDH-40FEH holds Free memory pointer.
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.
Note: 40AFH holds Current number type flag.
Note: 40AEH holds LOCATE/CREATE variable flag.
Note: 40D8H-40D9H holds temporary storage location.
Note: 40AEH holds LOCATE/CREATE variable flag.
Note: 40FDH-40FEH holds free memory pointer.
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.
Note: 40D8H-40D9H holds Temporary storage location.
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.
NOTE: 40AFH holds Current number type flag.
Note: 40F3H-40F4H holds Temporary storage location.
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.
NOTE: 40AFH holds Current number type flag.
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.
NOTE: 40FDH-40FEH holds Free memory pointer.
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.
NOTE: 40A0H-40A1H holds the start of string space pointer.
NOTE: 40D6H-40D7H holds Next available location in string space pointer.
Note: 40A6H holds the current cursor line position.
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.
Note: 40AFH holds Current number type flag.
(02=INT, 03=STR, 04=SNG, 08=DBL).
- Note: 408EH-408FH holds the entry address of a machine language program to be called by a USR command.
Usually called by LET to convert the result of arithmetic routines to the proper destination type.
(02=INT, 03=STR, 04=SNG, 08=DBL).
Usually called from the INPUT routine. On entry HL has the current line number in binary.
- Note: 40A2H-40A3H holds the current BASIC line number.
Note: 40D3H-40D5H holds Used for temporary string VARPTR’s.
This is the quote routine. C will be a counter.
“CSVEC”
Note: 40D3H-40D5H holds Used for temporary string VARPTR’s.
Note: 40B3H-40B4H holds Next available location in the temporary string work area pointer.
Note: 40AFH holds Current number type flag.
Note: 40D6H-40D7H holds Next available location in string space pointer.
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.
Note: 40B3H-40B4H holds Next available location in the temporary string work area pointer.
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.
“DSTR”
- Note: 40A0H-40A1H holds the start of string space pointer.
Note: 40D6H-40D7H holds Next available location in string space pointer.
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.
Note: 40D6H-40D7H holds Next available location in string space pointer.
Note: 40B1H-40B2H holds MEMORY SIZE? pointer.
Note: 40D6H-40D7H holds Next available location in string space pointer.
NOTE: 40A0H-40A1H holds the start of string space pointer.
Note: 40B5H-40D2H holds Temporary string work area.
NOTE: 40B3H-40B4H holds Next available location in the temporary string work area pointer.
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.
NOTE: 40F9H-40FAH holds the starting address of the simple variable storage area.
- Note: 40FBH-40FCH holds the starting address of the BASIC array variable storage area.
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.
Note: 40FDH-40FEH holds Free memory pointer.
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.
Note: 40D8H-40D9H holds Temporary storage location.
Note: 40D8H-40D9H holds Temporary storage location.
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.
NOTE: 40D6H-40D7H holds Next available location in string space pointer.
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.
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.
NOTE: 40D6H-40D7H holds Next available location in string space pointer.
On entry, the stack should have the count/source address and DE should have the destination address.
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.
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.
Note: 40D6H-40D7H holds Next available location in string space pointer.
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.
Note: 40D6H-40D7H holds Next available location in string space pointer.
Note: 40B3H-40B4H holds Next available location in the temporary string work area pointer.
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.
Note: 40B3H-40B4H holds Next available location in the temporary string work area pointer.
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.
28
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).
2C
29
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).
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.
2C
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).
29
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).
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.
29
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).
Note: 4093H-4095H holds INP routine.
Note: 4096H-4098H holds OUT routine.
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.
2E
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).
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.
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.
This routine sets the output device flag to PRINTER and then flows through to the LIST command.
Note: 409CH holds the current output device flag: -1=cassette, 0=video and 1=printer.
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.
- Note: 40A2H-40A3H holds the current BASIC line number.
In NEWDOS 2.1, this is called from LIST processing.
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.
Note: 40ECH-40EDH holds EDIT line number.
Note: 40A7H-40A8H holds the input Buffer pointer.
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 41C1H.
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.
Note: 40A7H-40A8H holds the input Buffer pointer.
Difference between M1 and M3 ROMs: This change is to the LIST command. JP 069AH in the Model III replaces LD D,0FFH followed by JR 2B8CH in the Model I.
Difference between M1 and M3 ROMs: Another change to LIST. In the Model I three instructions occupied this area: LD A,(HL); OR A; INC HL. In the Model III the INC HL instruction is moved to the beginning of the three.
Difference between M1 and M3 ROMs: The final change to LIST – a JP P,2B89H instruction in the Model I is changed to a JP 302DH instruction in the Model III.
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.
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).
- Note: 40F9H-40FAH holds the starting address of the simple variable storage area.
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.
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.
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).
- Note: 40F9H-40FAH holds the starting address of the simple variable storage area.
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.
- Note: 40F9H-40FAH holds the starting address of the simple variable storage area.
- Note: 40A4H-40A5H holds the starting address of BASIC program text also known as the PROGRAM STATEMENT TABLE (PST).
- Note: 40F9H-40FAH holds the starting address of the simple variable storage area.
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.
Difference between M1 and M3 ROMs:Another change that originated in the “new” ROM Model I modified the CLOAD command (changed the order of portions of the CLOAD routine, disallowed CLOAD from cassette drive #2, etc.).
- Note: 40A4H-40A5H holds the starting address of BASIC program text also known as the PROGRAM STATEMENT TABLE (PST).
- Note: 40F9H-40FAH holds the starting address of the simple variable storage area.
Difference between M1 and M3 ROMs: Also part of CLOAD, this change turns off the tape before printing READY on the video display. In the Model I, the code from 2C7AH – 2C82H consisted of the instructions LD HL,1929H; CALL 28A7H, CALL 01F8H. In the Model III the CALL to 01F8H has been moved to the beginning of these instructions.
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).
- Note: 40A4H-40A5H holds the starting address of BASIC program text also known as the PROGRAM STATEMENT TABLE (PST).
Difference between M1 and M3 ROMs: This is part of the CLOAD? routine used when a bad byte has been read from the tape. In the Model I, a LD HL, 2CA5H instruction is found here (loads HL with the starting address of the “BAD” message), while the Model III uses a CALL 31BDH instruction, which does some housekeeping in addition to pointing HL to the “BAD” message.
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).
2E
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).
3B
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).
Note: 40DEH holds READ flag.
Note: 40DEH holds READ flag.
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).
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.
Note: 40DEH holds READ flag.
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.
Note: 409AH holds the RESUME flag.
Note: 40EAH-40EBH holds the line number with error.
Note: 40ECH-40EDH holds EDIT line number.
Note: 40A7H-40A8H holds the input Buffer pointer.
Note: 409CH holds the current output device flag: -1=cassette, 0=video and 1=printer.
Note: 40A7H-40A8H holds the input Buffer pointer.