VideoCast: COSMAC Elf – ukázkové programy

Co dělat s věcí, která má jen dvouciferný displej a 12 přepínačů?

Vžijte se do role Američana, který roku 1976 dočetl Practical Electronics, koupil si za těch 80 doláčů součástky, na univerzálce natahal dráty a součástky připájel.
Vyzkouší si, co se s tím dá dělat, a tady se lidé rozdělí do dvou skupin.

Tu první to nadchne. Počítač! Jako opravdový! A chytne je to nejspíš na celý život.

Ta druhá si s tím chvilku pohraje, zjistí, že to vlastně k ničemu není, a odloží to.

Tak se podívejme, co s tím strojem udělají, než se stane jedno nebo druhé.

Zadání a spuštění uvedených programů si můžete prohlédnout v mém VideoCastu.

COSMAC je skvělý procesor, s 16bitovými registry, jednoduchou instrukční sadou bez prefixů, dá se programovat přímo ve strojovém kódu bez nějakých větších obtíží.

Přehledně instrukční sadu charakterizuje tento obrázek.
Všimněte si, že jsou instrukce ve většině uspořádány tak, aby dolní nibble obsahoval číslo registru, se kterým se pracuje. Proto třeba instrukci LDN neprovádí s registrem 0, protože kód 00 je vyhrazen pro instrukci IDL.
(Lidé kolem Elfa jsou nadšeni, že má instrukci SEX, ale to většinou nevědí, že 6502 má kromě instrukce SEX i instrukci BRA…)
Nevýhodou je, že komunikace s pamětí probíhá po bajtu, a narozdíl od 8080 nebo Z80, které načtou celý registrový pár jednou instrukcí, musí 1802 načítat nejprve půlku a pak druhou půlku, každou jinou instrukcí. Výhodou je, že při čtení z paměti umí jednou instrukcí načíst obsah a současně zvýšit ukazatel, načítání bloku dat se pak zrychluje.

Podívejme se tedy na co nejkratší program, který “něco dělá”.

Uvažujme rovnou základní, nerozšířenou konfiguraci Elfa.
Vezmeme proramy z původního článku či příručky.

Náš program číslo 1 pak bude asi toto:


0000 7A REQ - resetuje Q, tedy nastaví výstup Q do nuly (a zhasne na něj připojenou LED diodu)
0001 3F BN4 - skočí na adresu 0, pokud vstup 4 (EF4) je ...
0002 00 - ... nula.

0003 7B SEQ - nastaví výstup Q na 1 (a rozsvítí LED diodu)
0004 30 BR - a skočí na adresu ...
0005 01 - ... jedna.

Co se z programu dozvídáme?

1) na jednobitový výstup Q je pověšena LED dioda.
2) na jednobitový vstup 4 (EF4) je připojen přepínač INP.
3) jsou použity “krátké” skoky v rámci jedné 256bajtové “stránky” paměti, takže mají jednobajtový parametr.

A co program dělá?
Po spuštění můžete přepínačem INP rozsvěcet a zhasínat LED diodu.
Počítač za skoro stovku dolarů tedy slouží jako přepínač v ceně možná necelého dolaru.

Podívejme se na program číslo 2.
Umíme načíst stav přepínače (nebo tlačítka) INP, tak si rozsviťme diodu až po určitém počtu sepnutí.


0000 F8 LDI - uloží do akumulátoru (registr D) číslo...
0001 05 - ...pět. (Požadovaný počet sepnutí)
0002 3F BN4 - pokud vstup 4 (EF4 - přepínač INP) je 0, skočí na adresu...
0003 02 - ... dva.

0004 37 B4 - pokud vstup 4 je 1, skočí na adresu...
0005 04 - ... čtyři.
0006 FF SMI - od akumulátoru D odečte číslo...
0007 01 - ... jedna.
0008 3A BNZ - pokud D≠0, skočí na adresu ...
0009 02 - ... dva.

000A 7B SEQ - nastaví Q na 1 (a rozsvítí LED diodu)
000B 30 BR - a skočí na adresu...
000C 0A - ... 0A (tedy deset).

Program číslo 3 se chová trochu sofistikovaněji.
Použijme místo diody displej!
Jde-li načíst stav přepínačů a zobrazovat na displeji, můžeme si na displeji zobrazit na přepínačích nastavené číslo.
Tento program si ukládá data do paměti, a musí tedy běžet s povoleným zápisem do paměti.


0000 E1 SEX1 - oblíbená Elfí instrukce. Registr X (čtyřbitový ukazatel na registr) nastaví na registr R1.
0001 90 GHI0 - načte do akumulátoru D obsah vyššího bajtu registru R0.
0002 B1 PHI1 - uloží obsah akumulátoru D do vyššího bajtu registru R1.
0003 F8 LDI - uloží do akumulátoru D hodnotu ...
0004 0A - ... 0A (deset).
0005 A1 PLO1 - uloží obsah akumulátoru D do nižšího bajtu registru R1.
0006 6C INP4 - načte stav portu 4 (stav přepínačů - ne vstup EF4) a uloží na adresu (R(X)).
0007 64 OUT4 - pošle na port 4 (displej) data z adresy (R(X)).
0008 30 BR - skočí na adresu ...
0009 00 - ... nula.

000A xx - dočasné úložiště stavu přepínačů.

Zjistili jsme, že
1) jako program counter je nyní použit R0, takže instrukce GHI 0 : PHI 1 nastaví registr 1 do aktuální stránky paměti (jeho vyšší bajt bude 00), další instrukce nastaví nižší bajt na adresu 0A. registr R1 pak směřuje na adresu 000A.
Program tedy bude fungovat správně, ať ho přesuneme do jakékoli 256bajtové stránky.
2) stav přepínačů se načte na portu 4 (osmibitový port 4 není totožný s jednobitovým vstupem EF4).
Jendobitové vstupy EF jsou 4, osmibitových portů INP a OUT je 7.
3) i displej je na portu 4.
4) se zapnutým přepínačem MP to nefunguje.

To už je lepší, co to dělá.
Ale pokud chceme, aby se to trochu hejbalo, musíme neustále cvakat přepínači.
Tak nechme Elfa, ať dělá něco sám.
I kdybychom se kvůli tomu měli vrátit k diodě.

Program číslo 4 pak bude vypadat takto:


0000 7A REQ - resetuje Q, tedy nastaví výstup Q do nuly (a zhasne na něj připojenou LED diodu)
0001 F8 LDI - uloží do akumulátoru D číslo...
0002 10 - ... 10 (tedy šestnáct).
0003 B1 PHI1 - uloží obsah akumulátoru D do vyššího bajtu registru R1.
0004 21 DEC1 - sníží obsah registru R1 o 1
0005 91 GHI1 - načte do akumulátoru D obsah vyššího bajtu registru R1.
0006 3A BNZ - pokud D≠0, skočí na adresu ...
0007 04 - ... čtyři.

0008 31 BQ - pokud je výstup Q nastaven na 1, skočí na adresu ...
0009 00 - ... nula.

000A 7B SEQ - nastaví Q na 1 (a rozsvítí LED diodu)
000B 30 BR - a skočí na adresu ...
000C 01 - ... jedna.

Co jsme se z programu dozvěděli?
1) celkem nic. Ale krásně to bliká, samo.
2) interval bliknutí je definován časovou smyčkou čítanou registrem R1, obsahujícím číslo 10xx (na nižším bajtu celkem nezáleží), tedy minimálně 4096 cyklů.

A přidám ještě jeden program, který se mi líbí.
Vznikl pro “membership card“, která zobrazuje data na binárních LED, proto na této verzi dává větší smysl, než na ostatních modifikacích Elfa s TIL311 displejem.
Jedná se o “jednorozměrnou hru Life”, respektive pravidlo 90.


0000 90 GHI 0 - Načte aktivní stránku (R0 = PC)
0001 B1 PHI 1 - a uloží do R1.
0002 F8 LDI - Uloží do akumulátoru D číslo ...
0003 F0 - dvěstěčtyřicet (F0), adresu dočasného úložiště,
0004 A1 PLO 1 - a uloží do R1.
0005 E1 SEX 1 - Nastaví registr X ukazovat na registr R1.
0006 6C INP 4 - Načte vstup INP4, tedy stav přepínačů,
0007 A2 PLO 2 - a uloží do registru R2.
0008 F6 SHR - Bitový posun akumulátoru D doprava.
0009 51 STR 1 - Posunutý stav uloží dočasného úložiště (ukazovaného registrem R1).
000A F8 LDI - Uloží do akumulátoru číslo ...
000B 20 - ... třicet dva (20).
000C B3 PHI 3 - Nastaví čekací smyčku (512 průběhů, na dolním bajtu R3 nezáleží)
000D 23 DEC 3 - a po dekrementaci registru R3
000E 93 GHI - dokud nedosáhne
000F 3A 0D BNZ - nuly, čeká skákáním na adresu ...
0010 0D - ... třináct (0D).
0011 82 GLO 2 - Obnoví aktuální stav
0012 FE SHL - a po bitovém posunu akumulátoru doleva
0013 F3 XOR - XORuje se stavem posunutým doleva (nový stav každé buňky je XORem jejích sousedů vlevo a vpravo).
0014 51 STR 1 - výsledek uloží do dočasného úložiště
0015 64 OUT 4 - a pošle na výstup OUT4 (zobrazí na displeji) s inkrementací R1,
0016 21 DEC 1 - který vzápětí dekrementuje na původní hodnotu.
0017 30 BR - Vše opakuje skokem na adresu ...
0018 07 - ... sedm (07).

Používá adresu F0 jako dočasné úložiště (viz parametr na adrese 0003). Program je relokovatelný do libovolné “stránky”.