Development
The machines that would become theShepardson Microsystems
In September 1978, Shepardson Microsystems won the bid on completing BASIC. At the time they were finishing Cromemco 16K Structured BASIC for the Z80-basedReleases
The version Shepardson gave to Atari for the CES demo was not intended to be final, and Shepardson continued to fix bugs. Unknown to Shepardson, Atari had already sent the CES version to manufacturing. This version was later known as Revision A. It contains a major bug in a routine that copies memory: deleting lines of code that are exactly 256 bytes long causes a lockup after the next command is entered. The key does not fix it. Revision B attempted to fix the major bugs in Revision A and was released in 1983 as a built-in ROM in the 600XL and 800XL models. While fixing the memory copying bug, the programmer noticed the same pattern of code in the section for inserting lines, and applied the same fix. This instead introduced the original bug into this code. Inserting new lines is much more common than deleting old ones, so the change dramatically increased the number of crashes. Revision B also adds 16 bytes to a program every time it isSAVE
d and LOAD
ed, eventually causing the machine to run out of memory for even the smallest programs. '' Mapping the Atari'' described these as "awesome bugs" and advised Revision B owners "Don't fool around; get the new ROM, which is available on cartridge" from Atari. The book provides a type-in program to patch Revision B to Revision C for those without the cartridge.
Revision C eliminates the memory leaks in Revision B. It is built-in on later versions of the 800XL and all XE models including the XEGS. Revision C was also available as a cartridge.
The version can be determined by typing PRINT PEEK(43234)
at the READY prompt. The result is 162
for Revision A, 96
for Revision B, and 234
for Revision C.
Description
Program editing
Like most home computer BASICs, Atari BASIC is anchored around its line editor. Program lines can be up to three physical screen lines of 40 characters, 120 characters total. The cursor can be moved freely, with the editor automatically tracking which BASIC program line the current screen line is part of. For instance, if the cursor is currently positioned in line 30 and the user uses cursor-up into line 20, any editing from that point will be carried out on line 20. Atari BASIC's editor catches many errors that would not be noticed in MS-derived versions. If an error is found, the editor re-displays the line, highlighting the text near the error in inverse video. Errors are displayed as numeric codes, with the descriptions printed in the manual. Because of the way the line editor works, the user can immediately fix the error. In the example pictured above (withPRUNT
), the error can be fixed by moving the cursor over the U
, typing (the editor only has an overwrite mode), and hitting .
A line entered with a leading number, from 0 to 32767, is inserted in the current program or replaces an existing line. If there's no line number, the interpreter assigns it the number -1 (800016) and the commands are executed immediately, in "immediate mode". The RUN
command executes the stored program from the lowest line number. Atari BASIC allows all commands to be executed in both modes. For example, LIST
can be used inside a program, whereas in many interpreters this would be available in immediate mode only.
During entry, keywords can be abbreviated using the pattern set by Palo Alto Tiny BASIC, by typing a period at any point in the word. So L.
is expanded to LIST
, as is LI.
. Only enough letters have to be typed to make the abbreviation unique, so PLOT
requires PL.
because the single letter P is not unique. To expand an abbreviation, the tokenizer searches through its list of reserved words to find the first that matches the portion supplied. More commonly used commands occur first in the list of reserved words, with REM
at the beginning (it can be typed as .
). When the program is later LIST
ed it will always write out the full words with three exceptions: PRINT
has a synonym, ?
; GOTO
has a synonym, GO TO
; and LET
has a synonym which is the empty string (so ?
as a short-form for PRINT
, but this used the same token so it expanded back to when ed, treating it as an abbreviation, not a synonym.
Tokenizer
When the user presses while editing, the current line is copied into the BASIC Input Line Buffer in memory between 580 and 5FF16. Atari BASIC's tokenizer scans the text, converting each keyword to a single-byte token (for example, is 2016), each number to a six-byte floating point value, each variable name to an index into a table, and so on, until the line is fully turned into an easy to interpret format. The result is stored in an output buffer located at the first 256 bytes of the lowest available free memory, pointed to by the LOMEM pointer stored at 80, 8116. The output from the tokenizer is then relocated. The program is stored as a parse tree. Shepardson referred to this complete-tokenizing concept as a "pre-compiling interpreter". The resulting tokenized code eliminates any parsing during runtime, making it run faster. It has the disadvantage that small constants, like 0 or 1, are six bytes each, longer than the original text. A set of pointers (addresses) indicates various data: variable names are stored in the ''variable name table'' (VNTP – 82, 8316) and their values are stored in the ''variable value table'' (pointed to at VVTP – 86, 8716). By indirecting the variable names in this way, a reference to a variable needs only one byte to address its entry into the appropriate table. String variables have their own area (pointed to at STARP – 8C, 8D16) as does the runtime stack (pointed to at RUNSTK – 8E, 8F16) used to store the line numbers of looping statements (FOR...NEXT
) and subroutines (GOSUB...RETURN
). Finally, the end of BASIC memory usage is indicated by an address stored at MEMTOP – 90, 9116) pointer.
Mathematical functions
Atari BASIC includes three trigonometric functions: sine, cosine, and arc tangent.DEG
and RAD
set whether these functions use radians or degrees, defaulting to radians. Eight additional functions include rounding, logarithms, and square root. The random function, RND
, generates a number between 0 and 1; the parameter not being used.
String handling
Atari BASIC copied the string-handling system of Hewlett-Packard BASIC, where the basic data type is a single character, and strings are arrays of characters. Internally, a string is represented by a pointer to the first character in the string and its length. To initialize a string, it must be DIMensioned with its maximum length. For example:A$(1,10)
returns a string of the first 10 characters of A$
. The arrays are 1-indexed, so a string of length 10 starts at 1 and ends at 10. Slicing functions simply set pointers to the start and end points within the existing allocated memory.
Arrays are not initialized, so a numeric array or string contains whatever data was in memory when it was allocated. The following trick allows fast string initialization, and it is also useful for clearing large areas of memory of unwanted garbage. Numeric arrays can only be cleared with a FOR...NEXT loop:
Input/output
The Atari OS includes a subsystem forGraphics and sound
Atari BASIC supports sound, (via the statement), graphics (), and controllers (). The statement sets one of hardware's 4 square-wave channels with parameters for volume, pitch and distortion. Advanced capabilities of the hardware such as higher pitch resolution, high-pass filters, digitised sound and waveforms, player/missile graphics ( sprites), redefined character sets, scrolling, and custom graphics modes are not supported by BASIC; these will require machine language routines or PEEK/POKE statements. A few of the 17 basic character/graphics modes supported by the hardware cannot be simply accessed from BASIC on the Atari 400/800 as the OS ROMs do not support them. These include some multicolour character modes (ANTIC modes 4 & 5), descender character mode (ANTIC mode 3) and the highest resolution 2 and 4-color modes (ANTIC modes C & E, 160x192 pixels). The only way to access them is via or machine language, setting the ANTIC registers and Display List manually. The OS ROMs on the XL/XE added support for these modes except for ANTIC mode 3, which requires a character set redefined in RAM to operate correctly. Bitmap modes in BASIC are normally set to have a text window occupying the last four rows at the bottom of the screen so the user may display prompts and enter data in a program. If a 16 is added to the mode number invoked via the GRAPHICS statement, the entire screen will be in bitmap mode (e.g. GRAPHICS 8+16). If bitmap mode in full screen is invoked Atari BASIC will gracefully switch back into text mode when program execution is terminated, avoiding leaving the user with an unresponsive screen that must be escaped by typing a blind command or resetting the computer. Bitmap coordinates are in the range of 0 to maximum row/column minus one, thus in Mode 6 (160x192), the maximum coordinates for a pixel can be 159 and 191. If Atari BASIC attempts to plot beyond the allowed coordinates for the mode a runtime error occurs.Advanced techniques
Line labels
Atari BASIC allows numeric variables and expressions to be used to supply line numbers toGOTO
and GOSUB
commands. For instance, a subroutine that clears the screen can be written as GOSUB CLEARSCREEN
, which is easier to understand than GOSUB 10000
.
Strings as a way to manipulate memory
The base addresses of a string is stored in a variable table. String addresses can be redirected to point to arbitrary areas of RAM. This allows the rapid memory-shifting routines underlying string and substring assignment can be applied from BASIC to the memory used for the screen or player/missile graphics. This is particularly useful for achieving rapid vertical movement of player/missile images directly from Atari BASIC.Random access via DATA/RESTORE
Numeric variables and expressions can be used as the parameter for theRESTORE
statement, allowing DATA
statements to be randomly accessed through code such as . This can also be used to emulate static string arrays: .
Error handling with TRAP
TheTRAP
statement jumps to a line number when an error occurs, and this reduces the need for manual error-checking. For example, when drawing graphics on the screen it is not necessary to check whether lines go beyond screen boundaries of the current graphics mode. This error state can be trapped, and the error handled if necessary.
Includes
TheENTER
command reads source code from a device and merges it into the current program, as if the user had typed it in. This allows programs to be saved out in sections via LIST
, reading them in using ENTER
to merge or replace existing code. By using blocks of line numbers that do not overlap, programmers can build libraries of subroutines and merge them into new programs as needed.
Self-modifying code
The editor can be set-up to repeatedly read input from the screen until an EOF is reached. This allows a program to write new program code followed by aCONT
statement to the screen then, positioning the screen cursor at the start of the new code, STOP
the running program, causing the new code to be read in then execution be continued by the CONT
statement.
Embedded machine language
Atari BASIC can call machine code subroutines stored in strings orPOKE
ed into memory. The 256 byte area starting at address 153610 (60016) is often used for this purpose.
Machine code is invoked with the USR
function. The first parameter is the address of the subroutine and the following values are parameters. If the code is stored in a string named ROUTINE$
it can be called with two parameters as .
Parameters are pushed onto the hardware stack as 16-bit integers in the order specified in the USR
call in low byte, high byte order. A final byte is pushed indicating the number of arguments. The machine language code must remove these values before returning via the RTS
instruction. A 16-bit value can be returned to BASIC by placing it in addresses 21210 and 21310 (D416 and D516).
Performance
In theory, Atari BASIC should run faster than contemporary BASICs based on the MS pattern. Because the source code is fully tokenized when it is entered, the entire tokenization and parsing steps are already complete. Even complex mathematical operations are ready-to-run, with any numerical constants already converted to the internal 40-bit format, and variables values are looked up by address rather than having to be searched for. In spite of these theoretical advantages, in practice, Atari BASIC is slower than most other home computer BASICs, often by a large amount. On two widely used benchmarks of the era, ''GOTO
or GOSUB
, the interpreter searches through the entire program for the matching line number. In contrast, contemporary versions of MS-derived BASICs would search forward from the current line if the line number of the branch target was greater, thereby improving branch performance about two times on average.
A related and more serious problem is the implementation of FOR
...NEXT
loops. When a FOR
statement is executed, Atari BASIC records its line number. Every time the NEXT
is reached, it searches through the program for that line, despite it being in the same place as the last time. All other BASICs instead record the memory location of the FOR
statement and can immediately return to it without having to search.
The reason for this poor performance is best illustrated by a quote from one of its primary authors, Bill Wilkinson; in 1982 he stated:
One may contrast this philosophy with that of Steve Wozniak's Apple BASIC for the original Apple I which was designed specifically to have the performance required to write games:
Several third-party BASICs emerged on the platform that addressed some or all of these issues. This included Wilkinson's own BASIC XL, which reduced the time for the ''Byte'' benchmark from 194 to 58 seconds, over three times as fast. On the Ahl benchmark, Atari BASIC required 405 seconds, while exactly the same code in Turbo-BASIC XL took 41.6 seconds, an order of magnitude improvement.
Differences from Microsoft BASIC
*Syntax is checked and errors highlighted immediately on line entry. *Variable names can be of arbitrary length, and all characters are significant. *The following keywords are not in Atari BASIC:INKEY$
, CLS
,DEF FN
, SPC
, TAB
, ELSE
.
*All arrays must be dimensioned prior to use while Microsoft BASIC defaults an array to 10 elements if not dimensioned.
*String variables are treated as character arrays and must be dimensioned before use. MS BASIC stores strings on the LEFT$
, MID$
, and RIGHT$
are replaced by string indexing.
*There is not an operator for string concatenation.
*There are no arrays of strings.
*There is no support for integer variables.
*There are no bitwise operators.
*INPUT
does not allow a prompt.
*PRINT
may be abbreviated as ?
as in Microsoft BASIC, but Atari BASIC does not tokenize it into PRINT
. It remains a question mark.
*The target of GOTO
and GOSUB
can be a variable or expression.
*RESTORE
may take a numeric constant, variable, or expression as a parameter, causing the next READ
to begin from the specified line number
*FOR..NEXT
loops in Atari BASIC must have a variable name referenced by the NEXT
statement while Microsoft BASIC does not require it.
*Multiple variables are not permitted with NEXT
statements as they are in Microsoft BASIC (e.g., NEXT X,Y
).
*LIST
uses a comma to separate a range instead of a minus sign.
Keywords
Notes
References
Citation
Bibliography
* * * * * * * *External links