Obsah
1. Tvorba her pro Atari 2600 v Batari BASICu: úkol pro hardcode programátory
2. Základní technické parametry herní konzole Atari 2600
3. Komplikovaný vývoj her pro osmibitové herní konzole
4. Oficiální vývojové prostředí pro konzole Atari 2600 a Atari 7800
5. Vývoj her pro konzoli Atari 2600 v současnosti aneb kouzlo minimalizmu
7. Je možné pro Atari 2600 programovat i ve vyšších programovacích jazycích?
11. Instalace emulátoru herní konzole Atari 2600
12. Překlad a spuštění demonstračního programu
13. Vytvoření vlastního programu – vykreslení textu na pozadí
14. Změna barvy herní plochy modifikací řídicího registru
17. Změna barvy střely tlačítkem joysticku
18. Čísla řádků ve zdrojových kódech
19. Repositář s demonstračními příklady
1. Tvorba her pro Atari 2600 v Batari BASICu: úkol pro hardcode programátory
„A minimum is required to program the beast.“
Okolo některých osmibitových herních konzolí (zejména se to týká legendárních konzolí Atari 2600 a Nintendo Entertainment System – NES) se vytvořila komunita vývojářů, z nichž někteří dodnes vytváří nové hry, které jsou většinou dostupné ve zdrojové a binární podobě (určeno především pro emulátory herních konzolí), tak i v některých případech ve formě paměťové cartridge (určeno pro původní hardware, zde se samozřejmě již musí za cartridge i za její doručení platit – ovšem vlastnit fyzický HW je něco, co mnozí lidé oceňují, podobně jako například vlastnictví hudebního nosiče). Zajímavý je i fakt, že se tyto herní konzole používaly popř. dodnes používají pro výuku programování, především s orientací na počítačovou grafiku. Propagátorem tohoto netradičního způsobu výuky je dnes Ian Bogost, který na téma programování a návrhu her napsal i několik článků a knih. Důvody, proč i v současnosti mají osmibitové konzole své (mnohdy skalní) zastánce, si řekneme za chvíli.
Obrázek 1: Herní konzole Atari 2600 byla navržena tak, aby dokázala provozovat jednoduché hry typu Combat. Později se ovšem objevily i 3D hry atd., které z dostupného hardware vyždímaly téměř nemožné.
Proč by se však měl někdo vůbec zajímat o tak „předpotopní“ věc, jako je konzole Atari 2600 nebo (můj druhý tip – poněkud překvapivě) například ZX Spectrum? Může se jednat o souběh několika zájmů. V první řadě je programování osmibitových čipů mnohdy skutečná „challenge“, na rozdíl od některých jiných výzev, které mohou vypadat více uměle. A ve druhé řadě můžeme v poslední době vidět poměrně velkou popularitu retro her a knihoven určených pro tvorbu takových her. Takže pokud má vývojář pocit, že programovat hru v Pythonu, která vyžaduje pro svůj běh i5 a 500 MB RAM a nabízí „retro vzhled“, je do určité míry obelhávání sebe sama, může si otestovat své schopnosti právě vytvořením nějaké jednoduché hry pro Atari 2600, složitější hry pro ZX Spectrum (či jiný oblíbený osmibit) popř. již komplexní hry určené například pro Atari ST či Amigu (nebo klidně i PC a DOS). Ve výsledku se sice nebude jednat o komerční trhák, ovšem minimálně několik tisícovek stejně zapálených lidí bude moci takový SW spustit a uznale pokývat hlavou.
V následující tabulce jsou pro ilustraci vypsány základní technické parametry herní konzole Atari 2600, z nichž je patrné, s jakými zásadními překážkami se potenciální vývojář setká:
Mikroprocesor | MOS 6507 |
Grafický řadič | TIA |
Počet barev | 128 NTSC, 104 PAL, pouze 8 SECAM |
Zvuková syntéza | TIA |
Hodinová frekvence | 1,19 MHz |
Adresový rozsah | 8192 bajtů |
Kapacita RAM | 128 bajtů |
Kapacita ROM | 0 bajtů |
Kapacita ROM/EPROM na cartridge | standardně 4 kB, s bankou i 64 kB |
Vstupy | 2× digitální joystick, 2× paddle |
Výstup | televizní signál (úpravou lze získat i kompozitní video) |
Obrázek 2: Hra Outlaw se dočkala konverze snad na všechny počítačové platformy. Její princip je jednoduchý a přitom se jedná o zábavnou hru.
2. Základní technické parametry herní konzole Atari 2600
Při návrhu herní konzole Atari 2600 se její konstruktéři snažili o vytvoření co nejjednoduššího hardware, protože (v kontextu doby zcela správně) předpokládali, že většinu funkcionality by mělo zařídit programové vybavení a nikoli složitý a především drahý hardware. Navíc jednodušší hardware samozřejmě znamenal snížení výsledné ceny herní konzole na úroveň dostupnou i pro průměrné americké rodiny, což se ukázalo být velmi důležité.
Obrázek 3: Grafika hry Breakout je velmi jednoduchá a dosti hrubá (číslice se skóre, počtem životů a úrovní jsou pravděpodobně přímo vykreslovány do pozadí, které má nízké horizontální rozlišení).
Původní prototypy sice byly zkonstruovány s využitím většího množství čipů o poměrně nízké integraci, ovšem výsledná verze konzole se – kromě přibližně třiceti diskrétních součástek – skládala pouze z trojice čipů s vyšší mírou integrace. Jednalo se především o samotný osmibitový mikroprocesor MOS 6507 s taktovací frekvencí 1,2 MHz, jenž byl umístěný v 28pinovém pouzdru (i díky tomu byla jeho cena nižší, než cena za plnohodnotný čtyřicetipinový MOS 6502, ovšem standardní kapacita EPROM byla kvůli tomu omezena na pouhé čtyři kilobajty). K mikroprocesoru byl připojen čip MOS 6532, jenž v sobě kombinoval operační paměť o kapacitě pouhých 128 bajtů (nikoli kilobajtů a už vůbec ne megabajtů) a taktéž dvojici osmibitových paralelních portů, k nimž byly mj. připojeny i oba digitální joysticky.
Obrázek 4: Obrazovka hry Video Chess – šachy využívající pouhých 128 bajtů RAM!
Obrázek 5: Hru Solaris (technicky jednu z nejdokonalejších her na Atari 2600 vůbec) vytvořil stejný autor, jako hru Star Raiders.
Třetím čipem, který se velkou mírou podílel na úspěchu herní konzole Atari 2800, byl čip nazvaný TIA, neboli Television Interface Adaptor. Jednalo se o čip navržený Jayem Minerem, který se kromě práce na TIA později proslavil svým podílem na vývoji čipů ANTIC a GTIA určených pro osmibitové domácí počítače Atari a dále pak na vývoji čipové sady pro slavné počítače Amiga. Jay Miner ve svém čipu TIA, který byl postaven na bázi dvou prototypů navržených Joem Decuirem a Ronem Milnerem (jeden z prototypů se nazýval Stella, později se tak začal označovat i čip TIA a dokonce i celá konzole), implementoval jak jednoduchý ale překvapivě výkonný grafický řadič, tak i generátor zvuků. Jedním z typických znaků čipu TIA i některých dalších integrovaných obvodů navržených Jayem Minerem bylo použití polynomických čítačů (založených na posuvném registru se zpětnou vazbou) namísto běžných čítačů binárních. Předností polynomických čítačů je to, že na čipu zaberou přibližně čtvrtinu plochy v porovnání s binárními čítači, nevýhodou pak fakt, že se jejich hodnota nemění o jedničku, ale generuje se pseudonáhodná sekvence čísel. Nicméně pro potřeby generování obrazu i zvuků byly polynomické čítače díky své jednoduchosti výhodnější.
Obrázek 6: Další screenshot získaný ze hry Solaris.
3. Komplikovaný vývoj her pro osmibitové herní konzole
První podpůrné nástroje určené pro vývoj her a dalších aplikací pro herní konzoli Atari 2600 byly vyvinuty přímo ve společnosti Atari (za vývojem stál Dave Crane a jeho kolegové), a to původně pro známý minipočítač DEC PDP-11. Jednalo se zejména o cross assembler spouštěný přímo na minipočítači, jímž produkovaný binární kód se přes sériovou linku (klasickou RS-232) přenášel do speciální cartridge umístěné v herní konzoli, konkrétně v konektoru určenému pro běžné herní cartridge. Tato vývojová cartridge kromě paměti RAM obsahovala i jednoduché rozhraní pro řádkový debugger spouštěný taktéž na minipočítači. Vývojová cartridge emulovala běžnou paměťovou cartridge s pamětí ROM či EPROM. Tímto způsobem se postupně hra vyvíjela a testovala, což byl v porovnání s dneškem poměrně zdlouhavý proces, který byl navíc drahý – zejména pro nově založené společnosti zaměřené pouze na vývoj her (nikoli na prodej hardware) bylo problematické si zaplatit potřebný strojový čas minipočítače.
Obrázek 7: Barvová paleta herní konzole Atari 2600 při použití televizního systému NTSC (tyto barvy využijeme později v demonstračních příkladech).
Z tohoto důvodu se někteří programátoři alespoň zpočátku museli spokojit s jednodušším „hardcode“ systémem: ručním překladem kódu z assembleru do strojového kódu, „vypálením“ binárního obrazu hry do čipu EPROM a následným použitím této EPROM v cartridgi, která se v tomto případě prakticky nelišila od cartridgí, na nichž se prodávaly komerční hry (jediným rozdílem byl chybějící obal a umístění EPROM do patice a nikoli přímo na plošný spoj). Tento styl programování a testování byl v některých případech aplikován i při vývoji her pro herní konzoli Nintendo Entertainment System (NES); jeden vývojář vzpomíná, že celý cyklus překlad+naprogramování EPROM+přenos paměťového čipu+spuštění hry na konzoli trval většinou patnáct minut (což může být dobré ponaučení pro nás dnešní vývojáře, kteří někdy nadáváme na to, že spuštění nového kódu z IDE trvá i několik sekund :-).
Obrázek 8: O tomto modulu se prozatím definitivně neví, zda se jedná o originální vývojový modul hry River Raid (Activision), nebo jde o pirátskou kopii původní hry.
Obrázek 9: První úroveň hry River Raid.
4. Oficiální vývojové prostředí pro konzole Atari 2600 a Atari 7800
Později, především po úspěšné revoluci v oblasti domácích a později i osobních počítačů, se vývoj her a dalších aplikací určených pro herní konzole postupně přenesl na tyto relativně (skutečně však relativně) levné počítače, což mj. znamenalo, že se o vývoj her mohli pokusit i jednotlivci a společnosti s nízkým počátečním rozpočtem. Názorným příkladem takto pojatého „vývojového prostředí“ může být vývojové prostředí nabízené společností Atari pro její herní konzole Atari 7800 a taktéž Atari 2600 (díky prakticky stoprocentní zpětné kompatibilitě 7800 s 2600). Tento vývojový nástroj byl určen pro běh na osobních počítačích Atari 520ST, Atari 1040ST či pro řadu Mega ST; pro plnou činnost byl vyžadován i pevný disk (nejenom disketová jednotka). Tyto počítače byly přes paralelní port propojeny se speciální cartridgí s pamětí RAM, která dokázala emulovat běžnou paměťovou cartridge (s ROM) a navíc podporovala i komunikaci používanou debuggerem (ovládání probíhalo přes emulátor terminálu). Tato cartridge byla přes standardní konektor připojena do herní konzole 7800 (původní verze navíc vyžadovala úpravu ROM) či do původní konzole 2600.
Obrázek 10: Pohled na další typ vývojového modulu pro herní konzoli Atari 2600 (zde ještě není osazen paměťovými čipy).
Mezi reálným modulem se hrou a vývojovou cartridgí samozřejmě existovalo několik nepatrných rozdílů, které se týkaly zejména obsazení paměťových banků a jejich přepínání. Navíc první dvě instrukce na vývojové cartridge musely provádět její inicializaci (tím se vyplýtvaly celé čtyři cenné bajty :-).
Obrázek 11: Jednoduchý program napsaný v assembleru mikroprocesoru MOS 6502.
Softwarová část takto pojatého vývojového prostředí se skládala z několika nástrojů: programátorského editoru (upravená verze MicroEMACSu), cross assembleru, konvertoru objektových souborů generovaných assemblerem do formátu vhodného pro přímé uložení do RAM či EPROM na cartridgi a mj. i z debuggeru, který podporoval trasování, nastavování breakpointů, změnu obsahu RAM, změnu řídicích registrů atd. Z tohoto popisu je zřejmé, že i přesto, že vývoj her probíhal na osobním počítači (a ne minipočítači), základní nástroje a postupy zůstaly zachovány – vývoj stále probíhal s využitím assembleru a (pravděpodobně) jen minimum her využívalo kód napsaný v některém vyšším programovacím jazyku.
Obrázek 12: Část výukového programu pro herní konzoli Atari 2600, která je taktéž naprogramovaná v assembleru mikroprocesoru MOS 6502.
5. Vývoj her pro konzoli Atari 2600 v současnosti aneb kouzlo minimalizmu
Jak jsme si již řekli v úvodních kapitolách, existuje i v současnosti skupina vývojářů-amatérů (vlastně i polo-profesionálů, protože některé hry jsou prodávány), jejichž koníčkem je vytváření her pro staré osmibitové herní konzole. Někteří z těchto programátorů tvrdí, že osmibitové herní konzole a konkrétně právě Atari 2600, jsou pro nekomerční hry ideální platformou, protože takovou hru může vytvořit skutečně pouze jeden člověk, podobně jako v osmdesátých letech minulého století. Navíc jsou grafické možnosti těchto konzolí na tak nízké úrovni (v porovnání nejenom se současnými standardy), že hra musí zaujmout především hratelností a nikoli dechberoucí grafikou či pokročilými, ale mnohdy jen prvoplánovými grafickými efekty. Další programátoři navíc vyzdvihují skutečnost, že na osmibitových herních konzolích (a samozřejmě i na osmibitových domácích mikropočítačích) se programuje jen o jednu úroveň nad hardware. Nejsou zde tedy žádné další mezivrstvy, knihovny a frameworky; záleží jen na umu programátora, jak bude výsledný produkt vypadat.
Obrázek 13: Jedna z novějších homebrew her, která se snaží napodobit původní styl počítačových her.
Jak vlastně vývoj hry pro konzoli Atari 2600 může vypadat dnes? K dispozici je zapotřebí pouze minimum vývojových nástrojů (opět návrat k minimalismu, zejména v porovnání se současnými IDE doplněnými o mnohdy monstrózní frameworky, pro které prakticky každý den vychází opravné verze), ovšem na druhou stranu je dnes snadnost vývoje pro 2600 na tak vysoké úrovni, o níž se mohlo na konci sedmdesátých a v první polovině osmdesátých let minulého století programátorům jenom zdát a to především díky existenci kvalitních emulátorů herní konzolí. Díky nim je možné celý vývoj i testování provést na osobním počítači s tím, že pouze finální produkt se otestuje na reálném hardware herní konzole (mnohdy ani to není striktně zapotřebí).
Obrázek 14: Další snímek ze stejné hry.
6. Současné vývojové a testovací nástroje používané pro vývoj homebrew her pro Atari 2600: hardcore varianta
Pro vývoj nové hry či pro úpravu starší hry určené pro herní konzoli Atari 2600 dostačuje překvapivě pouze několik aplikací. V „hardcode“ variantě (tedy pro ty, kdo se nebojí assembleru a především pak neustálé „honby za elektronovým paprskem“) se jedná v první řadě o vhodný (cross) assembler, který dokáže zpracovat programy určené pro osmibitový mikroprocesor MOS 6502. Jedná se například o makro assembler DASM, který je takzvaným cross assemblerem, tj. běží na moderních desktopech (není ho tedy nutné provozovat na reálném MOS 6502). Dále se používá disassembler, který může být součástí emulátoru herní konzole. Pochopitelně se používá i programátorský textový editor popř. může být vhodný i hexa editor pro úpravy výsledného binárního souboru. A samozřejmě nesmíme zapomenout na samotný emulátor herní konzole:
- Cross assembler (většinou se používá DASM)
- Disassembler (DiStella)
- Textový editor (samozřejmě Vim a pro skutečné fajnšmekry Notepad :-)
- Hexa editor (Beye, hexedit, xxd, hiew apod.)
- Emulátor herní konzole (pravděpodobně nejpoužívanější je Stella či z26)
Obrázek 14: Homebrew hra AVCSTec Challenge.
Existují však i další specializované nástroje, například:
- Atari 2600 BASIC Compiler (překladač z jednoduchého BASICu do strojového kódu, viz další text)
- TIA Playfield Painter (jednoduchý editor pro tvorbu pozadí v maximálním rozlišení 80×192 pixelů)
Obrázek 15: Homebrew hra AVCSTec Challenge.
Nejdůležitější z těchto nástrojů je cross assembler DASM (http://sourceforge.net/projects/dasm-dillon/), tj. takový assembler, který sice může být spuštěn na dnešním běžném osobním počítači, ale generuje objektový soubor pro jiný typ mikroprocesoru. První verze assembleru DASM vznikla už v období let 1987 až 1988 a jejím autorem je Matt Dillon. Později došlo k mnoha úpravám tohoto assembleru a v současnosti se jedná o produkt využitelný pro produkování objektového kódu pro mnoho různých osmibitových mikroprocesorů: MOS 6502, MOS 6507 (v podstatě to samé až na jinou šířku adresové sběrnice), Motorola řady 6800, Motorola řady 68HC11 či Fairchild F8. Existují ovšem i další nativní a cross assemblery pro procesory MOS 6502, jejich seznam lze nalézt zde: http://en.wikipedia.org/wiki/Comparison_of_assemblers#6502_assemblers.
Obrázek 16: Homebrew hra AVCSTec Challenge.
7. Je možné pro Atari 2600 programovat i ve vyšších programovacích jazycích?
Na osmibitových domácích mikropočítačích se typicky používal BASIC ve funkci vyššího programovacího jazyka a assembler pro nízkoúrovňové operace (viz odkazy uvedené níže). Ovšem herní konzole Atari 2600 nabízí mnohem méně prostředků, než i ten nejmenší (ještě prakticky použitelný) mikropočítač (kterým je pravděpodobně ZX80 a ZX81), nehledě na problémy související s generováním obrazu pro jeho zobrazení na televizoru. Z tohoto důvodu se hry pro Atari 2600 psaly v assembleru. V současnosti se sice laboruje s využitím céčka (viz například https://atariage.com/forums/topic/283441-attemping-to-code-the-atari-2600-in-c-with-cc65/), ovšem problém spočívá v tom, jak rozumným způsobem napsat kernel zajišťující vykreslení herní scény, protože je nutné explicitně generovat každý obrazový řádek.
- Programovací jazyky a vývojové nástroje pro mikropočítače společnosti Sinclair Research
https://www.root.cz/clanky/programovaci-jazyky-a-vyvojove-nastroje-pro-mikropocitace-spolecnosti-sinclair-research/ - Vývojové nástroje používané v dobách osmibitových mikropočítačů
https://www.root.cz/clanky/vyvojove-nastroje-pouzivane-v-dobach-osmibitovych-mikropocitacu/ - Programovací jazyky používané na platformě osmibitových domácích mikropočítačů Atari
https://www.root.cz/clanky/programovaci-jazyky-pouzivane-na-platforme-osmibitovych-domacich-mikropocitacu-atari/ - Programovací jazyky používané na platformě osmibitových domácích mikropočítačů Atari (2)
https://www.root.cz/clanky/programovaci-jazyky-pouzivane-na-platforme-osmibitovych-domacich-mikropocitacu-atari-2/
Obrázek 17: Hra Frogger vytvořená firmou Parker Bros pro herní konzoli Atari 2600. Jedná se o konverzi z herního automatu postaveného na mikroprocesoru Zilog Z80.
8. Projekt Batari BASIC
Problém kernelu a současně i vyššího programovacího jazyka řeší například dnes popisovaný Batari BASIC. Ten obsahuje již připravené kernely, které jsou napsány v assembleru, jsou konfigurovatelné a volají se automaticky. Programátor tedy „pouze“ musí napsat logiku hry a posléze instruovat kernel, jakým způsobem má vykreslit herní scénu, která je interně složena z pozadí, herního pole, dvou hráčů, dvou střel a takzvaného míče. Ve výsledku je tak program psaný v Batari BASICu směsí vysokoúrovňového kódu s logikou hry popř. ovládáním pozice střel atd. a nízkoúrovňového kódu, který řeší ovládání čipu TIA přes jeho řídicí registry. V případě potřeby je však možné použít i assembler, který je plně integrován do zdrojového kódu.
Samotný kernel Batari BASICu umožňuje pracovat s celým herním polem, jako by se jednalo o 2D bitmapu. Podobně je možné pracovat se sprity hráčů, jakoby se jednalo o 2D sprity a nikoli o jednořádkové vzorky. Příklady si ukážeme jak dnes (herní pole), tak příště (sprity hráčů).
V programu lze používat několik desítek pseudoproměnných (které jsou mnohdy mapovány na řídicí registry) a 26 proměnných nazvaných a až z. Proč je však počet proměnných omezen? Nesmíme zapomenout, že jak stav kernelu, tak i zásobník a všechny proměnné se musí vejít do pouhých 128 bajtů RAM!
Přímo ovládat lze tyto řídicí registry čipu TIA:
Registry | Stručný popis |
---|---|
AUDV0/AUDC0/AUDF0 | řízení prvního zvukového kanálu |
AUDV1/AUDC1/AUDF1 | řízení druhého zvukového kanálu |
COLUBK | barva pozadí obrazovky |
COLUPF | barva herního pole a „míčku“ |
COLUP0/COLUP1 | barva hráčů a střel |
REFP0/REFP1 | řízení způsobu zobrazení hráčů a střel |
NUSIZ0/NUSIZ1 | řízení způsobu zobrazení hráčů a střel |
CTRLPF | řízení grafických efektů hráčů, herního pole a míče |
PF0 | vzorek herního pole |
Samotný překlad zdrojového kódu napsaného v Batari BASICu je proveden v několika průchodech:
- Preprocesing + tokenizace
- Překlad (přesněji řečeno transpřeklad) do assembleru, výsledkem je čitelný kód v assembleru
- Slinkování na úrovni assembleru se zvoleným vykreslovacím kernelem
- Optimalizace s odstraněním nepoužívaného kódu
- Překlad z assembleru do binárního nativního kódu
9. Překlad Batari BASICu
Batari BASIC sice nebývá běžnou součástí repositářů distribucí Linuxu, ovšem jeho překlad ve skutečnosti není nijak složitý. Potřebujete pouze překladač céčka (resp. celý GNU toolchain) a taktéž nástroj Lex. Celý postup zabere jen několik minut:
Získání poslední verze zdrojových kódů Batari BASICu:
$ git clone git@github.com:batari-Basic/batari-Basic.git Cloning into 'batari-Basic'... remote: Enumerating objects: 298, done. remote: Counting objects: 100% (93/93), done. remote: Compressing objects: 100% (42/42), done. remote: Total 298 (delta 61), reused 51 (delta 51), pack-reused 205 Receiving objects: 100% (298/298), 510.74 KiB | 1.46 MiB/s, done. Resolving deltas: 100% (139/139), done.
Přechod do adresáře s naklonovaným projektem:
$ cd batari-Basic
Vlastní překlad (s několika varováními):
$ make cc -O2 -o 2600basic 2600bas.c statements.c keywords.c In file included from /usr/include/string.h:495, from 2600bas.c:5: In function ‘strncpy’, inlined from ‘main’ at 2600bas.c:158:7: /usr/include/x86_64-linux-gnu/bits/string_fortified.h:106:10: warning: ‘__builtin___strncpy_chk’ specified bound depends on the length of the source argument [-Wstringop-overflow=] 106 | return __builtin___strncpy_chk (__dest, __src, __len, __bos (__dest)); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 2600bas.c: In function ‘main’: 2600bas.c:158:34: note: length computed here 158 | strncpy(finalcode, mycode, strlen(mycode) - strlen(codeadd)); | ^~~~~~~~~~~~~~ lex -t<preprocess.lex>lex.yy.c cc -O2 -o preprocess lex.yy.c rm -f lex.yy.c cc -O2 -o postprocess postprocess.c lex -t -i<optimize.lex>lex.yy.c cc -O2 -o optimize lex.yy.c rm -f lex.yy.c cc -O2 -o bbfilter bbfilter.c
Výsledkem překladu by měl být tento soubor:
$ ls -l 2600basic -rwxrwxr-x 1 ptisnovs ptisnovs 113480 Apr 22 15:55 2600basic $ ./2600basic -version batari Basic v1.6-SNAPSHOT (c)2021
10. Příprava assembleru dasm
Batari BASIC je, jak již víme, transpřekladačem, který provádí překlad zdrojového kódu z BASICu do assembleru. Následně je nutné tento vygenerovaný assembler přeložit do strojového kódu, jenž bude následně poslán do emulátoru herní konzole Atari 2600 popř. nahrán na cartridge. Takovým assemblerem je dasm, o němž jsme se již krátce zmínili v šesté kapitole. Ani tento assembler nebývá standardní součástí repositářů distribucí Linuxu, ovšem jeho spustitelnou podobu lze získat snadno. V adresáři s Batari BASICem se totiž nachází podadresář nazvaný contrib, jenž obsahuje skript, který dasm stáhne pro konkrétní architekturu procesoru:
$ pushd contrib $ ./fetch_dasm.sh $ popd
dasm sice v rámci dalších kapitol nebudeme používat přímo, ovšem je vhodné si ověřit, zda je alespoň spustitelný:
$ ./dasm.Linux.x64 DASM 2.20.14.1 Copyright (c) 1988-2020 by the DASM team. License GPLv2+: GNU GPL version 2 or later (see file LICENSE). DASM is free software: you are free to change and redistribute it. There is ABSOLUTELY NO WARRANTY, to the extent permitted by law. Usage: dasm sourcefile [options] -f# output format 1-3 (default 1) -oname output file name (else a.out) -lname list file name (else none generated) -Lname list file, containing all passes -sname symbol dump file name (else none generated) -v# verboseness 0-4 (default 0) -d debug mode (for developers) -Dsymbol define symbol, set to 0 -Dsymbol=expression define symbol, set to expression -Msymbol=expression define symbol using EQM (same as -D) -Idir search directory for INCLUDE and INCBIN -p# maximum number of passes -P# maximum number of passes, with fewer checks -T# symbol table sorting (default 0 = alphabetical, 1 = address/value) -E# error format (default 0 = MS, 1 = Dillon, 2 = GNU) -S strict syntax checking -R remove binary output-file in case of errors -m# safety barrier to abort on recursions, max. allowed file-size in kB Report bugs on https://github.com/dasm-assembler/dasm please!
11. Instalace emulátoru herní konzole Atari 2600
Emulátor herní konzole Atari 2600 se jmenuje Stella. Na rozdíl od předchozích nástrojů je balíček se Stellou běžnou součástí distribucí Linuxu, takže je jeho instalace snadná:
$ sudo apt-get install stella Reading package lists... Done Building dependency tree Reading state information... Done The following additional packages will be installed: evemu-tools evtest joystick libevemu3 The following NEW packages will be installed: evemu-tools evtest joystick libevemu3 stella 0 upgraded, 5 newly installed, 0 to remove and 0 not upgraded. Need to get 1 654 kB of archives. After this operation, 7 254 kB of additional disk space will be used. Do you want to continue? [Y/n] y
Tento emulátor budeme používat v dalších kapitolách:
Obrázek 18: Výběr programu pro spuštění v emulátoru Stella.
Obrázek 19: Nastavení vlastností emulátoru.
Obrázek 20: Nastavení pro vývojáře, které využijeme příště.
Obrázek 21: Nastavení pro vývojáře (běžící hra Adventure), které využijeme příště.
12. Překlad a spuštění demonstračního programu
Součástí Batari BASICu je i několik demonstračních programů, na nichž je možné si otestovat, zda je Batari BASIC, DASM i emulátor herní konzole korektně nainstalován a nakonfigurován. Před pokusem o překlad demonstračního příkladu je nutné nastavit resp. přenastavit tyto proměnné prostředí:
$ export PATH=.:$PATH $ export bB=.
V dalším kroku se můžeme pokusit o překlad demonstračního příkladu nazvaného bbstarfield.bas, jenž ukazuje některé grafické možnosti čipu TIA:
$ ./2600basic.sh bbstarfield.bas Found dasm version: DASM 2.20.14.1 Starting build of bbstarfield.bas batari Basic v1.6-SNAPSHOT (c)2021 2600 Basic compilation complete. 2373 bytes of ROM space left Complete. (0) Build complete.
V průběhu překladu vznikne několik souborů, z nichž pro nás nejdůležitější je soubor s koncovkou .bin, jehož velikost by měla být přesně 4kB:
$ ls -la bbstarfield* -rw-rw-r-- 1 ptisnovs ptisnovs 2446 Apr 22 15:54 bbstarfield.bas -rw-rw-r-- 1 ptisnovs ptisnovs 45033 Apr 22 16:06 bbstarfield.bas.asm -rw-rw-r-- 1 ptisnovs ptisnovs 4096 Apr 22 16:06 bbstarfield.bas.bin -rw-rw-r-- 1 ptisnovs ptisnovs 163820 Apr 22 16:06 bbstarfield.bas.lst -rw-rw-r-- 1 ptisnovs ptisnovs 21947 Apr 22 16:06 bbstarfield.bas.sym
Tento soubor spustíme v emulátoru:
$ stella bbstarfield.bas.bin
S následujícím (animovaným) výsledkem:
Obrázek 22: Takto by mělo demo vypadat po spuštění v emulátoru.
13. Vytvoření vlastního programu – vykreslení textu na pozadí
Pokusme se nyní o vytvoření vlastního příkladu, který vykreslí na obrazovku řetězec „Root“. Využijeme přitom standardní vykreslovací kernel Batari BASICu, který umožňuje definici tzv. herního pole o rozlišení (spíše tedy o „rozlišení“) 32×11 bloků („pixelů“). Bitmapu s herním polem lze definovat příkazem playfield. Vykreslení je provedeno příkazem drawscreen:
playfield: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ................................ ................................ ...XXXX....XXX.....XXX...XXXXX.. ...X...X..X...X...X...X....X.... ...XXXX...X...X...X...X....X.... ...X.X....X...X...X...X....X.... ...X..X...X...X...X...X....X.... ...X...X...XXX.....XXX.....X.... ................................ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX end drawscreen
Tento program sice půjde přeložit, ale již nikoli spustit, a to z toho důvodu, že se drawscreen musí neustále volat dokola. Pokud takovou smyčku nevytvoříme, dojde emulovaný mikroprocesor dříve či později k neznámé instrukci (popř. častěji k instrukci BRK a program je v emulátoru ukončen:
Obrázek 23: Pád programu po přechodu na neznámou instrukci.
Oprava je snadná – použijeme oblíbený příkaz goto:
playfield: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ................................ ................................ ...XXXX....XXX.....XXX...XXXXX.. ...X...X..X...X...X...X....X.... ...XXXX...X...X...X...X....X.... ...X.X....X...X...X...X....X.... ...X..X...X...X...X...X....X.... ...X...X...XXX.....XXX.....X.... ................................ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX end mainloop drawscreen goto mainloop
Nyní již program bude přeložitelný i spustitelný. No není to krása?:
Obrázek 24: První program, který jsme přeložili a spustili na emulaci HW starého 45 let!
14. Změna barvy herní plochy modifikací řídicího registru
V dalším demonstračním příkladu je ukázáno, jakým způsobem je možné změnit barvu herní plochy. Tato barva je ukládána do řídicího registru nazvaného COLUPF (COLor PlayField). Barva se vybírá z palety resp. přesněji řečeno z několika palet, které jsou sice neměnné, ale liší se podle použitého televizního standardu. Ostatně se podívejte sami na stránku s těmito paletami, kterou lze nalézt na adrese http://www.qotile.net/minidig/docs/tia_color.html.
Změna barvy zápisem do řídicího registru COLUPF je v Batari BASICu snadná:
COLUPF = 14
Můžeme si to vyzkoušet modifikací předchozího příkladu:
playfield: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ................................ ................................ ...XXXX....XXX.....XXX...XXXXX.. ...X...X..X...X...X...X....X.... ...XXXX...X...X...X...X....X.... ...X.X....X...X...X...X....X.... ...X..X...X...X...X...X....X.... ...X...X...XXX.....XXX.....X.... ................................ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX end COLUPF = 14 mainloop drawscreen goto mainloop
Po spuštění tohoto příkladu by měl na začátku „problinkout“ text v barvě číslo 14. Ihned poté ovšem dojde k překreslení zpět na barvu bílou. Proč tomu tak je? Standardní kernel Batari BASICu totiž dokáže ve spodní části obrazovky vykreslit skóre (vytvářené hry) a pro tento účel pochopitelně používá jak herní pole, tak i další grafické objekty konzole TIA. A u těch je implicitně (pro skóre) nastavena černá resp. bílá barva a proto interně dojde mj. i k přepisu registru COLUPF.
Úprava resp. přesněji řečeno oprava je snadná – přesunutí nastavení registru COLUPF do programové smyčky:
playfield: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ................................ ................................ ...XXXX....XXX.....XXX...XXXXX.. ...X...X..X...X...X...X....X.... ...XXXX...X...X...X...X....X.... ...X.X....X...X...X...X....X.... ...X..X...X...X...X...X....X.... ...X...X...XXX.....XXX.....X.... ................................ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX end mainloop COLUPF = 14 drawscreen goto mainloop
S výsledkem:
Obrázek 25: Text vykreslený odlišnou barvou.
S využitím proměnné a lze snadno docílit postupné změny barvy herního pole:
playfield: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ................................ ................................ ...XXXX....XXX.....XXX...XXXXX.. ...X...X..X...X...X...X....X.... ...XXXX...X...X...X...X....X.... ...X.X....X...X...X...X....X.... ...X..X...X...X...X...X....X.... ...X...X...XXX.....XXX.....X.... ................................ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX end a = 0 mainloop drawscreen COLUPF = a a = a + 1 goto mainloop
15. Zobrazení střely
Jak uvidíme příště, dokáže čip TIA zobrazit kromě herního pole i další tři typy objektů. Tyto objekty se nazývají hráči (players), střely (missiles) a míč (ball). Na rozdíl od herního pole jsou tyto objekty pohyblivé – lze je v rámci obrazového řádku umístit na libovolné místo (tedy jimi pohybovat doleva a doprava). Podívejme se nejdříve na možnosti střel. Existují dva objekty tohoto typu – mossile0 a missile1. Nastavit lze jejich pozici jak na obrazovém řádku, tak i číslo obrazového řádku (toto je ovšem možnost zajištěná kernelem, protože čip TIA pracuje striktně vždy s jediným obrazovým řádkem):
missile0x = 64 missile0y = 64
Kernel umožňuje nastavit i výšku střely měřenou počtem obrazových řádků:
missile0height = 8
Šířka střely (v pixelech) se nastavuje v řídicím registru NUSIZ0, a to výběrem hodnoty m z této tabulky. Pokud tedy budeme chtít, aby byla střela široká 8 pixelů, použijeme m=3:
NUSIZ0 = $30
Zbývá nám nastavit barvu střely číslo 0. Tato barva je totožná s barvou hráče číslo 0 a specifikuje se zápisem do řídicího registru COLUP0:
COLUP0 = $1E
Celý demonstrační příklad tedy bude vypadat následovně:
playfield: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ................................ ................................ ...XXXX....XXX.....XXX...XXXXX.. ...X...X..X...X...X...X....X.... ...XXXX...X...X...X...X....X.... ...X.X....X...X...X...X....X.... ...X..X...X...X...X...X....X.... ...X...X...XXX.....XXX.....X.... ................................ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX end missile0x = 64 missile0y = 64 missile0height = 8 mainloop NUSIZ0 = $30 COLUPF = 14 COLUP0 = $1E drawscreen goto mainloop
Zobrazený výsledek získaný po spuštění příkladu by měl vypadat takto:
Obrázek 26: Text vykreslený do herního pole a střela vykreslená nad textem.
16. Posun střely joystickem
Velkou předností Batari BASICu je jeho schopnost manipulovat s pseudoproměnnými, které reprezentují například stav joysticku či grafických objektů. Například v pseudoproměnných joy0up, joy0down, joy0left a joy0right jsou uloženy příznaky, že je první joystick nakloněn v daném směru. Tyto příznaky je možné přímo použít v podmínce, takže se ušetří kód (i čas) pro dekódování stavu joysticku atd. Navíc je možné přímo ovlivnit pseudoproměnné missile0× a missile0y představující pozici první střely na obrazovce. Zajištění posunu střely joystickem (ve všech osmi směrech) je tedy až triviálně jednoduché:
if joy0up then missile0y = missile0y - 1 if joy0down then missile0y = missile0y + 1 if joy0left then missile0x = missile0x - 1 if joy0right then missile0x = missile0x + 1
Úplný zdrojový kód takto upraveného programu bude vypadat následovně:
playfield: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ................................ ................................ ...XXXX....XXX.....XXX...XXXXX.. ...X...X..X...X...X...X....X.... ...XXXX...X...X...X...X....X.... ...X.X....X...X...X...X....X.... ...X..X...X...X...X...X....X.... ...X...X...XXX.....XXX.....X.... ................................ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX end missile0x = 64 missile0y = 64 missile0height = 8 mainloop NUSIZ0 = $30 COLUPF = 14 COLUP0 = $1E if joy0up then missile0y = missile0y - 1 if joy0down then missile0y = missile0y + 1 if joy0left then missile0x = missile0x - 1 if joy0right then missile0x = missile0x + 1 drawscreen goto mainloop
Po spuštění dema je možné střelou posouvat po obrazovce joystickem:
Obrázek 27: Přesun pozice střely joystickem.
17. Změna barvy střely tlačítkem joysticku
Stejně snadné je programově zajistit, aby se po stisku tlačítka joysticku postupně měnila barva střely (resp. přesněji řečeno čtverce, který střelu představuje na obrazovce). Postačuje použít proměnnou (například a) pro uložení barvy střely s tím, že se po stisku tlačítka joysticku zvýší index barvy v barvové paletě o jedničku:
a = $1E mainloop COLUP0 = a ... ... ... if joy0fire then a = a + 1 ... ... ... goto mainloop
Úplný zdrojový kód upraveného demonstračního příkladu:
playfield: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ................................ ................................ ...XXXX....XXX.....XXX...XXXXX.. ...X...X..X...X...X...X....X.... ...XXXX...X...X...X...X....X.... ...X.X....X...X...X...X....X.... ...X..X...X...X...X...X....X.... ...X...X...XXX.....XXX.....X.... ................................ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX end missile0x = 64 missile0y = 64 missile0height = 8 a = $1E mainloop NUSIZ0 = $30 COLUPF = $7F COLUP0 = a if joy0up then missile0y = missile0y - 1 if joy0down then missile0y = missile0y + 1 if joy0left then missile0x = missile0x - 1 if joy0right then missile0x = missile0x + 1 if joy0fire then a = a + 1 drawscreen goto mainloop
Obrázek 28: Pohyb střely se změnou její barvy.
18. Čísla řádků ve zdrojových kódech
Batari BASIC podporuje i využití čísel řádků namísto textových návěští, což může vyhovovat pamětníkům, kteří používali BASIC v dobách jeho největší slávy, tj. zhruba v osmdesátých letech minulého století. Podívejme se, jak by mohl zápis předchozího programu vypadat v případě použití čísel řádků. Povšimněte si zejména skoku na začátek vykreslovací smyčky (text je označen tučně):
playfield: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ................................ ................................ ...XXXX....XXX.....XXX...XXXXX.. ...X...X..X...X...X...X....X.... ...XXXX...X...X...X...X....X.... ...X.X....X...X...X...X....X.... ...X..X...X...X...X...X....X.... ...X...X...XXX.....XXX.....X.... ................................ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX end 10 missile0x = 64 20 missile0y = 64 30 missile0height = 8 40 a = $1E 50 51 NUSIZ0 = $30 52 COLUPF = $7F 53 COLUP0 = a 54 if joy0up then missile0y = missile0y - 1 55 if joy0down then missile0y = missile0y + 1 56 if joy0left then missile0x = missile0x - 1 57 if joy0right then missile0x = missile0x + 1 58 if joy0fire then a = a + 1 59 drawscreen 60 goto 50
Obrázek 29: Scéna ze hry H.E.R.O. jak ji vidí hráč.
Obrázek 30: A takto je scéna rozdělena na sprity a herní pole.
19. Repositář s demonstračními příklady
Všechny dnes popisované demonstrační příklady určené pro překlad Batari-BASICem byly uloženy do Git repositáře, který je dostupný na adrese https://github.com/tisnik/8bit-fame. Příklady si můžete v případě potřeby stáhnout i jednotlivě bez nutnosti klonovat celý (dnes již poměrně rozsáhlý) repositář:
20. Odkazy na Internetu
- Batari BASIC GitHub repositář
https://github.com/batari-Basic/batari-Basic - Programming Tutorial
https://atariage.com/forums/topic/111938-programming-tutorial/ - batari Basic Commands
https://www.randomterrain.com/atari-2600-memories-batari-basic-commands.html - About batari Basic
https://bataribasic.com/ - Rationale
https://bataribasic.com/rationale.html - Games That Push The Limits of the Atari 2600
https://www.youtube.com/watch?v=zM0IsWdIc_g - Vývojové nástroje používané v dobách osmibitových mikropočítačů
https://www.root.cz/clanky/vyvojove-nastroje-pouzivane-v-dobach-osmibitovych-mikropocitacu/ - Programovací jazyky používané na platformě osmibitových domácích mikropočítačů Atari
https://www.root.cz/clanky/programovaci-jazyky-pouzivane-na-platforme-osmibitovych-domacich-mikropocitacu-atari/ - Programovací jazyky používané na platformě osmibitových domácích mikropočítačů Atari (2)
https://www.root.cz/clanky/programovaci-jazyky-pouzivane-na-platforme-osmibitovych-domacich-mikropocitacu-atari-2/ - Barvové palety čipu TIA
http://www.qotile.net/minidig/docs/tia_color.html - Crazy Limit Pushing Games From the Last Years of the Atari 2600!
https://www.youtube.com/watch?v=ADy1F8v59YU - Atari 2600 VCS Top 100 Games Hits (past week)
http://www.atarimania.com/top-atari-atari-2600-vcs-_G2_7.html - Tobikomi – The Sound Of Thunder [Atari TIA Chip]
https://www.youtube.com/watch?v=j0w-IZ6nAMQ - TIA Visual Objects
https://github.com/jigo2600/jigo2600/blob/master/doc/TIA_Visual_Objects.md - TIA Sound
https://github.com/jigo2600/jigo2600/blob/master/doc/TIA_Sound.md - How To Make An Atari Game
https://www.youtube.com/watch?v=Ww3her2zk_I - Let's Make an Atari 2600 Game! – Part 1
https://www.youtube.com/watch?v=Iqo_oARxjEg - Let's Make an Atari 2600 Game! – Part 2
https://www.youtube.com/watch?v=hFFQjwFbzV8 - Let's Make an Atari 2600 Game! – Part 3
https://www.youtube.com/watch?v=lZ0AL6jCBXY - Let's Make an Atari 2600 Game! Part 4 – Title screens and challenges
https://www.youtube.com/watch?v=-G2kmsmqk-E - Let's Make an Atari 2600 Game! Part 5 – Sound
https://www.youtube.com/watch?v=9rX2eo20×q8 - Let's Make an Atari 2600 game! 6 – Realtime RPG combat
https://www.youtube.com/watch?v=alRGuQ9gjRA - Let's Make an Atari 2600 Game! Part 7 – Monsters
https://www.youtube.com/watch?v=vaAlYC_8YSA - Let's Make an Atari 2600 Game! Part 8 – 3D Engine
https://www.youtube.com/watch?v=c1dPY1ROZe4 - Let's Make an Atari 2600 Game – Part 9 – Homemade cartridge
https://www.youtube.com/watch?v=xKlMohF_9Cc - Bird Poop! – Atari 2600 Homebrew – batari Basic
https://www.youtube.com/watch?v=-m4gKis0vBg - DP Interviews: Bob Whitehead (By Scott Stilphen)
http://www.digitpress.com/library/interviews/interview_bob_whitehead.html - The dasm macro assembler
http://dasm-dillon.sourceforge.net/ - Official home of dasm, a versatile macro assembler
https://dasm-assembler.github.io/ - Dokumentace k DASMu
https://raw.githubusercontent.com/dasm-assembler/dasm/master/docs/dasm.pdf - Atari Programming Workshop Chapter links
http://atariage.com/forums/viewtopic.php?t=47479 - Various Development Kits
http://devkits.handheldmuseum.com/ - Classic Console Development
http://sebastianmihai.com/ccd/ - Atari 2600 development – Snappy (batari basic)
http://sebastianmihai.com/main.php?t=47 - Atari VCS (Atari 2600) – fotografie
http://oldcomputers.net/atari-vcs.html - History of Consoles: Atari VCS/2600 (1977)
http://gamester81.com/history-of-consoles-atari-vcs2600–1977/ - Iag Bogost: Racing the Beam
http://www.bogost.com/books/video_computer_system.shtml - Atari 2600 Programming Tutorial
http://www.randomterrain.com/atari-2600-memories-tutorial-andrew-davie-01.html - Atari 2600 Development Cartridge *Super Deluxe*~!
http://jazz-disassemblies.blogspot.cz/2013/09/atari-2600-development-cartridge-super.html - Atari „Alpine“ Devkit (pro Atari Jaguar)
http://justclaws.atari.org/devcats/hardware/ataridev.htm - 6502 compatible assembler and emulator in javascript
http://www.6502asm.com/ - Atari 2600 Programming
http://atariage.com/2600/programming/ - Retrozone – Brand new original homebrew games by current programmers
http://www.retrousb.com/index.php?cPath=30 - ATARI VCS/2600 TIA CHIPS
http://www.ataricompendium.com/faq/vcs_tia/vcs_tia.html - Elena, New programming language for the ZX Spectrum Next
https://www.vintageisthenewold.com/elena-new-programming-language-for-the-zx-spectrum-next - ZX Spectrum development with modern tools
http://www.breakintoprogram.co.uk/software_development/zx-spectrum-development-with-modern-tools - Z80 Development Toolchain
http://www.breakintoprogram.co.uk/computers/zx-spectrum/assembly-language/z80-development-toolchain