Page Customization:

Display OPCodes

Display Labels

1034 – LEVEL II BASIC MATH ROUTINE – “FOUINI”

Initially set up the format specs and put in a SPACE for the sign of a positive number. This routine gets called by the FLOATING to ASCII Conversion Routine (at 0FBEH) and by the BINARY to ASCII Conversion Routine (at 0FAFH)

Note: 40D8H-40D9H holds the temporary storage location

103D – LEVEL II BASIC MATH ROUTINE – “FOUFRV”

This routine gets called by the FLOATING to ASCII Conversion Routine (0FBEH-0FC0H) if the value being converted is either Single Precision or Double Precision. This will print a single or double precision number in free format

OK, this is fun. The next instructions are supposed to set Register D to be the counter for the number of digits to display. There is no agreement on what the next two instructions do:

“Microsoft BASIC Decoded & Other Mysteries” says it turns 04 (SP) and 08 (SP) into 08 (SP) and 10 (DP) into 09 (SP) and 0B (DP)

“Model III ROM Commented” says it turns D into 07 (SP) and 17 (DP)

The original ROM Source Code comment says it turns D into 04 to 06 (SP) and 10 to 20 (DP)

The FOFRS2 routine will suppress trailing zeroes.

At this point, all trailing zeroes are now gone and HL points to the last non-zero character.

1074 – LEVEL II BASIC MATH ROUTINE – “FOFLDN”

This routine will put the exponent and a D or E into the buffer. On entry, Register A holds the exponent and it is assumed that all FLAGs are set correctly.

↳ FOFLDN

1085 – LEVEL II BASIC MATH ROUTINE – “FOUCE1” and “FOUCE2”

This routine will calculate the two digit exponent.

↳ FOUCE1

1093 – LEVEL II BASIC MATH ROUTINE – “FOUTDN”

This routine will print a free format zero.

↳ FOUTDN

Note: 4130H-4149H holds an internal print buffer

109A- LEVEL II BASIC MATH ROUTINE – “FOUTFX”

This routine will print a number in fixed format.

↳ FOUTFX

If we are here then we are going to print an integer in fixed format/fixed point notation.

10BF – LEVEL II BASIC MATH ROUTINE – “FOUTTS”

This routine will finish up the printing of a fixed format number.

Now we need to check to see if the fixed format/fixed point number overflowed its field length. The location if the decimal point needs to be in TEMP2.

10DF – LEVEL II BASIC MATH ROUTINE – “FOUBE2”

In this routine, we check to see if we can ignore the leading zero before a decimal point. We can do this if if we see the following: (in order)

+,- a sign (either “-” or “+”) [optional] $ a dollar sign [optional] 0 a zero [mandatory] . a decimal point [mandatory] 0-9 another digit [mandatory]

If we see a leading zero, it must be the one before a decimal point or else FOUTZS would have akready suppressed it. In that case, we just INC HL over the character following the zero, and not have to check for the decimal point explicitly.

↳ FOUBE2

The RST 10H routine parses the characters starting at HL+1 for the first non-SPACE,non-09H,non-0BH character it finds. On exit, Register A will hold that character, and the C FLAG is set if its alphabetic, and NC FLAG if its alphanumeric. All strings must have a 00H at the end.

The RST 10H routine parses the characters starting at HL+1 for the first non-SPACE,non-09H,non-0BH character it finds. On exit, Register A will hold that character, and the C FLAG is set if its alphabetic, and NC FLAG if its alphanumeric. All strings must have a 00H at the end.

10F9 – LEVEL II BASIC MATH ROUTINE – “FOUBE3”

If we can get rid of the zero, we put the characters on the STACK back into the buffer one position in front of where they originally were.

Note that the maximum number of STACK levels this uses is three — one for the last entry flag, one for a possible sign, and one for a possible dollar sign.

We don’t have to worry about the first character being in the buffer twice because the pointer when FOUT exits will be pointing to the second occurance.

↳ FOUBE3

1102 – LEVEL II BASIC MATH ROUTINE – “FOUBE4”

If the number is too big for the field, we wind up here to deal with that.

1109 – LEVEL II BASIC MATH ROUTINE – “FOUFXV”

This is where the PRINT USING routine will print a single or double precision number in a fixed format

↳ FOUFXV

If we are here, then we are printing a DOUBLE PRECISION number in fixed format/fixed point notation

111B – LEVEL II BASIC MATH ROUTINE – “FFXSDO”

This routine will print a number which is greaster than 10^16 in free format with a percent sign

↳ FFXSDO

1124 – LEVEL II BASIC MATH ROUTINE – “FFXSFX”

This routine will print a SINGLE PRECISION number in fixed format/fixed point notation

The results are stored in A as follows:

If ACCumulator = BCDE | A=00 |

If ACCumulator > BCDE | A=01 |

If ACCumulator < BCDE | A=FF |

1124 – LEVEL II BASIC MATH ROUTINE – “FFXSDC”

This routine will print a SINGLE PRECISION or DOUBLE PRECISION number in fixed format/fixed point notation

This routine will print a number that has no fractional digits

If the field length is higher than the number of characters we actually have, we are going to need to put in that number of leading zeroes.

1157 – LEVEL II BASIC MATH ROUTINE – “FFXXVS”

This routine will print a SINGLE PRECISION or DOUBLE PREVISION number that has fractional digits

↳ FFXXVS

This routine will print numbers with integer digits, and will print some leading zeroes if the field is bigger than the number of digits we need to print.

117F – LEVEL II BASIC MATH ROUTINE – “FFXXV3”

This routine will print a number without integer digits.

↳ FFXXV3

Note: 40F3H-40F4H is a temporary storage location

119A – LEVEL II BASIC MATH ROUTINE – “FFXXV7”

This routine will print trailing zeroes.

↳ FFXXV7

11A3 – LEVEL II BASIC MATH ROUTINE – “FFXIFL”

This routine will print an integer in fixed format/floating point notation.

↳ FFXIFL

11AA – LEVEL II BASIC MATH ROUTINE – “FFXFLV”

This routine will print a SINGLE or DOUBLE PRECISION number in fixed format/floating point notation.

↳ FFXFLV

1201 – Test the magnitude of SP and DP numbers, and clear the times the value was scaled – “FOUTNV”

This routine will scale (normalize) the number in the accumulator so that all the digits are in the integer part (i.e., between 99,999 and 999,999). The signed base 10 exponent is returned in Register A. Registers D and E are unchanged.

NOTE: The RST 20H routine determines the type of the current value in ACCumulator 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.

1222 – LEVEL II BASIC MATH ROUTINE – “FOUNDB”

There is a big bug in this routine which was fixed in v1.2 of the ROM. The fixing of that bug caused a renumbering from 1228H-124CH. The numbering here will show both.

NOTE: The RST 20H routine determines the type of the current value in ACCumulator 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.

The next two instructions load BCDE with 99999.95 so as to check to see if the number in FAC is too big.

*1228-122A

*122B-122D

*122E-1230

The results are stored in A as follows:

If ACCumulator = BCDE | A=00 |

If ACCumulator > BCDE | A=01 |

If ACCumulator < BCDE | A=FF |

*1236-1238

*123C

*123D-123F

*1240

1241-1242

1244-1246

1247

*1248-124A

124C

*124D

124F – LEVEL II BASIC MATH ROUTINE – “FOUNVC”

This routine will see if the number in the ACCumulator is small enough yet

↳ FOUNVC

NOTE: The RST 20H routine determines the type of the current value in ACCumulator 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.

The next two instructions load BCDE with 999999.5 to see if the number in the FAC is too large.

The results are stored in A as follows:

If ACCumulator = BCDE | A=00 |

If ACCumulator > BCDE | A=01 |

If ACCumulator < BCDE | A=FF |

1269H – LEVEL II BASIC MATH ROUTINE – “FOTZER”

This routine puts leading zeroes into the input buffer. The count is held in Register A and it can be zero, but the Z FLAG needs to be set in that case. Only (HL) and Register A are affected.

1271 – LEVEL II BASIC MATH ROUTINE – “FOTZNC”

This routine will put zeroes in the buffer along with commans or a decimal point in the middle. The count is held in Register A and it can be zero, but the Z FLAG needs to be set in that case. Registers B (decimal point count) and C (comma count) are updated accordingly. Everything but DE is affected.

127D – LEVEL II BASIC MATH ROUTINE – “FOUTCD”

This routine will put a possible comma count into Register C and will zero Register C if we are not using commas in the specification.

↳ FOUTCD

1291 – LEVEL II BASIC MATH ROUTINE – “FOUTED”

This routine will put decimal points and commas in their correct places. This subroutine should be called before the next digit is put in the buffer. Register B = the decimal point count and Register C = the comma count.

The counts tell how many more digits have to go in before the comma ;or decimal point go in.

The comma or decimal point then goes before the last digit in the count. For example, if the decimal point should come after the first digit, the decimal point count should be 2.

Note: 40F3H-40F4H is a temporary storage location

129C – LEVEL II BASIC MATH ROUTINE – “FOUED1”

Part of the above routine, jumped here to test to see if a comma needs to be placed at (HL).

↳ FOUED1

12A4 – LEVEL II BASIC MATH ROUTINE – “FOUTCV”

This routine will convert a SINGLE PRECISION or a DOUBLE PRECISION number that has been normalized to decimal digits. The decimal point count is in Register B and the comma count is in Register C. (HL) points to where the first digit will go. Routine will exit with A=0.

↳ FOUTCV

NOTE: The RST 20H routine determines the type of the current value in ACCumulator 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.

Top of a loop to convert the next digit. It is executed “A” times.

12EA – LEVEL II BASIC MATH ROUTINE – “FOUTCS”

This routine is to convert a SINGLE precision value to an INTEGER which will be the decimal digits. Divide the integer equivalent by 100,000 and 10,000. Use the code at 1335H to convert the last 1000 to ASCII.

12FC – LEVEL II BASIC MATH ROUTINE – “FOUCS1”

This routine is to calculate the next digit of the number.

↳ FOUCS1

130A – LEVEL II BASIC MATH ROUTINE – “FOUCS2”

This routine divides the integer portion of the current value by 100,000 using compound subtraction. The quotient is kept in Register B as an ASCII value.

↳ FOUCS2

132F – This routine will convert an INTEGER to ASCII – “FOUTCI”

This routine converts an integer into decimal digits by dividing the integer portion of the current value by 100,000 using compound subtraction. The quotient is kept in Register B as an ASCII value and A=0 on exit.

This loop divides the current value by a power of 10 starting at 10,000 and working down to 10. The remainder frome ach division is added to the division and the sum becomes the dividend for the next division until done. The quotient is +2FH (which is the ASCII equivalent of a quotient).

1364-136B – DOUBLE PRECISION CONSTANT STORAGE LOCATION – “TENTEN”

↳ TENTEN

136C-1373 – DOUBLE PRECISION CONSTANT STORAGE LOCATION – “FOUTDL”

↳ FOUTDL

1374-137B – DOUBLE PRECISION CONSTANT STORAGE LOCATION – “FOUTDU”

↳ FOUTDU

137C-1383 – DOUBLE PRECISION CONSTANT STORAGE LOCATION – “DHALF”

↳ DHALF

BYTE SAVING NOTE: Referencing 1380H, which is half-way through this double precision value of .5, results in a single precision value of 0.5

↳ FHALF

BYTE SAVING NOTE: Referencing 1380H, which is half-way through this double precision value of .5, results in a single precision value of 0.5

1384-138B – DOUBLE PRECISION CONSTANT STORAGE LOCATION – “FFXDXM”

↳ FFXDXM

138C-13D1 – DOUBLE PRECISION INTEGER CONSTANT STORAGE LOCATION – “FODTBL”

↳ FODTBL

13D2-13D9 – SINGLE PRECISION POWER OF TEN TABLE LOCATION – “FOSTBL

↳ FOSTBL

13D8 – SINGLE PRECISION POWER OF TEN TABLE LOCATION – “FOITBL

↳ FOITBL

13E2-13E6 – LEVEL II BASIC MATH ROUTINE – “PSHNEG”

13E7-13F1 – LEVEL II BASIC SQR(n) – “SQR”

This routine computes the square root of any value in ACCumulator. It processes it by raising n to the power of 0.5. The root is left in ACCumulator as a single precision value. Single-precision values only should be used

↳ SQR

13F2-1478H LEVEL II BASIC X to the Y Power (X^Y) ROUTINE – “FPWRQ”

A call to 13F2H raises the single precision value which has been saved to the STACK to the power specified in ACCumulator. The result will be returned in ACCumulator. The method of computation is e ** (y ln x).

↳ FPWRQ

13F7 – LEVEL II BASIC Exponentiation routine – “FPWR”

This routine handles the exponentiation routine of X^Y. To do so, first Y is checked for 0 and, if so, then the answer is simply 1. Then we check X for 0 and, if so, then the answer is simply 0.

If neither of those scenarios is the case, then must check to see if X is positive and, if not, check to see if Y is negative and if it is even or odd.

If Y is negative, the we negate it to avoid the LOG routine giving a ?FC ERROR when we call it.

If X is negative and Y is odd, the NEG routine is pushed to the STACK as the exit rouine so that the result will be negative.

The actual math here is X^Y = EXP(Y*LOG(X)).

↳ FPWR

/0 ERROR entry point

The results are stored in A as follows:

If ACCumulator = BCDE | A=00 |

If ACCumulator > BCDE | A=01 |

If ACCumulator < BCDE | A=FF |

1439 – LEVEL II ROM EXP ROUTINE.

Single-precision only. (ACCumulator = EXP(REG1)).

To process this function we first save the original argument and multiply the ACCumulator by log2(e). The result of that is then used to determine if we will get overflow, since exp(x)=2^(x*log2(e)) where log2(e)=log(e) base 2.

We then save the integer part of this to scale the answer at the end, since 2^y=2^int(y)*2^(y-int(y)) and 2^int(y) is easy to compute.

So in the end we compute 2^(x*log2(e)-int(x*log2(e))) by p(ln(2)*(int(x*log2(e))+1)-x) where p is an approximation polynomial.

The result is then scaled by the power of 2 we previously saved.

A call to 1439H raises E (natural base) to the value in ACCumulator which must be a single precision value. The result will be returned in ACCumulator as a single precision number.

1479-1499 – SINGLE PRECISION CONSTANT STORAGE LOCATION

This represents 1/6, -1/5, 1/4, -1/3, 1/2, -1, and 1 – “EXPCON”

↳ EXPCON

149A-14C8 – LEVEL II BASIC MATH ROUTINE – “POLYX”

This is a general purpose summation routine which computes the series C0*X+C1*X^3+C2*X^5+C3*X^7+…+C(N)*X^(2*N+1) for I=0 to N when entered at 149AH If entered at 14A9H the series changes to SUM ((((x*c0+c1)x*c2)x+c3)x+.cN. On entry, the x is held in BC/DE and HL points to a list containing the number of terms followed by the coefficients.

The pointer to degree+1 is in (HL) and the constants should follow the egree, stored in reverse order. X is in the ACCumulator.

14A9 – LEVEL II BASIC MATH ROUTINE – “POLY”

General polynomial evaluator routine. Pointer to degree+1 is in (HL), and that gets updated through the computation. The Constants follow the degree and should be stored in reverse order. The ACCumulator has the X. The formula is c0+c1*x+c2*x^2+c3*x^3+…+c(n-1)*x^(n-1)+c(n)*x^n

PUSH BCD5

14C9-1540 – LEVEL II BASIC RND(n) ROUTINE – “RND”.

If the passed argument is 0, the last random number generated is returned. If the argument is < 0, a new sequence of random numbers is started using the argument.

To form the next random number in the sequence, we multiply the previous random number by a random constant, and add in another random constant. Then the HIGH ORDER and LOW ORDER bytes are switched, the exponent is put where it will be shifted in by normal, and the exponent in the ACCUMULATOR is set to 80H so the result will be less than 1. This is then normalized and saved for the next time.

The reason we switch the HIGH ORDER and LOW ORDER bytes is so we have a random chance of getting a number less than or greater than .5

Integer, single or double-precision. Output will be single-precision. (ACC=RND (ACC))

A call to 14C9H Generates a random number between 0 and 1, or 1 and n depending on the parameter passed in ACCumulator, The random value is returned in ACCumulator as an integer with the mode flag set. The parameter passed will determine the range of the random number returned. A parameter of 0 will return an interger between 0 and 1. A parameter greater than 0 will have any fraction portion truncated and will cause a value between 1 and the integer portion of the parameter to be returned.

There is a bug in the operation of this command. According to Vernon Hester RND(n) where n is an integer from 1 to 32767 is supposed to return an integer from 1 to n. However, when n is a power of two raised to a positive integer exponent from 0 to 14 sometimes returns n+1

↳ RND

POP DEC1

14F0 – This routine calculates RND(0) – “RND0”.

Note: 40AAH-40ADH holds the random number seed

Note: 40AAH-40ADH holds the random number seed

Note: 4125H-4126H is used by floating point routines

1541-1546 – LEVEL II BASIC COS

ROUTINE – “COS”.

Single-precision only.(ACCumulator = COS(ACCumulator)). A call to 1541H computes the cosine for an angle given in radians. The angle must be a floating point value in ACCumulator; the cosine will be returned in ACCumulator as a floating point value.

The formula being used is COS(X) = SIN(X+PI/2)

1547-158A – LEVEL II BASIC SIN ROUTINE – “SIN”

Single-precision only.(ACCumulator = SIN(ACCumulator)).

A call to 1549H returns the sine as a single precision value in ACCumulator. The sine must be given in radians in ACCumulator.

The actual calculation routine is:

- Assume X <= 360 degrees.
- Recompute x as x=x/360 so that x=< 1.
- If x <= 90 degrees go to step 7.
- If x <= 180 degrees then x=0.5-x and then go to step 7.
- If x <= 270 degrees then x=0.5-x.
- Recompute x as x=x-1.0.
- Compute SIN using the power series.

POP DEC1

POP DEC1

158B-158E – SINGLE PRECISION CONSTANT STORAGE LOCATION – “PI2”

↳ PI2

158F-1592 – SINGLE PRECISION CONSTANT STORAGE LOCATION – “FR4”

↳ FR4

1593-15A7 – SINGLE PRECISION CONSTANTS STORAGE LOCATION – “SINCON”

↳ SINCON

15A8-15BC – LEVEL II BASIC TAN(n) ROUTINE – “TAN”

Single-precision only.(ACCumulator = TAN(ACCumulator)).

A call to 15A8H computes the tangent of an angle in radians. The angle must be specified as a single precision value in ACCumulator. The tangent will be left in ACCumulator.

Uses the fact that TAN(x) = SIN(x) / COS(x)

↳ TAN

POP HLC1

15BD-15E2 – LEVEL II BASIC ATN(n) ROUTINE – “ATN”.

Single-precision only.(ACCumulator = ATN(ACCumulator)).

A call to 15BD returns the angle in radians, for the floating point tangent value in ACCumulator. The angle will be left as a single precision value in ACCumulator.

The method of computation used in this routine is:

- Test the sign of the tangent to see if a negative angle is in the 2nd or 4th quadrant. Set the flag to force the result to positive on exit. If the value is negative, invert the sign.
- Test magnitude of tangent. If it is < 1 go to step 3. Otherwise, compute its reciprocal and put the return address on the STACK that will calculate pi/2 – series value.
- Evaluate the series: (((x^2*c0+c1) x^2+c2) . c8)x
- If the flag from step 1 is not set, then invert the sign of the series result.
- If the original value is < 1 then return to the caller. Otherwise, compute pi/2-value from step 4 and then return.

↳ ATN

15E3-1607 – SINGLE PRECISION CONSTANTS STORAGE LOCATION – “ATNCON”

↳ ATNCON

1608-18C8 – LIST OF BASIC RESERVED WORDS, TOKENS, AND ENTRY LOCATIONS AS FOLLOWS:

The original ROM source code makes an interesting note about the order of these reserved words. Some reserved words are contained in other reserved words, which will cause a problem. They given examples of:SO, the smaller word always has to appear later in the reserved word table.

- IF J=F OR T=5 will process a FOR
- INP is part of INPUT
- IF T OR Q THEN will process a TO

ABS | D9 | 0977 | | | AND | D2 | 25FD |

ASC | F6 | 2A0F | | | ATN | E4 | 15BD |

AUTO | B7 | 2008 | | | CDBL | F1 | 0ADB |

CHR$( | F7 | 2A1F | | | CINT | EF | 0A7F |

CLEAR | B8 | 1E7A | | | CLOAD | B9 | 2C1F |

CLOSE | A6 | 4185 | | | CLS | 84 | 01C9 |

CMD | 85 | 4173 | | | CONT | B3 | 1DE4 |

COS | El | 1541 | | | CSAVE | BA | 2BF5 |

CSNG | F0 | 0ABl | | | CVD | E8 | 415E |

CVI | E6 | 4152 | | | CVS | E7 | 4158 |

DATA | 88 | 1F05 | | | DEF | DD | 415B |

DEFDBL | 9B | 1E09 | | | DEFINT | 99 | 1E03 |

DEFSNG | 9A | 1E06 | | | DEFSTR | 98 | 1E00 |

DELETE | B6 | 2BC6 | | | DIM | 8A | 2608 |

EDIT | 9D | 2E60 | | | ELSE | 95 | 1F07 |

END | 80 | 1DAE | | | EOF | E9 | 4161 |

ERL | C2 | 24DD | | | ERR | C3 | 24CF |

ERROR | 9E | 1FF4 | | | EXP | E0 | 1439 |

FIELD | A3 | 417C | | | FIX | F2 | 0B26 |

FN | BE | 4155 | | | FOR | 81 | 1CA1 |

FRE | DA | 27D4 | | | GET | A4 | 4174 |

GOSUB | 91 | 1EB1 | | | GOTO | 5D | 1EC2 |

IF | 8F | 2039 | | | INKEY$ | C9 | 019D |

INP | DB | 2AEF | | | INPUT | 89 | 219A |

INSTR | C5 | 419D | | | INT | D8 | 0B37 |

KILL | AA | 4191 | | | LEFT$ | F8 | 2A61 |

LEN | F3 | 2A03 | | | LET | 8C | 1F21 |

LINE | 9C | 41A3 | | | LIST | B4 | 2B2E |

LLIST | B5 | 2B29 | | | LOAD | A7 | 4188 |

LOC | EA | 4164 | | | LOF | EB | 4167 |

LOG | DF | 0809 | | | LPRINT | AF | 2067 |

LSET | AB | 4197 | | | MEM | C8 | 27C9 |

MERGE | A8 | 418B | | | MID$ | FA | 2A9A |

MKD$ | EE | 4170 | | | NAME | A9 | 418E |

NEW | BB | 1B49H | | | NEXT | 87 | 22B6 |

NOT | CB | 25C4 | | | ON | A1 | 1FC6 |

OPEN | A2 | 4179 | | | OR | D3 | 25F7 |

OUT | AO | 2AFB | | | PEEK | E5 | 2CAA |

POINT | C6 | 0132 | | | POKE | B1 | 2CB1 |

POS | DC | 27F5 | | | B2 | 206F | |

PUT | A5 | 4182 | | | RANDOM | 86 | 01D3 |

READ | 8B | 21EF | | | REM | 93 | 1F07 |

RESET | 82 | 0138 | | | RESTORE | 90 | 1D91 |

RESUME | 9F | 1FAFH | | | RETURN | 92 | 1EDEH |

RIGHT$ | F9 | 2A91 | | | RND | DE | 14C9 |

RSET | AC | 419A | | | RUN | 8E | 1EA3 |

SAVE | AD | 41A0 | | | SET | 83 | 0135 |

SGN | D7 | 098A | | | SIN | E2 | 1547 |

SQR | CD | 13E7 | | | STEP | cc | 2B01 |

STOP | 94 | 1DA9 | | | STR$ | F4 | 2836 |

STRING$ | C4 | 2A2F | | | SYSTEM | AE | 02B2 |

TAB( | BC | 2137 | | | TAN | E3 | 15A8 |

THEN | CA | | | TIME$ | C7 | 4176 | |

TO | BD | | | TROFF | 97 | 1DF8 | |

TRON | 96 | 1DF8 | | | USING | BF | 2CBD |

USR | C1 | 27FE | | | VAL | FF | 2AC5 |

VARPTR | C0 | 24EB | | | + | CD | 249F |

– | CE | 2532 | | | * | CF | |

/ | D0 | | | ? | D1 | ||

> | D4 | | | = | D5 | ||

< | D6 | | | & | 26 | ||

‘ | FB | 3A93 |

18C9-18F6 – STORAGE LOCATION FOR LEVEL II BASIC ERROR MESSAGES – “ERRTAB”

18F7-1904 – STORAGE LOCATION FOR THE SINGLE PRECISION DIVISION ROUTINE

This code is moved from 18F7-191DH to 4080H-40A5H during non-disk initial setup.

1905-191C – STORAGE LOCATION FOR VALUES PLACED IN RAM UPON INITIALIZATION.

This code is moved to 408E during non-disk initial setup.

191D-1923 – MESSAGE STORAGE LOCATION – “ERR”

↳ ERR

1929-192F – MESSAGE STORAGE LOCATION – “REDDY”

↳ REDDY

1930-1935 – MESSAGE STORAGE LOCATION – “BRKTXT”

↳ BNKTXT

1936-1954 – SCAN STACK ROUTINE – “FNDFOR”

This routine is called with DE as the address of the NEXT index. It scans the STACK backwards looking for a FOR push. If one is found, it gets the address of the index and compares with the DE that was in place when this routine was called. If it is equal, then it exits with A=0 and HL=Address of the variable. If it is not equal it will keep scanning until no FOR push is found and then exit with A<>0.

According to the original ROM source, this routine is part of the general storage management routines, and if designed to find a FOR entry on the STACK with the variable pointer passed in Register Pair DE.

OR E7A

LD BC,FORSIZ01 0E 00

1955-1962 – DATA MOVEMENT ROUTINE – “BLTU”

This routine moves a variable into another area specified by the caller. On entry BC is set as the end address of the list to move (which is the upper limit); DE is set as the start address of the list to move; and HL is the end of the area to move it to.

According to the original ROM source, this routine is part of the general storage management routines, and if designed to make space by shoving everything forward and to check to make sure a reasonable amount of space remains between the top of the STACK and the highest location transferred to. On Entry, HL should be the destination of the high address, DE should be the low address to be transferred there, and BC should be the high address to be transferred there. On exit, HL=DE=Low BC=The location LOW was moved to.

CALL REASONCD 6C 19

1963-197D – MEMORY CHECK ROUTINE – “GETSTK”

This routine computes the amount of space between HL and the end of memory at FFC6. On entry, Register C should hold the number of desired bytes.

According to the original ROM source, this routine is part of the general storage management routines, and if designed to make sure that a certain number of locations remain available for the STACK. To use this routine, Register C needs to hold the number of two byte entries needed, and then do a CALL GETSTK. This routine must be called by any reoutine which puts an arbitrary amount of stuff into the STACK (such as a recursive routine like FRMEVL). It is also called by routines such as GOSUB and FOR which make permanent entries in the STACK.

Note: 40FDH-40FEH holds Free memory pointer

LD A,256-(2*NUMLEV)3E C6

197A-197B – ?OM ERROR ENTRY POINT – “OMERR”

197E-1AF7 – LEVEL II BASIC COMMAND MODE ERROR HANDLING – “PRGEND”

Note: 40A2H-40A3H holds the current BASIC line number

Note: 40DAH-40DBH holds DATA line number

Note: 40A2H-40A3H holds the current BASIC line number

The next few instructions are all Z-80 tricks to allow Register E to hold its value while passing through them all.

Note: 40EAH-40EBH holds Line number with error

Note: 40E8H-40E9H holds STACK pointer pointer

19B4 – LEVEL II BASIC COMMAND MODE ERROR HANDLING – “ERRMOR”

↳ ERRMOR

Note: 409AH holds the RESUME flag

Note: 40E6H-40E7H holds the temporary storage location

Note: 40EEH-40EFH is used by RESUME

Note: 40EAH-40EBH holds Line number with error

AND L7C

Note: 40F5H-40F6H holds the last line number executed

Note: 40F7H-40F8H holds Last byte executed

Note: 40F0H-40F1H is used by ON ERROR

OR L7C

Note: 40F2H holds Error flag

19E3 – LEVEL II BASIC COMMAND MODE ERROR HANDLING – “NOTRAP”

↳ NOTRAP

The RST 10H routine parses the characters starting at HL+1 for the first non-SPACE,non-09H,non-0BH character it finds. On exit, Register A will hold that character, and the C FLAG is set if its alphabetic, and NC FLAG if its alphanumeric. All strings must have a 00H at the end.

Note: 40EAH-40EBH holds Line number with error

This basically reserves the line number 65534 as a trigger for the next few steps

The original ROM has this note: The following code is for “LIST” command stopping and for returning from a failed “CVER” and to correct a direct GOSUB which does input.

Re-entry into BASIC command mode entry point. (see 6CCH also)

1A33 – MAIN LEVEL II BASIC INTERPRETER ENTRY – “MAIN”

If the jump here was from an AUTO call, (40E4H) will have the increment number, (40E1H) will be 0 if no AUTO and non-zero if AUTO, and (40E2H) will have the starting line number.

While not for this specific routine, this is the best place to mention it. Vernon Hester has pointed out that while BASIC is supposed to ignore spaces in commands, it fails to properly handle some commands because of spaces

If you have a statement with a type declaration tag after a number and a space before an add or subtract arithmetic operator, the ROM applies the operator as a unary operator for the following argument

Example: PRINT 2% + N will display two numbers. PRINT 2%+N will display one number.

Also, if you have a statement with a type declaration tag after a number and a space before a multiply or divide arithmetic operator, the ROM willl throw a ?SN ERROR

Example: PRINT 2%*N will display a number. PRINT 2% * N will display a ?SN ERROR.

↳ MAIN

Note: 40A2H-40A3H holds the current BASIC line number

Note: 40E2H-40E3H holds Current BASIC line number

`BREAK`key was pressed so we need to zero Register A to clear the AUTO increment flag

1A60H – Part of the AUTO command – “AUTGOD”

↳ AUTGOD

Note: 40E4H-40E5H holds AUTO increment

`BREAK`key was hit

There is an explanation at 1E5AH as to why 65529 is the highest possible line number (vs 65535 which would make more sense)

`BREAK`key was hit

Note: 40E2H-40E3H holds Current BASIC line number

1A76H – Part of the AUTO command – “NTAUTO”

↳ NTAUTO

The RST 10H routine parses the characters starting at HL+1 for the first non-SPACE,non-09H,non-0BH character it finds. On exit, Register A will hold that character, and the C FLAG is set if its alphabetic, and NC FLAG if its alphanumeric. All strings must have a 00H at the end.

Note: 40E6H-40E7H holds the temporary storage location

Note: 40DDH holds the BUFFER KILLED flag

The RST 10H routine parses the characters starting at HL+1 for the first non-SPACE,non-09H,non-0BH character it finds. On exit, Register A will hold that character, and the C FLAG is set if its alphabetic, and NC FLAG if its alphanumeric. All strings must have a 00H at the end.

Note: 40ECH-40EDH holds EDIT line number

↳ LEXIST

↳ NODEL

Note: 40F9H-40FAH holds the starting address of the simple variable storage area

Note: 40F9H-40FAH holds the starting address of the simple variable storage area

Note: 40A7H-40A8H holds Input Buffer pointer

1AF8-1B0F – LINE POINTERS ROUTINE – “LINKER”

This routine fixes the line pointers in a BASIC program. This is useful, for instance for a renumber program which has to move BASIC program lines from one location in memory to an other, which means that the line pointers would no longer be valid. This routine will fix them. Registers A, HL and DE are used.

↳ LINKER

**Note:**40A4H-40A5H holds the starting address of BASIC program text also known as the PROGRAM STATEMENT TABLE (PST)

A note in the original rom source code says that CHEAD goes through the program storage area in RAM and fixes up all the links. The end of each line is found by searching for a zero. The double zero link is used to detect the end of the program.

If we are here, we did not get a 00 end of program, so we continue

1B10-1B48 – EVALUATE LINE NUMBERS – “SCNLINE”

This is called by LIST and DELETE. It converts the starting and ending linbers (X-Y) to binary and saves the ending line number on the STACK. Then the code locates the program table address for the starting line. The routine leaves the address of the starting line in BC and the ending line number in the STACK.

According to the original ROM source, SCNLIN scans a line range of the form of #-# or #- or -# or blank, and then finds the first line in the range.

1B2CH – SEARCH FOR A LINE NUMBER – “FNDLIN”

According to the original ROM source, the FNDLIN routine searches the program text for the line whose line number is held in Register Pair DE. DE is preserved. There are three possible returns:This routine searches a BASIC program for a BASIC line with a line number matching the value in the DE Register Pair. To use this routine, the required line number must be placed in the DE Register Pair. When a match is found, this routine sets the carry flag; the BC Register Pair points to the start of the required line, and the HL Register points to the start of the next line. HL, AF and BC are used.

- If there is no line in the program which is greater than the one sought, then Z/NC and HL=BC.
- If the line which was searched for was actually found, Z and BC=the link field in the line and HL=the link field in the next line.
- If the line was not found, but there is still more lines in the program, NZ/NC, BC=the line in the porgram greater than the one searched for, and HL = the link field in the next line.

This is the the SEARCH FOR LINE NUMBER routine at 1B2C, which searches the Program Statement Table (PST) for a BASIC statement with the line number specified in the DE Register Pair. All registers are used. The exit conditions are:

- C/Z=Line Found and BC is the starting address of the line in the PST and HL is the address following;
- NC/Z=Line not found or too large and HL/BC will have the address of the next available PST location; and
- NC/NZ=Line not found and BC=Address of the first line number greater than the one specified and HL will be the address of the following line.

↳ FNDLIN

**Note:**40A4H-40A5H holds the starting address of BASIC program text also known as the PROGRAM STATEMENT TABLE (PST)

LD C,L44

1B49-1B5C – LEVEL II BASIC NEW ROUTINE – “SCRATH”

↳ SCRATH

**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

1B5D-1BB2 – LEVEL II BASIC RUN ROUTINE – “RUNC”

This routine does a lot of variable resets and other things that are common to NEW as well, so NEW just does the special NEW stuff and than passes right through to here to reset the rest.

To use a ROM call to RUN a BASIC program, starting with its first line, execute the following instructions:

LD HL,1D1EH

PUSH HL

JP 1B5DH.

**Note:**40A4H-40A5H holds the starting address of BASIC program text also known as the PROGRAM STATEMENT TABLE (PST)

1B61H – Subroutine which initializes a lot of stuff – “CLEARC”

Initialize he variable and array space by resetting ARYTAB (which is the end of the the simple variable spac) and STREND (which is the end of the array storage). It then falls into STKINI which resets the STACK. HL is preserved.

↳ CLEARC

Note: 40DFH-40E0H is used by DOS

Note: 4101H-411AH holds Variable Declaration Table

Note: 40F2H holds Error flag

Note: 40F0H-40F1H is used by ON ERROR

`BREAK`, STOP, or END address.

Note: 40F7H-40F8H holds Last byte executed

Note: 40B1H-40B2H holds MEMORY SIZE? pointer

Note: 40D6H-40D7H holds the next available location in string space pointer

Note: 40F9H-40FAH holds the starting address of the simple variable storage area

Note: 40FDH-40FEH holds Free memory pointer

1B8F – Subroutine which initializes a lot of stuff – “STKINI”

According to the notes in the original ROM source code, this routine resets the STACK point, which will also destroy all GOSUBs and FORs. String temporaries are freed, SUBFLG is reset, CONT is forbidden, and a dummy entry is put on the STACK, so that FNDFOR will always find a NON-“FOR” entry at the bottom of the STACK. A will be reset to 0 and Register Pair DE is preserved.

Note: 40E8H-40E9H holds STACK pointer pointer

Note: 40B5H-40D2H holds Temporary string work area

Note: 40B3H-40B4H holds the next available location in the temporary string work area pointer

↳ WASDIR

Note: 40DCH holds FOR flag

↳ GTMPRT

1BB3-1BBF – KEYBOARD INPUT ROUTINE – “QINLIN”

This is the last of the general purpose input routines. This routine functions identically to the 0361H routine with the exception that it prints a ? on the screen (like INPUT does with BASIC) before allowing input from the keyboard.

1BC0-1C8F – TOKENIZE INPUT ROUTINE – “CRUNCH”

The original ROM source code says that this routine translates all “reserved words” into single bytes with the MSB on. This saves space and time by allowing for table dispatch during execution, and, as such, all statements appear together in the ; reserved word list in the same ; order they appear in in STMDSP.

↳ CRUNCH

Note: 40B0H holds the temporary storage location

Note: 40A7H-40A8H holds Input Buffer pointer

Note: 40B0H holds the temporary storage location

If we are here, the the character in the reserved word list had its MSB on, and is a reserved word.

If we are here then we are in the middle of checking against the reserved word list, and we are still in the middle of a reserved word that might be a potential match.

The GOTO reserved word is the only one which allows for spaces to be inside it, so . if we find that we have GO so far, we will call the RST 10H to strip out any intevening spaces before continuing.

The RST 10H routine parses the characters starting at HL+1 for the first non-SPACE,non-09H,non-0BH character it finds. On exit, Register A will hold that character, and the C FLAG is set if its alphabetic, and NC FLAG if its alphanumeric. All strings must have a 00H at the end.

1C3D – Part of the tokeninzing routine – “NOTRES”

↳ NOTRES

The ELSE token needs to be treated differently as it is a reserved word which is followed by a reserved word. To deal with this, we put in a fake colon!

The ‘ token needs to be treated differently as it doesn’t require a colon. To deal with this, we put in a fake colon!

1C5A – Part of the tokeninzing routine – “NTSNGT” and “STUFFH”

Note: 40B0H holds the temporary storage location

1C7D – Part of the tokeninzing routine – Jumped here when an EOL is found – “CRDONE”

↳ CRDONE

LD C,L44

Note: 40A7H-40A8H holds Input Buffer pointer

1C90-1C95 – RST 0018H CODE – “DCOMPR”

The RST 18H code is located here. Unsigned compare (HL-DE), which numerically compares DE and HL. Will not work for signed integers (except positive ones). Uses the A-register only. The result of the comparison is returned in the status Register as: CARRY SET=HL<DE; NO CARRY=HL>DE; NZ=Unequal; Z=Equal).

1C96-1CA0 – RST 0008H CODE – “SYNCHR”

The RST 8H code is located here. This is the COMPARE SYMBOL routine which comparess 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 in Register A 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).

1CA1-1D1D – Level II BASIC FOR ROUTINE – “FOR”

According to the comments to the actual ROM source code, the FOR entry in the STACK has 16 bytes, as follows:

- 1 Byte – The FOR token
- 2 Bytes – A pointer to the loop’s variable
- 1 Byte – A byte reflecting the sign of the increment
- 4 Bytes – The value of the STEP
- 4 Bytes – The upper limit of the loop
- 2 Bytes – The line number of the FOR statement
- 2 Bytes – A text pointo into the FOR statement

Vernon Hester has flagged a bug in the FOR…NEXT routines. FOR-NEXT loops with valid integer values should complete, but FOR J% = 0 TO 30000 STEP 5000 : PRINT J%, : NEXT J% will trigger an ?OV ERROR.

↳ FOR

Note: 40DCH holds FOR flag

Note: 40E8H-40E9H holds STACK pointer pointer

Note: 40A2H-40A3H holds the current BASIC line number

NOTE: The RST 20H routine determines the type of the current value in ACCumulator 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.

1CECH – Part of the Level II BASIC FOR ROUTINE – “SNGFOR”

↳ SNGFOR

PUSH DEC5

NOTE: The RST 20H routine determines the type of the current value in ACCumulator 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.

1D1E-1D77 – LEVEL II BASIC INTERPRETER – “NEWSTT”

According to the original ROM source code, this is where we go for a new statement. The character on the BASIC program line pointed to by Register Pair HL should be either a “:” or an END OF LINE. The address of this routine is left on the STACK so that when a statement is executed and done, the RETurn comes back here.

Note: 40E6H-40E7H holds the temporary storage location

Note: 40E8H-40E9H holds STACK pointer pointer

Honor a TRON by showing the line number if it is in effect.

Note: 411BH holds TRON/TROFF flag

That finishes the TRON routine where we display <nnnn> if it is in effect.

The RST 10H routine parses the characters starting at HL+1 for the first non-SPACE,non-09H,non-0BH character it finds. On exit, Register A will hold that character, and the C FLAG is set if its alphabetic, and NC FLAG if its alphanumeric. All strings must have a 00H at the end.

↳ NUMCMD

1D78-1D90 – RST 0010H CODE – “CHRGTR”

The RST 10H code is located here. This is the EXAMINE NEXT SYMBOL routine which loads the next character from the string pointed to by the HL Register set into the A-register and clears the CARRY flag if it is alphabetic, or sets it if is alphanumeric. Blanks and control codes 09 and OB 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).

↳ CHRGT2

↳ CHRCON

1D91-1D9A – LEVEL II BASIC RESTORE ROUTINE – “RESTORE”

**Note:**40A4H-40A5H holds the starting address of BASIC program text also known as the PROGRAM STATEMENT TABLE (PST)

Note: 40FFH-4100H holds READ pointer

1D9B-1DAD – SCAN KEYBOARD ROUTINE – “ISCNTC”

Note: 4099H holds the Last key pressed

`BREAK`key was pressed

1DA9-1DAD – STOP ROUTINE – “STOP”

↳ STOP

`BREAK`key wasn’t pressed.

This is the STOP entry point

1DAE-1DE3 – LEVEL II BASIC END ROUTINE – “END”

↳ END

`BREAK`

Note: 40E6H-40E7H holds the temporary storage location

Note: 40B5H-40D2H holds Temporary string work area

Note: 40B3H-40B4H holds the next available location in the temporary string work area pointer

Note: 40A2H-40A3H holds the current BASIC line number

If we are here, then there was a line number, so we need to set some locations to enable a CONT command to work.

Note: 40F5H-40F6H holds the last line number executed

Note: 40E6H-40E7H holds the temporary storage location

Note: 40F7H-40F8H holds Last byte executed

`BREAK`message

`BREAK`or a STOP that halted program execution

1DE4-1DF6 – LEVEL II BASIC CONT ROUTINE – “CONT”

↳ CONT

Note: 40F7H-40F8H holds Last byte executed

`ENTER`

`in response to an INPUT request, and hitting``BREAK`↳ RESERR

Note: 40F5H-40F6H holds the last line number executed

Note: 40A2H-40A3H holds the current BASIC line number

1DF7-1DF8 - TRON ENTRY POINT - "TON"

Turns TRON feature on. Causes line numbers for each BASIC statement executed to be displayed. Uses Register A.

↳ TON

1DF8 - TROFF ENTRY POINT - "TOFF"

The following code is common to both TRON and TROFF.

Note: 411BH holds TRON/TROFF flag

1DFD-1DFF - DISK ROUTINE NOT USED BY LEVEL II BASIC - "POPAHT".

↳ POPAHT

1E00-1E02 - DEFSTR ENTRY POINT - "DEFSTR"

↳ DEFSTR1E 03

1E03-1E05 - DEFINT ENTRY POINT - "DEFINT"

↳ DEFINT

1E06-1E08 - DEFSNG ENTRY POINT - "DEFREA"

↳ DEFREA

1E09-1E0A - DEFDBL ENTRY POINT - "DEFDBL"

↳ DEFDBL

1E0B-1E3C - COMMON CODE SHARED BY DEFSTR/DEFINT/DEFSNG/DEFDBL - "DEFCON".

All of those can either have a - for a range of values or be separated by ,. This code needs to figure out the variables that followed the DEF??? instruction and then set the variable type (which is currently sitting in Register E) in the variable table

The RST 10H routine parses the characters starting at HL+1 for the first non-SPACE,non-09H,non-0BH character it finds. On exit, Register A will hold that character, and the C FLAG is set if its alphabetic, and NC FLAG if its alphanumeric. All strings must have a 00H at the end.

The RST 10H routine parses the characters starting at HL+1 for the first non-SPACE,non-09H,non-0BH character it finds. On exit, Register A will hold that character, and the C FLAG is set if its alphabetic, and NC FLAG if its alphanumeric. All strings must have a 00H at the end.

The RST 10H routine parses the characters starting at HL+1 for the first non-SPACE,non-09H,non-0BH character it finds. On exit, Register A will hold that character, and the C FLAG is set if its alphabetic, and NC FLAG if its alphanumeric. All strings must have a 00H at the end.

Note: 4101H-411AH holds Variable Declaration Table

The RST 10H routine parses the characters starting at HL+1 for the first non-SPACE,non-09H,non-0BH character it finds. On exit, Register A will hold that character, and the C FLAG is set if its alphabetic, and NC FLAG if its alphanumeric. All strings must have a 00H at the end.

1E3D-1E44 - EXAMINE VARIABLE - "ISLET"

This routine tests the value pointed to by the HL Register Pair and sets the C FLAG if it is an ASCII letter value; and otherwise the NC FLAG is set.

↳ ISLET2

1E45-1E4E - EXAMINE VARIABLE - "INTIDX"

This is called when evaluating a subscript for a variable reference. It will evaluate if the value is positive or negative.

According to the original ROM source code, this routine reads a formula from the current position and turns it into a positive integer, with the result put into Register Pair DE. Negative arguments are not allowed. On exit, Register Pair HL wil point to the terminating character of the formula on the BASIC program line being examined.

The RST 10H routine parses the characters starting at HL+1 for the first non-SPACE,non-09H,non-0BH character it finds. On exit, Register A will hold that character, and the C FLAG is set if its alphabetic, and NC FLAG if its alphanumeric. All strings must have a 00H at the end.

1E4A - ?FC ERROR entry point - "FCERR"

1E4F-1E79 - Line Number Conversion Routine 1 - "LINSPC"

According to the original ROM source code, LINSPC and LINGET are identical except t hat LINSPC also permits the use of a "." to act as the current line number. Otherwise, They read the line number from the current position in the BASIC program. Possible line numbers are 00000-65529. On exit, DE holds the line number, and HL is updated to point to the terminating character, and Register A will contain the terminating character with the FLAGs set based on Register A's value.

Note: 40ECH-40EDH holds current line number

1E5A - Line Number Conversion Routine 2 - "LINGET"

Converts numeric ASCII string pointed to by the HL Register Pair, to HEX and places the result in the DE Register Pair. After execution HL points to the delimiter and the A Register contains the delimiter value. The Z flag is set if the delimiter equals 00 or 3A. Z is reset if any other delimiter is used. If there is no string at the location pointed to by HL the routine will return a MO ERROR (missing operand). If the result in the DE Register Pair exceeds FFFFH an OV ERROR (overflow) results.

The RST 10H routine parses the characters starting at HL+1 for the first non-SPACE,non-09H,non-0BH character it finds. On exit, Register A will hold that character, and the C FLAG is set if its alphabetic, and NC FLAG if its alphanumeric. All strings must have a 00H at the end.

Why 6552? Well, since the Z-80 has no multiply function, checking for any possible arbitrary number would require 4 branches for each step in the 'add to itself until it hits * 10' plus another 4 when adding the last digit. The TRS-80 ROM didn't have that kind of room, nor the time to do all that, so they needed a cheat and that cheat was to let it go as high 65529. After all, 6552 + 1 more digit can NEVER exceed 65535, but 6553 + 1 digit sure can!

So with this trick, the ROM just needs to first check the number against 6552, which, when multiplied by 10, and adding one more digit, will never exceed 65529 (because 9 is the highest one number can go).

By using this trick, only 1 comparison is needed (is it greater or less than 6552) . at the cost of 4 usable line numbers/memory size setting in the 6553x range.

Wait, you say. 65535-65529 is 6 numbers, so why do you say 4. Well, another shortcut the ROM uses is that it assumes anything at line number 65535 is being entered in direct mode (i.e., no line number; just a command), so 65535 couldn't be a line number. Similarly, in 1A09, 65534 is reserved to trigger the BASIC interpreter to jump to the initial powerup routine in the ROM (i.e., a reboot) so you couldn't use that line number either

Now we need HL = DE * 10

This is so we can multiply HL (which should hold the number 6552) by 10

This is so we can multiply HL (which should hold the number 6552) by 10

As noted above, adding in any digit can only result in HL going to 65529

1E7A-1EA0 - LEVEL II BASIC CLEAR ROUTINE - "CLEAR"

According to the original ROM source code, this will change the amount of string space allowed. If no formula is given, the amount of string space will remain unchanged. On entry, if the Z flag is set, there was no parameter present

↳ CLEAR

The RST 10H routine parses the characters starting at HL+1 for the first non-SPACE,non-09H,non-0BH character it finds. On exit, Register A will hold that character, and the C FLAG is set if its alphabetic, and NC FLAG if its alphanumeric. All strings must have a 00H at the end.

Note: 40B1H-40B2H holds MEMORY SIZE? pointer

Note: 40F9H-40FAH holds the starting address of the simple variable storage area

1EA3-1EB0 - LEVEL II BASIC RUN ROUTINE - "RUN"

On entry, if the Z flag is set, there was no parameter present

↳ RUN

1EB1-1EC1 - LEVEL II BASIC GOSUB ROUTINE - "GOSUB"

According to the original ROM source code, the 5 byte GOSUB entry on the STACK is as follows:Can be used to execute the equivalent of a GOSUB statement from an assembly program. It allows a BASIC subroutine to be called from an assembly subroutine. After the BASIC subroutine executes, control returns to the next statement in the assembly program. All registers are used. On entry, the HL must contain an ASCII string with the starting line number of the subroutine.

- LOW ADDRESS

- 1 Byte - The GOSUB token.
- 2 Bytes - The line number of the GOSUB statement.
- 2 Bytes - A pointer to the text of the GOSUB in the BASIC program being executed.
- HIGH ADDRESS

↳ GOSUB

Note: 40A2H-40A3H holds the current BASIC line number

1EC2-1EDD - LEVEL II BASIC GOTO ROUTINE - "GOTO"

Note: 40A2H-40A3H holds the current BASIC line number

Yes, this is a second search that kicks in if the prior search (which started at the current line number) failed, as this one will start at the beginning of the program

LD L,C60

1ED9-1EDD - LEVEL II BASIC ?UL ERROR ROUTINE - "USERR"

↳ USERR

1EDE-1E04 - LEVEL II BASIC RETURN ROUTINE - "RETURN"

Returns control to the BASIC statement following the last GOSUB call. An assembly program called by a BASIC subroutine may wish to return directly to the orginal caller without returning through the subroutine entry point. This exit can be used for that return. The return address to the STACK for the call to the assembly program must be cleared before returning via 1EDFH. On entry, if the Z flag is set, there was no parameter present.

↳ RETURN

Note: 40E8H-40E9H holds STACK pointer pointer

1EEC - RG ERROR entry point.

Note: 40A2H-40A3H holds the current BASIC line number

The next few instructions set up to see if there was GOSUB from the command line instead of insiude a program.

Note: 40DDH holds INPUT flag

↳ DATAH

1F05-1F20 - SCAN ROUTINE - "DATA"

The notes in the original ROM source code explain that when a quote is seen, the second terminator is traded, so in a DATA statement a colon inside quotations will have no effect.

↳ EXCHQT

`"`"FE 22

The notes in the original ROM source code say that when an IF takes a false branch, it must find the appropriate ELSE to start execution at. "DATA" counts the number of IF's it sees so that the ELSE code can matche ELSE's with IF's. This count is kept in Register D.

1F21-1F6B - LEVEL II BASIC LET ROUTINE - "LET"

↳ LET

A note in the original ROM source code explains that the following sets up "TEMP" for the FOR command so when user-functions call REDINP, the "TEMP" doesn't get changed.

Note: 40DFH-40E0H is a common temporary storage area

↳ REDINP

NOTE: The RST 20H routine determines the type of the current value in ACCumulator 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.

↳ LETCN3

↳ LETCON

↳ LETCN2

**Note:**40A4H-40A5H holds the starting address of BASIC program text also known as the PROGRAM STATEMENT TABLE (PST)

Next, we need to see if it is a variable by checking the descriptor. If it is not a variable, we do not want to copy it.

Note: 40F9H-40FAH holds the starting address of the simple variable storage area

1F6C-1FAE - LEVEL II BASIC ERROR ON ROUTINE - "ONGOTO"

↳ ONGOTO

The RST 10H routine parses the characters starting at HL+1 for the first non-SPACE,non-09H,non-0BH character it finds. On exit, Register A will hold that character, and the C FLAG is set if its alphabetic, and NC FLAG if its alphanumeric. All strings must have a 00H at the end.

1F7E

LD E,C50

Note: 40F0H-40F1H is used by ON ERROR

Note: 40F2H holds Error flag

Note: 409AH holds the RESUME flag

1F95 - Still in the ON routine - "NTOERR"

We know it isn't ON ERROR. We now need to deal with the possibility that it was an ON n GOTO or ON n GOSUB.

1FAF-1FF3 - LEVEL II BASIC RESUME ROUTINE - "RESUME"

↳ RESUME

Note: 40F2H holds Error flag

1FC6

1FCDH - Part of the RESUME ROUTINE - "RESNXT"

The RST 10H routine parses the characters starting at HL+1 for the first non-SPACE,non-09H,non-0BH character it finds. On exit, Register A will hold that character, and the C FLAG is set if its alphabetic, and NC FLAG if its alphanumeric. All strings must have a 00H at the end.

1FCF - This is the RESUME 0 routine - "RESTXT"

Note: 40EEH-40EFH is used by RESUME

Note: 40EAH-40EBH holds Line number with error

Note: 40A2H-40A3H holds the current BASIC line number

1FF4H-2007 - LEVEL II BASIC ERROR ROUTINE - "ERRORS"

This evaluates n for ERROR n

↳ ERRORS