Ira Goldklang's TRS-80 Revived Site

TRS-80 Revived Site by Ira Goldklang's is an archive of everything related to the Tandy Radio Shack TRS-80 microcomputer lines. Site contains emulators, programs, manuals, books, patches, games, hints, discussions, questions, forums, and tons more.

TRS-80 Information: Model 1 Level 2 BASIC Language Reference

by @ 1:03 am on February 20, 2009.
TRS-80 Model 1 Level 2 BASIC Language Reference


TRS-80 Model 1 Level 2 BASIC Language Reference
By Joe Ganley
The following is republished on my site, unchanged (other than this line), with permission of Ron Kneusel
This document is in beta release and has been discontinued by its prior author.

Contents

  Basics
    Types and Notation
    Program Structure
    Variables
    Storage Representations
    Casting Rules
    Expressions
  Commands and Functions
    Utility Functions
    Assignment
    Input/Output
    Graphics
    Control Structures
    Error Handling
    Static Data
    Type Declarations
    String Functions
    Math Functions
    Random Number Generation
    Hardware/Assembly Access
    Storage Access
  Keyword Index
  Level 3 Keywords
  Acknowledgments

Basics

Types and Notation

Values in TRS-80 Level 2 BASIC may have one of four types: integer,
single- or double-precision floating point, or string.
Throughout this document, values beginning with I
have integer type, values beginning with F have
single-precision floating point type, values beginning with
D have double-precision floating point type, and
values beginning with S have string type.
Values beginning with N may have any of the three
numeric types.
Values beginning with B have integer type and must
be in the range 0 to 255, inclusive.
Values beginning with L are line numbers, which
are integer literals (integer variables cannot be used).
Prepending V to a value notation indicates that
the name of a variable with the corresponding type is expected;
V alone indicates a variable of any type, or of an
unspecified type.

The notation “[ stuff ]” indicates that
stuff is optional.
The notation “{ a | b | ... }” indicates that
any one of the values indicated is acceptable.
The notation * indicates that the quantity it
follows can be repeated zero or more times.

Program Structure

Each line in a BASIC program has a line number, which is an integer in
the range 0 to 65529, inclusive.
The line number from 65530 to 65535 are reserved for system use; e.g.,
65535 is used internally to store a line entered directly without a
line number.
The character “.” gives the current line, i.e. the line
at which the program was stopped by a
STOP or
END command, a user interrupt, or an
error.
The “.” character can be used anywhere a line number is
expected.
When a program is executed, its lines are executed in line-number
order unless a control command causes the
execution order to behave otherwise.

Multiple commands can appear on a single line; these commands are
separated from one another by the “:” character.

In addition, commands (or multiple commands separated by
:“) can be entered directly, without a line number.
These commands are executed immediately, as soon as the line is
completed.
Some commands have no effect (e.g.

href="#DATA">DATA) or do not make
sense (e.g. RETURN) when entered
without a line number.
Other commands (e.g. NEW) are almost
always used without a line number.

Variables


A numeric variable stores a numeric value of type integer,
single, or double.
The lexical structure of a numeric variable name is
letter {letter | number}* [{ % | ! | # }].
However, only the first two characters of a variable name are
significant.
Thus, AA, AAA, AAAA, etc. are
all considered to be the same variable.
The suffix character “%” indicates an integer value,
!” indicates a single, and “#” indicates a
double.
Variables are dynamically typed unless their type is explicitly
specified using one of these suffix characters or a
type declaration.
Variable names cannot contain any BASIC keyword as a substring.
An uninitialized numeric variable is considered to have value 0.


A string variable stores a string value.
The lexical structure of a string variable name is
letter {letter | number}* $ (i.e. the same as a
numeric variable but with $ appended).
Like numeric variable names, only the first two characters are
significant.
As with numeric variables, string variable names cannot contain any
BASIC keyword as a substring.
Strings are implicitly dynamically allocated and their contents and
length can be changed at any time.
String length cannot exceed 255.
There is no character type; a character is represented by a string of
length 1.
The empty string "" is a valid string, and has
length 0.

In the absence of any type declarations, the name
spaces for the four types are all separate,
i.e. “A%“, “A!“, “A#“, and
A$” can all have distinct values.
The default type of, e.g. “A“, is single.

Storage Representations

Integers are stored in 16-bit, two’s complement format; thus, their
range is -32768 to 32767.
They are stored little-endian, i.e. the least significant byte is at
the lower memory address.

How Floating Point Numbers Are Represented.

String variables’ values are allocated on a heap starting from the
highest available memory address and working backward.
For each string variable, a three-byte record is stored in the normal
variable address space.
The first byte contains the length of the string.
The second two bytes contain an unsigned, little-endian integer
specifying the address a containing the first character in the
actual string data.
The remaining characters appear contiguously in the next memory
addresses above a.

Casting Rules

Casting only applies to numeric types.
When a single or double is cast to an integer, the fractional part of
the number is truncated.
When a double is cast to a single, the value is rounded to the nearest
single-precision value (I think).

Expressions

Mathematical expressions on numeric types are like in most any
programming language, with the operators being “+
(addition), “-” (subtraction), “*
(multiplication), “/” (division), and
up-arrow, denoted “^” in this document (exponentiation),
as well as unary “+” and “-“, which indicate
a number’s sign.

The operators “AND“, “OR“, and
NOT” perform the corresponding bitwise operations on
their operands, which are cast to integers.

The relational operators are “&lt” (less than),
&lt=” (less than or equal to), “=” (equal
to), “&gt=” (greater than or equal to),
&gt” (greater than), and “&lt>” (not
equal to).
These are boolean operators, but since there is no boolean type, they
return integer 0 (whose bit representation is hexadecimal 0000) for
“false” and integer -1 (whose bit representation is hexadecimal FFFF)
for “true”.
Thus, the bitwise operators “AND“, “OR“, and
NOT” behave as expected on the results of these
“boolean” operators.

Finally, the “+” operator with string operands
concatenates the right operand onto the end of the left one.

The precedence of the operators is as follows (highest precedence
first):

unary + - NOT

^

* / AND

binary + - OR

&lt &lt= = &lt> &gt= &gt

Commands and Functions

Utility Functions


AUTO [ L1 [ , L2 ] ]

Initiate automatic line numbering.
Lines are numbered starting with L1, or 10 if it
is absent, and incremented by L2, or 10 if it is
absent.
Once AUTO has been started, the program produces the
appropriate line numbers and waits for the user to enter the code for
each.
Hitting BREAK on an empty line terminates and returns to the
READY prompt.
If a line already exists, its line number is followed by a
*“; hitting anything but BREAK at this
point replaces the existing line with whatever the user types.
If the user hits RETURN on a blank line, the line is
deleted.


CLS

Clears the screen and returns the cursor to the upper left.


EDIT L

Enters edit mode for a particular line L.
In edit mode, the following keystroke commands are available:

  • SPACE moves the cursor one character to the right.
  • BACKSPACE moves the cursor one character to the left.
  • D deletes the character at the current position.
  • ID deletes I characters.
  • I enters insert mode. In insert mode,
    characters are inserted as they are typed.

  • SHIFT-[ leaves insert mode.

Pressing RETURN ends insert mode, enters the changes
made, and returns to the READY prompt.
Other EDIT subcommands are under construction


LIST [ L1 ] [ - L2 ]

LLIST [ L1 ] [ - L2 ]

LIST prints the program lines to the screen.
It lists line numbers from L1, or the first line
if L1 is absent, to L2, or the
last line if L2 is absent.
LLIST is exactly the same except that the listing is sent
to the printer rather than the screen.


NEW

Erases all program data and variables currently in memory.


CLEAR [ I ]

Erases all variables currently in memory.
If present, I indicates the amount of space to be
allocated for the string heap; otherwise, the default is 50 or 200
bytes (depending on ROM version).


RUN [ L ]

Runs the program starting with line L, or starting
with the first line if L is absent.


TRON

TROFF

Turns tracing on or off, respectively.
When tracing is on, the line numbers being executed are printed as
they are run.


REM ...

Remark: everything from REM to the end of the line is
ignored.

Assignment


[ LET ] VN
= N

[ LET ] VS = S

Assigns N to VN,
casting if necessary, or assigns
S to VS.

Input/Output


{ PRINT | ? } { X | ; | , } *

LPRINT { X | ; | , } *

PRINT prints zero or more values to the screen.
The values denoted X can be anything at all: a
variable or literal of any type.
The tokens following PRINT are handled in order.
For values X, the value of X
is printed.
If values are separated by “;” or by no separator at all,
then the values are printed right next to one another.
Each time a “,” is encountered, PRINT tabs
over to the next column evenly divisible by 16, moving to the next
line if necessary.
If a PRINT command ends with “;” or
,“, then the next PRINT command will resume
in the position where this one left off, just as though its arguments
were appended to the current PRINT command’s arguments.
Otherwise, the line is ended by a carriage return, and the next
PRINT command will resume at the beginning of the next
line.
The character “?” can be used as a shorthand for
PRINT“.
LPRINT works exactly the same as PRINT
except that output is directed to the printer rather than to the
screen.


{ PRINT | ? } @ I { X | ; | , } *

Same as PRINT, but starts at screen position
I.
Screen positions are numbered in row-major order, i.e. the upper left
corner is 0, the leftmost position in the second line is 64, and so
forth, with the lower right corner at 1023.


TAB ( I )

Tabs to position I on the current line
(modulo 64).
Has no effect if the current cursor position is right of position
I.


PRINT USING S ; { X | ; | , } *

Print the arguments using the format string S.
Specifics of S are under construction.


INPUT [ S ; ] V [ , Vn ] *

Prints the value of S, if present, and then
prompts the user to enter values, which are assigned to the remaining
arguments in order.
Multiple values may be entered separated by commas, by hitting
RETURN after each, or in any combination of the two.


INKEY$ returns S

If a key is currently pressed, then INKEY$ returns a
one-character string containing that key’s value; otherwise, it
returns the empty string.
The keypress is stored in a buffer which is then flushed without
repeat, so if a key is held down, INKEY$ returns its value
only once.


POS ( any ) returns I

Returns the current horizontal cursor position, between 0 and 63
inclusive.
The argument is ignored, and thus can be any pretty much anything.

Graphics


SET ( IX , IY )

RESET ( IX , IY )

SET turns on the pixel at position
(IX,IY), where
0 <= IX <= 127 and 0 <= IY <= 47.
RESET turns off the pixel.


POINT ( IX , IY ) returns I

Returns a nonzero value if pixel (IX,IY) is
on, or 0 if it is off.

Control Structures


GOTO L

Jumps to the first command on line L.


GOSUB L

RETURN

The GOSUB command jumps to the first command on line
L.
A subsequent RETURN command then jumps back to the next
command following the most recently executed GOSUB.
If at any point the number of RETURN commands executed
exceeds the number of GOSUB commands executed, a runtime
error is thrown.


ON N GOTO L [ , Ln ] *

ON N GOSUB L [ , Ln ] *

Jumps, with either GOTO or GOSUB semantics,
to a line number depending on the value x of the greatest
integer less than or equal to N.
If x is 1, it jumps to the first line in the list; if x
is 2, it jumps to the second line, and so on.
If x is 0 or is greater than the length of the list of lines,
then the command has no effect and control continues to the next
command.
If x is negative, then a runtime error is thrown.


IF I THEN commands [ ELSE commands ]

If I evaluates to a nonzero value, then
the commands from after the THEN statement to the end of
the line or the ELSE keyword (if present) are executed.
If commands consists solely of a line number
L, then it behaves as if
commands were "GOTO L".
If I evaluates to 0, then the same action
is performed with the commands or line number from the
ELSE to the end of the line.


FOR VN
= N1 TO N2
[ STEP N3 ]


NEXT [ VN [ , VNn ] * ]

The first time the FOR statement is hit,
VN is set to N1.
When the NEXT is hit, the value of
VN is incremented by N3, or by
1 if the STEP clause is absent.
If the resulting value is less than or equal to
N2, then control is transferred back to
the statement following the FOR statement; otherwise,
control continues to the statement following the NEXT.
If the NEXT has no argument, then it is associated with
the nearest matching FOR.
NEXT VI,VJ is equivalent to NEXT VI:NEXT VJ.
It is permissible to modify VN inside the
loop.
The looping happens at the NEXT, so a FOR
with no matching NEXT is equivalent to
VN = N1.
A NEXT without a matching FOR causes a
runtime error.


STOP

Stops the program just as if the user had hit BREAK.


END

Stops the program like STOP, but without the
"BREAK IN line" message being printed.


CONT

After the user hits BREAK or a STOP or
END command is executed, CONT continues
program execution.
If CONT is executed when the program has not been stopped
in one of these ways, a runtime error is thrown.

Error Handling


ON ERROR GOTO L

Once this command is executed, if an error occurs, rather than
stopping the program and printing an error message, the interpreter
executes a "GOTO L" command.
After the GOTO is executed, the variable ERL
contains the line number where the error occurred, and the variable
ERR contains an integer code for the type of error that
occurred.
The ERR error codes are as follows:
Make this a table?

Code Abbreviation Error
  1       NF      NEXT without FOR
  2       SN      Syntax error
  3       RG      RETURN without GOSUB
  4       OD      Out of data
  5       FC      Illegal function call (e.g. argument type mismatch)
  6       OV      Numeric overflow
  7       OM      Out of memory
  8       UL      Undefined line
  9       BS      Subscript out of range
 10       DD      Redimensioned array
 11       /0      Division by zero
 12       ID      Illegal direct (can't use INPUT at READY prompt)
 13       TM      Type mismatch
 14       OS      Out of string space
 15       LS      String too long
 16       ST      String formula too complex
 17       CN      Can't CONTinue
 18       NR      No RESUME
 19       RW      RESUME without error
 20       UE      Unprintable error (e.g. nested error)
 21       MO      Missing operand
 22       FD      Bad file data
 23       L3      Level 3 (disk) BASIC only


RESUME [ { NEXT | L } ]

After an error is caught, RESUME resumes execution of the
program.
RESUME with no argument resumes starting with the
offending command.
RESUME NEXT starts with the command following the
offending command.
RESUME L starts with line L.
A RESUME that is reached other than as the result of an
ON ERROR GOTO is an error.

Static Data


DATA value [ , values ] *

READ V , [ Vn } ] *

RESTORE

These commands are used for storing and retrieving static data stored
as part of a program's code.
The values in the DATA statement are literals of any
type, though string values should be entered without quotation marks.
All of the DATA values in a program are indexed from left
to right within each statement, and in line-number order throughout
the program, and a pointer is maintained to the next item to be read
(which is initially the first item in the program).
The READ command reads the next DATA item
(or items) into the variables specified, and increments the "next
item" pointer appropriately.
If the variable specified in a READ is a string variable,
then the data is read as a string, regardless of its apparent type.
If the variable is numeric, then the data is read as a numeric value
if possible; if an attempt is made to read a non-numeric data value
into a numeric variable, then (rather cryptically) a syntax error is
thrown at the line number of the DATA statement.
The RESTORE command reinitializes the "next item" pointer
to point to the first data item in the program.

Type Declarations


DEFINT V [ - V
[ , V [ - V ] ] ] *


DEFSNG V [ - V
[ , V [ - V ] ] ] *


DEFDBL V [ - V
[ , V [ - V ] ] ] *


DEFSTR V [ - V
[ , V [ - V ] ] ] *

Declares one or more variables to be of type integer, single, double,
or string, respectively.
The hyphen is used for ranges of variables; e.g., A - E
is the variables A, B, C,
D, and E.
Separate variables or separate ranges of variables are separated by commas.
Once a variable has been declared to a particular numerical type,
assigning a value of another numerical type to it causes the value to
be
cast to the variable's type.
Ranges of variables only work for single-letter variable names.
A variable can be redeclared, but doing so destroys the value it held
before the redeclaration if the new type is not the same as the old
type.
If a variable is declared to be of string type, then the
"$" following its name becomes implicit; i.e., If
"DEFSTR A" is executed, then henceforth "A"
and "A$" both refer to the same string variable.


DIM V ( I )

Declares an array variable V containing
I number of elements, which are indexed from 0 to
I.
The value of an array element is accessed as
V(I).
If the argument is out of array bounds, a runtime error is thrown.
Array variables that are used without declaring them in a
DIM statement have dimension 10 by default.

String Functions


ASC ( S ) returns B

Returns the ASCII value of the first character in S.


CHR$ ( B ) returns S

Returns a string consisting of a single character whose ASCII value is
B.


LEFT$ ( S1 , I ) returns S2

RIGHT$ ( S1 , I ) returns S2

Returns a string containing, respectively, the leftmost or rightmost
I characters in S1.


MID$ ( S1 , I1 , I2 )
returns S2

Returns substring of S1 that starts at index
I1 and has length I2.


LEN ( S ) returns I

Returns the length of S.


STR$ ( N ) returns S

Returns the string representation of N,
e.g. STR$(3.14) = "3.14".


VAL ( S ) returns N

Returns the value of S considered as a
number, e.g. VAL("3.14") = 3.14.
If S does not contain a valid number, then
VAL returns 0.


STRING$ ( I , S1 ) returns S2

Returns a string of length I, all of whose
characters are the first character of S1.

Math Functions


ABS ( N ) returns S

Returns the absolute value of N.


SIN ( N ) returns S

COS ( N ) returns S

TAN ( N ) returns S

ATN ( N ) returns S

Returns the sine, cosine, tangent, or arctangent, respectively, of
N.


CINT ( N ) returns I

CSNG ( N ) returns F

CDBL ( N ) returns D

Casts N to integer, single, or double type,
respectively (see
above for casting rules).


FIX ( N ) returns I

Returns N with the fractional portion
truncated, i.e. returns the integer highest in absolute value but
nearer to 0 than N.


INT ( N ) returns I

Returns the greatest integer less than or equal to
N.


EXP ( N ) returns S

Returns e (approximately 2.71828) raised to the
N power.


LOG ( N ) returns S

Returns the natural (base-e) logarithm of
N.
A runtime error is thrown if N is less than or
equal to 0.


SQR ( N ) returns S

Returns the square root of N.
A runtime error is thrown if N is less than 0.

Random Number Generation


RANDOM

Seeds the random number generator.
The seed is based on the value of the R (refresh) register,
which is clocked at a higher rate than the CPU and thus produces a more
or less random value.


RND ( I1 ) returns I2 if I1 > 0

RND ( 0 ) returns S

RND(I1), for I1 > 0,
returns a pseudorandom integer value I2 such that
1 <= I2 <= I1.

RND(0) returns a pseudorandom single-precision
floating-point value S such that
0 < S < 1.

Hardware/Assembly Access


POKE I, B

PEEK ( I ) returns B

POKE sets the value of memory location
I to B.
PEEK returns the value stored in memory location
I.

VARPTR ( V ) returns I

Returns the memory address of the variable V.
For a numeric variable, this is the actual address of the low-order
byte of the number (see
above for details on how
numbers are stored in memory).
For a string variable, the address returned by VARPTR is
the address of the three-byte record containing the string's length
and a pointer to its data (see above for details
on how strings are stored in memory).
Note that position (I - 3) holds the variable's
type (2 for integer, 3 for string, 4 for single, and 8 for double),
and positions (I - 2) and (I - 1)
hold the first two characters in the variable's name.

MEM returns I

Returns the amount of memory currently available, in bytes.

FRE ( { V | S | N } ) returns I

Returns the amount of memory currently available for variables of the
same type as the argument.
If the type of the argument is numeric, then this is the same as
MEM.
If the type of the argument is string, then this indicates the amount
of string heap space available.
(The amount of string heap space available can be changed using the
CLEAR command.)

SYSTEM

Puts the machine in monitor mode, giving a "*?" prompt,
from which two commands are available.
Entering a filename loads the named assembly-language file from
cassette.
Entering "/" executes an unconditional jump to the
starting address of the last program loaded, or entering
"/" followed by an integer I
executes an unconditional jump to address I.

USR ( I1 ) returns I2

Calls an assembly-language routine.
Prior to calling USR, the address of the routine must be
stored (using, e.g.,
POKE),
little-endian, in addresses 16526 and 16527.
Within the assembly-language program, "CALL 0A7FH" loads
I1 into the HL register pair, and
"JP 0A9AH" returns the HL register pair as
I2.
Note that an assembly-language routine called by USR is
only allocated 8 stack entries.

OUT B1 , B2

IN ( B1 ) returns B2

OUT sends the value B2 to expansion
interface port number B1.
IN returns the value read from port B1 on the
expansion interface.

Storage Access


CLOAD S

CSAVE S

Load a file named S from or save it to cassette,
respectively.


CLOAD? S

Verifies that program S on tape matches the program in memory.

Keyword Index


?
ABS
AND
ASC
ATN
AUTO
CDBL
CHR$
CINT
CLEAR
CLOAD
CLOAD?
CLS
CONT
COS
CSAVE
CSNG
DATA
DEFDBL
DEFINT
DEFSNG
DEFSTR
DELETE
DIM
EDIT
ELSE
END
ERL
ERR
ERROR
EXP
FIX
FOR
FRE
GOSUB
GOTO
IF
INKEY$
INP
INPUT
INT
LEFT$
LEN
LET
LIST
LLIST
LOG
LPRINT
MEM
MID$
NEW
NEXT
NOT
ON
OR
OUT
PEEK
POINT
POKE
POS
PRINT
PRINT@
RANDOM
READ
REM
RESET
RESTORE
RESUME
RETURN
RIGHT$
RND
RUN
SET
SGN
SIN
SQR
STEP
STOP
STR$
STRING$
SYSTEM
TAB
TAN
THEN
TO
TROFF
TRON
USING
USR
VAL
VARPTR

Level 3 Keywords

Disk systems enhanced the machine's BASIC to Level 3, storing the
routines in RAM and plugging their locations into the jump tables for
the appropriate keywords.
Thus, a number of Level 3 BASIC keywords are reserved words in Level 2
BASIC, but attempting to use them results in an error.
These Level 3 keywords are:

CLOSE   CMD     CVD     CVI     CVS     DEF     EOF     FIELD   FN
GET     INSTR   KILL    LINE    LOAD    LOC     LOF     LSET    MERGE
MKD$    MKI$    MKS$    NAME    OPEN    PUT     RSET    SAVE    TIME$

Acknowledgments

I am grateful for contributions to this page from
James Cameron,
Pete Cervasio,
Jeff Hunsinger,
Gary Katz,
Don Moore,
and Randy Williams.

Last Modified 23 April 1997


"TRS-80" is a trademark of the Tandy
Corporation.


Copyright © 1996-97 J. L. Ganley. All rights reserved.

Leave a Reply

[Ira Goldklang's TRS-80 Revived Site is proudly powered by WordPress.]