Kouzlo minimalismu potřetí: vývoj her a dem pro osmibitová Atari

Dnes
Doba čtení: 30 minut

Sdílet

Projekt Atari perex.
Autor: Michal Tauchman, podle licence: CC BY-SA 4.0
Projekt Atari perex.
Na sérii článků o vývoji her pro Atari 2600, NES a ZX Spectrum dnes nepřímo navážeme. Ukážeme si totiž, jakým způsobem je možné vyvíjet hry a grafická či hudební dema pro osmibitové mikropočítače Atari.

Obsah

1. Kouzlo minimalismu potřetí: vývoj her a grafických i zvukových dem pro osmibitová Atari

2. Vývojové nástroje pro osmibitová Atari

3. Assemblery pro osmibitová Atari

4. Překladače jazyka C pro osmibitová Atari

5. Základní programové vybavení pro vývoj her pro Atari v současnosti

6. Instalace ca65 a ld65

7. Praktická část: čím se liší vývoj pro osmibitová Atari od dnes běžného vývoje?

8. První demonstrační příklad: prostá nekonečná smyčka

9. Překlad do strojového kódu s vytvořením listingu

10. Konfigurace linkeru, spuštění linkeru s vytvořením výsledného souboru ve formátu xex

11. Formát .xex

12. Druhý demonstrační příklad: změna barvy pozadí v textovém režimu

13. Symboly definované v souboru atari.inc

14. Třetí demonstrační příklad: využití symbolů definovaných v souboru atari.inc

15. Adresovací režimy mikroprocesoru MOS 6502, využití registrů X a Y

16. Čtvrtý demonstrační příklad: tisk znaku „A“ do horního levého rohu obrazovky

17. Příloha A: Konfigurační soubor pro linker ld65

18. Příloha B: Makefile pro překlad všech demonstračních příkladů

19. Repositář s demonstračními příklady

20. Odkazy na Internetu

1. Kouzlo minimalismu potřetí: vývoj her a grafických i zvukových dem pro osmibitová Atari

Na sérii článků o vývoji her (či spíše hříček) pro osmibitovou herní konzoli Atari 2600 s využitím Batari Basicu [1] [2] [3] a taktéž na jedenáctidílný seriál o vývoji pro slavnou osmibitovou herní konzoli NES i na seriál o vývoji pro ZX Spectrum dnes nepřímo navážeme. Řekneme si totiž, jakým způsobem je možné vyvíjet hry a grafická či hudební dema pro neméně slavné osmibitové stroje – Atari (modely 400, 800, řadu XL i XE). Vývoj pro Atari se od vývoje pro (například) již zmíněné ZX Spectrum odlišuje v prakticky všech aspektech, od zcela odlišně pojatého instrukčního souboru, až po rozdíly v grafickém subsystému. To je ostatně jen dobře, protože se naučíme (pro někoho) nové techniky a nebudeme se příliš opakovat.

Poznámka: pro vývoj použijeme cross assembler a později se alespoň okrajově zmíníme o cross překladači programovacího jazyka C. Zapomeňme tedy na sice snadno naučitelný, ale pomalý a i jinak omezený BASIC.

Obrázek 1: Jednou z nejoblíbenějších her pro ZX Spectrum zůstává JetPac od firmy Ultimate Play the Game. Tato hra si vystačila s pouhými 16kB RAM (kam musíme počítat i obrazovou paměť!).

2. Vývojové nástroje pro osmibitová Atari

Na osmibitových mikropočítačích (a nyní se zaměříme především na domácí mikropočítače) měli ti uživatelé, kteří se chtěli zabývat programováním, na výběr z relativně velkého množství různých vývojových nástrojů a pomůcek (bylo jich dokonce až překvapivě velké množství – desítky programovacích jazyků atd.). Některé mikropočítače byly vybaveny pouze velmi jednoduchým operačním systémem zajišťujícím základní vstupně/výstupní operace (čtení klávesnice, zápis znaku na obrazovku, rutiny pro čtení a zápis dat na magnetofon).

Poměrně často byl tento minimalistický operační systém doplněn o takzvaný monitor což byl (a někde doposud je) program umožňující manipulaci s daty v operační paměti, tj. zápis dat do paměti, čtení (zobrazení) vybraného bloku, přesun bloku, vyplnění určité oblasti konstantou, čtení a zápis dat na externí paměťové médium (typicky na magnetofon) a některé pokročilejší monitory byly vybaveny i takzvaným disassemblerem umožňujícím transformaci sekvence bajtů na symbolické instrukce. Mimochodem – při výpisu obsahu operační paměti se v monitorech většinou používal stejný formát, jaký najdeme u mnoha moderních programátorských hexa editorů.

Monitory, zejména ty vybavené disassemblerem (zpětným assemblerem) bylo možné použít i pro tvorbu programů na úrovni strojového kódu. Takový program se většinou nejprve zapsal na papír ve formě assembleru, dále se provedl ruční překlad jednotlivých instrukcí do sekvence decimálních nebo hexadecimálních číslic a následně se tato sekvence zapsala do monitoru do určité předem vybrané oblasti operační paměti. V případě, že monitor podporoval zápis bloku paměti na externí paměťové médium (kazetový magnetofon, disketu), jednalo se o dosti primitivní, ovšem stále ještě použitelné (a v některých případech i používané) vývojové prostředí.

Na druhou stranu je programování na úrovni strojového kódu samozřejmě velmi pracné, zejména ve chvíli, kdy je nutné existující program modifikovat a tím pádem měnit cílové adresy skoků, adresy globálních proměnných atd. Mnohem civilizovanější způsob představovalo použití takzvaných assemblerů, což byly nástroje schopné překládat programy zapsané v jazyku symbolických adres/instrukcí do strojového kódu – ostatně přesně pro podobné činnosti jsou počítače zkonstruovány.

Obrázek 2: Jedním z poměrně velkého množství assemblerů vyvinutých pro osmibitové mikropočítače Atari je SynAssembler vytvořený a prodávaný společností Synapse Software. Tato společnost, s níž jsme se již na stránkách Roota seznámili, se nezaměřovala pouze na vývoj počítačových her. Kromě nich totiž vydávala i programy určené jak pro běžné koncové uživatele (FileManager 800, DiskManager, SynFile+, SynCalc, SynChron, SynComm, SynStock, SynTrend, …) tak právě vývojové nástroje; mezi nimi i SynAssembler.

Z vyšších programovacích jazyků byl populární především Pascal, a to díky tomu, že tento jazyk byl navržen takovým způsobem, aby byl překlad programů proveden jednoprůchodově a tudíž velmi rychle v porovnání s víceprůchodovými překladači. Ovšem existovaly i další programovací jazyky, například i populární céčko. Zde je nutné zmínit především známý překladač Aztec C portovaný na velké množství různých typů mikropočítačů, zapomenout nesmíme ani na Deep Blue C pro osmibitové počítače Atari (zde se autoři museli vyrovnat s faktem, že znaková sada neobsahovala složené závorky, tento jazyk měl ovšem i mnoho dalších omezení). A taktéž se jednalo o jazyky, které vznikly pouze pro jedinou platformu a jinam se nerozšířily. Ve světě osmibitových Atari je takovým zvláštním (a nepřenositelným) jazykem Action!.

Obrázek 3: Disassembling neboli zobrazení symbolických instrukcí získaných z obsahu strojového kódu.

Zapomenout nesmíme ani na Interlisp. Jedná se o dialekt jazyka Lisp, v němž se objevilo několik nových technologií, které byly navrženy tak, aby usnadnily dialog člověka s počítačem. Příkladem až překvapivě dobré portace je Interlisp/65 určený právě pro osmibitové domácí mikropočítače Atari. Zajímavé je, že distribuci (ne ovšem samotnou portaci) zajišťovala společnost Datasoft, s níž jsme se seznámili ve zcela jiném kontextu – tato firma totiž vytvářela i počítačové hry; viz například Hry vytvořené firmou Datasoft pro osmibitové domácí mikropočítače (už jsem psal, že v IT vše souvisí se vším, že?).

Obrázek 4: Úvodní obrazovka Intelispu/65

 Obrázek 4: Úvodní obrazovka Interlispu/65.

Autor: tisnik, podle licence: Rights Managed

3. Assemblery pro osmibitová Atari

Nás však v dnešním článku budou zajímat především assemblery.

Na osmibitových domácích mikropočítačích se používaly dva typy assemblerů. Prvním typem byly assemblery interaktivní, které uživateli nabízely poměrně komfortní vývojové prostředí, v němž bylo možné zapisovat jednotlivé instrukce, spouštět programy, krokovat je, vypisovat obsahy registrů mikroprocesoru atd. Výhodou takto pojatého řešení byla nezávislost těchto assemblerů na rychlém externím paměťovém médiu. S těmito assemblery určenými pro počítače Atari se ve stručnosti seznámíme i v dnešním článku, protože jak Atari Assembler Editor, tak i MAC/65 náleží do této kategorie. Druhý typ assemblerů je používán dodnes – jedná se vlastně o běžné překladače, kterým se na vstupu předloží zdrojový kód (uložený na kazetě či disketě) a po překladu se výsledný nativní kód taktéž uloží na paměťové médium (odkud ho lze spustit). Tyto assemblery byly mnohdy vybaveny více či méně dokonalým systémem maker (odtud název macroassembler). Příkladem takového assembleru pro Atari jsou všechny moderní crossassemblery.

Jedním z nejstarších vývojových nástrojů pro osmibitové mikropočítače Atari je Atari Assembler Editor, jehož vznik se datuje do let 1979 až 1980. Tento nástroj byl používán i pro vývoj samotného operačního systému počítačů Atari. Jak však tento nástroj vůbec vznikl, když ještě vlastně počítače Atari nebyly dokončené? První (zjednodušené) verze byly ručně děrovány na děrnou pásku, která byla použita pro naprogramování čipu EPROM. Ten byl vložen do prototypu Atari a následně otestován. Jednalo se tak o jednu z forem bootstrapingu, kterým jsme ze zabývali v článku Můžeme věřit překladačům? Projekty řešící schéma „důvěřivé důvěry“. Výsledná podoba Atari Assembler Editoru byla dodávána na standardní cartridge o kapacitě osmi kilobajtů (ovšem ve skutečnosti se do značné míry využívaly subrutiny z operačního systému a používané i Atari Basicem).

Obrázek 5: Úvodní obrazovka Atari Assembler Editoru je pojata přísně minimalisticky. Pouze se na ní oznamuje aktuálně vybraný režim, zde konkrétně režim editace.

Atari Assembler Editor se skládal ze tří částí: editoru, assembleru a debuggeru (což však byl ve skutečnosti pouze monitor – viz předchozí text). Všechny tři části byly dostupné z cartridge a bylo možné se mezi nimi přepínat. Zdrojový kód zapisovaný v editoru byl překládán dvouprůchodovým překladačem a mohl být v operační paměti uložen souběžně se zdrojovým kódem, což ovšem znamenalo omezení maximálního objemu zdrojového kódu. Zajímavé a typické pro interaktivní assemblery je, že řádky zdrojového kódu byly číslovány, podobně jako v BASICu. K dispozici však byly i poměrně pokročilé operace pro vyhledání návěští atd.

Obrázek 6: Přepnutí do režimu debuggeru a výpis obsahu prvních několika bajtů s interpretrem jazyka Basic.

Debugger (spíše monitor) umožňoval zobrazení obsahu operační paměti, zobrazení obsahu registrů mikroprocesoru, modifikaci paměti, zobrazení disassemblované části paměti, krokování programu atd. – ovšem ne tak kvalitně, jako tomu bylo u dále popsaného assembleru MAC/65.

Obrázek 7: Disassembler (zpětný assembler) určený pro mikropočítače Atari (úvodní nastavení).

Další programátorský nástroj, s nímž se dnes alespoň ve stručnosti seznámíme, se jmenuje MAC/65. Jedná se o assembler a současně i o debugger, jehož ovládání je odvozeno od výše zmíněného Atari Assembler Editoru; ve skutečnosti je však MAC/65 prakticky po všech stránkách lepší (až na poněkud vyšší cenu). Za vývojem MAC/65 stála společnost Optimized Systems Software (OSS). MAC/65 byl dodáván na specializované cartridgi s kapacitou 16kB, což je dvojnásobná kapacita, než jakou počítače Atari podporují (konektor měl pouze třináct adresních pinů). Z tohoto důvodu bylo oněch 16kB rozděleno do dvojice paměťových bank, z nichž každá měla kapacitu osmi kilobajtů a mezi kterými se provádělo automatické přepínání (taková cartridge se někdy nazývala „supercartridge“ a existovalo jich více typů, které se lišily způsobem přepínání paměťových bank).

Obrázek 8: Úvodní obrazovka MAC/65 verze 1.02.

Předností assembleru MAC/65 byl mnohem rychlejší překlad v porovnání s Atari Assembler Editorem. Taktéž byla k dispozici lepší forma debuggeru dostupná pod příkazem DDT.

Obrázek 9: V režimu EDIT se zapisují jednotlivé deklarace i instrukce procesoru MOS 6502. Řádky s deklaracemi a instrukcemi jsou číslovány, takže přidání resp. smazání řádku je snadné. Taktéž je možné si vyžádat automatické číslování (což například Atari BASIC neumí). K dispozici jsou i složitější příkazy – obecně je možné říci, že programátorský editor v MAC/65 je propracovanější, než v případě BASICů.

4. Překladače jazyka C pro osmibitová Atari

Pro osmibitová Atari byly dostupné i překladače jazyka C. Některé překladače C pro MOS 6502 byly navrženy přímo pro běh na strojích osazených tímto čipem. To je dnes zcela normální situace (aplikace pro PC se překládají na PC), ovšem v případě MOS 6502 se museli tvůrci překladačů vypořádat s pomalým čipem, velmi malou kapacitou paměti a navíc i relativně pomalým externím paměťovým médiem (typicky disketa, protože kazetové verze C by byly ještě problematičtější). V důsledku těchto omezení se jednalo spíše o projekty určené pro amatérské použití, zatímco profesionální software stále vznikal v assembleru. Jednou z prvních implementací překladače C pro MOS 6502 je C/65 od slavné firmy Optimized Systems Software (OSS).

Obrázek 10: C/65 od společnosti Optimized Systems Software (OSS).

Taktéž se na tomto místě musíme zmínit o známém překladači Aztec C, jenž byl portovaný na velké množství různých typů mikropočítačů, zapomenout nesmíme ani na Deep Blue C (viz též https://en.wikipedia.org/wi­ki/Deep_Blue_C) pro osmibitové počítače Atari. Zde se autoři museli vyrovnat s faktem, že znaková sada neobsahovala složené závorky, takže zápis vypadal například takto:

main()
$(
    printf("Hello World!");
$)
Poznámka: což připomíná trigraphy C.

Obrázek 11: Dobová reklama na nástroje společnosti OSS.

Zajímavější jsou z dnešního pohledu cross compilery a cross assemblery (viz poznámka o českém překladu tohoto názvu). Tyto typy nástrojů jsou velmi často používané i dnes, zejména v oblasti mikrořadičů, digitálních signálových procesorů nebo mobilních telefonů (viz například Scratchbox). Ovšem tato technologie se používala již na začátku osmibitové éry. Například vývoj her pro herní konzoli Atari 2600 (Atari Video Computer System neboli Atari VCS) byl prováděn na minipočítači. Ovšem i později některé firmy vyvíjely profesionální software pro Atari, C64 i další osmibitové mikropočítače na výkonnějších strojích, kde se prováděl i překlad.

Poznámka: existuje i český termín křížový překladač, ale musím se přiznat, že mi připadá jako výsledek otrockého překladu a navíc se slovo „cross“ přeložilo ve špatném kontextu.

Obrázek 12: Jeden z konkurenčních překladačů k Aztec C byl Lattice C (ovšem až v pozdější době).

Dobrým a možná i typickým příkladem jsou právě cross překladače programovacího jazyka C. Tvorbou těchto cross překladačů se zabývala například společnost Manx Software Systems, jejíž překladače céčka (Aztec C) určené pro IBM PC s DOSem i pro osobní mikropočítače Macintosh dokázaly provádět cross překlad na osmibitové mikropočítače Commodore C64 a Apple II. Na chvíli se u Aztec C zastavme, i když přímo nesouvisí s osmibitovými Atari.

Aztec C totiž byl ve své době velmi úspěšný překladač, jenž existoval jak ve verzi pro osmibitové mikroprocesory (MOS 6502, Zilog Z-80), tak i pro mikroprocesory 16bitové a 32bitové. Tento překladač byl velmi úspěšný právě na Amize, kde byl používán, společně s Lattice C, prakticky až do faktického zániku této platformy. Ovšem na IBM PC jeho sláva netrvala dlouho, především z toho důvodu, že firma Microsoft považovala segment překladačů za poměrně důležitý a snažila se vytlačit jakoukoli konkurenci z trhu (i když ve skutečnosti v té době ještě neměla vlastní céčkový překladač). Společnosti Manx Software Systems se postupně zmenšoval počet platforem, na něž bylo možné překladač prodávat a přechod na podporu vestavěných systémů již přišel dosti pozdě. A právě pro cross překlad se Aztec C může používat dodnes (běží v DOSu, takže dnes vlastně taktéž v emulovaném prostředí).

Poznámka: další informace o překladačích i cross překladačích Aztec C lze najít na stránce http://aztecmuseum.ca/compilers.htm.

Podobným stylem byl řešen i Microsoft C původně vytvořený společností, která stála za slavným Lattice C. Ostatně Lattice C byl s velkou pravděpodobností vůbec prvním překladačem céčka pro IBM PC (pochází z roku 1982). Ten byl později převeden i na Amigu, dále se rozšířil i na minipočítače a mainframy společnosti IBM. Firma Microsoft překladač Lattice C nabízela pod svým názvem MSC (Microsoft C) a teprve verze MSC 4.0 byla skutečně vytvořena přímo programátory z Microsoftu. Lattice C byl používán i při portaci aplikací z operačního systému CP/M na DOS (dnes je však možné pouze odhadnout, kolik kódu bylo skutečně napsáno v céčku a kolik kódu vzniklo transformací assembleru).

5. Základní programové vybavení pro vývoj her pro Atari v současnosti

Pro vývoj aplikací pro osmibitová Atari postačuje poměrně malé množství nástrojů. Základem pro nás bude assembler ca65 zkombinovaný s linkerem ld65. Jedná se vlastně o cross assembler, takže vývoj bude probíhat přímo na PC a do Atari se bude nahrávat až výsledný binární soubor. Dále je pochopitelně nutné mít k dispozici (libovolný) programátorský textový editor, ideálně s podporou zvýraznění syntaxe. A zapomenout nesmíme ani na emulátor osmibitových počítačů Atari. Výsledkem činnosti assembleru a linkeru budou binární soubory s koncovkou .xex, které je možné přímo nahrát do emulátoru a spustit je tam. Později si ukážeme, jakým způsobem se vytvoří obrazy disket, kazet (pro vážné zájemce) nebo aplikací uložených na cartridge.

Obrázek 13: Moderní editor Helix s assemblerem pro historický osmibitový počítač Atari.

Obrázek 13: Moderní editor Helix s assemblerem pro historický osmibitový počítač Atari. 

Autor: tisnik, podle licence: Rights Managed

6. Instalace ca65 a ld65

Jak jsme si již řekli v předchozí kapitole, budeme pro vývoj potřebovat assembler ca65 a linker ld65. Tyto dva nástroje jsou součástí instalace sady nástrojů vytvořených okolo překladače jazyka C, který se nazývá cc65. To znamená, že „instalací céčka“ získáme i nainstalovaný assembler a linker. Samotná instalace cc65 je na většině distribucí Linuxu snadná, neboť se jedná o balíčky umístěné přímo v repositářích dané distribuce. Příkladem může být Linux Mint (založený na apt/aptitude):

$ sudo apt-get install cc65
 
Reading package lists... Done
Building dependency tree
Reading state information... Done
Suggested packages:
  cc65-doc
The following NEW packages will be installed:
  cc65
0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded.
Need to get 2 162 kB of archives.
After this operation, 31,8 MB of additional disk space will be used.
Get:1 http://archive.ubuntu.com/ubuntu focal/universe amd64 cc65 amd64 2.18-1 [2 162 kB]
Fetched 2 162 kB in 5s (423 kB/s)
Selecting previously unselected package cc65.
(Reading database ... 291820 files and directories currently installed.)
Preparing to unpack .../archives/cc65_2.18-1_amd64.deb ...
Unpacking cc65 (2.18-1) ...
Setting up cc65 (2.18-1) ...

Instalace na Fedoře založené na RPM/DNF je stejně snadná:

$ sudo dnf install cc65
 
Updating and loading repositories:
Repositories loaded.
Package                                       Arch          Version                   Repository          Size
Installing:
 cc65                                         x86_64        2.19-12.fc42              fedora           1.2 MiB
Installing dependencies:
 cc65-devel                                   noarch        2.19-12.fc42              fedora          29.8 MiB
 
Transaction Summary:
 Installing:         2 packages
 
Total size of inbound packages is 2 MiB. Need to download 2 MiB.
After this operation, 31 MiB extra will be used (install 31 MiB, remove 0 B).
Is this ok [y/N]: y
[1/2] cc65-0:2.19-12.fc42.x86_64                           100% |   1.0 MiB/s | 422.1 KiB |  00m00s
[2/2] cc65-devel-0:2.19-12.fc42.noarch                     100% |   1.5 MiB/s |   1.8 MiB |  00m01s
---------------------------------------------------------------------------------------------------
[2/2] Total                                                100% |   1.3 MiB/s |   2.3 MiB |  00m02s
Running transaction
[1/4] Verify package files                                 100% | 105.0   B/s |   2.0   B |  00m00s
[2/4] Prepare transaction                                  100% |   3.0   B/s |   2.0   B |  00m01s
[3/4] Installing cc65-devel-0:2.19-12.fc42.noarch          100% | 213.2 MiB/s |  29.8 MiB |  00m00s
[4/4] Installing cc65-0:2.19-12.fc42.x86_64                100% |   1.7 MiB/s |   1.2 MiB |  00m01s
Complete!

Po dokončení instalace budou k dispozici všechny tři výše zmíněné nástroje (a několik podpůrných nástrojů).

V první řadě se jedná o assembler:

$ cc65 --version
cc65 V2.18 - Ubuntu 2.18-1

Dále o překladač céčka:

$ ca65 --version
ca65 V2.18 - Ubuntu 2.18-1

A využijeme i samostatný linker:

$ ld65 --version
ld65 V2.18 - Ubuntu 2.18-1
Poznámka: nainstalován je ovšem ale například i disassembler atd. K těmto nástrojům se ještě později vrátíme.

7. Praktická část: čím se liší vývoj pro osmibitová Atari od dnes běžného vývoje?

V současnosti (pokud tedy vynecháme vibe coding a specs coding) typický vývoj probíhá takovým způsobem, že se vývojář seznámí s programovacím jazykem a taktéž se sadou knihoven, které bude používat. Vývoj pro osmibitová Atari, ale i pro další podobné stroje, je poněkud odlišný. Vývojář se musí seznámit s assemblerem i s podrobným popisem činnosti mikroprocesoru a navíc musí znát hardwarové vlastnosti Atari. Na druhou stranu odpadá seznamování se s knihovnami – každý pravý vývojář pro osmibitové stroje si totiž potřebné knihovny (nebo i celé enginy) naprogramuje sám. A podobně budeme v tomto seriálu postupovat i my: v jednotlivých krocích se seznámíme s možnostmi CPU MOS 6502 a taktéž hardwarem Atari, tj. s čipy ANTIC, GTIA a POKEY. Vývoj pro Atari totiž do značné míry znamená přímé ovládání těchto čipů popř.v případě ANTICu jeho programování (přes takzvaný display list, což je série specializovaných instrukcí).

Obrázek 14: Emulátor Atari po dodání obrazu standardní ROM určené pro systém Atari 800 XL

Obrázek 14: Emulátor Atari po dodání obrazu standardní ROM určené pro systém Atari 800 XL. 

Autor: tisnik, podle licence: Rights Managed

8. První demonstrační příklad: prostá nekonečná smyčka

Dnešní první demonstrační příklad bude po logické stránce velmi jednoduchý. Je v něm totiž pouze implementována nekonečná programová smyčka. Ta je definována v segmentu .CODE (ten v našem případě začíná na adrese 0×2000, ovšem může se posunout prakticky kamkoli kromě nulté a první stránky a stránek s HW registry či mapovanou ROM). Samotná smyčka je pro lepší čitelnost zařazena do procedury nazvané main. Segment .CODE tedy bude vypadat následovně:

.CODE
 
.proc main
loop:   jmp loop
end:
.endproc

To však nestačí, protože ve výsledném binárním souboru s koncovkou .xex musí být uloženy další dva segmenty. První z těchto segmentů obsahuje hlavičku 0×ffff a dvě adresy se začátkem a koncem kódového segmentu:

.segment "EXEHDR"
.word   $ffff                   ; uvodni sekvence bajtu v souboru XEX
.word   main                    ; zacatek kodoveho segmentu
.word   main::end - 1           ; konec kodoveho segmentu

A druhý segment obsahuje adresu první instrukce, která se má spustit. Tato adresa se uloží do slova umístěného na adrese RUNAD (0×02e0):

.segment "AUTOSTRT"             ; segment s pocatecni adresou
.word   $02E0                   ; naplni se pouze adresy RUNAD a RUNAD+1
.word   $02E1
.word   main                    ; adresa vstupniho bodu do programu

Celý zdrojový kód tohoto demonstračního příkladu je sice poněkud dlouhý, ale v praxi vlastně nebudeme segmenty EXEHDR a AUTOSTRT (prakticky nikdy) měnit, takže v dalších příkladem pouze zmodifikujeme instrukce v kódovém segmentu:

.CODE
 
.proc main
loop:   jmp loop
end:
.endproc
 
 
.segment "EXEHDR"
.word   $ffff                   ; uvodni sekvence bajtu v souboru XEX
.word   main                    ; zacatek kodoveho segmentu
.word   main::end - 1           ; konec kodoveho segmentu
 
 
.segment "AUTOSTRT"             ; segment s pocatecni adresou
.word   $02E0                   ; naplni se pouze adresy RUNAD a RUNAD+1
.word   $02E1
.word   main                    ; adresa vstupniho bodu do programu
 
; finito

9. Překlad do strojového kódu s vytvořením listingu

Překlad demonstračního příkladu z předchozí kapitoly je proveden ve dvou krocích. V kroku prvním se spustí assembler ca65, jenž vytvoří soubor s objektovým kódem a taktéž „listing“ pro kontrolu, jakým způsobem byl vlastně překlad proveden:

$ ca65 background_color_1.asm -t atari -o dummy.o -l dummy.asm --list-bytes 100

Soubor s listingem by měl vypadat následovně. Povšimněte si, že obsahuje i kódy instrukcí a jediné chybějící údaje se týkají adres, které (prozatím) nejsou doplněny (namísto nich jsou použity znaky rr):

ca65 V2.18 - Fedora 2.19-12.fc42
Main file   : dummy.asm
Current file: dummy.asm
 
000000r 1               .CODE
000000r 1
000000r 1               .proc main
000000r 1  4C rr rr     loop:   jmp loop
000003r 1               end:
000003r 1               .endproc
000003r 1
000003r 1
000003r 1               .segment "EXEHDR"
000000r 1  FF FF        .word   $ffff                   ; uvodni sekvence bajtu v souboru XEX
000002r 1  rr rr        .word   main                    ; zacatek kodoveho segmentu
000004r 1  rr rr        .word   main::end - 1           ; konec kodoveho segmentu
000006r 1
000006r 1
000006r 1               .segment "AUTOSTRT"             ; segment s pocatecni adresou
000000r 1  E0 02        .word   $02E0                   ; naplni se pouze adresy RUNAD a RUNAD+1
000002r 1  E1 02        .word   $02E1
000004r 1  rr rr        .word   main                    ; adresa vstupniho bodu do programu
000006r 1
000006r 1               ; finito
000006r 1

10. Konfigurace linkeru, spuštění linkeru s vytvořením výsledného souboru ve formátu xex

V kroku druhém se spouští linker ld65. Výsledkem jeho činnosti bude soubor s mapou paměti a především pak binární soubor ve formátu xex, který bude možné přímo spustit v emulátoru Atari. Linker spustíme následujícím příkazem:

$ ld65 -C linker.cfg dummy_1.o -o dummy_1.xex -m dummy_1.map

Soubor dummy1.map obsahuje mapu paměti. Povšimněte si tabulky se všemi třemi segmenty. Kódový segment skutečně začíná na adrese 0×2000 a končí na adrese 0×2002 (tedy celkem tři bajty, do kterých je zakódována instrukce jmp):

Modules list:
-------------
dummy.o:
    CODE              Offs=000000  Size=000003  Align=00001  Fill=0000
    EXEHDR            Offs=000000  Size=000006  Align=00001  Fill=0000
    AUTOSTRT          Offs=000000  Size=000006  Align=00001  Fill=0000
 
 
Segment list:
-------------
Name                   Start     End    Size  Align
----------------------------------------------------
AUTOSTRT              000000  000005  000006  00001
EXEHDR                000000  000005  000006  00001
CODE                  002000  002002  000003  00001
 
 
Exports list by name:
---------------------
 
 
 
Exports list by value:
----------------------
 
 
 
Imports list:
-------------

Ovšem důležitější je soubor dummy.xex, jenž má velikost patnácti bajtů a je přímo spustitelný v emulátoru Atari:

$ ls -l dummy.xex
 
-rw-r--r--. 1 ptisnovs ptisnovs 15 Mar  3 17:01 dummy.xex
Obrázek 16: Takto sofistikovaně vypadá obrazovka po spuštění prvního demonstračního příkladu v emulátoru

Obrázek 16: Takto sofistikovaně vypadá obrazovka po spuštění prvního demonstračního příkladu v emulátoru. 

Autor: tisnik, podle licence: Rights Managed

11. Formát .xex

Zastavme se na chvíli u souboru dummy.xex, který vznikl jako výsledek činnosti linteru a je ho možné přímo spustit v emulátoru osmibitových mikropočítačů Atari. Tento soubor má interně velmi jednoduchou strukturu. Skládá se z jednotlivých segmentů, přičemž na začátku je speciální segment nazvaný EXEHDR (ten jsme již viděli ve zdrojovém kódu). Každý segment je uložen následovně:

Offset Stručný popis
00–01 obsahuje 0×ffff u prvního segmentu EXEHDR, u dalších segmentů uveden nemusí být
02–03 startovní adresa (dva bajty); obsah segmentu se do paměti nahraje právě od této adresy
04–05 koncová adresa určená pro výpočet délky segmentu
06-?? obsah segmentu

Až se do paměti nahrají všechny segmenty, je program spuštěn od adresy uložené na 0×02e0.

Ostatně se můžeme podívat na náš soubor dummy1.xex. Jeho obsah je následující:

$ od -Ad -tx1 dummy_1.xex
 
0000000 ff ff 00 20 02 20 4c 00 20 e0 02 e1 02 00 20
0000015

Význam všech patnácti bajtů je následující:

Bajty Stručný popis
ff ff začátek segmentu EXEHDR
00 20 startovní adresa = 0×2000
02 20 koncová adresa = 0×2002 (tři bajty celkem)
4c 00 20 instrukce JMP 0×2000
e0 02 druhý segment, startovní adresa = 0×02e0
e1 02 druhý segment, koncová adresa = 0×02e1 (dva bajty celkem)
00 20 obsah segmentu = 0×2000 (což je startovní adresa programu)
Poznámka: v praxi není nutné formátu xex dopodrobna rozumět, ovšem tuto kapitolu jsem uvedl z toho důvodu, aby bylo zřejmé, že je samotný formát až triviálně jednoduchý a přitom umožňuje například linking obrázků i dalších dat (a nejedná se o otrockou kopii obsahu operační paměti).

12. Druhý demonstrační příklad: změna barvy pozadí v textovém režimu

Úvodní demonstrační příklad byl až příliš jednoduchý – vlastně ani nebylo poznat, že byl korektně spuštěn. Z tohoto důvodu si ukážeme jen nepatrně složitější příklad, který po svém spuštění změní hodnotu HW registru mapovaného na adresu 710 (decimálně). Tento registr obsahuje kód barvy pozadí textového režimu (v grafických režimech tomu je jinak, tedy kromě režimu číslo 8). Kód barvy je uložen v jednom bajtu a obsahuje intenzitu barvy i její odstín. Zápisem nuly nastavíme černou barvu, což již bude viditelná změna, protože ve výchozím nastavení má textový režim na pozadí barvu světle modrou.

A jak se provede zápis nuly na adresu 710? Musíme použít dvě instrukce. První instrukce vynuluje akumulátor A a druhá instrukce uloží obsah akumulátoru na zvolenou adresu. Povšimněte si, že konstanta se zapisuje s křížkem na začátku, zatímco adresa je reprezentována pouze číslem (POZOR: na i86 je tomu zcela jinak):

        lda #0                  ; kod barvy
        sta 710                 ; ulozit do registru COLOR2

Celý zdrojový kód tohoto demonstračního příkladu bude vypadat následovně:

.CODE
 
.proc main
        lda #0                  ; kod barvy
        sta 710                 ; ulozit do registru COLOR2
loop:   jmp loop
end:
.endproc
 
 
.segment "EXEHDR"
.word   $ffff                   ; uvodni sekvence bajtu v souboru XEX
.word   main                    ; zacatek kodoveho segmentu
.word   main::end - 1           ; konec kodoveho segmentu
 
 
.segment "AUTOSTRT"             ; segment s pocatecni adresou
.word   $02E0                   ; naplni se pouze adresy RUNAD a RUNAD+1
.word   $02E1
.word   main                    ; adresa vstupniho bodu do programu
 
; finito

Výsledek po spuštění v emulátoru osmibitových Atari:

Obrázek 17: Změna barvy pozadí v textovém režimu.

Obrázek 17: Změna barvy pozadí v textovém režimu. 

Autor: tisnik, podle licence: Rights Managed

13. Symboly definované v souboru atari.inc

Ve zdrojovém kódu předchozího demonstračního příkladu bylo použito mnoho „magických konstant“, konkrétně konstanty 710, 0×02e0 a 0×02e1. Mj. i kvůli používání takových konstant má assembler reputaci špatně čitelného jazyka, ovšem nemusí tomu tak být. Společně s cc65 a dalšími nástroji je totiž dodáván soubor nazvaný atari.inc, který obsahuje přibližně tisíc (!) pojmenovaných konstant – jmen HW registrů, tabulek v ROM, kódů kláves atd. atd. A mj. v tomto souboru nalezneme i následující pětici pojmenovaných konstant s adresami barvových registrů:

COLOR0  = $02C4         ;1-byte playfield 0 color/luminance
COLOR1  = $02C5         ;1-byte playfield 1 color/luminance
COLOR2  = $02C6         ;1-byte playfield 2 color/luminance
COLOR3  = $02C7         ;1-byte playfield 3 color/luminance
 
COLOR4  = $02C8         ;1-byte background color/luminance

A navíc zde nalezneme konstantu:

RUNAD   = $02E0         ;##map## 2-byte binary file run address

Tyto konstanty můžeme snadno využít ve zdrojových kódech; pouze je nutné na začátku hlavičkový soubor načíst:

.include "atari.inc"

14. Třetí demonstrační příklad: využití symbolů definovaných v souboru atari.inc

Podívejme se nyní, jak se zápis programu zpřehlední, pokud v něm použijeme konstanty COLOR2 a RUNAD. Nyní již kód neobsahuje žádná „magická čísla“:

.include "atari.inc"
 
.CODE
 
.proc main
        lda #0                  ; kod barvy
        sta COLOR2              ; ulozit do registru COLOR2
loop:   jmp loop
end:
.endproc
 
 
.segment "EXEHDR"
.word   $ffff                   ; uvodni sekvence bajtu v souboru XEX
.word   main                    ; zacatek kodoveho segmentu
.word   main::end - 1           ; konec kodoveho segmentu
 
 
.segment "AUTOSTRT"             ; segment s pocatecni adresou
.word   RUNAD                   ; naplni se pouze adresy RUNAD a RUNAD+1
.word   RUNAD+1
.word   main                    ; adresa vstupniho bodu do programu
 
; finito

15. Adresovací režimy mikroprocesoru MOS 6502, využití registrů X a Y

Adresovací režimy odlišují mikroprocesor MOS 6502 od naprosté většiny ostatních mikroprocesorů a umožňují použít odlišný styl programování založený na efektivním použití nulté stránky paměti a obou index registrů. Existuje celkem třináct (!) adresovacích režimů, ovšem žádná instrukce nevyužívá všechny dostupné režimy. Některé adresovací režimy jsou určeny pouze pro skoky, další pro implicitní operandy atd.:

# Zápis Název Assembler Stručný popis
1 A accumulator INS A operandem je přímo akumulátor
2 abs absolute INS $LLHH za instrukcí následuje šestnáctibitová adresa, na níž je operand uložen
3 abs,X absolute, X-indexed INS $LLHH,X za instrukcí následuje šestnáctibitová adresa, která je přičtena k X
4 abs,Y absolute, Y-indexed INS $LLHH,Y za instrukcí následuje šestnáctibitová adresa, která je přičtena k Y
5 # immediate INS #$BB za instrukcí následuje bajt s konstantou
6 impl implied INS operand je odvozen přímo z instrukce, například INX
7 ind indirect INS ($LLHH) nepřímá adresace přes adresu uloženou za instrukcí (ta je ukazatelem), nepřímý skok
8 X,ind X-indexed, indirect INS ($LL,X) efektivní adresa je spočtena z hodnoty uložené na (LL+X)
9 ind,Y indirect, Y-indexed INS ($LL),Y efektivní adresa je spočtena z hodnoty uložené na LL, k výsledku se přičte Y
10 rel relative INS $BB použito u relativních skoků; za instrukcí je jeden bajt reprezentující offset se znaménkem
11 zpg zeropage INS $LL operand je uložen na nulté stránce na adrese LL
12 zpg,X zeropage, X-indexed INS $LL,X operand je uložen na nulté stránce na adrese LL+X
13 zpg,Y zeropage, Y-indexed INS $LL,Y operand je uložen na nulté stránce na adrese LL+Y
Poznámka: povšimněte si, že použití registrů X a Y není zcela symetrické, protože se od sebe liší podporou resp. nepodporou adresovacího režimu X,ind a ind,Y. Zejména poslední zmíněný režim lze použít pro operace s poli, přesuny bloků, mazání bloků atd.

16. Čtvrtý demonstrační příklad: tisk znaku „A“ do horního levého rohu obrazovky

Popis adresovacích režimů byl do tohoto článku zařazen schválně. Ukážeme si totiž, jakým způsobem lze provádět zápis do obrazové paměti. Standardní textový režim počítačů Atari má 40 znaků na řádku a 24 řádků, celkem tedy zabírá 960 bajtů. Začátek obrazové paměti je ovšem proměnný, takže ho nejprve musíme nějak zjistit. Konkrétní adresa začátku obrazové paměti je uložena ve dvou bajtech na adrese 88 (decimálně). Pokud tedy budeme chtít na začátek obrazovky vypsat písmeno „A“, musíme přečíst adresu uloženou na adresách 88+89 a na tuto načtenou adresu (může být například rovna 40000) uložíme ATASCII hodnotu znaku „A“.

Ovšem díky adresovacímu režimu (ADR),Y se celá situace zjednodušuje. Tento adresovací režim načte z adresy ADR (v našem případě z adresy 88) ukazatel a přičte k němu hodnotu registru Y. To tedy znamená, že zápis na nepřímo zadanou adresu je proveden jedinou instrukcí! A právě tento postup je použit v dnešním posledním demonstračním příkladu:

.include "atari.inc"
 
.CODE
 
.proc main
        lda #33                 ; ATASCII hodnota znaku "A"
        ldy #0                  ; vynulovat registr Y
        sta (88),y              ; tisk znaku "A" na první místo na obrazovce
                                ; (adresa Video RAM je na adresách 88 a 89)
loop:   jmp loop
end:
.endproc
 
 
.segment "EXEHDR"
.word   $ffff                   ; uvodni sekvence bajtu v souboru XEX
.word   main                    ; zacatek kodoveho segmentu
.word   main::end - 1           ; konec kodoveho segmentu
 
 
.segment "AUTOSTRT"             ; segment s pocatecni adresou
.word   RUNAD                   ; naplni se pouze adresy RUNAD a RUNAD+1
.word   RUNAD+1
.word   main                    ; adresa vstupniho bodu do programu
 
; finito
Poznámka: použitý adresovací režim je vlastně jednou z největších zbraní mikroprocesoru MOS 6502 (což si ostatně ukážeme příště) a umožňuje použít nultou stránku paměti jako de facto sadu 128 adresovacích registrů.

Můžete pochopitelně použít i následující pojmenovanou konstantu:

SAVMSC  = $58           ;2-byte saved memory scan counter
Obrázek 18: Znak 'A' byl zapsán na první volné místo na obrazovce, dokonce ještě před textový kurzor

Obrázek 18: Znak „A“ byl zapsán na první volné místo na obrazovce, dokonce ještě před textový kurzor. 

Autor: tisnik, podle licence: Rights Managed

17. Příloha A: Konfigurační soubor pro linker ld65

Připomeňme si, že v průběhu vytváření výsledného souboru ve formátu xex musí linker mj. znát i paměťové rozsahy, adresy některých symbolů (minimálně EXEHDR, STARTUP, CODE) atd. Pro naše prozatím velmi jednoduché demonstrační příklady bude postačovat následující konfigurace linkeru (později ji rozšíříme):

FEATURES
{
    STARTADDRESS: default = $2000;
}
 
SYMBOLS
{

}
 
MEMORY
{
    ZP:         start = $0082, size = $007E, type = rw, define = yes;
    HEADER:     start = $0000, size = $0006, file = %O;
    RAM:        start = %S,    size = $8000, file = %O;
    TRAILER:    start = $0000, size = $0006, file = %O;
}
 
SEGMENTS
{
    EXEHDR:   load = HEADER,  type = ro;
    STARTUP:  load = RAM,     type = ro, define = yes, optional = yes;
    ZEROPAGE: load = ZP,      type = zp;
    CODE:     load = RAM,     type = ro, define = yes;
    AUTOSTRT: load = TRAILER,   type = ro;
}
 
FEATURES
{
    CONDES: segment = INIT,
        type = constructor,
        label = __CONSTRUCTOR_TABLE__,
        count = __CONSTRUCTOR_COUNT__;
    CONDES: segment = RODATA,
        type = destructor,
        label = __DESTRUCTOR_TABLE__,
        count = __DESTRUCTOR_COUNT__;
    CONDES: type = interruptor,
        segment = RODATA,
        label = __INTERRUPTOR_TABLE__,
        count = __INTERRUPTOR_COUNT__;
}

18. Příloha B: Makefile pro překlad všech demonstračních příkladů

Všechny tři dnes popsané demonstrační příklady, pro jejichž překlad je zapotřebí použít assembler ca65 a linker ld65, je možné přeložit s využitím souboru Makefile, jehož obsah je vypsán pod tímto odstavcem:

Školení Zabbix

execs := dummy.xex print_a.xex background_color_1.xex background_color_2.xex
 
all: $(execs)
 
clean:
        rm -f *.o
        rm -f *.xex
 
.PHONY: all clean
 
%.o: %.asm
        ca65 $< -t atari -o $@ -l $(basename $<)_list.asm --list-bytes 100
 
%.xex: %.o
        ld65 -C linker.cfg $< -o $@ -m $(basename $<).map

Výsledkem překladu jsou soubory s koncovkou .xex, které je možné přímo spustit v emulátoru osmibitových počítačů Atari.

19. Repositář s demonstračními příklady

Všechny demonstrační příklady, s nimiž jsme se v dnešním článku seznámili a které jsou určeny pro překlad s využitím assembleru ca65, jsou dostupné, jak je zvykem, na GitHubu. V tabulce níže jsou uvedeny odkazy na jednotlivé zdrojové kódy příkladů psané v assembleru i „listingy“ vygenerované samotným assemblerem, ze kterých je patrné, jakým způsobem se jednotlivé příklady přeložily do výsledného XEX souboru:

# Příklad Stručný popis příkladu Adresa
1 Makefile definice cílů pro překlad všech demonstračních příkladů z této tabulky https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/Makefile
2 linker.cfg konfigurační soubor pro linker https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/linker.cfg
       
3 dummy.asm pouze nekonečná smyčka https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/dummy.asm
4 dummy_list.asm „listing“ vygenerovaný assemblerem https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/dummy_list.asm
5 dummy_list.map mapa paměti; soubor vytvořený linkerem https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/dummy.map
       
6 background_color1.asm změna barvy pozadí – základní varianta příkladu https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/background_color1.asm
7 background_color1_list.asm „listing“ vygenerovaný assemblerem https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/background_color1_list.asm
8 background_color1.map mapa paměti; soubor vytvořený linkerem https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/background_color1.map
       
9 background_color2.asm změna barvy pozadí – využití předdefinovaných konstant https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/background_color2.asm
10 background_color2_list.asm „listing“ vygenerovaný assemblerem https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/background_color2_list.asm
11 background_color2.map mapa paměti; soubor vytvořený linkerem https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/background_color2.map
       
12 print_a.asm tisk znaku přímo do obrazové paměti https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/print_a.asm
13 print_a_list.asm „listing“ vygenerovaný assemblerem https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/print_a_list.asm
14 print_a.map mapa paměti; soubor vytvořený linkerem https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/print_a.map

20. Odkazy na Internetu

  1. MOS 6502 instruction set
    http://www.6502.org/users/o­belisk/6502/instructions.html
  2. EXE File Format Description
    https://gury.atari8.info/ref­s/file_formats_exe.php
  3. XEX Filter – A toolkit to analyze and manipulate Atari binary files
    https://www.vitoco.cl/atari/xex-filter/index.html
  4. chkxex.py
    https://raw.githubusercon­tent.com/seban-slt/tcx_tools/refs/heads/mas­ter/chkxex.py
  5. ca65 Users Guide
    https://cc65.github.io/doc/ca65.html
  6. cc65 Users Guide
    https://cc65.github.io/doc/cc65.html
  7. ld65 Users Guide
    https://cc65.github.io/doc/ld65.html
  8. da65 Users Guide
    https://cc65.github.io/doc/da65.html
  9. Překladače jazyka C pro historické osmibitové mikroprocesory
    https://www.root.cz/clanky/prekladace-jazyka-c-pro-historicke-osmibitove-mikroprocesory/
  10. Překladače programovacího jazyka C pro historické osmibitové mikroprocesory (2)
    https://www.root.cz/clanky/prekladace-programovaciho-jazyka-c-pro-historicke-osmibitove-mikroprocesory-2/
  11. Getting Started Programming in C: Coding a Retro Game with C Part 2
    https://retrogamecoders.com/getting-started-with-c-cc65/
  12. NES game development in 6502 assembly – Part 1
    https://kibrit.tech/en/blog/nes-game-development-part-1
  13. NES 6502 Programming Tutorial – Part 1: Getting Started
    https://dev.xenforo.relay­.cool/index.php?threads/nes-6502-programming-tutorial-part-1-getting-started.858389/
  14. Minimal NES example using ca65
    https://github.com/bbbradsmith/NES-ca65-example
  15. List of 6502-based Computers and Consoles
    https://www.retrocompute.co.uk/list-of-6502-based-computers-and-consoles/
  16. 6502 – the first RISC µP
    http://ericclever.com/6500/
  17. 3 Generations of Game Machine Architecture
    http://www.atariarchives.or­g/dev/CGEXPO99.html
  18. “Hello, world” from scratch on a 6502 — Part 1
    https://www.youtube.com/wat­ch?v=LnzuMJLZRdU
  19. A Tour of 6502 Cross-Assemblers
    https://bumbershootsoft.wor­dpress.com/2016/01/31/a-tour-of-6502-cross-assemblers/
  20. Adventures with ca65
    https://atariage.com/forum­s/topic/312451-adventures-with-ca65/
  21. example ca65 startup code
    https://atariage.com/forum­s/topic/209776-example-ca65-startup-code/
  22. 6502 PRIMER: Building your own 6502 computer
    http://wilsonminesco.com/6502primer/
  23. 6502 Instruction Set
    https://www.masswerk.at/6502/6502_in­struction_set.html
  24. Chip Hall of Fame: MOS Technology 6502 Microprocessor
    https://spectrum.ieee.org/tech-history/silicon-revolution/chip-hall-of-fame-mos-technology-6502-microprocessor
  25. Single-board computer
    https://en.wikipedia.org/wiki/Single-board_computer
  26. www.6502.org
    http://www.6502.org/
  27. 6502 PRIMER: Building your own 6502 computer – clock generator
    http://wilsonminesco.com/6502pri­mer/ClkGen.html
  28. Great Microprocessors of the Past and Present (V 13.4.0)
    http://www.cpushack.com/CPU/cpu.html
  29. Jak se zrodil procesor?
    https://www.root.cz/clanky/jak-se-zrodil-procesor/
  30. Osmibitové mikroprocesory a mikrořadiče firmy Motorola (1)
    https://www.root.cz/clanky/osmibitove-mikroprocesory-a-mikroradice-firmy-motorola-1/
  31. Mikrořadiče a jejich použití v jednoduchých mikropočítačích
    https://www.root.cz/clanky/mikroradice-a-jejich-pouziti-v-jednoduchych-mikropocitacich/
  32. Mikrořadiče a jejich aplikace v jednoduchých mikropočítačích (2)
    https://www.root.cz/clanky/mikroradice-a-jejich-aplikace-v-jednoduchych-mikropocitacich-2/
  33. 25 Microchips That Shook the World
    https://spectrum.ieee.org/tech-history/silicon-revolution/25-microchips-that-shook-the-world
  34. Comparison of instruction set architectures
    https://en.wikipedia.org/wi­ki/Comparison_of_instructi­on_set_architectures
  35. How To Start Learning Atari 8 Bit Assembly For Free
    https://forums.atariage.com/to­pic/300732-how-to-start-learning-atari-8-bit-assembly-for-free/
  36. WUDSN (Demo Group)
    https://www.wudsn.com/
  37. Machine Language For Beginners
    https://www.atariarchives.org/mlb/
  38. Assembly language: all about I/O
    https://www.atarimagazines­.com/v3n8/AllAbout_IO.html
  39. Sedmdesátiny assemblerů: lidsky čitelný strojový kód
    https://www.root.cz/clanky/sed­mdesatiny-assembleru-lidsky-citelny-strojovy-kod/

Autor článku

Vystudoval VUT FIT a v současné době pracuje na projektech vytvářených v jazycích Python a Go.



Nejnovější články