Zvuky a hudba na ZX Spectru: zvukové čipy řady AY-3–8910

13. 6. 2023
Doba čtení: 46 minut

Sdílet

Autor: Depositphotos
V sedmnácté části seriálu o vývoji her a dalších aplikací pro slavné ZX Spectrum si ukážeme, jakým způsobem lze produkovat zvuky či hudbu s využitím zvukového čipu řady AY-3–8910, tedy slavného „ayčka“. To bylo součástí ZX Spectra 128k i některých dalších rozšíření (Melodik atd.).

Obsah

1. Integrované obvody pro generování zvuků a hudby na osmibitových domácích mikropočítačích

2. Co si máme představit pod pojmem „zvukový čip“?

3. Zvukový čip AY-3–8910 – slavné „ayčko“ a jeho varianty

4. Tři varianty ayčka

5. Příklady použití ayčka

6. Tónové generátory čipu AY-3–8910

7. Úprava signálu s využitím obálky

8. Nelineární D/A převodníky

9. AY-3–8910 z pohledu programátora

10. Nastavení frekvence výsledného tónu

11. Výpočet hodnot ukládaných do registrů R0 a R1 pro přehrání komorního A

12. Generátor obálky

13. Mixer a ovládání hlasitosti jednotlivých kanálů

14. Tvarování výsledného zvuku s využitím obálky (envelope)

15. Programové ovládání čipu AY na ZX Spectru z assembleru

16. Přehrání komorního A prakticky

17. Úprava programu – nastavení zvoleného řídicího registru čipu AY v podprogramu

18. Příloha: upravený soubor Makefile pro překlad demonstračních příkladů

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

20. Odkazy na Internetu

1. Integrované obvody pro generování zvuků a hudby na osmibitových domácích mikropočítačích

Integrované obvody určené pro generování zvuků a hudby tvoří nedílnou a současně i velmi důležitou součást historie vývoje herních konzolí a samozřejmě i osmibitových domácích mikropočítačů. Až na několik výjimek, mezi něž patří především původní ZX Spectrum 48k a vlastně i všechny osmibitové domácí mikropočítače vyráběné v ČSSR, byly těmito čipy osazeny prakticky všechny úspěšné herní konzole a mikropočítače vyráběné od konce sedmdesátých let minulého století až po začátek let devadesátých, kdy již na trhu začaly převažovat šestnáctibitové a 32bitové stroje. A právě vlastnosti a nabízené možnosti zvukových čipů do značné míry určovaly oblíbenost dané platformy.

Jedná se zejména o tyto typy integrovaných obvodů:

  • Integrovaný obvod TIA použitý především v herních konzolích Atari 2600 i v Atari 7800
  • Integrovaný obvod POKEY, který byl použit v osmibitových mikropočítačích Atari (a některých herních konzolích a automatech).
  • Zvukový čip Texas Instruments SN76489 (DCSG)
  • Zvukový čip Texas Instruments SN76496 (varianta DCSG)
  • Do třetice zvukový čip Texas Instruments, tentokrát ovšem s označením SN76477
  • Zvukový subsystém konzole NES založené na čipu Ricoh 2A03/2A07
  • Integrovaný obvod AY-3–8910 neboli podomácku „áýčko“ a jeho varianty (Yamaha YM2149 atd.), ten nás dnes bude zajímat nejvíce.
  • Na závěr nesmíme zapomenout na SID firmy MOS použitý v počítačích Commodore.

2. Co si máme představit pod pojmem „zvukový čip“?

Hned na začátku dnešního článku si musíme ozřejmit, že pod termínem „zvukový čip“ nebo „hudební čip“ můžeme mít na mysli tři typy obvodů. Nejjednodušší jsou obvody označované zkratkou PSG neboli Programmable Sound Generator. Interně mnohem komplikovanější jsou čipy s FM syntézou a později, se zvyšující se kapacitou pamětí, se začaly více prosazovat i obvody určené především pro přehrávání a mixování samplů (PCM). Nás bude v tomto článku zajímat především první skupina, která je v mnoha ohledech nejzajímavější a navíc nás PSG provázely prakticky celou érou osmibitových domácích mikropočítačů i konzolí. Čipy s FM syntézou (OPL-2, OPL-3 atd.) si spojujeme spíše s érou PC a zvukových karet AdLib a SoundBlaster.

Všechny PSG, které jsme si vypsali v úvodní kapitole, jsou založeny na zpracování vstupního hodinového signálu, kterým jsou řízeny interní moduly PSG. PSG mohou generovat obdélníkové signály s volitelnou frekvencí (a někdy i s konfigurovatelnou střídou), dále pak šum s volitelnou frekvencí a některé PSG navíc generují i trojúhelníkový a/nebo pilový signál (pro zvuk hudebních nástrojů je vhodnější pilový signál). Podle typu PSG můžeme na čipu očekávat i takzvaný generátor obálky (envelope generator), popř. i různé typy filtrů a propustí.

V případě, že je hodinový signál přiveden na běžný čítač s výstupem propojeným s klopným obvodem T, bude takto zapojený modul generovat obdélníkový výstupní signál s frekvencí určenou počáteční hodnotou čítače (samotná konstrukce čítačů se od sebe může odlišovat, většinou však čítají směrem k nule a při podtečení se na výstupu objeví impuls přivedený do klopného obvodu). Výsledkem je obdélníkový signál (který ostatně známe, protože ho můžeme generovat i původním beeperem na ZX Spectru. Jak se ovšem tvoří další tvary signálů?

Několik PSG používá pro generování trojúhelníkového nebo i pilového signálu čtyřbitový čítač (tedy 16 úrovní), jehož výstup je přes jednoduchý čtyřbitový D/A převodník přiváděn na reproduktor (popř. na mixer a teprve poté na reproduktor). To znamená, že na osciloskopu uvidíme spíše různé schůdky, ale určitě ne čistý trojúhelníkový průběh. Konkrétní tvar signálu je samozřejmě ovlivněn i filtry a zesilovačem, které „schůdky“ do jisté míry vyhladí.

Generování šumu je u naprosté většiny PSG založeno na použití posuvného registru se zpětnou vazbou (LSFR, též poly counter), přičemž bitová délka tohoto registru určuje, jak bude šum znít – zda bude skutečně „náhodný“, nebo zda bude mít tak krátkou periodu, že vlastně vznikne pouze zkreslený tón. LSFR použité u zvukových generátorů mají mnoho podob a různou délku (od čtyř do sedmnácti bitů).

3. Zvukový čip AY-3–8910 – slavné „ayčko“ a jeho varianty

Nepřehlédnutelným zvukovým čipem pocházejícím z éry osmibitových počítačů, který si v tomto článku popíšeme, je čip AY-3–8910 firmy General Instrument (GI), později vyráběný i firmou Yamaha pod označením YM2149. Tento čip byl součástí osmibitového domácího mikropočítače ZX Spectrum 128K (a navazujících modelů), herních konzolí Vectrex a Intellivision či 16/32bitového počítače Atari ST (YM2149) či CP1610. Samotné jádro čipu, které se stará o generování zvuku, firma Yamaha používala prakticky dodnes i v současných integrovaných obvodech určených pro video hry či mobilní telefony (tedy ještě v době před smartphony). Jedná se především o čip YM-2203 (označovaný též zkratkou OPN), který původní AY-3–8910 rozšiřuje o frekvenční modulaci (FM).

Obrázek 1: Zvukový čip AY-3–8910 na základní desce počítače.

4. Tři varianty ayčka

Samotný zvukový čip AY-3–8910 byl vyráběn ve třech variantách označovaných AY-3–8910, AY-3–8912 a AY-3–8913. Jednotlivé varianty čipu se však nelišily způsobem generování zvuků (funkční bloky pro práci se zvukem totiž zůstávaly nezměněné), ale především počtem osmibitových vstupně/výstupních portů ovládaných přes řídicí registry (viz navazující odstavce).

AY-3–8910 se totiž používal kromě práce se zvuky a hudbou také pro ovládání dalších zařízení; mohl například pracovat jako jednoduchý programově řízený paralelní port, rozhraní pro připojení digitálních joysticků, přepínač mezi bankami operační paměti atd. Počítače či herní konzole, které pro ovládání dalších zařízení využívaly jiný obvod (například Intel 8255), tak obsahovaly buď nejmenší a samozřejmě i nejlevnější čtyřiadvacetipinovou variantu AY-3–8913, popř. osmadvacetipinovou variantu AY-3–8912.

Základní vlastnosti všech tří variant čipu AY jsou vypsány v následující tabulce:

Označení čipu Osmibitové porty Počet I/O pinů
AY-3–8910 2 40
AY-3–8912 1 28
AY-3–8913 žádný 24
Poznámka: poslední zmíněný čip měl jeden pin nezapojený, další přidaný pin byl určen pro výběr obvodu (chip select) a navíc obsahoval testovací piny TEST IN a TEST OUT.

V ZX Spectru 128 je použitá varianta AY-3–8912 s 28 piny. Jedná se o čip, který je na tomto snímku umístěn v pravém dolním rohu (i bez zvětšení na něm můžete vidět logo GI).

Obrázek 2: Schéma zapojení domácího osmibitového mikropočítače ZX Spectrum+ 128k, který obsahoval i zvukový čip AY-3–8910 (ten na schématu naleznete uprostřed jeho dolní části).

5. Příklady použití ayčka

V této kapitole se ve stručnosti seznámíme s těmi zařízeními, v nichž se ayčko používalo. Začneme osmibitovým domácím mikropočítačem ZX Spectrum, který pravděpodobně není zapotřebí čtenářům tohoto seriálu blíže představovat. V Evropě se jednalo o nejrozšířenější domácí osmibitový počítač se silnou programátorskou i uživatelskou podporou. Tento počítač, který byl po hardwarové stránce velmi jednoduchý (v porovnání s Atari až primitivní :-), bylo také velmi snadné „klonovat“. Z tohoto důvodu existuje několik desítek typů klonů vyráběných v různých zemích (u nás, resp. dnes spíše v SR, se jednalo například o typovou řadu Didaktik Gama a Didaktik M).

Obrázek 3: Zvukový čip AY-3–8910 ve čtyřicetipinovém pouzdře DIL (originál od firmy General Instrument)

Původní ZX Spectrum 48k sice bylo vybaveno pouze interním reproduktorem připojeným na jeden z pinů čipu ULA (bylo tedy možné vytvářet zvuk jen s využitím dvoustavového obdélníkového signálu, podobně jako později na PC-Speakeru – viz též předchozí článek), ale modernější verze ZX Spectra nazvaná ZX Spectrum 128K již obsahovala – kromě mnoha dalších vylepšení – i zvukový čip AY, což oproti původnímu řešení představovalo značný pokrok.

Zvukový čip AY-3–8912 byl použit i v herní konzoli Vectrex, která je zajímavá především tím, že pro zobrazování používá zabudovaný vektorový displej. Aby se alespoň z malé části nahradily některé nedostatky vektorové grafiky (například praktická nemožnost vyplňování ploch a také viditelné poblikávání zobrazovaných vektorů ve složitějších obrazech), byla ke každé hře dodávána poloprůhledná fólie, která se umístila před monitor. Na fólii byl většinou nakreslen okolní herní svět. Přímo v herní konzoli byla zabudována i obrazovka Samsung 240RB40, která měla velikost cca 8×11 palců a byla postavena poněkud netradičně „nastojato“. Za účelem dosažení co nejnižší ceny celé konzole byly použity černobílé výprodejové obrazovky. Ve druhé generaci se tvůrci pokoušeli použít i barevnou obrazovku, to však značným způsobem navyšovalo cenu celého systému, proto bylo od tohoto nápadu upuštěno.

Kromě mikroprocesoru, pamětí a D/A převodníku s multiplexerem byla konzole osazena i v článku popisovaným zvukovým čipem AY-3–8912 (tj. „prostřední“ variantou s jedním osmibitovým portem), který sloužil pro generování zvukového doprovodu, dále obvod PIA pro řízení vstupů i výstupů a nakonec digitálně-analogový převodník MC1408 (ten byl v zařízení přítomen pouze jeden, i když ve skutečnosti přes multiplexer ovládal celkem tři analogové výstupy).

Další počítač, který obsahoval zvukový čip AY-3–8910 (resp. jeho variantu YM2149 od firmy Yamaha), již byl představitelem nové generace 16/32bitových strojů. Jednalo se o počítače řady Atari ST. Řada ST začínala modelem Atari 260 ST (přesněji, existoval ještě model Atari 130 ST, ten se však prakticky neprodával), který však byl poměrně rychle nahrazen třemi typy počítačů, jež svými vlastnostmi pokrývaly značnou část tehdejšího trhu s osobními počítači: Atari 520 ST, Atari 1040 ST a Atari Mega ST.

AYčko bylo použito i v mnoha více či méně známých herních automatech, a to mnohdy ve dvojici pro vytváření stero zvuků a hudby:

1942 Popeye
Anteater Scramble
Bagman Super Cobra
Bomb Jack Roc'n Rope
BurgerTime Time Pilot
Dragon's Lair Tutankham
Elevator Action Discs of Tron
Frogger Kick
Gyruss Satan's Hollow
Kangaroo Spy Hunter
Karate Champ Tapper
Moon Patrol Timber
Omega Race Tron
Pooyan  

Obrázek 4: Počítač Amstrad CPC 464 taktéž obsahoval zvukový čip kompatibilní s AY-3–8910

6. Tónové generátory čipu AY-3–8910

Čip AY-3–8910 i všechny jeho varianty používá pro tvorbu zvuků a hudby tři samostatně nastavitelné tónové generátory, které produkují obdélníkové signály o zadané frekvenci (rozsah je 8 oktáv, každý kanál přitom obsahuje dvanáctibitový dělič), jež jsou dále zpracovávány. Každý tónový generátor vytváří zdroj zvukového signálu pro jeden ze zvukových kanálů – celkem jsou tedy k dispozici tři zvukové kanály, přičemž výstup každého z kanálů je vyveden na samostatný pin (jedná se o analogový výstup, na který lze například přímo zapojit zesilovač).

Obrázek 5: Blokové schéma zvukového čipu AY-3–8910.

To je pro PSG velmi netypické zapojení, protože u většiny ostatních zvukových čipů jsou zvuky z jednotlivých kanálů namixovány přímo na čipu do jednoho výstupu; na druhou stranu je však možné velmi jednoduše i s pomocí pouze jediného AY-3–8910 vytvářet stereo hudbu. Kromě tónových generátorů je možné použít i generátor šumu, jehož výstup lze přivést do zvoleného (či zvolených) zvukových kanálů. Generátor šumu se často používá například pro napodobení zvuku perkusních nástrojů, podobně jako tomu je u zvukových čipů POKEY či u SIDu.

Poznámka: maximální frekvence hodinového signálu čipu AY-3–8910 je rovna 2MHz, což je méně než hodinová frekvence samotného ZX Spectra (3.5469 MHz). Z tohoto důvodu musí ULA hodinovou frekvenci dělit dvěma a do AY-3–8910 je posílán hodinový signál s frekvencí poloviční, tedy 1.7734 MHz, který je interně dále dělen 16 na 110837 Hz. Tuto hodnotu použijeme při výpočtu výšky tónu.

7. Úprava signálu s využitím obálky

Obdélníkový signál vytvářený v tónových generátorech lze upravit pomocí obálky, která je však generována poněkud netypickým způsobem (například u SIDu je použita klasická obálka typu ADSR – attack, decay, sustain, release). Obálka má u ayčka tvar digitalizovaného periodického nebo neperiodického pilového či trojúhelníkového signálu. Taktéž je možné obálku ovládat programově, což vlastně znamená, že se pomocí zápisu do jednoho z řídicích registrů (viz další text) mění amplituda generovaného obdélníkového signálu.

Obrázek 5: Obálky vytvářené čipem AY-3–8910.

8. Nelineární D/A převodníky

Na výstupu čipu AY-3–8910 se nachází nelineární digitálně/analogový převodník, který slouží k převodu čtyřbitové hodnoty získané modifikací obdélníkového signálu obálkou na napěťovou úroveň v rozsahu do 1,35 Voltů (při zatížení analogového výstupu obvodem s odporem 1 kΩ). Díky použití nelineárního D/A převodníku se signál s původně lichoběžníkovým průběhem (výsledek změny amplitudy obdélníkového signálu pomocí obálky) mění na signál se „špičkami“, které dodávají hudbě vytvářené na čipu AY-3–8910 typické zabarvení.

Nelinearita D/A převodníku způsobuje problémy při přehrávání samplované hudby, neboť ta je většinou uložena ve formě osmibitových či šestnáctibitových vzorků s lineární závislostí mezi uloženou hodnotou a zaznamenanou úrovní. Z tohoto důvodu se při přehrávání samplované hudby na AY-3–8910 musejí používat převodní tabulky (existuje jich větší množství, liší se jak způsobem uložení, tak i konkrétními hodnotami pro převod; nesmíme také zapomínat na to, že zesilovače zapojené za AY-3–8910 nemusí mít lineární průběh a tudíž se převodní tabulky mohou mezi jednotlivými typy počítačů odlišovat).

9. AY-3–8910 z pohledu programátora

Podívejme se nyní na tento zvukový čip z pohledu programátora. Zvukový čip AY-3–8910 je ovládán pomocí čtrnácti až šestnácti osmibitových řídicích registrů, které jsou pojmenovány R0 až RF. Jejich stručný popis je uveden v tabulce pod tímto odstavcem:

Registr Stručný popis registru
R0 dolních osm bitů děliče frekvence hudebního kanálu A
R1 horní čtyři bity děliče frekvence hudebního kanálu A
R2 dolních osm bitů děliče frekvence hudebního kanálu B
R3 horní čtyři bity děliče frekvence hudebního kanálu B
R4 dolních osm bitů děliče frekvence hudebního kanálu C
R5 horní čtyři bity děliče frekvence hudebního kanálu C
R6 pět bitů děliče frekvence generátoru šumu
R7 nastavení zvukového mixéru i směru obou I/O portů (povolení/zákaz/směr)
R8 nastavení úrovně hlasitosti hudebního kanálu A
R9 nastavení úrovně hlasitosti hudebního kanálu B
RA nastavení úrovně hlasitosti hudebního kanálu C
RB dolních osm bitů děliče frekvence generátoru obálky
RC horních osm bitů děliče frekvence generátoru obálky
RD nastavení tvaru obálky (bitové pole)
RE data I/O portu A (vstup či výstup)
RF data I/O portu B (vstup či výstup)
Poznámka: to, zda budou poslední dva registry použité, záleží na konkrétním typu čipu, tj. zda obsahuje žádný, jeden či dva osmibitové porty. Například konkrétně u ZX Spectra nemá poslední registr žádný význam, neboť tento port není vyveden na piny čipu.

Řídicí registry je možné podle jejich funkce rozdělit do několika skupin:

  1. Prvních šest registrů R0R5 slouží pro nastavení frekvence obdélníkového signálu generovaného v každém hudebním kanálu (pro jeden hudební kanál jsou použity vždy dva sousední registry, do nichž se ukládá hodnota pro frekvenční dělič).
  2. Následuje registr R6, kterým se nastavuje frekvence šumu, registr R7 pro řízení mixéru a vstupně-výstupních portů.
  3. Trojice registrů R8, R9 a RA se používá pro nastavení hlasitosti jednotlivých hudebních kanálů.
  4. Další dvojice registrů RB a RC slouží pro nastavení frekvence obálky a registr RD určuje tvar obálky.
  5. A konečně dvojice registrů RE a RF je použita při práci se vstupně-výstupními porty. Těmito dvěma registry se nebudeme dále zabývat, neboť nemají vliv na vytvářený zvuk, ostatní registry budou naopak popsány podrobněji v navazujícím textu.

10. Nastavení frekvence výsledného tónu

Základ tónu je pro každý hudební kanál tvořen v generátoru obdélníkového signálu (square wave generator). Princip práce tohoto generátoru je velmi jednoduchý (ostatně právě proto ho můžeme nalézt jak v AY-3–8910, tak i v čipu POKEY). Frekvence pravidelného hodinového signálu přiváděného na vstup CLOCK, jenž se nachází na pinu číslo 22, je u YM2149 nejprve pomocí klopného obvodu typu T vydělena na polovinu. To, zda k vydělení skutečně dojde, závisí na stavu pinu SEL; naproti tomu u původního AY-3–8910 se toto vydělení frekvence na polovinu neprovádí nikdy (takže s ním u ZX Spectra nemusíme počítat). Výsledkem je signál nazvaný master clock, který je interně rozváděn do dalších modulů na čipu.

Poté je hodinový signál přiveden do binárních čítačů, které pracují jako frekvenční děliče (pravděpodobně jsou v AY-3–8910 skutečně použity děliče založené na binárních čítačích, které s každým hodinovým taktem sníží svoji hodnotu o jedničku, přičemž po dosažení nuly je jejich výstup invertován a do čítače se dosadí původní hodnota). Frekvence obdélníkového signálu je pro každý hudební kanál ovládána zvlášť pomocí dvojice osmibitových řídicích registrů (R0+R1 pro kanál A, R2+R3 pro kanál B a R4+R5 pro kanál C), v nichž je uloženo dvanáctibitové číslo představující hodnotu, kterou se dělí hodinový signál.

Z celkem šestnácti bitů je možné nastavit pouze bitů dvanáct, což je však pro požadovaný frekvenční rozsah osmi oktáv dostatečné. Frekvence každé obdélníkové vlny se vypočte pomocí vztahu:

fsquare=fmaster/16TP

kde TP je hodnota uložená ve dvojici řídicích registrů a fmaster je frekvence hodinového signálu.

11. Výpočet hodnot ukládaných do registrů R0 a R1 pro přehrání komorního A

Podívejme se nyní na způsob výpočtu hodnot, které se mají uložit do registrů R0 a R1 tak, aby se přehrálo komorní A. To je nota s frekvencí 440 Hz, frekvence hodin procesoru je u ZX Spectra 128 nastavena na 3,5469 MHz (a nikoli přesně na 3,5 MHz tak, jako u původního ZX Spectra 48k. Výpočet není nijak složitý:

  1. Hodinová frekvence: 3546900 Hz
  2. Frekvence vstupního CLK po vydělení dvěma v ULA: fmaster = 1773400 Hz
  3. Frekvence po vydělení 16: fmaster/16 = 1773400 / 16 = 110837 Hz
  4. Nota, která se má zahrát: 440 Hz
  5. Potřebná konstanta pro dělič: 110837 / 440 = 251
  6. Hodnota vyšších 4 bitů ukládaná do registru R1: int(251/256) = 0
  7. Hodnota nižších 8 bitů ukládaná do registru R0: 251 mod 256 = 251

12. Generátor šumu

Dalším primárním zdrojem signálu pro tvorbu zvuku je generátor šumu (noise generator). Výstup z tohoto generátoru (opět se jedná o binární signál, v tomto případě o náhodné pulsy) může být přiveden do libovolného hudebního kanálu, v případě potřeby i do všech kanálů. Ovšem šumový generátor je pouze jeden a i jeho frekvence je pro všechny tři hudební kanály vždy stejná. Pro nastavení frekvence šumového generátoru je určeno pět bitů řídicího registru R6 (možnosti nastavení frekvence jsou tedy mnohem menší, než u tónových generátorů).

Frekvence je vypočtena podle vztahu prakticky totožného se vztahem uvedeným v předchozím textu:

fnoise=fmaster/16NP

kde NP je hodnota uložená v řídicím registru R6. Vzhledem k menší maximální hodnotě, kterou lze uložit do pěti bitů (25-1=31 vs. 212-1=4095) je i frekvence vytvářeného šumu většinou mnohem vyšší než frekvence obdélníkového signálu (v případě šumu však není zcela přesné hovořit o frekvenci, spíše se jedná o maximální mez frekvence).

Poznámka: podrobnosti si ukážeme příště.

13. Mixer a ovládání hlasitosti jednotlivých kanálů

Důležitou součástí zvukového čipu AY-3–8910 je takzvaný mixér. V něm se pro každý hudební kanál zvlášť nastavuje zdroj signálu, který má být dále zpracováván. Pro každý hudební kanál lze povolit vstup obdélníkového signálu o zvolené frekvenci a vstup z generátoru šumu. V případě, že jsou pro jeden hudební kanál povoleny oba zdroje zvuku, jsou korektně smíchány (tato operace je implementačně velmi jednoduchá, neboť obdélníkový i šumový signál je binární, tudíž lze mixér realizovat pomocí logických hradel). Nastavení mixéru se provádí pomocí řídicího registru R7. Pro každý kanál jsou v tomto registru vyhrazeny dva bity – zápis nuly do příslušného bitu povoluje vstup obdélníkového signálu či šumu. Pokud jsou oba bity nastaveny na logickou jedničku, je výstup pro zvolený zvukový kanál zakázán:

Bit Povolení/zákaz/směr
0 tón kanálu A
1 tón kanálu B
2 tón kanálu C
3 šum do kanálu A
4 šum do kanálu B
5 šum do kanálu C
6 I/O port 1 (směr: vstup či výstup)
7 I/O port 2 (směr: vstup či výstup), na ZX Spectrum nepoužito

Nejvyšší dva bity řídicího registru R7 slouží k určení směru vstupně-výstupních portů. Každý port může být nastaven buď do výstupního režimu (zápis dat) nebo do režimu vstupního (čtení dat).

Hlasitost hudebních kanálů lze nastavit buď programově na jednu ze šestnácti úrovní, nebo je možné hlasitost měnit pomocí generátoru obálky popsaného v následujících odstavcích. Pro řízení hlasitosti každého hudebního kanálu je určený jeden řídicí registr – R8RA. Amplituda je nastavena čtyřmi bity (rychlou programovou změnou amplitudy je možné přehrávat samplované zvuky), pátým bitem řídicího registru je určeno, zda má být amplituda skutečně řízena programově nebo zda se má použít generátor obálky. Nejvyšší tři bity těchto tří řídicí registrů tedy zůstávají nevyužity.

14. Tvarování výsledného zvuku s využitím obálky (envelope)

Dalším funkčním blokem, který se podílí na tvarování výsledného zvuku, je takzvaný generátor obálky (envelope generator). Obálkou je možné (s využitím amplitudové modulace) ovlivnit maximální hodnoty původního obdélníkového a/nebo šumového signálu. Zatímco například u hudebního čipu SID byly použity obálky typu ADSR (attack, decay, sustain, release), má u AY-3–8910 obálka tvar periodického či neperiodického trojúhelníkového nebo pilového signálu. Ve skutečnosti se však nejedná o analogový signál, ale o signál digitální se šestnácti úrovněmi, tj. na osciloskopu by místo čistých průběhů bylo na každé náběžné nebo sestupné patrných šestnáct „schodů“ (více či méně zkreslených analogovou částí obvodů).

Pro nastavení frekvence změny obálky (přesněji doby čítání stavů 0–15) slouží dvojice řídicích registrů RB a RC, do nichž lze zadat šestnáctibitovou konstantu, která je použita v následujícím vztahu:

fEP=fmaster/256EP

kde EP je šestnáctibitová hodnota uložená do výše zmíněné dvojice řídicích registrů RB a RC. Vzhledem ke konstantě, která se v tomto vztahu vyskytuje, má signál představovaný obálkou výrazně delší periodu, než signál obdélníkový. To odpovídá významu obálky, protože v každém cyklu obálky (tEP=1/fEP) se vygeneruje trojúhelníková část vlny mající šestnáct kroků – vždy se projde všemi šestnácti úrovněmi.

Tvar obálky je určen nejnižšími čtyřmi bity řídicího registru RD, pomocí nichž je možné vybrat jeden z osmi tvarů obálky (ze šestnácti možných kombinací je tedy pouze osm kombinací unikátních). Tyto čtyři bity jsou pojmenovány CONT, ATT, ALT a HOLD. Bitem CONT (continue) se určuje, zda se bude obálka periodicky opakovat, bit ATT (attenuation) vybírá tvar náběžné části vlny (vzestupná či sestupná), nastavením bitu ALT (alternation) lze vynutit zrcadlové či naopak periodické opakování náběžné části vlny (tj. buď se vytváří pilový nebo trojúhelníkový signál) a konečně bitem HOLD lze zajistit „podržení“ výstupu po první periodě na konstantní hodnotě:

 0      \__________     pouze sestupná fáze, která se neopakuje
 
 4      /|_________     vzestupná fáze, následovaná skokem na 0, která se neopakuje
 
 8      \|\|\|\|\|\     opakující se sestupná fáze
 
 9      \__________     single decay then off
 
10      \/\/\/\/\/\     pilovitý signál
          _________
11      \|              sestupná fáze následovaná skokem na 1, která se neopakuje
 
12      /|/|/|/|/|/     opakující se vzestupná fáze
         __________
13      /               klasický attack & hold
 
14      /\/\/\/\/\/     pilovitý signál fázově posunutý od 10
 
15      /|_________     dtto jako 4

Generátor obálky se používá mnoha způsoby, například při samplingu (zde lze využít automatické vytváření vzestupných a sestupných hran), syntéze řeči atd. Je také možné vytvářet tón pouze pomocí periodicky se opakující obálky a napodobovat tak generátor pilového nebo trojúhelníkového signálu.

Poznámka: s podrobnostmi se seznámíme příště.

15. Programové ovládání čipu AY na ZX Spectru z assembleru

V praktické části dnešního článku si ukážeme, jakým způsobem je možné ovládat čip AY z assembleru. Je to ve skutečnosti velmi snadné, protože tvorba hudby spočívá v nastavování řídicích registrů ayčka (a to mnohdy v pevně daných intervalech, typicky 50× za sekundu). Víme již, že nejdříve je nutné řídicí registr vybrat a potom na něj zapsat osmibitovou hodnotu. To v praxi znamená, že je nutné provést dvě operace OUT. První OUT vybere řídicí registr ayčka zápisem hodnoty 0 až 14 na adresu 0×fffd, nová hodnota registru se potom zapisuje na adresu 0×bffd.

Poznámka: povšimněte si, že i když je adresa portů jen osmibitová, používáme zde šestnáctibitové adresy. Je tomu tak proto, že při zápisu na port instrukcí OUT ©, A se horní bajt uložený v pracovním registru B přenese na adresovou sběrnici.

V demonstračních příkladech budeme čipem AY přehrávat komorní A. Je to nota o frekvenci 440 Hz, přičemž způsob výpočtu dělicí konstanty pro tuto frekvenci byl uveden již v jedenácté kapitole. Jaké operace se tedy mají provést pro přehrání komorního A?:

  1. Nastavíme dělicí konstantu pro kanál A zápisem hodnoty 0 do registru R1 a 251 do registru R0.
  2. Nastavíme hlasitost kanálu A na maximální hodnotu zápisem hodnoty 15 do registru R8
  3. Povolíme výstup z kanálu A vynulováním bitu číslo 0 v registru R7 (bity v tomto registru používají inverzní logiku, takže povolení kanálu či portu atd. se provádí zápisem logické nuly a nikoli jedničky)
  4. Teoreticky by se ještě měla nastavit obálka atd., to ovšem není nutné, protože zápis 15 do registru R8 současně znamená, že se generátor obálky pro kanál A nepoužije (bit číslo 5 je vynulován)
Poznámka: jméno kanálu A pochopitelně nemá nic společného s přehrávanou notou :-)

Samotný výběr řídicího registru ayčka se zápisem kýžené hodnoty se provede, jak již víme, dvojicí instrukcí OUT, a to následovně:

AY_SELECT_REGISTER equ $fffd
AY_DATA_REGISTER   equ $bffd
 
        ld      a,   index_řídicího_registru
        ld      bc,  AY_SELECT_REGISTER
        out     (c), a
        ld      a,   hodnota_zapisovaná_do_řídicího_registru
        ld      bc,  AY_DATA_REGISTER
        out     (c), a                 ; zápis hodnoty do AY
Poznámka: instrukce OUT existuje v několika variantách, ovšem prakticky použitelná je pouze varianta založená na použití registrového páru BC, protože jen tehdy se nastaví i vyšších osm bitů adresové sběrnice.

16. Přehrání komorního A prakticky

Naivní (ale na druhou stranu velmi rychlý) způsob zápisu čtyř výše popsaných konstant do čtyř řídicích registrů ayčka může v assembleru vypadat následovně:

ENTRY_POINT        equ $8000
AY_SELECT_REGISTER equ $fffd
AY_DATA_REGISTER   equ $bffd
 
 
 
org ENTRY_POINT
 
start:
        ld      a, 0                   ; výška tónu (spodní bajt)
        ld      bc, AY_SELECT_REGISTER
        out     (c), a
        ld      a, 251
        ld      bc, AY_DATA_REGISTER
        out     (c), a                 ; zápis hodnoty do AY
 
        ld      a, 1                   ; výška tónu (horní bajt)
        ld      bc, AY_SELECT_REGISTER
        out     (c), a
        ld      a, 0
        ld      bc, AY_DATA_REGISTER
        out     (c), a                 ; zápis hodnoty do AY
 
        ld      a, 8                   ; hlasitost kanálu A
        ld      bc, AY_SELECT_REGISTER
        out     (c), a
        ld      a, 15                  ; maximální hlasitost
        ld      bc, AY_DATA_REGISTER
        out     (c), a                 ; zápis hodnoty do AY
 
        ld      a, 7                   ; povolení výstupu z kanálu A
        ld      bc, AY_SELECT_REGISTER
        out     (c), a
        ld      a, %11111110           ; bitová maska
        ld      bc, AY_DATA_REGISTER
        out     (c), a                 ; zápis hodnoty do AY
 
loop:
        jr loop                        ; nechceme návrat do BASICu
 
 
end ENTRY_POINT

Výsledný kód má v tomto případě délku přesně 64 bajtů:

ENTRY_POINT     EQU 8000
AY_SELECT_REGISTER EQU FFFD
AY_DATA_REGISTER EQU BFFD
                ORG 8000
8000:           label start
8000:3E00       LD A, 00
8002:01FDFF     LD BC, FFFD
8005:ED79       OUT (C), A
8007:3EFB       LD A, FB
8009:01FDBF     LD BC, BFFD
800C:ED79       OUT (C), A
800E:3E01       LD A, 01
8010:01FDFF     LD BC, FFFD
8013:ED79       OUT (C), A
8015:3E00       LD A, 00
8017:01FDBF     LD BC, BFFD
801A:ED79       OUT (C), A
801C:3E08       LD A, 08
801E:01FDFF     LD BC, FFFD
8021:ED79       OUT (C), A
8023:3E0F       LD A, 0F
8025:01FDBF     LD BC, BFFD
8028:ED79       OUT (C), A
802A:3E07       LD A, 07
802C:01FDFF     LD BC, FFFD
802F:ED79       OUT (C), A
8031:3EFE       LD A, FE
8033:01FDBF     LD BC, BFFD
8036:ED79       OUT (C), A
8038:           label loop
8038:18FE       JR 8038
803A:           END 8000
Emiting TAP basic loader
Emiting TAP from 8000 to 8039

17. Úprava programu – nastavení zvoleného řídicího registru čipu AY v podprogramu

Předchozí program lze upravit a zkrátit takovým způsobem, že se výběr a nastavení řídicího registru čipu AY provádí v podprogramu (subrutině). Číslo registru se předává v registru D, zapisovaná hodnota v registru E, přičemž subrutina interně využívá (a ničí obsah) registrový pár BC:

ay_write:
        ld      bc, AY_SELECT_REGISTER ; zápis do výběrového registru AY
        out     (c), d                 ; index vybraného registru
        ld      bc, AY_DATA_REGISTER   ; zápis do datového registru AY
        out     (c), e                 ; zapisovaná hodnota
        ret                            ; návrat ze subrutiny

Upravený zdrojový kód programu bez dalších optimalizací vypadá takto:

bitcoin školení listopad 24

ENTRY_POINT        equ $8000
AY_SELECT_REGISTER equ $fffd
AY_DATA_REGISTER   equ $bffd
 
 
 
org ENTRY_POINT
 
start:
        ld      d, 0                   ; výška tónu (spodní bajt)
        ld      e, 251
        call    ay_write               ; zápis hodnoty do AY
 
        ld      d, 1                   ; výška tónu (horní bajt)
        ld      e, 0
        call    ay_write               ; zápis hodnoty do AY
 
        ld      d, 8                   ; hlasitost kanálu A
        ld      e, 15                  ; maximální hlasitost
        call    ay_write               ; zápis hodnoty do AY
 
        ld      d, 7                   ; povolení výstupu z kanálu A
        ld      e, %11111110           ; bitová maska
        call    ay_write               ; zápis hodnoty do AY
 
loop:
        jr      loop                   ; nechceme návrat do BASICu
 
 
ay_write:
        ld      bc, AY_SELECT_REGISTER ; zápis do výběrového registru AY
        out     (c), d                 ; index vybraného registru
        ld      bc, AY_DATA_REGISTER   ; zápis do datového registru AY
        out     (c), e                 ; zapisovaná hodnota
        ret                            ; návrat ze subrutiny
 
 
end ENTRY_POINT
ENTRY_POINT     EQU 8000
AY_SELECT_REGISTER EQU FFFD
AY_DATA_REGISTER EQU BFFD
                ORG 8000
8000:           label start
8000:1600       LD D, 00
8002:1EFB       LD E, FB
8004:CD1E80     CALL 801E
8007:1601       LD D, 01
8009:1E00       LD E, 00
800B:CD1E80     CALL 801E
800E:1608       LD D, 08
8010:1E0F       LD E, 0F
8012:CD1E80     CALL 801E
8015:1607       LD D, 07
8017:1EFE       LD E, FE
8019:CD1E80     CALL 801E
801C:           label loop
801C:18FE       JR 801C
801E:           label ay_write
801E:01FDFF     LD BC, FFFD
8021:ED51       OUT (C), D
8023:01FDBF     LD BC, BFFD
8026:ED59       OUT (C), E
8028:C9         RET
8029:           END 8000
Emiting TAP basic loader
Emiting TAP from 8000 to 8028
Poznámka: tento program lze ještě zkrátit, a to konkrétně úpravou subrutiny ay_write. Jak to lze provést?

18. Příloha: upravený soubor Makefile pro překlad demonstračních příkladů

Výše uvedené demonstrační příklady i příklady, které již byly popsány v předchozích patnácti článcích [1] [2], [3], [4], [5], [6], [7], [8], [9], [10], [11], [12], [13], [14], [15], je možné přeložit s využitím souboru Makefile, jehož aktuální verze vypadá následovně (pro překlad a slinkování je použit assembler Pasmo):

ASSEMBLER := pasmo
 
all: 01.tap 02.tap 03.tap 04.tap 05.tap 06.tap 07.tap 08.tap 09.tap 10.tap \
    11.tap 12.tap 13.tap 14.tap 15.tap 16.tap 17.tap 18.tap 19.tap 20.tap \
    21.tap 22.tap 23.tap 24.tap 25.tap 26.tap 27.tap 28.tap 29.tap 30.tap \
    31.tap 32.tap 33.tap 34.tap 35.tap 36.tap 37.tap 38.tap 39.tap 40.tap \
    41.tap 42.tap 43.tap 44.tap 45.tap 46.tap 47.tap 48.tap 49.tap 50.tap \
    51.tap 52.tap 53.tap 54.tap 55.tap 56.tap 57.tap 58.tap 59.tap 60.tap \
    61.tap 62.tap 63.tap 64.tap 65.tap 66.tap 67.tap 68.tap 69.tap 70.tap \
    71.tap 72.tap 73.tap 74.tap 75.tap 76.tap 77.tap 78.tap 79.tap 80.tap \
    81.tap 82.tap 83.tap 84.tap 85.tap 86.tap 87.tap 88.tap 80.tap 90.tap \
    91.tap 92.tap 93.tap 94.tap 95.tap 96.tap 97.tap 98.tap 99.tap 100.tap \
    101.tap 102.tap 103.tap 104.tap 105.tap 106.tap 107.tap 108.tap 109.tap \
    110.tap
 
clean:
        rm -f *.tap
 
.PHONY: all clean
 
 
01.tap: 01-color-attribute.asm
        $(ASSEMBLER) -v -d --tap $< $@ > 01-color-attribute.lst
 
02.tap: 02-blinking-attribute.asm
        $(ASSEMBLER) -v -d --tap $< $@ > 02-blinking-attribute.lst
 
03.tap: 03-symbolic-names.asm
        $(ASSEMBLER) -v -d --tap $< $@ > 03-symbolic-names.lst
 
04.tap: 04-operators.asm
        $(ASSEMBLER) -v -d --tap $< $@ > 04-operators.lst
 
05.tap: 05-better-symbols.asm
        $(ASSEMBLER) -v -d --tap $< $@ > 05-better-symbols.lst
 
06.tap: 06-tapbas-v1.asm
        $(ASSEMBLER) -v -d --tapbas $< $@ > 06-tapbas-v1.lst
 
07.tap: 07-tapbas-v2.asm
        $(ASSEMBLER) -v -d --tapbas $< $@ > 07-tapbas-v2.lst
 
08.tap: 08-loop.asm
        $(ASSEMBLER) -v -d --tapbas $< $@ > 08-loop.lst
 
09.tap: 09-loop.asm
        $(ASSEMBLER) -v -d --tapbas $< $@ > 09-loop.lst
 
10.tap: 10-loop.asm
        $(ASSEMBLER) -v -d --tapbas $< $@ > 10-loop.lst
 
11.tap: 11-loop.asm
        $(ASSEMBLER) -v -d --tapbas $< $@ > 11-loop.lst
 
12.tap: 12-loop.asm
        $(ASSEMBLER) -v -d --tapbas $< $@ > 12-loop.lst
 
13.tap: 13-loop.asm
        $(ASSEMBLER) -v -d --tapbas $< $@ > 13-loop.lst
 
14.tap: 14-loop.asm
        $(ASSEMBLER) -v -d --tapbas $< $@ > 14-loop.lst
 
15.tap: 15-loop.asm
        $(ASSEMBLER) -v -d --tapbas $< $@ > 15-loop.lst
 
16.tap: 16-loop.asm
        $(ASSEMBLER) -v -d --tapbas $< $@ > 16-loop.lst
 
17.tap: 17-loop.asm
        $(ASSEMBLER) -v -d --tapbas $< $@ > 17-loop.lst
 
18.tap: 18-cls.asm
        $(ASSEMBLER) -v -d --tapbas $< $@ > 18-cls.lst
 
19.tap: 19-print-char-call.asm
        $(ASSEMBLER) -v -d --tapbas $< $@ > 19-print-char-call.lst
 
20.tap: 20-print-char-rst.asm
        $(ASSEMBLER) -v -d --tapbas $< $@ > 20-print-char-rst.lst
 
21.tap: 21-print-char.asm
        $(ASSEMBLER) -v -d --tapbas $< $@ > 21-print-char.lst
 
22.tap: 22-print-all-chars.asm
        $(ASSEMBLER) -v -d --tapbas $< $@ > 22-print-all-chars.lst
 
23.tap: 23-print-all-chars.asm
        $(ASSEMBLER) -v -d --tapbas $< $@ > 23-print-all-chars.lst
 
24.tap: 24-change-color.asm
        $(ASSEMBLER) -v -d --tapbas $< $@ > 24-change-color.lst
 
25.tap: 25-change-flash.asm
        $(ASSEMBLER) -v -d --tapbas $< $@ > 25-change-flash.lst
 
26.tap: 26-print-at.asm
        $(ASSEMBLER) -v -d --tapbas $< $@ > 26-print-at.lst
 
27.tap: 27-print-string.asm
        $(ASSEMBLER) -v -d --tapbas $< $@ > 27-print-string.lst
 
28.tap: 28-print-string.asm
        $(ASSEMBLER) -v -d --tapbas $< $@ > 28-print-string.lst
 
29.tap: 29-print-colorized-string.asm
        $(ASSEMBLER) -v -d --tapbas $< $@ > 29-print-colorized-string.lst
 
30.tap: 30-print-string-ROM.asm
        $(ASSEMBLER) -v -d --tapbas $< $@ > 30-print-string-ROM.lst
 
31.tap: 31-attributes.asm
        $(ASSEMBLER) -v -d --tapbas $< $@ > 31-attributes.lst
 
32.tap: 32-fill-in-vram.asm
        $(ASSEMBLER) -v -d --tapbas $< $@ > 32-fill-in-vram.lst
 
33.tap: 33-fill-in-vram-no-ret.asm
        $(ASSEMBLER) -v -d --tapbas $< $@ > 33-fill-in-vram-no-ret.lst
 
34.tap: 34-fill-in-vram-pattern.asm
        $(ASSEMBLER) -v -d --tapbas $< $@ > 34-fill-in-vram-pattern.lst
 
35.tap: 35-slow-fill-in-vram.asm
        $(ASSEMBLER) -v -d --tapbas $< $@ > 35-slow-fill-in-vram.lst
 
36.tap: 36-slow-fill-in-vram-no-ret.asm
        $(ASSEMBLER) -v -d --tapbas $< $@ > 36-slow-fill-in-vram-no-ret.lst
 
37.tap: 37-fill-block.asm
        $(ASSEMBLER) -v -d --tapbas $< $@ > 37-fill-block.lst
 
38.tap: 38-fill-block-with-pattern.asm
        $(ASSEMBLER) -v -d --tapbas $< $@ > 38-fill-block-with-pattern.lst
 
39.tap: 39-fill-block-optimized.asm
        $(ASSEMBLER) -v -d --tapbas $< $@ > 39-fill-block-optimized.lst
 
40.tap: 40-draw-char.asm
        $(ASSEMBLER) -v -d --tapbas $< $@ > 40-draw-char.lst
 
41.tap: 41-draw-any-char.asm
        $(ASSEMBLER) -v -d --tapbas $< $@ > 41-draw-any-char.lst
 
42.tap: 42-block-anywhere.asm
        $(ASSEMBLER) -v -d --tapbas $< $@ > 42-block-anywhere.lst
 
43.tap: 43-block-anywhere-rrca.asm
        $(ASSEMBLER) -v -d --tapbas $< $@ > 43-block-anywhere-rrca.lst
 
44.tap: 44-better-draw-char.asm
        $(ASSEMBLER) -v -d --tapbas $< $@ > 44-better-draw-char.lst
 
45.tap: 45-even-better-draw-char.asm
        $(ASSEMBLER) -v -d --tapbas $< $@ > 45-even-better-draw-char.lst
 
46.tap: 46-draw-char-at.asm
        $(ASSEMBLER) -v -d --tapbas $< $@ > 46-draw-char-at.lst
 
47.tap: 47-draw-char-at-unrolled.asm
        $(ASSEMBLER) -v -d --tapbas $< $@ > 47-draw-char-at-unrolled.lst
 
48.tap: 48-incorrect-print-string.asm
        $(ASSEMBLER) -v -d --tapbas $< $@ > 48-incorrect-print-string.lst
 
49.tap: 49-correct-print-string.asm
        $(ASSEMBLER) -v -d --tapbas $< $@ > 49-correct-print-string.lst
 
50.tap: 50-ascii-table.asm
        $(ASSEMBLER) -v -d --tapbas $< $@ > 50-ascii-table.lst
 
51.tap: 51-plot-block.asm
        $(ASSEMBLER) -v -d --tapbas $< $@ > 51-plot-block.lst
 
52.tap: 52-plot-pixel.asm
        $(ASSEMBLER) -v -d --tapbas $< $@ > 52-plot-pixel.lst
 
53.tap: 53-plot-pixel.asm
        $(ASSEMBLER) -v -d --tapbas $< $@ > 53-plot-pixel.lst
 
54.tap: 54-plot-pixel-on-background.asm
        $(ASSEMBLER) -v -d --tapbas $< $@ > 54-plot-pixel-on-background.lst
 
55.tap: 55-plot-pixel-on-background.asm
        $(ASSEMBLER) -v -d --tapbas $< $@ > 55-plot-pixel-on-background.lst
 
56.tap: 56-inverse-ascii-table.asm
        $(ASSEMBLER) -v -d --tapbas $< $@ > 56-inverse-ascii-table.lst
 
57.tap: 57-plot-pixel-on-inverse-background.asm
        $(ASSEMBLER) -v -d --tapbas $< $@ > 57-plot-pixel-on-inverse-background.lst
 
58.tap: 58-plot-inverse-pixel-on-inverse-background.asm
        $(ASSEMBLER) -v -d --tapbas $< $@ > 58-plot-inverse-pixel-on-inverse-background.lst
 
59.tap: 59-configurable-ascii-table.asm
        $(ASSEMBLER) -v -d --tapbas $< $@ > 59-configurable-ascii-table.lst
 
60.tap: 60-plot-over.asm
        $(ASSEMBLER) -v -d --tapbas $< $@ > 60-plot-over.lst
 
61.tap: 61-print-number-A.asm
        $(ASSEMBLER) -v -d --tapbas $< $@ > 61-print-number-A.lst
 
62.tap: 62-print-number-B.asm
        $(ASSEMBLER) -v -d --tapbas $< $@ > 62-print-number-B.lst
 
63.tap: 63-print-number-C.asm
        $(ASSEMBLER) -v -d --tapbas $< $@ > 63-print-number-C.lst
 
64.tap: 64-print-number-D.asm
        $(ASSEMBLER) -v -d --tapbas $< $@ > 64-print-number-D.lst
 
65.tap: 65-more-numbers-A.asm
        $(ASSEMBLER) -v -d --tapbas $< $@ > 65-more-numbers-A.lst
 
66.tap: 66-more-numbers-B.asm
        $(ASSEMBLER) -v -d --tapbas $< $@ > 66-more-numbers-B.lst
 
67.tap: 67-print-flags-1.asm
        $(ASSEMBLER) -v -d --tapbas $< $@ > 67-print-flags-1.lst
 
68.tap: 68-print-flags-2.asm
        $(ASSEMBLER) -v -d --tapbas $< $@ > 68-print-flags-2.lst
 
69.tap: 69-print-flags-3.asm
        $(ASSEMBLER) -v -d --tapbas $< $@ > 69-print-flags-3.lst
 
70.tap: 70-print-flags-4.asm
        $(ASSEMBLER) -v -d --tapbas $< $@ > 70-print-flags-4.lst
 
71.tap: 71-print-flags-5.asm
        $(ASSEMBLER) -v -d --tapbas $< $@ > 71-print-flags-5.lst
 
72.tap: 72-print-flags-6.asm
        $(ASSEMBLER) -v -d --tapbas $< $@ > 72-print-flags-6.lst
 
73.tap: 73-print-flags-7.asm
        $(ASSEMBLER) -v -d --tapbas $< $@ > 73-print-flags-7.lst
 
74.tap: 74-print-hex-number.asm
        $(ASSEMBLER) -v -d --tapbas $< $@ > 74-print-hex-number.lst
 
75.tap: 75-print-hex-number.asm
        $(ASSEMBLER) -v -d --tapbas $< $@ > 75-print-hex-number.lst
 
76.tap: 76-print-hex-numbers.asm
        $(ASSEMBLER) -v -d --tapbas $< $@ > 76-print-hex-numbers.lst
 
77.tap: 77-add-hex-numbers.asm
        $(ASSEMBLER) -v -d --tapbas $< $@ > 77-add-hex-numbers.lst
 
78.tap: 78-add-bcd-numbers.asm
        $(ASSEMBLER) -v -d --tapbas $< $@ > 78-add-bcd-numbers.lst
 
79.tap: 79-print-hex-digit-jmp.asm
        $(ASSEMBLER) -v -d --tapbas $< $@ > 79-print-hex-digit-jmp.lst
 
80.tap: 80-print-hex-digit-overflow.asm
        $(ASSEMBLER) -v -d --tapbas $< $@ > 80-print-hex-digit-overflow.lst
 
81.tap: 81-print-hex-digit-daa.asm
        $(ASSEMBLER) -v -d --tapbas $< $@ > 81-print-hex-digit-daa.lst
 
82.tap: 82-print-hex-numbers-daa.asm
        $(ASSEMBLER) -v -d --tapbas $< $@ > 82-print-hex-numbers-daa.lst
 
83.tap: 83-print-fp-numbers.asm
        $(ASSEMBLER) -v -d --tapbas $< $@ > 83-print-fp-numbers.lst
 
84.tap: 84-print-ascii-table.asm
        $(ASSEMBLER) -v -d --tapbas $< $@ > 84-print-ascii-table.lst
 
85.tap: 85-copy-ascii-table.asm
        $(ASSEMBLER) -v -d --tapbas $< $@ > 85-copy-ascii-table.lst
 
86.tap: 86-copy-ascii-table-B.asm
        $(ASSEMBLER) -v -d --tapbas $< $@ > 86-copy-ascii-table-B.lst
 
87.tap: 87-copy-ascii-table-C.asm
        $(ASSEMBLER) -v -d --tapbas $< $@ > 87-copy-ascii-table-C.lst
 
88.tap: 88-copy-ascii-table-D.asm
        $(ASSEMBLER) -v -d --tapbas $< $@ > 88-copy-ascii-table-D.lst
 
89.tap: 89-copy-ascii-table-E.asm
        $(ASSEMBLER) -v -d --tapbas $< $@ > 89-copy-ascii-table-E.lst
 
90.tap: 90-copy-ascii-table-F.asm
        $(ASSEMBLER) -v -d --tapbas $< $@ > 90-copy-ascii-table-F.lst
 
91.tap: 91-copy-ascii-table-G.asm
        $(ASSEMBLER) -v -d --tapbas $< $@ > 91-copy-ascii-table-G.lst
 
92.tap: 92-copy-ascii-table-H.asm
        $(ASSEMBLER) -v -d --tapbas $< $@ > 92-copy-ascii-table-H.lst
 
93.tap: 93-copy-ascii-table-I.asm
        $(ASSEMBLER) -v -d --tapbas $< $@ > 93-copy-ascii-table-I.lst
 
94.tap: 94-color-attribute.asm
        $(ASSEMBLER) -v -d --tapbas $< $@ > 94-color-attribute.lst
 
95.tap: 95-keypress.asm
        $(ASSEMBLER) -v -d --tapbas $< $@ > 95-keypress.lst
 
96.tap: 96-keypress-row.asm
        $(ASSEMBLER) -v -d --tapbas $< $@ > 96-keypress-row.lst
 
97.tap: 97-keypress-all-rows.asm
        $(ASSEMBLER) -v -d --tapbas $< $@ > 97-keypress-all-rows.lst
 
98.tap: 98-game-character.asm
        $(ASSEMBLER) -v -d --tapbas $< $@ > 98-game-character.lst
 
99.tap: 99-game-character-2.asm
        $(ASSEMBLER) -v -d --tapbas $< $@ > 99-game-character-2.lst
 
100.tap:        100-cursor-joystick.asm
        $(ASSEMBLER) -v -d --tapbas $< $@ > 100-cursor-joystick.lst
 
101.tap:        101-sinclair-joystick.asm
        $(ASSEMBLER) -v -d --tapbas $< $@ > 101-sinclair-joystick.lst
 
102.tap:        102-kempston-joystick.asm
        $(ASSEMBLER) -v -d --tapbas $< $@ > 102-kempston-joystick.lst
 
103.tap:        103-beep.asm
        $(ASSEMBLER) -v -d --tapbas $< $@ > 103-beep.lst
 
104.tap:        104-music-scale.asm
        $(ASSEMBLER) -v -d --tapbas $< $@ > 104-music-scale.lst
 
105.tap:        105-direct-speaker.asm
        $(ASSEMBLER) -v -d --tapbas $< $@ > 105-direct-speaker.lst
 
106.tap:        106-direct-speaker-di.asm
        $(ASSEMBLER) -v -d --tapbas $< $@ > 106-direct-speaker-di.lst
 
107.tap:        107-direct-speaker-border.asm
        $(ASSEMBLER) -v -d --tapbas $< $@ > 107-direct-speaker-border.lst
 
108.tap:        108-direct-speaker-border-di.asm
        $(ASSEMBLER) -v -d --tapbas $< $@ > 108-direct-speaker-border-di.lst
 
109.tap:        109-ay-note-a.asm
        $(ASSEMBLER) -v -d --tapbas $< $@ > 109-ay-note-a.lst
 
110.tap:        110-ay-note-a.asm
        $(ASSEMBLER) -v -d --tapbas $< $@ > 110-ay-note-a.lst

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

V tabulce zobrazené pod tímto odstavcem jsou uvedeny odkazy na všechny prozatím popsané demonstrační příklady určené pro překlad a spuštění na osmibitovém domácím mikropočítači ZX Spectrum (libovolný model či jeho klon), které jsou psány v assembleru mikroprocesoru Zilog Z80. Pro překlad těchto demonstračních příkladů je možné použít například assembler Pasmo (viz též úvodní článek):

# Soubor Stručný popis Adresa
1 01-color-attribute.asm modifikace jednoho barvového atributu https://github.com/tisnik/8bit-fame/blob/master/Speccy-asm/01-color-attribute.asm
2 02-blinking-attribute.asm barvový atribut s nastavením bitů pro blikání a vyšší intenzitu https://github.com/tisnik/8bit-fame/blob/master/Speccy-asm/02-blinking-attribute.asm
3 03-symbolic-names.asm symbolická jména v assembleru https://github.com/tisnik/8bit-fame/blob/master/Speccy-asm/03-symbolic-names.asm
4 04-operators.asm operátory a operace se symbolickými hodnotami https://github.com/tisnik/8bit-fame/blob/master/Speccy-asm/04-operators.asm
5 05-better-symbols.asm tradičnější symbolická jména https://github.com/tisnik/8bit-fame/blob/master/Speccy-asm/05-better-symbols.asm
6 06-tapbas-v1.asm vygenerování BASICovského loaderu (neúplný příklad) https://github.com/tisnik/8bit-fame/blob/master/Speccy-asm/06-tapbas-v1.asm
7 07-tapbas-v2.asm vygenerování BASICovského loaderu (úplný příklad) https://github.com/tisnik/8bit-fame/blob/master/Speccy-asm/07-tapbas-v2.asm
8 08-loop.asm jednoduchá počítaná programová smyčka: naivní varianta https://github.com/tisnik/8bit-fame/blob/master/Speccy-asm/08-loop.asm
9 09-loop.asm programová smyčka: zkrácení kódu pro vynulování použitých pracovních registrů https://github.com/tisnik/8bit-fame/blob/master/Speccy-asm/09-loop.asm
10 10-loop.asm programová smyčka: optimalizace skoku na konci smyčky (instrukce DJNZ) https://github.com/tisnik/8bit-fame/blob/master/Speccy-asm/10-loop.asm
11 11-loop.asm programová smyčka: optimalizace využití pracovních registrů https://github.com/tisnik/8bit-fame/blob/master/Speccy-asm/11-loop.asm
12 12-loop.asm programová smyčka: použití pracovního registru IX https://github.com/tisnik/8bit-fame/blob/master/Speccy-asm/12-loop.asm
13 13-loop.asm programová smyčka: použití pracovního registru IY https://github.com/tisnik/8bit-fame/blob/master/Speccy-asm/13-loop.asm
14 14-loop.asm programová smyčka se šestnáctibitovým počitadlem, základní varianta https://github.com/tisnik/8bit-fame/blob/master/Speccy-asm/14-loop.asm
15 15-loop.asm programová smyčka se šestnáctibitovým počitadlem, vylepšená varianta https://github.com/tisnik/8bit-fame/blob/master/Speccy-asm/15-loop.asm
16 16-loop.asm použití relativního skoku a nikoli skoku absolutního https://github.com/tisnik/8bit-fame/blob/master/Speccy-asm/16-loop.asm
17 17-loop.asm programová smyčka: inc l namísto inc hl https://github.com/tisnik/8bit-fame/blob/master/Speccy-asm/17-loop.asm
       
18 18-cls.asm smazání obrazovky a otevření kanálu číslo 2 (screen) přes funkci v ROM https://github.com/tisnik/8bit-fame/blob/master/Speccy-asm/18-cls.asm
19 19-print-char-call.asm smazání obrazovky a výpis jednoho znaku na obrazovku přes funkci v ROM (použití instrukce CALL) https://github.com/tisnik/8bit-fame/blob/master/Speccy-asm/19-print-char-call.asm
20 20-print-char-rst.asm smazání obrazovky a výpis jednoho znaku na obrazovku přes funkci v ROM (použití instrukce RST) https://github.com/tisnik/8bit-fame/blob/master/Speccy-asm/20-print-char-rst.asm
21 21-print-char.asm pouze výpis jednoho znaku na obrazovku bez jejího smazání https://github.com/tisnik/8bit-fame/blob/master/Speccy-asm/21-print-char.asm
22 22-print-all-chars.asm výpis znakové sady znak po znaku (nekorektní verze příkladu) https://github.com/tisnik/8bit-fame/blob/master/Speccy-asm/22-print-all-chars.asm
23 23-print-all-chars.asm výpis znakové sady znak po znaku (korektní verze příkladu) https://github.com/tisnik/8bit-fame/blob/master/Speccy-asm/23-print-all-chars.asm
24 24-change-color.asm změna barvových atributů (popředí a pozadí) vypisovaných znaků https://github.com/tisnik/8bit-fame/blob/master/Speccy-asm/24-change-color.asm
25 25-change-flash.asm povolení či zákaz blikání vypisovaných znaků https://github.com/tisnik/8bit-fame/blob/master/Speccy-asm/25-change-flash.asm
26 26-print-at.asm výpis znaku či znaků na určené místo na obrazovce https://github.com/tisnik/8bit-fame/blob/master/Speccy-asm/26-print-at.asm
27 27-print-string.asm výpis celého řetězce explicitně zapsanou programovou smyčkou (základní varianta) https://github.com/tisnik/8bit-fame/blob/master/Speccy-asm/27-print-string.asm
28 28-print-string.asm výpis celého řetězce explicitně zapsanou programovou smyčkou (vylepšená varianta) https://github.com/tisnik/8bit-fame/blob/master/Speccy-asm/28-print-string.asm
29 29-print-colorized-string.asm výpis řetězce, který obsahuje i řídicí znaky pro změnu barvy atd. https://github.com/tisnik/8bit-fame/blob/master/Speccy-asm/29-print-colorized-string.asm
30 30-print-string-ROM.asm výpis řetězce s využitím služby/subrutiny uložené v ROM ZX Spectra https://github.com/tisnik/8bit-fame/blob/master/Speccy-asm/30-print-string-ROM.asm
       
31 31-attributes.asm modifikace atributů pro tisk řetězce subrutinou uloženou v ROM https://github.com/tisnik/8bit-fame/blob/master/Speccy-asm/31-attributes.asm
32 32-fill-in-vram.asm vyplnění celé bitmapy barvou popředí, návrat do systému https://github.com/tisnik/8bit-fame/blob/master/Speccy-asm/32-fill-in-vram.asm
33 33-fill-in-vram-no-ret.asm vyplnění celé bitmapy barvou popředí, bez návratu do systému https://github.com/tisnik/8bit-fame/blob/master/Speccy-asm/33-fill-in-vram-no-ret.asm
34 34-fill-in-vram-pattern.asm vyplnění celé bitmapy zvoleným vzorkem https://github.com/tisnik/8bit-fame/blob/master/Speccy-asm/34-fill-in-vram-pattern.asm
35 35-slow-fill-in-vram.asm pomalé vyplnění celé bitmapy, vizualizace struktury bitmapy https://github.com/tisnik/8bit-fame/blob/master/Speccy-asm/35-slow-fill-in-vram.asm
36 36-slow-fill-in-vram-no-ret.asm pomalé vyplnění celé bitmapy, vizualizace struktury bitmapy, bez návratu do systému https://github.com/tisnik/8bit-fame/blob/master/Speccy-asm/36-slow-fill-in-vram-no-ret.asm
37 37-fill-block.asm vykreslení bloku 8×8 pixelů https://github.com/tisnik/8bit-fame/blob/master/Speccy-asm/37-fill-block.asm
38 38-fill-block-with-pattern.asm vykreslení bloku 8×8 pixelů zvoleným vzorkem https://github.com/tisnik/8bit-fame/blob/master/Speccy-asm/38-fill-block-with-pattern.asm
39 39-fill-block-optimized.asm optimalizace předchozího příkladu https://github.com/tisnik/8bit-fame/blob/master/Speccy-asm/39-fill-block-optimized.asm
40 40-draw-char.asm vykreslení znaku do levého horního rohu https://github.com/tisnik/8bit-fame/blob/master/Speccy-asm/40-draw-char.asm
41 41-draw-any-char.asm podprogram pro vykreslení libovolně zvoleného znaku do levého horního rohu https://github.com/tisnik/8bit-fame/blob/master/Speccy-asm/41-draw-any-char.asm
42 42-block-anywhere.asm podprogramy pro vykreslení bloku 8×8 pixelů kamkoli na obrazovku https://github.com/tisnik/8bit-fame/blob/master/Speccy-asm/42-block-anywhere.asm
       
43 43-block-anywhere-rrca.asm podprogramy pro vykreslení bloku 8×8 pixelů kamkoli na obrazovku, vylepšená varianta https://github.com/tisnik/8bit-fame/blob/master/Speccy-asm/43-block-anywhere-rrca.asm
44 44-better-draw-char.asm vykreslení znaku v masce 8×8 pixelů, vylepšená varianta https://github.com/tisnik/8bit-fame/blob/master/Speccy-asm/44-better-draw-char.asm
45 45-even-better-draw-char.asm posun offsetu pro vykreslení dalšího znaku https://github.com/tisnik/8bit-fame/blob/master/Speccy-asm/45-even-better-draw-char.asm
46 46-draw-char-at.asm vykreslení znaku v masce 8×8 pixelů kamkoli na obrazovku https://github.com/tisnik/8bit-fame/blob/master/Speccy-asm/46-draw-char-at.asm
47 47-draw-char-at-unrolled.asm vykreslení znaku v masce 8×8 pixelů kamkoli na obrazovku https://github.com/tisnik/8bit-fame/blob/master/Speccy-asm/47-draw-char-at-unrolled.asm
48 48-incorrect-print-string.asm tisk řetězce, nekorektní varianta https://github.com/tisnik/8bit-fame/blob/master/Speccy-asm/48-incorrect-print-string.asm
49 49-correct-print-string.asm tisk řetězce, korektní varianta https://github.com/tisnik/8bit-fame/blob/master/Speccy-asm/49-correct-print-string.asm
       
50 50-ascii-table.asm tisk několika bloků ASCII tabulky https://github.com/tisnik/8bit-fame/blob/master/Speccy-asm/50-ascii-table.asm
51 51-plot-block.asm vykreslení pixelu verze 1: zápis celého bajtu na pozici pixelu https://github.com/tisnik/8bit-fame/blob/master/Speccy-asm/51-plot-block.asm
52 52-plot-pixel.asm vykreslení pixelu verze 2: korektní vykreslení jednoho pixelu, ovšem překreslení celého bajtu https://github.com/tisnik/8bit-fame/blob/master/Speccy-asm/52-plot-pixel.asm
53 53-plot-pixel.asm vykreslení pixelu verze 3: vylepšená verze předchozího demonstračního příkladu https://github.com/tisnik/8bit-fame/blob/master/Speccy-asm/53-plot-pixel.asm
54 54-plot-pixel-on-background.asm vykreslení pixelu vůči pozadí (nekorektní varianta) https://github.com/tisnik/8bit-fame/blob/master/Speccy-asm/54-plot-pixel-on-background.asm
55 55-plot-pixel-on-background.asm vykreslení pixelu vůči pozadí (korektní varianta) https://github.com/tisnik/8bit-fame/blob/master/Speccy-asm/55-plot-pixel-on-background.asm
       
56 56-inverse-ascii-table.asm vykreslení ASCII tabulky inverzní barvou (inkoust vs. papír) https://github.com/tisnik/8bit-fame/blob/master/Speccy-asm/56-inverse-ascii-table.asm
57 57-plot-pixel-on-inverse-background.asm vykreslení pixelů barvou papíru proti inverzní ASCII tabulce https://github.com/tisnik/8bit-fame/blob/master/Speccy-asm/57-plot-pixel-on-inverse-background.asm
58 58-plot-inverse-pixel-on-inverse-background.asm vykreslení pixelů inverzní barvou proti inverzní ASCII tabulce https://github.com/tisnik/8bit-fame/blob/master/Speccy-asm58-plot-inverse-pixel-on-inverse-background.asm/
59 59-configurable-ascii-table.asm vykreslení ASCII tabulky buď přímo inkoustem nebo inverzně https://github.com/tisnik/8bit-fame/blob/master/Speccy-asm/59-configurable-ascii-table.asm
60 60-plot-over.asm přibližná implementace příkazu PLOT OVER https://github.com/tisnik/8bit-fame/blob/master/Speccy-asm/60-plot-over.asm
       
61 61-print-number-A.asm ukázka použití podprogramu pro tisk celého čísla https://github.com/tisnik/8bit-fame/blob/master/Speccy-asm/61-print-number-A.asm
62 62-print-number-B.asm pokus o vytištění záporných čísel https://github.com/tisnik/8bit-fame/blob/master/Speccy-asm/62-print-number-B.asm
63 63-print-number-C.asm tisk maximální podporované hodnoty 9999 https://github.com/tisnik/8bit-fame/blob/master/Speccy-asm/63-print-number-C.asm
64 64-print-number-D.asm tisk vyšší než podporované hodnoty 10000 https://github.com/tisnik/8bit-fame/blob/master/Speccy-asm/64-print-number-D.asm
65 65-more-numbers-A.asm vytištění číselné řady https://github.com/tisnik/8bit-fame/blob/master/Speccy-asm/65-more-numbers-A.asm
66 66-more-numbers-B.asm kombinace tisku celočíselných hodnot s dalšími subrutinami https://github.com/tisnik/8bit-fame/blob/master/Speccy-asm/66-more-numbers-B.asm
67 67-print-flags-1.asm příznakové bity po provedení celočíselné operace 1+2 https://github.com/tisnik/8bit-fame/blob/master/Speccy-asm/67-print-flags-1.asm
68 68-print-flags-2.asm příznakové bity po provedení celočíselné operace 0+0 https://github.com/tisnik/8bit-fame/blob/master/Speccy-asm/68-print-flags-2.asm
69 69-print-flags-3.asm příznakové bity po provedení operace 255+1 https://github.com/tisnik/8bit-fame/blob/master/Speccy-asm/69-print-flags-3.asm
70 70-print-flags-4.asm příznakové bity po provedení operace 254+1 https://github.com/tisnik/8bit-fame/blob/master/Speccy-asm/70-print-flags-4.asm
71 71-print-flags-5.asm příznakové bity po provedení operace 255+255 https://github.com/tisnik/8bit-fame/blob/master/Speccy-asm/71-print-flags-5.asm
72 72-print-flags-6.asm výsledek operace 100+100, nastavení příznakových bitů https://github.com/tisnik/8bit-fame/blob/master/Speccy-asm/72-print-flags-6.asm
73 73-print-flags-7.asm výsledek operace 128+128, nastavení příznakových bitů https://github.com/tisnik/8bit-fame/blob/master/Speccy-asm/73-print-flags-7.asm
       
74 74-print-hex-number.asm tisk hexadecimálního čísla v rozsahu 0×00 až 0×ff (neoptimalizovaná varianta) https://github.com/tisnik/8bit-fame/blob/master/Speccy-asm/74-print-hex-number.asm
75 75-print-hex-number.asm tisk hexadecimálního čísla v rozsahu 0×00 až 0×ff (optimalizovaná varianta) https://github.com/tisnik/8bit-fame/blob/master/Speccy-asm/75-print-hex-number.asm
76 76-print-hex-numbers.asm tisk několika hexadecimálních hodnot https://github.com/tisnik/8bit-fame/blob/master/Speccy-asm/76-print-hex-numbers.asm
77 77-add-hex-numbers.asm součet dvou osmibitových hexadecimálních hodnot s tiskem všech výsledků https://github.com/tisnik/8bit-fame/blob/master/Speccy-asm/77-add-hex-numbers.asm
78 78-add-bcd-numbers.asm součet dvou osmibitových BCD hodnot s tiskem všech výsledků https://github.com/tisnik/8bit-fame/blob/master/Speccy-asm/78-add-bcd-numbers.asm
       
79 79-print-hex-digit-jmp.asm tisk jedné hexadecimální cifry s využitím podmíněného skoku https://github.com/tisnik/8bit-fame/blob/master/Speccy-asm/79-print-hex-digit-jmp.asm
80 80-print-hex-digit-overflow.asm otestování, jaký znak je vytištěn pro hodnoty větší než 15 https://github.com/tisnik/8bit-fame/blob/master/Speccy-asm/80-print-hex-digit-overflow.asm
81 81-print-hex-digit-daa.asm tisk jedné hexadecimální cifry s využitím instrukce DAA https://github.com/tisnik/8bit-fame/blob/master/Speccy-asm/81-print-hex-digit-daa.asm
82 82-print-hex-numbers-daa.asm tisk série hexadecimálních hodnot s využitím instrukce DAA https://github.com/tisnik/8bit-fame/blob/master/Speccy-asm/82-print-hex-numbers-daa.asm
83 83-print-fp-numbers.asm tisk numerických hodnot reprezentovaných v systému plovoucí řádové tečky https://github.com/tisnik/8bit-fame/blob/master/Speccy-asm/83-print-fp-numbers.asm
       
84 84-print-ascii-table.asm tisk jednoho bloku s ASCII tabulkou https://github.com/tisnik/8bit-fame/blob/master/Speccy-asm/84-print-ascii-table.asm
85 85-copy-ascii-table.asm kopie bloku bajt po bajtu založená na naivní programové smyčce https://github.com/tisnik/8bit-fame/blob/master/Speccy-asm/85-copy-ascii-table.asm
86 86-copy-ascii-table-B.asm kopie bloku s využitím instrukce LDIR https://github.com/tisnik/8bit-fame/blob/master/Speccy-asm/86-copy-ascii-table-B.asm
87 87-copy-ascii-table-C.asm kopie bloku bajt po bajtu založená na programové smyčce a instrukci LDI https://github.com/tisnik/8bit-fame/blob/master/Speccy-asm/87-copy-ascii-table-C.asm
88 88-copy-ascii-table-D.asm rozbalení programové smyčky s instrukcí LDI https://github.com/tisnik/8bit-fame/blob/master/Speccy-asm/88-copy-ascii-table-D.asm
89 89-copy-ascii-table-E.asm korektní smyčka pro všechny možné velikosti bloků https://github.com/tisnik/8bit-fame/blob/master/Speccy-asm/89-copy-ascii-table-E.asm
       
90 90-copy-ascii-table-F.asm kostra programu, který pro kopii bloků (16 bajtů) využívá zásobník https://github.com/tisnik/8bit-fame/blob/master/Speccy-asm/90-copy-ascii-table-F.asm
91 91-copy-ascii-table-G.asm definice makra a několikeré použití (aplikace) tohoto makra https://github.com/tisnik/8bit-fame/blob/master/Speccy-asm/91-copy-ascii-table-G.asm
92 92-copy-ascii-table-H.asm opakování makra založené na REPT https://github.com/tisnik/8bit-fame/blob/master/Speccy-asm/92-copy-ascii-table-H.asm
93 93-copy-ascii-table-I.asm vícenásobná kopie části obrazovky https://github.com/tisnik/8bit-fame/blob/master/Speccy-asm/93-copy-ascii-table-I.asm
       
94 94-color-attribute.asm modifikace jednoho barvového atributu na obrazovce ZX Spectra https://github.com/tisnik/8bit-fame/blob/master/Speccy-asm/94-color-attribute.asm
95 95-keypress.asm detekce stisku jedné klávesy s vizualizací stisku https://github.com/tisnik/8bit-fame/blob/master/Speccy-asm/95-keypress.asm
96 96-keypress-row.asm detekce stisku kláves v jednom fyzickém řádku https://github.com/tisnik/8bit-fame/blob/master/Speccy-asm/96-keypress-row.asm
97 97-keypress-all-rows.asm detekce stisku všech kláves klávesnice ZX Spectra 48k https://github.com/tisnik/8bit-fame/blob/master/Speccy-asm/97-keypress-all-rows.asm
       
98 98-game-character.asm zajištění pohybu hráče v herní scéně s využitím klávesnice https://github.com/tisnik/8bit-fame/blob/master/Speccy-asm/98-game-character.asm
99 99-game-character-2.asm vylepšení předchozího demonstračního příkladu https://github.com/tisnik/8bit-fame/blob/master/Speccy-asm/99-game-character-2.asm
100 100-cursor-joystick.asm zajištění pohybu hráče v herní scéně kurzorovým joystickem https://github.com/tisnik/8bit-fame/blob/master/Speccy-asm/100-cursor-joystick.asm
101 101-sinclair-joystick.asm zajištění pohybu hráče v herní scéně joystickem připojeným přes Interface 2 https://github.com/tisnik/8bit-fame/blob/master/Speccy-asm/101-sinclair-joystick.asm
102 102-kempston-joystick.asm zajištění pohybu hráče v herní scéně joystickem připojeným přes rozhraní Kempston https://github.com/tisnik/8bit-fame/blob/master/Speccy-asm/102-kempston-joystick.asm
       
103 103-beep.asm využití subrutiny v ROM s implementací příkazu BEEP https://github.com/tisnik/8bit-fame/blob/master/Speccy-asm/103-beep.asm
104 104-music-scale.asm přehrání celé stupnice https://github.com/tisnik/8bit-fame/blob/master/Speccy-asm/104-music-scale.asm
105 105-direct-speaker.asm přímé programové ovládání beeperu https://github.com/tisnik/8bit-fame/blob/master/Speccy-asm/105-direct-speaker.asm
106 106-direct-speaker-di.asm zakázání přerušení při přehrávání https://github.com/tisnik/8bit-fame/blob/master/Speccy-asm/106-direct-speaker-di.asm
107 107-direct-speaker-border.asm vizualizace frekvence přehrávání změnou okraje v reálném čase https://github.com/tisnik/8bit-fame/blob/master/Speccy-asm/107-direct-speaker-border.asm
108 108-direct-speaker-border-di.asm vizualizace frekvence přehrávání změnou okraje v reálném čase https://github.com/tisnik/8bit-fame/blob/master/Speccy-asm/108-direct-speaker-border-di.asm
       
109 109-ay-note-a.asm přehrání komorního A na čipu AY-3–8912 na ZX Spectru https://github.com/tisnik/8bit-fame/blob/master/Speccy-asm/109-ay-note-a.asm
110 110-ay-note-a.asm přehrání komorního A na čipu AY-3–8912 na ZX Spectru https://github.com/tisnik/8bit-fame/blob/master/Speccy-asm/110-ay-note-a.asm
       
111 Makefile Makefile pro překlad a slinkování všech demonstračních příkladů do podoby obrazu magnetické pásky https://github.com/tisnik/8bit-fame/blob/master/Speccy-asm/Makefile

20. Odkazy na Internetu

  1. z80 standalone assembler
    https://www.asm80.com/one­page/asmz80.html
  2. The ZX BASIC Compiler
    https://www.boriel.com/pages/the-zx-basic-compiler.html
  3. Z80 Assembly programming for the ZX Spectrum
    https://www.chibiakumas.com/z80/ZXSpec­trum.php
  4. 8-BIT SMACKDOWN! 65C02 vs. Z80: slithy VLOGS #6
    https://www.youtube.com/wat­ch?v=P1paVoFEvyc
  5. Instrukce mikroprocesoru Z80
    https://clrhome.org/table/
  6. Z80 instructions: adresní režimy atd.
    https://jnz.dk/z80/instructions.html
  7. Z80 Instruction Groups
    https://jnz.dk/z80/instgroups.html
  8. Elena, New programming language for the ZX Spectrum Next
    https://vintageisthenewold.com/elena-new-programming-language-for-the-zx-spectrum-next/
  9. Sinclair BASIC
    https://worldofspectrum.net/legacy-info/sinclair-basic/
  10. Grafika na osmibitových počítačích firmy Sinclair
    https://www.root.cz/clanky/grafika-na-osmibitovych-pocitacich-firmy-sinclair/
  11. Grafika na osmibitových počítačích firmy Sinclair II
    https://www.root.cz/clanky/grafika-na-osmibitovych-pocitacich-firmy-sinclair-ii/
  12. HiSoft BASIC
    https://worldofspectrum.net/in­foseekid.cgi?id=0008249
  13. YS MegaBasic
    https://worldofspectrum.net/in­foseekid.cgi?id=0008997
  14. Beta Basic
    https://worldofspectrum.net/in­foseekid.cgi?id=0007956
  15. BASIC+
    https://worldofspectrum.net/in­foseekid.php?id=0014277
  16. Spectrum ROM Memory Map
    https://skoolkit.ca/disas­semblies/rom/maps/all.html
  17. Goto subroutine
    https://skoolkit.ca/disas­semblies/rom/asm/7783.html
  18. Spectrum Next: The Evolution of the Speccy
    https://www.specnext.com/about/
  19. Sedmdesátiny assemblerů: lidsky čitelný strojový kód
    https://www.root.cz/clanky/sed­mdesatiny-assembleru-lidsky-citelny-strojovy-kod/
  20. Programovací jazyk BASIC na osmibitových mikropočítačích
    https://www.root.cz/clanky/pro­gramovaci-jazyk-basic-na-osmibitovych-mikropocitacich/
  21. Programovací jazyk BASIC na osmibitových mikropočítačích (2)
    https://www.root.cz/clanky/pro­gramovaci-jazyk-basic-na-osmibitovych-mikropocitacich-2/#k06
  22. Programovací jazyk BASIC na osmibitových mikropočítačích (3)
    https://www.root.cz/clanky/pro­gramovaci-jazyk-basic-na-osmibitovych-mikropocitacich-3/
  23. Sinclair BASIC (Wikipedia CZ)
    http://cs.wikipedia.org/wi­ki/Sinclair_BASIC
  24. Assembly Language: Still Relevant Today
    http://wilsonminesco.com/AssyDefense/
  25. Programovani v assembleru na OS Linux
    http://www.cs.vsb.cz/gryga­rek/asm/asmlinux.html
  26. Why Assembly Language Programming? (Why Learning Assembly Language Is Still a Good Idea)
    https://wdc65×x.com/market­s/education/why-assembly-language-programming/
  27. Low Fat Computing
    http://www.ultratechnology­.com/lowfat.htm
  28. Assembly Language
    https://www.cleverism.com/skills-and-tools/assembly-language/
  29. Why do we need assembly language?
    https://cs.stackexchange.com/qu­estions/13287/why-do-we-need-assembly-language
  30. Assembly language (Wikipedia)
    https://en.wikipedia.org/wi­ki/Assembly_language#Histo­rical_perspective
  31. Assembly languages
    https://curlie.org/Computer­s/Programming/Languages/As­sembly/
  32. vasm
    http://sun.hasenbraten.de/vasm/
  33. B-ELITE
    https://jsj.itch.io/b-elite
  34. ZX-Spectrum Child
    http://www.dotkam.com/2008/11/19/zx-spectrum-child/
  35. Speccy.cz
    http://www.speccy.cz/
  36. Planet Sinclair
    http://www.nvg.ntnu.no/sinclair/
  37. World of Spectrum
    http://www.worldofspectrum.org/
  38. The system variables
    https://worldofspectrum.or­g/ZXBasicManual/zxmanchap25­.html
  39. ZX Spectrum manual: chapter #17 Graphics
    https://worldofspectrum.or­g/ZXBasicManual/zxmanchap17­.html
  40. Why does Sinclair BASIC have two formats for storing numbers in the same structure?
    https://retrocomputing.stac­kexchange.com/questions/8834/why-does-sinclair-basic-have-two-formats-for-storing-numbers-in-the-same-structu
  41. Plovoucí řádová čárka na ZX Spectru
    https://www.root.cz/clanky/norma-ieee-754-a-pribuzni-formaty-plovouci-radove-tecky/#k05
  42. Norma IEEE 754 a příbuzní: formáty plovoucí řádové tečky
    https://www.root.cz/clanky/norma-ieee-754-a-pribuzni-formaty-plovouci-radove-tecky/#k05
  43. 1A1B: THE ‚REPORT AND LINE NUMBER PRINTING‘ SUBROUTINE
    https://skoolkid.github.i­o/rom/asm/1A1B.html
  44. 2DE3: THE ‚PRINT A FLOATING-POINT NUMBER‘ SUBROUTINE
    https://skoolkid.github.i­o/rom/asm/2DE3.html
  45. 5C63: STKBOT – Address of bottom of calculator stack
    https://skoolkid.github.i­o/rom/asm/5C63.html
  46. 5C65: STKEND – Address of start of spare space
    https://skoolkid.github.i­o/rom/asm/5C65.html
  47. Why does Sinclair BASIC have two formats for storing numbers in the same structure?
    https://retrocomputing.stac­kexchange.com/questions/8834/why-does-sinclair-basic-have-two-formats-for-storing-numbers-in-the-same-structu
  48. Chapter 24: The memory
    https://worldofspectrum.or­g/ZXBasicManual/zxmanchap24­.html
  49. Survey of Floating-Point Formats  
    https://mrob.com/pub/math/flo­atformats.html
  50. Convert an 8bit number to hex in z80 assembler
    https://stackoverflow.com/qu­estions/22838444/convert-an-8bit-number-to-hex-in-z80-assembler
  51. 80 MICROPROCESSOR Instruction Set Summary
    http://www.textfiles.com/pro­gramming/CARDS/z80
  52. Extended Binary Coded Decimal Interchange Code
    http://en.wikipedia.org/wiki/EBCDIC
  53. ASCII/EBCDIC Conversion Table
    http://docs.hp.com/en/32212–90008/apcs01.html
  54. EBCDIC
    http://www.hansenb.pdx.edu/DMKB/dic­t/tutorials/ebcdic.php
  55. EBCDIC tables
    http://home.mnet-online.de/wzwz.de/temp/eb­cdic/cc_en.htm
  56. The Mainframe Blog
    http://mainframe.typepad.com/blog/2006/11/my_per­sonal_mai.html
  57. Binary-coded decimal
    https://en.wikipedia.org/wiki/Binary-coded_decimal
  58. BCD
    https://cs.wikipedia.org/wiki/BCD
  59. Z80 heaven: Floating Point
    http://z80-heaven.wikidot.com/floating-point
  60. Z80, the 8-bit Number Cruncher
    http://www.andreadrian.de/ol­dcpu/Z80_number_cruncher.html
  61. Floating-point library for Z80
    https://github.com/DW0RKiN/Floating-point-Library-for-Z80
  62. z80float
    https://github.com/Zeda/z80float
  63. Fixed point arithmetic
    https://www.root.cz/clanky/fixed-point-arithmetic/
  64. ZX Spectrum BASIC Programming – 2nd Edition
    https://archive.org/details/zx-spectrum-basic-programming/page/n167/mode/2up
  65. ZX Spectrum BASIC Programming – 2nd Edition
    https://archive.org/details/zx-spectrum-basic-programming/page/n169/mode/2up
  66. How fast is memcpy on the Z80?
    https://retrocomputing.stac­kexchange.com/questions/4744/how-fast-is-memcpy-on-the-z80
  67. How do Z80 Block Transfer instructions work?
    https://retrocomputing.stac­kexchange.com/questions/5416/how-do-z80-block-transfer-instructions-work
  68. Retro Programming Made Simple: Keyboard
    http://www.breakintoprogram­.co.uk/hardware/computers/zx-spectrum/keyboard
  69. How ZX Spectrum avoided key ghosting
    https://retrocomputing.stac­kexchange.com/questions/16235/how-zx-spectrum-avoided-key-ghosting
  70. ZX Spectrum Keyboard Visualized
    http://www.kameli.net/marq/?p=2055
  71. Sinclair ZX Spectrum Joysticks Explained
    https://www.retroisle.com/ge­neral/spectrum_joysticks.php
  72. When A Single Bit Was Enough, Into The Sound Of The ZX Spectrum
    https://hackaday.com/2022/01/20/when-a-single-bit-was-enough-into-the-sound-of-the-zx-spectrum/
  73. 03B5: THE ‚BEEPER‘ SUBROUTINE
    https://skoolkid.github.i­o/rom/asm/03B5.html
  74. How To Write ZX Spectrum Games – Chapter 3
    https://chuntey.wordpress­.com/2013/02/28/how-to-write-zx-spectrum-games-chapter-3/
  75. Understanding computer sound
    https://www.youtube.com/pla­ylist?list=PL0qES-IQZC8w4vqeQhxHxKgxYYqs3CEOx
  76. Understanding Computer Sound. 5. ZX Spectrum
    https://www.youtube.com/wat­ch?v=N5ACJd2LvbY
  77. Dark Fusion (Gremlin Graphics, 1988)
    https://www.youtube.com/wat­ch?v=ADL3mdRMzoA
  78. Arkanoid Spectrum Title Music
    https://www.youtube.com/wat­ch?v=TymO0Lj7Vp8
  79. Tim Follin – „Chronos“ (ZX Spectrum) [Oscilloscope Visualization]
    https://www.youtube.com/wat­ch?v=yJy45MHrPjc
  80. [60 FPS] Wally Beben – „Sanxion Loader“ [ZX Spectrum (Beeper)] (Oscilloscope View)
    https://www.youtube.com/wat­ch?v=JwMxOfQVl7A
  81. Understanding Computer Sound
    http://forgottencomputer.com/re­tro/sound/
  82. AY-3–8912
    https://sinclair.wiki.zxnet­.co.uk/wiki/AY-3–8912
  83. AY-3–8912
    https://github.com/topics/ay-3–8912
  84. Z80 Assembly programming for the ZX Spectrum
    https://www.chibiakumas.com/z80/ZXSpec­trum.php?noui=1
  85. AY-3–8910
    http://vgmpf.com/Wiki/index.php/AY-3–8910
  86. AY-3–8910/8912 Programmable sound generator data manual
    https://f.rdw.se/AY-3–8910-datasheet.pdf

Autor článku

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