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
6. Tónové generátory čipu AY-3–8910
7. Úprava signálu s využitím obálky
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
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
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 |
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.
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) |
Řídicí registry je možné podle jejich funkce rozdělit do několika skupin:
- Prvních šest registrů R0 až R5 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č).
- Následuje registr R6, kterým se nastavuje frekvence šumu, registr R7 pro řízení mixéru a vstupně-výstupních portů.
- Trojice registrů R8, R9 a RA se používá pro nastavení hlasitosti jednotlivých hudebních kanálů.
- Další dvojice registrů RB a RC slouží pro nastavení frekvence obálky a registr RD určuje tvar obálky.
- 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ý:
- Hodinová frekvence: 3546900 Hz
- Frekvence vstupního CLK po vydělení dvěma v ULA: fmaster = 1773400 Hz
- Frekvence po vydělení 16: fmaster/16 = 1773400 / 16 = 110837 Hz
- Nota, která se má zahrát: 440 Hz
- Potřebná konstanta pro dělič: 110837 / 440 = 251
- Hodnota vyšších 4 bitů ukládaná do registru R1: int(251/256) = 0
- 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).
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 – R8 až RA. 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.
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.
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?:
- Nastavíme dělicí konstantu pro kanál A zápisem hodnoty 0 do registru R1 a 251 do registru R0.
- Nastavíme hlasitost kanálu A na maximální hodnotu zápisem hodnoty 15 do registru R8
- 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)
- 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)
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
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:
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
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
- z80 standalone assembler
https://www.asm80.com/onepage/asmz80.html - The ZX BASIC Compiler
https://www.boriel.com/pages/the-zx-basic-compiler.html - Z80 Assembly programming for the ZX Spectrum
https://www.chibiakumas.com/z80/ZXSpectrum.php - 8-BIT SMACKDOWN! 65C02 vs. Z80: slithy VLOGS #6
https://www.youtube.com/watch?v=P1paVoFEvyc - Instrukce mikroprocesoru Z80
https://clrhome.org/table/ - Z80 instructions: adresní režimy atd.
https://jnz.dk/z80/instructions.html - Z80 Instruction Groups
https://jnz.dk/z80/instgroups.html - Elena, New programming language for the ZX Spectrum Next
https://vintageisthenewold.com/elena-new-programming-language-for-the-zx-spectrum-next/ - Sinclair BASIC
https://worldofspectrum.net/legacy-info/sinclair-basic/ - Grafika na osmibitových počítačích firmy Sinclair
https://www.root.cz/clanky/grafika-na-osmibitovych-pocitacich-firmy-sinclair/ - Grafika na osmibitových počítačích firmy Sinclair II
https://www.root.cz/clanky/grafika-na-osmibitovych-pocitacich-firmy-sinclair-ii/ - HiSoft BASIC
https://worldofspectrum.net/infoseekid.cgi?id=0008249 - YS MegaBasic
https://worldofspectrum.net/infoseekid.cgi?id=0008997 - Beta Basic
https://worldofspectrum.net/infoseekid.cgi?id=0007956 - BASIC+
https://worldofspectrum.net/infoseekid.php?id=0014277 - Spectrum ROM Memory Map
https://skoolkit.ca/disassemblies/rom/maps/all.html - Goto subroutine
https://skoolkit.ca/disassemblies/rom/asm/7783.html - Spectrum Next: The Evolution of the Speccy
https://www.specnext.com/about/ - Sedmdesátiny assemblerů: lidsky čitelný strojový kód
https://www.root.cz/clanky/sedmdesatiny-assembleru-lidsky-citelny-strojovy-kod/ - Programovací jazyk BASIC na osmibitových mikropočítačích
https://www.root.cz/clanky/programovaci-jazyk-basic-na-osmibitovych-mikropocitacich/ - Programovací jazyk BASIC na osmibitových mikropočítačích (2)
https://www.root.cz/clanky/programovaci-jazyk-basic-na-osmibitovych-mikropocitacich-2/#k06 - Programovací jazyk BASIC na osmibitových mikropočítačích (3)
https://www.root.cz/clanky/programovaci-jazyk-basic-na-osmibitovych-mikropocitacich-3/ - Sinclair BASIC (Wikipedia CZ)
http://cs.wikipedia.org/wiki/Sinclair_BASIC - Assembly Language: Still Relevant Today
http://wilsonminesco.com/AssyDefense/ - Programovani v assembleru na OS Linux
http://www.cs.vsb.cz/grygarek/asm/asmlinux.html - Why Assembly Language Programming? (Why Learning Assembly Language Is Still a Good Idea)
https://wdc65×x.com/markets/education/why-assembly-language-programming/ - Low Fat Computing
http://www.ultratechnology.com/lowfat.htm - Assembly Language
https://www.cleverism.com/skills-and-tools/assembly-language/ - Why do we need assembly language?
https://cs.stackexchange.com/questions/13287/why-do-we-need-assembly-language - Assembly language (Wikipedia)
https://en.wikipedia.org/wiki/Assembly_language#Historical_perspective - Assembly languages
https://curlie.org/Computers/Programming/Languages/Assembly/ - vasm
http://sun.hasenbraten.de/vasm/ - B-ELITE
https://jsj.itch.io/b-elite - ZX-Spectrum Child
http://www.dotkam.com/2008/11/19/zx-spectrum-child/ - Speccy.cz
http://www.speccy.cz/ - Planet Sinclair
http://www.nvg.ntnu.no/sinclair/ - World of Spectrum
http://www.worldofspectrum.org/ - The system variables
https://worldofspectrum.org/ZXBasicManual/zxmanchap25.html - ZX Spectrum manual: chapter #17 Graphics
https://worldofspectrum.org/ZXBasicManual/zxmanchap17.html - Why does Sinclair BASIC have two formats for storing numbers in the same structure?
https://retrocomputing.stackexchange.com/questions/8834/why-does-sinclair-basic-have-two-formats-for-storing-numbers-in-the-same-structu - Plovoucí řádová čárka na ZX Spectru
https://www.root.cz/clanky/norma-ieee-754-a-pribuzni-formaty-plovouci-radove-tecky/#k05 - 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 - 1A1B: THE ‚REPORT AND LINE NUMBER PRINTING‘ SUBROUTINE
https://skoolkid.github.io/rom/asm/1A1B.html - 2DE3: THE ‚PRINT A FLOATING-POINT NUMBER‘ SUBROUTINE
https://skoolkid.github.io/rom/asm/2DE3.html - 5C63: STKBOT – Address of bottom of calculator stack
https://skoolkid.github.io/rom/asm/5C63.html - 5C65: STKEND – Address of start of spare space
https://skoolkid.github.io/rom/asm/5C65.html - Why does Sinclair BASIC have two formats for storing numbers in the same structure?
https://retrocomputing.stackexchange.com/questions/8834/why-does-sinclair-basic-have-two-formats-for-storing-numbers-in-the-same-structu - Chapter 24: The memory
https://worldofspectrum.org/ZXBasicManual/zxmanchap24.html - Survey of Floating-Point Formats
https://mrob.com/pub/math/floatformats.html - Convert an 8bit number to hex in z80 assembler
https://stackoverflow.com/questions/22838444/convert-an-8bit-number-to-hex-in-z80-assembler - 80 MICROPROCESSOR Instruction Set Summary
http://www.textfiles.com/programming/CARDS/z80 - Extended Binary Coded Decimal Interchange Code
http://en.wikipedia.org/wiki/EBCDIC - ASCII/EBCDIC Conversion Table
http://docs.hp.com/en/32212–90008/apcs01.html - EBCDIC
http://www.hansenb.pdx.edu/DMKB/dict/tutorials/ebcdic.php - EBCDIC tables
http://home.mnet-online.de/wzwz.de/temp/ebcdic/cc_en.htm - The Mainframe Blog
http://mainframe.typepad.com/blog/2006/11/my_personal_mai.html - Binary-coded decimal
https://en.wikipedia.org/wiki/Binary-coded_decimal - BCD
https://cs.wikipedia.org/wiki/BCD - Z80 heaven: Floating Point
http://z80-heaven.wikidot.com/floating-point - Z80, the 8-bit Number Cruncher
http://www.andreadrian.de/oldcpu/Z80_number_cruncher.html - Floating-point library for Z80
https://github.com/DW0RKiN/Floating-point-Library-for-Z80 - z80float
https://github.com/Zeda/z80float - Fixed point arithmetic
https://www.root.cz/clanky/fixed-point-arithmetic/ - ZX Spectrum BASIC Programming – 2nd Edition
https://archive.org/details/zx-spectrum-basic-programming/page/n167/mode/2up - ZX Spectrum BASIC Programming – 2nd Edition
https://archive.org/details/zx-spectrum-basic-programming/page/n169/mode/2up - How fast is memcpy on the Z80?
https://retrocomputing.stackexchange.com/questions/4744/how-fast-is-memcpy-on-the-z80 - How do Z80 Block Transfer instructions work?
https://retrocomputing.stackexchange.com/questions/5416/how-do-z80-block-transfer-instructions-work - Retro Programming Made Simple: Keyboard
http://www.breakintoprogram.co.uk/hardware/computers/zx-spectrum/keyboard - How ZX Spectrum avoided key ghosting
https://retrocomputing.stackexchange.com/questions/16235/how-zx-spectrum-avoided-key-ghosting - ZX Spectrum Keyboard Visualized
http://www.kameli.net/marq/?p=2055 - Sinclair ZX Spectrum Joysticks Explained
https://www.retroisle.com/general/spectrum_joysticks.php - 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/ - 03B5: THE ‚BEEPER‘ SUBROUTINE
https://skoolkid.github.io/rom/asm/03B5.html - How To Write ZX Spectrum Games – Chapter 3
https://chuntey.wordpress.com/2013/02/28/how-to-write-zx-spectrum-games-chapter-3/ - Understanding computer sound
https://www.youtube.com/playlist?list=PL0qES-IQZC8w4vqeQhxHxKgxYYqs3CEOx - Understanding Computer Sound. 5. ZX Spectrum
https://www.youtube.com/watch?v=N5ACJd2LvbY - Dark Fusion (Gremlin Graphics, 1988)
https://www.youtube.com/watch?v=ADL3mdRMzoA - Arkanoid Spectrum Title Music
https://www.youtube.com/watch?v=TymO0Lj7Vp8 - Tim Follin – „Chronos“ (ZX Spectrum) [Oscilloscope Visualization]
https://www.youtube.com/watch?v=yJy45MHrPjc - [60 FPS] Wally Beben – „Sanxion Loader“ [ZX Spectrum (Beeper)] (Oscilloscope View)
https://www.youtube.com/watch?v=JwMxOfQVl7A - Understanding Computer Sound
http://forgottencomputer.com/retro/sound/ - AY-3–8912
https://sinclair.wiki.zxnet.co.uk/wiki/AY-3–8912 - AY-3–8912
https://github.com/topics/ay-3–8912 - Z80 Assembly programming for the ZX Spectrum
https://www.chibiakumas.com/z80/ZXSpectrum.php?noui=1 - AY-3–8910
http://vgmpf.com/Wiki/index.php/AY-3–8910 - AY-3–8910/8912 Programmable sound generator data manual
https://f.rdw.se/AY-3–8910-datasheet.pdf