Obsah
1. Práce s klávesnicí na ZX Spectru
3. Připojení matice kláves k čipům ZX Spectra
4. Instrukce pro čtení dat z portu či zápis dat na port
5. Přečtení a dekódování informací o stavu kláves v jedné řadě
6. Krátké ohlédnutí zpět: modifikace barvových atributů obrazovky
7. Vizuální indikace stisku klávesy
8. Úplný zdrojový kód dnešního druhého demonstračního příkladu
9. Detekce stisku klávesy či kláves na jednom fyzickém řádku
10. Pomocná makra a implementace rutiny pro vizualizaci stisku kláves
11. Úplný zdrojový kód dnešního třetího demonstračního příkladu
12. Čtení a dekódování všech kláves
13. Subrutina pro načtení a vizualizaci jednoho fyzického řádku klávesnice
14. Pomocné makro pro volání subrutiny z předchozí kapitoly
15. Úplný zdrojový kód dnešního čtvrtého demonstračního příkladu
16. Problematika detekce stisku většího množství kláves
17. Od klávesnice k joystickům
18. Příloha: upravený soubor Makefile pro překlad demonstračních příkladů
19. Repositář s demonstračními příklady
1. Práce s klávesnicí na ZX Spectru
V předchozích částech seriálu o vývoji programů pro legendární osmibitový domácí mikropočítač ZX Spectrum jsme se zaměřili především na popis práce s video pamětí ZX Spectra, takže nyní již máme alespoň rámcovou představu, jakým způsobem se vykreslují objekty na obrazovku tohoto slavného domácího osmibitového mikropočítače. Ovšem abychom se mohli pustit do tvorby nějaké skutečné (i když jednoduché) hry, potřebujeme mít možnost tuto hru ovládat. K dispozici je pochopitelně vestavěná klávesnice nebo joystick (kterých navíc existuje několik typů – liší se nikoli svou konstrukcí, ale způsobem připojení k ZX Spectru), popř. exotičtější zařízení typu myš. V dnešním článku si ukážeme základní práci s klávesnicí. Současně se seznámíme s instrukcemi určenými pro čtení nebo zápis dat na vstupně-výstupní porty, což je (stručně řečeno) z pohledu mikroprocesoru Zilog Z80 adresová oblast oddělená od adresního prostoru pamětí ROM a RAM.
Obrázek 1: Většina postav ve hrách se na ZX Spectru ovládá buď klávesnicí nebo joystickem.
Obrázek 2: ZX Spectrum+ s odlišnou klávesnicí (a novou klávesou Extend Mode zjednodušující zápis některých příkazů a funkcí Sinclair BASICu). Dnes si však popíšeme práci s klávesnicí původního „gumáka“ ZX Spectrum 48k.
2. Klávesnice ZX Spectra
Klávesnice originálního ZX Spectra 48k obsahuje čtyřicet kláves, které jsou uspořádány do čtyř řad, přičemž každá řada obsahuje deset kláves (nenajdeme zde tedy například řadu pouze s mezerníkem atd.). Kromě deseti numerických kláves a 26 kláves se znaky anglické abecedy zde najdeme čtveřici kláves se speciálním významem: mezerník, Enter, Caps Shift a Symbol Shift:
Obrázek 3: Klávesnice originálního ZX Spectra 48k (zobrazeno v emulátoru Fuse).
Jednotlivé klávesy mají v BASICu větší množství funkcí, které se přepínají oběma Shifty. Ovšem nás v dnešním článku bude zajímat nízkoúrovňový přístup, tedy jak v reálném čase přečíst stisk testované klávesy. Z tohoto pohledu se všechny klávesy chovají naprosto stejným způsobem.
3. Připojení matice kláves k čipům ZX Spectra
Z pohledu uživatele obsahuje klávesnice čtyři řady kláves po deseti klávesách, ovšem interně vypadá zapojení kláves k čipům ZX Spectra odlišně, protože se jedná o matici 5×8 kláves:
Obrázek 4: Zapojení kláves k čipům ZX Spectra.
Z výše uvedeného zapojení vyplývá, že se vždy v daný okamžik může testovat stisk pěti kláves umístěných (na schématu) v jednom sloupci (ale pro větší zmatení se většinou mluví o řádcích – ideální by tedy bylo schéma otočit o 90°). Nejprve je nutné programově (přes I/O porty) vybrat jednu z linek na adresové sběrnici a posléze z datové sběrnice přečíst stav pěti kláves. Ovšem vzhledem ke způsobu zapojení klávesnice (pull-up rezistor atd.) bude stisknutá klávesa indikována logickou nulou, nikoli jedničkou. A samotný výběr linky se provádí taktéž „inverzně“ – vybraná linka je nastavena na logickou nulu a ostatní linky na jedničku. Proč tomu tak je? Stisk klávesy v takovém případě sníží logickou úroveň na vstupu do ULA na logickou nulu, zatímco u ostatních 35 kláves z jiných linek k tomu nedojde – stiskem se pouze na obě strany diody přivede logická jednička (resp. +5V, což je více než logická jednička).
Hodnoty přiváděné na horních osm bitů adresové sběrnice:
Řádek kláves | Hodnota hex | Bitová maska |
---|---|---|
0 | $fe | 11111110 |
1 | $fd | 11111101 |
2 | $fb | 11111011 |
3 | $f7 | 11110111 |
4 | $ef | 11101111 |
5 | $df | 11011111 |
6 | $bf | 10111111 |
7 | $7f | 01111111 |
4. Instrukce pro čtení dat z portu či zápis dat na port
Čtení informací o stisknutých klávesách se provádí IO (vstupně-výstupní) instrukcí určenou pro přečtení hodnoty z vybraného portu, což je z pohledu mikroprocesoru osmibitová adresa, která je ovšem oddělena od adresy ROM či adresy do RAM. Na porty se tedy můžeme dívat jako na oddělený adresový prostor, z něhož lze jednotlivé bajty číst nebo je modifikovat k tomu určenými speciálními instrukcemi. Tyto instrukce jsou vypsány v následující tabulce:
Instrukce | Stručný popis |
---|---|
IN A,(n) | přečtení bajtu z portu N (0..255) |
IN r,(C) | přečtení bajtu z portu uloženého v registru C, registr B je poslán na horní polovinu adresové sběrnice |
INI | čtení bloku dat z portu, jehož číslo je uloženo v registru C, uložení od adresy HL, registru B pracuje jako čítač |
INIR | dtto, ale registr B je navíc poslán na horní polovinu adresové sběrnice |
IND | provedení jediné operace blokového čtení dat z portu |
INDR | blokové čtení dat, registr B je čítač, HL poslední adresa bloku pro zápis |
OUT (n),A | zápis bajtu z akumulátoru na port N (0..255) |
OUT ©,r | zápis bajtu z registru r do portu uloženého v registru C |
OUTI | zápis bloku dat do portu, jehož číslo je uloženo v registru C, B je opět ve funkci čítače |
OTIR | dtto, ale registr B je navíc poslán na horní polovinu adresové sběrnice |
OUTD | provedení jediné operace blokového zápisu dat na port |
OTDR | blokový zápis dat na port, registr B je opět čítač |
Nás bude zajímat pouze druhá instrukce IN r,C), která přečte bajt z portu, jehož číslo 0..255 je uloženo v registru C. Kromě toho se ovšem před vlastním čtením pošle obsah registru B na horních osm adresových bitů adresové sběrnice A8 až A15, čehož využijeme. Opět je vhodné se podívat na čtvrtý obrázek – zde je zřejmé, že je nutné nastavit bity A8 až A15 (až na jediný) na logickou hodnotu 1, což uzavře příslušné diody.
5. Přečtení a dekódování informací o stavu kláves v jedné řadě
Nyní se konečně dostáváme k ústřední části dnešního článku – jak přečíst informaci o tom, že byla stisknuta nějaká klávesa. Vyzkoušíme si například testování stisku klávesy Caps Shift, která se nachází v první řádce, společně s klávesami Z, X, C a V. Stav těchto pěti kláves se čte z portu 0×fef0, kde 0×fe představuje bitovou masku 11111110 zapisovanou na horní polovinu adresové sběrnice (viz obrázek a tabulku ze třetí kapitoly):
KB_ROW_0_PORT equ $fef0
Čtení stavu všech pěti kláves se provede instrukcí IN, přičemž přečtená osmibitová hodnota se uloží do akumulátoru A:
ld bc, KB_ROW_0_PORT ; adresa portu, ze kterého budeme číst údaje in a, (c) ; vlastní čtení z portu (5 bitů)
Informace o stisku klávesy Caps Shift bude uložena do nultého bitu, takže si připravíme masku:
SHIFT_KEY_MASK equ %00000001
Nyní nám pouze zbývá zamaskovat hodnoty dalších bitů instrukcí AND. Výsledkem bude nulová hodnota v případě, že je klávesa stisknuta (připomeňme si „inverzní“ logiku) a nenulová hodnota, pokud stisknuta není. Pro test nulové hodnoty nám postačuje otestovat příznak zero:
and SHIFT_KEY_MASK ; test, zda je stisknuta klávesa SHIFT jr z, shift_pressed ; pokud je stlačena, skok ... ... ... jp ... nebo ret atd. shift_pressed: ... ... ...
6. Krátké ohlédnutí zpět: modifikace barvových atributů obrazovky
V rámci dalších demonstračních příkladů budeme stisk klávesy vizuálně zobrazovat na obrazovce ZX Spectra, a to konkrétně tak, že zvýrazníme znak s příslušnou klávesou. Pro zvýraznění znaku postačuje maličkost – změnit příslušný barvový atribut. Připomeňme si tedy ve stručnosti, jak se tato operace provádí. Je to jednoduché – atributová paměť začíná na adrese 0×5800 a má strukturu 32×24=768 atributových bajtů. Každý atributový bajt obsahuje bit pro řízení blikání, bit pro řízení intenzity popředí, barvu popředí (3 bity) a barvu pozadí (taktéž 3 bity):
BLINK_BIT equ %10000000 INTENSITY_BIT equ %01000000 BLACK_COLOR equ %000 BLUE_COLOR equ %001 RED_COLOR equ %010 MAGENTA_COLOR equ %011 GREEN_COLOR equ %100 CYAN_COLOR equ %101 YELLOW_COLOR equ %110 WHITE_COLOR equ %111
Modifikace jednoho atributu (8×8 pixelů) se tedy provede jediným zápisem do atributové paměti, což je ukázáno na dnešním prvním demonstračním příkladu:
ATTRIBUTE_ADR equ $5800 ENTRY_POINT equ $8000 BLINK_BIT equ %10000000 INTENSITY_BIT equ %01000000 BLACK_COLOR equ %000 BLUE_COLOR equ %001 RED_COLOR equ %010 MAGENTA_COLOR equ %011 GREEN_COLOR equ %100 CYAN_COLOR equ %101 YELLOW_COLOR equ %110 WHITE_COLOR equ %111 org ENTRY_POINT start: ld a, INTENSITY_BIT | (BLUE_COLOR << 3) | RED_COLOR ld (ATTRIBUTE_ADR+32*3+2), a ; zápis atributu do atributové paměti ret ; návrat do BASICu end ENTRY_POINT
Výsledek činnosti tohoto příkladu:
Obrázek 5: Modifikace popředí a pozadí vybraného atributu na obrazovce ZX Spectra.
Celý příklad se přeloží do pouhých pěti bajtů strojového kódu:
ATTRIBUTE_ADR EQU 5800 ENTRY_POINT EQU 8000 BLINK_BIT EQU 0080 INTENSITY_BIT EQU 0040 BLACK_COLOR EQU 0000 BLUE_COLOR EQU 0001 RED_COLOR EQU 0002 MAGENTA_COLOR EQU 0003 GREEN_COLOR EQU 0004 CYAN_COLOR EQU 0005 YELLOW_COLOR EQU 0006 WHITE_COLOR EQU 0007 ORG 8000 8000: label start 8000:3E4A LD A, 4A 8002:326258 LD (5862), A 8005:C9 RET 8006: END 8000 Emiting TAP basic loader Emiting TAP from 8000 to 8005
7. Vizuální indikace stisku klávesy
Nyní již máme k dispozici všechny informace, které potřebujeme znát pro vizuální indikaci stisku vybrané klávesy:
- Způsob přečtení stavu pětice kláves v jednom řádku
- Způsob detekce stisku vybrané klávesy z bitového pole
- Způsob zajištění vizuální zpětné vazby na obrazovce ZX Spectra
Vlastní implementace je ve skutečnosti velmi přímočará – atribut změníme jak ve chvíli, kdy je klávesa stisknutá, tak i tehdy, pokud stisknutá není (samozřejmě se použije odlišný atribut):
start: and SHIFT_KEY_MASK ; test, zda je stisknuta klávesa SHIFT jr z, shift_pressed ; pokud je stlačena, skok ld a, WHITE_COLOR << 3 ; "neviditelný" atribut ld (ATTRIBUTE_ADR+32*3+2), a ; zápis atributu do atributové paměti jp start ; opětovný test stisku klávesy shift_pressed: ld a, INTENSITY_BIT | (RED_COLOR << 3) ld (ATTRIBUTE_ADR+32*3+2), a ; zápis atributu do atributové paměti jp start ; opětovný test stisku klávesy
Výsledek bude vypadat následovně:
Obrázek 6: Stisk klávesy Caps Shift.
Obrázek 7: Klávesa Caps Shift není stisknuta.
8. Úplný zdrojový kód dnešního druhého demonstračního příkladu
Úplný zdrojový kód dnešního prvního demonstračního příkladu s detekcí stisku jedné klávesy bude vypadat následovně:
ATTRIBUTE_ADR equ $5800 ENTRY_POINT equ $8000 BLINK_BIT equ %10000000 INTENSITY_BIT equ %01000000 BLACK_COLOR equ %000 BLUE_COLOR equ %001 RED_COLOR equ %010 MAGENTA_COLOR equ %011 GREEN_COLOR equ %100 CYAN_COLOR equ %101 YELLOW_COLOR equ %110 WHITE_COLOR equ %111 KB_ROW_0_PORT equ $fef0 SHIFT_KEY_MASK equ %00000001 org ENTRY_POINT start: ld bc, KB_ROW_0_PORT ; adresa portu, ze kterého budeme číst údaje in a, (c) ; vlastní čtení z portu (5 bitů) and SHIFT_KEY_MASK ; test, zda je stisknuta klávesa SHIFT jr z, shift_pressed ; pokud je stlačena, skok ld a, WHITE_COLOR << 3 ; "neviditelný" atribut ld (ATTRIBUTE_ADR+32*3+2), a ; zápis atributu do atributové paměti jp start ; opětovný test stisku klávesy shift_pressed: ld a, INTENSITY_BIT | (RED_COLOR << 3) ld (ATTRIBUTE_ADR+32*3+2), a ; zápis atributu do atributové paměti jp start ; opětovný test stisku klávesy end ENTRY_POINT
Jak je z výpisu přeloženého strojového kódu patrné, je celý příklad velmi krátký a přeloží se do pouhých 24 bajtů strojového kódu:
ATTRIBUTE_ADR EQU 5800 ENTRY_POINT EQU 8000 BLINK_BIT EQU 0080 INTENSITY_BIT EQU 0040 BLACK_COLOR EQU 0000 BLUE_COLOR EQU 0001 RED_COLOR EQU 0002 MAGENTA_COLOR EQU 0003 GREEN_COLOR EQU 0004 CYAN_COLOR EQU 0005 YELLOW_COLOR EQU 0006 WHITE_COLOR EQU 0007 KB_ROW_0_PORT EQU FEF0 SHIFT_KEY_MASK EQU 0001 ORG 8000 8000: label start 8000:01F0FE LD BC, FEF0 8003:ED78 IN A, (C) 8005:E601 AND 01 8007:2808 JR Z, 8011 8009:3E38 LD A, 38 800B:326258 LD (5862), A 800E:C30080 JP 8000 8011: label shift_pressed 8011:3E50 LD A, 50 8013:326258 LD (5862), A 8016:C30080 JP 8000 8019: END 8000 Emiting TAP basic loader Emiting TAP from 8000 to 8018
9. Detekce stisku klávesy či kláves na jednom fyzickém řádku
Nyní se podívejme na způsob detekce stisku libovolné klávesy nebo i více kláves na jednom fyzickém řádku. Celá subrutina je naprogramována přímočarým způsobem:
- Přečteme bitové pole obsahující stav všech pěti kláves na řádku
- V programové smyčce provádíme bitový posun doprava, přičemž se nejnižší bajt uloží do příznaku C
- Na základě obsahu příznaku C provádíme rozeskok do bloků/větví „stisknuta“/„nestistknuta“
- Počitadlo smyčky se sníží o jedničku a pokud se nedosáhlo nuly, pokračuje se od bodu 2
V assembleru vypadá tento algoritmu následovně (opět použijeme pouze první řádek kláves):
keypress: ld bc, KB_ROW_0_PORT ; adresa portu, ze kterého budeme číst údaje in a, (c) ; vlastní čtení z portu (5 bitů) ld b, 5 ; počet testovaných kláves next_key: srl a ; přesunout kód stisku klávesy do příznaku carry jr nc, key_pressed ; test stisku klávesy ... ... ; část kódu zavolaná, pokud klávesa není stisknutá ... jr next ; test další klávesy key_pressed: ... ... ; část kódu zavolaná, pokud klávesa je stisknutá ... next: djnz next_key ; opakovat celou smyčku 5x jp keypress ; další test stisku kláves
10. Pomocná makra a implementace rutiny pro vizualizaci stisku kláves
V dále uvedeném demonstračním příkladu použijeme několik pomocných maker (jen pro další ilustraci možností jejich použití). První makro slouží pro zobrazení jednoho znaku na obrazovce ZX Spectra, přičemž volá příslušnou subrutinu uloženou v ROM:
printChar MACRO character ld a, character rst 0x10 ; zavolání rutiny v ROM ENDM
Druhé makro pouze změní barvový atribut adresovaný registrovým párem HL a zvýší hodnotu uloženou v HL o jedničku. To znamená, že další volání stejného makra změní následující atribut:
changeAttribute MACRO attribute ld (hl), attribute inc hl ENDM
Na začátku programu vymažeme obrazovku, což současně otevře kanál použitý ROM rutinami pro tisk znaku. Následně si necháme vytisknout pětici znaků reprezentujících klávesy v prvním řádku (Caps Shift, Z, X, C a V):
start: call ROM_CLS ; smazání obrazovky a otevření kanálu číslo 2 (screen) printChar '^' ; tisk pětice znaků na obrazovku printChar 'Z' printChar 'X' printChar 'C' printChar 'V'
Výsledek bude vypadat následovně:
Obrázek 8: Pětice kláves na prvním řádku.
Dále nám již stačí doplnit algoritmus z předchozí kapitoly tak, aby se modifikovaly jednotlivé atributy:
keypress: ld bc, KB_ROW_0_PORT ; adresa portu, ze kterého budeme číst údaje in a, (c) ; vlastní čtení z portu (5 bitů) ld hl, ATTRIBUTE_ADR ; adresa, od které budeme měnit barvové atributy ld b, 5 ; počet atributů + počet testovaných kláves next_key: srl a ; přesunout kód stisku klávesy do příznaku carry jr nc, key_pressed ; test stisku klávesy changeAttribute WHITE_COLOR << 3 jr next ; test další klávesy key_pressed: changeAttribute INTENSITY_BIT | (RED_COLOR << 3) next: djnz next_key ; opakovat celou smyčku 5x jp keypress ; další test stisku kláves
Výsledky mohou vypadat takto:
Obrázek 9: Stisk Caps Shiftu.
Obrázek 10: Stisk klávesy C.
Obrázek 11: Stisk kombinace kláves.
Obrázek 12: Stisk kombinace kláves (více kláves není na mé klávesnici detekováno :-).
11. Úplný zdrojový kód dnešního třetího demonstračního příkladu
Podívejme se nyní na úplný zdrojový kód dnešního třetího demonstračního příkladu, který dokáže detekovat stisk libovolné kombinace kláves v jednom fyzickém řádku Shift-Z-X-C-V:
ATTRIBUTE_ADR equ $5800 ENTRY_POINT equ $8000 ROM_CLS equ $0DAF org ENTRY_POINT BLINK_BIT equ %10000000 INTENSITY_BIT equ %01000000 BLACK_COLOR equ %000 BLUE_COLOR equ %001 RED_COLOR equ %010 MAGENTA_COLOR equ %011 GREEN_COLOR equ %100 CYAN_COLOR equ %101 YELLOW_COLOR equ %110 WHITE_COLOR equ %111 KB_ROW_0_PORT equ $fef0 printChar MACRO character ld a, character rst 0x10 ; zavolání rutiny v ROM ENDM changeAttribute MACRO attribute ld (hl), attribute inc hl ENDM start: call ROM_CLS ; smazání obrazovky a otevření kanálu číslo 2 (screen) printChar '^' ; tisk pětice znaků na obrazovku printChar 'Z' printChar 'X' printChar 'C' printChar 'V' keypress: ld bc, KB_ROW_0_PORT ; adresa portu, ze kterého budeme číst údaje in a, (c) ; vlastní čtení z portu (5 bitů) ld hl, ATTRIBUTE_ADR ; adresa, od které budeme měnit barvové atributy ld b, 5 ; počet atributů + počet testovaných kláves next_key: srl a ; přesunout kód stisku klávesy do příznaku carry jr nc, key_pressed ; test stisku klávesy changeAttribute WHITE_COLOR << 3 jr next ; test další klávesy key_pressed: changeAttribute INTENSITY_BIT | (RED_COLOR << 3) next: djnz next_key ; opakovat celou smyčku 5x jp keypress ; další test stisku kláves end ENTRY_POINT
Povšimněte si, že každá expanze makra printChar zvětšuje výsledný strojový kód o tři bajty, stejně jako expandované makro changeAttribute:
ATTRIBUTE_ADR EQU 5800 ENTRY_POINT EQU 8000 ROM_CLS EQU 0DAF ORG 8000 BLINK_BIT EQU 0080 INTENSITY_BIT EQU 0040 BLACK_COLOR EQU 0000 BLUE_COLOR EQU 0001 RED_COLOR EQU 0002 MAGENTA_COLOR EQU 0003 GREEN_COLOR EQU 0004 CYAN_COLOR EQU 0005 YELLOW_COLOR EQU 0006 WHITE_COLOR EQU 0007 KB_ROW_0_PORT EQU FEF0 Defining MACRO printChar Params: character Defining MACRO changeAttribute Params: attribute 8000: label start 8000:CDAF0D CALL 0DAF Expanding MACRO printChar character= ^ LD A , character 8003:3E5E LD A, 5E RST 0010 8005:D7 RST 10 ENDM ENDM End of MACRO printChar Expanding MACRO printChar character= Z LD A , character 8006:3E5A LD A, 5A RST 0010 8008:D7 RST 10 ENDM ENDM End of MACRO printChar Expanding MACRO printChar character= X LD A , character 8009:3E58 LD A, 58 RST 0010 800B:D7 RST 10 ENDM ENDM End of MACRO printChar Expanding MACRO printChar character= C LD A , character 800C:3E43 LD A, 43 RST 0010 800E:D7 RST 10 ENDM ENDM End of MACRO printChar Expanding MACRO printChar character= V LD A , character 800F:3E56 LD A, 56 RST 0010 8011:D7 RST 10 ENDM ENDM End of MACRO printChar 8012: label keypress 8012:01F0FE LD BC, FEF0 8015:ED78 IN A, (C) 8017:210058 LD HL, 5800 801A:0605 LD B, 05 801C: label next_key 801C:CB3F SRL A 801E:3005 JR NC, 8025 Expanding MACRO changeAttribute attribute= WHITE_COLOR << 0003 LD ( HL ) , attribute 8020:3638 LD (HL), 38 INC HL 8022:23 INC HL ENDM ENDM End of MACRO changeAttribute 8023:1803 JR 8028 8025: label key_pressed Expanding MACRO changeAttribute attribute= INTENSITY_BIT | ( RED_COLOR << 0003 ) LD ( HL ) , attribute 8025:3650 LD (HL), 50 INC HL 8027:23 INC HL ENDM ENDM End of MACRO changeAttribute 8028: label next 8028:10F2 DJNZ 801C 802A:C31280 JP 8012 802D: END 8000 Emiting TAP basic loader Emiting TAP from 8000 to 802C
12. Čtení a dekódování všech kláves
V dalších kapitolách si ukážeme jeden ze způsobů čtení a dekódování stavu všech čtyřiceti kláves na klávesnici ZX Spectra. Celý postup je vlastně jednoduchý, protože nám postačuje výše uvedený algoritmus opakovat osmkrát, pokaždé pro jinou řadu pěti kláves.
Obrázek 13: Žádná klávesa není stisknuta.
Obrázek 14: Detekce stisku jediné klávesy.
Obrázek 15: Detekce stisku jediné klávesy.
Obrázek 16: Detekce stisku kombinace kláves.
Obrázek 17: Detekce stisku kombinace kláves.
Obrázek 18: Detekce stisku kombinace kláves.
Pro jednoduchost jsou adresy ukládané do pracovního registru B a posílané na vyšší bajt adresové sběrnice instrukcí IN reprezentovány formou symbolické konstanty, i když by bylo možné provádět jejich výpočet bitovým posuvem:
KB_ROW_0_PORT equ $fe KB_ROW_1_PORT equ $fd KB_ROW_2_PORT equ $fb KB_ROW_3_PORT equ $f7 KB_ROW_4_PORT equ $ef KB_ROW_5_PORT equ $df KB_ROW_6_PORT equ $bf KB_ROW_7_PORT equ $7f
13. Subrutina pro načtení a vizualizaci jednoho fyzického řádku klávesnice
Subrutinu, která načte stav jedné řady kláves a zvýrazní na obrazovce ZX Spectra ty klávesy, které jsou stisknuty, již známe z předchozího textu. Pouze tuto subrutinu upravíme do takové podoby, aby se jí předávalo číslo portu a obsah pracovního registru B ve formě parametrů. Výsledek by mohl vypadat následovně:
keypress_detection: in a, (c) ; vlastní čtení z portu (5 bitů) ld b, 5 ; počet atributů + počet testovaných kláves next_key: srl a ; přesunout kód stisku klávesy do příznaku carry jr nc, key_pressed ; test stisku klávesy changeAttribute WHITE_COLOR << 3 jr next ; test další klávesy key_pressed: changeAttribute INTENSITY_BIT | (RED_COLOR << 3) next: djnz next_key ; opakovat celou smyčku 5x ret ; návrat z podprogramu
14. Pomocné makro pro volání subrutiny z předchozí kapitoly
Vzhledem k tomu, že budeme výše uvedenou subrutinu volat celkem osmkrát (protože existuje osm řad kláves), připravíme si pro tento účel jednoduché makro:
keypress MACRO port, attribute_address ld b, port ; adresa portu, ze kterého budeme číst údaje ld c, $fe ld hl, attribute_address ; adresa, od které budeme měnit barvové atributy call keypress_detection ; zavolání subrutiny pro detekci sticku kláves ENDM
Expanze tohoto makra vypadají takto:
Expanding MACRO keypress port= KB_ROW_7_PORT attribute_address= ATTRIBUTE_ADR + 0020 * 0007 LD B , port 804F:067F LD B, 7F LD C , 00FE 8051:0EFE LD C, FE LD HL , attribute_address 8053:21E058 LD HL, 58E0 CALL keypress_detection 8056:CD5D80 CALL 805D ENDM
15. Úplný zdrojový kód dnešního čtvrtého demonstračního příkladu
Podívejme se nyní na úplný zdrojový kód dnešního třetího demonstračního příkladu, který dokáže detekovat stisk (teoreticky) libovolné kombinace kláves:
ATTRIBUTE_ADR equ $5800 ENTRY_POINT equ $8000 ROM_CLS equ $0DAF org ENTRY_POINT BLINK_BIT equ %10000000 INTENSITY_BIT equ %01000000 BLACK_COLOR equ %000 BLUE_COLOR equ %001 RED_COLOR equ %010 MAGENTA_COLOR equ %011 GREEN_COLOR equ %100 CYAN_COLOR equ %101 YELLOW_COLOR equ %110 WHITE_COLOR equ %111 KB_ROW_0_PORT equ $fe KB_ROW_1_PORT equ $fd KB_ROW_2_PORT equ $fb KB_ROW_3_PORT equ $f7 KB_ROW_4_PORT equ $ef KB_ROW_5_PORT equ $df KB_ROW_6_PORT equ $bf KB_ROW_7_PORT equ $7f changeAttribute MACRO attribute ld (hl), attribute inc hl ENDM keypress MACRO port, attribute_address ld b, port ; adresa portu, ze kterého budeme číst údaje ld c, $fe ld hl, attribute_address ; adresa, od které budeme měnit barvové atributy call keypress_detection ; zavolání subrutiny pro detekci sticku kláves ENDM start: call ROM_CLS ; smazání obrazovky a otevření kanálu číslo 2 (screen) ld HL, keys ; adresa prvního znaku v řetězci call print_string ; subrutina pro tisk řetězce repeat: keypress KB_ROW_0_PORT, ATTRIBUTE_ADR+32*0 keypress KB_ROW_1_PORT, ATTRIBUTE_ADR+32*1 keypress KB_ROW_2_PORT, ATTRIBUTE_ADR+32*2 keypress KB_ROW_3_PORT, ATTRIBUTE_ADR+32*3 keypress KB_ROW_4_PORT, ATTRIBUTE_ADR+32*4 keypress KB_ROW_5_PORT, ATTRIBUTE_ADR+32*5 keypress KB_ROW_6_PORT, ATTRIBUTE_ADR+32*6 keypress KB_ROW_7_PORT, ATTRIBUTE_ADR+32*7 jp repeat ret ; návrat do BASICu (nikdy k němu nedojde) keypress_detection: in a, (c) ; vlastní čtení z portu (5 bitů) ld b, 5 ; počet atributů + počet testovaných kláves next_key: srl a ; přesunout kód stisku klávesy do příznaku carry jr nc, key_pressed ; test stisku klávesy changeAttribute WHITE_COLOR << 3 jr next ; test další klávesy key_pressed: changeAttribute INTENSITY_BIT | (RED_COLOR << 3) next: djnz next_key ; opakovat celou smyčku 5x ret ; návrat z podprogramu print_string: ld A, (HL) ; načíst kód znaku z řetězce and a ; test na kód znak s kódem 0 ret Z ; ukončit program na konci řetězce rst 0x10 ; zavolání rutiny v ROM inc HL ; přechod na další znak jr print_string ret ; návrat ze subrutiny keys: ; layout klávesnice z pohledu čipů ZX Spectra NEW_LINE equ 13 END_OF_STRING equ 0 DB "^", "Z", "X", "C", "V", NEW_LINE DB "A", "S", "D", "F", "G", NEW_LINE DB "Q", "W", "E", "R", "T", NEW_LINE DB "1", "2", "3", "4", "5", NEW_LINE DB "0", "9", "8", "7", "6", NEW_LINE DB "P", "O", "I", "U", "Y", NEW_LINE DB 127, "L", "K", "J", "H", NEW_LINE DB "_", $60, "M", "N", "B", END_OF_STRING end ENTRY_POINT
A takto vypadá způsob překladu tohoto demonstračního příkladu do strojového kódu (výsledný kód je relativně objemný kvůli expanzi maker):
ATTRIBUTE_ADR EQU 5800 ENTRY_POINT EQU 8000 ROM_CLS EQU 0DAF ORG 8000 BLINK_BIT EQU 0080 INTENSITY_BIT EQU 0040 BLACK_COLOR EQU 0000 BLUE_COLOR EQU 0001 RED_COLOR EQU 0002 MAGENTA_COLOR EQU 0003 GREEN_COLOR EQU 0004 CYAN_COLOR EQU 0005 YELLOW_COLOR EQU 0006 WHITE_COLOR EQU 0007 KB_ROW_0_PORT EQU 00FE KB_ROW_1_PORT EQU 00FD KB_ROW_2_PORT EQU 00FB KB_ROW_3_PORT EQU 00F7 KB_ROW_4_PORT EQU 00EF KB_ROW_5_PORT EQU 00DF KB_ROW_6_PORT EQU 00BF KB_ROW_7_PORT EQU 007F Defining MACRO changeAttribute Params: attribute Defining MACRO keypress Params: port, attribute_address 8000: label start 8000:CDAF0D CALL 0DAF 8003:217880 LD HL, 8078 8006:CD7080 CALL 8070 8009: label repeat Expanding MACRO keypress port= KB_ROW_0_PORT attribute_address= ATTRIBUTE_ADR + 0020 * 0000 LD B , port 8009:06FE LD B, FE LD C , 00FE 800B:0EFE LD C, FE LD HL , attribute_address 800D:210058 LD HL, 5800 CALL keypress_detection 8010:CD5D80 CALL 805D ENDM ENDM End of MACRO keypress Expanding MACRO keypress port= KB_ROW_1_PORT attribute_address= ATTRIBUTE_ADR + 0020 * 0001 LD B , port 8013:06FD LD B, FD LD C , 00FE 8015:0EFE LD C, FE LD HL , attribute_address 8017:212058 LD HL, 5820 CALL keypress_detection 801A:CD5D80 CALL 805D ENDM ENDM End of MACRO keypress Expanding MACRO keypress port= KB_ROW_2_PORT attribute_address= ATTRIBUTE_ADR + 0020 * 0002 LD B , port 801D:06FB LD B, FB LD C , 00FE 801F:0EFE LD C, FE LD HL , attribute_address 8021:214058 LD HL, 5840 CALL keypress_detection 8024:CD5D80 CALL 805D ENDM ENDM End of MACRO keypress Expanding MACRO keypress port= KB_ROW_3_PORT attribute_address= ATTRIBUTE_ADR + 0020 * 0003 LD B , port 8027:06F7 LD B, F7 LD C , 00FE 8029:0EFE LD C, FE LD HL , attribute_address 802B:216058 LD HL, 5860 CALL keypress_detection 802E:CD5D80 CALL 805D ENDM ENDM End of MACRO keypress Expanding MACRO keypress port= KB_ROW_4_PORT attribute_address= ATTRIBUTE_ADR + 0020 * 0004 LD B , port 8031:06EF LD B, EF LD C , 00FE 8033:0EFE LD C, FE LD HL , attribute_address 8035:218058 LD HL, 5880 CALL keypress_detection 8038:CD5D80 CALL 805D ENDM ENDM End of MACRO keypress Expanding MACRO keypress port= KB_ROW_5_PORT attribute_address= ATTRIBUTE_ADR + 0020 * 0005 LD B , port 803B:06DF LD B, DF LD C , 00FE 803D:0EFE LD C, FE LD HL , attribute_address 803F:21A058 LD HL, 58A0 CALL keypress_detection 8042:CD5D80 CALL 805D ENDM ENDM End of MACRO keypress Expanding MACRO keypress port= KB_ROW_6_PORT attribute_address= ATTRIBUTE_ADR + 0020 * 0006 LD B , port 8045:06BF LD B, BF LD C , 00FE 8047:0EFE LD C, FE LD HL , attribute_address 8049:21C058 LD HL, 58C0 CALL keypress_detection 804C:CD5D80 CALL 805D ENDM ENDM End of MACRO keypress Expanding MACRO keypress port= KB_ROW_7_PORT attribute_address= ATTRIBUTE_ADR + 0020 * 0007 LD B , port 804F:067F LD B, 7F LD C , 00FE 8051:0EFE LD C, FE LD HL , attribute_address 8053:21E058 LD HL, 58E0 CALL keypress_detection 8056:CD5D80 CALL 805D ENDM ENDM End of MACRO keypress 8059:C30980 JP 8009 805C:C9 RET 805D: label keypress_detection 805D:ED78 IN A, (C) 805F:0605 LD B, 05 8061: label next_key 8061:CB3F SRL A 8063:3005 JR NC, 806A Expanding MACRO changeAttribute attribute= WHITE_COLOR << 0003 LD ( HL ) , attribute 8065:3638 LD (HL), 38 INC HL 8067:23 INC HL ENDM ENDM End of MACRO changeAttribute 8068:1803 JR 806D 806A: label key_pressed Expanding MACRO changeAttribute attribute= INTENSITY_BIT | ( RED_COLOR << 0003 ) LD ( HL ) , attribute 806A:3650 LD (HL), 50 INC HL 806C:23 INC HL ENDM ENDM End of MACRO changeAttribute 806D: label next 806D:10F2 DJNZ 8061 806F:C9 RET 8070: label print_string 8070:7E LD A, (HL) 8071:A7 AND A 8072:C8 RET Z 8073:D7 RST 10 8074:23 INC HL 8075:18F9 JR 8070 8077:C9 RET 8078: label keys NEW_LINE EQU 000D END_OF_STRING EQU 0000 8078:5E5A5843 DEFB of 6 bytes 807C:560D 807E:41534446 DEFB of 6 bytes 8082:470D 8084:51574552 DEFB of 6 bytes 8088:540D 808A:31323334 DEFB of 6 bytes 808E:350D 8090:30393837 DEFB of 6 bytes 8094:360D 8096:504F4955 DEFB of 6 bytes 809A:590D 809C:7F4C4B4A DEFB of 6 bytes 80A0:480D 80A2:5F604D4E DEFB of 6 bytes 80A6:4200 80A8: END 8000 Emiting TAP basic loader Emiting TAP from 8000 to 80A7
16. Problematika detekce stisku většího množství kláves
ZX Spectrum, podobně jako prakticky všechny další typy osmibitových domácích počítačů, mají (z pohledu zapojení) klávesy na klávesnici uspořádané do pravidelné mřížky, kterou jsme mohli vidět na třetím obrázku ve druhé kapitole. Vzhledem ke snaze o dosažení výhodné výrobní ceny nejsou k jednotlivým klávesám paralelně připojeny diody (což je problematické i z hlediska konstrukčního), což v praxi znamená, že stisk několika kláves může vést k tomu, že si program bude „myslet“, že jsou stlačeny i další klávesy – tomuto jevu se říká ghosting. Podívejme se na příklad:
Obrázek 19: Stisk kláves 4, 5 a V.
Na předchozím obrázku je ukázána situace, kdy jsou stlačeny klávesy 4, 5 a V. Přitom se snažíme číst informace o klávesách ze sloupce A8. To znamená, že se na horní polovinu adresní sběrnice pošlou logické hodnoty 11111110, což vede k tomu, že pouze přes diodu D6 dojde ke „stažení“ napěťové úrovně na logickou nulu. Pokud čteme hodnoty z ULA (D0-D4), bude logická nula nastavena pouze v případě, že je příslušná klávesa Caps Shift, Z, X, C či V stisknuta – potom se totiž „stáhne“ napěťová úroveň na nulu za diodou. Ovšem kvůli současnému stisku 4 a 5, tedy kláves z jiné části matrice, dojde k tomu, že stisk klávesy V ovlivní i informaci o stisku klávesy C – ta bude jakoby stlačena současně s V. Proč tomu tak je? I hodnota čtená přes KB3 bude rovna logické nule, protože došlo k elektrickému propojení obou řádků přes 4 a 5.
17. Od klávesnice k joystickům
Jak jsme si již řekli v úvodní části dnešního článku, nemusí se na ZX Spectru pro ovládání her používat pouze klávesnice. Prakticky u každé hry se setkáme i s nabídkou použití joysticku. Těch existuje několik typů, přičemž se od sebe odlišují způsobem zapojení k ZX Spectru a tím pádem i způsobem čtení jejich stavu (ovšem díky jednoduchosti HW ZX Spectra i snahou o co nejmenší cenu joysticků je čtení jejich stavu triviální). Setkáme se s de-facto standardy pojmenovanými Kempston, Interface II, Protek, Fuller, Cursor atd. (proč a jak tyto názvy vznikly, si povíme příště).
Obrázek 20: Hra Quazatron nabízející různé způsoby ovládání několika typy joysticků i s využitím klávesnice.
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 dvanácti článcích [1] [2], [3], [4], [5], [6], [7], [8], [9], [10], [11], [12], 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 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
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 | 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