Atari BASIC

Atari BASIC
An Atari BASIC program ready to run
Original author(s) Paul Laughton
Kathleen O'Brien
Developer(s) Shepardson Microsystems
Initial release 1979 (1979)
Stable release
Revision C / 1983 (1983)
Platform Atari 8-bit family
Type BASIC
License Commercial proprietary software

Atari BASIC is an interpreter for the BASIC programming language that shipped with the Atari 8-bit family of 6502-based home computers. Unlike most 8-bit BASICs, Atari BASIC is not a derivative of Microsoft BASIC, and differs in significant ways. It includes keywords for Atari-specific features and lacks support for string arrays, for example.

The language was originally an 8 KB ROM cartridge for the first machines in the 8-bit series, the 400 and 800. Starting with the 1200XL, BASIC was built-in to the machines, but can be disabled by holding down the OPTION key while booting. The XEGS disables BASIC if powered without the keyboard attached.

The complete annotated source code and design specifications of Atari BASIC were published as The Atari BASIC Source Book in 1983.[1]

History

The machines that would become the Atari 8-bit family had originally been developed as second-generation video game consoles intended to replace the Atari 2600. Ray Kassar, the new president of Atari, decided to challenge Apple Computer by building a home computer instead.[2] This meant the designs, among other changes, needed to support the BASIC programming language, then the standard language for home computers.

In 1978, Atari purchased the source code to the MOS 6502 version of Microsoft 8K BASIC.[3] The original 8K BASIC referred to its memory footprint when compiled on the Intel 8080's instruction set. The lower code density of the 6502 expanded the code to about 9 kB. This was slightly larger than the natural 8 kB size of the Atari's ROM cartridges.[4]

Atari felt that they also needed to expand the language to add better support for the specific hardware features of their computers, similar to what Apple had done with their Applesoft BASIC. This increased the size from 9 kB to around 11 kB. Paring down the code from 11 to 8 kB to fit in a ROM turned out to be a significant problem.[3] Adding to the problem was the fact that the 6502 code supplied by Microsoft was undocumented.

Six months later they were almost ready with a shippable version of the interpreter. However, Atari was facing a January 1979 deadline with the Consumer Electronics Show (CES) where the machines would be demonstrated. They decided to ask for help to get a version of BASIC ready in time for the show.[3]

Shepardson Microsystems

The 8K ROM Atari BASIC cartridge for Atari 8-bit computers.

In September 1978, Shepardson Microsystems won the bid on completing BASIC.[3] Shepardson had written a number of programs for the Apple II family, which used the same 6502 processor, and were in the middle of finishing a new BASIC for the Cromemco S-100 bus machines (Cromemco 32K Structured BASIC).[5]

Shepardson examined the existing work and decided it was too difficult to continue cutting it down to size; instead, they recommended developing a completely new version, originally 10k in size.[6] To make it fit on an 8k ROM, some of the common routines would be moved to the operating system ROMs. Atari accepted the proposal, and when the specifications were finalized in October 1978, Paul Laughton and Kathleen O'Brien began work on the new language.[3]

The contract specified a delivery date on or before 6 April 1979 and this also included a File Manager System (later known as DOS 1.0).[6] Atari's plans were to take an early 8K version of Microsoft BASIC to the 1979 CES and then switch to the new Atari BASIC for production. Development proceeded quickly, helped by a bonus clause in the contract, and an 8K cartridge was available just before the release of the machines. Atari took that version to CES instead of the MS version.[7] Atari Microsoft BASIC later became available as a separate product.[8]

Releases

The version Shepardson gave to Atari for the CES demo was not supposed to be the final version. Between the time they delivered the demo and the final delivery a few weeks later, Shepardson found several bugs in the code and had developed fixes for them.[7] However, unknown to Shepardson, Atari had already sent the CES version to manufacturing.[9]

This version was later known as Revision A. Among several problems, this version contains a major bug in a subroutine that copies memory; under certain conditions, deleting lines of code causes a lockup. This was sometimes known as the "two-line lockup" because it triggered when the next line of code or command was entered. It was notorious as it was one of a very few problems that could not be fixed by pressing the Reset key.[10]

Revision B attempted to fix all of 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 "fix" 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.[10] Another major problem in Revision B was a bug that added 16 bytes to the memory of the program every time it was SAVEd and LOADed, eventually causing the machine to run out of memory even on the smallest programs.[11][12] Mapping the Atari described them as "awesome bugs", and advised Revision B owners "Don't fool around; get the new ROM, which is available on cartridge" from Atari.[12] The book provided a type-in program to patch Revision B to Revision C for those without the cartridge.[13]

Revision C finally eliminated the memory leaks in Revision B.[12] This version was built-in on later versions of the 800XLs,[11] all XE computers, and the XEGS. Revision C was also available in a cartridge production run.[12]

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.[14]

Description

Program editing

Atari BASIC uses a line editor, like most home computer BASICs. Unlike most BASICs, Atari BASIC will scan the program line and stop the user if he makes a typo. The tokenizer/error checking routine had bugs in it and would sometimes refuse to accept a program line if the user "crunched" it, this typically occurred if the program line contained an expression like IFA<>12THEN40.RUN.

This technique saved memory, theoretically improved performance, and had the advantage of immediately displaying problems. If the line failed to tokenize, the editor re-displays the line, highlighting the text near the error in inverse video. This can make catching syntax errors on the Atari much easier than on other editors; most BASICs will not display the errors until the program is executed.

Atari BASIC does not display descriptive errors like Commodore BASIC or some other BASIC variants, instead an error code is printed which the user must look up in a manual.

Like with Microsoft BASIC, Atari BASIC supports "crunching" of program lines in that spaces were not necessary anywhere on the program line, although when LISTed, the program text will be displayed with spaces.

Program lines can be entered by starting with a line number, which will insert a new line or amend an existing one. Lines without a line number are executed immediately. When the programmer types RUN the program executes from the lowest line number. Atari BASIC allows all commands to be executed in both modes. For instance, the LIST command can be used inside a program.

The LIST statement can be used to display either the entire BASIC program or a section of program lines by specifying the starting and ending line. These are separated with a comma rather than a hyphen like in Microsoft BASIC and Atari BASIC also does not support the "display entire program listing up to or following the specified line" feature of Microsoft BASIC (eg. LIST -50 will display everything up to line 50 and LIST 50- will display everything from line 50 onward).

Program lines ("logical lines") can be up to three screen lines ("physical lines") of 40 characters, so 120 characters total, whereas Microsoft BASIC limits the user to 80 characters per program line. The cursor can be moved freely in these lines, unlike in other BASICs where to get "up" a line one has to continuously scroll leftwards until the cursor is wrapped at the left margin (and similarly to go down when wrapping at the right margin) though that works too, except the cursor when wrapping left to right or right to left does not move up or down a line. The OS handles tracking whether a physical line flowed to the next on the same logical line.

The cursor can be moved freely around the screen, and it will wrap on all sides. Hitting ↵ Enter sends the tokenizer the (logical) line on which the cursor sits. So, in the example pictured above (with PRUNT), all the author needs to do to fix the error is move the cursor over the U, type I (the editor only has an overwrite mode) and hit ↵ Enter. This is a common editing technique for, say, renumbering lines. Atari BASIC has no built-in renumbering command, but one can quickly learn to overwrite the numbers on a set of lines then just hit ↵ Enter repeatedly to put them back into the program.

The tokenizer

Atari BASIC uses a token structure to handle lexical processing for better performance and reduced memory size.[15] In contrast to MS-derived BASICs, which perform this tokenization on a line-by-line basis while the program runs, in Atari BASIC this occurs when the user hits Return. The immediate syntax checking described in the "Program editing" section is a side effect of converting each line into a tokenized form before it is stored. Shepardson referred to this early-tokenizing concept as a "pre-compiling interpreter".[16]

The tokenizer converts lines using a small buffer in memory, and the program is stored as a parse tree.[lower-alpha 1] The token output buffer (addressed by a pointer at LOMEM 80, 8116) is 256 bytes, and any tokenized statement larger than the buffer generates an error (14  line too long). The output from the tokenizer is then moved into more permanent storage in various locations in memory. A set of pointers (addresses) indicates these locations: variables are stored in the variable name table (pointed to at VNTP 82, 8316) and the 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 two bytes to address its entry into the appropriate table. Strings 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.

Atari BASIC uses a unique way to recognize abbreviated reserved words. In Microsoft BASIC, there are a few predefined short forms like ? for PRINT and ' for REM. Atari BASIC allows any keyword to be abbreviated using a period at any point in writing it. So L. is expanded to LIST, as is LI.. 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 LISTed 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 10 LET A = 10 and 10 A = 10 mean the same thing). These are separate tokens, and so will remain as such in the program listing.

In the keywords for communicating with peripherals (see the Input/Output section, below) such as OPEN # and PRINT #, the " #" is actually part of the tokenized keyword and not a separate symbol. For example, "PRINT" and "PRINT #0" are the same thing,[lower-alpha 2] just presented differently.

String handling

Atari BASIC differs considerably from Microsoft-style BASICs in the way it handles strings. In the Microsoft model, originally from BASIC-PLUS, strings are variable length without a specified maximum size. In Atari BASIC, strings are arrays of characters like Fortran or C. A string is allocated a fixed size using the DIM statement; its actual length can vary at runtime from 0 to this maximum size.

Strings are not initialized with a default value like "empty" and care has to be taken not to interpret random data in RAM as part of a string. The following trick allows fast string initialization:

10 REM Initialize A$ with 1000 characters of x
20 DIM A$(1000)
30 A$="x":A$(1000)=A$:A$(2)=A$

Another difference is that Atari BASIC uses a single syntax for "slicing" up strings, where A$ refers to the entire string and A$(4,6) slices out the three characters at locations 4, 5 and 6. These replace the LEFT$, MID$, and RIGHT$ commands in Microsoft BASIC. However, this is the same syntax that one would use to access a multi-dimensional array, so there is no way to define an array of strings in Atari BASIC. Additionally, the MS MID$ is based on starting location and length, whereas the Atari slicing are start and end locations, so it is easy to create off-by-one errors. Attempting to access or enter a string greater than the allocated size of a string variable will result in the excess characters being truncated.

String handling routines written for Microsoft BASIC will require considerable modification for Atari BASIC, especially if arrays are used since each string array element refers to a character instead of a string like in Microsoft BASIC. A common workaround was to create a single large string variable that could be used as a pseudo-string array (eg. a string of 100 characters can be "divided" into five blocks of 20 characters each).

Input/Output

The Atari OS includes a subsystem for peripheral device input/output (I/O) known as CIO (Central Input/Output). Most programs can be written independently of what device they might use, as they all conform to a common interface; this was rare on home computers at the time. New device drivers could be written fairly easily that would automatically be available to Atari BASIC and any other program using the Atari OS, and existing drivers could be supplanted or augmented by new ones. A replacement E:, for example could displace the one in ROM to provide an 80-column display, or to piggy-back on it to generate a checksum whenever a line is returned (such as used to verify a type-in program listing).

Atari BASIC supports CIO access with reserved words OPEN #, CLOSE #, PRINT #, INPUT #, GET #, PUT #, NOTE #, POINT # and XIO #. There are routines in the OS for graphics fill and draw, but they are not all available as specific BASIC keywords. PLOT and DRAWTO for line drawing are supported while a command providing area fill is not. The fill feature can be used through the general CIO entry point, which is called using the BASIC command XIO.

The BASIC statement OPEN # prepares a device for I/O access:

10 REM Opens the cassette device on channel 1 for reading in BASIC
20 OPEN #1,4,0,"C:MYPROG.DAT"

Here, OPEN # means "ensure channel 1 is free," call the C: driver to prepare the device (this will set the cassette tape spools onto tension and advance the heads keeping the cassette tape player "paused". The 4 means "read" (other codes are 8 for write and 12 = 8 + 4 for "read-and-write"). The third number is auxiliary information, set to 0 when not needed. The C:MYPROG.DAT is the name of the device and the filename; the filename is ignored for the cassette driver. Physical devices can have numbers (mainly disks, printers and serial devices), so "P1:" might be the plotter and "P2:" the daisy-wheel printer, or "D1:" may be one disk drive and "D2:" and so on. If not present, 1 is assumed.

Typing "DOS" from BASIC will exit the user out to the Atari DOS command menu. Any unsaved programs will be lost. Unlike most BASICs, there is no command to display a disk directory from within BASIC and this must be done by exiting out to DOS.

Graphics and sound support

Atari BASIC has good built-in support of sound, (via the SOUND statement), graphics (GRAPHICS, SETCOLOR, COLOR, PLOT and DRAWTO), joysticks (STICK, STRIG), and paddles (PADDLE, PTRIG). There isn't a supplied FILL command to fill an arbitrary shape with pixels, but a limited operating system function exists and can be called with the XIO command.[17]

There is no dedicated command for clearing the screen in Atari BASIC, this is usually done with PRINT CHR$(125), which PRINTs the clear screen control code (analogous to PRINT CHR$(147) in Commodore BASIC).

Advanced aspects of the hardware such as player/missile graphics (sprites), redefined character sets, scrolling, and custom graphics modes are not supported at the language level. Some of the graphics modes of the underlying hardware are also not directly supported in BASIC, notably what came to be known as "GRAPHICS 7.5", as it offered resolution halfway between GRAPHICS 7 and GRAPHICS 8. Support was added to the XL/XE operating system, accessible from BASIC as GRAPHICS 15.[18]

Advanced techniques

Line labels

Unlike MS-derived BASICs, Atari BASIC allows numeric variables and expressions to be used to supply line numbers to GOTO and GOSUB commands. This can be used to clarify code. For instance, a subroutine that clears the screen could be written as GOSUB CLEARSCREEN, which is much easier to understand than the typical GOSUB 10000.

Loops

FOR...NEXT loops in Atari BASIC must have a variable name referenced by the NEXT statement while Microsoft BASIC did not require it. Multiple variables are not permitted with NEXT statements as they are in Microsoft BASIC (a line like NEXT X,Y is illegal in Atari BASIC).

Atari BASIC does not support ELSE clauses with IF...THEN statements (also not supported in all Microsoft BASIC implementations).

Includes

Most BASICs of the era allow the LIST command to send the source code to a printer or other device. Atari BASIC also includes the ENTER command, which reads source code from a device and merges it back into the program, as if the user had typed it in. This allows programs to be saved out in sections, reading them in using ENTER to merge or replace existing code. By carefully using blocks of line numbers that do not overlap, programmers can build libraries of subroutines and merge them into new programs as needed.

Embedded machine language

Atari BASIC can call machine code subroutines. The machine code is generally stored in strings, which can be anywhere in memory so the code needs to be position independent, or in the 256-byte Page 6 area (starting at address 153610, 60016), which is not used by BASIC or the operating system. Code can be loaded into Page 6 by reading it from DATA statements.

Machine code is invoked with the USR function. The first parameter is the address of the machine code routine and the following values are parameters. For example, if the machine language code is stored in a string named ROUTINE$ it can be called with parameters as ANSWER=USR(ADR(ROUTINE$),VAR1,VAR2).

Parameters are pushed onto the hardware stack as 16-bit integers in the order specified in the USR function in low byte, high byte order. The last value pushed to the stack is a byte indicating the number of arguments. The machine language code must remove all of these values before returning via the RTS instruction. A value can be returned to the BASIC program by placing it in addresses 21210 and 21310 (D416 and D516) as a 16-bit integer.

Performance

Running on original hardware, Atari BASIC is slower than other BASICs on contemporaneous equipment for the same home market, often by a large amount. On two widely used benchmarks of the era, Byte Magazine's Sieve of Eratosthenes and Creative Computings test written by David H. Ahl, the Atari was typically much slower than machines like the Apple II,[19] and even machines like the Sinclair ZX81. In the case of Ahl's test, it took almost seven minutes to complete the benchmark, while the ostensibly slower Commodore VIC-20 did so in just under two minutes. This left the Atari near the end of the list in terms of performance.[20] This is despite the fact that the Atari's CPU ran twice as fast as most other 6502-based computers of era, and that the language was pre-tokenized. Most of the language's slowness stemmed from two problems.[21]

The first is that all numeric values in Atari BASIC are stored in floating-point binary coded decimal (BCD) format, and this includes numbers that could only ever be integers, like line numbers or array indexes. Every time such a number is encountered, the interpreter has to convert it from the BCD format to an internal binary representation using routines in the operating system. Floating point math routines on the Atari were very slow, notably the BCD to binary conversion function, and this affected all programs. In the Byte benchmark, the constant conversion of the array indexes greatly slows the program down. In Ahl benchmark, a single exponent operation, which loops over a poorly optimized multiplication function, was responsible for much of the machine's poor showing.[21]

Atari BASIC uses 48-bit floating point arithmetic. While this has the advantage of greater numerical precision than the 32 or 40-bit floating point in most Microsoft BASICs, it also takes more memory to store (six bytes for each numeric variable) and contributed to slow program execution.

The second problem is due to how Atari BASIC implemented loops and branches. To perform a branch, a GOTO or GOSUB, the interpreter searches through the entire program for the matching line number it needs.[15][lower-alpha 3] On the Atari, this is already slowed by the need to convert these numbers to binary. However, there was a more serious problem; in the case of a FORNEXT loop, most interpreters would push a pointer to the location of the FOR on a stack, so when it reached the NEXT it could easily return to the FOR again. In Atari BASIC, it was not the location in memory that was placed on the stack, but the line number itself. This meant every time a NEXT was encountered, the system had to search through the entire program to find that line. This operation used the slow BCD conversion function. Any loops in an Atari BASIC program cause a large loss of performance relative to other BASICs.[21]

Several BASICs for the Atari addressed some or all of these issues, resulting in large performance gains. BASIC XL reduced the time for the Byte benchmark from 194 to 58 seconds,[21] over three times as fast. This was accomplished by caching the location of FOR/NEXT loops, but BASIC XL also did the same for GOTO and GOSUBs using the same mechanism. Turbo-BASIC XL included a similar feature, as well as a re-written, very high-performance, floating-point library. On the Ahl benchmark, Atari BASIC required 405 seconds, while the exact same code in Turbo BASIC took 41.6 seconds,[22] almost ten times as fast. Using these BASICs, the Atari was one of the fastest home computers of its era; on the Ahl benchmark, Turbo BASIC XL's result places it far ahead of other MS BASICs running on similar machines, approaching the performance of much faster hardware like the IBM PC.[20]

As with all Atari 8-bit family programming languages, the performance of Atari BASIC programs can be increased by as much as 50% by disabling display processing hardware (though this results in a black screen).[21]

Differences from Microsoft BASIC

  • Atari BASIC uses a different string model and does not allow arrays of strings. String concatenation is not supported.
  • DEF FN is not supported.
  • INPUT cannot include a prompt.
  • There is no equivalent of the INKEY$, which returns a single keycode without waiting (unlike INPUT). This could be simulated by PEEKing the keyboard driver.
  • There is no support for integer variables.
  • All string variables and arrays must be dimensioned prior to use while Microsoft BASIC does not require this if there are ten or fewer elements.
  • Variable names can be of arbitrary length.
  • The TAB function is not supported.
  • PRINT may be abbreviated as ? as in Microsoft BASIC, but Atari BASIC does not tokenize it into PRINT. LIST-ing a program will still show the question mark.
  • The target of GOTO and GOSUB can be a variable or expression.

Keywords

See also

Notes

  1. Although the parse tree is implemented as a set of tables, which is really an implementation detail.
  2. Although 0 is actually explicitly disallowed here by BASIC assuming it to be a coding error, isn't it?
  3. One minor improvement found in most Microsoft-derived BASICs is to compare the target line number to the current line number, and search forward from that point if it is greater.

References

Citation

  1. Wilkinson, O'Brien & Laughton 1983.
  2. Decuir 2004.
  3. 1 2 3 4 5 Wilkinson 1982, p. ix.
  4. Steil, Michael (20 October 2008). "Create your own Version of Microsoft BASIC for 6502". Some Assembly Required.
  5. Wilkinson 1982, pp. iv-v.
  6. 1 2 Wilkinson 1982, p. v.
  7. 1 2 Wilkinson 1982, p. x.
  8. Cherry, Charles (June 1987). "BASIC Bonanza". Antic.
  9. Wilkinson 1982, p. vi.
  10. 1 2 "Atari BASIC Bugs". Compute!. July 1986. p. 10.
  11. 1 2 Radcliff, Matthew (September 1995). "Revision C Converter". Antic.
  12. 1 2 3 4 Chadwick 1985, p. 230.
  13. Chadwick 1985, pp. 250-251.
  14. Hardy, Bob (February 1993). "Keycode Getter". Atari Classics. p. 18.
  15. 1 2 Winner, Lane (1982). "De Re Atari, Chapter 10: Atari BASIC". Atari, Inc.
  16. Wilkinson, O'Brien & Laughton 1983, p. 5.
  17. Atari BASIC Reference Manual. p. 54.
  18. "ATR: chpt.15: Display Lists".
  19. Ahl, David (November 1983). "Benchmark comparison test". Creative Computing. pp. 259–260.
  20. 1 2 Ahl, David (January 1984). "Creative Computing Benchmark". Creative Computing. p. 12.
  21. 1 2 3 4 5 Wilkinson 1985, p. 139.
  22. "Ahl's Benchmark?". 28 November 2007.

Bibliography

  • The ATARI BASIC Reference Manual, Atari Inc, 1980, archived from the original on May 1, 2005
  • Chadwick, Ian (1985). Mapping the Atari. Compute! Publications. ISBN 0-87455-004-1.
  • Wilkinson, Bill (1982). Inside Atari DOS. Optimized Systems Software,Inc. ISBN 0-942386-02-7. Retrieved 2009-04-04.
  • Decuir, Joe (December 30, 2004). 3 Generations of Game Machine Architecture (Speech). Classic Gaming Expo 2004. San Jose Convention Center.
  • Wilkinson, Bill; O'Brien, Kathleen; Laughton, Paul (1983). The Atari BASIC Source Book. Compute! Books. ISBN 0-942386-15-9.
  • Wilkinson, Bill (February 1985). "INSIGHT: Atari". Creative Computing. pp. 139–140.
  • Atari BASIC, The Good, the Bad, and the Ugly
  • Albrecht, Bob; Finkel, LeRoy; Brown, Jerald R. (1979). Atari Basic - A Self-Teaching Guide. Retrieved 29 June 2013.
  • Albrecht, Bob; Finkel, LeRoy; Brown, Jerald R. (1985). Atari Basic - XL Edition. Retrieved 29 June 2013.
This article is issued from Wikipedia. The text is licensed under Creative Commons - Attribution - Sharealike. Additional terms may apply for the media files.