TRS-80 Level I Simulator Help Page
Overview | Keyboard help | Language help | Error messages | Saving your program | Reporting bugs | Privacy policy
This Simulator is based on TRS-80 Level I BASIC which debuted back in 1977. It is not an emulator but rather a recreation of Level I BASIC that runs entirely within a browser. Why did I do it? Because these days, programming has been taken out of reach of the average person. Level I BASIC was a simple language from another era. It's my hope that we'll be able to recapture the computer hobbiest atmosphere of the early 80's, and share simple but neat programs in the Simulator's Software Library.
If you are not familiar with Level I flavour of BASIC, it may be helpful to check out some of the sample programs in the Library. Here's an overview for those familiar with other variations of BASIC already:
The Simulator also provides some additional features not found in the original TRS-80 Level I BASIC:
This is an early release of this Java-based Simulator. As such, it's an experiment. Comments are welcome.
The following special keys are implemented in the Simulator:
Key | Function |
Escape (ESC) | Same as the TRS-80's BREAK key. It can be used to halt a program that's running. |
Home | Same as the TRS-80's CLEAR key. Clears the screen. |
F3 | Brings up a File Window showing you the file generated by all PRINT# commands in your program. This is the same file read by INPUT# and may be edited in this window. |
Shift+F4 | Same as the TRS-80's RESET button. Similar to BREAK but will also recover from some BASIC-induced lock-ups. In addition to stopping the program, it also clears the screen and restores the text colour to white. |
Shift+Arrows | Types an arrow symbol. |
Language Reference: |
Subsections: Commands | Statements | Functions | Operations | PRINT statement (details) | Colour chart
This is not intended to be tutorial, but rather a refresher/reference guide. If you want to learn Level I BASIC, check out some of the samples in the Library.
Notation used in this reference:
The following commands may be issued only at the READY prompt:
Command | Abbreviation | Description |
LIST [n] | L. [n] | List program lines starting with line n (or the first program line if n is omitted). Up to 12 lines are listed initially. If there are more than 12 lines from line n on, the list will pause. You may scroll through the remaining lines, one at a time, by pressing the Up Arrow or hitting "^" (that's the carat which is Shift+6 on most keyboards). Pressing ENTER or ESCAPE will end the list and return you to the READY prompt. If there are only 12 lines or less, you will go to the READY prompt automatically. |
RUN [n] | R. [n] | Start running your program from line n. If n is omitted the program will start at the first line. Note: variables are not cleared when you run a program. |
NEW | N. | Erase all lines of the current program from memory. Variables are not cleared. |
CONT | C. | Continue a program that has been interrupted by pressing ESCAPE. The program resumes where it left off. You cannot continue a program if you have edited it. In that event, you'll have to restart your program by typing RUN. |
CLOAD | CL. | In the original Level I BASIC, this loaded a program from casssette. In the Simulator, it brings up a window into which you can paste program text (e.g. if you had it stored in a text file on your computer). The same result can be accomplished by clicking the "Open Program Window" button.. |
CSAVE | CS. | In the original Level I BASIC, this saved your program to a casssette. In the Simulator, this command brings up a text window containing your program. You can copy this text into another file (e.g. into Notepad) for safe-keeping. The same result can be accomplished by clicking the "Open Program Window" button and copying the text from there. |
Statement subsections: Output and graphics | Variables | Flow control | File input/output
Statement | Abbreviation | Description |
CLS | none | Clears the screen and moves the cursor back to the upper left hand corner. If INVERSE has been set non-zero, then the screen will be filled with the colour set by the last COL. command. The screen WIDTH is automatically restored to 64 characters after a CLS. |
PRINT [...] | P. [...] | Prints a message or the contents of a variable. Can also be used to position the cursor. Full syntax details are listed separately below. |
COLOUR n or COLOR n |
COL. n | n is a value between 1 and 15 (see colour chart below). It specifies the colour that all subsequent text and graphics will be drawn in. (Note: due to the way graphics are handled on the TRS-80, when you draw pixels with SET or RESET, the colour will also apply to a 2x3 block containing the pixel you are changing.) |
INVERSE | INV. n | n may be 0 (normal text) or 1 (inverse text). Like COL., this setting applies to all subsequent text printed after the command is issued. This command does not affect graphics drawn by SET or RESET. |
SET(x,y) | S.(x,y) | Draws a pixel at the screen coordinate (x,y) where (0,0) is the upper-left corner, (127,0) is the upper-right corner, and (127,47) is the lower right corner. If no COL. command is issued, the pixel will be white. Otherwise, it will be the colour specified by the last COL. command executed. |
RESET(x,y) | R.(x,y) or RE.(x,y) |
Equivalent to SET, but clears the pixel at (x,y) (i.e. sets it to black). If used as an immediate command (i.e. at the READY prompt without being preceeded by a line number) you should use the RE. abbreviation instead of R. so as to avoid confusion with RUN. |
WIDTH x | W. x | WIDTH 64 sets the screen to 64x16 characters, while WIDTH 32 sets the screen to 32x16 characters. (Note: when in 32x16 mode, graphics drawn using SET and RESET ignore every second pair of pixels along a horizontal line. i.e. the X co-ordinate of pixels in 32x16 mode are 0, 1, 4, 5, 8, 9, 12, 13, ..., 124, 125. This reproduces the behaviour of the 32x16 mode in Level II BASIC.) |
CURSOR x | CU. x | By default, the cursor is always printed on the screen. The command CURSOR 0 will hide the cursor when the user is not being prompted for INPUT (or at the command prompt). CURSOR 1 will make the cursor appear always. |
LET v = x | L. v = x or v = x |
Set variable v (can be a numeric variable A-Z, an array element A(n) or a string A$ or B$) to the value or expression x. (e.g. "LET A=2:LET B=1/A:LET A$=DOG") With strings, quotes are not necessary if it is the last statement on a line and the string value does not contain a comma. The word LET may be omitted, as it is implicit when the = sign follows a variable name at the start of statement.. |
INPUT ["message";] v[, v2][, v3][...] | I. ["message";] v[, v2][, v3][...] | Optionally prints message, then prints a question mark ("?") and waits for the user to type a response (followed by ENTER). The user's input is then assigned to v. (The user can type a number, a string, or an expression. e.g. typing "1/2" in response to "INPUT A" will set A=.5.) If multiple variables are specified, then the user should enter multiple values, separated by commas. (e.g. responding "2,5" to " INPUT A, B" will set A=2 and B=5.) |
READ v[, v2][, v3][...] | none | Starting at the top of the program, the READ statement scans the program for DATA statements. When a DATA value is found, it is assigned to v. The next one is assigned to v2 (if a second variable is specified), the third to v3 (again, if specified). Subsequent READs will pick up where the last one left off (even if it was in the middle of a single DATA statement). An error will occur if a READ is issued and all DATA has already been READ. Use RESTORE to start READ from the beginning of the program again. |
DATA value1 [,value2] [,value3] | D. value1 [,value2] [,value3] | Specifies data for the READ statements. values can be numbers or strings. (If value is a string and the variable v in READ v is a numeric variable, the result will not be useful.) If the program reaches a line containing a DATA statement, execution continues on to the next line, passing harmlessly through the DATA statement. There can be no statements following a DATA statement on the same line (e.g. separated by a colon). Everything on a single line that comes after the DATA statement is interpreted as data. |
RESTORE | REST. | Rewinds the internal pointer so that the next READ will start looking for the first DATA value from the beginning of the program. |
REM | none | Everything after the REM ("remark") statement on a given line is ignored. Execution continues on to the next line after the REM statement. This is useful if you want to insert comments, reminders or explanations into your program. |
END | E. | Stops the program and returns to the READY prompt. |
STOP | ST. | Makes BASIC act as if the ESCape key had been pressed (which halts the program and displays the command prompt). The user can manually resume execution at the next statement after the STOP by typing CONT at the READY prompt. Useful for debugging. |
FOR v = a TO b [STEP c] | F. v = a TO b [S. c] | Indicates the start of a counting loop. Numeric variable v (which represents a variable A-Z or an array element A(n)) is set to the value a. When a NEXT statement is encountered, the value c is added to v and compared to b. If c is positive and the new v is less than or equal to b, execution returns to the first line following the matching FOR statement. (If c is negative, the program loops back if v is greater than or equal to b.) Note: there will always be at least one pass through the loop. Whether v is in range or not is not tested until the NEXT statement is encountered. Multiple FOR/NEXT statements may be nested (e.g. "FOR X=0 TO 127:FOR Y=0 TO 47:SET(X,Y):NEXT Y:NEXT X"). However, the variable NEXTs must name the variables in the reverse order to the FORs. (e.g. in the preceeding example, ending it with "NEXT X:NEXT Y" would lead to an error.) |
NEXT v | N. v | See the FOR statement for details. Note: unlike some other versions of BASIC, the variable v cannot be omitted in the NEXT statement, and forms combining multiple variables in a single statement (e.g. "NEXT Y,X") are not valid. Also, NEXT cannot be used as an immediate command (i.e. typed at the READY prompt without a line number so that it will execute immediately). In fact, N. at the READY prompt means "NEW", not "NEXT". |
IF expression [THEN] statement | IF expression [T.] statement | expression is evaluated. If it is true or non-zero, statement is executed. statement can be any statement or combination of statements separated by colons. e.g. IF A=21 PRINT"BLACKJACK!" or IF (R>5)*(A<=21) THEN PRINT"PUSH". (The latter example reads as "if R is greater than 5 and A is less than or equal to 21". Replacing the * with a + would replace the "and" with an "or".) As a shorthand, if statement is "GOTO l", you can simply write the line number alone (e.g. "IF A<=21 THEN 300" instead of "IF A<=21 THEN GOTO 300"). |
GOTO l | G. l | Go to line l. Sets the next statement to execute to be line l. |
GOSUB l | GOS. l | Similar to GOTO, but when a RETURN is encountered, the program will resume at the next statement following the GOSUB. (e.g. '10 GOSUB 20:PRINT"THERE":END' followed by '20 PRINT"HELLO":RETURN' will print "HELLO" followed by "THERE".) |
RETURN | RET. | See GOSUB. |
ON x GOTO l1[, l2][, l3][...] | ON x G. l1[, l2][, l3][...] | Evaluates the numeric expression x, truncating anything after the decimal. If the result is 1, the program goes to line l1. If it is 2, the program goes to l2, etc. If x is out of range (less than 1 or greater than the number of entries in the list), the statement is ignored. |
ON x GOSUB l1[, l2][, l3][...] | ON x GOS. l1[, l2][, l3][...] | Same as ON ... GOTO except that a GOSUB l1 is executed if the result is 1, GOSUB l2 if the result is 2, etc. |
PAUSE x | PA. x | The program will stop for x 1/1000ths of a second, where x can be between 0 and 32767 (32.767 seconds). PAUSE may be interrupted with the Escape key. |
INPUT# v[, v2][, v3][...] | I.# v[, v2][, v3][...] | Same as INPUT except that instead of prompting the user, the data is read from a file. In the Simulator, the file read by INPUT# may be viewed by pressing F3. If INPUT# has reached the end of the file, the File Window will automatically open, asking you to add more data. To make your program start reading from the top of the file again, use the REWIND command. |
PRINT# v [;","; v2] [;",";v3] [...] | P.# v [;","; v2] [;",";v3] [...] | PRINT# is used to write variables (strings, numeric variables and/or array elements) to a file which will then be read back by INPUT#. Note the format requires that multiple variables be separated by ;","; so that a comma is written between the elements. In the Simulator, the output of PRINT# is directed to the file window, which may be viewed by pressing F3. Output will be placed in the file after the previous read or written line. If you wish to write the file again from the beginning, use the REWIND command. |
REWIND | REW. | Used in conjunction with PRINT# and INPUT#. In the original TRS-80, PRINT# wrote to a cassette file and INPUT# read back from it. In the Simulator, PRINT# writes to a text window which may be brought up by pressing F3. INPUT# reads from the same window. After a REWIND command, the next INPUT# or PRINT# will start reading/writing at the top of this text file again. |
The following functions return a numeric value:
Function | Abbreviation | Description |
RND(x) | R.(x) | Returns a random whole number between 1 and x. If x is zero it returns a random decimal number between 0 and 1. |
ABS(x) | A.(x) | Returns the absolute value of x (i.e. removes the negative sign if the number is negative). |
INT(x) | I.(x) | Returns the integer portion of a value x (i.e. removes the fraction after the decimal). |
MEM | M. | Returns a number indicating how many bytes of memory are still free. (i.e. not taken up by your program.) The largest array index n which may be used in the array variable A(n) is INT(MEM/4-1). |
POINT(x,y) | P.(x,y) | If there is a pixel set at co-ordinate (x,y), this function returns a 1. If the pixel at (x,y) is off (black), this function returns a 0. Pixels are turned on or off via the SET or RESET statements, respectively. |
CPOINT(x,y) | CP.(x,y) | Works like POINT(x,y) except it returns the colour of the pixel at (x,y) or 0 if it is black. |
INKEY | INK. | Returns a number uniquely indicating the character of the key being held down. If no key is being held down, INKEY returns 0. |
The following math operations are supported:
Operation | Description |
x * y | Multiplies x by y. |
x / y | Divides x by y. |
x + y | Returns the sum of x and y. |
x - y | Returns the difference x minus y. |
x = y | Returns a 1 if x equals y. Otherwise the result is 0. |
x < y | Returns a 1 if x is less than y. Otherwise the result is 0. |
x > y | Returns a 1 if x is greater than y. Otherwise the result is 0. |
x <= y or x =< y | Returns a 1 if x is less than or equal to y. Otherwise the result is 0. |
x >= y or x => y | Returns a 1 if x is greater than or equal to y. Otherwise the result is 0. |
x <> y or x >< y | Returns a 1 if x does not equal y. Otherwise the result is 0. |
x and y must be each be either a numeric variable or an array element. Testing of string equality is not supported Level I BASIC.
Multiplication and division are evaluated prior to addition and subtraction. And, all four of these math operations are evaluated before the <, =, and > comparisons. Parantheses can be used to override this order of operations. For example:
The expression | Evaluates as |
1-3/4 | 0.25 |
(1-3)/4 | -0.5 |
1<4 | 1 |
0.5>=0.7 | 0 |
(1<4)*(0.5>=0.7) | 0 |
Note for programmers from other languages: The IF statement will execute the statement that follows the THEN only if the expression evaluated is non-zero. Since a*b will be non-zero only if a and b are both non-zero, "*" works like a logical AND. Similarly, since comparisons return an unsigned number a+b will be non-zero when either of a or b are non-zero. So, "+" can be used as a logical OR.
PRINT is a very flexible command. At its basic level it can output a message or the contents of a variable. For example:
Statement | What you see |
PRINT"HELLO" | HELLO |
A=3 PRINT A |
3 |
PRINT 27*6/9-40 | -22 |
A$=TEST PRINT A$ |
TEST |
If you end your PRINT statement with a semicolon, the next PRINT statement (or INPUT statement) will continue on the same line, rather than starting on the next line. e.g. PRINT"HELLO ";:PRINT"THERE" will print the message "HELLO THERE" on a single line.
You can also combine PRINT statements with the semicolon. For example A=3:PRINT"A=";A will print the message "A= 3 ". (There is a space between the equal sign and the 3 as that is where the sign would go if the number were negative.)
TABs: You can also include the function TAB(x) which will position the cursor to column x of the current line before it prints anything. For example, PRINT TAB(29);"CENTRE" will print the word CENTRE in the centre of the line. (Each line is 64 characters wide and x can be in the range 0-63. If the cursor is already to the right of the requested column, the text will print at the cursor position. Remember, if you don't end your PRINT statement with a ";", subsequent PRINTs start at the beginning of a new line).
Positioning the cursor anywhere: There are 16 lines in the Simulator window, each 64 characters wide. You can use the statement PRINT AT x;... to position the cursor anywhere on the screen prior to printing. In this case x is a number from 0 to 1023. 0 represents the upper-left corner, 64 the beginning of the second line, 128 the beginning of the third line, etc. down to 1023 which is the lower-right corner. (Note: if you position near the bottom there may not be enough room for what you wish to print. If this happens the screen will scroll.) The general formula is x = 64*r + c where r is the row (from 0-15) and c is the column (from 0-63). PRINT AT 541;"MIDDLE" will print the word MIDDLE starting 8 rows down from the top, 29 columns from the left. You can also use PRINT AT to position where the INPUT prompt is printed (e.g. "PRINT AT 541;:INPUT A$").
Below is a chart of the colour values used by the COL. command and returned by the CPOINT(x,y) function. The colours follow a pattern analogous to the CGA graphics palette.
0 black* | 4 dark red | 8 dark grey | 12 light red |
1 dark blue | 5 dark magenta | 9 light blue | 13 light magenta |
2 dark green | 6 brown | 10 light green | 14 yellow |
3 dark cyan | 7 light grey | 11 light cyan | 15 white |
*Colour 0 (black) is a valid return value for CPOINT(x,y) but it may not be used as a parameter for the COL. command. If you want to draw pixels in black, use RESET instead of SET. If you want to draw text in black on another colour background, use INVERSE. If you want to draw black text on a black background, use spaces instead and pretend.
There are three error messages you may encounter when running your program in the Simulator:
WHAT? | This generally indicates a syntax error. Either you misspelled a command, or entered its parameters incorrectly (e.g. left out a comma, had an inappropriate character, etc.) |
HOW? | This usually indicates a parameter that is out of range. e.g. PRINT 1/0 will generate a HOW? message, since dividing by zero gives infinity. |
SORRY | Usually indicates that you are out of memory. Either your program is too large, your array element n in A(n) is too high, or the formula you were trying to evaluate was too complex. |
Click "Open Program Window" or type CSAVE at the READY prompt to bring up a text window that contains your program. You can then copy it (e.g. with CTRL-C) and paste it into a text file (e.g. into Notepad) for safe keeping on your own computer.
Warning: if you leave the Simulator's page or hit reload/refresh while viewing it, the Simulator will reset and your program and data will be lost. There is a checkbox on the bottom of the page which, when checked, should give you a warning before this happens. However, this feature may not work on all browsers.
Loading a program:
Click "Open Program Window" or type CLOAD at the READY prompt to bring up a text window. Paste the program you wish to load into this text window. For example, if your program is in a text file in Windows' Notepad, follow these steps:
If you find a bug in the Simulator, please report it to me. Be sure to specify your computer type and the brand and version of your browser. Of course, any other email regarding the Simulator can be sent to me as well.
BEFORE EMAILING: The Simulator and its associated pages require both Java Applet (i.e. Java Virtual Machine) and JavaScript support in your browser. Make sure these options are installed and enabled. Without them, virtually nothing here will work. If you are uncertain whether your browser suppports these features or has them enabled, consult the Help Page for your browser (usually accessible from your browser's Help menu). I confess I haven't tested this on many different systems or browser versions, and I'm definitely not familiar with the configuration of all breeds of browsers, so your browser's Help Page is probably a better bet for assistance in that regard.
Since this Simulator makes aggressive use of Java and JavaScript, I felt it would be polite to disclose what it's doing. First off, your BASIC programs are stored in your computer's memory, running in your local Java Virtual Machine. Though the Program Window is mediated by a web page, your programs are not uploaded to any server. (Unless, of course, you intentionally fill out the form to submit it to the Software Library. Anythng you enter on that form will ultimately end up on the web page for your submitted program, but I'm hoping that it's obvious enough what you're doing when you fill out the form.)
A cookie is submitted to your browser by the JavaScript, but this is strictly to save your preference for the "confirm on exit" checkbox -- nothing else. No other data is stored on your computer's hard drive, aside from what may end up in your browser cache. (If I could store on your hard drive, it'd make saving your BASIC programs a lot simpler.)
Finally, the hit counter at the bottom of the page does do some rudamentary visitor tallying. It records the referring page that brought you here, and visitors' IPs in order to determine how many visitors are new and how many are "repeat customers". This is so I can get an idea of how popular this site is and whether it's worth the trouble to keep it going and/or expand upon it. :-) I do not share this data with others.
Beyond that, there is no malicious code or subterfuge in my Java and JavaScript. In theory it's supposed to be an isolated enivornment anyway. Nonetheless, I can't be reponsible for the consequences if your browser's Java VM is not working properly. I've seen Java crash Internet Explorer 4.0 regularly, for example. If you're worried, save anything important before visiting here, and as a general rule it's always a good idea to make backups.
All content ©2000 Jeff Vavasour. Updated April 09, 2003. TRS-80 is a trademark of RadioShack Corporation.