Hlavní navigace

Práce s klávesnicí na ZX Spectru

18. 5. 2023
Doba čtení: 45 minut

Sdílet

 Autor: Depositphotos
Ukážeme si základní práci s klávesnicí ZX Spectra a seznámíme se s instrukcemi určenými pro čtení nebo zápis dat na vstupně-výstupní porty, což je z pohledu Z80 adresová oblast oddělená od prostoru pamětí ROM a RAM.

Obsah

1. Práce s klávesnicí na ZX Spectru

2. Klávesnice ZX Spectra

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

20. Odkazy na Internetu

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.

Poznámka: koncept vstupně-výstupních portů nalezneme jen u některých typů mikroprocesorů. Typicky se používá u „rodiny 8000“, tedy u čipů Intel 8008, Intel 8080, Intel 8085, Intel 8086 a samozřejmě též u Zilogu Z80. Ovšem například konkurenční čip MOS 6502 tento koncept nepoužívá, takže vstupně-výstupní zařízení jsou namapována do jediného adresního prostoru společně s pamětí (což mj. zjednodušuje instrukční soubor).

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
Poznámka: ona „kráčící nula“ je z bitové masky jasně viditelná. Teoreticky můžete vynulovat i více bitů, k čemuž se ještě vrátíme.
Poznámka: způsob zapojení kláves je ukázán na stránce http://www.kameli.net/marq/?p=2055, konkrétně na obrázku http://www.kameli.net/marq/wp-content/uploads/2012/11/membrein-visu.png.

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.

Poznámka: pokud se pracuje s operační pamětí, používá mikroprocesor pin/signál MREQ, při práci s IO porty pak signál IORQ (oba jsou negované, takže si nad těmito jmény představte symbol negace). Díky tomu je možné zcela přesně rozlišit, který čip má reagovat na adresu zapsanou na adresové sběrnici (zda ROM, RAM, ULA či nějaký další obvod).

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:

  1. Způsob přečtení stavu pětice kláves v jednom řádku
  2. Způsob detekce stisku vybrané klávesy z bitového pole
  3. 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
Poznámka: úplný zdrojový kód tohoto demonstračního příkladu najdete na adrese https://github.com/tisnik/8bit-fame/blob/master/Speccy-asm/95-keypress.asm.

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:

  1. Přečteme bitové pole obsahující stav všech pěti kláves na řádku
  2. V programové smyčce provádíme bitový posun doprava, přičemž se nejnižší bajt uloží do příznaku C
  3. Na základě obsahu příznaku C provádíme rozeskok do bloků/větví „stisknuta“/„nestistknuta“
  4. 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
Poznámka: úplný zdrojový kód tohoto demonstračního příkladu najdete na adrese https://github.com/tisnik/8bit-fame/blob/master/Speccy-asm/96-keypress-row.asm.

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
Poznámka: ve skutečnosti ne všechny kombinace kláves je možné detekovat zcela korektně a to kvůli takzvanému ghostingu, o němž se zmíníme v závěrečné části dnešního článku.

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
Poznámka: mimochodem – na tomto místě lze provést malou optimalizaci spočívající v přenosu jedné instrukce z makra do subrutiny. O jakou instrukci se jedná a proč? A jak se tato optimalizace projeví na velikosti nebo rychlosti výsledného strojového kódu vygenerovaného assemblerem?

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
Poznámka: úplný zdrojový kód tohoto demonstračního příkladu najdete na adrese https://github.com/tisnik/8bit-fame/blob/master/Speccy-asm/97-keypress-all-rows.asm.

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.

Poznámka: aby to bylo ještě napínavější, není emulace ZX Spectra dokonalá, protože běžné (neherní) klávesnice trpí buď podobným problémem nebo problémem opačným – není možné zjistit stisk většího množství kláves v jednom bloku, přičemž bloky mohou být různé. Ostatně si to sami můžete vyzkoušet – dnešní poslední demonstrační příklad velmi pravděpodobně nedonutíte k tomu, aby byly červeně zvýrazněny všechny klávesy (většinou nepůjde detekovat stisk více než zhruba 3–5 kláves; výjimkou bývají Shifty a podobné přeřaďovače). Nebo si můžete toto chování otestovat zde.

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.

CS24_early

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

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

Byl pro vás článek přínosný?

Autor článku

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