To use ATARI BASIC effectively, you must know its strengths and weaknesses. With this information, programs can be written that make good use of the assets and features of ATARI BASIC.
Strengths of ATARI BASIC
Token | An 8-bit byte containing a particular interpretable code. |
Statement | A complete "sentence" of tokens that causes BASIC to perform some meaningful task. In LIST form, statements are separated by colons. |
Line | One or more statements preceded either by a line number in the range of 0 to 32767 or an immediate mode line with no number. |
Command | The first executable token of a statement that tells BASIC to interpret the tokens that follow in a particular way. |
Variable | A token that is an indirect pointer to its actual value; thus the value can be changed without changing the token. |
Constant | A 6-byte BCD value preceeded by a special token. This value remains unchanged throughout program execution. |
Operator | Any one of 46 tokens that in some way move or modify the values that follow them. |
Function | A token that when executed returns a value to the program. |
EOL | End of Line. A character with the value 9B hex. |
BCD | Binary code decimal. A number that uses the 6502 decimal mode. |
After the record is returned, the syntax checking and tokenizing processes begin. First BASIC looks for a line number. If one is found, it is converted into a 2- byte integer. If no line number is present, it is assumed to be in immediate mode and the line-number 8000 hex is assigned to it. These will be the first two tokens of the tokenized line. This line is built in the token output buffer that is 256 bytes long and resides at the end of the reserved operating system RAM.
The next token is a dummy byte reserved for the byte count (or offset) from the start of this line to the start of the next line. Following that is another dummy byte for the count of the start of this line to the start of the next statement. These values will be set when tokenization is complete for the line and the statement respectively. The use of these values is discussed in the program execution process section.
BASIC now looks for the command of the first statement of the input line. A check is made to determine if this is a valid command by scanning a list of legal commands in ROM. If a match is found, then the next byte in the token line becomes the number of the entry in the ROM list that matched. If no match is found, a syntax error token is assigned to that byte and BASIC stops tokenizing, copies the rest of the input buffer in ATASCII format to the token output buffer, and prints the error line.
Assuming a good line, one of seven items can follow the command: a variable, a constant, an operator, a function, a double quote, another statement, or an EOL. BASIC tests if the next input character is numeric. If not then it compares that character and those following against the entries of the variable name table. If this is the first line of code entered in the program then no match is found. The characters are then compared against the function and operator tables. If no match is found there then BASIC assumes that this is a new variable name. Since this is the first variable it is assigned the first entry in the variable name table. The characters are copied out of the input buffer and stored into the name table with the most significant bit (MSB) set on the last byte of the name. Eight bytes are then reserved in the variable value table for this entry. (See the variable value table discussion in the section, "Token File Structure".)
The token that ends up in the tokenized line is the variable number minus one; with the MSB set. Thus the token of the first variable entered would be 80 Hex, the second would be 81, and so on up to FF for a total of 128 unique variable numbers.
If a function is found, then its entry number in the operator function table is assigned to the token. Functions require certain sequences of parameters; these are contained in syntax tables, and if they are not matched, a syntax error will result.
If an operator is found, then a token is given its table entry number. Operators can follow each other in a rather complex fashion (such as multiple parentheses), so the syntax checking of them is a bit complicated.
In the case of the double quotes, BASIC assumes that a character string is following and assigns a 0F hex to the output token and reserves a dummy byte for the string length. The characters are moved from the input buffer into the output buffer until the second set of quotes is found. The length byte is then set to the character count.
If the next characters in the input buffer are numeric, BASIC converts them into a 6-byte BCD constant. A 0E hex token will be put in the output buffer, followed by the six byte constant.
When a colon is encountered, a 14 hex token is inserted in the output buffer and the offset from the start of the line is stored in the dummy byte that was reserved for the count to the start of the next statement. At this point another dummy byte is reserved and the process goes back to get a command.
When the EOL is found, a 16 hex token is stored and the offset from the start of the line is put in the dummy byte for the line offset. At this point, tokenization is complete and BASIC moves the token line into the token program. First it searched the program for that line number. If it is found it replaces the old line with the new one. If it is not found, then it inserts the new line in the correct numerical sequence. In both cases, the data following the line will be moved either up or down in memory to allow for an expanding and contracting program size.
BASIC now checks if the tokenized line is an immediate mode line. If so, that line is executed according to the methods described in the interpretive process; if not, BASIC goes back to get another line of input.
If at any time during the tokenizing process the length of the token line exceeds 256 bytes, an ERROR 14 message (line too long) is sent to the screen and BASIC goes back to get the next line of input.
An example line of input and its token form looks like this (all token values are hexadecimal):
10 LET X=1 : PRINT X
0A 00 | 13 | OF | 06 | 80 | 2D | 0E | 40 01 00 00 00 00 | 14 | 13 | 20 | 80 | 16 |
Line 10 | Line Offset |
Statement Offset |
Let | X | = | Numeric Constant |
1 | End Of Statement |
Statement Offset |
X | End Of Line |
Figure 10-1 Example Line of Tokenized Input
COMMANDS | OPERATORS | FUNCTIONS | ||||||
---|---|---|---|---|---|---|---|---|
HEX | DEC | HEX | DEC | HEX | DEC | |||
00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 |
00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
REM DATA INPUT COLOR LIST ENTER LET IF FOR NEXT GOTO GO TO GOSUB TRAP BYE CONT COM CLOSE CLR DEG DIM END NEW OPEN LOAD SAVE STATUS NOTE POINT XIO ON POKE RAD READ RESTORE RETURN RUN STOP POP ? GET PUT GRAPHICS PLOT POSITION DOS DRAWTO SETCOLOR LOCATE SOUND LPRINT CSAVE CLOAD [IMPLIED LET] ERROR - [SYNTAX] |
0E 0F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C |
14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 |
[NUM CONST] [STR CONST] [NOT USED] [NOT USED] , $ : [STMT END] ; [LINE END] GOTO GOSUB TO STEP THEN # <= [NUMERICS] <> >= < > = * + - / NOT OR AND ( ) = [ARITHM ASSIGN] = [STRING ASSIGN] <= [STRINGS] <> >= < > = + [UNARY] - ( [STRING LEFT PAREN] ( [ARRAY LEFT PAREN] ( [DIM ARRAY LEFT PAREN] ( [FUN LEFT PAREN] ( [DIM STR LEFT PAREN] , [ARRAY COMMA] |
3D 3E 3F 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 |
61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 |
STR$ CHR$ USR ASC VAL LEN ADR ATN COS PEEK SIN RND FRE EXP LOG CLOG SQR SGN ABS INT PADDLE STICK PTRIG STRIG |
Pointer (hex) | Token File Section (Contiguous Blocks) | ||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
LOMEM 80,81 | Token output buffer - This is the buffer BASIC uses to tokenize one line of code. It is 256 bytes long. This buffer resides at the end of the operating system's allocated RAM. | ||||||||||||||||||||||||||||||||||||
VNTP 82,83 | Variable name table - A list of all the
variable names that have been entered in the
program. They are stored as ATASCII characters, each
new name stored in the order it was entered. Three
types of name entries exist:
| ||||||||||||||||||||||||||||||||||||
VNTD 84,85 | Variable name table dummy end - BASIC uses this pointer to indicate the end of the name table. This normally points to a dummy zero byte when there are less than 128 variables. When 128 variables are present, this points to the last byte of the last variablename. | ||||||||||||||||||||||||||||||||||||
VVTP 86,87 | Variable value table - This table contains
current information on each variable. For each
variable in the name table, eight bytes are
reserved in the value table. The information
for each variable type is:
A scalar variable contains a numeric value. An example is X=1. The scalar is X and its value is 1, stored in 6-byte BCD format. An array is composed of numeric elements stored in the string/array area and has one entry in the value table. A string, composed of character elements in the string/array area, also has one entry in the table. The first byte of each value entry indicates the type of variable: 00 for a scalar, 40 for an array, and 80 for a string. If the array or string has been dimensioned, then the LSB is set on the first byte. The second byte contains the variable number. The first variable entry is number zero, and if 128 variables were present, the last would be 7F. In the case of the scalar variable the third through eighth byte contain the 6-byte BCD number that has currently been assigned to it. For arrays and strings, the third and fourth bytes contain an offset from the start of the string/array area (described below) to the beginning of the data. The fifth and sixth bytes of an array contain its first dimension. The quantity is a 16-bit integer and its value is 1 greater than the user entered. The seventh and eighth bytes are the second dimension, also a value of 1 greater. The fifth and sixth bytes of a string are a 16 bit integer that contains its current length. The seventh and eighth bytes are its dimension (up to 32767 bytes in size). | ||||||||||||||||||||||||||||||||||||
STMTAB 88,89 | Statement Table - This block of data includes all the lines of code that have been entered by the user and tokenized by BASIC, and it also includes the immediate mode line. The format of these lines is described in the tokenized line example of the section on the tokenizing process. | ||||||||||||||||||||||||||||||||||||
STMCUR 8A,8B | Current Statement - This pointer is used by BASIC to reference particular tokens within a line of the statement table. When BASIC is waiting for input, this pointer is set to the beginning of the immediate mode line. | ||||||||||||||||||||||||||||||||||||
STARP 8C,8D | String/Array area - This block contains all the string and array data. String characters are stored as one byte ATASCII entries, so a string of 20 characters will require 20 bytes. Arrays are stored with 6-byte BCD numbers for each element. A 10-element array would require 60 bytes. This area is allocated and subsequently enlarged by each dimension statement encountered, the amount being equal to the size of a string dimension or six times the size of an array dimension. | ||||||||||||||||||||||||||||||||||||
RUNSTK 8E,8F | Run time stack - This software stack contains GOSUB and FOR/NEXT entries. The GOSUB entry consists of four bytes. The first is a 0 byte indicating GOSUB, followed by the 2-byte integer line number on which the call occurred. This is followed by the offset into that line so the RETURN can come back and execute the next statement. The FOR/NEXT entry contains 16 bytes. The first is the limit the counter variable can reach. The second byte is the step or counter increment. Each of these quantities is in 6-byte BCD format. The thirteenth byte is the counter variable number with the MSB set. The fourteenth and fifteenth bytes are the line number, and the sixteenth is the line offset to the FOR statement. | ||||||||||||||||||||||||||||||||||||
MEMTOP 90,91 | Top of application RAM - This is the end of the user program. Program expansion can occur from this point to the end of free RAM, which is defined by the start of the display list. The FRE function returns the amount of free RAM by subtracting MEMTOP from HIMEM (2E5,2E6). Note that the BASIC MEMTOP is not the same as the OS variable called MEMTOP. |
The first line of code that is executed in a program is the immediate mode line. This is usually a RUN or GOTO. In the case of the RUN, BASIC gets the first line of tokens from the statement table (tokenized program) and processes it. If all the code is in-line, then BASIC merely executes consecutive lines.
If a GOTO is encountered, then the line to go to must be found. The statement table contains a linked list of tokenized BASIC lines. These lines are stored in ascending numerical order. To find a line somewhere in the middle of the table, BASIC starts by finding the first line of the program.
The address of the first line is contained in the STMTAB pointer at 88 and 89. This address is now stored in a temporary pointer. The first 2 bytes of the first line are its line number which is compared against the requested line number. If the first number is less, then BASIC gets the next line by adding the third byte of the first line to the temporary pointer. The temporary pointer will now be pointing to the second line. Again the first 2 bytes of this new line are compared to he requested line, and if they are less, the third byte is added to the pointer. If a line number does match, the contents of the temporary pointer are moved into STMCUR and BASIC fetches the next token from the new line. Should the requested line number not be found, an ERROR 12 is generated.
The GOSUB involves more processing than the GOTO. The line finding routine is the same, but before BASIC goes to that line it sets up an entry in the Run Time Stack. It allocates four bytes at the end of the stack and stores a 0 in the first byte to indicate a GOSUB stack entry. It then stores the line number it was on when the call was made into the next two bytes of the stack. The final byte contains the offset in bytes from the start of that line to where the GOSUB token was found. BASIC then executes the line it looked up. When the RETURN is found, the entry on the stack is pulled off, and BASIC returns to the calling line.
The FOR command causes BASIC to allocate 16 bytes on the Run Time Stack. The first six bytes are the limit the variable can reach in 6-byte BCD format. The second six bytes are the step, in the same format. Following these, BASIC stores the variable number (MSB set) of the counting variable. It then stores the present line number (two bytes) and the offset into the line. The rest of the line is then executed.
When BASIC finds the NEXT command, it looks at the last entry on the stack. It makes sure the variable referenced by the NEXT is the same as the one on the stack and checks if the counter has reached or exceeded the limit. If not then BASIC returns to the line with the FOR statement and continues execution. If the limit was reached, then the FOR entry is pulled off the stack and execution continues from that point.
When an expression is evaluated, the operators are put onto an operator stack and are pulled off one at a time and evaluated. The order in which the operators are put onto the stack can either be implied, in which case BASIC looks up the operator's precedence from a ROM table, or the order can be explicitly stated by the placement of parentheses.
Pressing the BREAK key at any time causes the operating
system to set a flag to indicate this occurrence. BASIC
checks this flag after each token is processed. If it
finds it has been set, it stores the line number at
which this occurred, prints out a "STOPPED AT LINE XXXX"
message, clears the BREAK flag and waits for user input.
At this point the user could type CONT and program
execution would continue at the next line.
SYSTEM INTERACTION
BASIC communicates with the Operating System primarily
through the use of 1/0 calls to the Central 1/0 Utility
(CIO). Following is a list of user BASIC calls and the
corresponding operating system IOCB (Input/Output
Control Block) setups.
BASIC | OS |
---|---|
OPEN #1,12,0,"E:" | IOCB=1 Command=3 (OPEN) Aux1=12 (Input/Output) Aux2=0 Buffer Address=ADR("E:") |
GET #1,X | IOCB=1 Command=7 (Get Characters) Buffer Length=0 Character returned in accumulator |
PUT #1,X | IOCB=1 Command=11 (Put Characters) Buffer Length=0 Character output through accumulator |
INPUT #1,A$ | IOCB=1 Command=5 (Get Record) Buffer Length=Length of A$ (not over 120) Buffer Address=Input Line Buffer |
PRINT #1,A$ | IOCB=1 BASIC uses a special put byte vector in the IOCB to talk directly to the handler. |
XIO 18,#6,12,0,"S:" | IOCB=6 Command=18 (Special - Fill) Aux1=12 Aux2=0 |
The second block of information written consists of the following token file sections: (1) The variable name table, (2) the variable value table, (3) the token program, and (4) the immediate mode line.
When this program is loaded into memory, BASIC looks at the OS variable MEMLO (2E7,2E8) and adds its value to each of the 2-byte zero page pointers as they are read from the device. These pointers are placed back on page zero and then the values of RUNSTK(8E,8F) and MEMTOP (90,91) are set to the value in STARP.
Next, 256 bytes are reserved in memory above the value of MEMLO to allocate space for the token output buffer. Then the token file information, consisting of the variable name table through the immediate mode line, is read in. This data is placed in memory immediately following the token output buffer.
Figure 10-2 OS and BASIC Pointers (No DOS Present)
Speeding Up a BASIC Program
Example 1 - String Initialization - This program will set all the bytes of a string of any length to the same value. BASIC copies the first byte of the source string into the first byte of the destination string, then the second, third, and so on. By making the destination string the second byte of the source, the same character can be stored throughout the entire string.
Example 2 - Delete Lines Of Code - By using a feature of the operating system, a program can delete or modify lines of code within itself. The screen editor can be set to accept data from the screen without user input. Thus by first setting up the screen, positioning the cursor to the top, and then stopping the program, BASIC will be getting the commands that have been printed on the screen.
Example 3 - Player/Missile (P/M) Graphics With Strings - A fast way to move player/missile graphics data is shown in this example. A dimensioned string has its string/array area offset value changed to point to the P/M graphics area. Writing to this string with an assignment statement will now write data into the P/M area at assembly language rates.
10 REM STRING INITIALIZATION
20 DIM A$(1000)
30 A$(l)="A":A$(1000)="A"
40 A$(2)=A$
10 REM DELETE LINE EXAMPLE
20 GRAPHICS 0:POSITION 2,4
30 ? 70:? 80:? 90:? "CONT"
40 POSITION 2,0
50 POKE 842,13:STOP
60 POKE 842,12
70 REM THESE LINES
80 REM WILL BE
90 REM DELETED
100 REM PLAYER/MISSILE EXAMPLE
110 DIM A$(512),B$(20)
120 X=X+1:READ A:IF A<>-l THEN B$(X,X)=CHR$(A):GOTO 120
130 DATA 0,255,129,129,129,129,129,129,129,129,255,0,-1
2000 POKE 559,62:POKE 704,88
2020 I=PEEK(106)-16:POKE 54279,I
2030 POKE 53277,3:POKE 710,224
2040 VTAB=PEEK(134)+PEEK(135)*256
2050 ATAB=PEEK(140)+PEEK(141)*256
2060 OFFS=I*256+1024-ATAB
2070 HI=INT(OFFS/256):LO=OFFS-HI*256
2090 POKE VTAB+2,LO:POKE VTAB+3,HI
3000 Y=60:Z=100:V=1:H=1
4000 A$(Y,Y+11)=B$:POKE 53248,Z
4010 Y=Y+V:Z=Z+H
4020 IF Y>213 OR Y<33 THEN V=-V
4030 IF Z>206 OR Z<49 THEN H=-H
4420 GOTO 4000