Commodore BASIC
The Commodore 8-bit computers come with BASIC built-in to ROM for immediate use on power-up without the need to load the language from cassette or disk or cartridge. In fact, the BASIC interpreter can be considered the operating system from the user perspective. Of course there is a lower-level kernel (called KERNAL) that is often considered the operating system by advanced users (typically assembly language programmers and hackers).
Versions
The various versions of Commodore BASIC are generally upward compatible. So for example, a Plus/4 (BASIC version 3.5) can run all the commands of the VIC-20 and C64 (both have version 2.0). However there are two notable glitches. A minor issue is that BASIC v3.5 has nearly all the commands of BASIC 4.0 plus many new ones (perhaps v3.5 should have been called version 4.5 or 5.0). A more serious issue is several disk-related tokens have changed in versions 3.5 and 7.0 as compared to the older 4.0 and 4.7 – this breaks binary compatibility with the affected commands, although source compatibility should hold true. See disk commands for a list of these. One token in version 7.0 is broken compared to version 3.5 (RLUM()). One token is version 4.7 is unique (DISPOSE).
Known versions:
- 1.0 Very first PET
- 2.0 Early PETs, VIC-20, C64
- 4.0 Later PETs
- 4.7 CBM-II (e.g, B128 a.k.a. C610)
- 3.5 Plus/4, C16
- 7.0 C128
- 10.0 Prototype C65
Tokens
To reduce memory use and improve load/save/execute time, the BASIC program text is stored in tokenized form. Anywhere a keyword is found, it is replaced with a one- or two- byte token. Assuming the average keyword is 5 characters and the typical token is 1 byte, this results in 5-to-1 compression ratio. Note that text in double quotes and any text in DATA or REM statements is not tokenized. See TOKENS for a list of keywords sorted by token value.
Binary Program Format
(This should go in a seperate article.)
The first two bytes of any PRG file has two bytes to indicate the “load-address”, which is the memory address from which it was saved. Most of the CBM machines ignore this when loading a BASIC program, and instead load the file to the current “start of BASIC” for the current machine. The exceptions are the PETs; on these machines, loading BASIC software from another machine will often result in no listing or possibly a system crash (because of an incompatible address). Other CBMs (non-PETs) have no problem loading BASIC software written on another machine (of course if the BASIC of the program is newer than the BASIC of the machine, the program will likely halt with a SYNTAX error, but it should never totally crash).
The actuall program text is stored as a series of programs lines, each of which consists of four parts:
- A two-byte pointer to the next line
- A two-byte line number
- The text of the program line, with keywords substituted by tokens
- A terminating null (zero byte).
This format is repeated for every line of the program. The end of the program is indicated with a two-byte pointer whose value is zero. Because the prior line ended with a terminating null, searching a file for a triple null is effective to find the end of the BASIC program.
It should be noted that, except for the PETs, the two-byte pointers are re-calculated after loading to be sure they are correct for the (new) load-address. This may take several seconds for a large program. It is also possible, if a non-BASIC or corrupted file were loaded, to send the machine into an infinite loop if the data contains a sequence of 256 bytes or more without an intervening null byte.
Another important note is that additional data may be present in the file after the triple null (end of BASIC text). This may be ML code, audio data, font data, etc. Such use is very machine-specific.
Keywords
The keywords that get tokenized can be grouped into four catagories:
- Commands and statements
- Functions and reserved variables
- Operators
- Prepositions
Below is a list of keywords sorted by catagory. See keywords for a list sorted alphabetically.
Commands and statements
The majority of keywords fall into this category. The difference between a command and statement is rather vague. Statements are generally used in a program; examples would be RETURN or IF. Commands are generally used in direct mode (no program running); examples would be LOAD or LIST. Most entries in this category can be used in either program or direct mode but there are exceptions.
| Keyword | Token | Version | Category(s) |
|---|---|---|---|
| END | $80 | 1.0+ | Statement |
| FOR | $81 | 1.0+ | Command and Statement |
| NEXT | $82 | 1.0+ | Command, Statement and Preposition |
| DATA | $83 | 1.0+ | Statement |
| INPUT# | $84 | 1.0+ | Statement |
| INPUT | $85 | 1.0+ | Statement |
| DIM | $86 | 1.0+ | Command and Statement |
| READ | $87 | 1.0+ | Command and Statement |
| LET | $88 | 1.0+ | Command and Statement |
| GOTO | $89 | 1.0+ | Command and Statement |
| RUN | $8A | 1.0+ | Command and Statement |
| IF | $8B | 1.0+ | Command and Statement |
| RESTORE | $8C | 1.0+ | Command and Statement |
| GOSUB | $8D | 1.0+ | Command and Statement |
| RETURN | $8E | 1.0+ | Statement |
| REM | $8F | 1.0+ | Command and Statement |
| STOP | $90 | 1.0+ | Statement |
| WAIT | $92 | 1.0+ | Command and Statement |
| LOAD | $93 | 1.0+ | Command and Statement |
| SAVE | $94 | 1.0+ | Command and Statement |
| VERIFY | $95 | 1.0+ | Command and Statment |
| DEF | $96 | 1.0+ | Statement |
| POKE | $97 | 1.0+ | Command and Statement |
| PRINT# | $98 | 1.0+ | Command and Statement |
| $99 | 1.0+ | Command and Statement | |
| CONT | $9A | 1.0+ | Command* |
| LIST | $9B | 1.0+ | Command* |
| CLR | $9C | 1.0+ | Command, Statement and Preposition |
| CMD | $9D | 1.0+ | Command and Statement |
| SYS | $9E | 1.0+ | Command and Statement |
| OPEN | $9F | 1.0+ | Command and Statement |
| CLOSE | $A0 | 1.0+ | Command and Statement |
| GET | $A1 | 1.0+ | Statement |
| NEW | $A2 | 1.0+ | Command* |
| GO | $CB | 2.0+ | Command and Statement |
| CONCAT | $CC | 4.0, 4.7 | Command and Statement |
| DOPEN | $CD | 4.0, 4.7 | Command and Statement |
| DCLOSE | $CE | 4.0, 4.7 | Command and Statement |
| RECORD | $CF | 4.0, 4.7 | Command and Statement |
| HEADER | $D0 | 4.0, 4.7 | Command and Statement |
| COLLECT | $D1 | 4.0, 4.7 | Command and Statement |
| BACKUP | $D2 | 4.0, 4.7 | Command and Statement |
| COPY | $D3 | 4.0, 4.7 | Command and Statement |
| APPEND | $D4 | 4.0, 4.7 | Command and Statement |
| DSAVE | $D5 | 4.0, 4.7 | Command and Statement |
| DLOAD | $D6 | 4.0, 4.7 | Command* |
| RESUME | $D6 | 3.5, 7.0+ | Statement |
| CATALOG | $D7 | 4.0, 4.7 | Command and Statement |
| TRAP | $D7 | 3.5, 7.0+ | Command and Statement |
| RENAME | $D8 | 4.0, 4.7 | Command and Statement |
| TRON | $D8 | 3.5, 7.0+ | Command and Statement |
| SCRATCH | $D9 | 4.0, 4.7 | Command and Statement |
| TROFF | $D9 | 3.5, 7.0+ | Command and Statement |
| DIRECTORY | $DA | 4.0, 4.7 | Command and Statement |
| SOUND | $DA | 3.5, 7.0+ | Command and Statement |
| DCLEAR | $DB | 4.7 | Command and Statement |
| VOL | $DB | 3.5, 7.0+ | Command and Statement |
| BANK | $DC | 4.7 | Command and Statement |
| AUTO | $DC | 3.5, 7.0+ | Command |
| BLOAD | $DD | 4.7 | Command and Statement |
| PUDEF | $DD | 3.5, 7.0+ | Command and Statement |
| BSAVE | $DE | 4.7 | Command and Statement |
| GRAPHIC | $DE | 3.5, 7.0+ | Command and Statement |
| KEY | $DF | 4.7 | Command and Statement |
| PAINT | $DF | 3.5, 7.0+ | Command and Statement |
| DELETE | $E0 | 4.7 | Command |
| CHAR | $E0 | 3.5, 7.0+ | Command and Statement |
| BOX | $E1 | 3.5, 7.0+ | Command and Statement |
| TRAP | $E2 | 4.7 | Statement |
| CIRCLE | $E2 | 3.5, 7.0+ | Command and Statement |
| RESUME | $E3 | 4.7 | Statement |
| GSHAPE | $E3 | 3.5, 7.0+ | Command and Statement |
| DISPOSE | $E4 | 4.7 | Command and Statement |
| SSHAPE | $E4 | 3.5, 7.0+ | Command and Statement |
| PUDEF | $E5 | 4.7 | Command and Statement |
| DRAW | $E5 | 3.5, 7.0+ | Command and Statement |
| LOCATE | $E6 | 3.5, 7.0+ | Command and Statement |
| COLOR | $E7 | 3.5, 7.0+ | Command and Statement |
| SCNCLR | $E8 | 3.5, 7.0+ | Command and Statement |
| SCALE | $E9 | 3.5, 7.0+ | Command and Statement |
| HELP | $EA | 3.5, 7.0+ | Command* |
| DO | $EB | 3.5, 7.0+ | Command and Statement |
| LOOP | $EC | 3.5, 7.0+ | Command and Statement |
| EXIT | $ED | 3.5, 7.0+ | Command and Statement |
| DIRECTORY | $EE | 3.5, 7.0+ | Command and Statement |
| DSAVE | $EF | 3.5, 7.0+ | Command and Statement |
| DLOAD | $F0 | 3.5, 7.0+ | Command* |
| HEADER | $F1 | 3.5, 7.0+ | Command and Statement |
| SCRATCH | $F2 | 3.5, 7.0+ | Command and Statement |
| COLLECT | $F3 | 3.5, 7.0+ | Command and Statement |
| COPY | $F4 | 3.5, 7.0+ | Command and Statement |
| RENAME | $F5 | 3.5, 7.0+ | Command and Statement |
| BACKUP | $F6 | 3.5, 7.0+ | Command and Statement |
| DELETE | $F7 | 3.5, 7.0+ | Command |
| RENUMBER | $F8 | 3.5, 7.0+ | Command |
| KEY | $F9 | 3.5, 7.0+ | Command, Statement and Preposition |
| MONITOR | $FA | 3.5, 7.0+ | Command and Statement |
| BANK | $FE $02 | 7.0+ | Command and Statement |
| FILTER | $FE $03 | 7.0+ | Command and Statement |
| PLAY | $FE $04 | 7.0+ | Command and Statement |
| TEMPO | $FE $05 | 7.0+ | Command and Statement |
| MOVSPR | $FE $06 | 7.0+ | Command and Statement |
| SPRITE | $FE $07 | 7.0+ | Command and Statement |
| SPRCOLOR | $FE $08 | 7.0+ | Command and Statement |
| RREG | $FE $09 | 7.0+ | Command and Statement |
| ENVELOPE | $FE $0A | 7.0+ | Command and Statement |
| SLEEP | $FE $0B | 7.0+ | Command and Statement |
| CATALOG | $FE $0C | 7.0+ | Command and Statement |
| DOPEN | $FE $0D | 7.0+ | Command and Statement |
| APPEND | $FE $0E | 7.0+ | Command and Statement |
| DCLOSE | $FE $0F | 7.0+ | Command and Statement |
| BSAVE | $FE $10 | 7.0+ | Command and Statement |
| BLOAD | $FE $11 | 7.0+ | Command and Statement |
| RECORD | $FE $12 | 7.0+ | Command and Statement |
| CONCAT | $FE $13 | 7.0+ | Command and Statement |
| DVERIFY | $FE $14 | 7.0+ | Command and Statement |
| DCLEAR | $FE $15 | 7.0+ | Command and Statement |
| SPRSAV | $FE $16 | 7.0+ | Command and Statement |
| COLLISION | $FE $17 | 7.0+ | Command and Statement |
| WINDOW | $FE $1A | 7.0+ | Command and Statement |
| BOOT | $FE $1B | 7.0+ | Command and Statement |
| WIDTH | $FE $1C | 7.0+ | Command and Statement |
| SPRDEF | $FE $1D | 7.0+ | Command and Statement |
| QUIT | $FE $1E | 7.0+ | Command and Statement |
| STASH | $FE $1F | 7.0+ | Command and Statement |
| FETCH | $FE $21 | 7.0+ | Command and Statement |
| SWAP | $FE $23 | 7.0+ | Command and Statement |
| FAST | $FE $25 | 7.0+ | Command and Statement |
| SLOW | $FE $26 | 7.0+ | Command and Statement |
| TYPE | $FE $27 | 10.0 | Command and Statement |
| BVERIFY | $FE $28 | 10.0 | Command and Statement |
| ERASE | $FE $2A | 10.0 | Command and Statement |
| FIND | $FE $2B | 10.0 | Command |
| CHANGE | $FE $2C | 10.0 | Command |
| SET | $FE $2D | 10.0 | Command and Statement |
| SCREEN | $FE $2E | 10.0 | Command and Statement |
| POLYGON | $FE $2F | 10.0 | Command and Statement |
| ELLIPSE | $FE $30 | 10.0 | Command and Statement |
| VIEWPOINT | $FE $31 | 10.0 | Command and Statement |
| GCOPY | $FE $32 | 10.0 | Command and Statement |
| PEN | $FE $33 | 10.0 | Command and Statement |
| PALETTE | $FE $34 | 10.0 | Command and Statement |
| DMODE | $FE $35 | 10.0 | Command and Statement |
| DPAT | $FE $36 | 10.0 | Command and Statement |
| PIC | $FE $37 | 10.0 | Command and Statement |
| GENLOCK | $FE $38 | 10.0 | Command and Statement |
| FOREGROUND | $FE $39 | 10.0 | Command and Statement |
| BACKGROUND | $FE $3B | 10.0 | Command and Statement |
| BORDER | $FE $3C | 10.0 | Command and Statement |
| HIGHLIGHT | $FE $3D | 10.0 | Command and Statement |
| MOUSE | $FE $3E | 10.0 | Command and Statement |
| RMOUSE | $FE $3F | 10.0 | Command and Statement |
Functions and Reserved Variables
The next largest category includes mostly functions. These are easy to recognize as they all require one or more parameters enclosed in parentheses () following the keyword. Examples would be LEN() and COS(). These return a value which can be stored in a variable, used in an expression, or printed.
R = RND(0) IF LEN(N$) > 16 THEN PRINT "NAME TOO LONG" PRINT COS(A)
Note that SPC() and TAB() appear to functions, but they are really prepositions which can only be used in a PRINT command. Therefore they are not in the following list.
Reserved variables are very similar to functions, although they do not need an argument in parentheses. None are tokenized, unless you count PI.
| Keyword | Token | Version | Category(s) |
|---|---|---|---|
| DS | 3.5+ | Reserved variable | |
| DS$ | 3.5+ | Reserved variable | |
| EL | 3.5, 4.7+ | Reserved variable | |
| ER | 3.5, 4.7+ | Reserved variable | |
| ST | 1.0+ | Reserved variable | |
| TI | 1.0? | Reserved variable | |
| TI$ | 1.0? | Reserved variable | |
| FNxx() | $A5 | 1.0+ | Function |
| SGN() | $B4 | 1.0+ | Function |
| INT() | $B5 | 1.0+ | Function |
| ABS() | $B6 | 1.0+ | Function |
| USR() | $B7 | 1.0+ | Function |
| FRE() | $B8 | 1.0+ | Function |
| POS() | $B9 | 1.0+ | Function |
| SQR() | $BA | 1.0+ | Function |
| RND() | $BB | 1.0+ | Function |
| LOG() | $BC | 1.0+ | Function |
| EXP() | $BD | 1.0+ | Function |
| COS() | $BE | 1.0+ | Function |
| SIN() | $BF | 1.0+ | Function |
| TAN() | $C0 | 1.0+ | Function |
| ATN() | $C1 | 1.0+ | Function |
| PEEK() | $C2 | 1.0+ | Function |
| LEN() | $C3 | 1.0+ | Function |
| STR$() | $C4 | 1.0+ | Function |
| VAL() | $C5 | 1.0+ | Function |
| ASC() | $C6 | 1.0+ | Function |
| CHR$() | $C7 | 1.0+ | Function |
| LEFT$() | $C8 | 1.0+ | Function |
| RIGHT$() | $C9 | 1.0+ | Function |
| MID$() | $CA | 1.0+ | Function |
| RGR() | $CC | 3.5, 7.0+ | Function |
| RCLR() | $CD | 3.5, 7.0+ | Function |
| RLUM() | $CE | 3.5 | Function |
| POT() | $CE $02 | 7.0+ | Function |
| BUMP() | $CE $03 | 7.0+ | Function |
| PEN() | $CE $04 | 7.0+ | Function |
| RSPPOS() | $CE $05 | 7.0+ | Function |
| RSPRITE() | $CE $06 | 7.0+ | Function |
| RSPCOLOR() | $CE $07 | 7.0+ | Function |
| XOR() | $CE $08 | 7.0+ | Function |
| RWINDOW() | $CE $09 | 7.0+ | Function |
| POINTER() | $CE $0A | 7.0+ | Function |
| JOY() | $CF | 3.5, 7.0+ | Function |
| RDOT() | $D0 | 3.5, 7.0+ | Function |
| DEC() | $D1 | 3.5, 7.0+ | Function |
| HEX$() | $D2 | 3.5, 7.0+ | Function |
| ERR$() | $D3 | 3.5, 7.0+ | Function |
| INSTR() | $D4 | 3.5, 7.0+ | Function |
| ERR$() | $E7 | 4.7 | Function |
| INSTR() | $E8 | 4.7 | Function |
| pi | $FF | 1.0+ | Reserved variable |
Operators
Commodore used tokens instead of plain text for mathemtical operators. Although as this saves no memory (except for boolean operators) and makes reading a hex dump difficult, it was done to simplify the code for forumula evaluation.
| Keyword | Token | Version | Category | Priority |
|---|---|---|---|---|
| NOT | $A8 | 1.0+ | Operator | 5 |
| + | $AA | 1.0+ | Operator | 3 |
| - | $AB | 1.0+ | Operator | 3 |
| * | $AC | 1.0+ | Operator | 2 |
| / | $AD | 1.0+ | Operator | 2 |
| ^ | $AE | 1.0+ | Operator | 1 (highest) |
| AND | $AF | 1.0+ | Operator | 6 |
| OR | $B0 | 1.0+ | Operator | 7 (lowest) |
| < | $B1 | 1.0+ | Operator | 4 |
| = | $B2 | 1.0+ | Operator | 4 |
| > | $B3 | 1.0+ | Operator | 4 |
Prepositions
These are miscellaneous words that are used in conjunction with other commands.
| Keyword | Token | Version | Category(s) |
|---|---|---|---|
| ON | $91 | 1.0+ | Preposition |
| TAB() | $A3 | 1.0+ | Preposition |
| TO | $A4 | 1.0+ | Preposition |
| SPC() | $A6 | 1.0+ | Preposition |
| THEN | $A7 | 1.0+ | Preposition |
| STEP | $A9 | 1.0+ | Preposition |
| ELSE | $D5 | 3.5, 7.0+ | Preposition |
| ELSE | $E1 | 4.7 | Preposition |
| USING | $E6 | 4.7 | Preposition |
| USING | $FB | 3.5, 7.0+ | Preposition |
| UNTIL | $FC | 3.5, 7.0+ | Preposition |
| WHILE | $FD | 3.5, 7.0+ | Preposition |
| BEGIN | $FE $18 | 7.0+ | Preposition |
| BEND | $FE $19 | 7.0+ | Preposition |
| OFF | $FE $24 | 7.0+ | Preposition |