BBC BASIC is the BASIC of the BBC Micro. SAVE writes the program as it is kept in memory: the text of each line
with its keywords replaced by one-byte tokens, so a program is smaller and runs faster than text.
This page is the file as SAVE writes it. The table of keywords below was compared with the BBC BASIC II ROM image
that ships with the jsbeeb emulator.
Lines
| Field | Size | Meaning |
|---|---|---|
| Start | 1 | $0D |
| Line number | 2 | High byte first (the opposite of the 6502's usual order); 0 to 32767 |
| Length | 1 | The length of the whole line in bytes, these four bytes included; so a line is at most 255 bytes |
| Text | length − 4 | The statements, with tokens |
The next line starts right after: there is no link, only the length. A line is the bytes
0D 00 0A 58 4E 55 4D … from a real disc: line 10, 88 bytes long, text NUMBER=….
The end of the program
A $0D followed by $FF instead of a high byte ends the program (line numbers stop at 32767, so
$FF cannot be one). A file may carry bytes after it; BASIC does not read them, and the viewer marks them as
extra bytes. A program of no lines is the two bytes 0D FF. A file that starts 0D FF and goes on is not a program
(one real machine-code file does: A.CYLON on Games.ssd), and the viewer does not take it for one.
Tokens
Every byte of the text from $80 up is a token, unless it is in a string or after REM or
DATA (see below). The keywords PTR, PAGE, TIME, LOMEM and
HIMEM have two tokens each: $8F to $93 where they are read as functions and
$CF to $D3 where they are assigned to (PAGE=…). $8D is not a keyword but the
line number marker, and $CE has no keyword in this ROM.
| Token | Keyword | Token | Keyword | Token | Keyword | Token | Keyword |
|---|---|---|---|---|---|---|---|
$80 | AND | $81 | DIV | $82 | EOR | $83 | MOD |
$84 | OR | $85 | ERROR | $86 | LINE | $87 | OFF |
$88 | STEP | $89 | SPC | $8A | TAB( | $8B | ELSE |
$8C | THEN | $8D | line number | $8E | OPENIN | $8F | PTR |
$90 | PAGE | $91 | TIME | $92 | LOMEM | $93 | HIMEM |
$94 | ABS | $95 | ACS | $96 | ADVAL | $97 | ASC |
$98 | ASN | $99 | ATN | $9A | BGET | $9B | COS |
$9C | COUNT | $9D | DEG | $9E | ERL | $9F | ERR |
$A0 | EVAL | $A1 | EXP | $A2 | EXT | $A3 | FALSE |
$A4 | FN | $A5 | GET | $A6 | INKEY | $A7 | INSTR( |
$A8 | INT | $A9 | LEN | $AA | LN | $AB | LOG |
$AC | NOT | $AD | OPENUP | $AE | OPENOUT | $AF | PI |
$B0 | POINT( | $B1 | POS | $B2 | RAD | $B3 | RND |
$B4 | SGN | $B5 | SIN | $B6 | SQR | $B7 | TAN |
$B8 | TO | $B9 | TRUE | $BA | USR | $BB | VAL |
$BC | VPOS | $BD | CHR$ | $BE | GET$ | $BF | INKEY$ |
$C0 | LEFT$( | $C1 | MID$( | $C2 | RIGHT$( | $C3 | STR$ |
$C4 | STRING$( | $C5 | EOF | $C6 | AUTO | $C7 | DELETE |
$C8 | LOAD | $C9 | LIST | $CA | NEW | $CB | OLD |
$CC | RENUMBER | $CD | SAVE | $CE | none | $CF | PTR (assigned) |
$D0 | PAGE (assigned) | $D1 | TIME (assigned) | $D2 | LOMEM (assigned) | $D3 | HIMEM (assigned) |
$D4 | SOUND | $D5 | BPUT | $D6 | CALL | $D7 | CHAIN |
$D8 | CLEAR | $D9 | CLOSE | $DA | CLG | $DB | CLS |
$DC | DATA | $DD | DEF | $DE | DIM | $DF | DRAW |
$E0 | END | $E1 | ENDPROC | $E2 | ENVELOPE | $E3 | FOR |
$E4 | GOSUB | $E5 | GOTO | $E6 | GCOL | $E7 | IF |
$E8 | INPUT | $E9 | LET | $EA | LOCAL | $EB | MODE |
$EC | MOVE | $ED | NEXT | $EE | ON | $EF | VDU |
$F0 | PLOT | $F1 | $F2 | PROC | $F3 | READ | |
$F4 | REM | $F5 | REPEAT | $F6 | REPORT | $F7 | RESTORE |
$F8 | RETURN | $F9 | RUN | $FA | STOP | $FB | COLOUR |
$FC | TRACE | $FD | UNTIL | $FE | WIDTH | $FF | OSCLI |
Every keyword and token in this table was read out of the keyword table of the BBC BASIC II ROM (a 16 KB image with
the copyright text (C)1982 Acorn) and compared by a test, so the table is as the ROM has it. Operators such as
+, = and < are not tokens: they are stored as their ASCII characters. Names such as
FNname and PROCname are the token and the name's letters.
Text that is not tokenised
- Strings. From an opening
"to the closing one the bytes are as typed; a byte from$80up in a string is that character, not a token. - REM and DATA. After
REM($F4) andDATA($DC) the rest of the line is stored as typed. In the ROM's keyword table these two are the only keywords with bit 5 ($20) of their flag byte set, which is how the table marks the keywords after which the line is not tokenised. - Star commands. A line that starts with
*is passed to the operating system as it stands, so it holds no tokens. The viewer applies this only to a*at the start of a line (after any spaces); a star command later in a line is not told apart.
Line numbers inside a line: $8D
A line number after GOTO, GOSUB, THEN, ELSE, RESTORE, TRACE,
AUTO, DELETE, LIST or RENUMBER (the ten keywords with bit 4 of the ROM flag byte set) is stored as the token $8D and three bytes, so that
RENUMBER can change it. With lo and hi the two bytes of the number:
| Byte | Value |
|---|---|
| 1 | (((lo AND $C0) ÷ 4) OR ((hi AND $C0) ÷ 16)) EOR $54 |
| 2 | (lo AND $3F) OR $40 |
| 3 | (hi AND $3F) OR $40 |
Checks made: every number from 0 to 32767 survives the round trip, and in the 135 real BASIC files on the discs of this
Mac 1,310 of 1,312 numbers found behind $8D are the number of a line that exists in the same program. The
two others point at no line; why is not known. A wrong constant or bit order would have made nearly all of them miss.
Versions
The table is that of BASIC II. BASIC I, the Master's BASIC 4, BASIC V and other dialects (Hi-BASIC, ARM BASIC with
tokens of two bytes) are not described: a program from them may show a keyword wrong or a token as {XX}. A program saved by
some of the real discs carries the execution address $801F instead of $8023, which may mean
another version; that is not checked.