The BASIC32 language reference

Quick reference

BASIC32 is a line-numbered BASIC close to classic 1980s home-computer dialects, with a small graphics extension. This reference documents every command, statement, function, special variable, operator group, and language rule the interpreter currently implements — nothing more, nothing speculative.

Entering programs

Typing a line that starts with a number stores (or replaces) that line in a program held in memory; typing a bare line number with nothing after it deletes that line. Anything else typed at the prompt — not starting with a line number — is an immediate statement: it executes right away and is never stored, e.g. PRINT 2+2. RUN, LIST, NEW, RENUM, LOAD, SAVE, KILL, FILES, MERGE, CONT, AUTO, and EDIT are direct commands rather than statements; see their entries below.

The program in memory is lost at a power cycle or NEW. To keep one, use SAVE: saved programs live in the board's internal flash, survive a power cycle, and come back with LOAD or RUN "FILE".

A few rules apply everywhere in the language:

Running the examples

The examples below are complete BASIC programs. Type them in line by line, or load them from a file, and RUN them.

The LIST / RUN / direct-statement transcripts throughout this reference show how the interpreter responds to each line entered; they document the language.

Index

ABS · ASC · ATN · AUTO · BATTERY · BEEP · CHR$ · CIRCLE · CLEAR · CLOSE · CLS · COLOR · CONT · COS · DATA · DATE$ · DEF FN · DIM · EDIT · ELSE · END · EOF · ERASE · EXP · FILES · FILL · FIX · FOR/NEXT · FRE · GET · GFONTH · GFONTW · GHEIGHT · GOSUB · GOTO · GPRINT · GWIDTH · HEX$ · IF/THEN · INKEY · INKEY$ · INPUT · INPUT$ · INSTR · INT · KILL · LCASE$ · LEFT$ · LEN · LET · LINE · LIST · LOAD · LOC · LOCATE · LOF · LOG · Logical Operators · MERGE · MID$ · NAME · NEW · OCT$ · ON · OPEN · PAINT · PALETTE · PAUSE · PLAY · PMAP · POINT · POS · PRESET · PRINT · PSET · PUT · RANDOMIZE · READ · REM · RENUM · RESET · RESTORE · RETURN · RGB · RIGHT$ · RND · RUN · SAVE · SCREEN · SGN · SIN · SLEEP · SOUND · SPACE$ · SPC · SQR · STOP · STR$ · String variables · STRING$ · SWAP · TAB · TAN · TICK · TIME$ · TIMER · TRON/TROFF · UCASE$ · VAL · VIEW · WHILE/WEND · WRITE

ABS

Function — ABS(x)

Returns the absolute value of x.

Examples

PRINT ABS(-5)

Output: 5

Comments

Takes exactly one parenthesized argument, like every BASIC32 function (there's no varargs or optional-argument form). See INT, SQR.

ASC

Function — ASC(s$)

Returns the unsigned byte value (0–255) of the first character of string expression s$.

Examples

PRINT ASC("A")
PRINT ASC("ABC")

Output: 65, 65

Comments

ASC("") on an empty string is ?ILLEGAL QUANTITY ERROR. The argument must be a string; a number is ?TYPE MISMATCH ERROR. ASC is the inverse of CHR$ for a single byte. Bytes are not decoded as Unicode.

ATN

Function — ATN(x)

Arctangent of x, in radians (between -PI/2 and PI/2).

Examples

PRINT ATN(1)*4

Output: 3.14159

Comments

4*ATN(1) is the usual way to get PI. See TAN, SIN, COS.

AUTO

Command — AUTO [start][,increment]

Turns on automatic line numbering: the next input line comes up already typed with start (default 10) and a space, and each numbered line you enter brings up the next number, increment (default 10) higher.

Examples

AUTO 100,5
100 PRINT "HI"
105 END
110

(100 , 105 and 110 were typed by AUTO; pressing Enter on the bare 110 ends it.)

Comments

AUTO ends when you enter a line with nothing after its number (which deletes nothing), erase the number and enter an empty line, or enter any line without a line number (that line then runs as usual). Pre-typed text is edited like typed text — Backspace removes it. A line number that already exists is replaced, as with any typed line.

BEEP

Statement — BEEP

Sounds a short beep: an 800 Hz tone for a quarter second, through the same path as SOUND.

Examples

10 PRINT "DONE": BEEP

Comments

Blocks for the beep's length like SOUND. On a target with no speaker the program still waits that long.

CHR$

Function — CHR$(n)

Returns a one-byte string whose single character has byte value n. n is converted to an integer.

Examples

PRINT CHR$(65)
PRINT CHR$(42)

Output: A, *

Comments

n outside 0–255 is ?ILLEGAL QUANTITY ERROR. CHR$(n) is a string-typed value: it belongs in a string context (a $ assignment, PRINT, or another string function's argument), not where a number is expected. Inverse of ASC.

CIRCLE

Statement — CIRCLE (x,y),radius[,[color][,[start][,[end][,aspect]]]]

Draws a circle centered on (x,y) in color (default: the current COLOR foreground). With start and/or end it draws an arc instead; with aspect an ellipse.

Examples

SCREEN 1
CIRCLE (160,90),40
CIRCLE (160,90),40,14,0,3.14159
CIRCLE (160,90),40,12,-0.5,-5.8
CIRCLE (160,90),40,10,,,0.5

A full circle; the top half as an arc; a pie slice (the negative angles also draw the two radius lines); a flat ellipse.

Comments

Angles are radians, counterclockwise from 3 o'clock, between -2*PI and 2*PI (?ILLEGAL QUANTITY ERROR outside). Leave start out to begin at 0 and end out to finish at 2*PI. aspect is the vertical radius divided by the horizontal one (default 1); radius is always the larger of the two. Moves the current graphics position to the center. SCREEN 1 only; clipped like LINE.

CLEAR

Statement — CLEAR

Forgets every variable, array, and DEF FN, closes all open files, empties the FOR/GOSUB/WHILE stacks, and restarts DATA. The program itself stays.

Examples

10 X=5: DIM A(3)
20 CLEAR
30 PRINT X

Output: 0

Comments

Classic BASIC's memory-size arguments (CLEAR ,32768) are accepted and ignored. RUN does the same clearing before a program starts.

CLOSE

Statement — CLOSE [[#]n[, [#]n...]]

Closes the numbered files, or every open file when no number is given. A file opened for output or append is written to storage as it closes. See OPEN.

CLS

Statement — CLS

Clears whichever screen is currently active: the text console in SCREEN 0, or the graphics surface to black in SCREEN 1.

Examples

CLS

Comments

Switching screens with SCREEN preserves neither screen's contents, so CLS is the only way to blank either one. In SCREEN 1 it also returns the graphics text cursor (see LOCATE and PRINT) to row 1, column 1.

COLOR

Statement — COLOR foreground[,background]

Sets the current foreground and background colors. Each is a numeric expression: a palette index 0-15 or an RGB(r,g,b) value. An invalid value is ?ILLEGAL QUANTITY ERROR; a missing, empty, or extra argument is ?SYNTAX ERROR. Both values are checked before either is applied, so a bad background never leaves a half-changed foreground.

Examples

COLOR 4          : REM red text, background unchanged
COLOR 15,1       : REM white on blue
COLOR RGB(255,128,0),0

Comments

COLOR foreground leaves the background alone. A fresh interpreter starts at foreground 15 (white) on background 0 (black); the choice survives CLS, SCREEN changes, and RUN, and resets only when the interpreter starts. It works in either screen mode.

PRINT (SCREEN 0 and 1) and GPRINT draw each character cell opaque: the glyph in the foreground and the rest of the cell in the background, so a space clears its cell to the background. Newlines and cursor movement paint nothing, and text already on screen is not recolored. Serial output stays plain text. LINE, PSET, PAINT, and FILL use the foreground when their color is left off; an explicit color overrides it for that one statement and does not change the COLOR state.

Logical Operators

Operator group — NOT AND OR XOR EQV IMP

Bitwise operators on whole numbers: each operand is rounded to a 32-bit integer and the operation is applied to every bit. Because true is -1 (all bits set) and false is 0, they also work as the logical connectives for conditions. Precedence, highest to lowest: NOT, AND, OR, XOR, EQV, IMP — all below the comparisons, so A>1 AND B<2 needs no parentheses.

Operator Result bit is 1 when
NOT a the bit of a is 0
a AND b both bits are 1
a OR b either bit is 1
a XOR b the bits differ
a EQV b the bits are equal
a IMP b a's bit is 0 or b's bit is 1

Examples

PRINT 12 AND 10; 12 OR 3; 12 XOR 10
PRINT NOT 0; NOT -1
IF X>0 AND NOT X=5 THEN PRINT "OK"

Output: 8156, -10

Comments

Operator words must stand alone (A AND B, not AANDB); a name that merely starts with one, like ORANGE, is an ordinary variable. A value beyond the 32-bit range is ?OVERFLOW ERROR.

CONT

Command — CONT

Resumes a program stopped by STOP or by BREAK (Ctrl-C), at the statement after the STOP or at the statement BREAK interrupted, with every variable, loop, open file and GOSUB intact.

Examples

10 PRINT "A"
20 STOP
30 PRINT "B"
RUN
A
BREAK IN 20
READY.
CONT
B

Comments

In between, direct statements can inspect or change variables (PRINT X, X=0). Editing the program, NEW, LOAD, CLEAR, a normal end, or an error makes it impossible to resume: ?CAN'T CONTINUE ERROR.

COS

Function — COS(x)

Cosine of x, where x is in radians.

Examples

PRINT COS(0)

Output: 1

Comments

Radians, not degrees — matching C's cos(), which the interpreter calls directly. See SIN.

DATA

Statement — DATA item[, item...], with READ and RESTORE

Holds constants for READ. Items are numbers or strings; a string needs quotes only if it contains a comma, a colon, or leading/trailing spaces. DATA does nothing when it runs.

Examples

10 FOR I=1 TO 3
20 READ N$, A
30 PRINT N$; A
40 NEXT
50 DATA ANN, 36, BOB, 41
60 DATA "SMITH, C", 29

Output: ANN36, BOB41, SMITH, C29

Comments

READ takes items in program order across every DATA line, wherever they sit. Reading past the last item is ?OUT OF DATA ERROR; reading a string item into a numeric variable is ?SYNTAX ERROR; an empty item reads as 0 or "".

DATE$

Special variable (readable and assignable) — DATE$

The current local date as a 10-character string, MM-DD-YYYY, with leading zeroes.

Examples

PRINT DATE$

Output: 09-10-2026

DATE$ = "09-10-2026"
LET DATE$ = "09-10-2026"
PRINT DATE$

Output: 09-10-2026

Comments

Not a function call — like TICK, it's read like a variable with no (), and it's re-read from the clock every time it's evaluated. It is a string value: it works anywhere a string expression is accepted (PRINT, GPRINT, assignment to a $ variable, and inside LEFT$, MID$, VAL, and the rest); using it where a number is expected is ?TYPE MISMATCH ERROR.

Assigning it — with implicit assignment (DATE$ = ...) or LET — sets the system clock's date, accepting any valid string expression on the right-hand side, not just a literal. The value must match the exact MM-DD-YYYY format with leading zeroes, and name a real calendar date (02-29 only on a leap year); anything else — malformed strings, out-of-range fields, an impossible date — is ?ILLEGAL QUANTITY ERROR and leaves the clock unchanged. Setting DATE$ preserves the current time of day and the clock keeps advancing normally afterward. INPUT DATE$ is still rejected — setting the clock is assignment syntax, not a new INPUT destination.

The clock has no battery or network backing. The firmware seeds it at boot to a fixed default, 01-01-1970, rather than the build time, so it's consistent across reboots instead of merely approximate — the value has no wall-clock meaning, it's a starting point the clock then advances from, until a program or a direct-mode command corrects it with an assignment. See TIME$.

DEF FN

Statement — DEF FNname[(param[, param...])] = expression

Defines a one-line function. Call it as FNname(args) anywhere an expression is allowed. A name ending in $ makes a string function.

Examples

10 DEF FNHYP(A,B)=SQR(A*A+B*B)
20 DEF FNI$(S$)=LEFT$(S$,1)
30 PRINT FNHYP(3,4); FNI$("BASIC")

Output: 5B

Comments

Up to 8 parameters, each an ordinary variable name: during a call the parameters take the argument values, and afterwards they are put back, so a parameter never changes a program variable of the same name. Any other variable in the body is the program's own. Defining a name again replaces it. Calling an undefined function is ?UNDEFINED USER FUNCTION ERROR; FN NAME with a space is the same as FNNAME. Functions may call other functions, 16 deep.

DIM

Statement — DIM name(bound[, bound...])[, name(...)...]

Creates arrays. Each subscript runs from 0 to its bound, so DIM A(10) holds 11 numbers. A $ name makes a string array. Up to 4 dimensions.

Examples

10 DIM A(5), B$(2,3)
20 A(5)=7: B$(1,2)="HI"
30 PRINT A(5); B$(1,2); A(0)

Output: 7HI0

Comments

Elements start at 0 or "". An array used without a DIM is created automatically with every bound at 10. Subscripts are rounded; one outside the bounds, or the wrong number of subscripts, is ?SUBSCRIPT OUT OF RANGE ERROR. DIM of an existing array is ?DUPLICATE DEFINITION ERROR — ERASE it first. Arrays have their own names: A, A$, A() and A$() are four different things.

EDIT

Command — EDIT line

Brings up stored line line as the next input line, already typed, so it can be changed with Backspace and retyped, then entered with Enter.

Comments

The line editor has no cursor movement, so editing means backspacing to the change. A line number that doesn't exist is ?UNDEF'D STATEMENT ERROR.

ELSE

See IF/THEN.

EOF

Function — EOF(n)

-1 once input file n has nothing left to read, else 0. See OPEN.

ERASE

Statement — ERASE name[, name...]

Deletes arrays, freeing their memory so the names can be DIMmed again. Erasing an array that doesn't exist is ?ILLEGAL QUANTITY ERROR.

EXP

Function — EXP(x)

e raised to the power x.

Examples

PRINT EXP(1)

Output: 2.71828

Comments

EXP(x) above about 709 is ?OVERFLOW ERROR. See LOG.

FILES

Command — FILES

Lists the names of the saved program files in internal flash, one per line, in alphabetical order that ignores case, followed by the READY. prompt.

Examples

SAVE "PONG"
SAVE "clock"
FILES

Output:

clock
PONG
READY.

Comments

With no saved files, FILES prints nothing before READY.. Names are shown exactly as they were saved. FILES takes no arguments; FILES "X" is ?SYNTAX ERROR. See SAVE, LOAD, KILL.

END

Statement — END

Stops program execution immediately.

Examples

10 PRINT "A"
20 END
30 PRINT "B"
RUN

Output: A (line 30 never runs)

Comments

Only meaningful inside a running program; typed directly it does nothing observable. It stops immediately — any statements after END on the same physical line don't run. Unlike NEW, END doesn't clear the stored program or variables — a later RUN starts over from the top with variables left however the previous run left them.

FILL

Statement — FILL (x,y)[,color]

Samples the displayed color at the zero-based pixel (x,y) on the graphics surface, then replaces every pixel in its four-way (up, down, left, right) connected region of that exact color with color, or with the current COLOR foreground when color is omitted.

Examples

SCREEN 1
LINE (50,10)-(10,80),4
LINE -(90,80),4
LINE -(50,10),4
FILL (50,40),2

Comments

Only valid in SCREEN 1 — using it in screen 0 is ?ILLEGAL IN SCREEN 0 ERROR. color is a standard palette number or an RGB() value, same as LINE; an out-of-range palette number is ?ILLEGAL QUANTITY ERROR. Unlike PAINT, FILL has no separate border color — every pixel that doesn't exactly match the seed's captured color acts as a boundary, so the fill stops at the first color change in every direction rather than at a named border color.

A seed pixel outside the graphics surface is a clipped no-op. If the seed already displays color, FILL changes nothing (comparing displayed colors, so a palette number and an RGB() value that render identically also count as already matching). A large fill still terminates safely — it never recurses and never grows unbounded.

FIX

Function — FIX(x)

x with its fractional part dropped, toward zero: FIX(-2.5) is -2 where INT(-2.5) is -3.

FOR/NEXT

Statement — FOR var=start TO limit [STEP step] ... NEXT [var]

Repeats the statements between FOR and its matching NEXT, counting var from start to limit inclusive, in increments of step (default 1).

Examples

10 FOR I=1 TO 3
20 PRINT I
30 NEXT I
RUN

Output: 1, 2, 3

10 FOR I=1 TO 5 STEP 2
20 PRINT I
30 NEXT I
RUN

Output: 1, 3, 5

Comments

The loop body always runs at least once before the exit condition is checked — FOR I=5 TO 1 (no STEP) still runs once with I=5, since the default step is +1 and the check only happens at NEXT. FOR, its body, and NEXT can share one physical line (FOR I=1 TO 3 : PRINT I : NEXT I): each NEXT iteration resumes at the statement right after FOR, mid-line included. The variable name after NEXT is optional and, if given, isn't checked against the loop's own variable — Phase 1 always operates on the top-of-stack loop, so NEXT alone and NEXT I behave identically. Loops nest up to 16 deep (?FOR TOO DEEP ERROR beyond that); a NEXT with no matching FOR is ?NEXT WITHOUT FOR ERROR. Like GOTO, both FOR and NEXT are only legal inside a running program — typed directly, either is ?ILLEGAL DIRECT ERROR.

FRE

Function — FRE(x)

Bytes of memory currently free on the board. The argument (a number or a string) is ignored.

Examples

PRINT FRE(0)

GET

Statement — GET (x1,y1)-(x2,y2), array

Copies a rectangle of the graphics screen into a numeric array, to draw again with PUT. Element 0 holds the width, element 1 the height, then one packed RGB value per pixel, row by row.

Examples

10 SCREEN 1
20 DIM S(16*16+2)
30 CIRCLE (8,8),7,14
40 GET (0,0)-(15,15),S
50 PUT (100,50),S

Comments

DIM the array first with at least width*height+2 elements, and keep the rectangle inside the screen (or VIEW); otherwise ?ILLEGAL QUANTITY ERROR. SCREEN 1 only. Random-access files (GET #) aren't supported.

GFONTH

Special variable (read-only) — GFONTH

The graphics text cell height in pixels — the line height of the fixed-width font PRINT and GPRINT draw in SCREEN 1.

Examples

SCREEN 1
ROWS = INT(GHEIGHT/GFONTH)

Comments

Fixed by the console font the board draws with, so a SCREEN 1 program that positions text with LOCATE derives its row/column counts from GHEIGHT/GFONTH and GWIDTH/GFONTW rather than assuming either. See GFONTW.

GFONTW

Special variable (read-only) — GFONTW

The graphics text cell width in pixels — the advance width of the fixed-width font PRINT and GPRINT draw in SCREEN 1. So in graphics mode LOCATE row,col starts the next PRINT at pixel ((col-1)*GFONTW, (row-1)*GFONTH).

Examples

SCREEN 1
COLS = INT(GWIDTH/GFONTW)

Comments

See GFONTH for why a program reads these rather than hardcoding a cell size.

GHEIGHT

Special variable (read-only) — GHEIGHT

The drawable graphics surface's height in pixels, for use in SCREEN 1 programs.

Examples

PRINT GHEIGHT

Comments

Fixed to the round display's usable drawing area. The surface size is meant to be queried, not assumed, so a program can center or scale itself without hardcoding a resolution. See GWIDTH, LINE.

GOSUB

Statement — GOSUB line

Calls the subroutine that starts at the given line number. Execution jumps there and continues until a RETURN, which resumes at the statement right after the GOSUB.

Examples

10 GOSUB 100
20 PRINT "BACK"
30 END
100 PRINT "IN SUB"
110 RETURN
RUN

Output: IN SUB, then BACK (line 30's END stops the program before it falls into line 100 a second time)

10 GOSUB 100
20 GOSUB 100
30 END
100 PRINT "HELLO"
110 RETURN
RUN

Output: HELLO, HELLO

Comments

Only legal inside a running program — typed directly it's ?ILLEGAL DIRECT ERROR. A GOSUB to a line that isn't in the stored program is ?UNDEF'D STATEMENT ERROR. Calls nest up to 16 deep, sharing no space with FOR/NEXT; a 17th pending call is ?GOSUB TOO DEEP ERROR. Every RUN starts with an empty return stack, so a program stopped by Ctrl-C (BREAK), an error, or reaching its end never leaks pending calls into the next run. There is no ON ... GOSUB, no arguments, and no local variables — a subroutine reads and writes the same global variables as its caller. Pairs with RETURN.

GOTO

Statement — GOTO line

Jumps unconditionally to the given line number.

Examples

10 GOTO 30
20 PRINT "SKIPPED"
30 PRINT "HERE"
RUN

Output: HERE (line 20 never runs)

Comments

Only legal inside a running program — typed directly it's ?ILLEGAL DIRECT ERROR. Jumping to a line number that doesn't exist in the stored program is ?UNDEF'D STATEMENT ERROR. The jump lands on the first statement of the target line, and any statements after GOTO on its own line never run. Most often used as IF's THEN target for conditional branching.

GPRINT

Statement — GPRINT x,y,print-list

Draws a PRINT list on the graphics surface, in the current COLOR foreground on an opaque background-colored cell per character,, starting at the zero-based pixel coordinate (x,y) (top-left origin). print-list follows the same string-literal, expression, ,/; separator, and trailing-separator rules as PRINT.

Examples

SCREEN 1
GPRINT 2,2,"HELLO"
GPRINT 0,20,"X=";X

Comments

BASIC32-specific — not a classic-BASIC statement. Only valid in SCREEN 1 (?ILLEGAL IN SCREEN 0 ERROR otherwise). Unlike graphics-mode PRINT, GPRINT neither reads nor moves the graphics text cursor, so it and LOCATE/PRINT can be mixed freely; a trailing newline from the list is ignored, since it has no meaning at an absolute origin. A , in the list still advances by the same 8-column zones as PRINT, but measured from (x,y) as the list's own column 1 rather than from any screen column, and a zone past the last one that fits the graphics surface's width starts a new line directly below (x,y) rather than wrapping relative to the console or graphics text cursor. Pixels outside the surface are clipped, like LINE. The font cell is GFONTW × GFONTH.

GWIDTH

Special variable (read-only) — GWIDTH

The drawable graphics surface's width in pixels. See GHEIGHT for how it's derived.

Examples

PRINT GWIDTH

HEX$

Function — HEX$(n)

n, rounded, as hexadecimal digits. A negative number shows its 32-bit two's complement.

Examples

PRINT HEX$(255); " "; HEX$(-1)

Output: FF FFFFFFFF

Comments

&HFF writes a hexadecimal constant; see Arithmetic Operators. See OCT$.

IF/THEN

Statement — IF condition THEN line|statements [ELSE line|statements], or IF condition GOTO line

Evaluates condition. If it's nonzero (true), either jumps to THEN's line number or runs the statement(s) after THEN. THEN governs the rest of the physical line: a true condition runs every :-separated statement on it, a false condition skips them all and continues at the next line — or, when the line has an ELSE, at the statement(s) after the ELSE.

Examples

10 X=5
20 IF X=5 THEN PRINT "FIVE"
30 IF X=5 THEN 50
40 PRINT "SKIPPED"
50 PRINT "END"
RUN

Output: FIVE, END (line 40 never runs)

10 X=5
20 IF X=5 THEN PRINT "A" : PRINT "B"
30 IF X=9 THEN PRINT "C" : PRINT "D"
RUN

Output: A, B (line 30's condition is false, so neither C nor D prints)

10 FOR N=1 TO 3
20 IF N=2 THEN PRINT "TWO" ELSE PRINT N : PRINT "-"
30 NEXT
RUN

Output: 1, -, TWO, 3, -

ELSE

ELSE runs its statements (or jumps to its line number) only when the condition is false; when the condition is true, reaching ELSE ends the line. Each side may hold several :-separated statements. When IFs are nested on one line, each ELSE belongs to the nearest IF that doesn't already have one, so IF A THEN IF B THEN X ELSE Y ELSE Z runs Y when only A is true and Z when A is false.

String comparisons

A condition whose left side starts with a string expression (a "literal", a $ variable, or a string-returning function) is a string comparison: two string expressions joined by one of =, <>, <, >, <=, or >=.

10 A$="yes"
20 IF A$ = "yes" THEN PRINT "YES"
30 IF A$ <> "no" THEN PRINT "NOT NO"
40 IF A$ > "M" THEN PRINT "AFTER M"
50 IF UCASE$(A$) = "YES" THEN PRINT "UPPER"
RUN

Output: YES, NOT NO, AFTER M, UPPER

Comparison is bytewise and case-sensitive: "a" is not equal to "A", and every lowercase letter sorts after every uppercase letter. When one value is a prefix of the other, the shorter one sorts first ("A" < "AB"), and the empty string sorts before any non-empty string. To compare without regard to case, normalise both sides with UCASE$ or LCASE$ first; there is no separate case-insensitive operator.

A string compared with a number, on either side, is ?TYPE MISMATCH ERROR, and so is a string with no operator after it. A string comparison is an ordinary expression worth -1 or 0: it can be combined with AND/OR, printed, or assigned.

Comments

The statement form chains: IF X=5 THEN PRINT "HI" : GOSUB 200 runs both when X=5 and neither otherwise. The numeric form (IF X=5 THEN 100) jumps to the start of that line; IF X=5 GOTO 100 is the same. See Comparison Operators and Logical Operators for what condition typically looks like.

INKEY

Special variable (read-only) — INKEY

Returns the next queued key code as an ASCII value, or -1 if nothing is waiting. Never blocks, so a program can poll it in a loop without stalling. It drains the board's own button/BLE-keyboard queue, which delivers one event per keystroke.

Examples

10 K = INKEY
20 IF K = -1 THEN GOTO 10
30 PRINT "GOT ";K

Comments

Not a function call — like TICK, it's read like a variable with no (). Ctrl-C (ASCII 3) is reserved as BREAK and never comes back from INKEY; see RUN. INKEY$ reads the same queue as a one-character string.

INKEY$

Special variable (read-only) — INKEY$

The next queued key as a one-character string, or "" when no key is waiting. Never blocks. The string form of INKEY.

Examples

10 K$ = INKEY$
20 IF K$ = "" THEN 10
30 PRINT "GOT ";K$

INPUT

Statement — INPUT var, or INPUT #file, var[, var...]

Prompts with ? and reads one line of input into a single variable or array element. A $ on the name reads a string; otherwise it reads a number. Works in direct mode and in a stored program. The #file form reads from an open file instead; see OPEN.

Examples

10 INPUT NAME$
20 INPUT AGE
30 PRINT "HELLO ";NAME$
40 PRINT "NEXT YEAR YOU ARE ";AGE+1

Session:

? Ada
? 36
HELLO Ada
NEXT YEAR YOU ARE 37

Comments

Exactly one variable per keyboard INPUT. A prompt string (INPUT "NAME"; N$) and a comma-separated list of variables are out of scope for this version; INPUT # does take a list.

The line is read one character at a time through the same input queue INKEY drains — on this board, the BOOT/PWR buttons and the USB serial link. Typed characters echo and a backspace (BS or DEL) erases the last one, matching the READY. line editor.

There is no end-of-file on the serial link, so an INPUT with no input available simply waits. Press Ctrl-C at the prompt to abandon it: the statement ends with ?INPUT ERROR, which stops a running program the way any other error does.

INPUT$

Function — INPUT$(n[, [#]file])

Reads exactly n characters (1–255): from the keyboard, waiting for each key without echoing it, or from an input file opened with OPEN.

Examples

10 PRINT "PRESS Y OR N"
20 K$ = INPUT$(1)
30 PRINT "YOU PRESSED ";K$

Comments

Ctrl-C while waiting for keys is ?INPUT ERROR. Reading past the end of a file is ?INPUT PAST END ERROR.

INSTR

Function — INSTR([start,] text$, find$)

The position (1-based) of the first find$ in text$ at or after character start (default 1), or 0 when there is none.

Examples

PRINT INSTR("HELLO", "L"); INSTR(4, "HELLO", "L"); INSTR("HELLO", "Z")

Output: 340

Comments

An empty find$ matches at start. start must be 1–255.

INT

Function — INT(x)

Rounds x toward negative infinity (floor), not toward zero.

Examples

PRINT INT(3.7)
PRINT INT(-3.7)

Output: 3, -4

Comments

INT(-3.7) is -4, not -3 — this is floor, not truncation.

KILL

Command — KILL "FILE"

Deletes one saved program file from internal flash.

Examples

KILL "OLDTEST"

Comments

The name must match a saved file, ignoring case, and is taken literally: KILL "A*" is ?BAD FILE NAME ERROR rather than a wildcard, and a missing file is ?FILE NOT FOUND ERROR. Filenames are described under SAVE. Deleting a file doesn't touch the program in memory. See FILES.

LCASE$

Function — LCASE$(s$)

Returns a new string in which every ASCII capital letter A–Z in string expression s$ is converted to lowercase.

Examples

PRINT LCASE$("Hello, World 42!")

Output: hello, world 42!

Comments

Only the ASCII letters A–Z change. Digits, punctuation, spaces, and every byte outside the ASCII letter ranges pass through unchanged, and the result has the same length as s$ (see LEN). The argument is a string expression, so LCASE$ nests and works anywhere one is valid: a $ assignment, PRINT, another string function's argument, or either side of a string IF comparison. A number argument is ?TYPE MISMATCH ERROR. Case conversion is not locale- or Unicode-aware. The upper-case form is UCASE$.

LEFT$

Function — LEFT$(s$, n)

Returns the first n bytes of string expression s$. n is converted to an integer.

Examples

PRINT LEFT$("PROGRAM", 4)
PRINT LEFT$("HI", 0)
PRINT LEFT$("HI", 99)

Output: PROG, `` (empty), HI

Comments

n of 0 returns ""; an n larger than the string returns the whole string. A negative n is ?ILLEGAL QUANTITY ERROR. The first argument must be a string; a number is ?TYPE MISMATCH ERROR. See RIGHT$, MID$.

LEN

Function — LEN(s$)

Returns the length of string expression s$ in bytes, as a number.

Examples

PRINT LEN("HELLO")
A$ = "":PRINT LEN(A$)

Output: 5, 0

Comments

Counts bytes, not decoded characters. The argument must be a string; a number is ?TYPE MISMATCH ERROR.

LET

Statement — [LET] var=expr

Assigns expr's value to var. The LET keyword is optional; var=expr alone works identically. A var ending in $ takes a string expression; any other var takes a numeric expression.

Examples

LET X=5
PRINT X
Y=10
PRINT Y
NAME$ = "JOEL"
PRINT NAME$

Output: 5, 10, JOEL

Comments

Names are case-insensitive and created automatically the first time they are assigned or read — a numeric name starts at 0, a string name at "". Assigning a string to a numeric name, or a number to a $ name, is ?TYPE MISMATCH ERROR. See String variables for the full type rules and the string expression grammar.

LINE

Statement — LINE (x1,y1)-(x2,y2)[,color][,B|BF] or LINE -(x2,y2)[,color]

Draws a one-pixel-wide line between two integer pixel coordinates on the graphics surface, in the given color (default: the current COLOR foreground; write ,B or ,BF alone for a default-color rectangle). Coordinates start at (0,0) in the top-left. With ,B, draws the rectangle having (x1,y1) and (x2,y2) as opposite corners as a one-pixel border instead. With ,BF, draws that same rectangle filled solid. The continuation form, a leading - with no first point, draws from the previous successful LINE's second endpoint — see "Current graphics position" below.

Examples

SCREEN 1
LINE (0,0)-(10,10),2
LINE (0,0)-(10,10),RGB(40,200,80)
LINE (10,10)-(100,50),4,B
LINE (20,20)-(90,40),2,BF

Connected polygon via continuation:

LINE (50,10)-(10,80),4
LINE -(90,80),4
LINE -(50,10),4

Comments

Only valid in SCREEN 1 — using it in screen 0 is ?ILLEGAL IN SCREEN 0 ERROR. color is either a standard palette number 0 through 15, or a value returned by RGB(); an out-of-range palette number is ?ILLEGAL QUANTITY ERROR. The 16 palette colors are listed under Color Palette.

Coordinates outside the surface are clipped rather than erroring. PSET sets one pixel with the same color and clipping rules. See examples/gfxclock.bas for a three-hand analog clock with a digital HH:MM readout, built from LINE, graphics-mode LOCATE/PRINT, SCREEN, GWIDTH/GHEIGHT, GFONTW/GFONTH, TIME$, VAL, INT, SIN, and COS.

B and BF rectangles

B and BF are case-insensitive and only valid on the full (x1,y1)-(x2,y2) form — using either on a continuation line (LINE -(x2,y2),color,B) is ?SYNTAX ERROR, and so is an unrecognized mode, a comma with nothing recognizable after it, or anything after a valid B/BF. The two corners work in either order — (x1,y1) and (x2,y2) can name any two opposite corners, and the rectangle drawn is the same either way. A rectangle where the corners share an x coordinate draws a vertical line, share a y coordinate draws a horizontal line, and share both draws a single pixel. Both border and fill are inclusive of both corners; a rectangle that is partly or wholly off-screen clips without error.

Current graphics position

BASIC32 tracks a current graphics position, initialized to (0,0) and reset to (0,0) when the interpreter starts, NEW runs, SCREEN runs, or CLS clears the graphics surface (screen 1). Every successful LINE — plain, B, or BF — moves it to (x2,y2) as written, even for a rectangle. PSET and PRESET move it to their pixel, CIRCLE to its center, and VIEW back to (0,0). POINT(n) reads it. LINE -(x2,y2),color starts from wherever the position currently is, which is what lets a chain of continuation lines draw a closed polygon without repeating each segment's start point, as in the example above.

LIST

Command — LIST

Prints every stored program line, in line-number order, as <number> <text>.

Examples

10 PRINT "HELLO"
20 GOTO 10
LIST

Output:

10 PRINT "HELLO"
20 GOTO 10

Comments

Prints nothing if no lines are stored. See NEW, RUN.

LOAD

Command — LOAD "FILE"

Replaces the program in memory with a program saved under FILE, and clears the variables, exactly as NEW does. The program is not run; use RUN afterward, or RUN "FILE" to load and run in one step.

Examples

LOAD "PONG"
LIST
RUN

Comments

The file is read and checked in full before anything changes. A missing file reports ?FILE NOT FOUND ERROR. A file larger than 64 KiB reports ?FILE TOO LARGE ERROR. A file with a nonblank line that doesn't start with a line number, or a line number with no statement after it, reports ?BAD FILE ERROR. Each of these leaves the program and variables in memory exactly as they were.

A line in a saved file is a line number, one space, and the statement text, ending in a line feed. Files written by SAVE use this form; a file written on a computer may use CRLF line endings, and blank lines are ignored. Lines are read with the same rules as typing them in, so a line of 511 characters or more is rejected. See SAVE for filename rules.

LOC

Function — LOC(n)

Bytes read so far from input file n, or written so far to output file n. See OPEN.

LOCATE

Statement — LOCATE row,col

Moves the active screen's text cursor to a 1-based row and column before the next PRINT.

Examples

CLS
LOCATE 2,3
PRINT "X"
SCREEN 1
LOCATE 5,10
PRINT "SCORE:";SCORE

Comments

In SCREEN 0 it positions the text console's cursor; in SCREEN 1 it positions the graphics text cursor, whose cells are GFONTW × GFONTH pixels, so LOCATE 5,10 there starts the next PRINT at pixel ((10-1)*GFONTW, (5-1)*GFONTH). The two cursors are independent state.

An out-of-range row or column is clamped to the last fully visible character cell rather than erroring: the fixed 20×10 console in SCREEN 0, or the graphics surface's cell grid in SCREEN 1.

LOF

Function — LOF(n)

The length in bytes of open file n (for an output file, what has been written so far). See OPEN.

LOG

Function — LOG(x)

Natural logarithm of x. x must be greater than 0, else ?ILLEGAL QUANTITY ERROR. See EXP.

MERGE

Command — MERGE "FILE"

Adds the lines of a saved program to the one in memory. Where both have the same line number, the file's line wins. Variables are kept.

Comments

The file is checked in full first, like LOAD: a file that isn't a valid program is ?BAD FILE ERROR and changes nothing.

MID$

Function — MID$(s$, start, length)

Returns up to length bytes of string expression s$, beginning at 1-based position start. start and length are converted to integers.

Examples

PRINT MID$("PROGRAM", 2, 3)
PRINT MID$("PROGRAM", 4, 99)
PRINT MID$("PROGRAM", 20, 3)

Output: ROG, GRAM, `` (empty)

Comments

Position 1 is the first byte. A start past the end returns ""; a length that runs past the end is clipped to what remains. A start below 1, or a negative length, is ?ILLEGAL QUANTITY ERROR. This is the three-argument form only — there is no MID$(s$, start) "to the end" shorthand and no MID$ assignment statement. The first argument must be a string; a number is ?TYPE MISMATCH ERROR. See LEFT$, RIGHT$.

NAME

Statement — NAME "old" AS "new"

Renames a saved file (program or data). Renaming onto another existing file is ?FILE ALREADY EXISTS ERROR; changing only the case of a name is allowed. Names follow the same rules as SAVE.

NEW

Command — NEW

Clears the stored program and all variables — numeric and string, the latter's storage freed — and resets to SCREEN 0. Saved files are not touched.

Examples

10 PRINT "A"
NEW
LIST

Output: nothing (the program is gone)

Comments

Irreversible — there's no undo. The program lives in RAM until it is SAVEd, so NEW or a power cycle discards any unsaved work. To keep a copy, SAVE it first, then reload it with LOAD.

OCT$

Function — OCT$(n)

n, rounded, as octal digits; OCT$(8) is 10. &O17 writes an octal constant. See HEX$.

ON

Statement — ON n GOTO line[, line...] or ON n GOSUB line[, line...]

Jumps to (or calls) the nth line in the list. n is rounded; 0 or a number past the end of the list does nothing and the program carries on with the next statement.

Examples

10 FOR I=1 TO 3
20 ON I GOSUB 100,200,300
30 NEXT
40 END
100 PRINT "ONE": RETURN
200 PRINT "TWO": RETURN
300 PRINT "THREE": RETURN

Output: ONE, TWO, THREE

Comments

A negative n or one above 255 is ?ILLEGAL QUANTITY ERROR. ON works only in a program. RENUM updates the line numbers in the list.

OPEN

Statement — OPEN "name" FOR INPUT|OUTPUT|APPEND AS [#]n, or OPEN "I"|"O"|"A", [#]n, "name"

Opens a data file in the board's storage as file number n (1–4). OUTPUT starts it empty, APPEND adds to the end of what is there, and INPUT reads it from the start. Then:

Examples

10 OPEN "SCORES.TXT" FOR OUTPUT AS #1
20 WRITE #1, "ANN", 90
30 WRITE #1, "BOB", 75
40 CLOSE #1
50 OPEN "SCORES.TXT" FOR INPUT AS #1
60 WHILE NOT EOF(1)
70 INPUT #1, N$, S
80 PRINT N$; " "; S
90 WEND
100 CLOSE

Output: ANN 90, BOB 75

Comments

Files are kept whole in memory while open, up to 64 KB each: an input file is read in full when it opens, and an output file is written in one step when it closes — so a file written but never closed is never saved. Every open file is closed (and written) by CLOSE, RESET, CLEAR, NEW, LOAD, RUN, and when a program ends, except after STOP or BREAK, which leave them open for CONT.

INPUT # skips leading spaces and line breaks; a field in double quotes is taken exactly; otherwise a string field runs to the next comma or line end, and a number field to the next comma, space, or line end.

Data files share storage and naming with saved programs: FILES lists them and KILL deletes them. Errors: ?FILE NOT FOUND ERROR (input), ?BAD FILE NUMBER ERROR (not 1–4, or not open), ?FILE ALREADY OPEN ERROR, ?BAD FILE MODE ERROR (writing to an input file or reading an output file), ?INPUT PAST END ERROR, ?FILE TOO LARGE ERROR.

PAINT

Statement — PAINT (x,y)[,fill[,border]]

Flood fills the four-way (up, down, left, right) connected area of the graphics surface reachable from the zero-based pixel (x,y) without crossing a pixel displaying border, replacing it with fill. When border is omitted, it defaults to fill, so the fill then stops at any pixel already that color. PAINT (x,y) alone uses the current COLOR foreground for both fill and border.

Examples

SCREEN 1
LINE (50,10)-(10,80),4
LINE -(90,80),4
LINE -(50,10),4
PAINT (50,40),4,4

Omitted border (defaults to the fill color, so a border drawn in the same color as the fill still contains it):

SCREEN 1
LINE (10,10)-(100,50),2,B
PAINT (50,30),2

Comments

Only valid in SCREEN 1 — using it in screen 0 is ?ILLEGAL IN SCREEN 0 ERROR. fill and border are each a standard palette number or an RGB() value, same as LINE; an out-of-range palette number is ?ILLEGAL QUANTITY ERROR.

A seed pixel outside the graphics surface is a clipped no-op. PAINT also changes nothing if the seed already displays border or fill (comparing displayed colors, so a palette number and an RGB() value that render identically also count as a match). See FILL for filling a same-colored region with no separate border color. A large fill still terminates safely — it never recurses and never grows unbounded.

PALETTE

Statement — PALETTE [index, color]

Changes the color that palette index index (0–15) stands for. color is an RGB() value or a standard color number 0–15. With no arguments, restores the standard palette.

Examples

10 SCREEN 1
20 LINE (10,10)-(60,60),2,BF
30 FOR K=1 TO 15: PALETTE 2,K: PAUSE 2: NEXT
40 PALETTE

The square cycles through every color, then returns to green.

Comments

Like a hardware palette, the change shows at once: in SCREEN 1 every pixel showing the index's old color is redrawn in the new one, and a COLOR foreground or background that was that color follows it. Text already on the SCREEN 0 console keeps its color. A pixel drawn with an RGB() value equal to the old color changes too.

PAUSE

Statement — PAUSE n

Blocks for n tenths of a second — PAUSE 10 is one second, the classic- BASIC convention.

Examples

PAUSE 10

(pauses for one second)

Comments

n is a full expression, so fractional values work (PAUSE 5 is half a second). Shares its underlying delay with SLEEP.

PLAY

Statement — PLAY string-expression

Plays a short melody: a whitespace-separated string of natural note names C D E F G A B, case-insensitive, each in octave 4 and lasting 250ms. Uses the same tone playback as SOUND, so a target with no sound hardware stays silent but keeps the same timing.

Examples

PLAY "C D E F G"
PLAY "c d e"

(the first plays five ordered quarter-second notes; lowercase works the same as uppercase)

Comments

The whole string is validated before anything plays — an unknown token (a sharp/flat, an octave number, a rest, anything but a bare A-G letter) is ?SYNTAX ERROR with no partial melody, not an error partway through playback. Sharps/flats, octaves, tempo, rests, note lengths, and a fuller music-macro grammar are out of scope for this version. On the ESP32-C6, each note streams to the connected browser for Web Audio playback the same way SOUND does.

PMAP

Function — PMAP(value, mode)

Converts a coordinate between world and screen coordinates: mode 0 is world x to screen x, 1 world y to screen y, 2 screen x to world x, 3 screen y to world y. With no WINDOW statement (not implemented yet) the two coordinate systems are the same, so PMAP returns value. A mode other than 0–3 is ?ILLEGAL QUANTITY ERROR.

POINT

Function — POINT(x, y) or POINT(n)

POINT(x,y) reads the pixel at (x,y): the palette index (0–15) whose current color it shows, or, when it matches no palette entry, its RGB() value. A point outside the screen or VIEW gives -1.

POINT(n) reads the current graphics position: n=0 or 1 gives x or y in screen coordinates, 2 or 3 in VIEW-relative coordinates.

Examples

10 SCREEN 1
20 PSET 5,5,12
30 PRINT POINT(5,5); POINT(0); POINT(1)

Output: 1255

Comments

SCREEN 1 only. Colors read back at the screen's own precision, so two colors that look identical on the display read as the same value.

POS

Function — POS(x)

The column (1-based) where the next PRINT will go. The argument is ignored. In SCREEN 1, the graphics text cursor's column.

PRESET

Statement — PRESET x,y[,color]

PSET with the background color as its default: without color it erases the pixel to the current COLOR background.

PRINT

Statement — PRINT [item] [sep item]...

Text is drawn in the current COLOR foreground and background (opaque character cells) in both screen modes.

Prints zero or more items — a numeric expression or a string expression (a "literal", a $ variable, or a string function) — each separated from the next by whitespace, ;, or ,:

A trailing ; suppresses the line's closing newline outright, leaving the cursor where the last item ended. A trailing , makes its zone advance (or line wrap) first, then suppresses the newline, so the next PRINT continues from that column. PRINT with no items just prints a newline.

Examples

PRINT "A","B"
PRINT "A";"B"
PRINT "A" "B"
NAME$ = "JOEL"
PRINT "HI ";NAME$;" (";LEN(NAME$);")"
PRINT 1;
PRINT 2
FOR I=1 TO 3: PRINT I,: NEXT I
PRINT "DONE"

Output:

A       B
AB
AB
HI JOEL (4)
1
2
1       2       3       DONE

(1 and READY. actually land on the same line in that fourth case — the trailing ; suppressed PRINT 1's own newline, so READY. runs straight into it; shown above on separate lines only for clarity.) The FOR loop's trailing , on every pass leaves the cursor at the next print zone, so the three numbers line up 8 columns apart and the untrailed PRINT "DONE" that follows the loop picks up right where the last comma left off instead of starting a new line.

Comments

Whitespace between two complete items is only a separator — PRINT "A" "B" prints AB with nothing inserted — but whitespace inside one item is ordinary expression syntax and never splits it: PRINT 1 + 2 and a spaced function call still evaluate as a single item, and spaces inside a "string literal" are preserved exactly. Numbers print via C's %.6g — six significant digits, switching to exponential notation outside that range (PRINT 1000000 prints 1e+06; PRINT 1/3 prints 0.333333). A string expression prints its bytes unchanged. Because a trailing ;/, suppresses only PRINT's own newline and not the READY. prompt that always follows a completed direct statement, a direct-mode PRINT ending in ; or , runs its output straight into READY. on the same line, as noted above.

In SCREEN 1, PRINT draws the same fixed-width glyphs in white onto the graphics surface at the graphics text cursor (set with LOCATE), advancing, wrapping, handling newlines, and scrolling in character cells exactly as the text console does — the formatting and separator rules above are unchanged, with print zones measured in that cursor's own character cells. Use GPRINT instead to place text at an absolute pixel coordinate without touching that cursor.

PSET

Statement — PSET x,y[,color]

Sets the single pixel at the zero-based coordinate (x,y) on the graphics surface to color, or to the current COLOR foreground when omitted, and moves the current graphics position there. PRESET is the same with the background as its default color.

Examples

SCREEN 1
PSET 10,10,15
PSET 12,10,RGB(255,128,0)

Comments

Only valid in SCREEN 1 — ?ILLEGAL IN SCREEN 0 ERROR otherwise. color uses the exact same resolution as LINE: a palette index 0–15 or an RGB() value, with an out-of-range palette number raising ?ILLEGAL QUANTITY ERROR. Pixels outside the surface are clipped without error, also like LINE.

PUT

Statement — PUT (x,y), array[, PSET|PRESET|AND|OR|XOR]

Draws an image saved by GET with its top-left corner at (x,y). How each pixel combines with what is already on screen:

Examples

100 FOR X=0 TO 300 STEP 4
110 PUT (X,50),S: PAUSE 1: PUT (X,50),S
120 NEXT

Comments

Pixels outside the screen or VIEW are clipped. SCREEN 1 only.

RANDOMIZE

Statement — RANDOMIZE

Reseeds the random-number generator from the board's uptime, so the RND sequence that follows differs from the last run's.

Examples

RANDOMIZE
PRINT INT(RND*6)+1

Comments

RANDOMIZE takes no argument. RANDOMIZE TIMER and any other trailing input are ?SYNTAX ERROR; the seed is always the uptime, and there's no way to supply your own. Until a program calls RANDOMIZE, the generator starts from a fixed seed, so an un-randomized program produces the same numbers after every power-up. The sequence isn't saved across resets.

READ

Statement — READ var[, var...]

Takes the next item from DATA for each variable or array element.

REM

Statement — REM text or 'text

Marks the rest of the physical line as a comment; nothing after REM or ' is evaluated — including any :, so a statement placed after a comment on the same line never runs.

Examples

10 REM this line does nothing
20 PRINT "A"
30 'so does this one
40 PRINT "B"
50 PRINT "C" : REM everything from REM to the end of line 50 is a comment
RUN

Output: A, B, C

Comments

Because a comment consumes the whole physical line, REM/' must come last on a line that also does work — PRINT X : REM note is fine, REM note : PRINT X prints nothing. REM (like every keyword) is case-insensitive; the apostrophe form needs no keyword at all.

RENUM

Command — RENUM [new],[old],[increment]

Renumbers stored program lines in place, and updates the line numbers that GOTO, GOSUB, and numeric IF ... THEN statements use to refer to them.

Each omitted field takes its own default: new is 10, old is 0, and increment is 10. Bare RENUM renumbers the whole program as 10, 20, 30, .... A field can be left empty between commas, as in RENUM 100,,10.

A literal destination in GOTO, GOSUB, or a numeric IF ... THEN that names a renumbered line is changed to that line's new number, including destinations inside colon-separated statement chains. Destinations that name no renumbered line, numbers in expressions, text inside quoted strings, and REM or apostrophe comments are left exactly as typed.

RENUM is a direct command, like RUN, LIST, and NEW: it can't be stored as a numbered line or chained after a colon. On success it prints only the READY. prompt. Renumbering an empty program, or a range with no lines in it, succeeds and changes nothing.

Malformed arguments — a non-integer, more than three fields, or text after the fields — report ?SYNTAX ERROR. Values out of range report ?ILLEGAL QUANTITY ERROR: a new or increment below 1, a negative old, a number above 2147483647, or a result that would not stay above the last unchanged line. A failed RENUM changes no line numbers and no line text.

Examples

5 X=1
7 GOTO 5
30 PRINT X
RENUM
LIST

Output:

10 X=1
20 GOTO 10
30 PRINT X
READY.

Renumbering only the lines from 500 upward, starting at 1000 in steps of 20:

RENUM 1000,500,20

Starting from 10 A=1, 400 PRINT 400, 500 PRINT 500, and 600 GOTO 500, this leaves lines 10 and 400 alone, and changes 500 to 1000, 600 to 1020, and the GOTO destination to match.

Comments

Only a suffix of the program can be renumbered: there's no way to renumber a middle range or to stop at a final old line. Computed destinations such as GOTO X*10 are not rewritten, since their target isn't known until RUN.

RESET

Statement — RESET

Closes every open file, writing the output files. See OPEN.

RESTORE

Statement — RESTORE [line]

Makes the next READ start over with the first DATA item of the program, or of line line onward. A missing line is ?UNDEF'D STATEMENT ERROR.

RETURN

Statement — RETURN

Ends the current subroutine and resumes execution at the statement right after the GOSUB that called it.

Examples

10 GOSUB 100
20 PRINT "DONE"
30 END
100 FOR I=1 TO 3
110 PRINT I
120 NEXT I
130 RETURN
RUN

Output: 1, 2, 3, DONE

Comments

Only legal inside a running program — typed directly it's ?ILLEGAL DIRECT ERROR. A RETURN with no matching GOSUB still pending is ?RETURN WITHOUT GOSUB ERROR. Resume is statement-precise: if the GOSUB shared its line with later statements (GOSUB 100 : PRINT X), RETURN continues at the next one; if the GOSUB was last on its line, it continues at the next line. Nested calls unwind last-in-first-out: each RETURN matches the most recent unreturned GOSUB.

RGB

Function — RGB(red,green,blue)

Builds a true-color value from three integer components, each 0 through 255, for use as LINE's color argument.

Examples

LINE (0,0)-(10,10),RGB(40,200,80)

Comments

Only meaningful as LINE's color argument — it isn't a general-purpose color type. An out-of-range component is ?ILLEGAL QUANTITY ERROR, the same error LINE raises for an out-of-range palette number. Internally, RGB() tags its result above the packed 24-bit range so LINE can tell a true color apart from a palette index (0-15) whose packed value happens to also fall in 0-15; this is an interpreter implementation detail a program never needs to know about. See LINE's palette table.

Function — RIGHT$(s$, n)

Returns the last n bytes of string expression s$. n is converted to an integer.

Examples

PRINT RIGHT$("PROGRAM", 3)
PRINT RIGHT$("HI", 0)
PRINT RIGHT$("HI", 99)

Output: RAM, `` (empty), HI

Comments

n of 0 returns ""; an n larger than the string returns the whole string. A negative n is ?ILLEGAL QUANTITY ERROR. The first argument must be a string; a number is ?TYPE MISMATCH ERROR. See LEFT$, MID$.

RND

Function-like value (read-only) — RND

A pseudorandom number 0 <= RND < 1. Each evaluation returns a new value.

Examples

PRINT RND
PRINT INT(RND*6)+1

Comments

Not a function call — like TICK, it takes no (), so RND(1), RND(0), and RND() are ?SYNTAX ERROR. Use INT(RND*n) for whole numbers from 0 to n-1, or INT(RND*n)+1 for 1 to n. The generator starts from a fixed seed until RANDOMIZE is called.

RUN

Command — RUN

Executes the stored program from its lowest line number, in order, following any GOTO/IF jumps, until END, the last line, a runtime error, or Ctrl-C (BREAK).

Examples

10 PRINT "HELLO"
20 GOTO 10
RUN

(prints HELLO forever until Ctrl-C stops it — a deliberately minimal example of why END or a bounded FOR loop matters)

Comments

RUN starts clean: like CLEAR, it forgets every variable, array, and DEF FN, closes open files, and restarts DATA. (The COLOR, PALETTE, and screen mode carry over.) A program stopped by STOP or BREAK can be resumed with CONT instead.

RUN "FILE" loads a saved program with LOAD and runs it in one step. If the load fails, nothing runs and the error is reported. A plain RUN with no filename runs the program already in memory, as above. Prints READY. once the program stops, whether that's normal completion, a runtime error, or BREAK. Ctrl-C is checked before every line, so it stops a program even if it never reads INKEY itself — otherwise a program that reads its own buttons/keyboard through INKEY would have no way to be interrupted. On BREAK, the console shows BREAK IN followed by the line number that was about to run, e.g. BREAK IN 20.

SAVE

Command — SAVE "FILE"

Writes the program in memory to internal flash under FILE, as plain ASCII source: one line per stored line, in line-number order, each as its number, a space, and its statement text, ending in a line feed.

Examples

10 PRINT "HELLO"
20 END
SAVE "HELLO"

Output: READY.

The file HELLO then contains:

10 PRINT "HELLO"
20 END

Comments

Saving to a name that already exists replaces that file completely. The new copy is written under a temporary name first and moved into place only once it is complete, so a failed save leaves the previous file untouched.

Names may use letters, digits, _, -, and ., up to 31 characters, and are matched without regard to case. Saving "Clock" after "CLOCK" keeps the new spelling and removes the old one. Names must not contain .., path separators, spaces, or wildcards, and no extension is added — SAVE "HELLO" writes exactly HELLO. An empty, illegal, or unquoted name is ?BAD FILE NAME ERROR or ?SYNTAX ERROR.

A program over 64 KiB, or a save that would exceed the flash's free space, reports ?PROGRAM TOO LARGE ERROR or ?STORAGE FULL ERROR, and nothing is written. If the flash cannot be used at all, the error is ?STORAGE ERROR.

Saved files are stored in the board's own internal flash, not on any SD card; they persist across power cycles and are removed only by KILL or by reflashing the storage partition. SAVE, LOAD, RUN "FILE", KILL, and FILES are direct commands; they can't be stored as numbered lines or chained after a colon. Saved files hold only the program, never variables or the screen. See LOAD, FILES.

SCREEN

Statement — SCREEN mode

Selects the active screen: 0 for the text console (the startup default), 1 for the graphics surface. Only one is visible at a time.

Examples

SCREEN 1
LINE (0,0)-(10,10),2
SCREEN 0

Comments

Any value other than 0 or 1 is ?ILLEGAL QUANTITY ERROR. Switching screens preserves neither screen's contents. NEW always resets SCREEN back to 0. SCREEN 1 is the only mode in which LINE, PSET, GPRINT, and graphics-mode LOCATE/PRINT are legal; SCREEN 0 is the only mode in which PRINT reaches the text console.

SGN

Function — SGN(x)

-1 if x is negative, 0 if it is zero, 1 if it is positive.

SIN

Function — SIN(x)

Sine of x, where x is in radians.

Examples

PRINT SIN(0)

Output: 0

Comments

Radians, not degrees. See COS.

SLEEP

Statement — SLEEP n

Blocks for n whole seconds.

Examples

SLEEP 1

Comments

Reads more directly than PAUSE for whole-second delays; both share the same underlying delay, and n is a full expression so fractional seconds also work.

SOUND

Statement — SOUND frequency,duration

Plays an exact tone at frequency Hz for duration milliseconds, blocking until it finishes — sequential SOUND statements form predictable timing. frequency must be 20-20000 and duration 0-60000; a value outside that range is ?ILLEGAL QUANTITY ERROR, and a missing argument or trailing input is ?SYNTAX ERROR.

Examples

SOUND 440,100
SOUND 660,100
SOUND 880,100

(three ascending 100ms tones, one after another)

Comments

A duration of 0 is valid and produces no audible output — useful for muting a SOUND call without removing it. Both arguments are full numeric expressions, truncated to whole Hz/ms. On targets with no sound hardware (ESP32-S3, RP2350), SOUND is silent but still blocks for the full duration so program timing matches the ESP32-C6, which instead streams the tone to its connected browser for Web Audio playback; with no browser connected, or if the send fails, the program continues silently. See PLAY for short melodies built from natural note names.

SPACE$

Function — SPACE$(n)

A string of n spaces (0–255).

SPC

Print function — SPC(n), inside a PRINT list

Prints n spaces (0–255). Like a trailing ;, SPC at the end of the list leaves the cursor on the line. Only valid as a PRINT/PRINT #/ GPRINT item.

Examples

PRINT "A"; SPC(3); "B"

Output: A B

SQR

Function — SQR(x)

Square root of x.

Examples

PRINT SQR(16)

Output: 4

Comments

A negative argument is ?ILLEGAL QUANTITY ERROR, not NaN or a complex result.

STOP

Statement — STOP

Stops the program and prints BREAK IN and the line number, like Ctrl-C. CONT carries on from the next statement.

Comments

Unlike END, a STOPped program keeps its open files open and can be resumed. Handy for debugging: stop, PRINT a few variables, then CONT.

STR$

Function — STR$(n)

Returns the string form of number n, formatted the same way PRINT formats a number: C's %.6g, with no leading space in front of a non-negative value.

Examples

PRINT "[" ; STR$(42) ; "]"
PRINT "[" ; STR$(-3.5) ; "]"
PRINT LEN(STR$(1/3))

Output: [42], [-3.5], 8

Comments

STR$(n) is a string-typed value for use in a string context. It is the rough inverse of VAL: VAL(STR$(n)) recovers n within %.6g precision. Classic BASICs put a leading space where the sign of a positive number would go; BASIC32 does not, matching its own PRINT.

STRING$

Function — STRING$(n, code) or STRING$(n, text$)

A string of n copies (0–255) of one character: the character with ASCII code code, or the first character of text$.

Examples

PRINT STRING$(5, "*"); STRING$(3, 61)

Output: *****===

SWAP

Statement — SWAP a, b

Exchanges the values of two variables or array elements of the same type (both numeric or both string); otherwise ?TYPE MISMATCH ERROR.

Examples

10 A=1: B=2: SWAP A,B: PRINT A; B

Output: 21

TAB

Print function — TAB(n), inside a PRINT list

Moves to column n by printing spaces. If the cursor is already past column n, it starts a new line first. Like a trailing ;, TAB at the end of the list leaves the cursor on the line. Only valid as a PRINT/ PRINT #/GPRINT item.

Examples

PRINT "NAME"; TAB(10); "SCORE"

Output: NAME SCORE

TAN

Function — TAN(x)

Tangent of x, where x is in radians. See ATN.

TIMER

Special variable (read-only) — TIMER

Whole seconds since midnight on the board's clock (see TIME$). Read with no (), like TICK; use TICK for millisecond timing.

TRON/TROFF

Statement — TRON, TROFF

TRON turns on tracing: as each program line starts, its number prints in brackets, e.g. [10][20]. TROFF turns it off. NEW also turns it off.

VIEW

Statement — VIEW [[SCREEN] (x1,y1)-(x2,y2)[,[fill][,border]]]

Limits graphics to a rectangle of the screen. With plain VIEW, coordinates become relative to the rectangle's top-left corner; with VIEW SCREEN they stay screen coordinates and drawing is only clipped. fill paints the rectangle; border draws a frame just outside it. VIEW alone returns to the whole screen.

Examples

10 SCREEN 1
20 VIEW (100,40)-(220,140),1,15
30 FOR K=0 TO 200 STEP 8: LINE (0,K)-(200,K-100),14: NEXT
40 VIEW

Diagonal lines fill the blue box and stop at its edges.

Comments

Corners are screen coordinates and must be on the screen, else ?ILLEGAL QUANTITY ERROR. Every drawing statement (LINE, PSET, CIRCLE, PAINT, FILL, PUT, …) is clipped to the viewport, CLS clears just the viewport, and POINT reads -1 outside it. Text (PRINT, GPRINT) isn't affected. SCREEN removes the viewport. Resets the graphics position to (0,0).

WHILE/WEND

Statement — WHILE condition … WEND

Repeats the statements between WHILE and its WEND as long as condition is true (nonzero), testing it before every pass — so a false condition at the start skips the loop entirely.

Examples

10 I=1
20 WHILE I<=3
30 PRINT I;
40 I=I+1
50 WEND

Output: 123

Comments

Loops can nest, 16 deep. WEND with no open WHILE is ?WEND WITHOUT WHILE ERROR; a WHILE whose condition is false with no matching WEND after it is ?WHILE WITHOUT WEND ERROR. Works only in a program.

WRITE

Statement — WRITE [#n,] item[, item...]

Prints the items separated by commas, with strings in double quotes and numbers without padding, then ends the line — a form INPUT # reads back exactly. Without #n, it goes to the screen.

Examples

WRITE "ANN", 36, "X"

Output: "ANN",36,"X"

String variables

Language rule

A variable whose name ends in $ holds a string of 0–255 bytes instead of a number. It is a distinct variable from the same base name without the $ (A and A$ are unrelated), case-insensitive like every name, and defaults to the empty string "" until assigned.

Examples

10 A$ = "HELLO"
20 NAME$ = "JOEL"
30 PRINT A$ ; " " ; NAME$
40 PRINT LEN(NAME$)
50 PRINT LEFT$(A$, 3) ; MID$(A$, 4, 1) ; RIGHT$(A$, 1)

Output:

HELLO JOEL
4
HELLO

Comments

Where a string expression is allowed. The RHS of a $ assignment (LET NAME$="JOEL" or just NAME$="JOEL"), any PRINT item, an INPUT into a $ variable, and the string-typed arguments of the string functions.

The string grammar is tiny and has no operators. A string expression is one of: a "literal", a $ variable, a $ array element, a string DEF FN, INKEY$, or a call to LEFT$, RIGHT$, MID$, CHR$, STR$, UCASE$, LCASE$, HEX$, OCT$, SPACE$, STRING$, or INPUT$. There is no string concatenation (A$ + B$ is not valid — build up text with successive PRINT items instead). Two strings compare with =, <>, <, >, <=, >=; see String comparisons.

Type rules. Using a string where a number is expected, or a number where a string is expected, is ?TYPE MISMATCH ERROR — this covers A = "x", A$ = 5, LEN(5), PRINT A$ + 1, and FOR I$ = 1 TO 3. A string literal or an INPUT line longer than 255 bytes is ?STRING TOO LONG ERROR rather than a silent truncation.

Functions that consume or produce strings. Number → string: CHR$, STR$, HEX$, OCT$, SPACE$, STRING$. String → number: LEN, ASC, VAL, INSTR. String → string: LEFT$, RIGHT$, MID$, UCASE$, LCASE$.

Storage and lifetime. Each string value is an owned, heap-allocated copy. Reassigning a $ variable frees the value it replaces, and NEW frees every string value. Strings are byte-oriented: LEN, the slice functions, and ASC/CHR$ all work in bytes, with no Unicode-aware character counting.

BATTERY

Special variable (read-only) — BATTERY

Estimated remaining battery charge as an integer from 0 through 100, or -1 when no reading is available.

Examples

PRINT BATTERY
IF BATTERY >= 0 THEN PRINT BATTERY;"%"

Polling loop:

10 B = BATTERY
20 IF B < 0 THEN PRINT "NO BATTERY DATA"
30 IF B >= 0 THEN PRINT "BATTERY";B;"%"
40 SLEEP 5
50 GOTO 10

Comments

Not a function call — like TICK, it takes no (), so BATTERY() is a syntax error. Always test for -1 before showing a percentage; 0 is a valid, fully depleted reading. Only the ESP32-S3 (Waveshare ESP32-S3-Touch-AMOLED-1.75-B) measures its battery, using the AXP2101 fuel gauge. It returns -1 if no battery is attached or the PMIC can't be read. The stock RP2350-PiZero and XIAO ESP32-C6 have no battery sense wired to the MCU and always return -1.

TICK

Special variable (read-only) — TICK

Milliseconds elapsed since the board booted.

Examples

PRINT TICK

Comments

Not a function call — every function requires exactly one parenthesized argument, and TICK needs none, so it's read like a variable with no (). TICK is monotonic uptime with no wall-clock meaning; for an advancing time and date, use TIME$ and DATE$, which the bundled examples/gfxclock.bas reads. examples/clock.bas still builds a digital display straight from TICK, counting up from 12:00:00 at boot.

TIME$

Special variable (readable and assignable) — TIME$

The current local time of day as an 8-character string, HH:MM:SS, in 24-hour form with leading zeroes.

Examples

10 PRINT TIME$
20 PAUSE 20
30 PRINT TIME$

Output:

14:07:05
14:07:07
TIME$ = "14:30:00"
LET TIME$ = "14:30:00"
PRINT TIME$

Output: 14:30:00

Comments

Not a function call — like TICK, it's read with no (), and each evaluation re-reads the clock, so two reads a moment apart differ. Successive reads advance in step with the system clock and roll MM and HH over normally at 60 seconds and 60 minutes.

It is a string value: valid anywhere a string expression is (PRINT, GPRINT, assignment to a $ variable, and inside LEFT$, MID$, VAL, …). HRS = VAL(LEFT$(TIME$,2)) pulls out the hour as a number. Using TIME$ where a number is expected is ?TYPE MISMATCH ERROR.

Assigning it — with implicit assignment (TIME$ = ...) or LET — sets the system clock's time of day, accepting any valid string expression on the right-hand side, not just a literal. The value must match the exact HH:MM:SS 24-hour format with leading zeroes and every field in range (00-23, 00-59, 00-59); anything else is ?ILLEGAL QUANTITY ERROR and leaves the clock unchanged. Setting TIME$ preserves the current date and the clock keeps advancing normally afterward. INPUT TIME$ is still rejected — setting the clock is assignment syntax, not a new INPUT destination.

The clock is not battery- or network-backed: at boot the firmware sets it to a fixed default, 12:00:00, like an unset alarm clock, and lets it advance from there. So it's consistent across reboots rather than an approximation of the actual time of day, until a program or a direct-mode command corrects it with an assignment. A later firmware update could add network time without changing how TIME$ behaves. See DATE$.

UCASE$

Function — UCASE$(s$)

Returns a new string in which every ASCII lowercase letter a–z in string expression s$ is converted to uppercase.

Examples

PRINT UCASE$("Hello, World 42!")

Output: HELLO, WORLD 42!

Comments

Only the ASCII letters a–z change. Digits, punctuation, spaces, and every byte outside the ASCII letter ranges pass through unchanged, and the result has the same length as s$ (see LEN). The argument is a string expression, so UCASE$ nests and works anywhere one is valid: a $ assignment, PRINT, another string function's argument, or either side of a string IF comparison. A number argument is ?TYPE MISMATCH ERROR. Case conversion is not locale- or Unicode-aware. The lower-case form is LCASE$.

VAL

Function — VAL(s$)

Parses the leading number out of string expression s$ and returns it as a number. Leading whitespace is skipped. When s$ has no numeric prefix, VAL returns 0.

Examples

PRINT VAL("42")
PRINT VAL("  3.5 kg")
PRINT VAL("kg")
PRINT VAL("-7e2")

Output: 42, 3.5, 0, -700

Comments

Accepts the same numeric forms the interpreter itself parses, including a leading sign and exponent. Parsing stops at the first character that can't extend the number, so trailing text is ignored rather than being an error. The argument must be a string; a number is ?TYPE MISMATCH ERROR. Rough inverse of STR$.

Reference

Arithmetic Operators

Operator group — + - * / (binary), unary + -

Operator group — MOD

Ordinary arithmetic on numbers. Precedence, highest to lowest: unary +/-, then *//, then MOD, then binary +/-, then the comparison operators, then the logical operators. Parentheses override precedence. All values are C doubles.

a MOD b is the remainder of dividing a by b after rounding both to whole numbers; it takes the sign of a (-17 MOD 5 is -2).

Number constants can also be written in hexadecimal or octal: &HFF is 255 and &O17 is 15.

Examples

PRINT 2+3*4
PRINT (2+3)*4
PRINT -5+2
PRINT 17 MOD 5

Output: 14, 20, -3, 2

Comments

Dividing by zero is a runtime error (?DIVISION BY ZERO ERROR), not infinity or NaN, and so is MOD by zero. There is no integer-division operator or exponentiation operator.

Color Palette

Reference — the 16 standard palette colors

These are the palette numbers accepted wherever a color is taken (COLOR, LINE, PSET, PAINT, FILL). PALETTE can remap them; the table shows the standard values.

Number Color RGB
0 Black RGB(0,0,0)
1 Blue RGB(0,0,170)
2 Green RGB(0,170,0)
3 Cyan RGB(0,170,170)
4 Red RGB(170,0,0)
5 Magenta RGB(170,0,170)
6 Brown RGB(170,85,0)
7 Light Gray RGB(170,170,170)
8 Gray RGB(85,85,85)
9 Light Blue RGB(85,85,255)
10 Light Green RGB(85,255,85)
11 Light Cyan RGB(85,255,255)
12 Light Red RGB(255,85,85)
13 Light Magenta RGB(255,85,255)
14 Yellow RGB(255,255,85)
15 White RGB(255,255,255)

Comparison Operators

Operator group — = <> < > <= >=

Compares two arithmetic expressions, or two string expressions, and evaluates to -1 (true) or 0 (false) — an ordinary number, usable anywhere a number is, most commonly as IF's condition. True is -1 (every bit set), as in classic BASIC, so the results combine correctly with the bitwise logical operators: NOT of a true comparison is false.

Examples

PRINT 3>2
PRINT 1=2
PRINT 2<=2

Output: -1, 0, -1

Comments

Below arithmetic and above the logical operators in precedence. Comparisons group left to right (1<2<3 is (1<2)<3, not a range test); combine conditions with AND/OR instead. See String comparisons for the string form.