This page covers 1001H-2002H of the Model III ROM. The ONLY difference between the Model I v1.3 ROM and the Model III ROM in this entire range is located at 1B5DH-1B5FH. On the Model I, that address loaded HL with the contents of memory location 40A4H, the start of data. On the Model III, that adress is a GOSUB to unprotect the screen and load HL with the start of data.

There is no difference between the early Model III ROM and the later Model III ROM in this range. The Model 4 ROM is also identical to the Model III ROM in this range.

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 initializes the input buffer for an ASCII conversion. It is 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.

**NOTE:**4130H-4149H holds Internal print buffer.

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.

**NOTE:**Results from a CP:

- Z: A and * are the same
- NZ: A and * are NOT the same
- C: A < *
- NC: A => *

**NOTE:**Results from a CP:

- Z: A and * are the same
- NZ: A and * are NOT the same
- C: A < *
- NC: 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
- Double Precision is NZ/NC/P/E and A is 5.

**NOTE:**4130H-4149H holds Internal print buffer.

- If A=04H it sets the ZERO FLAG
- If A<04H then the CARRY FLAG will be set
- If A>=04H then the NO CARRY FLAG will be set

Alternative interpretation is Jump to 11A3H if the variable is a string; which will leave us now with only an integer value.

10A6 – This is where the PRINT USING routine will edit for INTEGER values.

**NOTE:**40F3H-40F4H holds the 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:

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

1109 – This is where the PRINT USING routine will edit for FLOATING POINT values.

1124H – Continuation point if the current value in REG 1 is single precision.

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=00H if REG 1 = BCDE
- A=01H if REG 1>BCDE; and
- A=FFH if REG 1<BCDE.

1157H – Subroutine if REG 1 Needs to be Scaled Up (Multiplied by 10) To Get It In Range

117FH – Continuation Routine (From 1171H) if there are no digits to the left of the decimal point.

1190H – Continuation Routine (From 117DH) to edit the numbers before the decimal point.

**NOTE:**40F3H-40F4H holds the temporary storage location.

or

LD BC, 1E06H

11B0H – Continuation Routine (From 11AAH) if the current value in REG 1 is SINGLE precision.

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

- Scales so that the number lies between 99,999 and 999,999.
- On exit, A = +(times value divided) or A=-(times value multiplied).

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
- Double Precision is NZ/NC/P/E and A is 5.

**NOTE:**Results from a CP:

- Z: A and * are the same
- NZ: A and * are NOT the same
- C: A < *
- NC: A => *

**NOTE:**4127H-412EH holds REG 2.

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
- Double Precision is NZ/NC/P/E and A is 5.

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=00H if REG 1 = BCDE
- A=01H if REG 1>BCDE; and
- A=FFH if REG 1<BCDE.

Difference between M1 and M3 ROMs: This change first appeared in the “new” ROMs for the Model I. The order of two instructions (OR A and POP DE) have been reversed for no apparent reason.

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
- Double Precision is NZ/NC/P/E and A is 5.

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=00H if REG 1 = BCDE
- A=01H if REG 1>BCDE; and
- A=FFH if REG 1<BCDE.

This routine puts leading zeroes into the input buffer

127DH – Subroutine to set up BC for decimal point and comma counters. On entry: Register D holds the number of digits to print, Register E holds the count of the times the value was scaled up or down.

**NOTE:**40D8H-40D9H holds the temporary storage location.

1291H – Subroutine to count the leading digits before the decimal point.

**NOTE:**40F3H-40F4H holds the temporary storage location.

129CH – Continuation Routine (from 1292H) if the decimal point position hasn’t been reached.

12A4 – Routine to Convert the INTEGER porton of a DOUBLE precision value to its ASCII equivalent.

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
- Double Precision is NZ/NC/P/E and A is 5.

Note: 411DH-4124H holds REG l.

12EAH – This routine is to convert a SINGLE precision value to an INTEGER.

- Divide the integer equivalent by 100,000 and 10,000. Use the code at 1335H to convert the last 1000 to ASCII.

130AH – 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.

132FH – This routine will convert an INTEGER to ASCII.

1335H – This routine will convert the last x (based on A) digits of an INTEGER to ASCII.

1348 – 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

136C-1373 – DOUBLE PRECISION CONSTANT STORAGE LOCATION

1374-137B – DOUBLE PRECISION CONSTANT STORAGE LOCATION

137C-1383 – DOUBLE PRECISION CONSTANT STORAGE LOCATION

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

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

13D2H-13D9H – SINGLE PRECISION INTEGER CONSTANT STORAGE LOCATION

13E1-13E6 – LEVEL II BASIC MATH ROUTINE

**NOTE:**0982H is the address of the routine for conversion of floating point numbers from negative to positive.

13E7-13F1 – LEVEL II BASIC SQUARE ROOT ROUTINE – SQR(n) routine.

- Single-precision values only should be used. (REG 1 = SQR(REG 1)).

Computes the square root of any value in REG 1. The root is left in REG 1 as a single precision value. - NOTE: To use a ROM call to find the square root of a nonnegative single precision numbers, store the number in 4121H-4124H and then CALL 13E7H. The result (in single precision format) is in 4121H-4124Hin approximately 48 milliseconds. NOTE: A fatal error (returning control to the Level II monitor) occurs if the input number is negative.

13F2-1478 LEVEL II BASIC X to the Y Power (X^Y) ROUTINE

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

- NOTE: To use a ROM call to raise a single precision number (the base) to a single precision power (the exponent), store the base (single precision) in registers BCDE, and store the exponent (also single precision) in 4121H-4124H and then CALL 13F7H. The result (in single precision format) is in 4121H-4124H and in approximately 50 milliseconds.

/0 ERROR entry point.

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=00H if REG 1 = BCDE
- A=01H if REG 1>BCDE; and
- A=FFH if REG 1<BCDE.

1439 – EXP routine. Single-precision only. (REG 1 = EXP(REG1)).

- A call to 1439H raises E (natural base) to the value in REG 1 which must be a single precision value. The result will be returned in REG 1 as a single precision number.
- NOTE: To use a ROM call to find EXP(X), where X is a single precision variable, store the value of X in 4121H-4124H and then CALL 1439H. The result (in single precision format) is in 4121H-4124Hin approximately 28 milliseconds. NOTE: A fatal error occurs if the result is as large as 2 to the power of 127.

“EXP”

1479-1499 – SINGLE PRECISION CONSTANT STORAGE LOCATION

This represents 1/6, -1/5, 1/4, -1/3, 1/2, -1, and 1

149A-14C8 – LEVEL II BASIC MATH ROUTINE

- This is a general purpose summation routine which computes the series SUM ((((x^2 * c0+c1)x^2 +c2)x^2 + … cN)x 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.

**NOTE:**0C32H pops BC and DE and then JUMPs to JP 0847H.

POP DE

PUSH BC

14C9-1540 – LEVEL II BASIC RND(n). Generates a single-precisions random number between 0 and 1, or 1 and n depending on the parameter passed in REG 1, The random value is returned in REG 1 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.

“RNDM”

- NOTE: To run a RND(J) function via a ROM call just The RND(J) function (with J a nonzero integer) load the value of J into the HL register pair. Then CALL 14CCH and then CALL 0A7FH. The result (in integer format) is in 4121H-4122H and in HL in approximately 5.7 milliseconds. The input variable J must have a value between 1 and 32767, inclusive, or an FC error will occur.

POP DE

14F0H – This routine calculates RND(0).

- NOTE: To run a RND(0) function via a ROM call just CALL 14F0H. No input variable is necessary. The result (in single precision format) is in 4121H-4124H in approximately 2.4 milliseconds.

**NOTE:**4090H holds the random number seed 2

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

- COS routine. Single-precision only.(REG 1 = COS(REG 1)).

A call to 1541H computes the cosine for an angle given in radians. The angle must be a floating point value in REG 1; the cosine will be returned in REG 1 as a floating point value. - NOTE: To use a ROM call to find COS(X), where X is a single precision variable (in radians), store the value of X in 4121H-4124H and then CALL 1541H. The result (in single precision format) is in 4121H-4124Hin approximately 25 milliseconds.

“COSN”

1547-158A – LEVEL II BASIC SIN

- SIN(n) routine. Single-precision only.(REG 1 = SIN(REG 1)).
- A call to 1549H returns the sine as a single precision value in REG 1. The sine must be given in radians in REG 1.
- 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.

- NOTE: To use a ROM call to find SIN(X), where X is a single precision variable, store the value of X in 4121H-4124H and then CALL 1547H. The result (in single precision format) is in 4121H-4124Hin approximately 25 milliseconds. NOTE: The argument (X) must be in radians.

“SINE”

POP DE

POP DE

158BH-15A7H – SINGLE PRECISION CONSTANT STORAGE LOCATION

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

TAN(n)

- Single-precision only.(REG 1 = TAN(REG 1)).

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

Uses the fact that TAN(x) = SIN(x) / COS(x) - NOTE: To use a ROM call to find TAN(X), where X is a single precision variable (in radians), store the value of X in 4121H-4124H and then CALL 15A8H. The result (in single precision format) is in 4121H-4124Hin approximately 54 milliseconds. NOTE: A fatal error occurs if the result is as large as 2 to the power of 127, which will be the case if the value of X is sufficiently close to any odd multiple of pi/2 radians.

POP HL

15BD-15E2 – LEVEL II BASIC ATN ROUTINE – “ATAN”

ATN(n) routine.

- Single-precision only.(REG 1 = ATN(REG 1)).

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

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.

- NOTE: To use a ROM call to find ATN(X), where X is a single precision variable, store the value of X in 4121H-4124H and then CALL 15BDH. The result (in single precision format, in radians) is in 4121H-4124Hin approximately 27 milliseconds.

- If A=”1″ it sets the ZERO FLAG.
- If A<“1” then the CARRY FLAG will be set
- If A>=”1″ then the NO CARRY FLAG will be set.

15E3-1607 – SINGLE PRECISION CONSTANTS STORAGE LOCATION

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

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

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.

191DH-1935H – MESSAGE STORAGE LOCATION

1936-1954 – SCAN STACK ROUTINE

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

- HL<DE: CARRY SET
- HL>DE: NO CARRY
- HL><DE: NZ
- HL=DE: Z

1955-1962 – DATA MOVEMENT ROUTINE

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

- HL<DE: CARRY SET
- HL>DE: NO CARRY
- HL><DE: NZ
- HL=DE: Z

1963-197D – MEMORY CHECK ROUTINE – Computes the amount of space between HL and the end of memory at FFC6H.

**NOTE:**40FDH-40FEH holds the pointer to the starting address of free memory.

197A-197B – OM ERROR entry point.

197E-1AF7 – LEVEL II BASIC COMMAND MODE

**NOTE:**40A2H-40A3H holds the current BASIC line number.

**NOTE:**40F2H holds the error flag.

**NOTE:**40DAH-40DBH holds DATA line number.

**NOTE:**40A2H-40A3H holds the current BASIC line number.

SN ERROR entry point.

?NF ERROR entry point.

?RW ERROR entry point.

**NOTE:**40A2H-40A3H holds the current BASIC line number.

**NOTE:**40EAH-40EBH holds the line number with error.

**NOTE:**40ECH-40EDH holds EDIT line number.

**NOTE:**40E8H-40E9H holds Stack pointer pointer.

**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 the line number with error.

AND L

**NOTE:**40F5H-40F6H holds the last line number executed.

**NOTE:**40F7H-40F8H holds the last byte executed.

**NOTE:**40F0H-40F1H holds the ON ERROR adress.

**NOTE:**40F2H holds the error flag.

**NOTE:**41A6H-41E4H holds DOS links.

In NEWDOS 2.1, this would be a call to load a DISK BASIC error, with Register E holding the error number.

NOTE:

- The string must be terminated by a byte of zeros.

**NOTE:**40EAH-40EBH holds the line number with error.

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).

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

- HL<DE: CARRY SET
- HL>DE: NO CARRY
- HL><DE: NZ
- HL=DE: Z

1A19 – “$READY” – Jump to Model II BASIC “READY”

To exit from a machine-language program into BASIC’s immediate mode, jump (not call) to $READY.

“READY”

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

In NEWDOS 2.1, this is the start of BASIC just before BASIC shows the READY prompt.

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:**409AH holds the RESUME flag.

1A33 – Many routines jump here as the start of the Level II BASIC interpreter.

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

**NOTE:**FFFFH is the command mode line number.

**NOTE:**40A2H-40A3H holds the current BASIC line number.

**NOTE:**40E2H-40E3H holds Current BASIC line number.

**NOTE:**40E1H will hold 0 if no AUTO and non-zero if AUTO.

If we are here, then the `BREAK` key was not pressed.

**NOTE:**40E4H-40E5H holds the AUTO increment number.

`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).

- HL<DE: CARRY SET
- HL>DE: NO CARRY
- HL><DE: NZ
- HL=DE: Z

`BREAK`key was hit.

**NOTE:**40E2H-40E3H holds Current BASIC line number.

NOTE:

- The string must be terminated by a byte of zeros.

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

1A8BH – This little looping routine is to clear any trailing blanks between the line number and the statement.

**NOTE:**40E6H-40E7H holds the temporary storage location.

In NEWDOS 2.1, this is the input scanner after tokenizing the current statement.

**NOTE:**40DDH holds INPUT flag.

NOTE:

- The string must be terminated by a byte of zeros.

**NOTE:**40ECH-40EDH holds EDIT line number.

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

In NEWDOS 2.1, this is the input scanner after updating the PST (Program Statement Table).

In NEWDOS 2.1, this is the input scanner after reinitializing BASIC

1AF8-1B0F – LINE POINTERS ROUTINE

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

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

1B10-1B48 – EVALUATE LINE NUMBERS

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

CEH

1B2C – 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.

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.

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

- HL<DE: CARRY SET
- HL>DE: NO CARRY
- HL><DE: NZ
- HL=DE: Z

If we are here, then we have no match.

1B49-1B5C – LEVEL II BASIC NEW ROUTINE

- 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

Differences between M1 and M3 ROMs: The locations 1B5DH – 1B5FH are part of the RUN, NEW, EDIT, etc. commands; in the Model I these three bytes contain a LD HL,(40A4H) instruction (resets HL to point to the start of the BASIC program). In the Model III, this has been replaced by a CALL 046BH instruction, which unprotects the video display in addition to resetting HL to the start of the BASIC program.

- 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

The ability to RUN a BASIC program from an assembly language program is valuable for linking the two programs.

**NOTE:**40DFH-40E0H is used by DOS.

**NOTE:**4101H-411AH holds Variable Declaration Table.

**NOTE:**40F2H holds the error flag.

**NOTE:**40F0H-40F1H is used by ON ERROR.

**NOTE:**40F7H-40F8H holds the last byte executed.

**NOTE:**40B1H-40B2H holds MEMORY SIZE? pointer.

**NOTE:**40D6H-40D7H holds Next available location in string space pointer.

- 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:**40FDH-40FEH holds the pointer to the starting address of free memory.

In NEWDOS 2.1 this initializes BASIC for a new routine.

1B8FH – Inside the RUN routine – Initialize the Level II BASIC variables and pointers

- Note: 40A0H-40A1H holds the start of string space pointer.

Note: 40E8H-40E9H holds Stack pointer pointer.

**NOTE:**40B5H-40D2H holds Temporary string work area.

**NOTE:**40B3H-40B4H holds Next available location in the temporary string work area pointer.

**NOTE:**40DCH holds FOR flag.

**NOTE:**40DFH-40E0H holds Used by DOS.

1BB3-1BBF – KEYBOARD INPUT ROUTINE

- This is the last of the general purpose input routines. This routine functions identically to the 361H routine with the exception that it prints a “?” on the screen (like INPUT does with BASIC) before allowing input from the keyboard.
- To use a ROM call to display “?” on the video screen at the current cursor position (Non-DOS Systems Only), and then to input a string of up to 240 characters, execute CALL 1BB3H. The input string will be in consecutive memory locations starting at the address contained in 40A7H-40A8H, with a zero byte at the end. The HL register pair will contain an address one less than the starting address of the stored input.

“INPUT”

1BC0-1C8F – TOKENIZE INPUT ROUTINE

**NOTE:**40B0H holds the temporary storage location.

**NOTE:**Bit 0 HIGH means inside a quote. Bit 1 HIGH means inside a DATA. Bit 2 HIGH means inside a REM.

**NOTE:**In the original Model III ROM, this byte was placed into 40B0H which was just a temporary storage location.

**NOTE:**40A7H-40A8H holds Input Buffer pointer.

**NOTE:**40B0H holds the temporary storage location.

**NOTE:**Bit 0 HIGH means inside a quote. Bit 1 HIGH means inside a DATA. Bit 2 HIGH means inside a REM.

**NOTE:**In the original Model III ROM, this byte was read from 40B0H which was just a temporary storage location.

**NOTE:**Results from a CP:

- Z: A and * are the same
- NZ: A and * are NOT the same
- C: A < *
- NC: A => *

**NOTE:**Results from a CP:

- Z: A and * are the same
- NZ: A and * are NOT the same
- C: A < *
- NC: A => *

**NOTE:**Results from a CP:

- Z: A and * are the same
- NZ: A and * are NOT the same
- C: A < *
- NC: A => *

NOTE:

- The string must be terminated by a byte of zeros.

- If A=61H it sets the ZERO FLAG
- If A<61H then the CARRY FLAG will be set
- if A>=61H then the NO CARRY FLAG will be set.

**NOTE:**40B0H holds the temporary storage location.

**NOTE:**Bit 0 HIGH means inside a quote. Bit 1 HIGH means inside a DATA. Bit 2 HIGH means inside a REM.

**NOTE:**In the original Model III ROM, this byte was placed into 40B0H which was just a temporary storage location.

Still Inside the TOKENIZE INPUT ROUTINE – This routine is called if the character in register A is an end of the input character.

**NOTE:**40A7H-40A8H holds the pointer to the start of the Input Buffer.

1C90-1C95 – RST 0018H CODE

The RST 18H code is located here. (Unsigned compare (HL-DE)).

This is the COMPARE DE:HL routine, 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:

- HL<DE: CARRY SET
- HL>DE: NO CARRY
- HL><DE: NZ
- HL=DE: Z

“CHLDE”

1C96-1CA0 – RST 0008H CODE

- 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 the Aregister 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

**NOTE:**40DCH holds FOR flag.

**NOTE:**40E8H-40E9H holds Stack pointer pointer.

**NOTE:**40A2H-40A3H holds the current BASIC line number.

BDH

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
- Double Precision is NZ/NC/P/E and A is 5.

PUSH DE

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
- Double Precision is NZ/NC/P/E and A is 5.

**NOTE:**40DFH-40E0H holds Used by DOS.

1D1E-1D77 – LEVEL II BASIC INTERPRETER

**NOTE:**40E6H-40E7H holds the temporary storage location.

**NOTE:**40E8H-40E9H holds Stack pointer pointer.

**NOTE:**40A2H-40A3H holds the current BASIC line number.

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

**NOTE:**411BH holds the TRON/TROFF flag.

1D59 – Done with the TRON, so let us continue.

NOTE:

- The string must be terminated by a byte of zeros.

1D78-1D90 – RST 0010H CODE

- 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).

“FETCH”

- If A=: it sets the ZERO FLAG
- If A<: then the CARRY FLAG will be set
- if A>=: then the NO CARRY FLAG will be set.

- If A=0BH it sets the ZERO FLAG
- If A<0BH then the CARRY FLAG will be set
- if A>=0BH then the NO CARRY FLAG will be set.

- If A=09H it sets the ZERO FLAG
- If A<09H then the CARRY FLAG will be set
- if A>=09H then the NO CARRY FLAG will be set.

- If A=0 it sets the ZERO FLAG
- If A<0 then the CARRY FLAG will be set
- if A>=0 then the NO CARRY FLAG will be set.

1D91-1D9A – LEVEL II BASIC RESTORE ROUTINE

**NOTE:**40FFH-4100H holds READ pointer.

1D9B-1DAD – SCAN KEYBOARD ROUTINE

1DA0H – Inside the SCAN KEYBOARD ROUTINE – This will process a `SHIFT` + `@` (Pause) Keypress

`SHIFT`+

`@`.

`SHIFT`+

`@`we now need to honor that by waiting for yet another key to be pressed.

**NOTE:**4099H holds the Last key pressed.

1DA9H-1DADH – Inside the SCAN KEYBOARD ROUTINE – This will process a STOP.

This is the STOP entry point.

1DAE-1DE3 – LEVEL II BASIC END ROUTINE

**NOTE:**40E6H-40E7H holds the temporary storage location.

**NOTE:**40B5H-40D2H holds Temporary string work area.

**NOTE:**40B3H-40B4H holds Next available location in the temporary string work area pointer.

**NOTE:**40A2H-40A3H holds the current BASIC line number.

**NOTE:**40F5H-40F6H holds the last line number executed.

**NOTE:**40E6H-40E7H holds the temporary storage location.

**NOTE:**40F7H-40F8H holds the last byte executed.

1DE4-1DF6 – LEVEL II BASIC CONT ROUTINE.

**NOTE:**40F7H-40F8H holds the last byte executed.

OR L

**NOTE:**40F5H-40F6H holds the last line number executed.

**NOTE:**40A2H-40A3H holds the current BASIC line number.

1DF7H-1DFCH – TRON and TROFF Routine

1DF7H – TRON Entry Point (Set A with AFH)

1DF8H – TROFF Entry Point (Set A with 00H)

1DF9-1DFC – COMMON CODE SHARED BY TRON AND TROFF – Put A into (411BH)

**NOTE:**411BH holds the TRON/TROFF flag. 0=off (TROFF), 175=on (TRON)

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

1E00H-1E3CH – DEFxxx Routine

1E00-1E02 – INSIDE THE DEFxxx ROUTINE – DEFSTR Entry Point

1E03H-1E05H – INSIDE THE DEFxxx ROUTINE – DEFINT Entry Point

1E06H-1E08H – INSIDE THE DEFxxx ROUTINE – DEFSNG Entry Point

1E09-1E0AH – INSIDE THE DEFxxx ROUTINE – DEFDBL Entry Point

1E0BH-1E3CH – INSIDE THE DEFxxx ROUTINE – Common code shared by all the above – 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.

NOTE:

- The string must be terminated by a byte of zeros.

NOTE:

- The string must be terminated by a byte of zeros.

NOTE:

- The string must be terminated by a byte of zeros.

**NOTE:**4101H-411AH holds Variable Declaration Table.

NOTE:

- The string must be terminated by a byte of zeros.

1E3D-1E44 – EXAMINE VARIABLE – See if the value pointed to at the memory location (HL) is an ASCII letter. C Flag is set for yes, NC Flag for no.

- If A=A it sets the ZERO FLAG
- If A<A then the CARRY FLAG will be set
- If A>=A then the NO CARRY FLAG will be set

- If A=Z it sets the ZERO FLAG
- If A<Z then the CARRY FLAG will be set
- If A>=Z then the NO CARRY FLAG will be set

1E45-1E4E – EXAMINE VARIABLE

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

NOTE:

- The string must be terminated by a byte of zeros.

1E4A – FC ERROR entry point.

1E4F-1E79 – ASCII TO BINARY

- If A=. it sets the ZERO FLAG
- If A<. then the CARRY FLAG will be set
- If A>=. then the NO CARRY FLAG will be set

**NOTE:**40ECH-40EDH holds EDIT line number.

1E5A – “DECBIN” – 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.

NOTE:

- The string must be terminated by a byte of zeros.

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.

- HL<DE: CARRY SET
- HL>DE: NO CARRY
- HL><DE: NZ
- HL=DE: Z

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. If Z FLAG is set, no number of bytes was provided (i.e., CLEAR instead of CLEAR 20).

NOTE:

- The string must be terminated by a byte of zeros.

**NOTE:**40B1H-40B2H holds MEMORY SIZE? pointer.

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

- HL<DE: CARRY SET
- HL>DE: NO CARRY
- HL><DE: NZ
- HL=DE: Z

- Note: 40A0H-40A1H holds the start of string space pointer.

1EA3-1EB0 – LEVEL II BASIC RUN ROUTINE. If Z FLAG is set, no line number was provided (i.e., RUN instead of RUN nnnn).

If we are here, then the command was RUN nnnn and we are in Cassette BASIC.

1EB1-1EC1 – LEVEL II BASIC GOSUB ROUTINE

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.

**NOTE:**40A2H-40A3H holds the current BASIC line number.

1EC2-1EDD – LEVEL II BASIC GOTO ROUTINE. Register pair DE should hold the nnnn for the GOTO nnnn command.

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:**40A2H-40A3H holds the current BASIC line number.

- HL<DE: CARRY SET
- HL>DE: NO CARRY
- HL><DE: NZ
- HL=DE: Z

Inside the GOTO ROUTINE – If we are here, the line number nnnn was not found, so error out.

1EDE-1E04 – LEVEL II BASIC RETURN ROUTINE

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

**NOTE:**40E8H-40E9H holds Stack pointer pointer.

1EEC – ?RG ERROR entry point.

**NOTE:**40A2H-40A3H holds the current BASIC line number.

OR L

**NOTE:**40DDH holds INPUT flag.

1F05-1F20 – SCAN ROUTINE

- This is also the DATA entry point.

1F21-1F6B – LEVEL II BASIC LET ROUTINE

D5H

**NOTE:**40DFH-40E0H holds Used by DOS.

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
- Double Precision is NZ/NC/P/E and A is 5.

- HL<DE: CARRY SET
- HL>DE: NO CARRY
- HL><DE: NZ
- HL=DE: Z

- Note: 40A0H-40A1H holds the start of string space pointer.

- HL<DE: CARRY SET
- HL>DE: NO CARRY
- HL><DE: NZ
- HL=DE: Z

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

- HL<DE: CARRY SET
- HL>DE: NO CARRY
- HL><DE: NZ
- HL=DE: Z

LD A,D1H

1F6C-1FAE – LEVEL II BASIC ERROR ON ROUTINE

NOTE:

- The string must be terminated by a byte of zeros.

8DH

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

OR E

LD E,C

**NOTE:**40F0H-40F1H is used by ON ERROR.

**NOTE:**40F2H holds the error flag.

**NOTE:**409AH holds the RESUME flag.

1F95 – Still in the ON routine, but 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.

8DH

1FAF-1FF3 – LEVEL II BASIC RESUME ROUTINE

**NOTE:**40F2H holds the error flag.

**NOTE:**409AH holds the RESUME flag.

NOTE:

OR E

NOTE:

- The string must be terminated by a byte of zeros.

1FCF – This is the RESUME 0 routine

**NOTE:**40EEH-40EFH is used by RESUME.

**NOTE:**40EAH-40EBH holds the line number with error.

**NOTE:**40A2H-40A3H holds the current BASIC line number.

**NOTE:**40DDH holds INPUT flag.

1FF4H-2007 – LEVEL II BASIC ERROR ROUTINE – Evaluates n for ERROR n

- If A=2DH it sets the ZERO FLAG
- If A<2DH then the CARRY FLAG will be set
- if A>=2DH then the NO CARRY FLAG will be set.