Príručka jazyka BASIC pre 8-bitové počítače Atari, písaná pre ľudí, ktorí s Atari ani s BASICom nikdy nerobili a programujú málo alebo vôbec. Programy sa píšu na dnešnom počítači s Windows, preloží ich prekladač Basic26 a bežia na Atari alebo v jeho emulátore.
Každá kapitola vysvetlí jeden príkaz alebo jednu tému a obsahuje celý program, ktorý si môžeš hneď preložiť a spustiť. Všetky programy sú aj hotové v priečinku examples/.
Kniha má tri časti:
Atari BASIC (kapitoly 1 až 25) – jazyk, ktorý malo každé Atari XL a XE v sebe. Všetko z tejto časti platí aj v Turbo-BASICu XL.
Turbo-BASIC XL (kapitoly 26 až 38) – rozšírený BASIC Franka Ostrowského z roku 1985: slučky bez GOTO, procedúry, kruhy, vypĺňanie plôch a ďalšie.
Basic26 (kapitoly 39 až 50) – čo vie prekladač navyše: voľby, diskety, pribalené súbory, pamäť ukrytá pod operačným systémom a v rozšíreniach, kompresia, program bez čísel riadkov, nečitateľný súbor, hráči a strely, rýchle celé čísla.
Čítaj od začiatku. Kapitoly sú krátke a každá stavia na predošlých. Program z kapitoly si prelož, spusti a potom v ňom niečo zmeň – časť Vyskúšaj si na konci kapitoly dáva nápady.
Atari 800XL a 130XE sú domáce počítače z osemdesiatych rokov. Majú procesor 6502, 64 alebo 128 kilobajtov pamäte a pripájali sa k televízoru. Po zapnutí na nich nebeží žiadny Windows – počítač čaká, kým mu napíšeš program alebo mu ho dáš z kazety, z diskety či zo zásuvného modulu (cartridge).
Dnes tie počítače stále fungujú a kto ich nemá, používa emulátor: program, ktorý sa na dnešnom počítači správa ako Atari.
BASIC je programovací jazyk vymyslený pre začiatočníkov. Program v ňom sa číta skoro ako anglické vety:
ZX-Basic
10PRINT"Hello, Atari!"20GOTO10
Atari XL a XE majú BASIC zabudovaný – volá sa Atari BASIC. Zapneš počítač, na obrazovke sa objaví READY a môžeš písať. Tisíce programov a hier z časopisov tých čias sú napísané v ňom.
BASIC na Atari je interpreter: program číta riadok po riadku a každý riadok zakaždým znova lúšti. Je to pohodlné, ale pomalé.
V roku 1985 napísal Frank Ostrowski Turbo-BASIC XL. Rozumie všetkému, čo Atari BASIC, je niekoľkokrát rýchlejší a pridáva desiatky príkazov: slučky WHILE a REPEAT, procedúry, kreslenie kruhov, vypĺňanie plôch. Nahrával sa z diskety.
Prvé dve tretiny tejto knihy vystačia s Atari BASICom. Turbo-BASIC XL príde na rad v kapitole 26.
Basic26 je prekladač oboch jazykov, ktorý beží na počítači s Windows.
Program píšeš v ľubovoľnom textovom editore (Poznámkový blok, Visual Studio Code, Sublime Text …).
Basic26 ho preloží za zlomok sekundy.
Výsledok je súbor, ktorý sa dá spustiť na Atari alebo v emulátore – bez BASICu, bez Turbo-BASICu, sám.
Preložený program robí to isté, čo by s tým istým textom robil interpreter: vypíše tie isté čísla, nakreslí tie isté obrázky, ohlási tie isté chyby. Len beží rýchlejšie. Prekladač vie prečítať aj staré programy z diskiet (kapitola 41).
Súbor Basic26.exe. Je to jeden súbor, nič sa neinštaluje. Skopíruj si ho do priečinka, kde budeš mať svoje programy, alebo do priečinka, ktorý máš v systémovej ceste (PATH) – potom ho môžeš volať odkiaľkoľvek.
Súbor ATARIXL.ROM v priečinku atari800 vedľa Basic26.exe. Je to kópia programov, ktoré má Atari v sebe; simulátor z nej berie počítanie s číslami. Keď ho nemáš, vezme altirraos-xl.rom, ktorý je pri Basic26.exe – voľne šíriteľnú náhradu od autora emulátora Altirra; počíta takmer rovnako, len niekedy sa líši v poslednej číslici, a prekladač ťa na to upozorní.
Textový editor. Stačí Poznámkový blok. Pohodlnejší je editor, ktorý ukazuje čísla riadkov a stĺpcov, lebo prekladač nimi hlási chyby.
Príkazový riadok – okno, do ktorého sa píšu príkazy. Vo Windows je to Terminál alebo PowerShell (nájdeš ho v ponuke Štart).
Na kapitoly o grafike, zvuku a joysticku navyše:
Emulátor atari800 (atari800.exe) v tom istom priečinku atari800. Do kapitoly 19 sa bez neho zaobídeš.
Basic26 1.0.0.150
Atari BASIC and Turbo-BASIC XL cross compiler for Atari 8-bit (XEX)
Copyright (C) 2026 Pedro. MIT License.
Built from main 00f00945163050e23e1f460beedab775a5ecf909
Ak namiesto toho príde hlásenie, že príkaz Basic26 nie je známy, príkazový riadok nevie, kde Basic26.exe leží. Najjednoduchšia náprava: prejdi v príkazovom riadku do priečinka, kde ten súbor máš, a píš .\Basic26 namiesto Basic26.
Prejdeš celú cestu od prázdneho súboru po bežiaci program: napísať, uložiť, preložiť, spustiť. Všetky ďalšie kapitoly robia to isté, len s inými príkazmi.
Na skutočnom Atari sa program písal rovno do počítača a riadok sa nedal „vsunúť“ medzi dva iné – jeho miesto určovalo číslo. Preto sa čísluje po desiatich: keď neskôr zistíš, že medzi riadky 10 a 20 treba ešte niečo, dáš tomu číslo 15.
V textovom editore riadok vsunieš, kam chceš, ale číslo mu dať musíš aj tak – a prekladač riadky zoradí podľa čísel, nie podľa poradia v súbore. Číslo môže byť od 0 do 32767.
Po preklade pribudol vedľa zdrojáka súbor hello.xex. To je hotový program pre Atari – má 1005 bajtov. Dá sa skopírovať na disketu alebo spustiť v emulátore.
Keď chceš program len preložiť a nespúšťať, voľbu --sim vynechaj:
Bash
Basic26hello.abas
Keď sa preklad podarí, prekladač nevypíše nič. Ticho znamená „v poriadku“.
Simulátor ukáže len to, čo program vypíše. Emulátor ukáže celé Atari – modrú obrazovku, písmo, farby. Ak ho máš (priečinok atari800 vedľa Basic26.exe), spustíš program takto:
Bash
Basic26hello.abas--run
Otvorí sa okno emulátora a v ňom tvoj text. Keď program skončí, obrazovka ostane tak, ako ju nechal; emulátor zavrieš klávesom F9 alebo krížikom okna.
Chyby sú pri programovaní bežné. Skús úmyselne jednu spraviť: namiesto PRINT napíš PRIT.
ZX-Basic
10REM My first program in BASIC20 PRIT "Hello, Atari!"
Prekladač odpovie:
hello.abas(2,9): error B26017: expected '=' after a string
Každé hlásenie má štyri časti:
Časť
V príklade
Čo znamená
súbor
hello.abas
v ktorom súbore je chyba
miesto
(2,9)
druhý riadok súboru, deviaty znak (nie číslo riadka programu!)
druh a číslo
error B26017
error je chyba, warning len upozornenie; číslo sa dá nájsť v prílohe C
popis
expected '=' after a string
čo prekladaču vadí (po anglicky)
Popis tu na prvý pohľad nesedí – veď chýba písmeno, nie rovná sa. Prekladač však slovo PRIT nepozná, a tak si myslí, že je to meno premennej, do ktorej chceš niečo uložiť (o tom je kapitola 4); za takým menom čaká znak =. Z toho plynú dve rady:
Opravuj vždy prvú chybu. Ďalšie sú často len jej následkom.
Chyba je na označenom mieste alebo tesne pred ním. Prekladač si ju všimne, až keď mu prestane dávať zmysel to, čo číta.
Kým má program chybu (error), súbor .xex nevznikne a nič sa nespustí. Upozornenie (warning) preklad nezastaví.
error B26017: Atari BASIC takes no lower case in "print"
chýba úvodzovka na konci textu
warning B26048: missing double quote in string – len upozornenie, text sa berie do konca riadka
súbor sa volá inak, ako píšeš v príkaze
error B26201: hello.abas: file not found
Príkazy Atari BASICu sa píšu veľkými písmenami. Malé písmená smú byť len v texte v úvodzovkách a za REM. Turbo-BASIC XL malé písmená berie (kapitola 26).
PRINT je najpoužívanejší príkaz BASICu: vypíše na obrazovku text, číslo alebo výsledok výpočtu. V tejto kapitole k nemu pribudnú tri drobnosti, bez ktorých sa žiadny program nezaobíde: komentár REM, dvojbodka medzi príkazmi a END.
10REM PRINT: writing on the screen20PRINT"One line"30PRINT"Two ";"parts ";"joined"40PRINT"Left","Right"50PRINT560PRINT"Five plus three is ";5+370PRINT80PRINT"No new line: ";
90PRINT"it goes on here"100 ? "A question mark is PRINT too"110PRINT"One":PRINT"Two":REM two statements on a line120 END
130PRINT"Never printed"
Riadok 30: bodkočiarka lepí veci tesne za seba. Medzery medzi slovami sú preto vo vnútri úvodzoviek ("Two "), BASIC žiadne nepridá.
Riadok 40: čiarka posunie výpis na ďalšiu zarážku. Zarážky sú po desiatich znakoch, takže Right sa začína na jedenástom mieste. Hodí sa to na jednoduché tabuľky.
Riadok 50: číslo sa píše bez úvodzoviek. PRINT 5 vypíše číslo 5, PRINT "5" vypíše znak 5 – na obrazovke vyzerajú rovnako, ale len s prvým sa dá počítať.
Riadok 60: text a výpočet v jednom príkaze. BASIC najprv vypočíta 5+3 a vypíše výsledok.
Riadky 80 a 90: bodkočiarka na konci drží kurzor na riadku, ďalší PRINT pokračuje tam, kde prvý skončil.
Riadok 110: tri príkazy na jednom riadku. Za REM je však komentárom všetko až do konca riadka, aj dvojbodka a čokoľvek za ňou – REM teda musí byť na riadku posledný.
Riadok 120:END program ukončí. Riadok 130 sa už nevykoná. Na konci programu END písať nemusíš; hodí sa, keď za hlavnou časťou programu nasleduje ešte niečo, kam program nemá „dobehnúť“ (kapitola 11).
Premenná je pomenované miesto v pamäti, do ktorého si program odloží číslo, aby ho mohol neskôr použiť alebo zmeniť. Predstav si škatuľku s menovkou: APPLES a v nej číslo 5.
10REM Variables: boxes with a name20LETAPPLES=530 PRICE=0.2540PRINT"Apples: ";APPLES
50PRINT"Price of one: ";PRICE
60 COST=APPLES*PRICE
70PRINT"Together: ";COST
80 APPLES=APPLES+190PRINT"One more apple: ";APPLES
100 BIG=1500000000000110PRINT BIG
120 THIRD=1/3130PRINT THIRD
140PRINT EMPTY
Riadky 20 a 30: to isté dvoma spôsobmi, s LET a bez neho. Desatinné číslo sa píše s bodkou, nie s čiarkou.
Riadok 60: vpravo je výpočet. BASIC vezme, čo je práve v APPLES a PRICE, vynásobí to (* je krát) a výsledok uloží do COST.
Riadok 80:APPLES=APPLES+1 nie je rovnica – tá by nemala riešenie. Je to príkaz: „zober, čo je v APPLES, pripočítaj 1 a ulož späť do APPLES“. Takto sa v programoch počíta.
Riadok 110: veľmi veľké a veľmi malé čísla vypisuje BASIC skrátene. 1.5E+12 znamená 1,5 krát desať na dvanástu, teda 1,5 a dvanásť miest doprava. Rovnako ich môžeš aj písať: BIG=1.5E12.
Riadok 130: jedna tretina má nekonečne veľa trojok, ale Atari si pamätá len desať číslic (a Atari BASIC ich vypíše deväť). Na bežné počítanie to stačí; pri peniazoch a dlhých výpočtoch sa občas na poslednom mieste objaví drobná odchýlka.
Riadok 140: do EMPTY nikto nič neuložil, je v nej nula.
Čísla môžu byť od približne 1E-98 po 9.99999999E+97, kladné aj záporné.
Meno môže byť dlhé, ale nesmie sa začínať slovom, ktoré BASIC pozná ako príkaz. Atari BASIC totiž medzery nepotrebuje – PRINTX číta ako PRINT X. Preto:
ZX-Basic
10 LETTER=420PRINT LETTER
vypíše 0. Riadok 10 sa prečíta ako LET TER=4, takže štvorka skončí v premennej TER, a riadok 20 vypíše inú, prázdnu premennú LETTER. Program je správny, len robí niečo iné, než si chcel. Prekladač na to upozorní, lebo meno LETTER program inde používa:
warning B26236: LETTER is read as LET TER here, as the interpreter reads it: a statement begins with the statement word its text begins with, and LETTER elsewhere in the program is another variable
Väčšinou sa však na také meno príde hneď, lebo zvyšok riadka prestane dávať zmysel:
Riadok
Ako ho BASIC číta
Čo povie prekladač
10 ONE=1
ON E=1
error B26017: expected GOTO, GOSUB, EXEC or GO# after ON
10 FORM=7
FOR M=7
error B26017: expected TO in FOR
10 IFFY=2
IF FY=2
error B26043: expected THEN
10 ENDING=5
END ING=5
error B26017: expected ':' or end of line, found variable ING
10 NOTE=5
príkaz NOTE
error B26017: expected #channel
Meno sa teda nesmie začínať slovom, ktorým sa môže začínať príkaz (LET, ON, FOR, IF, END, REM, DIM, RUN, GET, PUT, POP, NEW, DOS, BYE … – všetky sú v prílohe A). Uprostred mena slovo nevadí (COST, SCORE, TOTAL sú v poriadku).
Zvláštny prípad je slovo NOT (kapitola 8). Na začiatku príkazu sa meno s NOT na začiatku berie ako meno, ale vo výpočte ho BASIC rozdelí:
ZX-Basic
10 NOTHING=520PRINT NOTHING
vypíše 1. Riadok 10 uloží päťku do premennej NOTHING; riadok 20 sa však číta ako PRINT NOT HING – „opak“ prázdnej premennej HING, teda 1. K svojej päťke sa už nedostaneš. Tak to robia oba interpretery a tak to preloží aj Basic26, s upozornením:
warning B26230: NOTHING is read as NOT HING here, as the interpreter reads it: a name that begins with NOT is one only where a value is stored
Keď program počíta čudne, podozrievaj najprv meno.
Dobové programy mávajú premenné s jedným-dvoma písmenami (A, X1, SC). Šetrilo to pamäť. V programe pre prekladač si pokojne dovoľ meno, ktoré niečo hovorí.
Riadok 70 dá 14, nie 20: BASIC počíta ako v škole, násobenie a delenie pred sčítaním a odčítaním. Celé poradie:
zátvorky,
umocnenie ^,
násobenie a delenie * /,
sčítanie a odčítanie + -.
Rovnako silné znamienka sa počítajú zľava doprava: 10/4*2 je (10/4)*2, teda 5. Keď si nie si istý, daj zátvorky – nič nestoja a program je čitateľnejší.
INT(2.7) je 2, ale INT(-2.5) je -3: najbližšie celé číslo, ktoré je menšie. Pri kladných číslach je to to isté ako „odrezať desatinnú časť“, pri záporných nie.
Zvyšok po delení (riadok 160): A-INT(A/B)*B. Sedemnásť delené piatimi je 3 a zvyšok 2. Zvyškom sa zisťuje, či je číslo párne (N-INT(N/2)*2 je 0), a robí sa ním všetko, čo sa má „točiť dokola“.
Zaokrúhlenie (riadok 190): INT(X+0.5) zaokrúhli na celé číslo. Na dve desatinné miesta sa číslo najprv vynásobí stomi, zaokrúhli a zasa vydelí.
BASIC to neuhádne: vypíše 27 – dvojku a za ňou sedmičku
-3^2
je 9, nie -9: mínus pred číslom má v BASICu prednosť pred umocnením. Píš -(3^2)
ERROR- s číslom je chyba za behu: program sa preložil, ale počas behu narazil na niečo, čo sa vypočítať nedá. Vypíše číslo chyby a riadok programu, na ktorom sa stala, a skončí. Čísla sú v prílohe C; kapitola 17 ukáže, ako chybu zachytiť.
priprav reťazec A$, do ktorého sa zmestí najviac 20 znakov
A$="text"
ulož text
LEN(A$)
funkcia: koľko znakov v reťazci práve je
A$(3)
časť reťazca od tretieho znaku do konca
A$(2,4)
časť od druhého po štvrtý znak
A$(2,2)
jeden znak, druhý
A$(LEN(A$)+1)=B$
pripoj B$ na koniec A$
Na rozdiel od čísla treba reťazec vopred ohlásiť príkazom DIM (z anglického dimension, rozmer). Počítač mu musí vyhradiť miesto a potrebuje vedieť koľko. Jeden DIM môže ohlásiť viac reťazcov, oddelených čiarkou.
10REM Strings: variables that hold text20DIMNAME$(20),GREETING$(40)
30NAME$="Atari"40PRINTNAME$50PRINT"Length: ";LEN(NAME$)
60PRINT"First letter: ";NAME$(1,1)
70PRINT"Letters 2 to 4: ";NAME$(2,4)
80PRINT"From the 3rd on: ";NAME$(3)
90GREETING$="Hello, "100GREETING$(LEN(GREETING$)+1)=NAME$110PRINTGREETING$120NAME$(1,1)="a"130PRINTNAME$140DIMSHORT$(3)
150SHORT$="ABCDEFGH"160PRINTSHORT$
Riadok 20:NAME$ má miesto na 20 znakov, GREETING$ na 40. To je najviac; koľko znakov v reťazci naozaj je, závisí od toho, čo doň uložíš. Hneď po DIM je prázdny a LEN je 0.
Riadok 50: v NAME$ je päť znakov, hoci miesta je na dvadsať.
Riadky 60 až 80: znaky sa číslujú od jednotky. NAME$(2,4) je druhý až štvrtý znak. S jedným číslom ide časť až do konca.
Riadok 100: Atari BASIC nemá znamienko na spájanie textov. Spája sa tak, že druhý text zapíšeš za koniec prvého: GREETING$ má 7 znakov, zápis začína na ôsmom mieste.
Riadok 120: zápis do časti reťazca prepíše len tú časť – tu prvé písmeno.
Riadky 140 až 160: do reťazca sa zmestí len toľko, koľko povolil DIM. Zvyšok sa bez hlásenia odreže: z ôsmich písmen ostali tri.
Doteraz boli všetky čísla a texty napísané v programe. S INPUT sa program spýta – počká, kým človek niečo napíše a stlačí RETURN, a to, čo napísal, uloží do premennej.
10REM INPUT: the program asks20DIMNAME$(20)
30PRINT"What is your name";
40INPUTNAME$50PRINT"How old are you";
60INPUT AGE
70PRINT"Hello, ";NAME$;"!"80PRINT"Next year you will be ";AGE+190PRINT"Give me two numbers"100INPUT A,B
110PRINT A;" + ";B;" = ";A+B
Riadky 30 a 40:PRINT s bodkočiarkou na konci nechá kurzor za textom, INPUT zaň pripíše otáznik a čaká. Preto v texte otázky otáznik nie je.
Riadok 40: do NAME$ sa uloží celý riadok, ktorý človek napísal – aj s medzerami a čiarkami. Ak je dlhší než DIM, odreže sa.
Riadok 60:AGE je číselná premenná, takže INPUT čaká číslo. S číslom z klávesnice sa dá hneď počítať (riadok 80).
Riadok 100: dve premenné v jednom INPUT. Človek napíše 3,4 a RETURN; môže však napísať aj len 3, stlačiť RETURN, a program sa na druhé číslo spýta ďalším otáznikom.
10REM IF: deciding20DIMANSWER$(10)
30PRINT"How old are you";
40INPUT AGE
50IFAGE<0THENPRINT"That cannot be":END
60IFAGE<18THENPRINT"You are a child"70IFAGE>=18THENPRINT"You are an adult"80IFAGE>=13ANDAGE<=19THENPRINT"You are a teenager"90IFAGE=7ORAGE=77THENPRINT"A lucky number!"100IFNOT(AGE=100) THENPRINT"Not a hundred yet"110PRINT"Do you like BASIC";
120INPUTANSWER$130IFANSWER$="YES"THENPRINT"So do I"140IFANSWER$<>"YES" THENPRINT"You will"150PRINT"13<18 is ";13<18;", 13>18 is ";13>18
Riadok 50: za THEN sú dva príkazy oddelené dvojbodkou. Oba patria k podmienke – keď vek nie je záporný, nevykoná sa ani PRINT, ani END. To je dôležité pravidlo: IF rozhoduje o celom zvyšku riadka.
Riadky 60 a 70: Atari BASIC nemá „inak“ (ELSE). Opačný prípad sa napíše ako druhý IF s opačnou podmienkou. (Turbo-BASIC XL ELSE má, kapitola 27.)
Riadok 80:AND – musia platiť obe podmienky. Pozor: nedá sa napísať 13<=AGE<=19 ako v matematike, každé porovnanie musí byť celé.
Riadok 90:OR – stačí jedna.
Riadok 100:NOT obráti odpoveď. Porovnanie za ním daj do zátvorky: v Atari BASICu sa NOT viaže len na to, čo stojí tesne za ním, takže NOT AGE=100 by znamenalo (NOT AGE)=100.
Riadky 130 a 140: reťazce sa porovnávajú rovnako ako čísla. Rovnajú sa, len keď sú rovnaké znak po znaku – "YES" a "yes" sú rôzne.
Riadok 150: podmienka je pre BASIC tiež číslo: 1, keď platí, a 0, keď neplatí. A naopak, IF berie každé nenulové číslo ako „platí“ – IF A THEN … znamená „ak A nie je nula“.
Reťazce sa dajú porovnávať aj na menší a väčší; rozhoduje poradie znakov v tabuľke Atari, kde sú veľké písmená pred malými. "B"<"C" platí a "abc">"ABC" tiež.
Program beží po riadkoch zhora nadol. GOTO (anglicky go to, „choď na“) toto poradie poruší: prikáže pokračovať na inom riadku. Skokom dozadu vznikne opakovanie, skokom dopredu sa kus programu preskočí.
Riadky 30 až 60 sa opakujú. Riadok 60 posiela program späť na riadok 30 – to je slučka.
Riadok 50 je východ zo slučky: keď N prekročí tisíc, skočí sa dopredu na riadok 70, za slučku.
Keby riadok 50 chýbal, program by sa točil donekonečna. Na Atari sa taký program zastaví klávesom BREAK; simulátor sa po desiatich miliónoch krokov vzdá sám.
10REM A guessing game with IF and GOTO20 SECRET=37:TRIES=030PRINT"Guess my number (1-100)";
40INPUT G
50 TRIES=TRIES+160IFG<SECRET THENPRINT"Too small":GOTO3070IFG>SECRET THENPRINT"Too big":GOTO3080PRINT"Yes! It took you ";TRIES;" tries"
Guess my number (1-100)?50
Too big
Guess my number (1-100)?25
Too small
Guess my number (1-100)?37
Yes! It took you 3 tries
Riadky 60 a 70 sú typický tvar: „ak niečo nesedí, povedz to a choď späť“. Na riadok 80 sa program dostane, len keď neplatí ani jedno – číslo je uhádnuté. Tajné číslo je zatiaľ vždy 37; náhodné príde v kapitole 16.
GOTO je silný a ľahko sa ním spraví neporiadok. Program, v ktorom sa skáče krížom-krážom, sa nedá čítať – hovorí sa mu „špagetový“. Niekoľko zvykov, ktoré pomáhajú:
Na opakovanie so známym počtom použi FOR (kapitola 10).
Skákaj dozadu len na začiatok slučky a dopredu len za jej koniec.
Cieľ skoku označ komentárom: 500 REM Game over.
V Turbo-BASICu XL sa dá väčšina GOTO nahradiť slučkami WHILE, REPEAT a DO (kapitoly 28 a 29).
Riadky 20 až 40:I ide od 1 do 10 vrátane. Počítadlo sa dá v tele normálne používať – tu sa vypisuje.
Riadok 60: celá slučka na jednom riadku. STEP 5 zväčšuje I po piatich.
Riadok 80: záporný krok počíta nadol. Bez STEP -1 by to nešlo.
Riadky 120 až 140: počítadlo ROW vstupuje do výpočtu ROW*7.
Riadky 160 až 210: slučka v slučke. Vonkajšia ide po riadkoch, vnútorná vypíše toľko hviezdičiek, aké je číslo riadka. Vnútorná slučka má ako koniec premennúROW – koniec nemusí byť číslo. Vnútorná slučka musí byť celá vo vonkajšej: najprv NEXT COL, potom NEXT ROW.
Riadky 220 až 240: zbieranie súčtu. Pred slučkou sa SUM vynuluje a v každom prechode sa k nemu pripočíta I.
Telo slučky je odsadené o dve medzery za číslom riadka. BASIC tie medzery ignoruje (Atari BASIC ich pri písaní zahodí, Turbo-BASIC XL vo výpise odsadzuje sám), ale je z nich na prvý pohľad vidieť, čo k čomu patrí – a ktorá slučka nemá NEXT.
Začiatočníci často volajú počítadlá I, J, K. Je to zvyk z matematiky; meno ako ROW alebo COL však hovorí viac.
1. Telo sa vykoná vždy aspoň raz.FOR I=5 TO 1 bez záporného kroku telo jedenkrát vykoná (s I = 5) a až NEXT zistí, že je za koncom. Tak sa správa Atari BASIC aj Turbo-BASIC XL.
2. Po skončení slučky je počítadlo o krok ďalej. Po FOR I=1 TO 3 je v I číslo 4.
3. Koniec a krok sa vypočítajú raz, pri vstupe do slučky. Keď v tele zmeníš premennú, ktorá bola koncom, počet prechodov sa už nezmení.
4. Krok môže byť desatinný:FOR X=0 TO 1 STEP 0.25 prejde 0, 0.25, 0.5, 0.75 a 1.
Nerobí nič, len počíta – a tým spomaľuje. V interpreteri trvalo tristo prechodov asi pol sekundy a programátori si tak robili prestávky. Preložený program je však mnohokrát rýchlejší, takže prestávka skoro zmizne. Presné čakanie, ktoré od rýchlosti nezávisí, je v kapitolách 18 (časovač Atari) a 33 (PAUSE v Turbo-BASICu XL); pre dobové programy má prekladač voľbu --line-delay (kapitola 42).
Keď program potrebuje tú istú vec na viacerých miestach – podčiarknuť nadpis, počkať na kláves, nakresliť panáčika –, nemusí ju písať zakaždým znova. Napíše ju raz ako podprogram a z rôznych miest ju volá.
10REM GOSUB: a piece of program with a way back20DIMT$(30)
30T$="First":GOSUB100040T$="Second title":GOSUB100050 N=3:GOSUB200060 N=10:GOSUB200070 END
1000REM Print T$ underlined1010PRINTT$1020FORI=1TOLEN(T$):PRINT"-";:NEXTI
1030PRINT1040RETURN2000REM Print the square and the cube of N2010PRINT N;" squared is ";N*N;", cubed ";N*N*N
2020RETURN
Riadky 30 až 60 sú hlavný program. Je krátky a číta sa ako zoznam úloh.
Riadky 1000 až 1040 sú podprogram, ktorý vypíše text z T$ a podčiarkne ho pomlčkami. Volá sa dvakrát, zakaždým s iným textom.
Ako podprogram dostane údaje: cez obyčajné premenné. Hlavný program pred volaním uloží text do T$ (alebo číslo do N) a podprogram si ho odtiaľ vezme. BASIC nemá „parametre“; všetky premenné sú spoločné pre celý program.
Riadok 70, END, je tu nutný. Bez neho by program po riadku 60 pokračoval ďalej na riadok 1000, vbehol do podprogramu a jeho RETURN by sa nemal kam vrátiť.
Zvykom je dávať podprogramy na vysoké čísla riadkov (1000, 2000 …) a každý začať komentárom, čo robí a ktoré premenné číta.
Podprogram môže volať ďalší podprogram. Návraty sa pamätajú v poradí – každý RETURN sa vráti k tomu GOSUB, ktorý bol posledný.
Podprogram na riadku 1000 používa počítadlo I. Keby hlavný program volal GOSUB 1000 z vnútra vlastnej slučky FOR I=…, podprogram by mu počítadlo prepísal. Pomôcť si musíš sám: podprogramy nech používajú iné mená premenných než hlavný program.
Niekedy sa z podprogramu nechceš vrátiť – napríklad hráč v ňom prehral a program má skočiť rovno na koniec hry. Obyčajný GOTO z podprogramu by nechal zapamätaný návrat „visieť“. POP ho zahodí:
ZX-Basic
1050IFLIVES=0THENPOP:GOTO5000
Je to zriedkavý príkaz; v dobových programoch ho občas stretneš.
Ponuka s piatimi možnosťami by potrebovala päť riadkov IF C=1 THEN …, IF C=2 THEN …. ON to spraví jedným príkazom: podľa čísla vyberie jeden riadok zo zoznamu.
Riadok 80: keď je C jedna, zavolá sa podprogram na riadku 200; keď dva, na riadku 300.
Riadok 90: po návrate z podprogramu sa ide späť na ponuku.
Keď človek napíše číslo, ktoré v ponuke nie je (napríklad 7), ON neurobí nič a ponuka sa ukáže znova. Program sa teda nepokazí, len na voľbu nereaguje.
Hodnota nemusí byť celá – zaokrúhli sa. ON 2.7 GOTO … vyberie tretí riadok.
Za ON môže byť ľubovoľný výraz. Často sa hodnota najprv upraví, aby začínala jednotkou:
ZX-Basic
ON K-48GOTO100,200,300
(Kláves s číslicou 1 má kód 49, o kódoch je kapitola 15.)
Sedem teplôt za týždeň by potrebovalo sedem premenných a sedem skoro rovnakých riadkov na každú vec, ktorú s nimi chceš urobiť. Pole je rad čísel pod jedným menom: TEMP(0), TEMP(1) … TEMP(6). Číslo v zátvorke – index – môže byť premenná, a tak pole prejde jedna slučka.
10REM Arrays: many numbers under one name20DIMTEMP(6)
30 TEMP(0)=12:TEMP(1)=14:TEMP(2)=11:TEMP(3)=1740 TEMP(4)=19:TEMP(5)=16:TEMP(6)=1350 SUM=0:HIGH=060FORD=0TO670 SUM=SUM+TEMP(D)
80IFTEMP(D)>TEMP(HIGH) THENHIGH=D
90NEXTD
100PRINT"Average: ";SUM/7110PRINT"Warmest day: ";HIGH;" with ";TEMP(HIGH)
120REM A table with rows and columns130DIMT(3,3)
140FORR=1TO3:FORC=1TO3150 T(R,C)=R*C
160NEXTC:NEXTR
170FORR=1TO3180PRINT T(R,1),T(R,2),T(R,3)
190NEXTR
Atari BASIC pole pri DIMnevynuluje – ostane v ňom, čo bolo v pamäti predtým. Kým do prvku niečo neuložíš, nespoliehaj sa, že je nulový. Ak nuly potrebuješ, daj ich tam slučkou:
Každé číslo má šesť bajtov. DIM A(1000) je šesť kilobajtov, a sedem takých polí sa už do Atari nezmestí – program skončí chybou 2. Jedno pole smie mať najviac 32 767 bajtov: DIM T(100,100) by ich chcelo vyše šesťdesiattisíc a skončí chybou 9.
CLR vráti program do stavu ako na začiatku: číselné premenné sú nula, reťazce a polia neexistujú a treba ich ohlásiť znova. Zabudne aj otvorené slučky FOR a podprogramy GOSUB – NEXT za CLR je chyba 13, RETURN chyba 16; TRAP ostane. Použije sa zriedka – napríklad v hre, ktorá po skončení začína odznova a chce si polia pripraviť nanovo.
Program často potrebuje zoznam hodnôt, ktoré sa nemenia: mená mesiacov, noty melódie, body obrázka. Namiesto dvadsiatich riadkov A(0)=12:A(1)=14… ich napíšeš za sebou do riadkov DATA a program si ich po jednej číta.
10REM DATA: values written in the program20DIMNAME$(10)
30FORI=1TO440READNAME$,AGE
50PRINTNAME$;" is ";AGE
60NEXTI
70RESTORE101080READNAME$,AGE
90PRINT"Again: ";NAME$100 END
1000DATA Anna,121010DATA Boris,15,Cyril,91020DATA Dana,11
Počítač nepozná písmená, len čísla. Každý znak má svoj kód – A je 65, B je 66, medzera 32. Tabuľka kódov na Atari sa volá ATASCII. Štyri funkcie tejto kapitoly prevádzajú medzi znakom a jeho kódom a medzi číslom a textom.
10REM CHR$, ASC, STR$, VAL20DIMA$(20),D$(10)
30PRINT"The code of A is ";ASC("A")
40PRINT"Character 66 is ";CHR$(66)
50FORC=65TO90:PRINTCHR$(C);:NEXTC
60PRINT70A$="hello"80REM Small letters to capitals: 32 less90FORI=1TOLEN(A$)
100 C=ASC(A$(I,I))
110IFC>=97ANDC<=122THENA$(I,I)=CHR$(C-32)
120NEXTI
130PRINTA$140REM A number into text and back150 N=1234160D$=STR$(N)
170PRINTD$;" has ";LEN(D$);" digits"180PRINT"The last digit is ";D$(LEN(D$))
190PRINT VAL("12")+VAL("30")
200PRINT VAL("3.5 apples")
Riadok 50: kódy 65 až 90 sú veľké písmená A až Z. Slučka cez kódy vypíše celú abecedu.
Riadky 90 až 120: malé písmená majú kódy 97 až 122, presne o 32 viac než veľké. Slučka prejde text znak po znaku, a kde nájde malé písmeno, prepíše ho znakom s kódom o 32 menším. A$(I,I) je jeden znak – na čítanie aj na zápis.
Riadok 160:STR$ spraví z čísla text. S textom sa dajú robiť veci, ktoré s číslom nejdú: spočítať číslice (LEN), vybrať poslednú, zarovnať stĺpec.
Riadok 190:VAL robí opak. Dva texty, z ktorých sa stanú čísla, a tie sa sčítajú.
Riadok 200:VAL číta číslo od začiatku textu a skončí pri prvom znaku, ktorý do čísla nepatrí.
PRINT CHR$(125) teda nevypíše znak, ale zmaže obrazovku. Atari má takých riadiacich kódov viac; všetky sú v prílohe D. Kódy 0 až 31 a 123 až 127 sú grafické znaky – čiarky, rohy a srdiečka, z ktorých sa skladali rámčeky.
Úvodzovka sa v texte v úvodzovkách napísať nedá. Keď ju chceš vypísať, pomôže jej kód: PRINT CHR$(34);"Hello";CHR$(34).
Funkcie pre všetko, čo nejde štyrmi základnými znamienkami: uhly (kreslenie kruhov, pohyb po oblúku), mocniny a logaritmy – a RND, bez ktorého by nebola žiadna hra, lebo dáva náhodné číslo.
Riadok 20:DEG prepne na stupne. Platí, kým ho nezmení RAD.
Riadky 30 až 50: sínus tridsiatich stupňov je presne jedna polovica, ale Atari vypíše 0.499999999. Nie je to chyba prekladača – takto počíta Atari BASIC a preložený program dáva do poslednej číslice to isté. Funkcie sa počítajú približne a posledné miesto býva o kúsok vedľa. Preto výsledky funkcií neporovnávaj znakom = (kapitola 8).
Riadok 70: π ako premenná. Na kreslenie v stupňoch ho nepotrebuješ.
Riadok 150: najdôležitejší riadok kapitoly. RND(0) dá číslo ako 0.7312…; vynásobené šiestimi je od 0 po 5,99…; INT z neho spraví celé číslo 0 až 5; plus jedna je 1 až 6. Všeobecne:
ZX-Basic
INT(RND(0)*N)+1
je náhodné celé číslo od 1 do N. Na čísle v zátvorke RND nezáleží, zvykne sa písať nula.
V simulátore dostaneš pri každom spustení tie isté „náhodné“ čísla – preto môže táto kapitola ukázať, čo program vypíše. Na Atari a v emulátore sú zakaždým iné.
Niektoré chyby sa pri preklade zistiť nedajú: človek napíše písmená namiesto čísla, delí sa nulou, súbor na diskete nie je. Program vtedy vypíše ERROR- a skončí. S TRAP (anglicky „pasca“) sa chyba dá zachytiť: namiesto konca program skočí na riadok, ktorý si určíš, a tam sa rozhodne, čo ďalej.
10REM TRAP: catching an error20 TRAP 20030PRINT"Divide 100 by (999 ends)";
40INPUT N
50IFN=999THENPRINT"Bye":END
60PRINT"100/";N;" = ";100/N
70GOTO20200REM An error brought us here210 E=PEEK(195):L=PEEK(186)+256*PEEK(187)
220PRINT"Error ";E;" at line ";L
230IFE=8THENPRINT"That was not a number"240IFE=11THENPRINT"Cannot divide by zero"250GOTO20
Divide 100 by (999 ends)?4
100/4 = 25
Divide 100 by (999 ends)?abc
Error 8 at line 40
That was not a number
Divide 100 by (999 ends)?0
100/0 = Error 11 at line 60
Cannot divide by zero
Divide 100 by (999 ends)?999
Bye
Riadok 20 nastaví pascu. Kým nenastane chyba, nerobí nič.
Odpoveď abc:INPUT N čaká číslo, takže je to chyba 8. Bez pasce by program skončil hlásením ERROR- 8 AT LINE 40. S pascou skočí na riadok 200.
Riadok 210 si hneď odloží číslo chyby a riadok do premenných.
Riadok 250 sa vracia na riadok 20, nie 30 – aby sa pasca nastavila znova.
Odpoveď 0:PRINT na riadku 60 stihol vypísať začiatok (100/0 = ), až potom prišlo delenie a s ním chyba 11. Preto je hlásenie na tom istom riadku obrazovky.
RUN v programe ho spustí odznova: premenné sú nula, polia a reťazce neexistujú, DATA sa čítajú od začiatku, pasca je zrušená. Hra tak môže po skončení začať novú:
Pamäť Atari je rad 65 536 očíslovaných priehradok. Číslo priehradky je adresa (0 až 65535) a v každej je jeden bajt – číslo od 0 do 255. V pamäti je tvoj program, jeho premenné, obrazovka aj nastavenia počítača: farby, okraje, hodiny, posledný stlačený kláves.
PEEK sa do priehradky pozrie a POKE do nej zapíše. Tak sa z BASICu dostaneš k veciam, na ktoré nemá príkaz.
10REM PEEK and POKE: the memory of the computer20PRINT"Left margin: ";PEEK(82)
30PRINT"Right margin: ";PEEK(83)
40 SCR=PEEK(88)+256*PEEK(89)
50PRINT"The screen starts at ";SCR
60DIMA$(5):A$="HELLO"70PRINT"The first byte of A$ is ";PEEK(ADR(A$))
80POKE ADR(A$),7490PRINTA$100POKE82,10110PRINT"Margin 10 from the next line on"120PRINT"Here it is"130POKE82,2140PRINT"And back"
Tentoraz s voľbou --sim-screen: simulátor na konci neukáže, čo program postupne vypísal, ale ako vyzerá obrazovka – aj s medzerami na začiatku riadkov.
Riadky 20 a 30: na adresách 82 a 83 si Atari drží ľavý a pravý okraj textu. Ľavý okraj je 2 – preto každý riadok na obrazovke začína dvoma medzerami. (Staré televízory okraj obrazu orezávali.)
Riadok 40: adresa pamäte obrazovky je väčšia než 255, takže zaberá dva bajty, 88 a 89. Druhý bajt má váhu 256. Tento vzorec stretneš v dobových programoch stále.
Riadok 70:ADR(A$) je adresa prvého znaku reťazca. Je na nej 72 – kód písmena H.
Riadok 80:POKE tam zapíše 74, kód písmena J, a z HELLO je JELLO. Reťazec sa zmenil bez toho, aby sa ho dotkol príkaz priradenia.
Riadok 100:POKE 82,10 posunie ľavý okraj. Platí od najbližšieho nového riadka – preto je riadok 110 ešte na starom mieste a až riadok 120 odsadený.
Riadok 130: okraj späť. Aj tu zmena platí až od ďalšieho riadka, takže And back je ešte odsadený.
Bajt na adrese 20 sa sám od seba zväčší o jedna päťdesiatkrát za sekundu (na amerických strojoch šesťdesiatkrát). Keď doň zapíšeš nulu a počkáš, kým v ňom bude 50, prešla sekunda – nech je program akokoľvek rýchly. Súbor examples/wait.abas:
ZX-Basic
10REM Waiting by the clock of the computer20FORN=5TO1STEP-130PRINT N
40 S=50:GOSUB100050NEXTN
60PRINT"Go!"70 END
1000REM Wait S fiftieths of a second (S up to 255)1010POKE20,01020IFPEEK(20)<S THEN10201030RETURN
Bash
Basic26wait.abas--run
Program odpočíta od päť do jedna, s presne sekundovou prestávkou medzi číslami. Podprogram na riadku 1000 budú používať aj ďalšie kapitoly.
Tento program spúšťaj v emulátore. Hodiny poháňa obrazovka Atari a simulátor obrazovku nemá – bajt 20 v ňom stojí a riadok 1020 by sa točil donekonečna.
PRINT FRE(0) vypíše, koľko bajtov ostáva pre reťazce a polia, teda koľko ešte zoberie DIM. Preložený program dá iné číslo než ten istý program v interpreteri, lebo v pamäti leží inak. Na čísle v zátvorke nezáleží.
PRINT píše tam, kde práve stojí kurzor – riadok za riadkom, zhora nadol. Na hru, ponuku alebo tabuľku to nestačí: chceš písať na presné miesto, obrazovku zmazať a zmeniť jej farby.
10REM The text screen20 GRAPHICS 030 SETCOLOR 2,12,2:REM background: dark green40 SETCOLOR 1,0,14:REM letters: bright50 SETCOLOR 4,3,6:REM border: red60POKE752,1:REM hide the cursor70 POSITION 14,2:PRINT"A T A R I"80FORX=10TO2690 POSITION X,4:PRINT"-";
100NEXTX
110FORY=6TO10120 POSITION Y,Y:PRINT"Row ";Y
130NEXTY
140 POSITION 2,20:PRINT"Bottom line";
Riadok 20:GRAPHICS 0 začne s čistou obrazovkou a pôvodnými farbami. Na začiatku programu je to dobrý zvyk.
Riadky 30 až 50: tri z piatich farebných registrov. V textovom režime má register 2 pozadie, register 1 jas písmen a register 4 okraj. Po zapnutí je obrazovka modrá: SETCOLOR 2,9,4.
Riadok 70:POSITION 14,2 – najprv stĺpec, potom riadok. PRINT hneď za ním píše od toho miesta.
Riadok 90: bodkočiarka na konci PRINT je tu dôležitá. Bez nej by kurzor po každej pomlčke prešiel na nový riadok – a keby to bolo v poslednom riadku obrazovky, celá obrazovka by sa posunula nahor.
GRAPHICS 0 zmaže obrazovku a vráti farby. PRINT CHR$(125) ju len zmaže – farby aj skrytý kurzor ostanú. V dobových programoch nájdeš za PRINT v úvodzovkách zvláštny znak (zahnutú šípku); je to ten istý kód 125 napísaný rovno z klávesnice Atari.
Režimy 4, 6 a 14 sú dvojfarebné verzie režimov 5, 7 a 15. Úplná tabuľka je v prílohe D.
Pod obrázkom ostávajú štyri riadky textu – textové okno, do ktorého píše PRINT. Keď ho nechceš, pripočítaj k režimu 16: GRAPHICS 7+16 má obrázok cez celú obrazovku a 96 riadkov bodov namiesto 80.
10REM Graphics: a house in mode 720 GRAPHICS 730 SETCOLOR 4,9,2:REM background: dark blue40 SETCOLOR 2,3,8:REM COLOR 3: red50 COLOR 160PLOT50,70:DRAWTO 110,70:DRAWTO 110,40:DRAWTO 50,40:DRAWTO 50,7070 COLOR 280PLOT45,40:DRAWTO 80,15:DRAWTO 115,4090 COLOR 3100PLOT75,70:DRAWTO 75,52:DRAWTO 87,52:DRAWTO 87,70110 COLOR 1:PLOT62,50:PLOT98,50120 LOCATE 80,15,C
130PRINT"The roof top has colour ";C
140PRINT"A house in GRAPHICS 7"
V emulátore: na tmavomodrom pozadí oranžový obrys domu, zelená strecha, červené dvere a dve bodky ako okná. Pod obrázkom v textovom okne dva riadky. V simulátore len tie dva riadky:
Riadok 20: režim 7 má 160 bodov na šírku (x od 0 do 159) a 80 na výšku (y od 0 do 79).
Riadok 50:COLOR 1 vyberie prvé pero. Bez COLOR by sa kreslilo perom 0, teda farbou pozadia – a nebolo by vidieť nič. To je najčastejšia chyba prvého grafického programu.
Riadok 60:PLOT postaví pero do ľavého dolného rohu domu a štyri DRAWTO obídu obdĺžnik. Každý DRAWTO pokračuje tam, kde predošlý skončil.
Riadky 70 až 100: iné pero, iná farba: strecha a dvere.
Riadok 110: samotný PLOT je jeden bod.
Riadok 120:LOCATE je opak PLOT: neuloží bod, ale prečíta ho. Vrchol strechy je nakreslený perom 2.
Riadky 130 a 140:PRINT v grafickom režime píše do textového okna pod obrázkom.
COLOR nevyberá farbu, ale pero – číslo, ktoré sa uloží do bodu. Akú farbu to číslo na obrazovke má, hovorí farebný register a mení ho SETCOLOR. V režime 7:
COLOR
Register
Farba po zapnutí
1
0
oranžová
2
1
svetlozelená
3
2
modrá
0
4
čierna (pozadie a okraj)
SETCOLOR register,odtieň,jas: odtieň je 0 až 15 (0 sivá, 1 zlatá, 3 červená, 5 fialová, 7 a 9 modrá, 12 zelená, 14 žltozelená), jas párne číslo 0 (tmavá) až 14 (svetlá). Riadok 30 teda mení pozadie na tmavomodré a riadok 40 pero 3 na červené.
Zmena registra prefarbí všetko, čo je tým perom už nakreslené – okamžite a bez prekresľovania. Tak sa robili blikajúce a pulzujúce obrázky.
Atari má štyri hlasy – štyri nezávislé zdroje zvuku. Každý vie hrať čistý tón alebo šum, a to naraz s ostatnými. Jeden príkaz hlas zapne a hrá, kým ho iný príkaz nezmení alebo nevypne.
10REM SOUND: a scale20FORI=1TO830READ P
40 SOUND 0,P,10,850 S=15:GOSUB100060NEXTI
70 SOUND 0,0,0,080 END
1000REM Wait S fiftieths of a second1010POKE20,01020IFPEEK(20)<S THEN10201030RETURN2000DATA121,108,96,91,81,72,64,60
Dobové programy držia notu prázdnou slučkou FOR W=1 TO 100:NEXT W. V preloženom programe by takú melódiu nebolo počuť – prebehla by niekoľkokrát rýchlejšie. Čakanie podľa hodín trvá rovnako v interpreteri, v preloženom programe aj na rýchlejšom stroji.
Hra potrebuje vedieť, čo robí hráč – práve teraz, bez čakania na RETURN. Joystick, jeho tlačidlo aj klávesnica sa preto nečítajú príkazom INPUT, ale funkciami, ktoré vrátia okamžitý stav.
Programy tejto kapitoly sú pre emulátor. V emulátore atari800 sa joystick zvyčajne ovláda číselnou klávesnicou alebo šípkami a tlačidlo pravým klávesom Ctrl – presné nastavenie nájdeš v jeho ponuke (kláves F1).
10REM Joystick: move a star, the button ends20 GRAPHICS 0:POKE752,130 X=20:Y=1240 POSITION 2,0:PRINT"Joystick moves, the button ends";
50 POSITION X,Y:PRINT"*";
60 S=STICK(0)
70IFSTRIG(0)=0THENPOSITION 2,22:PRINT"Bye":END
80IFS=15THEN6090 POSITION X,Y:PRINT"";
100IFS=14ANDY>2THENY=Y-1110IFS=13ANDY<21THENY=Y+1120IFS=11ANDX>2THENX=X-1130IFS=7ANDX<38THENX=X+1140 W=3:GOSUB1000150GOTO501000REM Wait W fiftieths of a second1010POKE20,01020IFPEEK(20)<W THEN10201030RETURN
zmaže hráča na starom mieste medzerou (riadok 90),
posunie súradnice, ale len ak neprejdú za okraj (riadky 100 až 130),
chvíľu počká (riadok 140) a ide odznova.
Čakanie v kroku 6 určuje rýchlosť hry. Bez neho by hviezdička v preloženom programe preletela obrazovku skôr, než pustíš joystick. Tri päťdesiatiny sekundy dávajú asi 17 krokov za sekundu.
Podmienky ako Y>2 držia hviezdičku na obrazovke. Bez nich by POSITION dostal súradnicu mimo a program by skončil chybou 141.
Atari si kód posledného stlačeného klávesu ukladá na adresu 764. Kým nikto nič nestlačil, je tam 255.
ZX-Basic
10PRINT"Press any key"20POKE764,25530IFPEEK(764)=255THEN3040PRINT"The key code was ";PEEK(764)
50POKE764,255
Riadok 20 „vyprázdni“ pamäť klávesu, riadok 30 čaká, kým sa v nej niečo objaví. Pozor: číslo na adrese 764 nie je kód ATASCII, ale číslo klávesu na klávesnici (A je 63, medzera 33, RETURN 12). Tabuľka je v prílohe D. Skutočný znak prečítaš cez zariadenie K: – kapitola 24.
Tri klávesy vpravo sa čítajú zvlášť, z adresy 53279:
PEEK(53279)
Stlačené
7
nič
6
START
5
SELECT
3
OPTION
ZX-Basic
10PRINT"Press START"20IFPEEK(53279)<>6THEN2030PRINT"Here we go"
V simulátore sa tieto klávesy dajú „stlačiť“ voľbou --sim-console (kapitola 39).
Procesor Atari rozumie len strojovému kódu – radu bajtov, z ktorých každý je jednoduchý pokyn. Je stokrát rýchlejší než BASIC v interpreteri, ale píše sa ťažko. Dobové programy ním robili to, čo BASIC nestíhal: rýchly presun obrazovky, hudbu, pohyb postavičiek.
USR je most: funkcia BASICu, ktorá zavolá strojový kód na danej adrese a vráti, čo jej kód odovzdá.
Túto kapitolu nemusíš vedieť naspamäť. Stačí, keď USR v cudzom programe spoznáš a vieš, že taký program sa dá preložiť tiež.
Riadok 20: 21 bajtov z DATA sa cez POKE uloží do pamäte od adresy 1536. Adresy 1536 až 1791 (šestnástkovo $0600–$06FF, „šiesta stránka“) Atari necháva voľné práve na takéto krátke rutiny.
Riadok 30:USR(1536,5,7) rutinu zavolá a odovzdá jej čísla 5 a 7.
Čo rutina robí (pre zvedavých): BASIC jej pripraví na zásobník procesora počet hodnôt a potom každú hodnotu ako dva bajty. Rutina si ich musí všetky vyzdvihnúť – pokynom PLA, bajt 104. Súčet uloží na adresy 212 a 213; čo tam nájde BASIC po návrate (pokyn RTS, bajt 96), to je výsledok USR.
Rutina, ktorá si hodnoty zo zásobníka nevyzdvihne, sa nevráti tam, kam má, a počítač zamrzne. Na skutočnom Atari rovnako ako v preloženom programe.
Druhý obľúbený spôsob: bajty rutiny sú znaky reťazca a volá sa USR(ADR(M$)). Vo výpise takého programu vidíš v úvodzovkách zhluk čudných znakov – to je strojový kód. Prekladač taký reťazec nechá bajt po bajte tak, ako je.
Preložený program volá USR rovnako ako interpreter, takže rutiny z dobových programov fungujú. Niektoré z nich však čítajú veci, ktoré patria interpreteru – napríklad text programu v riadkoch REM, alebo čakajú strojový kód či znakovú sadu nahraté z iného súboru. Na to má prekladač voľby --keep-rem, --embed a --reserve (kapitoly 42 a 43).
Premenné žijú, len kým program beží. Čo má prežiť vypnutie počítača – tabuľka najlepších výsledkov, uložená hra, zoznam adries –, musí ísť do súboru na diskete.
Atari sa na disketu, klávesnicu, obrazovku aj tlačiareň pozerá rovnako: ako na zariadenie, z ktorého sa číta alebo do ktorého sa píše. Program si k zariadeniu otvorí kanál a ďalej už pracuje s číslom kanála.
Simulátor má disketu D: len v pamäti – súbor v nej vydrží do konca behu, čo na vyskúšanie stačí:
Bash
Basic26files.abas--sim
V emulátore potrebuje program skutočnú disketu a na nej DOS – program, ktorý na Atari s disketami pracuje. Voľba --atr vyrobí obraz diskety s DOS-om, uloží naň preložený program tak, aby sa po zapnutí spustil sám, a --run z tej diskety emulátor naštartuje:
Riadok 30: kanál 1 sa otvorí na zápis (režim 8). Ak súbor NOTES.TXT existuje, zmaže sa a začne odznova.
Riadky 40 až 60:PRINT #1; píše do súboru presne to, čo by PRINT napísal na obrazovku. Za #1 je bodkočiarka (čiarka by vložila medzery ako na obrazovke). Číslo sa zapíše ako text.
Riadok 70:CLOSE zapíše na disketu posledný kúsok dát a uvoľní kanál. Súbor, ktorý nezavrieš, je poškodený. Na konci programu (END alebo za posledným riadkom) zavrú kanály 1 až 7 oba interpretery aj preložený program; preložený navyše aj po STOP a chybe. Kým však program beží – a hlavne keď ho niekto zastaví klávesom RESET –, súbor bez CLOSE celý nie je.
Riadok 80: ten istý kanál, teraz na čítanie (režim 4).
Riadok 100:INPUT #1,L$ číta riadok po riadku.
Riadok 90: program nevie, koľko riadkov v súbore je. Číta, kým to ide; pokus čítať za koniec je chyba 136 a pasca TRAP ju zachytí. To je bežný a správny spôsob, ako nájsť koniec súboru.
Číslo zapísané cez PRINT #1;N sa číta cez INPUT #1,N. Viac čísel na jednom riadku oddeľ čiarkou, ktorú zapíšeš sám: PRINT #1;A;",";B a potom INPUT #1,A,B.
Kanál za XIO musí byť zavretý. Tieto operácie robí DOS, takže ich skúšaj v emulátore s disketou, nie v simulátore. Turbo-BASIC XL má na ne obyčajné príkazy RENAME, DELETE, LOCK, UNLOCK a DIR (kapitola 37).
Pripíš do NOTES.TXT štvrtý riadok režimom 9 a prečítaj súbor znova.
Ulož do súboru desať čísel z poľa a prečítaj ich späť do iného poľa.
Napíš program, ktorý sa spýta na meno a pri ďalšom spustení (v emulátore, s tou istou disketou) ťa ním pozdraví. Ak súbor ešte nie je, chybu 170 zachyť cez TRAP.
Na skutočnom Atari je BASIC zároveň aj editor: píšeš doň riadky programu a medzi nimi príkazy, ktorými program vypíšeš, uložíš, spustíš. Niektoré z týchto príkazov nájdeš aj vo vnútri dobových programov – program sa sám vypíše, nahrá ďalšiu časť, alebo po skončení odíde do DOS-u.
Preložený program však nemá ani editor, ani svoj text. Táto kapitola hovorí, čo také príkazy urobia v ňom. Nie je to kapitola na učenie – je na nahliadnutie, keď ich stretneš.
10REM Commands of the editor in a compiled program20PRINT"Before LIST"30LIST40PRINT"Before SAVE"50SAVE"D:PROGRAM.BAS"60PRINT"Still running"70NEW80PRINT"Never printed"
editor.abas(3,4): warning B26219: LIST only says it is not available: a compiled program has no program text
editor.abas(5,4): warning B26219: SAVE only says it is not available: a compiled program has no program text
Upozornenie preklad nezastaví; hovorí len, že tento riadok nebude robiť to, čo v interpreteri.
Riadok 30: program, ktorý sa sám vypisuje, to zvyčajne robí, aby ukázal svoj text na obrazovke. Tridsať čísel zaplní obrazovku rovnako ako výpis a hláška povie prečo: not in compiled program.
Riadok 50: uložiť nie je čo; program pokračuje.
Riadok 70:NEW program ukončí, riadok 80 sa nevykoná.
Väčšie dobové programy sa delili na časti, ktoré sa nahrávali za sebou: úvodná časť nakreslila titulný obrázok a skončila príkazom RUN "D:GAME.BAS". To je jediná vec z BASICu, ktorú prekladač odmietne – v preloženom programe nie je interpreter, do ktorého by sa ďalší program nahral.
Riešenie je preložiť každú časť zvlášť a spojiť ich inak: strojový kód a obrázky pribaliť k hlavnému programu (--embed, kapitola 43), alebo časti preložiť do samostatných súborov a spúšťať ich z DOS-u.
Tri slová, ktoré nie sú príkazmi editora, ale patria sem#
Slovo
Čo robí
LET
nepovinné slovo pred priradením (kapitola 4); v dobových programoch ho nájdeš tam, kde sa meno premennej začína slovom BASICu: LET TOP=5
Keď chceš mať istotu, že program nerobí nič, čo by v preloženej podobe nedávalo zmysel, prelož ho s --strict: z upozornení na príkazy editora sa stanú chyby.
Turbo-BASIC XL je rozšírený BASIC, ktorý v roku 1985 napísal Frank Ostrowski. Vie všetko, čo Atari BASIC – každý program z kapitol 1 až 25 v ňom beží rovnako –, a pridáva okolo sedemdesiat nových príkazov a funkcií. Najdôležitejšie z nich robia program čitateľnejším: slučky bez GOTO, podmienky na viac riadkov, podprogramy s menami.
Kapitoly 26 až 38 ich prejdú. Táto prvá ukazuje, čo si všimneš hneď.
Alebo voľbou --dialect turbo (či --dialect atari), ktorá má pred príponou prednosť.
Na jazyku záleží aj vtedy, keď program žiadny nový príkaz nepoužije. Slová Turbo-BASICu sú totiž v súbore .abas obyčajné mená: DELKA=5 je v Atari BASICu premenná DELKA, ale v Turbo-BASICu XL sa číta ako príkaz DEL KA=5 a prekladač ohlási chybu. Program písaný pre Atari BASIC preto nechaj v .abas.
Líšia sa aj drobnosti: Turbo-BASIC XL vypisuje čísla s desiatimi číslicami (Atari BASIC s deviatimi) a k chybe pridá slovo – ERROR- 11 OVERFLOW AT LINE 10.
Riadky 20 a 120:-- nerobí nič. Turbo-BASIC XL ho vo výpise programu nakreslí ako čiaru z tridsiatich pomlčiek, takže oddeľuje časti programu.
Riadky 30 až 50: príkazy malými písmenami. Turbo-BASIC XL ich pri písaní sám prevádzal na veľké; print, Print a PRINT je to isté, a total_sum a TOTAL_SUM je tá istá premenná. V tejto knihe ostanú príkazy veľkými písmenami, aby sa odlíšili od textov.
Riadok 60: číslo so znakom dolára vpredu je šestnástkové – zapísané v sústave so základom 16, kde po deviatke nasledujú A až F. Adresy v pamäti sa tak píšu oveľa pohodlnejšie: $0600 je začiatok šiestej stránky, $D000 adresa obvodov. Nepomýľ si to s dolárom na konci mena reťazca.
Riadok 90: text pred premennou sa vypíše ako otázka. So stredníkom zaň INPUT pridá otáznik.
nové príkazy sa berú ako mená premenných: error B26017 na prvom z nich
meno premennej sa začína slovom Turbo-BASICu (DELKA, DOOR, EXITS)
error B26017: DOOR=1 sa číta ako DO OR=1, EXITS=2 ako EXIT S=2
INPUT "text";A v Atari BASICu
error B26008: INPUT needs a variable to read into – tam otázka v INPUT nie je
$ pred desiatkovým číslom zo zvyku ($100 namiesto 100)
je to 256
Slov, ktorými sa nesmie začínať meno, je v Turbo-BASICu XL viac: DO, DEL, DIR, TIME, EXIT, EXEC, PROC, LOOP, MOVE, TEXT, CLS, PAUSE, PAINT, WHILE, WEND a ďalšie z prílohy A.
V Atari BASICu patrí k IF len zvyšok jedného riadka a „inak“ sa píše druhým IF s opačnou podmienkou. Turbo-BASIC XL vie podmienku, ktorá má telo cez viac riadkov a vetvu inak.
Medzery za číslom riadka BASIC ignoruje. Odsadením tela o dve medzery je však na prvý pohľad vidieť, čo k čomu patrí – a kde chýba ENDIF. Turbo-BASIC XL takto odsadzoval výpis programu sám.
FOR sa hodí, keď vieš, koľkokrát opakovať. Často to však nevieš: „opakuj, kým hráč neuhádne“, „čítaj, kým nie je koniec“. V Atari BASICu na to bol IF a GOTO (kapitola 9). Turbo-BASIC XL má dve slučky, ktoré to povedia priamo.
10REM REPEAT ... UNTIL and WHILE ... WEND20 N=130 REPEAT
40PRINT N;"";
50 N=N*260 UNTIL N>100070PRINT80REM The greatest common divisor of two numbers90 A=84:B=36100 WHILE A<>B
110IFA>B
120 A=A-B
130 ELSE
140 B=B-A
150 ENDIF
160 WEND
170PRINT"The divisor is ";A
180REM WHILE may not run at all, REPEAT runs at least once190 K=10200 WHILE K<5:PRINT"WHILE ran":WEND
210 REPEAT:PRINT"REPEAT ran":UNTIL K>5
Riadky 30 až 60: ten istý výpočet ako goto.abas v kapitole 9, ale bez čísel riadkov, na ktoré sa skáče. Slučku je vidieť: začína REPEAT, končí UNTIL a podmienka konca stojí hneď pri ňom.
Riadky 100 až 160: najväčší spoločný deliteľ starým Euklidovým postupom – od väčšieho čísla odčítaj menšie, kým nie sú rovnaké. WHILE sa hodí, lebo keby boli čísla rovnaké hneď, netreba robiť nič.
Riadok 200:K<5 neplatí už na začiatku, telo sa nevykoná.
Riadok 210:REPEAT telo najprv vykoná a až potom skúša. Obe slučky sa dajú napísať na jeden riadok.
Niektoré slučky nemajú prirodzenú podmienku na začiatku ani na konci: hlavná slučka hry beží „stále“, a vyskočiť z nej treba zo stredu – keď hráč stlačí tlačidlo, keď dôjdu životy. Na to je DO … LOOP a príkaz EXIT.
10REM DO ... LOOP and EXIT20 SUM=0:N=030DO40 N=N+150 SUM=SUM+N
60IFSUM>100THENEXIT70LOOP80PRINT"1+2+...+";N;" = ";SUM
90REM EXIT leaves FOR, REPEAT and WHILE as well100FORI=1TO100110IFI*I>200THENEXIT120NEXTI
130PRINT"The first square over 200 is ";I;"*";I
Riadky 30 až 70: program sčítava 1, 2, 3 … a po každom pripočítaní pozrie, či súčet prekročil sto. Keď áno, EXIT preskočí za LOOP na riadok 80.
Riadky 100 až 120: slučka má dva východy. Riadny, keď I prejde stovku, a predčasný cez EXIT, keď sa našlo, čo sa hľadalo. Počítadlo po EXIT ostane na hodnote, pri ktorej sa odišlo – preto riadok 130 vie vypísať 15.
EXIT opúšťa len najvnútornejšiu slučku, v ktorej stojí. Z dvoch vnorených slučiek naraz ním nevyskočíš.
V Atari BASICu sa zo slučky FOR predčasne odchádzalo skokom GOTO za NEXT. Slučka tým ostala „rozrobená“ – počítač si ju ďalej pamätal. EXIT to robí čisto: slučku naozaj ukončí a pokračuje za jej NEXT. Príkaz NEXT I vykonaný po EXIT by už svoju slučku nenašiel (chyba 13).
EXIT patrí dovnútra slučky – medzi jej FOR a NEXT. Keby program do tela slučky skočil cez GOTO a FOR nevykonal, EXIT nemá čo ukončiť a program skončí chybou 26.
GOSUB 1000 nehovorí, čo sa na riadku 1000 deje. V Turbo-BASICu XL môže mať podprogram meno – volá sa EXEC UNDERLINE a hneď je jasné, čo robí. Rovnako môže mať meno aj cieľ skoku: namiesto GOTO 500 je GO# FINISH.
Riadky 30 až 50:EXEC zavolá procedúru menom. Údaje sa jej stále odovzdávajú v premenných (T$, N) – procedúry Turbo-BASICu XL nemajú parametre a všetky premenné sú spoločné, tak ako pri GOSUB.
Riadok 60:GO# FINISH preskočí riadok 70.
Riadok 80: návestie. Medzi # a menom môže byť medzera.
Riadok 100:END je aj tu nutný, aby program nevbehol do procedúr pod ním.
Riadky 1000 až 1040: telo procedúry. Čísla riadkov sú tu už len kvôli BASICu – nikto sa na ne neodvoláva.
1 Colours 2 Animals 3 Quit: 2
cat dog fox
1 Colours 2 Animals 3 Quit: 1
red green blue
1 Colours 2 Animals 3 Quit: x
Error 8 at line 50
1 Colours 2 Animals 3 Quit: 3
Bye
Riadok 70:ON C EXEC zavolá prvú alebo druhú procedúru zo zoznamu.
Riadok 40: pasca na návestie. Odpoveď x nie je číslo, program skočí na # OOPS. ERR a ERL sú číslo chyby a riadok – pohodlnejšie než PEEK(195) (kapitola 38).
Riadky 1010 a 2010:RESTORE #CDATA nastaví čítanie na DATA za návestím. Procedúra THREE potom číta tri slová a nevie ani nemusí vedieť, ktoré.
V Atari BASICu sa celý podiel a zvyšok skladali z INT a delenia. Turbo-BASIC XL má na ne vlastné slová – a k nim funkcie na orezanie čísla, celé náhodné číslo, prácu s bitmi a šestnástkový zápis.
Každé číslo 0 až 255 je v pamäti osem bitov – prepínačov, ktoré sú zapnuté (1) alebo vypnuté (0). Bity majú váhy 128, 64, 32, 16, 8, 4, 2 a 1; číslo je súčet váh zapnutých bitov.
12 = 8+4 = 0000 1100
10 = 8+2 = 0000 1010
Operácia
Bit výsledku je zapnutý, keď
12 a 10
&
je zapnutý v oboch
0000 1000 = 8
!
je zapnutý aspoň v jednom
0000 1110 = 14
EXOR
je zapnutý práve v jednom
0000 0110 = 6
Načo to je: veľa adries Atari drží v jednom bajte viac nastavení naraz, každé v inom bite. Bitovými operáciami sa dá jedno zmeniť a ostatné nechať:
ZX-Basic
100 X=PEEK(A)
110POKE A,X!4:REM switch bit 2 on120POKE A,X&251:REM switch bit 2 off (251 = 255-4)130IFX&4THENPRINT"bit 2 is on"
&, ! a EXOR pracujú s celými číslami 0 až 65535. Nepomýľ si ich s AND a OR: tie hovoria len „platí – neplatí“ (1 alebo 0).
Jedna šestnástková číslica sú presne štyri bity, takže bajt sú vždy dve číslice: $FF je 255, $0C je 12. HEX$ vráti dve číslice pre čísla do 255 a štyri pre väčšie.
10REM INSTR and UINSTR: looking for a text in a text20DIMA$(40)
30A$="The quick brown fox"40PRINT"quick is at ";INSTR(A$,"quick")
50PRINT"QUICK is at ";INSTR(A$,"QUICK")
60PRINT"QUICK without case is at ";UINSTR(A$,"QUICK")
70PRINT"The first o is at ";INSTR(A$,"o")
80PRINT"The next o is at ";INSTR(A$,"o",14)
90PRINT"cat is at ";INSTR(A$,"cat")
100REM Cut the text into words110 P=1120 REPEAT
130 S=INSTR(A$,"",P)
140IFS=0THENS=LEN(A$)+1150PRINTA$(P,S-1)
160 P=S+1170 UNTIL P>LEN(A$)
Riadok 50: veľkými písmenami tam nie je – INSTR porovnáva presne. Výsledok 0 znamená „nenašlo sa“, a keďže nula je v podmienke „neplatí“, dá sa písať rovno IF INSTR(A$,"fox") THEN ….
Riadok 60:UINSTR na veľkosti písmen nehľadí.
Riadok 80: tretie číslo hovorí, odkiaľ hľadať. Prvé o je na mieste 13; hľadanie od 14 nájde ďalšie.
Riadky 110 až 170: rozdelenie vety na slová – základ každej textovej hry. P je začiatok slova, S miesto najbližšej medzery za ním. Keď už medzera nie je, slovo siaha po koniec textu.
10REM INKEY$ and GET: keys without RETURN20DIMK$(1)
30PRINT"Press keys, Q ends"40DO50K$=INKEY$60IFK$<>""
70PRINTK$;" has the code ";ASC(K$)
80IFK$="Q"THENEXIT90 ENDIF
100LOOP110PRINT"One more key to finish"120 GET K
130PRINT"It was ";CHR$(K)
Bash
Basic26keys.tbas--run
Riadok 50:INKEY$nečaká. Keď nie je stlačené nič, vráti prázdny text a program beží ďalej – slučka sa točí a môže medzitým robiť iné veci (hýbať príšerami, počítať čas). To je rozdiel oproti INPUT.
Riadok 120:GET K bez kanála naopak čaká, kým kláves príde. Hodí sa na „stlač kláves a pokračujeme“. Vráti kód ATASCII, nie číslo klávesu ako PEEK(764).
V Atari BASICu bolo na to isté treba otvoriť kanál na zariadenie K: (kapitola 24).
Opačným smerom funguje PUT bez kanála: PUT 65,66 vypíše na obrazovku znaky s kódmi 65 a 66, teda AB.
funkcia: počet päťdesiatin sekundy od zapnutia počítača
TIME$
funkcia: ten istý čas ako text HHMMSS – hodiny, minúty, sekundy
PAUSE n
príkaz: počkaj n päťdesiatin sekundy
Päťdesiatina sekundy je čas, za ktorý Atari nakreslí jeden obraz na televízore. PAUSE 50 je teda sekunda, PAUSE 25 pol sekundy, PAUSE 1 najkratšia možná prestávka.
10REM TIME, TIME$ and PAUSE20 T=TIME
30FORI=1TO100:X=SQR(I):NEXTI
40PRINT"A hundred square roots took ";(TIME-T)/50;" s"50PRINT"Since the start: ";TIME$60FORN=3TO1STEP-170PRINT N
80PAUSE5090NEXTN
100PRINT"Go!"
Riadok 40: rozdiel TIME-T je počet päťdesiatin, ktoré medzitým ubehli; delené 50 sú to sekundy. Takto sa meria rýchlosť kusu programu – a porovnáva sa interpreter s preloženým programom.
Riadok 50:TIME$ má vždy šesť číslic: 000003 sú tri sekundy od zapnutia. Hodiny a minúty z neho vyberieš ako z každého reťazca – po priradení do premennej T$ sú minúty T$(3,4).
Riadok 80:PAUSE 50 čaká sekundu, nech je počítač akokoľvek rýchly. Je to náhrada čakacej slučky FOR W=1 TO 500:NEXT W, ktorá v preloženom programe trvá len zlomok toho, čo v interpreteri.
Hlavná slučka hry potrebuje rovnomerné tempo. PAUSE 1 alebo PAUSE 2 na jej konci ju „prilepí“ na obraz televízora: pohyb je plynulý a rovnako rýchly v interpreteri aj v preloženom programe.
PEEK a POKE pracujú s jedným bajtom. Turbo-BASIC XL pridáva príkazy pre dva bajty naraz a pre celé kusy pamäte: skopírovať ich inam, zapísať do súboru, prečítať zo súboru. Čo v Atari BASICu trvalo slučkou sekundy, je tu jeden príkaz.
Riadok 20: adresa obrazovky jedným slovom namiesto PEEK(88)+256*PEEK(89).
Riadky 30 a 40:DPOKE rozdelí číslo na dva bajty: 12345 je 57 + 256 × 48. Menší bajt je na nižšej adrese.
Riadok 70:MOVE skopíruje päť bajtov zo začiatku A$ na začiatok B$. Pracuje s pamäťou, nie s reťazcami – o dĺžkach ani o DIM nevie nič, takže nepíš viac bajtov, než má cieľ miesta.
Riadok 90: zdroj a cieľ sa prekrývajú: desať bajtov sa posúva o dve miesta doprava v tom istom reťazci. Obyčajný MOVE by si pri kopírovaní od začiatku prepísal to, čo ešte len má skopírovať. -MOVE ide od konca a prekrytie mu nevadí. Pravidlo: pri posune k vyšším adresám -MOVE, k nižším MOVE.
Riadok 130:BPUT zapíše 12 bajtov pamäte do súboru jedným príkazom. Tak sa ukladá obrázok, znaková sada alebo pole.
Riadok 140:%PUT zapíše číslo presne tak, ako je v pamäti – šesť bajtov. Oproti PRINT #1;X sa nič nestratí zaokrúhlením a číta sa rýchlejšie.
Riadky 180 a 190: to isté naspäť, v tom istom poradí.
10REM CIRCLE, PAINT, FILLTO and TEXT20 GRAPHICS 730 COLOR 140CIRCLE40,40,2550CIRCLE110,30,40,1260 COLOR 270 PAINT 40,4080 COLOR 3:FCOLOR 390PLOT130,75:DRAWTO 130,60100PLOT90,60:FILLTO 90,75110 COLOR 1120 TEXT 96,27,"HI"130 LOCATE 40,40,C:PRINT"Inside the circle: ";C
140 LOCATE 110,70,C:PRINT"Inside the box: ";C
V emulátore: vľavo oranžová kružnica vyplnená zelenou, vpravo hore plochá elipsa s nápisom HI vo vnútri a pod ňou plný modrý obdĺžnik. V textovom okne (a v simulátore):
Riadok 50: štyri čísla dajú elipsu – 40 bodov na šírku od stredu, 12 na výšku.
Riadok 70:PAINT začne v strede kružnice a rozleje pero 2 všetkými smermi, kým nenarazí na body inej farby než pozadie. Kružnica je uzavretá, takže farba ostane vnútri. Keby mala hranica dieru, farba by vytiekla a zaliala celú obrazovku.
Riadky 90 a 100:FILLTO potrebuje najprv pravú hranu. Riadok 90 ju nakreslí ako zvislú čiaru na x=130. Riadok 100 postaví pero na ľavý horný roh a FILLTO kreslí ľavú hranu smerom nadol; z každého jej bodu vyplní riadok doprava, až po hranu z riadka 90. Farbu výplne určuje FCOLOR.
Riadok 120:TEXT nakreslí písmená z bodov, v každom grafickom režime a na ľubovoľnom mieste – nie len v textovom okne. Písmeno má 8 × 8 bodov.
Riadky 130 a 140:LOCATE potvrdí, že vnútro kruhu má pero 2 a vnútro obdĺžnika pero 3.
Výška tónu v príkaze SOUND je číslo 0 až 255. To je málo: vysoké tóny sú od seba ďaleko a ladia falošne, hlboké sa nedajú zahrať vôbec. Atari vie dva hlasy spojiť do jedného s výškou 0 až 65535 – jemnejšou 256-krát. Turbo-BASIC XL má na to DSOUND (double sound).
hlas 0 je spojenie obyčajných hlasov 0 a 1, hlas 1 spojenie hlasov 2 a 3
výška
0–65535
menšie číslo je vyšší tón
skreslenie
párne 0–14
10 je čistý tón, ako pri SOUND
hlasitosť
0–15
DSOUND bez čísel vypne všetko. Aj SOUND bez čísel vypne všetky štyri hlasy naraz.
Z dvoch dvojíc sú len dva spojené hlasy, takže naraz zahráš najviac dva jemne ladené tóny namiesto štyroch hrubých.
Čísla výšky nie sú tie isté ako pri SOUND. Približne platí: výška pre DSOUND je 28-násobok výšky pre SOUND s tým istým tónom. Stredné C (SOUND 121) je asi 3413.
Riadok 20: výška ide od 2000 po 500 po dvadsiatich – 76 krokov. S obyčajným SOUND by ten istý rozsah mal len asi päťdesiat stupňov a bolo by počuť „schody“.
Riadok 40:PAUSE 1 počká jednu päťdesiatinu sekundy (kapitola 33).
Riadky 60 a 70: vypnutie. Po DSOUND ostane Atari prepnuté do režimu spojených hlasov; SOUND bez čísel ho vráti do obyčajného.
V Atari BASICu sa súbory mazali a premenovávali krkolomným XIO (kapitola 24) a zoznam súborov na diskete sa z programu vypísať skoro nedal. Turbo-BASIC XL má na prácu s disketou obyčajné príkazy.
Tieto príkazy vykonáva DOS, takže program potrebuje disketu s DOS-om. Voľba --atr ju vyrobí, uloží na ňu preložený program a --run z nej emulátor naštartuje (kapitola 41):
Bash
Basic26disk.tbas--atrdisk.atr--run
Simulátor operácie DOS-u nevie, v ňom tento program neskúšaj.
Riadok 20: program si najprv vyrobí malý súbor, aby mal s čím pracovať.
Riadok 30:DIR so vzorom vypíše súbory s príponou TXT. Každý riadok je meno, prípona a veľkosť v sektoroch (sektor má 125 bajtov dát). Posledný riadok hovorí, koľko sektorov je na diskete ešte voľných.
Riadok 40: staré meno aj nové v jednom texte, oddelené čiarkou.
Riadok 60: zamknutý súbor má vo výpise na začiatku hviezdičku.
Riadok 80: zamknutý súbor zmazať nejde – chyba 167. Pasca na riadku 70 pošle program na návestie LOCKED.
Riadky 130 až 150: po odomknutí už DELETE prejde a súbor zo zoznamu zmizne; voľných sektorov je o jeden viac.
DIR bez vzoru vypíše všetko, čo na diskete je – aj súbory DOS-u (DOS.SYS, DUP.SYS) a tvoj program (AUTORUN.SYS).
Súbory so strojovým kódom majú na Atari vlastný formát: nesú v sebe adresy, kam sa majú nahrať (je to ten istý formát ako .xex). BLOAD taký súbor nahrá na jeho miesto a program pokračuje – takto si dobové programy nahrávali rutiny pre USR, znakové sady a obrázky. BRUN ho po nahratí aj spustí; keď sa strojový kód vráti, pokračuje program ďalším príkazom.
ZX-Basic
10 BLOAD "D:FONT.OBJ"20POKE756,152
V preloženom programe býva pohodlnejšie taký súbor pribaliť voľbou --embed (kapitola 43) – nahrá sa spolu s programom a disketu netreba.
Riadok 20: od tohto miesta program pred každým riadkom, na ktorý príde, vypíše jeho číslo.
Prvý riadok výstupu je stopa: 30, potom trikrát 40 a 50 (telo slučky), a 60, kde sa stopovanie vypne. Vidíš presne, koľkokrát slučka prebehla a kam sa skákalo. Keď program „niekam zmizne“, stopa ukáže kam.
Riadok 110: pole má prvky 0 až 5. Pre I = 6 je to chyba 9.
Riadok 140:ERR a ERL povedia, čo a kde sa stalo. Vypísať si pri chybe aj hodnoty premenných býva najrýchlejšia cesta k príčine.
Stopa spomaľuje a zaplní obrazovku, preto sa zapína len okolo podozrivého miesta.
Prvá slučka (bez *F) vypíše once, druhá sa preskočí celá. Je to rozumnejšie správanie a v nových programoch sa *F oplatí dať na začiatok; dobové programy však niekedy s jedným prechodom počítajú.
Bežne kláves BREAK program zastaví s hlásením STOPPED AT LINE …. Po *B sa BREAK stane chybou číslo 128, ktorú zachytí TRAP. Program tak môže pred koncom upratať – zavrieť súbory, vypnúť zvuk – alebo BREAK úplne ignorovať:
DUMP (výpis všetkých premenných), RENUM (prečíslovanie riadkov), DEL (zmazanie riadkov) a *L sú príkazy editora Turbo-BASICu. V preloženom programe len vypíšu NOT IN COMP PRG, tak ako LIST v kapitole 25.
Doteraz si prekladač volal dvoma spôsobmi: Basic26 program.abas --sim a --run. Vie toho viac. Táto kapitola prejde voľby, ktoré sa píšu na príkazový riadok – najprv tie, ktoré použiješ často, potom tie na zvláštne príležitosti. Všetky sú zhrnuté v prílohe B.
10REM A program to try the options of the compiler on20FORI=1TO530PRINT I;" squared is ";I*I;", its root ";SQR(I)
40NEXTI
50PRINT"Press START"60IFPEEK(53279)<>6THEN6070PRINT"Thank you"
Riadok 60 čaká na kláves START (kapitola 22). V simulátore ho „stlačí“ voľba --sim-console:
Bash
Basic26options.abas--sim--sim-console6@20000
1 squared is 1, its root 1
2 squared is 4, its root 1.41421356
3 squared is 9, its root 1.7320508
4 squared is 16, its root 2
5 squared is 25, its root 2.23606797
Press START
Thank you
6@20000 znamená: po dvadsaťtisíc krokoch procesora nech PEEK(53279) vracia 6 (START). Viac klávesov za sebou sa oddelí čiarkou: 6@20000,7@30000,5@40000.
meno výsledného súboru; bez nej je to meno programu s príponou .xex
-v
vypíše, čo prekladač robí
--list súbor
zapíše program ako čitateľný text
--scramble
zakóduje výsledný súbor, aby sa v ňom nedalo nič prečítať (kapitola 48)
Bash
Basic26options.abas-ostart.xex-v
reading options.abas (7 lines, text, Atari BASIC)
peephole: 7 change(s); runtime: 14845 byte(s) left out
wrote start.xex (3555 bytes, 5 segment(s), 3527 bytes of program)
Prvý riadok hovorí, ako prekladač program prečítal – tu ako text v Atari BASICu. Pri programe v Turbo-BASICu XL pribudne riadok so slovami, ktoré z neho program naozaj používa (Turbo-BASIC XL: DIV MOD WHILE). Druhý riadok hovorí, koľko zo svojej knižnice prekladač vynechal: do programu sa dostanú len tie rutiny, ktoré naozaj potrebuje. Tretí je veľkosť výsledku.
upozorní (a zastaví preklad) tam, kde by pôvodný interpreter program odmietol alebo kde preložený program robí len náhradu
--quirks
prijme aj to, čo interpreter prijme a čo zlyhá až počas behu
--no-line-numbers
program v Turbo-BASICu XL bez čísel riadkov (kapitola 47)
Na dialekte záleží viac, než sa zdá:
ZX-Basic
10 X=5:PRINT X DIV 2
Ako Turbo-BASIC XL vypíše 2. Ako Atari BASIC vypíše 502 – tam je DIV meno premennej (s nulou) a PRINT vypíše tri veci za sebou.
--quirks je pre dobové programy. Príklad: GOTO 100 v programe, ktorý riadok 100 nemá. Interpreter taký program spustí a chybu 12 ohlási, až keď na GOTO príde – a veľa programov naň nepríde nikdy. Prekladač to bežne odmietne (error B26012: line 100 does not exist); s --quirks z toho spraví upozornenie a chybu 12 nechá na beh.
program o niečo menší (až o 500 bajtov) a o niečo pomalší
-O0
nič sa nevynecháva ani nezlepšuje; len na skúmanie prekladača
--rom-fp
počíta rutinami operačného systému namiesto vlastných: pomalšie, ale asi o 1 700 bajtov menej
Program options.abas:
Voľby
Veľkosť .xex
(žiadne)
3 555 bajtov
--rom-fp
2 078 bajtov
-O0
19 640 bajtov
Kedy na tom záleží: veľký dobový program, ktorý sa s interpreterom do pamäte zmestil a preložený skončí chybou 2 pri DIM. Vtedy skús -O1 a --rom-fp (a kapitolu 42). Výsledky výpočtov sú pri všetkých voľbách do poslednej číslice rovnaké.
kde je ATARIXL.ROM, ak ho simulátor nenájde sám (bez neho vezme altirraos-xl.rom)
Čo simulátor vie a nevie:
Vie
Nevie
výpis, INPUT zo súboru, počítanie
písať na klávesnici – kláves je len to, čo je v --sim-input
súbory na D: (v pamäti, do konca behu)
ukázať obrázok, zahrať zvuk
kreslenie do pamäte: PLOT, DRAWTO, LOCATE, CIRCLE, PAINT; obrazovka a zoznam displeja ležia tam, kde ich má operačný systém
nárazy hráčov a striel (PMHIT je vždy 0)
joystick a tlačidlá z --sim-stick a --sim-trig (bez nich stojí: STICK 15, STRIG 1)
operácie DOS-u: DIR, RENAME, DELETE
hodiny: snímka je 10 000 krokov, PEEK(20), TIME a PAUSE bežia
banky a RAM pod ROM (--sim-mem)
Náhodné čísla sú v ňom pri každom spustení rovnaké. Keď program neskončí, simulátor to po limite vzdá hlásením error B26213: instruction limit reached.
Dlhý rad volieb sa dá uložiť do súboru a odovzdať so zavináčom. Súbor book.args:
# options for the book
-o start.xex
--sim --sim-console 6@20000
Bash
Basic26options.abas@book.args
Voľby v súbore oddeľujú medzery alebo konce riadkov; riadok so znakom # na začiatku je komentár. Voľby, ktoré patria k programu natrvalo, je lepšie napísať rovno doň – kapitola 40.
Niektoré voľby patria k programu natrvalo: hra potrebuje svoju znakovú sadu, veľký program sa bez --rom-fp nezmestí, textovka má texty v skrytej pamäti. Písať ich zakaždým na príkazový riadok je otravné a ľahko sa na niektorú zabudne. Program si ich preto môže niesť sám, v komentári na svojom začiatku.
pre interpreter je to obyčajný komentár – program ostáva platným BASICom
@COMPILE
značka, podľa ktorej riadok spozná prekladač
voľby
to isté, čo by si napísal na príkazový riadok
Pravidlá:
Riadky REM @COMPILE musia byť na začiatku programu, pred prvým príkazom. Môže ich byť viac za sebou.
Číslo riadka nie je povinné: REM @COMPILE --rom-fp na úplne prvom riadku súboru platí tiež. Hodí sa to pre dobové výpisy, kde nechceš meniť čísla riadkov.
Cesty k súborom (--embed font.fnt) sa počítajú od priečinka, v ktorom leží program – nie od miesta, kde stojíš v príkazovom riadku.
Príkazový riadok. Keď má program REM @COMPILE -O1 a ty napíšeš -O2, platí -O2 a prekladač na to upozorní. Voľby, ktoré sa dajú zopakovať (--embed, --file, --line-delay), sa sčítajú – platia tie z programu aj tie z príkazového riadka.
Keď chceš hlavičku programu na jeden preklad vypnúť:
Program, ktorý používa niečo nové, môže povedať, od ktorej verzie prekladača ho treba prekladať:
ZX-Basic
0REM @VERSION 1.0.0.150
Starší prekladač ho odmietne s jasnou správou, namiesto aby hlásil chyby v riadkoch, ktorým ešte nerozumie:
config.abas(1,1): error B26232: this program needs Basic26 1.0.0.150 or newer, this is 1.0.0.140
Verziu svojho prekladača zistíš cez Basic26 --version (kapitola 1). Stačia aj prvé tri čísla (1.0.0). Rovnako ako REM @COMPILE platí len v riadkoch, ktorými sa program začína, a pre interpreter je to komentár. V prekladači Action26 je to ;@version.
Program preložený s --int počíta celými číslami. Ktoré premenné majú predsa držať desatinné čísla, povie ďalší riadok na začiatku programu, REM @FLOAT X,Y,A( – podrobne v kapitole 50.
Atari ukladalo programy na diskety. Dnes sa disketa uchováva ako jeden súbor na PC – obraz diskety s príponou .atr. Emulátor s ním zaobchádza ako so skutočnou disketou a na internete sú v tomto tvare tisíce diskiet s dobovými programami.
Basic26 vie s obrazmi diskiet tri veci:
uložiť preložený program na disketu tak, aby sa po zapnutí Atari sám spustil,
pozrieť, čo na diskete je,
prečítať program rovno z diskety – a to aj v tvare, v akom ho uložil interpreter.
DOS 2.5 je ten, ktorý Atari dodávalo. --dos vyberie iný: mydos, sparta (SpartaDOS), bwdos, litedos, wolfdos, alebo cestu k vlastnému obrazu diskety, ktorý sa použije ako vzor. Každý DOS spúšťa programy po štarte pod iným menom; prekladač to vie a použije správne.
Preložený program po skončení stojí a nechá obrazovku tak, ako je. Program, ktorý sa má spúšťať z DOS-u ako nástroj a po skončení sa doň vrátiť, sa prekladá s --exit-to-dos.
Keby si STARS.BAS z diskety vytiahol a otvoril v editore, uvidel by si nezmysly. Interpreter totiž program neukladá ako text, ale tak, ako ho má v pamäti: každý príkaz je jeden bajt, čísla sú v šiestich bajtoch, mená premenných v tabuľke na začiatku. Prekladač tento tvar pozná a číta ho priamo.
Keď chceš program vidieť – a upravovať –, nechaj si ho vypísať:
10REM STARS - AN OLD PROGRAM SAVED ON A DISK20FORR=1TO530FORS=1TOR:PRINT"*";:NEXTS
40PRINT50NEXTR
To je ten istý text, aký by na Atari vypísal príkaz LIST. Dá sa upraviť a preložiť ako každý iný program:
Bash
Basic26stars.abas--sim
*
**
***
****
*****
Výpis je v kódovaní UTF-8: grafické znaky Atari, ktoré v dobových programoch bývajú v textoch, sa prevedú na podobné znaky, ktoré editor na PC vie ukázať, a pri preklade zasa naspäť. Z výpisu vznikne bajt po bajte ten istý program ako z pôvodného súboru. --list-atascii nechá bajty tak, ako sú – to treba, keď má výpis ísť späť na disketu pre skutočné Atari.
S voľbou -v prekladač povie, čo o programe zistil:
Interpreter pri ukladaní zahodil medzery (okrem tých v textoch a komentároch) a všetko previedol na veľké písmená. Výpis ich preto nemá. Niektoré programy boli proti čítaniu chránené – zmazané mená premenných, pokazené dĺžky riadkov. Prekladač si s bežnými ochranami poradí; premenné bez mien dostanú vo výpise mená V0, V1$, V2(.
Dobové nástroje vedeli program v BASICu „zabaliť“ do spustiteľného súboru, ktorý si so sebou niesol kópiu pamäte interpretera. Aj z takého súboru sa dá program dostať:
Bash
Basic26hra.xex--savehra.bas--listhra.abas
--save zapíše program tak, ako by ho uložil SAVE, --list ako text. (Samotný .xex na vstupe sa neprekladá – len sa z neho číta.)
Texty českých hier sa na Atari písali vlastnou znakovou sadou, v ktorej písmená s diakritikou ležia na miestach iných znakov. Výpis, ktorý niekto prepísal na PC s normálnymi českými písmenami (v kódovaní Windows-1250), prevedie na kódy tejto sady voľba --from-cp1250.
Program, ktorý si napíšeš sám, sa do pamäte zmestí a o tom, kde v nej leží, nemusíš vedieť nič. Túto kapitolu budeš potrebovať v dvoch prípadoch:
veľký program, ktorému pri DIM dôjde pamäť (chyba 2),
dobový program, ktorý počíta s tým, ako pamäť vyzerala v interpreteri: na pevnú adresu si dáva znakovú sadu, číta vlastné riadky REM, alebo má tempo postavené na pomalosti interpretera.
10REM Where the program lies and how much is left20PRINT"Free for DIM: ";FRE(0)
30PRINT"Top of memory: ";PEEK(106)*25640PRINT"The screen is at ";PEEK(88)+256*PEEK(89)
Bash
Basic26place.abas--sim
Free for DIM: 37879
Top of memory: 49152
The screen is at 48192
Prvé číslo sa bude s verziou prekladača trochu meniť; dôležité je, ako ho menia voľby:
Program skončí s ERROR- 2 pri DIM, hoci v interpreteri bežal. Preložený program totiž nie je vždy menší než ten istý program v interpreteri – nesie si so sebou knižnicu. Čo skúsiť, v tomto poradí:
--rom-fp – asi o 1 700 bajtov menej, program počíta o niečo pomalšie.
-O1 – až o 500 bajtov menej.
--origin $0700 – program sa začne nižšie a získa 6 400 bajtov. Na adrese $0700 však býva DOS, takže to ide len pre program, ktorý nepracuje s disketou a spúšťa sa bez DOS-u (z emulátora cez --run, alebo zo zavádzača hier).
--pack-text – texty zbalené na dve tretiny (kapitola 46).
--text-under-rom – texty v pamäti, ktorú inak nevyužiješ (kapitola 46).
Netreba čakať, kým program spadne na DIM. Voľba --memory po preklade povie, koľko pamäte program zaberá a koľko jej zostáva:
Bash
Basic26place.abas--memory
Basic26: memory [#-----------------------------] 5 % full
used by the program: 2121 bytes
still free: 37847 bytes
of it for DIM: 37847 bytes (the heap, which FRE(0) shows at the start)
biggest free piece: 37847 bytes
(counted between $2000 and $BC1F; --mem-lo and --mem-top change that, --memory-map lists every piece)
Riadok of it for DIM je pamäť pre reťazce a polia – približne to, čo program na začiatku uvidí vo FRE(0). Biggest free piece je najväčší súvislý kus: nové pole sa musí zmestiť do jedného.
--memory-map vypíše každý kus pamäte s adresami. Tu s pamäťou, ktorú si program necháva voľnú (--reserve, nižšie):
Basic26: memory $2000-$BC1F
Basic26: program $2000-$27DB 2012 bytes
Basic26: free $27DC-$7FFF 22564 bytes (the heap: DIM and strings)
Basic26: reserved $8000-$8FFF 4096 bytes
Basic26: program $9000-$9070 113 bytes
Basic26: free $9071-$BC1F 11183 bytes
Vidno z neho, prečo s --reserve klesne FRE(0) na 22 563: halda nepreskočí vyhradenú pamäť a nad ňou ostane 11 KB, na ktoré DIM nedosiahne. S oboma voľbami naraz príde najprv zoznam a za ním súhrn.
Počíta sa od začiatku programu (--origin) po obrazovku ($BC1F); inak to povedia --mem-lo a --mem-top. Číslo sa s verziou prekladača trochu mení. Voľby sú tie isté ako v prekladači jazyka Action! Action26.
kde končí pamäť stroja, pre ktorý prekladáš (predvolene $C000)
--reserve A-B
pamäť od A po B nechaj voľnú – program ani jeho dáta tam nebudú; --memory ju počíta ako zabratú
--memory
po preklade súhrn: koľko pamäte program zaberá a koľko zostáva
--memory-map
každý kus pamäte s adresou: program, vyhradená, voľná, halda
--mem-lo A, --mem-top A
odkiaľ a pokiaľ --memory počíta (predvolene od --origin po obrazovku)
--basic-screen
obrazovka tam, kde ju mal program s interpreterom: $9C40 namiesto $BC40
--keep-rem
riadky REM ostanú v pamäti tak, ako ich držal interpreter
--line-delay N
každý riadok programu chvíľu počká
--exit-to-dos
po skončení programu návrat do DOS-u (kapitola 41)
Adresy sa píšu šestnástkovo s dolárom ($9800) alebo desiatkovo (38912). V PowerShelli daj adresu s dolárom do apostrofov ('$9800'), inak si ju PowerShell vyloží po svojom; v hlavičke REM @COMPILE apostrofy netreba.
Dobová hra si cez POKE ukladá mapu na adresy $7530–$797C. V interpreteri tam bolo voľno; preložený program by tam mohol mať svoje dáta a hra by si ich prepísala.
Bash
Basic26hra.abas--reserve'$7530-$797C'
Prekladač tú oblasť obíde. Kód programu sa však rozdeliť nedá: musí sa celý zmestiť pred rezervu, za ňu idú už len texty, dáta a voľná pamäť.
Najčastejší dobový trik: program zníži číslo na adrese 106 (koniec pamäte v stránkach), zavolá GRAPHICS a tým si nad obrazovkou vyhradí miesto na znakovú sadu alebo postavičky. Prekladač na to upozorní:
warning B26230: this program moves the top of memory (POKE 106); the compiled program reaches $2622, and whatever it reserves below that lands inside it
Hlásenie hovorí, pokiaľ preložený program siaha. Ak je vyhradená oblasť nad touto adresou, je všetko v poriadku. Ak nie, treba program zmenšiť voľbami vyššie.
S cartridge BASICu končila pamäť na $A000 a obrazovka ležala na $9C40. Program, ktorý tie adresy má napísané natvrdo (vlastný zoznam displeja na $9C20, POKE rovno do obrazovky), sa prekladá s --basic-screen. Pamäť $A000–$BFFF, kde bola cartridge, pritom preložený program ďalej využíva.
Niektoré programy majú v riadkoch REM schované dáta – znakovú sadu alebo strojový kód – a čítajú ich rovno z pamäte, kde mal interpreter text programu. Prekladač komentáre bežne zahadzuje. Keď v úvodných riadkoch REM nájde bajty, ktoré nie sú text, nechá ich sám a upozorní:
warning B26231: this REM line holds bytes rather than text, so the REM lines the program begins with (10 to 10) are kept in memory the way the interpreter holds them
--keep-rem nechá všetky riadky REM, --keep-rem=0-9,500 len vymenované, --keep-rem=none žiadne.
Melódia alebo animácia v dobovom programe je často načasovaná len tým, ako dlho interpreteru trvalo vykonať riadok. Preložená prebehne niekoľkokrát rýchlejšie. Lepšie je program opraviť – čakať podľa hodín (kapitola 18). Keď to nejde, dá sa spomaliť zvonka:
Bash
Basic26hra.abas--line-delay369@9165-9190
Každý vykonaný riadok s číslom 9165 až 9190 počká 369 × 100 cyklov procesora (asi päťdesiatinu sekundy). Bez rozsahu (--line-delay 50) čaká každý riadok programu. Voľba sa dá zopakovať pre rôzne časti programu. Správne číslo treba nájsť skúšaním proti originálu.
Spusti place.abas s --origin '$0700' a s --rom-fp a porovnaj voľnú pamäť.
Pridaj do place.abas riadok 15 DIM A(5000),B(1400) – dve polia, spolu vyše 38 kilobajtov – a zisti, s ktorými voľbami prejde a s ktorými skončí chybou 2.
Pridaj --line-delay 2000 k programu for.abas z kapitoly 10 a spusti ho v emulátore.
Hra nie je len program. Patrí k nej znaková sada, obrázok, mapa, hudba, kus strojového kódu. V interpreteri sa to všetko nahrávalo z diskety – zvlášť, po častiach, často zavádzačom, ktorý dnes nikto nemá. Prekladač vie také súbory pribaliť do výsledného .xex: nahrajú sa spolu s programom a program ich nájde tam, kde ich čaká.
Súbor examples/level.dat má 40 bajtov – mapu miestnosti, päť riadkov po osem znakov:
########
#..$...#
#.##.#.#
#....*.#
########
(V súbore sú za sebou bez koncov riadkov.) Súbor examples/embed.abas ho má pribalený na adrese $9000, desiatkovo 36864:
ZX-Basic
0REM @COMPILE --embed level.dat@$900010REM A file carried in the program: a map at address $900020 A=3686430FORR=0TO440FORC=0TO750PRINTCHR$(PEEK(A+R*8+C));
60NEXTC
70PRINT80NEXTR
Riadok 0: prekladač pri preklade prečíta level.dat z priečinka programu a vloží ho do embed.xex. Pri nahrávaní programu sa tých 40 bajtov uloží na adresy $9000–$9027.
Riadok 50: program ich číta obyčajným PEEK. Nemusel nič otvárať ani nahrávať – dáta sú v pamäti skôr, než sa vykoná prvý riadok.
Prekladač vie, že na $9000 niečo leží, a vyhne sa tomu: voľná pamäť pre DIM sa rozdelí tak, aby reťazce a polia súbor neprepísali.
Najčastejšie použitie. Znaková sada Atari má 1 024 bajtov (128 znakov po 8 bajtoch) a musí začínať na adrese deliteľnej 1024:
ZX-Basic
0REM @COMPILE --embed myfont.fnt@$980010POKE756,152:REM 152 = $98, the page the font begins on20PRINT"Text in my own letters"
Adresa 756 hovorí Atari, na ktorej stránke pamäte (adresa delená 256) znaková sada leží. Jeden POKE – a celá obrazovka má iné písmo. Tak sú urobené české a slovenské textové hry: písmená s diakritikou sú nakreslené v sade na miestach menej používaných znakov.
Atari písmená ako č alebo š nemá. Keď ich napíšeš do textu programu, prekladač nevie, na ktorom mieste ich tvoja znaková sada má – urobí z nich otáznik a upozorní na to:
warning B26210: a character ATASCII does not have is a '?' in the program (--charmap says where the program's character set keeps it)
Povedz mu to súborom s mapou znakov. Je to obyčajný text (UTF-8), na každom riadku znak, medzera a jeho kód v sade – desiatkovo, alebo so znakom $ šestnástkovo. Riadok, ktorý sa začína bodkočiarkou, je poznámka. Súbor examples/letters.map:
; letters.map - where the character set keeps the Czech letters
á $01
č $03
ě $05
š $13
ž $1A
0REM @COMPILE --charmap letters.map10REM Czech letters go where the program's character set keeps them20DIMA$(10)
30A$="čaj"40FORI=1TOLEN(A$)
50PRINT ASC(A$(I,I))
60NEXTI
3
97
106
Písmeno č je v programe jeden bajt s kódom 3 – so znakovou sadou, ktorá má na tom mieste nakreslené č, ho PRINT ukáže správne. Mapa platí pre texty v úvodzovkách aj pre DATA. Smú v nej byť len znaky, ktoré Atari nemá; obyčajné písmená a číslice ostávajú, čím sú.
Pamäť obrazovky nedrží znaky v tých istých kódoch ako PRINT (kapitola D): medzera je tam 0 a A 33. Program, ktorý píše na obrazovku sám – cez POKE alebo MOVE –, musí každý znak prepočítať, a to je v BASICu pomalé.
S voľbou --screen-codes uloží prekladač každý text v úvodzovkách už prepočítaný. Celé slovo alebo riadok potom zapíše jeden príkaz:
ZX-Basic
T$="Ahoj"MOVE ADR(T$),DPEEK(88)+40,LEN(T$)
Platí to pre všetky texty v programe naraz. Čo ide cez PRINT alebo ako meno súboru do OPEN, vyjde zle – voľba je pre program, ktorý nič z toho nerobí. DATA ostávajú, ako boli.
Súbor .xex nesie v sebe adresy, kam jeho časti patria, preto sa adresa nepíše. Prekladač z neho vezme všetky časti okrem pokynu „spusti sa“ – spustiť sa má tvoj program, nie pribalený. Tak sa k preloženej hre pripája pôvodný strojový kód (rutiny na zvuk, kreslenie, hudbu), ktorý hra volá cez USR.
Keď má pribalený kód bajt, ktorý v preloženom programe prekáža – napríklad zapína BASIC, ktorý už netreba –, opraví ho --patch:
Niektoré programy svoje dáta nečítajú z pamäte, ale zo súboru: OPEN #1,4,0,"D:LEVEL.DAT". Aby si k takému programu nemusel robiť disketu, dá sa súbor pribaliť aj tak. Súbor examples/carried.abas:
ZX-Basic
0REM @COMPILE --file D:LEVEL.DAT=level.dat10REM A file the program opens by name, carried inside it20OPEN #1,4,0,"D:LEVEL.DAT"30 TRAP 9040FORC=1TO850 GET #1,K:PRINTCHR$(K);
60NEXTC
70PRINT80GOTO4090CLOSE #1100PRINT"That was the whole file"
Bash
Basic26carried.abas--run
Program vypíše tú istú mapu a pod ňu That was the whole file – bez diskety a bez DOS-u. OPEN mena D:LEVEL.DAT číta z pamäte programu; čítanie za koncom je chyba 136 ako pri skutočnom súbore. Pribalený súbor sa dá len čítať; zápis doň je chyba 135. Iné mená idú ďalej na skutočnú disketu, ak nejaká je.
Tento program skúšaj v emulátore: simulátor má vlastné zaobchádzanie so súbormi a pribalený súbor nevidí.
Súbory sa dajú pribaliť aj do pamäte, ktorú program bežne nevidí – pod operačný systém a do rozšírenej pamäte (--embed súbor@$C000, --embed súbor@1:$4000). O tom je kapitola 44.
Atari XL má 64 kilobajtov pamäte, ale štvrtinu z nich zakrýva operačný systém: na adresách $C000–$FFFF procesor vidí ROM, a RAM, ktorá leží „pod ňou“, je bežne nedostupná. Atari 130XE a rôzne rozšírenia majú navyše desiatky až stovky kilobajtov v bankách – kusoch pamäte, z ktorých je naraz vidieť len jeden, cez okno na adresách $4000–$7FFF.
V interpreteri sa k tejto pamäti dalo dostať len strojovým kódom a s rizikom, že počítač zamrzne. Basic26 má na ňu vlastné slová, ktoré nepozná žiadny interpreter. Program cez ne číta a zapisuje skrytú pamäť tak jednoducho ako cez PEEK a POKE – obrazovka, zvuk aj klávesnica pritom bežia ďalej.
Na čo to je dobré: 14 kilobajtov pod ROM je miesto na texty hry, mapy, obrázky, uloženú pozíciu. Program v hlavnej pamäti tak môže byť väčší.
0REM @COMPILE --xmem10REM Hidden memory: the RAM under the ROM and the banks20PRINT"Banks of extended memory: ";XBANKS
30REM Bank 0 from 49152 on is the RAM under the operating system40 XPOKE 0,49152,12350PRINT"Under the ROM: ";XPEEK(0,49152)
60PRINT"The ROM itself: ";PEEK(49152)
70 XDPOKE 0,49154,1234580PRINT"Two bytes: ";XDPEEK(0,49154)
90DIMA$(20):A$="HELLO, HIDDEN RAM"100 XPUT 0,55296,A$110PRINTXGET$(0,55296,5)
120 XFILL 0,58368,100,42130 XMOVE 0,55296,0,58368,5140PRINTXGET$(0,58368,8)
150IFXBANKS=0THENPRINT"This machine has no banks":END
160FORB=1TOXBANKS:XPOKE B,16384,B*10:NEXTB
170FORB=1TOXBANKS:PRINT XPEEK(B,16384);"";:NEXTB
180PRINT
Riadky 40 až 60:XPOKE zapíše 123 do RAM pod ROM na adrese 49152. XPEEK ho odtiaľ prečíta. Obyčajný PEEK na tej istej adrese vidí ROM – iný bajt, 17. Sú to dve rôzne pamäte na jednej adrese.
Riadky 70 a 80: dvojbajtové číslo, ako DPOKE a DPEEK v Turbo-BASICu XL.
Riadok 100:XPUT uloží text reťazca pod ROM – len znaky, bez dĺžky.
Riadok 110:XGET$ z nich spraví reťazec, ktorý sa dá vypísať, priradiť alebo porovnať. Dĺžku treba povedať.
Riadok 120: sto hviezdičiek (kód 42) od adresy 58368.
Riadok 130:XMOVE skopíruje päť bajtov spod ROM inde pod ROM. Zdroj a cieľ môžu byť v rôznych bankách, alebo jeden z nich v hlavnej pamäti – napríklad XMOVE 0,ADR(A$),1,16384,LEN(A$) skopíruje reťazec do banky 1.
Riadok 150: program, ktorý má bežať aj na stroji bez rozšírenia, sa najprv spýta. Slučka na riadku 160 by na 64 KB stroji prebehla raz (FOR v Atari BASICu vždy aspoň raz) a skončila chybou.
Riadky 160 a 170: do každej banky iné číslo na tú istú adresu 16384 – a z každej sa prečíta to svoje.
RAM-disk. DOS na 130XE vie banky používať ako rýchlu „disketu“ D8:. Program o nej nevie a zápisom do banky jej súbory zničí.
XGET$ si miesto požičiava z voľnej pamäte, len na chvíľu. Dlhý reťazec potrebuje aspoň toľko voľného miesta (FRE(0)).
Strojový kód pod ROM. Ak pribalený strojový kód (kapitola 43) používa RAM pod ROM sám, pobije sa s tvojimi XPOKE o miesto. Prekladač to nevidí.
Emulátor. Program, ktorý používa len RAM pod ROM, beží na každom XL a XE. Program s bankami potrebuje emulátor nastavený ako 130XE alebo stroj s rozšírením.
Kapitola 44 ukázala, ako do skrytej pamäte zapísať bajt a prečítať ho. Táto ukazuje, ako ju naozaj využiť: dáta sa do nej nahrajú spolu s programom, texty sa vypisujú rovno z nej a obrazovka sa dá pripraviť v banke, kým sa díva iná.
Textová hra má stovky viet. V hlavnej pamäti zaberajú miesto programu; pod ROM neprekážajú nikomu. Súbor examples/rooms.dat obsahuje tri texty za sebou, každý ukončený bajtom 0. Súbor examples/xprint.abas:
ZX-Basic
0REM @COMPILE --xmem --embed rooms.dat@$C00010REM Texts kept under the ROM and printed from there20 A=4915230FORR=1TO340PRINT R;": ";
50 XPRINT 0,A,060PRINT70REM Step over the text and the nought that ends it80IFXPEEK(0,A)<>0THENA=A+1:GOTO8090 A=A+1100NEXTR
110PRINT"The texts take ";A-49152;" bytes under the ROM"
Riadok 0:rooms.dat sa nahrá pod ROM od adresy $C000 (49152). Program beží na každom XL a XE, banky nepotrebuje.
Riadok 50:XPRINT 0,A,0 vypíše text od adresy A po najbližší bajt 0. Dĺžku netreba vedieť a text nikdy neprejde cez hlavnú pamäť programu – môže byť ľubovoľne dlhý. Koniec riadka XPRINT nepridáva, preto je za ním PRINT.
Riadky 80 a 90: program si nájde začiatok ďalšieho textu: preskočí znaky až po nulu a nulu samu.
Skutočná hra by si začiatky textov nehľadala zakaždým, ale mala by ich v poli alebo v DATA: XPRINT 0,T(ROOM),0.
Tretie číslo je znak, ktorým text končí. Nula je zvyk; hodí sa aj 155 (koniec riadka) pre texty uložené po riadkoch.
Súbor examples/xbank.abas má tie isté texty v banke 1 a ukazuje presun medzi bankou a súborom:
ZX-Basic
0REM @COMPILE --xmem --embed rooms.dat@1:$400010REM The same texts in a bank of extended memory20PRINT"Banks: ";XBANKS
30 XPRINT 1,16384,040PRINT50REM A file into a bank and back out of it60OPEN #1,8,0,"D:COPY.DAT"70 XBPUT #1,1,16384,2580CLOSE #190OPEN #1,4,0,"D:COPY.DAT"100 XBGET #1,2,16384,25110CLOSE #1120PRINTXGET$(2,16384,25)
Bash
Basic26xbank.abas--sim--sim-mem130xe
Banks: 4
You are in a dark cellar.
You are in a dark cellar.
Riadok 70:XBPUT zapíše 25 bajtov z banky 1 do súboru – ako BPUT v Turbo-BASICu XL (kapitola 34), ale zdroj je v banke.
Riadok 100:XBGET ich prečíta do banky 2. Takto sa do bánk nahráva, čo sa do programu pribaliť nedá alebo nechce: ďalšia úroveň hry, uložená pozícia.
Po XBANK 1 je banka 1 v okne $4000–$7FFF stále. Obyčajné PEEK, POKE, MOVE aj strojový kód cez USR tam potom pracujú s bankou; XBANK 0 vráti hlavnú pamäť.
vypíše 0 77. Háčik je v hlavičke: XBANK smie len program preložený s --reserve $4000-$7FFF. Bez toho by v okne ležal sám program a banka by ho zakryla – prekladač to odmietne (error B26056). S rezervou musí kód programu skončiť pod $4000 a voľná pamäť pre DIM začína až na $8000.
Atari 130XE vie niečo zvláštne: obvod, ktorý kreslí obraz (ANTIC), sa môže dívať do inej banky než procesor. XANTIC 1 povie: „obraz ber z banky 1“. Program tak môže mať v bankách pripravených niekoľko obrazoviek a prepínať medzi nimi okamžite, alebo novú obrazovku kresliť tam, kam sa práve nikto nedíva. XANTIC 0 to vráti.
Funguje to na 130XE a rozšíreniach, ktoré to tiež vedia; na ostatných (napríklad RAMBO) skončí chybou 60. Obrazovka v banke sa nedá vyskúšať v simulátore – ten obraz nekreslí.
Hra s veľa dátami v bankách sa dlho nahráva. Dá sa preložiť na dva súbory:
Bash
Basic26xbank.abas--data-only-oxbank.dat
Bash
Basic26xbank.abas--code-only-oxbank.xex
xbank.dat obsahuje len to, čo ide do bánk a pod ROM. xbank.xex je program bez dát. Na Atari sa nahrá najprv xbank.dat, potom xbank.xex. Program pri štarte skontroluje, či dáta na mieste sú; ak nie, vypíše THE DATA FILE IS NOT LOADED a skončí. Pri ladení potom stačí znova nahrať len krátky program. Oba súbory musia byť preložené s rovnakými voľbami.
Pamäte je na Atari málo a dáta sa často opakujú: obrazovka je z polovice prázdna, texty sa skladajú z tých istých slov. Kompresia (zbalenie) také dáta zapíše úspornejšie; pred použitím sa rozbalia naspäť.
Basic26 vie dve veci:
zbaliť ľubovoľný súbor (obrázok, mapu, obrazovku) a v programe ho rozbaliť príkazom XUNPACK,
zbaliť texty programu – bez jedinej zmeny v programe, len voľbou prekladača.
S --pack prekladač nič neprekladá: vstup je hocijaký súbor a výstup ten istý súbor zbalený. --unpack robí opak (na kontrolu).
Súbor examples/title.scr je titulná obrazovka: 960 bajtov, presne toľko, koľko má textová obrazovka (40 × 24).
Bash
Basic26title.scr--pack-otitle.pak-v
packed title.scr: 960 -> 82 bytes (ZX02)
Z 960 bajtov je 82. (Obrazovka plná medzier a hviezdičiek sa balí výborne; fotografia by dopadla horšie.) Metóda sa volá ZX02 – je to obľúbený formát malých počítačov, lebo rozbaľovací program je kratučký. Keď sa súbor zbaliť nedá, uloží sa tak, ako je, a XUNPACK si poradí aj s tým.
Banka a adresa sú tie isté ako v kapitole 44: banka 0 je hlavná pamäť a od $C000 RAM pod ROM. Dĺžku si zbalené dáta nesú samy. XUNPACK je jedno zo slov rozšírenej pamäte, takže program potrebuje --xmem.
Riadok 40:XUNPACK číta zbalené dáta spod ROM (banka 0, adresa 49152) a rozbalených 960 bajtov píše do hlavnej pamäte od adresy obrazovky. Celá obrazovka sa objaví naraz – žiadnych 24 príkazov PRINT.
Zdroj aj cieľ môžu byť kdekoľvek: v hlavnej pamäti, pod ROM, v rôznych bankách. Obrázok sa dá rozbaliť z banky 1 na obrazovku, mapa spod ROM do reťazca (ADR(M$)).
Poznámka k súboru title.scr: sú v ňom kódy obrazovky, nie ATASCII. Obrazovka Atari si znaky ukladá pod inými číslami, než aké má CHR$ – medzera je 0, A je 33. Najjednoduchšie je nechať si obrazovku nakresliť programom a uložiť ju cez BPUT #1,DPEEK(88),960 (kapitola 34).
Textová hra je z veľkej časti text v príkazoch PRINT. Tri voľby s ním vedia naložiť úspornejšie – program sa pritom nemení:
Voľba
Čo robí
--pack-text
zbalí texty slovníkom častých dvojíc znakov; zaberú asi dve tretiny
--text-under-rom
presunie texty do RAM pod ROM; hlavná pamäť ostane programu
--text-in-banks
presunie texty do bánk rozšírenej pamäte (--text-in-banks=2 najviac do dvoch)
Týkajú sa textov v úvodzovkách dlhých 8 až 255 znakov. Pri použití sa text na chvíľu skopíruje (a rozbalí) do voľnej pamäte, vypíše a miesto sa uvoľní.
10REM A program with a lot of text20PRINT"You are standing in a dark cellar under the old house."30PRINT"The walls are wet and the air smells of earth and mould."40PRINT"A narrow corridor leads north, deeper under the house."50PRINT"Somewhere in the dark you can hear water dripping slowly."60PRINT"On the floor lies an old rusty key and a broken lantern."70PRINT"The stairs behind you have fallen in. There is no way back."80PRINT"The corridor turns east and ends at a heavy wooden door."90PRINT"The door is locked. Its keyhole is full of rust and dust."100PRINT"You are in a small round room with a well in the middle."110PRINT"The water in the well is black and you cannot see the bottom."120PRINT"A rope hangs down into the well. It looks old but strong."130PRINT"You climb down the rope into the dark and the cold."140PRINT"At the bottom of the well there is a low tunnel going west."150PRINT"The tunnel is so low that you have to go on your knees."160PRINT"You are in a large cave. Something is shining in the corner."170PRINT"In the corner of the cave stands an old chest bound with iron."180PRINT"The chest is open. It is full of old coins and broken glass."190PRINT"A cold wind is blowing from a crack in the wall of the cave."200PRINT"Behind the crack you can see daylight and hear the birds."210PRINT"You are out in the garden behind the old house. Well done!"
Bash
Basic26texts.abas--pack-text-v
texts packed: 20, 1145 -> 712 bytes with the dictionary
wrote texts.xex (2110 bytes, 6 segment(s), 2078 bytes of program)
Dvadsať textov, 1 145 znakov, sa zmestilo do 712 bajtov vrátane slovníka. Bez voľby má program 2 289 bajtov, s ňou 2 110 – hoci pribudol rozbaľovač. Pri skutočnej hre s desiatkami kilobajtov textu sú to kilobajty.
Bash
Basic26texts.abas--text-under-rom--pack-text-v
texts under the ROM: $E400-$E631 (562 bytes)
texts left in the program: 0 bytes
texts packed: 20, 1145 -> 712 bytes with the dictionary
Teraz texty neležia v hlavnej pamäti vôbec. Výstup programu je pri všetkých voľbách ten istý:
--pack-text samotná: program je menší, beží na každom stroji a s ničím sa nebije. Dobrá prvá voľba. Program s pár riadkami textu sa nezbalí – slovník by stál viac, než by ušetril.
--text-under-rom: uvoľní najviac hlavnej pamäte (až 13 KB). Nehodí sa, keď RAM pod ROM používa pribalený strojový kód.
obe naraz: pod ROM sa zmestí o polovicu viac textu.
--text-in-banks: pre naozaj veľké hry; program potom potrebuje stroj s bankami a inde sa nespustí.
Čísla riadkov sú dedičstvo editora na Atari: určovali poradie riadkov a boli jediným spôsobom, ako niekam skočiť. V textovom editore na PC poradie určuje súbor, a Turbo-BASIC XL má na skoky mená – návestia a procedúry (kapitola 30). Čísla sú potom len na obtiaž: treba ich vymýšľať a pri vkladaní riadkov prečíslovať.
Basic26 preto vie preložiť program v Turbo-BASICu XL napísaný úplne bez čísel riadkov. Je to rozšírenie prekladača – pôvodný interpreter taký súbor neprijme.
REM @COMPILE --no-line-numbersREM A program without line numbersDIMNAME$(20)
INPUT"Your name";NAME$
EXEC GREET
COUNT=0DO
COUNT=COUNT+1IFCOUNT>3THENEXITPRINT"Round ";COUNT
LOOPRESTORE #COLOURS
FORI=1TO3READNAME$PRINTNAME$;"";
NEXTI
PRINT
TRAP #OOPS
PRINT10/(COUNT-4)
END
# OOPS
PRINT"Error ";ERR;" at line ";ERL
END
PROC GREET
PRINT"Hello, ";NAME$;"!"
ENDPROC
# COLOURS
DATA red,green,blue
Prvý riadok zapína mód. Pre prekladač je to nastavenie, inak obyčajný komentár.
Program sa číta zhora nadol, tak ako je napísaný. Prázdne riadky ho len rozdeľujú na časti.
EXEC GREET volá procedúru na konci súboru, RESTORE #COLOURS nastaví čítanie dát na návestie, TRAP #OOPS pošle chybu na návestie. Nikde nie je číslo, na ktoré by sa dalo odvolať – a ani ho netreba.
Posledný riadok výstupu:COUNT je po slučke 4, takže 10/(COUNT-4) je delenie nulou. ERL hovorí 23 – a to je presne dvadsiaty tretí riadok súboru nolines.tbas. Stačí v editore skočiť na riadok 23.
Program čísla riadkov nemá, ale chyba ich potrebuje: ERROR- 11 OVERFLOW AT LINE 23, funkcia ERL, stopa TRACE. Prekladač preto každému riadku pridelí číslo, ktoré má v súbore – počítajú sa aj prázdne riadky a komentáre. Hlásenie za behu aj hlásenie prekladača (nolines.tbas(23,7): error …) tak ukazujú na to isté miesto.
Keď program narastie, oplatí sa ho rozdeliť: hlavný program hovorí, čo sa robí, a procedúry, ktoré to robia, ležia v inom súbore. Riadok
ZX-Basic
INCLUDE "incltools.inc"
vloží na svoje miesto všetky riadky súboru incltools.inc, akoby tam boli napísané. Funguje to len v programe bez čísel riadkov – s číslami by dva súbory priniesli tie isté čísla a nevedelo by sa, ktorý riadok platí. Je to rozšírenie Basic26, pôvodný interpreter INCLUDE nepozná, a preto ho treba zapnúť voľbou --modern (ako hráčov a strely v kapitole 49).
REM @COMPILE --no-line-numbers --modernREM The main program; its procedures are in incltools.inc
EXEC FRAME
PRINT" Hello from two files!"
EXEC FRAME
TRAP #OOPS
EXEC CHECK
END
# OOPS
PRINT"Error ";ERR;" at line ";ERL
END
INCLUDE "incltools.inc"
REM incltools.inc - procedures for inclmain.tbas
PROC FRAME
FORI=1TO27:PRINT"-";:NEXTI
PRINT
ENDPROC
PROC CHECK
DIMA(3)
K=5:A(K)=1
ENDPROC
Prekladá sa len hlavný súbor – vložený si prekladač nájde sám:
Bash
Basic26inclmain.tbas--run
---------------------------
Hello from two files!
---------------------------
Error 9 at line 24
INCLUDE stojí na riadku sám, za ním len meno v úvodzovkách. Meno sa hľadá v adresári súboru, ktorý ho napísal; D: pred menom sa zahodí a bez prípony sa skúsi .TBAS, .BAS a .LST.
Vložený súbor môže vkladať ďalší, najviac do hĺbky 16. Sám seba vložiť nemôže – ani cez iný súbor.
Vložené súbory nemajú REM @COMPILE a samy sa nepreložia, preto im je dobré dať inú príponu (tu .inc). Voľby platia z hlavného programu pre celý.
Číslo riadka je poradie v celom zloženom programe.INCLUDE je pätnásty riadok inclmain.tbas, takže vložený súbor začína riadkom 15 a jeho desiaty riadok K=5:A(K)=1 je riadok 24 – ten hlási ERL. Kde to je, ukáže --list: vypíše celý program v jednom súbore s číslami. Prekladač pri chybe v preklade hlási súbor a riadok v ňom, aj s riadkom, ktorý ho vložil – keby bol v CHECK riadok A(5)=1, ktorý je zlý už pri preklade:
incltools.inc(10,5): error B26009: A(5) is past DIM A(3)
inclmain.tbas(15,9): note: included from here
Väčší program z troch súborov je medzi príkladmi: examples/turbobasic/include/.
Texty, ktoré program vypisuje alebo s ktorými porovnáva, ležia v súbore .xex tak, ako si ich napísal. Kto súbor otvorí v editore, prečíta si ich – pri textovej hre aj celé riešenie, pri programe s heslom heslo.
Voľba --scramble urobí zo súboru taký, v ktorom sa nedá prečítať nič: ani texty, ani DATA, ani kód. Program pritom robí presne to isté a v zdrojáku nemeníš nič. Je to rozšírenie prekladača – robí sa až s hotovým súborom, takže platí pre Atari BASIC aj pre Turbo-BASIC XL.
10REM A file nobody can read: Basic26 secret.abas --scramble20DIMA$(20)
30PRINT"What is the password";:INPUTA$40IFA$="SESAME"THENPRINT"The door opens.":END
50PRINT"Nothing happens."
Heslo SESAME je v programe napísané ako text, s ktorým sa porovnáva odpoveď.
Prekladač hotový program prekódoval bajt po bajte a pridal k nemu krátky dekodér. Ten sa po nahratí súboru spustí ako prvý, vráti pamäť do pôvodného stavu a až potom spustí tvoj program. Program o dekodéri nevie.
Čo to stojí, povie -v:
wrote secret.xex (1849 bytes, 4 segment(s), 1709 bytes of program)
scrambled 1642 bytes (level 1, key $A7), decoder at $0600 (112 bytes), file 116 bytes longer
Súbor je dlhší asi o sto bajtov – tu 1 849 namiesto 1 733.
Pamäť programu sa nezmenšila. Dekodér leží mimo neho, na adrese $0600 (stránka 6). Keď tam niečo nahráva sám program – napríklad strojový kód pribalený cez --embed –, dekodér sa uloží hneď za program. V oboch prípadoch ho program po štarte môže pokojne prepísať: POKE 1536,… aj DIM fungujú ako vždy.
Štart trvá o chvíľu dlhšie. Program s 25 kilobajtmi sa dekóduje asi pol sekundy.
Jediné, čo ostáva čitateľné, je krátky úsek na začiatku súboru, ktorý vypína zabudovaný BASIC (65 bajtov, rovnakých v každom preloženom programe). Musí bežať ako prvý, ešte pred dekodérom.
Zakódujú sa aj dáta, ktoré idú so súborom: pribalené súbory (--embed, --file), texty pod ROM a v bankách (--text-under-rom, --text-in-banks) a oba súbory z --data-only a --code-only. Program sa dá uložiť aj na disketu (--atr), s ktorýmkoľvek DOS-om.
Zakódovaný je aj samotný dekodér. Pred ním leží krátky prvý stupeň (24 bajtov), ktorý ho pri prvom spustení vráti a potom už len pustí ďalej. V súbore sa tak nedá prečítať ani to, ako dekodér pracuje, ani jeho kľúč.
Nie je to ochrana. Kto program spustí v emulátore, vidí v jeho pamäti všetko už dekódované. Zakódovanie bráni len tomu, aby si texty niekto prečítal priamo zo súboru.
Bežné --scramble kóduje každý bajt pomocou bajtu pred ním. Je to rýchle a dekodér je krátky, no kto ten postup pozná, napíše si program, ktorý súbor rozkóduje bez spúšťania. Voľba --scramble-level vyberá úroveň zakódovania:
Úroveň
Ako kóduje
Dekodér
25 KB trvá
1
každý bajt XOR bajt pred ním (predvolená, to isté ako --scramble)
112 bajtov
0,48 s
2
každý bajt XOR číslo zo 16-bitového generátora pseudonáhodných čísel (LFSR)
+12
asi 0,9 s
Bash
Basic26secret.abas--scramble-level2
--scramble-level už znamená --scramble, oboje písať netreba. Efekty fungujú rovnako, napríklad --scramble-level 2 --scramble-fx bars.
Pri úrovni 2 čísla, ktorými sa bajty kódujú, vôbec nezávisia od programu a generátor beží bez prerušenia cez celý súbor – v súbore do 64 KB sa teda nikde neopakujú. Kto ich chce odstrániť, musí generátor napodobniť a poznať číslo, od ktorého začína – kľúč. Bez voľby --scramble-key si prekladač pri každom preklade vyberie nový náhodný kľúč, takže ten istý program dá zakaždým iný súbor. Ak chceš, aby bol súbor pri každom preklade rovnaký (napríklad na porovnanie dvoch verzií), kľúč zadaj sám:
Pol sekundy, počas ktorej sa na obrazovke nič nedeje, vyzerá ako zaseknutý počítač. Staré programy na Atari preto pri rozbaľovaní kreslili pruhy. --scramble-fx meno zakóduje súbor rovnako ako --scramble a pridá do dekodéra efekt:
Bash
Basic26secret.abas--scramble-fxbars--run
Efekt uvidíš len v emulátore (--run) alebo na skutočnom Atari – simulátor (--sim) obrazovku nekreslí. Pri takom malom programe iba preblikne; poriadne ho vidno pri programe s desiatkami kilobajtov.
Meno
Čo je na obrazovke
Dekodér
25 KB trvá
none
nič – to isté ako --scramble
+0 bajtov
0,48 s
bars
farebné pásy cez celú obrazovku
+6
0,64 s
bars-border
farebné pásy len na okrajoch
+3
0,56 s
mono
čiernobiele pásy cez celú obrazovku
+8
0,68 s
mono-border
čiernobiele pásy na okrajoch
+5
0,60 s
rainbow
pravidelná dúha cez celú obrazovku
+6
0,64 s
rainbow-border
dúha na okrajoch
+3
0,56 s
slow
široké pomalé pásy cez celú obrazovku
+6
0,48 s
slow-border
široké pomalé pásy na okrajoch
+3
0,48 s
dots
bodky po celej obrazovke – znaky sa zmenia na zrnenie
+3
0,56 s
dots-bars
bodky a farebné pásy naraz
+9
0,74 s
blank
obrazovka zhasne, nič sa nekreslí
+20
0,36 s
bars-blank
obrazovka zhasne, farebné pásy cez celú plochu
+23
0,42 s
inc
obrazovka zhasne, biele čiarky na tmavočervenej ploche
+28
0,46 s
inc-border
biele čiarky na tmavočervených okrajoch
+8
0,64 s
Ako si vybrať:
Čo najrýchlejší štart:blank. Zhasnutá obrazovka neberie procesoru čas, preto je dekódovanie rýchlejšie než úplne bez efektu.
Efekt zadarmo:slow a slow-border. Farbu menia len raz za 256 bajtov, takže nič nespomalia.
Nech obrazovka ostane čitateľná: varianty -border kreslia len do okrajov; text v strede ostane, ako bol.
Ako za starých čias:bars alebo inc – ten kreslí to, čo rozbaľovač Super Packer.
Tri veci, ktoré je dobré vedieť:
„Celá obrazovka“ platí pre bežnú textovú obrazovku, na ktorej sa program nahráva. dots je vidno len v textových režimoch.
Farby aj znaky sa po dekódovaní vrátia samy, program nemusí nič upratovať.
Pri programe s dátami v skrytej pamäti (kapitoly 44 až 46) beží dekodér po kúskoch počas celého nahrávania. Efekty so zhasnutou obrazovkou (blank, bars-blank, inc) vtedy blikajú.
Prelož secret.abas s --scramble-fx rainbow --run a potom s --scramble-fx inc --run. Efekt trvá len okamih – pridaj do programu sto riadkov DATA a pozri, ako sa predĺži.
Pridaj na začiatok programu riadok 1 REM @COMPILE --scramble-fx bars a prelož ho bez volieb.
Prelož secret.abas dvakrát s --scramble-level 2 -v a porovnaj kľúče, ktoré prekladač vypíše. Potom pridaj --scramble-key $1234 a porovnaj oba súbory príkazom fc /b.
Prelož secret.abas s --scramble -v --embed secret.in@$0600. Stránka 6 je tým obsadená (voľbu --embed vysvetľuje kapitola 43) – kam prekladač uložil dekodér?
Okrem obrazu má Atari ešte štyroch hráčov (anglicky players) a štyri strely (missiles). Sú to úzke zvislé pásy, ktoré čip GTIA kreslí cez obraz: každý má vlastnú farbu, vodorovnú polohu a šírku, a čip sám zistí, do čoho narazil. Na loď, ktorá letí cez hviezdy, je to ako stvorené – loď sa hýbe, a obraz pod ňou sa nemusí prekresľovať.
V Atari BASICu aj v Turbo-BASICu XL sa s nimi dá pracovať len cez POKE: nájsť zarovnaný blok pamäte, zapísať jeho adresu do PMBASE, zapnúť ich v SDMCTL a GRACTL, kresliť tvar bajt po bajte. Basic26 má na to vlastné slová. Sú to rozšírenia prekladača – pôvodný interpreter ich nepozná.
Voľbou --modern, najlepšie v hlavičke programu (kapitola 40):
ZX-Basic
REM @COMPILE --modern
Bez nej sú slová PMGRAPHICS, PMX, HITCLR obyčajné mená premenných, tak ako v dobových programoch. A program, ktorý ich nepoužije, z nich v súbore .xex nemá ani bajt. Rovnaké slová má prekladač jazyka Action! Action26.
Objekt n je 0 až 3 pre hráča a 4 až 7 pre strely 0 až 3.
Slovo
Čo robí
PMGRAPHICS m
0 vypne, 1 zapne s jemnými pásmi (riadok obrazu na bajt), 2 s hrubými (dva riadky na bajt)
PMCREATE n,TVAR$,šírka,x,y
nakreslí objekt: riadky tvaru sú bajty reťazca, šírka 1, 2 alebo 4
PMSHAPE n,TVAR$
iný tvar na tom istom mieste (animácia)
PMCLEAR n
zmaže objekt
PMMOVE n,x,y
presunie objekt
PMHPOS n,x, PMVPOS n,y
len vodorovne, len zvislo
PMX(n), PMY(n)
kde objekt je
PMWIDTH n,w
šírka 1, 2 alebo 4
PMCOLOR n,odtieň,jas
farba ako pri SETCOLOR; strela má farbu svojho hráča
PMPRIORITY p
1 hráči nad obrazom, 4 obraz nad hráčmi
PMHIT(n,c)
1, keď objekt n narazil do hráča c (0–3) alebo do farby obrazu c-4 (4–7)
PMHITPF(n), PMHITPM(n)
to isté ako bity: farby obrazu, hráči
HITCLR
zabudne všetky nárazy
PMWAIT
počká na ďalšiu snímku
PMOVERLAP(a,b)
1, keď sa objekty prekrývajú – počíta sa z polohy a veľkosti, platí hneď
PMADR(n)
adresa pásu objektu v pamäti
Súradnice sú tie, ktoré používa čip: x od 48 po 207 je na obrazovke zľava doprava, y je riadok v páse – pri PMGRAPHICS 2 od 0 po 127, viditeľné asi 16 až 111.
REM @COMPILE --no-line-numbers --modernREM A ship, a rock and what they hitDIMSHIP$(8),ROCK$(6)
RESTORE #SHAPES
FORI=1TO8:READ B:SHIP$(I)=CHR$(B):NEXTI
FORI=1TO6:READ B:ROCK$(I)=CHR$(B):NEXTI
GRAPHICS 0
POSITION 2,2:? "XXXXXXXXXXXXXXXXXXXXXXXX"
PMGRAPHICS 2
PMCREATE 0,SHIP$,1,120,90
PMCREATE 1,ROCK$,2,116,24
PMCOLOR 0,1,10:PMCOLOR 1,3,6FORY=24TO86
PMWAIT
PMMOVE 1,116,Y
NEXTY
PMWAIT:HITCLR:PMWAIT:PMWAIT
POSITION 2,10:? "Rock hits the text: ";PMHIT(1,6)
? "Rock hits the ship: ";PMHIT(1,0)
? "Ship is at ";PMX(0);",";PMY(0)
END
# SHAPES
DATA24,60,126,255,219,255,36,66DATA60,126,255,255,126,60
Tvar je reťazec. Každý bajt je jeden riadok: bit 7 vľavo, bit 0 vpravo. Loď 24,60,126,255,… je v dvojkovej sústave 00011000, 00111100, 01111110… – špička hore a krídla dole. Reťazec musí ostať, kým sa objekt používa: prekladač si pamätá, kde leží, a pri PMMOVE ho číta znova.
Pamäť pridelí prekladač. Hráči potrebujú blok, ktorý začína na násobku 1 KB (pri PMGRAPHICS 1 2 KB). Prekladač ho dá hneď za program a FRE(0) je o toľko menšie; --memory ho ukáže ako PM graphics (kapitola 42).
Pohyb prekreslí len to, čo sa zmenilo.PMMOVE vodorovne zapíše jeden register, zvislo prepíše riadky tvaru – nie celý pás.
Nárazy hlási čip, a až po snímke. GTIA si náraz poznačí, keď objekty kreslí, a drží ho, kým program nezavolá HITCLR. Preto PMWAIT, potom čítanie, potom HITCLR. Prečítať náraz hneď po PMMOVE nemá zmysel – nová poloha ešte nebola nakreslená.
Písmo je farba 2. V GRAPHICS 0 čip hlási písmená ako farbu obrazu 2, preto PMHIT(1,6) (6 = 4 + 2). Kameň na začiatku cez písmená preletel, ale HITCLR po slučke to zabudol.
GRAPHICS hráčov nevypne, hoci operačný systém pri otvorení obrazovky vypne ich kreslenie – prekladač ho zapne znova. Návrat do DOS-u ich vypne.
Každé číslo je v Atari BASICu aj v Turbo-BASICu XL šesť bajtov v desiatkovej sústave (kapitola 4). Vďaka tomu 1/3 vyjde na desať trojok – ale aj I=I+1 znamená sčítanie desiatkových čísel po bajtoch, a to je na procesore 6502 pomalé.
Väčšina programov však počíta len s celými číslami: počítadlá slučiek, súradnice, adresy, body v hre. Voľba --int povie prekladaču, že číslo je celé číslo v štyroch bajtoch, tak ako ho počíta procesor. Program je potom dva- až trikrát rýchlejší, ak počíta, a o kúsok menší. Pôvodný interpreter nič také nemá – je to rozšírenie prekladača.
Kde program desatinné čísla naozaj potrebuje, povie riadok REM @FLOAT, ktoré premenné ich majú držať.
Výraz s desatinným číslom (0.5, 2.0, 1E3), so SIN, COS, ATN, SQR, LOG, CLOG, EXP, RND alebo ^ sa počíta po starom, v šiestich bajtoch, a až výsledok sa zmení na celé číslo – zlomok sa zahodí smerom k nule. X=INT(100*RND(0)) tak funguje ako vždy. INT, TRUNC, FRAC, ABS a SGN desatinného čísla dajú desatinné číslo (INT(-1.5) je −2), porovnanie a AND, OR, NOT dajú 1 alebo 0. PRINT desatinného výrazu vypíše desatinné číslo.
Do celej premennej sa však zlomok neuloží: X=0.5 je chyba, STEP so zlomkom pri celej premennej tiež.
Premenné a polia, ktoré majú držať desatinné čísla, vymenuje riadok REM @FLOAT na začiatku programu, pole s otvorenou zátvorkou:
ZX-Basic
0REM @COMPILE --int1REM @FLOAT X,Y,A(
Taká premenná má šesť bajtov a počíta sa s ňou ako v BASICu – aj FOR s STEP 0.25. Pole má šesť bajtov na prvok. Celé číslo sa do nej uloží presne, jej hodnota v celej premennej stratí zlomok. Riadkov REM @FLOAT môže byť viac, platia len tie pred prvým príkazom programu. Reťazec v nich byť nemôže.
Pozor na delenie: Y=X/2, keď je X celé, delí celé čísla, aj keď je Y vo @FLOAT. Kto chce zlomok, napíše X/2.0.
0REM @COMPILE --int1REM @FLOAT R,P10REM Whole numbers in four bytes, two variables with a fraction20 S=0:FORI=1TO1000:S=S+I*I:NEXTI
30PRINT"SUM OF SQUARES: ";S
40PRINT"7/2 = ";7/2;", -7/2 = ";-7/250 R=10:P=3.14159265*R*R
60PRINT"CIRCLE AREA: ";P
70PRINT"WHOLE PART: ";INT(P)
80 X=2147483647:PRINT"LARGEST: ";X
90 TRAP 120:X=X+1100PRINT"NEVER HERE"110 END
120PRINT"ERROR ";PEEK(195);": IT DID NOT FIT"
SUM OF SQUARES: 333833500
7/2 = 3, -7/2 = -3
CIRCLE AREA: 314.159265
WHOLE PART: 314
LARGEST: 2147483647
ERROR 11: IT DID NOT FIT
Ten istý program bez --int (Basic26 whole.abas --sim --no-source-options) vypíše 7/2 = 3.5, ako najväčšie číslo 2147483640 – v šiestich bajtoch BASIC z napísaného čísla prečíta len deväť číslic – a NEVER HERE, lebo o jednotku väčšie číslo sa do šiestich bajtov ešte zmestí.
Čas v sekundách v emulátore (PAL), ten istý program preložený bez voľby a s --int:
Program
Bez --int
--int
500× PRINT
10,26
10,18
X=X+1 v slučke
1,76
1,24
B*2, (C-B)/2
11,64
5,28
sito prvočísel v reťazci
54,54
20,14
POKE do obrazovky
8,12
3,78
práca s reťazcami
21,92
13,34
náhodné bajty do GRAPHICS 8
4,64
2,98
bublinkové triedenie
8,1
5,8
posun hráča cez PEEK a POKE
15,10
5,94
Čím viac program počíta, tým viac získa. Výpis textu sa nezrýchli – čas tam ide do operačného systému. Prekladač FastBASIC, ktorý celými číslami počíta vždy, zvládne bajty do GRAPHICS 8 za 2,34 s a triedenie za 6,58 s.
error B26011: with --int, 0.5 is no whole number of 32 bits; add X to REM @FLOAT
do celej premennej ide zlomok – pridaj ju do REM @FLOAT
error B26011: with --int, a STEP with a fraction needs a floating point loop variable (REM @FLOAT)
FOR so STEP 0.25 potrebuje premennú vo @FLOAT
error B26011: 2147483648 does not fit in 32 bits
číslo v programe je väčšie než štyri bajty
warning B26233: with --int, / leaves no fraction for the * to multiply …
A/B*C stratí zlomok skôr, než sa násobí; C*A/B nie
warning B26233: with --int this asks whether N divides X …
X/N=INT(X/N) je v starých programoch otázka „delí N číslo X?“ – prekladač to tak preloží; jasnejšie je X MOD N=0 v Turbo-BASICu XL, X-X/N*N=0 v Atari BASICu
warning B26233: with --int, X=RND(...) is always 0 …
RND je zlomok; do celej premennej INT(N*RND(0))
error B26042: REM @FLOAT A$: a string is not a number
reťazec do @FLOAT nepatrí
ERROR- 11 za behu
výsledok sa nezmestil do štyroch bajtov, alebo delenie nulou
program počíta inak než bez --int
niekde delí celé čísla a zlomok čakal; premennú daj do @FLOAT alebo pridaj .0
--int: číslo je celé, v štyroch bajtoch, od −2 147 483 648 po 2 147 483 647; čo sa nezmestí, je chyba 11.
/ zahodí zlomok smerom k nule.
Desatinné čísla vo výraze fungujú, výsledok sa zmení na celé číslo.
REM @FLOAT X,Y,A( dá vymenovaným premenným a poliam desatinné čísla.
Program, ktorý veľa počíta, je dva- až trikrát rýchlejší.
Tu sa kniha končí. V prílohách nájdeš všetko ešte raz v tabuľkách – a v priečinku examples pri prekladači stovky programov, na ktorých si to môžeš vyskúšať.
Všetky príkazy, funkcie a operátory na jednom mieste. Stĺpec AB hovorí, či slovo pozná Atari BASIC (súbory .abas); Turbo-BASIC XL (.tbas) pozná všetky. Stĺpec Kap. je kapitola, kde je slovo vysvetlené.
Slovami z týchto tabuliek sa nesmie začínať meno premennej (kapitoly 4 a 26); meno začínajúce na NOT sa vo výpočte číta ako NOT a zvyšok.
Program môže byť výpis (.abas, .tbas), program uložený cez SAVE (.bas), súbor na obraze diskety (disk.atr:MENO.BAS) alebo hotový .xex na spustenie. Basic26 --help vypíše voľby po anglicky.
Stĺpec V programe hovorí, či voľba smie stáť v hlavičke REM @COMPILE (kapitola 40).
program.abas(2,9): error B26017: expected '=' after a string
Súbor, v zátvorke riadok a stĺpec v súbore (nie číslo riadka BASICu), error alebo warning, kód a popis po anglicky. Opravuj vždy prvú chybu; ďalšie bývajú jej následkom.
Kódy 2 až 30 zodpovedajú číslam chýb interpretera – prekladač tú istú chybu našiel skôr, než program spustil.
dve návestia alebo procedúry s rovnakým menom; platí prvé
B26048
textu chýba úvodzovka na konci
B26210
v texte je znak, ktorý Atari nemá (písmeno s diakritikou); v programe z neho bude ? – kde ho má znaková sada programu, povie --charmap (kapitola 43)
B26219
príkaz editora (LIST, SAVE …) – s --strict je to chyba
B26230
program robí niečo, čo interpreter znesie, ale stojí za pozornosť: riadky nie sú v poradí, POKE 106, meno začínajúce na NOT vo výpočte, skok na neexistujúci riadok s --quirks
B26231
riadok REM s dátami ostáva v pamäti
B26232
REM @COMPILE alebo REM @FLOAT za prvým príkazom; príkazový riadok prebil voľbu z programu; REM @FLOAT bez --int alebo s menom, ktoré program nemá
B26233
s --int: A/B*C stratí zlomok A/B skôr, než násobí; X/N=INT(X/N) sa preloží ako „N delí X“; INT(A/B) je A/B; X=RND(…) je vždy 0; delenie celých čísel do premennej z REM @FLOAT (kapitola 50)
B26234
POKE, DPOKE alebo MOVE na pevnú adresu v zásobníku procesora ($0100–$01F9), kde program aj interpreter držia návratové adresy
B26235
číslo v DATA s medzerou za sebou (DATA 1,2 na konci riadku): READ ho ako číslo neprečíta a skončí chybou 8, aj v interpreteri. Editor Atari medzery na konci riadku zahodí, výpis upravený na PC ich môže mať
B26236
meno na začiatku príkazu sa začína príkazom: LETTER=4 je LET TER=4, a LETTER inde v programe je iná premenná. Hlási sa, len keď program také celé meno inde používa – zhustené IFA<>B alebo FORI=1TO3 nie
Kód znaku je to, čo vracia ASC a čo berie CHR$ (kapitola 15).
Kódy
Znaky
0–26
grafické znaky (čiary, rohy, srdce, trojuholníky) – na klávesnici Atari cez CTRL a písmeno
27–31
riadiace kódy (pozri nižšie)
32
medzera
33–47
! " # $ % & ' ( ) * + , - . /
48–57
číslice 0–9
58–64
: ; < = > ? @
65–90
veľké písmená A–Z
91–95
[ \ ] ^ _
96
grafický znak (kosoštvorec)
97–122
malé písmená a–z
123–124
grafický znak (pik), zvislá čiara
125–127
riadiace kódy
128–255
tie isté znaky inverzne (kód + 128); niektoré sú riadiace kódy
Riadiace kódy – PRINT CHR$(kód) nevypíše znak, ale niečo urobí:
Kód
Čo urobí
27
ESC: nasledujúci riadiaci kód sa vypíše ako znak, nevykoná sa
28, 29, 30, 31
kurzor hore, dole, vľavo, vpravo
125
zmaže obrazovku
126
zmaže znak pred kurzorom
127
tabulátor
155
koniec riadka (RETURN)
156, 157
zmaže riadok, vloží riadok
253
pípne
254, 255
zmaže znak, vloží znak
Pamäť obrazovky drží znaky pod inými číslami (kódy obrazovky): znaky 32–95 majú kód o 32 menší (medzera 0, A 33), znaky 0–31 o 64 väčší, 96–127 rovnaký.
Preložený program má robiť presne to, čo interpreter. Keď si chceš overiť, ako sa program správa v pôvodnom Atari BASICu:
Spusti emulátor atari800 so zapnutým BASICom (bez voľby -nobasic); objaví sa READY.
Program buď napíš rovno do emulátora, alebo ho načítaj zo súboru: ulož výpis do priečinka, ktorý má emulátor nastavený ako zariadenie H:, a napíš ENTER "H:PROGRAM.LST".
Napíš RUN.
Turbo-BASIC XL sa nahráva z diskety; jeho obraz nájdeš na stránkach venovaných Atari.
Keď ti BASIC začne byť malý: Action! je rýchly jazyk podobný Pascalu, pre ktorý existuje sesterský prekladač action26 a rovnako písaná príručka. A úplne dole je assembler 6502 – jazyk, v ktorom sú napísané hry, na ktoré si z Atari pamätáš.