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