Úno 182005
 

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.