← Back to sim_6502

Tiny BASIC

The line-numbered integer BASIC bundled with the sim_6502 simulator.

A small line-numbered, integer BASIC interpreter written in 6502 assembly. It runs inside the simulator using the Apple II-style keyboard ($C000/$C010) for input and the ATASCII text screen at $0800 for output. Source lives in example/tinybasic.asm; the assembled object (example/tinybasic.hex) loads and runs at $1000.

Loading & running Editing Values & expressions Statements Input / output Errors Limits Example

Loading and running

  1. Open example/tinybasic.hex with the Open .hex file toolbar button. The file sets the reset vector and a start address of $1000.
  2. Press Run.
  3. Switch to the Screen tab. You should see the TINY BASIC banner and a > prompt.
  4. Type at the > prompt. Use the on-screen keyboard or, on desktop, your physical keyboard. Letters are upper case (as on an Apple II).

The interpreter works in two modes:

Program entry and editing

Values, variables and expressions

Numbers

All values are 16-bit signed integers, range -32768 to 32767. Numbers are written in decimal. There is no floating point and there are no strings as values (string literals may only appear directly in PRINT).

Variables

There are 26 variables, named with the single letters A through Z. Each holds one integer. Variables start at 0 and are cleared by NEW.

Operators

In order of precedence, highest first:

OperatorMeaning
( )parentheses
-unary minus (negation)
* /multiply, divide (integer division, truncated toward zero)
+ -add, subtract

Evaluation within a precedence level is left to right, so 100-30-5 is 65 and 20/3 is 6. Division by zero is an error. Arithmetic wraps around modulo 65536 on overflow; no overflow error is reported.

Relations (used in IF only)

= equal, <> not equal, < less than, > greater than, <= less than or equal, >= greater than or equal.

PEEK(expression)

Reads one byte from the memory address given by the expression and returns it as a value 0..255. It may be used anywhere a value is allowed, e.g. PRINT PEEK(2048) or A = PEEK(B) + 1. The address is taken modulo 65536. Reading a memory-mapped I/O location (such as the keyboard at $C000) has the same side effects as the hardware would.

Statements

Only one statement is allowed per line, except that IF ... THEN may be followed by a second statement on the same line.

LET var = expression

Assigns a value to a variable. The word LET is optional, so LET A = 10 and A = 10 are equivalent.

POKE address, value

Writes the low byte of value to the memory address given by the first expression — the companion of PEEK. Example: POKE 2048, 65 stores 'A' at the top-left of the screen ($0800). The address is taken modulo 65536; only the low 8 bits of the value are stored.

PRINT item ; item , item ...

Prints expressions and quoted string literals.

Examples: PRINT "X=";X and PRINT A , B , C.

IF expr relation expr THEN statement

Evaluates the comparison. If it is true, the statement after THEN is executed; if false, the rest of the line is skipped. Example: IF X = 0 THEN GOTO 100.

GOTO expression

Jumps to the line whose number equals the expression's value.

GOSUB expression / RETURN

GOSUB is like GOTO, but remembers where it came from so RETURN can come back to the statement after the most recent GOSUB.

FOR var = start TO limit [ STEP step ] / NEXT [ var ]

Counted loop. The variable is set to start. The body runs, then NEXT adds step (default 1) to the variable and loops back while the variable has not passed limit (<= limit for a positive step, >= limit for a negative step). The variable name on NEXT is optional and is ignored. The limit is tested at NEXT, so the loop body always runs at least once. FOR loops may be nested.

INPUT var , var ...

Prints a ? prompt and waits for the user to type a number followed by RETURN, storing it in the variable. A leading - is allowed for negative input. Multiple variables may be listed, each prompting in turn.

REM ...text...

A remark (comment). The rest of the line is ignored.

END

Stops the program and returns to the > prompt.

NEW

Erases the program and clears all variables.

CLS

Clears the text screen and moves the cursor to the top-left corner.

CXY x , y

Moves the cursor to column x (0..39) and row y (0..31) so the next PRINT starts at that position. The arguments may be parenthesised, so CXY 10, 5 and CXY(10, 5) are equivalent. CXY is only useful inside a running program; at the direct > prompt the cursor is reset for the next input line.

LIST / LIST n / LIST a , b

Lists the stored program in line-number order.

The line numbers may be any expressions. Listing a range is handy when a program is longer than the 32-row screen, e.g. LIST 100,180.

SAVE / LOAD

SAVE writes the current program to a file. The host opens a "Save" dialog; the program is written as plain text (the same form LIST produces), so the file is human-readable and can be edited outside the simulator. A suggested name of PROGRAM.BAS is offered.

LOAD reads a program from a file, replacing the current program (like NEW first). The host opens a file picker; choose a text file previously written by SAVE (or any text file of numbered BASIC lines).

Saving and loading are most reliable on the desktop builds. They talk to the host through simple I/O ports at $C0F0 (command / status) and $C0F1 (data).

RUN

Runs the stored program from the lowest line number. RUN resets the GOSUB and FOR loop state before starting.

Input / output details

Keyboard. Input is read one key at a time from the Apple II keyboard register: $C000 bit 7 set means a key is ready and bits 0–6 are its ASCII code; reading $C010 clears the "key ready" strobe. The interpreter echoes typed characters to the screen and supports backspace editing of the current line.

Screen. Output goes to the 40-column by 32-row ATASCII text screen at $0800. The display scrolls up when the cursor passes the bottom line. Printable ASCII characters map directly to their ATASCII glyphs.

Errors

On any error (syntax problem, unknown line number for GOTO/GOSUB, RETURN with no matching GOSUB, NEXT with no matching FOR, division by zero, etc.) the interpreter prints ?ERROR and returns to the > prompt, abandoning the running program. The message does not identify the line or the specific cause.

Limits and things not included

This is intentionally a "Tiny BASIC". It does not include floating point, string variables or operations (string literals work in PRINT only), arrays / DIM, logical operators (AND, OR, NOT) or functions (ABS, RND, etc.), multiple statements per line separated by : (except IF ... THEN stmt), or DATA/READ, ON ... GOTO, WHILE, DO and similar.

Programs are stored starting at $2000 and grow upward; variables live in page 2, the input line buffers in page 3, and the GOSUB/FOR stacks in page 4. The interpreter code occupies roughly $1000–$1Bxx. Keywords and variable names are upper case; lower-case input is accepted and folded to upper case.

Example program

10 REM SUM OF 1..N
20 N = 10
30 S = 0
40 FOR I = 1 TO N
50 S = S + I
60 NEXT I
70 PRINT "SUM=";S
RUN
SUM=55

See also SNOW.BAS in the bundled examples for a screen animation that uses CXY, PEEK/POKE arrays and a 16-bit pseudo-random generator.