Použití ROMky nebo její obšlehnutí není jedniný způsob, jak testovat klávesy.
Bystřejší oko jistě uvidělo v rutině KEY SCAN instrukci na čtení portu in. Takže všechno popořadě. Podívejte na rozložení kláves na gumídkovi. Vidíte, že klávesy jsou rozloženy do 4 řad po 10 klávesách. Každou řadu ještě rozpůlíme a máme 8×5 kláves. Každá půlřada má vlastní port, na který je připojena a každá klávesa pak svůj bit. Naznačí podrobná tabulka:
Adresa portu bity
vyšší bajt binární úplná 0 1 2 3 4
---------------------------------------------
254 11111110 65278 CSH Z X C V
253 11111101 65022 A S D F G
251 11111011 64510 Q W E R T
247 11110111 63486 1 2 3 4 5
239 11101111 61438 0 9 8 7 6
223 11011111 57342 P O I U Y
191 10111111 49150 ENT L K J H
127 01111111 32766 SPC SSH M N B
Nižší bajt je vždy 254, takže stačí spočítat ještě vyšší bajt z tabulky a dostaneme celou adresu portu. Stištěná klávesa je indikovaná hodnotou 0 na příslušném bitu, ostatní bity jsou nastaveny na 1. Adresovat port můžeme několika způsoby:
úplnou adresou v registru bc:
ld bc,32766
in a,(c)
nebo čtením portu nastaveného v registru a a čísle:
ld a,127
in a,(254)
Oba tyto způsoby nám načtou aktuální stav kláves od mezerníku do B. Další zpracování stisku je už vysloveně banalitka, na to stačí testovací intrukce bit x,a pro jednu klávesu, nebo and %bin pro testování určité kombinace nebo pro testování postupně celé řady rra:
LOOP ld a,247 ;rada 1-5
in a,(254) ;nacti
rra ;presun bit 0 do carry
jr nc,AKCE1 ;skok pro akci na klavese 1
rra ;presun bit 1 do carry
jr nc,AKCE2 ;skok pro akci na klavese 2
rra ;presun bit 2 do carry
jr nc,AKCE3 ;skok pro akci na klavese 3
rra ;presun bit 3 do carry
jr nc,AKCE4 ;skok pro akci na klavese 4
rra ;presun bitu 4
jr c,LOOP ;ani posledni klavesa neni?
AKCE5 ...
V následující ukázce si přiblížíme, jak by se dala udělat definice ovládání. Nejprve je zavolána definice a pak test, jestli to dobře funguje. Rutina TESTPORT čte všechny klávesové porty a testuje, je-li nějaká klávesa stištěna. Pak následuje další port. Pokud jste se dívali pozorně do tabulky, je vám asi jasné, že přechod na „další“ port je velice jednoduchý, stačí jen zarotovat vyšším bajtem portu.
Zde je taky použita rutina z ROM: $D6B. Je to podprogram CLS. Význam dalších rutin podle mě není třeba vysvětlovat
cpu z80undoc
relaxed on
org 25000
START
call DEFINICE ;zavolej definici ovladani
call RUTINA ;zavolej rutinu na test nastaveni klaves
ret
DEFINICE call $D6B ;proved CLS
ld hl,16384+10 ;nastav pozici
ld (POZICE),hl ;pro prvni vypis textu
ld a,(23695) ;nastav barvu textu na tu samou
ld (COLOR),a ;jako v Basicu
ld b,5 ;celkem 5 klaves
ld hl,TEXTY ;adresa textu
ld de,NAHORU ;adresa tabulky s nadefinovanimy klavesami
LOOP1 push bc ;uloz pocitadlo
call TEXTOUT ;vytiskni text
call KLAVESA ;cekej na klavesu
ex af,af' ;uloz vystup z rutiny
ld a,c ;nizsi bajt portu
ld (de),a ;uloz do tabulky
inc de ;posun se
ld a,b ;vyssi bajt
ld (de),a ;uloz do tabulky
inc de ;posun se
ex af,af' ;obnov masku stisknute klavesy
ld (de),a ;uloz do tabulky
inc de ;posun se
inc de ;a preskoc 2 byty
inc de
call DOWN ;posun vypis textu o radek dolu
pop bc ;obnov pocitadlo
djnz LOOP1 ;smycka
ret
KLAVESA call TESTPORT ;testuj klavesnici
jr c,KLAVESA ;neni zadna, smycka
push bc ;uloz port
push af ;uloz masku
ld a,'x' ;znak "x"
call ZNAK ;vypis
WAIT call TESTPORT ;cekej na uvolneni klavesy
jr nc,WAIT ;neni, cekej
call DELAY ;mala pauza
pop af ;obnov masku
pop bc ;obnov port
ret ;navrat
TEXTY db "Nahoru",':'+128
db "Dolu",':'+128
db "Vlevo",':'+128
db "Vpravo",':'+128
db "Strelba",':'+128
;program na test libovolne klavesy, v BC vraci port a v A masku stistene klavesy
TESTPORT ld bc,$FEFE ;zacni s timto portem
TESTPOR1 in a,(c) ;nacti jej
cpl ;obrat vsechny biti v A
and %11111 ;ponech pouze ty platne
ret nz ;pokud bylo neco stisknuto, v a bude nastaven
;bit, ktery prislusi dane klavese a v BC
;pak port
rlc b ;zarotuj vyssim bajtem portu (viz tabulka)
jr c,TESTPOR1 ;dokud vystupuji do carry jednicky opakuj
scf ;jinak nastav carry pro dalsi zpracovani
ret
DELAY ld bc,5255 ;zpozdovaci smycka
DELAY1 ex (sp),hl ;tato instrukce trva 19T
ex (sp),hl ;a dve za sebou jsou neskodne
dec bc ;sniz pocitadlo
inc b ;zvys kvuli nasledujici intrukci
djnz DELAY1 ;opakuj, dokud bc=255
ret
DOWN push de ;posune POZICI o radek nize
ld de,(POZICE)
ld a,e
and %11100000
add a,32+10 ;na 10 sloupec
ld e,a
jr nz,DOWN_1
ld e,a
ld a,d
add a,8
ld d,a
cp 88
jr c,DOWN_1
ld d,64
DOWN_1 ld (POZICE),de
pop de
ret
;tabulka nadefinovanych klaves, masek a skoku
NAHORU dw $FEFE ;prvni je port klavesy
db 1 ;druhy je maska klavesy
dw JP_UP ;a treti adresa rutiny, ktera se o to postara
DOLU dw $FEFE ;pro smer dolu
db 1
dw JP_DOWN
VLEVO dw $FEFE ;vlevo
db 1
dw JP_LEFT
VPRAVO dw $FEFE ;vpravo
db 1
dw JP_RIGHT
OHEN dw $FEFE ;strelba
db 1
dw JP_FIRE
;tato rutina otestuje nastaveni klaves a spravnost tabulky
RUTINA ld hl,NAHORU ;zacatek tabulky
ld b,5 ;celkem 5 klaves
RUTINALP push bc ;uloz pocitadlo smycek
ld c,(hl) ;nacti z tabulky
inc hl ;hodnotu
ld b,(hl) ;portu
inc hl ;do BC
in a,(c) ;test portu
and (hl) ;vynech vsechny bity krome zadane (maska)
inc hl ;posun se v tabulce na adresu skoku
jr nz,RUTINAJP ;klavesa nesouhlasi, skoc
pop bc ;obnov pocitadlo
ld a,(hl) ;nacti nizsi bajt do A
inc hl ;posun se
ld h,(hl) ;nacti vyssi bajt do H
ld l,a ;a pak nizsi bajt do L
jp (hl) ;a skoc na rutinu, ktera patri ke klavese
RUTINAJP inc hl ;preskoc adresu skoku
pop bc ;vyzvedni pocitadlo
djnz RUTINALP ;smycka
ld a,' ' ;vypis mezeru (nic nestisteno)
call SET_POS ;nastav pozici a vypis
jr RUTINA ;a zpet do rutiny
JP_UP ld a,'^' ;znak "nahoru"
db 33 ;zrus vyznam nasledujicich 2 bajtu (ld a,n)
JP_DOWN ld a,'|' ;stane se z nej neskodne ld hl,nn
db 33
JP_LEFT ld a,'>'
db 33
JP_RIGHT ld a,'<'
call SET_POS ;nastav pozici a vypis znak
jr RUTINA ;a vrat se do rutiny
JP_FIRE ld a,'.' ;fire se chova podobne
jp SET_POS ;jen ukonci cely podprogram rutina
SET_POS ld hl,$4850 ;nastav pozici kdesi
ld (POZICE),hl ;uprosred obarzovky
jr ZNAK ;a vypis znak
include textout.a80 ;inkludni zdrojak jiz hotovy
Ještě zalistujeme do knihy a opíšeme jednu krátkou, ale dobrou rutinu. Bude to rutina na čekání na libovolnou klávesu:
WAITKEY xor a ;nuluj akumulator
in a,(254) ;nacti port klavesnice
cpl ;otoc bity v akumulatoru
and %11111 ;testuj pouze 5 bitu
jr z,WAITKEY ;zadna stistena, cekej dal
ret
Pokud je v horním bajtu portu klávesnice hodnota 0, testují se najednou všechny klávesové řady. Každý bit vlatně reprezentuje celý sloupec. Je-li alepoň jedna klávesa stištěna, její bit bude nastaven na 0, cpl obrátí hodnoty bitů, takže 1. and vynechá nepoužité 3 bity.
Stažení: 7dil.zip – zdrojový text
Je nám líto, ale formulář pro přidávání komentářů je momentálně uzavřen.