Atari BASIC: differenze tra le versioni

Contenuto cancellato Contenuto aggiunto
Recupero di 1 fonte/i e segnalazione di 0 link interrotto/i.) #IABot (v2.0.9.3
 
(31 versioni intermedie di 17 utenti non mostrate)
Riga 10:
}}
 
L''''Atari BASIC''' è un [[linguaggio interpretato|interprete]] del [[linguaggio di programmazione]] [[BASIC]] sviluppato per i [[Famiglia Atari 8-bit|computer ad 8 bit]] basati sul [[microprocessore]] [[MOS 6502]] commercializzati da [[Atari, Inc.]] nei primi [[anni ottanta1980|anni '80ottanta]]. L'interprete fu inizialmente distribuito su una [[cartuccia (supporto)|cartuccia]] da 8 [[byte|kB]] di [[Read-only memory|ROM]] e successivamente venne integrato nella memoria dei modelli XL/XLE, che lo caricavano in automatico se il computer veniva avviato senza nessuna cartuccia inserita nell'apposita porta. Il [[codice sorgente]] dell'Atari BASIC, completo di commenti e delle specifiche di progetto, fu pubblicato in un libro nel [[1983]].<ref name="wilko">{{cita libro|cognome=Wilkinson|nome=Bill|anno=1983|titolo=The Atari BASIC Source Book|url=https://archive.org/details/ataribooks-the-atari-basic-source-book|editore=Compute! Books|idisbn=ISBN 0-942386-15-9}}</ref>
 
 
==Le origini del linguaggio==
Line 18 ⟶ 17:
 
===Il Microsoft BASIC===
{{vedi anche|Atari Microsoft BASIC}}
Atari si rivolse quindi alla società che all'epoca produceva l'interprete più diffuso, la [[Microsoft]], per acquistare la licenza del suo interprete [[Microsoft BASIC|Microsoft 8K BASIC]]. La scelta della versione ad 8 kB dell'interprete fu dettata dal fatto che le [[Read-Only Memory|ROM]] di allora avevano quel taglio massimo. Atari si accorse però che il valore di 8 kB presente nel nome della versione dell'interprete fornito per le [[CPU]] [[MOS 6502]] non indicava la dimensione reale del sorgente: il Microsoft BASIC era nato sull'[[Intel 8080]] ed il [[portabilità|porting]] su 6502 aveva fatto lievitare il codice a 9 kB.
Atari si rivolse quindi alla società che all'epoca produceva l'interprete più diffuso, la [[Microsoft]], per acquistare la licenza del suo interprete [[Microsoft BASIC|Microsoft 8K BASIC]]. La scelta della versione ad 8 kB dell'interprete fu dettata dal fatto che le [[Read-Only Memory|ROM]] di allora avevano quel taglio massimo. Atari si accorse però che il valore di 8 kB presente nel nome della versione dell'interprete fornito per le [[CPU]] [[MOS 6502]] non indicava la dimensione reale del sorgente: il Microsoft BASIC era nato sull'[[Intel 8080]] ed il [[portabilità|porting]] su 6502 aveva fatto lievitare il codice a 9 kB.
 
Atari si rese poi conto che doveva espandere il linguaggio per supportare meglio le caratteristiche hardware dei propri computer, come la Apple aveva fatto con il suo [[Applesoft BASIC]]. Questo passaggio incrementò la dimensione dell'interprete fino a 11 kB. A questo problema si sommava il fatto che il sorgente per 6502 del suo interprete non era documentato, cosa che rallentava il lavoro dei programmatori.
Riga 26:
===Shepardson Microsystems===
[[File:Basic computing language for Atari 8-bit computers.jpg|thumb|La cartuccia da 8 kB di ROM dell'Atari BASIC per i computer Atari ad 8 bit]]
Nel mese di settembre del [[1978]] Atari contattò la [[Shepardson Microsystems]], che aveva già scritto diversi programmi per gli Apple II (che usavano lo stesso processore dei futuri computer Atari) e che era quasi al termine della scrittura di un BASIC per i computer di [[Cromemco]] basati sul [[S-100|bus S-100]] (il ''Cromemco 32K Structured BASIC''), incaricandola di completare il suo interprete BASIC. Shepardson esaminò il lavoro fin lì svolto e concluse che sarebbe stato più semplice riscrivere da capo un interprete che potesse risiedere in 8 kB di memoria piuttosto che cercare di terminare la riduzione di quello già esistente. Atari accettò la proposta e quando le specifiche del linguaggio furono definite, nel mese di ottobre del 1978, Paul Laughton e Kathleen O'Brien si misero al lavoro sul nuovo interprete.
 
===L'Atari BASIC===
Il risultato fu un interprete del tutto differente, che fu denominato '''Atari BASIC'''. Il nuovo BASIC differiva in particolar modo nella gestione delle [[Stringa (informatica)|stringhe di caratteri]]: mentre il Microsoft BASIC le considerava come costanti, non più modificabili, l'Atari BASIC ne consentiva la modifica, permettendo di incrementare o decrementare le loro dimensioni, l'Atari BASIC le considerava come costanti, non più modificabili.
 
Il contratto stipulato con Atari specificava la consegna entro il [[6 aprile]] [[1979]] dell'interprete funzionante (ed anche di un gestore di file, che in seguito sarebbe stato noto come DOS 1.0). Per coprirsi le spalle Atari decise però di continuare a lavorare sulla riduzione del Microsoft BASIC in modo da averne una prima versione in tempo utile per il CES del 1979, mostrarlo alla fiera e poi passare all'Atari BASIC non appena questo fosse stato completato. Ma i bonus sui tempi di consegna fecero terminare a Shepardson il lavoro prima del tempo per cui Atari decise di portare al CES l'Atari BASIC, visto che era stato completato prima della conversione del Microsoft BASIC.
 
===Versioni===
I programmatori di Shepardson avevano lasciato nella prima versione dell'interprete alcuni problemi, e si erano prefissati di sistemarli in un secondo tempo. Ma Atari aveva già messo in fabbricazione le ROM dell'Atari BASIC e la tecnologia dell'epoca non permetteva cambi di programma. L'Atari BASIC fu perciò prodotto con dei [[bug|bug noti]] noti e fu in seguito indicato come '''Revision A'''.
* '''Revision A'''&nbsp;&ndash; Prima versione della cartuccia dell'Atari BASIC (8 kB di ROM). Questa versione conteneva un bug nella [[Funzione (informatica)|funzione]] che copiava la memoria: in determinate circostanze, la cancellaturacancellazione delle righe del codice portava ada un blocco della macchina noto come "2-line lockup".<ref name=twoline>{{cita pubblicazioneRivistaVG|url=http://www.atarimagazines.com/compute/issue74/readers_feedback_10.phpc!|74|16|7|1986|titolo=Atari BASIC Bugs|rivista=Compute!|data=luglio 1986|pagine=10|accessons=05/08/201219}}</ref>
* '''Revision B'''&nbsp;&ndash; Corretta la maggior parte dei bug della Revision A. Durante la correzione del bug "2-line bug" i programmatori reintrodussero lo stesso errore in una funzione più comune, con il risultato che il numero di blocchi aumentò considerevolmente.<ref name=twoline/> Questa versione fu preinstallata all'interno dei modelli 600XL e nei primi 800XLs e non fu mai distribuita sotto forma di cartuccia.
* '''Revision C'''&nbsp;&ndash; Eliminava i problemi di gestione della memoria della precedente Revision B. Preinstallata negli 800XLs più recenti, negli 800XLF, negli XEGS ede in tutti i computer XE. La versione su cartuccia fu prodotta in piccola serie.
 
Un programmatore poteva sapere la versione dell'interprete in uso esaminando una precisa locazione di memoria. Il comando <code>PRINT PEEK(43234)</code> inserito al READY della macchina resistuivarestituiva <code>162</code> per la Revision A, <code>96</code> per la Revision B e <code>234</code> per la Revision C.
 
==DescrizioneCaratteristiche del linguaggio==
===Editor del programma===
L'Atari BASIC usava un [[editor (informatica)|editor]] a righe, come molti BASIC del tempo. A differenza di altri, però, esso analizzava immediatamente la riga immessa alla ricerca di errori di sintassi. Se veniveva inserito un comando sbagliato, l'editor riproponeva la riga che lo conteneva mostrando il punto in cui aveva individuato l'errore.
Riga 51:
A differenza di altri interpreti, l'Atari BASIC permetteva di eseguire tutti i comandi sia durante l'esecuzione del sorgente che in modalità immediata. Ad esempio, <code>LIST</code>, che mostrava il listato sorgente presente in memoria se inserito in modalità immediata, funzionava anche se richiamato dall'interno del programma stesso. Questo modo di interpretare i comandi era utile nel caso si fosse voluto scrivere del codice auto-modificante.
 
Ogni riga del programma (le "righe logiche") potevano occupare fino a 3 righe dello schermo (le "righe fisiche") da 40 caratteri ciascuna, per un totale di 120 caratteri. Il cursore poteva essere mosso liberamente all'interno di queste righe, a differenza degli editor di altri BASIC dove per andare "su" in una riga di programma bisognava per forza scorrere a sinistra finché il cursore non arrivava al bordo e proseguiva dalla fine della riga precedente dello schermo (la stessa cosa per scorrere "giù"). Il cursore poteva essere mosso liberamente all'interno dello schermo, e se usciva da un lato ricompariva dall'altro.
 
===CharacterL'insieme setdi caratteri===
L'Atari usava unaun versioneinsieme modificatadi dellacaratteri tabellaleggermente deimodificato caratteririspetto alla tabella [[ASCII]], denominata [[ATASCII]]. I primi 128 caratteri corrispondevano per la maggior parte a quelli ASCII, con l'eccezione che tutti i caratteri erano stampabili, anche quelli con i codici da 0 a 31, che nella tabella ASCII non lo erano perché corrispondenti a "codici di controllo" che eseguivano operazioni particolari come ad esempio il ritorno a capo. I caratteri dal 128 al 255 erano la visualizzazione inversa dei primi caratteri da 0 a 127.
 
L'interprete accettava per i nomi delle varibilivariabili i caratteri maiuscoli (65-90) ed i caratteri numerici (48-57), con il nome che doveva iniziare con una lettera. I nomi delle stringhe di testo dovevano terminare con il simbolo del dollaro, <code>$</code>.
 
L'insieme di caratteri conteneva anche i caratteri minuscoli ed alcuni caratteri grafici anche se poi la maggior parte dei linguaggiolinguaggi che furono resi disponibili per quei computer, compreso l'Atari BASIC, non riconoscevano i comandi scritti in lettere non maiuscole.
 
Nelle ROM della Revision C dell'interprete fu inserito un insieme di caratteri alternativo che comprendeva anche le lettere accentate, pensato per l'uso in [[Europa]].
 
Dato che l'insieme di caratteri era copiato in una determinata zona della memoria RAM da cui l'interprete leggeva i dati per i caratteri da stampare a video, l'utente poteva modificare tale insieme semplicemente copiando la propria mappa di caratteri sopra a quella originale (la modifica valeva solo fino allo spegnimento della macchina).
<!--
The ANTIC chip uses one byte to indicate the start page of a font (the memory consisting of 256 pages of 256 bytes). But only one font can be used at a time without machine code [[raster interrupt|display list interrupts]] to change the font midway down the screen. An infrequently used 8&times;10 font mode exists, where the range of characters for lower case letters are shifted down two lines thus allowing the actual glyphs to be 8&times;8 yet be presented with ascenders or descenders. This mode is only occasionally used, partly because dot matrix printers cannot easily support it.<ref>Some programs such as PrettyPrint exist which do so by sending the output as graphics to the printer, so that seven lines of 8-bit-high text are printed as eight passes of the 7-bit-high print head.</ref> The ease of implementing other fonts means many are freely available, with font editors and so forth.
 
===TheIl tokenizertokenizzatore===
Come molti interpreti dell'epoca, anche l'Atari BASIC utilizzava un ''tokenizzatore'' che si occupava della conversione dei comandi contenuti nelle righe fisiche dalla forma estesa in cui li inseriva l'utente ad una più stringata detta [[token (testo)|token]], che permetteva un risparmio della memoria utilizzata per contenere il programma.
Like most BASIC interpreters, Atari BASIC uses a token structure to handle [[Lexical analysis|lexical]] processing for better performance and reduced memory size. The [[token (parser)|tokenizer]] converts lines using a small buffer in memory, and the program is stored as a [[parse tree]].<ref>although Wilkinson tends to the parse tree as a set of tables which is really an implementation detail</ref> The token output buffer (addressed by a pointer at LOMEM &ndash; 80, 81<sub>16</sub>) is 1 page (256 bytes) long, and any tokenized statement that is larger than the buffer will generate a BASIC error (14&nbsp;&ndash; line too long). Indeed, the syntax checking described in the "Program editing" section is a side effect of converting each line into a tokenized form before it is stored. [[Sinclair BASIC]] uses a similar approach, though it varies between models.
 
Il risultato elaborato dal tokenizzatore veniva poi memorizzato in aree di memoria differenti a seconda del tipo di dato sotto forma di un [[Puntatore (programmazione)|puntatore]] a 2 byte: i nomi delle variabili erano memorizzati in un'area detta ''variable name table'' mentre i loro valori in un'altra zona detta ''variable value table'', e così via per gli altri oggetti. Una variabile non necessitava che il suo nome fosse tutte le volte che compariva nel codice memorizzato per esteso: bastava inserire il puntatore all'area di memoria appropriata. Il cambio di nome era parimenti semplice dato che bastava modificare i valori contenuti nell'area dove era memorizzato il nome per avere la modifica a livello globale.
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 &ndash; 82, 83<sub>16</sub>) and the values are stored in the ''variable value table'' (pointed to at VVTP &ndash; 86, 87<sub>16</sub>). Strings have their own area (pointed to at STARP &ndash; 8C, 8D<sub>16</sub>) as does the runtime stack (pointed to at RUNSTK &ndash; 8E, 8F<sub>16</sub>) used to store the line numbers of looping statements (<code>FOR...NEXT</code>) and subroutines (<code>GOSUB...RETURN</code>). Finally, the end of BASIC memory usage is indicated by an address stored at MEMTOP &ndash; 90, 91<sub>16</sub>) pointer.
 
Nel Microsoft BASIC c'erano poche forme abbreviate dei comandi, come <code>?</code> per <code>PRINT</code> e <code>'</code> per <code>REM</code>. L'Atari BASIC permetteva invece di abbreviare tutte le parole riservate semplicemente scrivendo una o più lettere della parola e poi inserendo un punto: ad esempio, <code>L.</code>, <code>LI.</code> e <code>LIS.</code> potevano essere tutte forme brevi e valide di <code>LIST</code>. Per espandere la forma abbreviata, il tokenizzatore cercava nel suo elenco di parole chiave e poi effettuava la sostituzione con la prima occorrenza trovata. L'elenco era ordinato in modo da porre in alto le abbreviazioni più corte per i comandi più comuni, così da aiutare il programmatore durante la scrittura del proprio codice: per questo motivo ".", che corrispondeva alla forma breve di <code>REM</code>, era al primo posto. Questo accelerava anche il processo di analisi lessicale dato che avere le forme contratte dei comandi più comuni in cima all'elenco permetteva al tokenizzatore di risparmiarsi tutte le volte la scansione dell'intera lista. Quando il programma veniva stampato a video, il tokenizzatore riconvertiva le forme abbreviate in comandi estesi.
By [[indirection|indirecting]] the variable names in this way, a reference to a variable needs only two bytes to address its entry into the appropriate table; the whole name does not need to be stored each time. This also makes variable renaming relatively trivial if the program is in storage, as it is simply a case of changing the single instance of its name in the table and the only difficulty is if the name changes length (and even then, only if it gets longer): indeed, [[obfuscated code]] can be produced for a finished program by renaming variables in the name tables &ndash; possibly all to the same name. This doesn't confuse the interpreter since internally it is using the index values not the names. Of course, new code will be difficult to add because the tokenizer has to search the name table to find a variable's index, and can get confused if names are not unique (though it is OK to have names in both the "string" and "variable" namespaces, e.g. <code>HELLO = 10</code> and <code>HELLO$ = "WORLD"</code>, because they have separate tables, that is to say, separate [[namespace]]s.)
 
Altri interpreti dell'epoca avevano comandi composti da più parole separati da uno spazio, ad esempio <code>GO TO</code>). L'Atari BASIC non adottava questa sintassi anche se aveva 2 eccezioni alla regola nei comandi per l'accesso alle periferiche esterne: <code>OPEN&nbsp;#</code> e <code>PRINT&nbsp;#</code>.
Atari BASIC uses a unique way to recognize abbreviated reserved words. In Microsoft BASIC there are a few predefined short forms, (like <code>?</code> for <code>PRINT</code> and <code>'</code> for <code>REM</code>). Atari BASIC allows any keyword to be abbreviated using a period, at any point in writing it. So <code>L.</code> will be expanded to <code>LIST</code>, as will <code>LI.</code> and (redundantly) <code>LIS.</code>. To expand an abbreviation the tokenizer will search through its list of reserved words and find the first that matches the portion supplied. To improve the chance of a programmer's correctly guessing an abbreviation, to save typing, and to improve the speed of the lookup, the list of reserved words is sorted to place the more-commonly used commands first. <code>REM</code> is at the very top, and can be typed in just as <code>.</code>. This also speeds lexical analysis generally, since although the time to search is in theory proportional to the length of the list, in practice it will find common keywords very quickly, to the extent that good programmers know when a line is syntactically incorrect even before the parser says so, because the time taken to search the list to find it wanting gives an indication that something is wrong.
 
Le istruzioni di salto <code>GOTO</code> e <code>GOSUB</code> permettevano l'uso di variabili al posto del numero di riga esplicitato.
So whereas Microsoft BASIC uses separate tokens for its few short forms, ATARI BASIC has only one token for each reserved word &ndash; when the program is later <code>LIST</code>ed it will always write out the full words (since only one token represents all possible forms, it can do no other). There are two exceptions to this: <code>PRINT</code> has a synonym, <code>?</code>, and <code>LET</code> has a synonym which is the empty string (so <code>10 LET A = 10</code> and <code>10 A = 10</code> mean the same thing). These are separate tokens, and so will remain as such in the program listing.
 
===Gestione delle stringhe===
Some other contemporary BASICs have variants of keywords that include spaces (for example <code>GO TO</code>). Atari BASIC does not. The main exception here is keywords for communicating with [[peripheral]]s (see the "[[#Input/Output|Input/Output]]" section, below) such as <code>OPEN&nbsp;#</code> and <code>PRINT&nbsp;#</code>; it rarely occurs to many programmers that the "<code>&nbsp;#</code>" is actually part of the tokenized keyword and not a separate symbol; and that for example "<code>PRINT</code>" and "<code>PRINT&nbsp;#0</code>" are the very same thing,<ref>Although 0 is actually explicitly disallowed here by BASIC assuming it to be a coding error, isn't it?</ref> just presented differently. It may be that the BASIC programmers kept the form <code> #</code> to conform with other BASICs (The syntax derives from [[Fortran]]), though it is entirely unnecessary, and probably a hindrance, for tokenizing, and is not used in other languages for the Atari 8-bit family.
L'Atari BASIC gestiva le stringhe in maniera completamente diversa rispetto ai BASIC stile Microsoft. In questi ultimi le stringhe potevano essere di lunghezza variabile e permettevano diverse operazioni mentre l'Altair BASIC usava l'approccio del [[Fortran]], ossia le stringhe erano [[array]] di caratteri la cui massima dimensione era indicata con il comando <code>DIM</code>, anche se poi la sua dimensione poteva variare durante l'esecuzione del programma tra questo valore e 0. Data una stringa, per accedere al suo intero contenuto bastava usare il nome stesso della stringa, ad esempio <code>A$</code>; se invece si voleva accedere solo ad una sua parte bastava indicare tra parentesi i caratteri di inizio e fine, ad esempio <code>A$(4,6)</code> prelevava i caratteri 4, 5 e 6.
 
Nonostante questo modo di gestione delle stringhe fosse molto elegante, comportava però dei problemi quando si dovevano portare sull'Atari BASIC programmi scritti per altri interpreti dato che non solo si dovevano considerare le istruzioni <code>LEFT$</code>, <code>RIGHT$</code> e simili usate dai BASIC in stile Microsoft ma anche il fatto che la dimensione di una stringa in Atari BASIC era stabilita a priori.
Expanding tokens in the listing can cause problems when editing. The Atari line input buffer is three lines (120 characters); up to three "physical lines" make one "logical line". After that a new "logical line" is automatically created. This doesn't matter much for output but it does for input, because the operating system will not return characters to the tokenizer after the third line, treating them as the start of a new "logical line". (The operating system keeps track of the mapping between physical and logical lines as they are inserted and deleted; in particular it marks each physical line with a flag for being a continuation line or a new logical line.) But using abbreviations when typing in a line can result, once they have been expanded on output, to a line that is longer than three lines and, a more minor concern, some [[whitespace characters]] can be omitted on input, so for example <code>PRINT"HELLO"</code> will be listed as <code>PRINT&nbsp;"HELLO"</code>, one character longer. If one then wants to edit the line, now split across two logical lines, one must replace the expanded commands back with their abbreviations to be submit them back to the tokenizer. The moral of this is, generally, don't try to squeeze more out of a line than is reasonable, or, in the alternate, obfuscate variables by <code>makinggggggthemverrrryverrrrylongindeed</code>.
 
[[Literal (computer science)|Literal]] line numbers in statements such as <code>GOTO</code> are calculated at run time using the same floating-point mathematical routines as other BASIC functions. This calculation allows [[subroutine]]s to be referred to by variables: for instance <code>GOTO EXITOUT</code> is as good as <code>GOTO 2000</code>, if one sets <code>EXITOUT</code> to 2000. This is much more useful than it might sound; literals are stored in the 6-byte floating-point variable format, but variables are stored as a two-byte pointer to their place in the variable value table, at VVTP, so by using a variable the GOTO target is just two bytes instead of six. Of course the actual number takes another six, but this is only stored once, so if the same line number is used more than twice, one saves some memory, though the line number takes a little longer to look up. (The design choice to store what can only legally be integers as floating-point numbers is discussed below.)
 
It is quite common in BASIC to use GOTO or GOSUB to a line number, so real savings can be made to replace these numbers with variables. It also means that if the programmer is careful always to use the variable and not the literal, subroutines can be easily renumbered (moved around in the program), because only the variable value needs to be changed. This makes it common to see, at the start of an Atari BASIC program, a sequence of LET statements assigning line numbers to variables.<ref>Because the literal line numbers are stored as floating point numbers, deliberate [[obfuscated code|obfuscation]] can happen by changing them to values other than [[natural number]]s. This is rarely useful, because the line number is rounded as part of the lookup.</ref>
 
===String handling===
Atari BASIC differs dramatically from Microsoft-style BASICs in the way it handles strings. In BASICs following the Microsoft model, strings are special types that allow for variable length and various operations. Atari BASIC has no strings of this sort, instead using [[Array data structure|arrays]] of characters, rather like [[Fortran]]. This allowed the BASIC language programmers to remove all the special-purpose code needed for handling dynamic resizing of strings, reusing instead the code already being used to handle arrays of numbers. A string is allocated a maximum size using the <code>DIM</code> statement, although its actual length can vary at runtime from 0 to this maximum size.
 
Of course, strings are ''not'' used by end programmers in the same way as arrays of numbers &ndash; at least not normally &ndash; so Atari BASIC also includes a selection of commands for "slicing" up arrays. <code>A$</code> refers to the entire string, whereas <code>A$(4,6)</code> "slices" out the three characters 4, 5 and 6. In theory, this is a more elegant solution than Microsoft BASIC's <code>LEFT$</code>, <code>MID$</code>, and <code>RIGHT$</code> solution, as this syntax replaces three separate commands with a single one.
 
Although this simplification reduces the size of Atari BASIC and offers some theoretical performance benefits, it is also a hindrance to porting BASIC programs from other computers to the Atari. When the Atari was first produced it was the norm for programs to be provided as listings in magazines for programmers to type in. They would have to scan them for instances of <code>LEFT$</code>, <code>RIGHT$</code> and so on, do some mental arithmetic and replace them with slicing commands. Because strings were allocated a fixed size it generally means that programmers will [[pessimization|pessimize]] or [[guesstimate]] the likely maximum size, allocating, perhaps 256 bytes for a string that only ever stores someone's first name.
 
Strings in Atari BASIC cannot themselves be members of arrays, so arrays of strings have to be implemented by the programmer. Strings can move around in memory, so it is not generally possible for example to store their memory addresses in an array. For short strings of approximately the same length, instead an array is generally built using [[Padding (cryptography)#Byte padding|padding]] so that the strings are all the same length and the ''n''th string in the array is ''n''&times;''l'' characters into it, where ''l'' is the length of the string.
 
Long strings initialization usually required <code>for</code> loops. Nevertheless, the language enabled fast string initialization with the following trick:
 
REM The following initialize A$ with 1000 characters of ''x''
DIM A$(1000)
A$="x":A$(1000)=A$:A$(2)=A$
 
===Input/Output===
L'Atari BASIC supportava l'accesso al CIO (Central Input/Output), che nel [[sistema operativo]] dei computer Atari si occupava dell'accesso alle periferiche di [[input/output]], con le parole chiave <code>OPEN&nbsp;#, CLOSE&nbsp;#, PRINT&nbsp;#, INPUT&nbsp;#, GET&nbsp;#, PUT&nbsp;#, NOTE&nbsp;#, POINT&nbsp;#</code> e <code>XIO&nbsp;#</code>, seguiti dal numero del canale che si intendeva utilizzare. I canali che il CIO offriva erano 8, numerati da 0 a 7 ma alcuni non erano disponibili all'utente perché riservati dal sistema: il canale 0 rappresentava l'editor stesso; il canale 6 era usato per accedere allo schermo in modalità grafica; il canale 7 era utilizzato per stampare e accedere al registratore a cassette mediante i comandi <code>LPRINT, SAVE, LOAD, CSAVE, CLOAD</code>.
====CIO overview====
The Atari [[operating system|OS]] includes a subsystem for [[peripheral]] device input/output (I/O) known as CIO (Central Input/Output). All I/O went through a central point of entry (E45C<sub>16</sub>) passing the address of an ''I/O Control Block'' (IOCB), a 16-byte structure that defines which device was meant, and what kind of operation (read, write, seek etc.). There are 8 such IOCBs, allocated at fixed locations in page 3 of memory from <code>380<sub>16</sub></code> to <code>3FF<sub>16</sub></code>.
 
===Grafica===
Most programs therefore can be written [[device independent|independently]] of what device they might use, as they all conform to a common interface &ndash; this was very rare on home computers when Atari BASIC was first made. [[Virtuality (software design)|virtual]] devices such as the screen, <code>S:</code> and the editor, <code>E:</code> did have special operations, for example to draw graphics or to ask for line input (in fact <code>E:</code> was pretty much a combination of <code>S:</code> and the keyboard, <code>K:</code>), but these were done in a uniform way and new device drivers could be written fairly easily that would automatically be available to ATARI BASIC and indeed any other program using the Atari OS, for example to provide support for new hardware devices such as mouse pointers, or software devices such as an 80-column display (using typically a 4&times;8 pixel font). Existing drivers could be supplanted or augmented by new ones since the driver table was searched newest-to-oldest, so a replacement <code>E:</code>, for example could displace the one in ROM to provide an 80-column display, or to [[Piggy-back (transportation)|piggy-back]] on it to generate a [[checksum]] whenever a line was returned &ndash; this technique is used for some of the program listing checkers that provide a checksum for each line.
{{Vedi anche|ANTIC}}
[[File:Atari-gr2-sl.png|thumb|L'output di un programma che usa le modalità GRAPHICS 2 e 0.]]
I computer Atari ad 8 bit avevano un sofisticato sistema di gestione della grafica dovuto all'uso di appositi chip, l'[[ANTIC]] ed il [[CTIA e GTIA|CTIA]]: ciò perché originariamente i computer erano stati progettati per essere console giochi. Grazie ai 2 chip il sistema offriva diverse modalità grafiche ed era presente anche il supporto agli [[sprite (informatica)|sprite]].
 
Purtroppo l'Atari BASIC non metteva a disposizione comandi per gestire direttamente gli sprite ma ciò era comunque fattibile mediante l'uso di [[PEEK e POKE]] con cui leggere e scrivere direttamente nei registri del CTIA. Il risultato non era però dei migliori perché il chip grafico supportava lo scorrimento orizzontale degli sprite ma non quello verticale per cui usando l'Atari BASIC, che era molto lento nello spostamento di blocchi di dati in memoria, nel caso di scorrimenti verticali si ottenevano prestazioni scarse. Per gestire questo problema i programmatori ricorrevano ad un paio di trucchi: usavano piccole funzioni scritte direttamente in [[linguaggio macchina]] oppure memorizzavano i dati degli sprite in stringhe e poi usavano le funzioni di copia delle stringhe, che erano funzioni in linguaggio macchina e quindi eseguite molto velocemente.
====CIO access in BASIC====
Atari BASIC supports CIO access with reserved words <code>OPEN&nbsp;#, CLOSE&nbsp;#, PRINT&nbsp;#, INPUT&nbsp;#, GET&nbsp;#, PUT&nbsp;#, NOTE&nbsp;#, POINT&nbsp;#</code> and <code>XIO&nbsp;#</code>. There are routines in the OS for graphics fill and draw, but they are not all available as specific BASIC keywords. <code>PLOT</code> and <code>DRAWTO</code> 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 <code>XIO</code>.
 
I comandi per gestire la grafica erano: <code>COLOR</code>, <code>SETCOLOR</code>, <code>CLEAR</code>, <code>PLOT</code>, <code>DRAWTO</code>, <code>LOCATE</code> e <code>GRAPHICS</code>. Mancava un comando <code>FILL</code> per riempire una determinata area con un colore, strana mancanza dato che il sistema operativo aveva una funzione per eseguire questa operazione.
It is odd that a machine that is superlatively endowed with graphics capabilities did not expose everything to BASIC, when they are already there in the hardware and the OS. One might assume the BASIC programmers ran out of time or space to add them to the BASIC tokenizer: they are available in variants such as [[Turbo-BASIC XL]], and in other languages.
 
===Prestazioni===
Up to eight IOCBs can be in use at a time, numbered 0 through 7 (0 was, by default, the editor <code>E:</code>). The BASIC statement <code>OPEN&nbsp;#</code> was used to prepare a device for I/O access:
Se paragonato ad altri interpreti preinstallati su computer similari dell'epoca, l'Atari BASIC risultava estremamente lento, specialmente se si considera che il MOS 6502 operava ad una frequenza quasi doppia rispetto agli altri sistemi. La maggior parte di questi problemi di lentezza derivava da diversi motivi che traevano origine dalla natura stessa del codice e del sistema.
 
Il primo motivo era che l'Atari BASIC poteva usare variabili al posto dei numeri di riga nelle istruzioni di salto <code>GOTO</code> e <code>GOSUB</code>, e ciò comportava un aggravio di calcoli nella funzione di ricerca del numero di riga. Inoltre l'interprete non generava un errore nel caso la riga indicata non esistesse ma l'esecuzione proseguiva alla riga immediatamente successiva. Questo comportamento veniva adottato per implementare il comportamento di <code>NEXT</code> nel ciclo <code>FOR</code>...<code>NEXT</code>, rallentandone l'esecuzione.
REM Opens the cassette device on channel 1 for reading in BASIC
OPEN #1,4,0,"C:MYPROG.DAT"
 
Il secondo motivo risiedeva nel fatto che l'Atari BASIC non gestiva nativamente i numeri interi: tutti i numeri, anche i numeri di riga, erano numeri in virgola mobile per cui un'operazione con numeri interi vedeva eseguita continuamente la conversione da intero a virgola mobile e viceversa. Questo perché l'Atari BASIC si appoggiava alle funzioni di gestione dei numeri in virgola mobile predefinite all'interno del sistema operativo del computer, che oltretutto usavano la notazione [[Binary-coded decimal|BCD]] per la memorizzazione dei numeri per via del fatto che la CPU supportava nativamente tale formato.
Here, <code>OPEN&nbsp;#</code> means "ensure channel 1 is free" (an error otherwise results), call the <code>C:</code> 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 <code>4</code> means "for read" (other codes were <code>8</code> for write, <code>12 = 8 + 4</code> for "read-and-write", and so forth), and the third number provides extra auxiliary information, here not used and set by convention to 0. The <code>C:MYPROG.DAT</code> is the name of the device and the filename, as it happens, files on cassette were not named by this device{{Clarify|date=March 2011}}. The string gives the device name and optionally a filename. 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:" another, "R1:" may be a modem and "R2:" an oscilloscope (R for [[RS-232]], provided by an add-on interface and not built into the OS), and so on; if not present, 1 is assumed.
 
Col tempo diversi produttori misero in commercio interpreti BASIC alternativi con prestazioni da 3 a 5 volte superiori rispetto a quelle dell'Atari BASIC. Anche la stessa Atari rilasciò il BASIC che aveva iniziato a sviluppare sulla base del Microsoft BASIC, l'[[Atari Microsoft BASIC]], che aveva prestazioni superiori ma che non era compatibile con l'Atari BASIC.
====Reserved IOCBs in Atari BASIC====
ATARI BASIC disallows access to IOCB 0 (the editor, <code>E:</code>) and reserves IOCB 7 for printing and cassette operations using the built-in commands <code>LPRINT, SAVE, LOAD, CSAVE, CLOAD</code>, though there is nothing to stop printers or the cassette being used on other channels too. IOCB 6 is used for accessing the graphics screen device (<code>S:</code>) for drawing lines, filling shapes and so on. <code>SAVE</code> and <code>LOAD</code> output the compact tokenized form of the BASIC program, <code>LIST</code> and <code>ENTER</code> output and input the text source, just as if they were being sent to or from the editor.
 
For the other CIO functions, Atari BASIC uses the <code>XIO</code> statement. This just primes an IOCB and calls the CIO entry point; any of the other commands (<code>PRINT</code>, <code>INPUT</code> and so on) can be achieved with the more general form <code>XIO</code>.
 
But the form of XIO is not very friendly for BASIC users, and it is mostly used for unusual functions that are specific to a particular device. For example, an <code>M:</code> device exists called "Multi-Mouse"<ref>Published in [[Page 6]] magazine, July 1986.</ref> that allows an Atari ST mouse, 8-bit trakball, touch tablet, or joystick, to be treated as a device whereby the position of the mouse cursor is set or got with <code>NOTE</code> and <code>POINT</code> commands. It should be remembered here that <code>POINT</code> does not mean, as it does in many BASICs, draw a point on the screen, but point a IOCB channel at a specific place in a file. In Atari DOS the two parameters to <code>NOTE</code> and <code>POINT</code> are the disk sector and offset, which is not very portable. In [[SpartaDOS]] they make up the offset from the start of the file. In the Multi-Mouse driver <code>M:</code>, they are the X and Y position of the mouse cursor.
 
====Error Handling====
I/O routines returned error codes of 128-255 (80<sub>16</sub>-FF<sub>16</sub>) via the processor's Y register and setting the carry flag of the processor. Setting the carry flag is a neat trick since the caller can immediately branch-on-carry (BCC or BCS instructions) to an error routine, a brief, quick and relocatable 6502 instruction (2 bytes, 2 cycles), without having to test Y for the (we hope) normal case where there is no error.
 
As with other aspects of the CIO, error codes were common across devices but could be extended for particular devices. Error handlers could thus be written quite generically, to [[Fault-tolerant system|fail gracefully]], maybe put out a message, ask the user whether to retry, propagate the error, and so on.
 
There were no user-friendly messages for standard error codes in the OS itself. They would be interpreted by the application.
 
Atari BASIC (and other languages) thus had the freedom to return error codes less than 128, and these meant different things in different languages. There was nothing to stop a perverse implementer using error codes of 128 or above, but no incentive to do so.
 
===Graphics===
====Hardware support====
{{Main|ANTIC}}
 
[[File:Atari-gr2-sl.png|thumb|right|250px|The output of a small program using GRAPHICS 2 mode. The text says in {{lang|es|Here are 3 lines in Graphics Mode 2. ''(At the foot of the screen)'' And here is a window with four lines in Graphics Mode 0.}} READY.]]
 
The Atari 8-bit family of hardware includes quite a sophisticated graphics system, stemming from its basis in video games consoles.
 
Unlike many other home computers, the graphics "mode" &ndash; the size of pixels and the number of colors that could be displayed &ndash; is not fixed for the whole display but described line-by-line in a small microcontrol language to create a ''display list''. Each entry in this list describes one or more lines on the TV display, top-to-bottom. A dedicated graphics microprocessor, "ANTIC", reads these out during the [[horizontal blanking interval]] to determine how to display the next TV line. Lines can be ''narrow'' (256 pixels wide at highest resolution), ''normal'' (320 pixels) or ''wide'' (384 pixels). Characters are 8&times;8 and one display list entry would thus describe 8 TV lines; the ANTIC keeps a counter (a [[shift register]]) of which line in the font to read the pixel data from for each of those lines, thus only requiring one entry for the whole 8 lines in the display. Similarly for larger, coarser graphics modes, the ANTIC chip kept track of the information so that it would display the data on more than one TV line.
 
The ANTIC thus has to reference the RAM and asserts control over the [[address bus]] and [[data bus]] to do so. This "steals" cycles from the main 6502 CPU. The [[Sinclair ZX81]] had <code>SLOW</code> and <code>FAST</code> commands to switch the display off and on, because writing the display took about three quarters of the whole processor time. Because the Atari's display rendering is on a separate chip, even though it has to [[Instruction cycle|fetch memory]], <!-- "Fetch DAB page links there, now --> <!-- its impact on the main processor is generally negligible.
 
That being said, American machines are [[clock rate|clocked]] to American [[NTSC]] video systems, at about 1.79&nbsp;Mhz, to fit the 60&nbsp;Hz vertical blank and correspondingly shorter horizontal blank; but European [[PAL]] models are clocked at 1.77&nbsp;Mhz<ref>http://www.faqs.org/faqs/atari-8-bit/faq/section-16.html NTSC vs PAL/SECAM Ataris.</ref> to fit a 50&nbsp;Hz vertical blank. Because European machines service fewer vertical blank interrupts per second, it makes mainline programs run faster, and code using vertical-blank interrupts run slower than American ones.
 
Original Atari 800 and 400 systems included another processor, [[CTIA and GTIA|CTIA]] that assisted Antic in producing the graphics output. Shortly after introduction this chip was upgraded to the [[CTIA and GTIA|GTIA]] also included in all subsequent Atari 8-bit models. GTIA provides three new color processing modes which are accessible via Atari BASIC GRAPHICS modes 9, 10, and 11. The alternative color interpretations are the basis of [[software-driven graphics modes for the Atari 8-bit computers|additional graphics modes]], but for the purposes of discussing Atari BASIC these do not affect the basic description as they were programmed much the same way as existing modes.
 
=====Sprites (Player/Missile Graphics)=====
A hardware [[sprite (computer graphics)|sprite]] system is handled by [[CTIA and GTIA|CTIA/GTIA]]. The official ATARI name for the sprite system is "Player/Missile Graphics", since it was designed to reduce the need to manipulate display memory for fast-moving objects, such as the "player" and his weapons, "missiles", in a [[shoot 'em up]] game. See the [[CTIA and GTIA|CTIA/GTIA]] page for the technical description of the Player/Missile implementation.
 
Atari BASIC does not provide direct support for Player/Missile graphics beyond the capability of PEEK/POKE. Moving a sprite horizontally is as simple as changing a register in the CTIA/GTIA (in Atari BASIC, a single POKE statement moves a player or missile horizontally). Moving the sprite vertically is achieved by block moving (or rotating) the definition of its glyph in memory. This is quite fast in 6502 machine language, even though the 6502 lacks a block-move instruction like the 8080, because the sprite is exactly 128 or 256 bytes long and so the indexing can be easily accommodated in a byte-wide register on the 6502. However, block memory moves are painfully slow in Atari BASIC. BASIC programs using sprites will ordinarily use one of two methods to perform high speed memory moves: first is including short USR() routines to perform the memory moves. The second exploits Atari BASIC's flexible string management by defining a large string for the Player/Missile memory map, and then using string copy functions which move memory at machine language speeds.
 
Careful use of sprites with the other graphics features of the Atari hardware can make graphics programming, particularly games, significantly simpler.
 
=====Interrupts=====
Short sections of machine language code can be executed during the horizontal blanking interval, and this is typically done to change the values in the color registers, horizontal sprite positions and so forth thus giving the appearance of more colors or more flexible sprites than the hardware provides ab initio. This machine code has to be very short as there are not many clock cycles available during each horizontal blank. These routines are known as DLIs (''display list interrupts'') but are simply off limits to Atari BASIC as it is far too slow to perform even the simplest of tasks. Strictly these should be called "DLI routines" but are usually just called "DLIs".
 
During the [[vertical blanking interval]], a much longer interval, another interrupt is generated and the Operating System hooks into this to perform some housekeeping tasks. Again, this is not available to Atari BASIC directly, although with some manipulation and severe restrictions (because BASIC was not designed to be [[reentrant (subroutine)|re-entrant]]) it is possible for a VBI (''vertical blank interrupt'') routine to call a BASIC routine. The VBI is a favourite place to stick some code that needs to execute frequently.
 
====Operating system support====
The operating System provided several standard "Graphics modes" by which it set up a display list automatically, and allocated memory, at the top end of free memory. These provided a range of graphics modes including text modes, graphics modes and mixed text-and-graphics modes. It was only these predefined modes that were available to Atari BASIC.
 
The lack of an OS routine for a general-purpose memory move routine perhaps exhibited in artifacts of the graphics design. For example, once a graphics channel had been opened, it was not possible (or at least easy) to move it down in memory so that other memory could be reserved above it, which meant that generally a program would allocate "more than enough" memory above the high memory pointer (HIMEM) then set the graphics mode (with the <code>GRAPHICS</code> statement) to have the operating system allocate memory for the display below the new high water mark.
 
Most of ANTIC's registers were write-only, their values could not be read (or rather they could be, but were meaningless or returned different values from those written as they were [[multiplexer|multiplexed]]). The Operating System kept copies of the values written in "shadow registers" in pages 0 and 2 of memory (page 1 was the hardware stack on 6502 processors), thus allowing programs to read the values. The values written here were rewritten to the ANTIC registers during the vertical blank interrupt.
 
The operating system provided access to the graphics in two ways: by allowing direct reads and writes (in Atari BASIC, through the <code>PEEK</code> and <code>POKE</code> commands to the memory being used to hold the graphics, by making available the address of the start of that memory in a well-known ___location, and to the shadow registers), and also by providing a CIO device, "S:", through which CIO commands could be issued. The S: device supported the general-purpose <code>XIO</code> command used to implement <code>PLOT</code>, <code>DRAWTO</code> and <code>FILL</code> (unfortunately the last was not exposed to Atari BASIC, and was also rather tricky to get right at the best of times, as it used a rather primitive [[scanline fill]] that filled lines left-to-right, bottom-to-top but stopped as soon as a boundary was met, rather than providing a full [[flood fill]]).
 
In a way there was some confusion and overlap here in the design. For example, the CIO <code>NOTE</code> and <code>POINT</code> commands could be considered analogous to reading and writing the position of the cursor, but instead they had a separate interface through well-defined memory locations. Thus the exposure of the graphics [[API]] to BASIC and other languages was perhaps not as orthogonal and device-independent as it could have been.
 
====Atari BASIC support====
Atari BASIC supported graphics using the statements <code>COLOR</code>, <code>SETCOLOR</code>, <code>CLEAR</code>, <code>PLOT</code>, <code>DRAWTO</code>, <code>LOCATE</code> and <code>GRAPHICS</code>.
 
Because of the support provided by the operating system, Atari BASIC implemented most of its graphics statements as simple calls to those routines or just set the memory registers for the cursor position and so on. In many cases it simply left programmers to use <code>PEEK</code> and <code>POKE</code> statements. It could be argued that some statements such as <code>SETCOLOR</code> were not only redundant but confusing, since they simply set one color value in a shadow register and could be as easily, and more quickly, done with a <code>POKE</code> command; the ROM space used by these routines could perhaps have been better used to implement other things.
 
The lack of a <code>FILL</code> command is a notable omission considering that the routine, however primitive, was available in the operating system. It could be achieved with the general-purpose <code>XIO</code> command, but was rather fiddly:
 
REM The co-ordinates of the corners of the fill quadrilateral have to be set up
REM before calling XIO, using POKE into the IOCB. This is quite a trick because
REM it's not easy to find out where the IOCB is. Anyway, then we do:
XIO 18,#6,12,0,"S:"
REM XIO # = Extended IO.
REM 18 = Fill (17=Drawto).
REM #6 = On Channel 6, mapped to the graphics screen device.
REM 12 = Read/write.
REM 0 = Redundant (unused).
REM "S:" = Logical device, used only for OPEN and some disk
REM commands with a target such as for a RENAME
REM Redundant here but used by convention
 
There was no BASIC support for sprites, although they were not particularly difficult to program in BASIC using <code>PEEK</code> and <code>POKE</code>, but this could not be done particularly fast in, say, games. Similarly, setting up a custom display list could be done, but was rather difficult, and was far more easily and effectively done in machine language. Sprite data could be defined using a <code>DATA</code> statement, and then <code>POKE</code>d into memory. However, scrolling a sprite vertically, for example, was not quick in BASIC as there was no "block memory move" statement and required a slow <code>FOR</code> loop of <code>PEEK</code>s and <code>POKE</code>s.
 
===Hardware support===
In comparison to the BASICs of some competing machines at the time, Atari BASIC had good built-in support of sound, (<code>SOUND</code> statement), graphics (<code>GRAPHICS, SETCOLOR, COLOR, PLOT</code> and <code>DRAWTO</code>) and peripheral units like joysticks (<code>STICK, STRIG</code>) and paddles (<code>PADDLE, PTRIG</code>). Other home computer users were often left with cryptic <code>[[PEEK and POKE|POKE]]</code>s for such programming.
 
That being said, the parameters for many of these commands were cryptic, and essentially little better than machine code. <code>SOUND</code> took four numeric parameters for pitch, tone, volume and channel (the Atari 8-bits had 4-channel sound); the <code>GRAPHICS</code> statement took three to handle the numerous graphics modes, <code>SETCOLOR</code> and <code>COLOR</code> each took a number of parameters with different meanings depending on the graphics mode and often which did not match between the two, and so forth. It may be an example of [[Conway's law]]: clever designers made excellent hardware, by and large following a common model (memory-mapped register addressing for [[ANTIC]], GTIA and [[Atari POKEY|Pokey]], for example), but the lack of the teams' interaction made them work in curiously different ways. One may wonder why it would be thought so important to include two key words for examining the state of paddles &ndash; something that could be done easily with a single <code>PEEK</code> and indeed in every respect more efficiently than a <code>PADDLE</code> statement &ndash; yet not have a <code>FILL</code> command that was already coded in the OS and would have been uniquely advanced for the BASICs of the time.
 
Similarly, advanced aspects of the hardware such as [[Sprite (computer graphics)|sprite]]s were completely out of bounds for BASIC programmers, and the lack of access to timers made sound programming difficult, particularly because North American machines ran on different [[clock speed]]s from the rest of the world (basically because they were tied to the speed of the television system).
 
===Performance===
Running on the original equipment, Atari BASIC is slower than other BASICs on contemporaneous equipment for the same home market, sometimes by a surprising amount, especially when one takes into account the fact that the Atari's CPU was clocked almost twice as fast as that of most other 6502-based computers of that era. Most of these problems stemmed from two particularly poorly implemented bits of code.
 
One is a side effect of how Atari BASIC recalculates line numbers as the program is run. This means that a <code>GOTO</code> has to run a small amount of additional code in order to find the line to jump to.<ref>For added excitement, unlike in most other BASICs, if the line number is not found, execution continues at the lowest-numbered line higher than that specified rather than producing an UNDEFINED STATEMENT ERROR</ref> This would normally be a minor issue, but the same code is also used to implement <code>NEXT</code> in a <code>FOR</code>...<code>NEXT</code> loop, so it dramatically lowers performance of these very common loops (indeed, the only loop structure in Atari BASIC). It is obvious that a line number less than 65536<sub>10</sub> (10000<sub>16</sub>) can be stored in a 16-bit unsigned integer, but presumably the designers chose to store it as floating point for other reasons.
 
Atari BASIC does not do well with integer variables; all numbers are stored as floating point. Atari BASIC relied on the Atari OS's built-in floating point routines ([[Binary coded decimal|BCD]] notation), which are relatively slow compared to other representations, even on the same hardware. But most of the slowness of the implementation lies in a particularly poor implementation of the multiply subroutine used throughout the math libraries. This is really not a problem of the language itself but of the underlying OS, but it adds to the general poor performance. More spectactularly, really, the fact that simple integer operations are converted back and forth to floating point really highlights the flaw, especially considering that the Atari's best features rely on special hardware (for graphics, sound and so on) that deals purely in integers: bytes or two-byte words. There is not even in Atari BASIC an easy way to perform [[bitwise operation]]s.
 
The [[MOS 6502]] processor had a special mode for dealing with BCD (the <code>SED</code> and <code>CLD</code> instructions to treat each [[nibble|4 bits of a byte]] as a BCD digit), and perhaps that was particularly attractive to the designers for implementing floating point as BCD. The now almost universal [[IEEE 754]] standard of representation of floating point numbers was still at the design stage when the Atari 8 bit family and its contemporaries first came to market, so the design of an FP implementation was very much up to the OS or BASIC designer.
 
Several commercial and shareware BASICs were available on the platform that addressed some or all of these issues, resulting in performance that was 3 to 5 times faster than the Atari version. Using these BASICs, the Atari was one of the fastest home computers of its era.
 
Atari later sold a [[floppy disk|diskette]]-based version of Microsoft BASIC, [[Atari Microsoft BASIC]], and later managed to fit it onto a cartridge as well, but no compiler or runtime was available for redistribution.
 
==Advanced techniques==
Despite its small footprint (8 kilobytes), Atari BASIC has some features that give it some powers of more-advanced, larger versions of BASIC.
 
===Subroutines===
Atari BASIC has no implementation of [[subroutine]]s, or rather, it does not have a concept of [[local variable]]s. In Fortran terminology, all variables are COMMON.
 
But programmers can simulate user functions because of the way the GOSUB command can reference a variable. For example, a programmer could start a subroutine at line 10000 and have the program initialize a variable with that number, e.g. <code>LET TEST = 10000</code>. The calling code can then initialize some mutually understood variables and use the statement <code>GOSUB TEST</code> to invoke the subroutine. The subroutine starting at line <code>TEST</code> can then do its operation on the predetermined variables and put return results into variables available after <code>RETURN</code>.
 
By extension, if the two agree on two variables, an array called, say, <CODE>STACK</CODE> and a numeric variable called <CODE>STACKTOP</CODE>, then a stack can be implemented in software whereby local variables are pushed and popped to the stack and so implement local variables. For example:
 
<pre>
10 DIM STACK(100)
20 STACKTOP = 0
35 REM LINE NUMBERS OF SOME FUNCTIONS FOLLOW
40 FACTORIAL = 8000
60 PUSHSTACK = 2100
70 POPSTACK = 2200
75 REM LET'S COMPUTE EIGHT FACTORIAL
80 LET STACKVALUE = 8: GOSUB PUSHSTACK
90 GOSUB FACTORIAL
100 GOSUB POPSTACK
110 PRINT "EIGHT FACTORIAL IS "; STACKVALUE
120 END
2099 REM PUSHSTACK SUBROUTINE
2100 STACK(STACKTOP) = STACKVALUE: STACKTOP = STACKTOP + 1: RETURN
2199 REM POPSTACK SUBROUTINE
2200 STACKTOP = STACKTOP - 1: STACKVALUE = STACK(STACKTOP): RETURN
7999 REM FACTORIAL SUBROUTINE
8000 GOSUB POPSTACK
8010 IF STACKVALUE <= 2 THEN GOSUB PUSHSTACK: RETURN
8020 FACTORIAL = STACKVALUE
8030 STACKVALUE = STACKVALUE - 1: GOSUB PUSHSTACK
8040 GOSUB POPSTACK: FACTORIAL = FACTORIAL * STACKVALUE
8050 RETURN
</pre>
 
BASIC or FORTRAN aficionados may notice that line 8010 can be optimized because a GOSUB followed by a RETURN is the same as a GOTO, because the subroutine will do the RETURN for us:
 
<pre>8010 IF STACK VALUE <= 2 THEN GOTO PUSHSTACK</pre>
 
This is of course a cute example of why the [[goto|GOTO]] statement is [[Considered Harmful]].
 
===Includes===
Because Atari BASIC can read in lines of code from any device, not just the editor, it is possible to save blocks of code and then read them in and merge them into a single program just as if they had been typed into the editor. Of course this means the lines being read in must have line numbers that are not used in the main program. The code to be merged is written to a device as text using the <code>LIST</code> command, and can be put back into the program with the <code>ENTER</code> command. So the stream of text on the device is, from the BASIC interpreter's point of view, no different from that had it been typed into the editor.
 
By carefully using blocks of line numbers that do not overlap, programmers can build libraries of subroutines (simulating functions as above) and merge them into new programs as needed.
 
===Embedded machine language===
Atari BASIC does not have a built-in assembly language processor. Machine code is generally stored as bytes in strings. Machine code functions are invoked from Atari BASIC with the <code>USR</code> statement, which works in much the same way as <code>GOSUB</code>, but with fewer guarantees.
 
String variables can hold any of the 256 characters available in the [[ATASCII]] character set and thus each byte of memory reserved for a string variable can hold any number from 0 to 255, including the characters 34<sub>10</sub> (22<sub>16</sub>, "quote") and 155<sub>10</sub> (9B<sub>16</sub>, "ENTER"), although these are tricky to type in. Short relocatable 6502 machine language routines can be converted to ATASCII characters and stored in the string variable. The machine language routine can be called as a function with the <code>USR</code> command specifying the address of the string variable as the ___location in memory to execute. For example, if the machine language code is stored in a string named <code>ROUTINE$</code> it can be called with parameters as <code>ANSWER=USR(ADR(ROUTINE$),VAR1,VAR2)</code>. Parameters are pushed onto the hardware stack (in Page 1) as 16-bit integers; variables are pushed as their addresses. The return value is in the A and X registers and interpreted by BASIC as a 16-bit integer; it cannot be pushed to the stack as there is no concept of a [[stack frame]], and for the same reason there is no concept of a void return, but typically if the machine code subroutine does not return anything useful, the value &ndash; just whatever happens to be in those registers at the time &ndash; is just ignored.
 
These routines have to use relocatable machine code: that is to say, they cannot use instructions like <code>JMP</code> or <code>JSR</code> that use absolute addresses, except to well-known addresses in the OS and so forth; they can only use branch instructions such as <code>BCC</code> (branch if carry clear) which jump backwards or forwards by roughly 128<sub>10</sub> (80<sub>16</sub>)<ref>Because the branch amount is one byte in two's complement arithmetic, but the instruction pointer onto which it is applied is already at the next instruction, so actually it can go -128 + 2 = 126 bytes back, or +127 + 2 = 129 bytes forward, from the current instruction, the 2 being the number of bytes the branch instruction takes. That only adds up to 245 places it could go, where did the other 11 go? Well, -2 +2 goes to the branch instruction again and so is an infinite loop; -1 goes to the -1 itself, which is not a valid instruction in the 6502 instruction set; +0 goes to the next instruction, and so is effectively a NOP but takes two cycles rather than 1. The other few small branches, similarly, might jump to an instruction or to part of an address, depending on whether the instructions before or after the branch are one, two or three bytes long.</ref> because the strings could be moved in memory. For this reason page 6 (0600<sub>16</sub>&ndash;06FF<sub>16</sub>), a page of memory not used by BASIC or the operating system, is very popular for storing small routines; but of course one runs the danger that another routine may also wish to be stored there.
 
On the 6502, relocation is not trivial. These days we expect programs to sit pretty much anywhere in memory; the loader and processor collaborate to make that happen. But microprocessors of that era did not do that. The 6502 was especially hindered by having very few indirection instructions, and those it had were asymmetric: the <code>X</code> and <code>Y</code> registers indirect in different directions. This leads either to rather clumsy code that is forever moving stuff between registers, or clever but obtuse code that keeps them where they need to be even if it would seem more obvious to stick something else there. The 6502 instruction set is small enough that, over a short time, programmers can model the entire processor in their heads, even down to knowing how many cycles each instruction takes, and then start making clever tricks.
 
As well as using machine code for advanced functions, fairly trivial <code>USR</code> routines are sometimes used simply to gain access to functions in the Atari OS that have not been provided through Atari BASIC: for example block serialization to and from devices (Atari BASIC only lets it be done byte by byte, with <code>GET</code> and <code>PUT</code>, which takes far longer for just shuffling back and forth through the OS layers than actually writing the one byte of data), or for reading and writing blocks of memory (the <code>PEEK</code> and <code>POKE</code> commands were also unnecessarily slow because of the numeric problems described above).
 
Machine code can also be stored as numbers in <code>DATA</code> statements, but this is pathological in that a byte is then stored as a six-byte floating point number, plus several other overheads, simply to be placed somewhere else as a byte. This method is sometimes used for very short routines where size isn't important but ease of use is (no special loaders or clever typing routines are required), or for one-off programs that then write out the resulting block of bytes (probably stored in a string) is written out as a program that can be read in later byte-for-byte.
 
==Atari BASIC keywords==
{| style="border: 1px solid darkgray;"
| style="font-weight:bold; text-align:right" | ABS || align="left" | Returns the [[absolute value]] of a number
|-
| style="font-weight:bold; text-align:right" | ADR || align="left" | Returns the address in memory of a variable (mostly used for machine code routines stored in variables)
|-
| style="font-weight:bold; text-align:right" | AND || align="left" | [[Logical conjunction]]
|-
| style="font-weight:bold; text-align:right" | ASC || align="left" | Returns the [[ATASCII]] value of a character
|-
| style="font-weight:bold; text-align:right" | ATN || align="left" | Returns the [[arctangent]] of a number
|-
| style="font-weight:bold; text-align:right" | BYE || align="left" | Transfers control to the internal "Self Test" program ("Memo Pad" on early models)
|-
| style="font-weight:bold; text-align:right" | CHR$ || align="left" | Returns a character given an [[ATASCII]] value
|-
| style="font-weight:bold; text-align:right" | CLOAD || align="left" | Loads from [[Compact Cassette|cassette tape]] a [[tokenization|tokenized]] program that was saved with CSAVE
|-
| style="font-weight:bold; text-align:right" | CLOG || align="left" | Returns the [[common logarithm]] of a number
|-
| style="font-weight:bold; text-align:right" | CLOSE || align="left" | Terminates pending transfers (flush) and closes an I/O channel
|-
| style="font-weight:bold; text-align:right" | CLR || align="left" | Clears variables' memory and program stack
|-
| style="font-weight:bold; text-align:right" | COLOR || align="left" | Chooses which logical color to draw in
|-
| style="font-weight:bold; text-align:right" | COM || align="left" | Implementation of MS Basic's COMMON was cancelled. Recognized but the code for DIM is executed instead
|-
| style="font-weight:bold; text-align:right" | CONT || align="left" | Resumes execution of a program after a STOP at the next line number (see STOP)
|-
| style="font-weight:bold; text-align:right" | COS || align="left" | Returns the [[cosine]] of a number
|-
| style="font-weight:bold; text-align:right" | CSAVE || align="left" | Saves to [[Compact Cassette|cassette tape]] a program in [[tokenization|tokenized]] form with fast method (short inter-record gap on tape) (see CLOAD)
|-
| style="font-weight:bold; text-align:right" | DATA || align="left" | Stores data in lists of numeric or string values
|-
| style="font-weight:bold; text-align:right" | DEG || align="left" | Switches trigonometric functions to compute in [[degree (angle)|degrees]] ([[radian]]s is the default mode) (see RAD)
|-
| style="font-weight:bold; text-align:right" | DIM || align="left" | Defines the size of a string or array (see COM)
|-
| style="font-weight:bold; text-align:right" | DOS || align="left" | Transfers control to the Disk Operating System (DOS); if DOS was not loaded, same as BYE
|-
| style="font-weight:bold; text-align:right" | DRAWTO || align="left" | Draws a line to given [[Cartesian coordinate system|coordinates]]
|-
| style="font-weight:bold; text-align:right" | END || align="left" | Finishes execution of the program, closes open I/O channels and stops any sound
|-
| style="font-weight:bold; text-align:right" | ENTER || align="left" | Loads and merges into memory a plain text program from an external device, usually from [[Compact Cassette|cassette tape]] or disk (see LIST)
|-
| style="font-weight:bold; text-align:right" | EXP || align="left" | [[Exponential function]]
|-
| style="font-weight:bold; text-align:right" | FOR || align="left" | Starts a [[for loop]]
|-
| style="font-weight:bold; text-align:right" | FRE || align="left" | Returns the amount of free memory in bytes
|-
| style="font-weight:bold; text-align:right" | GET || align="left" | Reads one byte from an I/O channel (see PUT)
|-
| style="font-weight:bold; text-align:right" | [[GOSUB]] || align="left" | Jumps to a subroutine at a given line in the program, placing the return address on the stack (see POP and RETURN)
|-
| style="font-weight:bold; text-align:right" | [[GOTO]] and GO TO || align="left" | Jumps to a given line in the program. GOTO can be omitted in "IF ... THEN GOTO ..."
|-
| style="font-weight:bold; text-align:right" | GRAPHICS || align="left" | Sets the graphics mode
|-
| style="font-weight:bold; text-align:right" | IF || align="left" | Executes code depending on whether a condition is true or not
|-
| style="font-weight:bold; text-align:right" | INPUT || align="left" | Retrieves a stream of text from an I/O channel; usually data from keyboard (default), [[Compact Cassette|cassette tape]] or disk
|-
| style="font-weight:bold; text-align:right" | INT || align="left" | Returns the [[floor function|floor]] of a number
|-
| style="font-weight:bold; text-align:right" | LEN || align="left" | Returns the length of a string
|-
| style="font-weight:bold; text-align:right" | LET || align="left" | Assigns a value to a variable. LET can be omitted
|-
| style="font-weight:bold; text-align:right" | LIST || align="left" | Lists (all or part of) the program to screen (default), printer, disk, [[Compact Cassette|cassette tape]], or any other external device (see ENTER)
|-
| style="font-weight:bold; text-align:right" | LOAD || align="left" | Loads a [[tokenization|tokenized]] program from an external device; usually a [[Compact Cassette|cassette tape]] or disk (see SAVE)
|-
| style="font-weight:bold; text-align:right" | LOCATE || align="left" | Stores the logical color or [[ATASCII]] character at given coordinates
|-
| style="font-weight:bold; text-align:right" | LOG || align="left" | Returns the [[natural logarithm]] of a number
|-
| style="font-weight:bold; text-align:right" | LPRINT || align="left" | Prints text to a printer device (same result can be achieved with OPEN, PRINT and CLOSE statements)
|-
| style="font-weight:bold; text-align:right" | NEW || align="left" | Erases the program and all the variables from memory; automatically executed before a LOAD or CLOAD
|-
| style="font-weight:bold; text-align:right" | NEXT || align="left" | Continues the next iteration of a FOR loop
|-
| style="font-weight:bold; text-align:right" | NOT || align="left" | [[Negation|Logical negation]]
|-
| style="font-weight:bold; text-align:right" | NOTE || align="left" | Returns the current position on an I/O channel
|-
| style="font-weight:bold; text-align:right" | ON || align="left" | A [[computed goto]] - performs a jump based on the value of an expression
|-
| style="font-weight:bold; text-align:right" | OPEN || align="left" | Initialises an I/O channel
|-
| style="font-weight:bold; text-align:right" | OR || align="left" | [[Logical disjunction]]
|-
| style="font-weight:bold; text-align:right" | PADDLE || align="left" | Returns the position of a [[paddle (game controller)|paddle controller]]
|-
| style="font-weight:bold; text-align:right" | [[PEEK and POKE|PEEK]] || align="left" | Returns the value at an address in memory
|-
| style="font-weight:bold; text-align:right" | PLOT || align="left" | Draws a point at given coordinates
|-
| style="font-weight:bold; text-align:right" | POINT || align="left" | Sets the current position on an I/O channel
|-
| style="font-weight:bold; text-align:right" | [[PEEK and POKE|POKE]] || align="left" | Sets a value at an address in memory
|-
| style="font-weight:bold; text-align:right" | POP || align="left" | Removes a subroutine return address from the stack (see GOSUB and RETURN)
|-
| style="font-weight:bold; text-align:right" | POSITION || align="left" | Sets the position of the graphics cursor
|-
| style="font-weight:bold; text-align:right" | PRINT and ? || align="left" | Writes text to an I/O channel; usually to screen (default), printer, [[Compact Cassette|cassette tape]] or disk (see LPRINT and INPUT)
|-
| style="font-weight:bold; text-align:right" | PTRIG || align="left" | Indicates whether a paddle trigger is pressed or not
|-
| style="font-weight:bold; text-align:right" | PUT || align="left" | Writes one byte to an I/O channel (see GET)
|-
| style="font-weight:bold; text-align:right" | RAD || align="left" | Switches trigonometric functions to compute in [[radian]]s (see DEG)
|-
| style="font-weight:bold; text-align:right" | READ || align="left" | Reads data from a DATA statement
|-
| style="font-weight:bold; text-align:right" | REM || align="left" | Marks a comment in a program
|-
| style="font-weight:bold; text-align:right" | RESTORE || align="left" | Sets the position of where to read data from a DATA statement
|-
| style="font-weight:bold; text-align:right" | RETURN || align="left" | Ends a subroutine, effectively branching to the line immediately following the "calling" GOSUB (see GOSUB and POP)
|-
| style="font-weight:bold; text-align:right" | RND || align="left" | Returns a [[pseudorandom number generator|pseudorandom number]]
|-
| style="font-weight:bold; text-align:right" | RUN || align="left" | Starts execution of a program, optionally loading it from an external device (see LOAD)
|-
| style="font-weight:bold; text-align:right" | SAVE || align="left" | Writes a [[tokenization|tokenized]] program to an external device; usually a [[Compact Cassette|cassette tape]] or disk (see LOAD)
|-
| style="font-weight:bold; text-align:right" | SETCOLOR || align="left" | Maps a logical color to a physical color
|-
| style="font-weight:bold; text-align:right" | SGN || align="left" | Returns the [[signum function|signum]] of a number
|-
| style="font-weight:bold; text-align:right" | SIN || align="left" | Returns the [[sine]] of a number
|-
| style="font-weight:bold; text-align:right" | SOUND || align="left" | Starts or stops playing a tone on a sound channel (see END)
|-
| style="font-weight:bold; text-align:right" | SQR || align="left" | Returns the [[square root]] of a number
|-
| style="font-weight:bold; text-align:right" | STATUS || align="left" | Returns the status of an I/O channel
|-
| style="font-weight:bold; text-align:right" | STEP || align="left" | Indicates the increment used in a FOR loop
|-
| style="font-weight:bold; text-align:right" | STICK || align="left" | Returns a joystick position
|-
| style="font-weight:bold; text-align:right" | STOP || align="left" | Stops the program, allowing later resumption (see CONT)
|-
| style="font-weight:bold; text-align:right" | STRIG || align="left" | Indicates whether a joystick trigger is pressed or not
|-
| style="font-weight:bold; text-align:right" | STR$ || align="left" | Converts a number to string form
|-
| style="font-weight:bold; text-align:right" | THEN || align="left" | Indicates the statements to execute if the condition is true in an IF statement
|-
| style="font-weight:bold; text-align:right" | TO || align="left" | Indicates the limiting condition in a FOR statement
|-
| style="font-weight:bold; text-align:right" | TRAP || align="left" | Sets to jump to a given program line if an error occurs (TRAP 40000 cancels this order)
|-
| style="font-weight:bold; text-align:right" | USR || align="left" | Calls a machine code routine, optionally with parameters
|-
| style="font-weight:bold; text-align:right" | VAL || align="left" | Returns the numeric value of a string
|-
| style="font-weight:bold; text-align:right" | XIO || align="left" | General-purpose I/O routine (from "Fill screen" to "Rename file" to "Format disk" instructions)
|}
 
==Running without Atari BASIC==
On the XL/XE models, Atari BASIC could be disabled by holding down the '''OPTION''' key while booting the computer. The XEGS would disable BASIC if powered without the keyboard attached.
 
If another cartridge were inserted it may also disable Atari BASIC, if they used the same address space.
 
==See also==
*[[BASIC A Plus programming language|BASIC A+]] &ndash; An extended BASIC for the Atari, from ''[[Optimized Systems Software]] (OSS)'' <!-- the same company that made Atari BASIC --><!--
*[[Turbo-Basic XL]] - Freeware BASIC compatible with Atari BASIC, also available with a compiler for greater speed and extra commands.
 
==References==
*{{citation|title=The ATARI BASIC Reference Manual|publisher=Atari Inc|year=1980|url=http://www.strotmann.de/twiki/bin/view/Infothek/AtBasicReferenceMa |archiveurl=http://web.archive.org/web/20050501034651/http://www.strotmann.de/twiki/bin/view/Infothek/AtBasicReferenceMa |archivedate=May 1, 2005}}
*{{citation|last=Wilkinson|first=Bill|title=The Atari BASIC Source Book|publisher=COMPUTE! Books|year=1983|isbn=0-942386-15-9|url=http://users.telenet.be/kim1-6502/6502/absb.html|publisher=Optimized Systems Software,Inc.|accessdate=2009-04-04}}
*{{citation|last=Wilkinson|first=Bill|title=Inside Atari DOS|publisher=COMPUTE! Books|year=1982|isbn=0-942386-02-7|url=http://www.atariarchives.org/iad/introduction.php|publisher=Optimized Systems Software,Inc.|accessdate=2009-04-04}}
*{{citation|url=http://www.atariarchives.org/dere/chapt10.php|title=De Re Atari|chapter=10: ATARI BASIC|publisher=AtariArchives.org|accessdate=2009-04-04}} &ndash; A detailed description of the dialect and interpreter
 
== Notes ==
{{Reflist}}
 
== External links ==
<!-- note that Atari BASIC (all caps both for 'Atari' and 'Basic' is the correct name, &mdash; even though this is not reflected by two of the references below. &mdash; wernher --><!--
*[http://web.archive.org/web/20070524044410/http://www3.sympatico.ca/maury/other_stuff/atari_basic.html Atari BASIC, The Good, the Bad, and the Ugly]
*{{citation |url=http://www.atariarchives.org/basic/ Atari Basic - A Self-Teaching Guide|first1=Bob|last1=Albrecht|first2=LeRoy|last2=Finkel|first3=Jerald R.|last3=Brown|year=1979}}
*{{citation |url=http://www.atariarchives.org/basicxl/ Atari Basic - XL Edition|]|first1=Bob|last1=Albrecht|first2=LeRoy|last2=Finkel|first3=Jerald R.|last3=Brown|year=1985}}
*[http://emulators.com/xformer.htm XFormer, a free Atari Emulator which needs no ROMs or other items]
*[http://www.atariarchives.org/dere/ De Re Atari] by Chris Crawford
-->
==Note==
<references/>
 
==Bibliografia==
*{{cita libro|autore=|titolo=Atari 400-800 - Manuale di riferimento del linguaggio Basic per l'elaboratore personale Atari|editore=Atari|anno=1982|url=https://archive.org/details/atari400800manualediriferimentodellinguaggiobasic}}
*{{cita libro|autore=|titolo=Atari BASIC - Manuale d'uso|editore=Atari|anno=1983|ISBN=|url=https://archive.org/details/ataribasicmultilingualmanual/page/n33}}
*{{cita libro|autore=Bill Carris|titolo=Basic Atari|editore=Gruppo Editoriale Jackson|anno=1985|ISBN=|url=https://archive.org/details/basicatari}}
*{{cita libro|autore=Gary Ryan, Cliff McConnell|titolo=Altri giochi per il vostro Atari|editore=Gremese Editore|anno=1985|ISBN=88-7605-153-8|url=https://archive.org/details/altrigiochiperilvostroatari}}
* {{cita libro|autore=Bill Wilkinson|titolo=The Atari BASIC Source Book|editore=COMPUTE! Books|anno=1983|isbn=0-942386-15-9|url=http://users.telenet.be/kim1-6502/6502/absb.html|accesso=5 agosto 2012|dataarchivio=26 luglio 2012|urlarchivio=https://web.archive.org/web/20120726155045/http://users.telenet.be/kim1-6502/6502/absb.html|urlmorto=sì}}
* {{cita libro|autore=Bill Wilkinson|titolo=Inside Atari DOS|editore=COMPUTE! Books|anno=1982|isbn=0-942386-02-7|url=http://www.atariarchives.org/iad/introduction.php|accesso=5 agosto 2012}}
* {{cita libro|url=http://www.atariarchives.org/dere/chapt10.php|titolo=De Re Atari|capitolo=10: ATARI BASIC|autore=Chris Crawford et al.|accesso=5 agosto 2012|anno=1982}}
* {{cita libro|url=http://www.atariarchives.org/basic/|titolo=Atari Basic - A Self-Teaching Guide|autore=Bob Albrecht|coautori=LeRoy Finkel, Jerald R. Brown|anno=1979|editore=Wiley Microcomputer Guides|accesso=5 agosto 2012}}
* {{cita libro|url=http://www.atariarchives.org/basicxl/|titolo=Atari Basic - XL Edition|autore=Bob Albrecht|coautori=LeRoy Finkel, Jerald R. Brown|anno=1985|accesso=5 agosto 2012}}
 
==Voci correlate==
* [[Atari Microsoft BASIC]]
* [[BASIC]]
 
== Collegamenti esterni ==
[[Categoria:BASIC]]
* {{cita web|http://emulators.com/xformer.htm|XFormer, un emulatore Atari per MS-DOS e Windows}}
[[Categoria:Linguaggi di programmazione]]
* [http://www.atariarchives.org/dere/ De Re Atari], un manuale sui computer Atari
 
{{Atari}}
{{portale|informatica}}
 
[[caCategoria:Atari BASIC]]
[[de:Atari BASIC]]
[[en:Atari BASIC]]
[[es:Atari BASIC]]
[[pl:Atari BASIC]]
[[pt:Atari BASIC]]