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.