Odpověď na názor

Odpovídáte na názor k článku Práce s klávesnicí na ZX Spectru. Názory mohou přidávat pouze registrovaní uživatelé. Nově přidané názory se na webu objeví až po schválení redakcí.

  • Článek je starý, nové názory již nelze přidávat.
  • 21. 5. 2023 2:04

    xbastaj

    Zkusil jsem si napsat podprogram pro získání kodu klavesy. V akumulátoru je vrácen poziční kod - není to nijak zvlášt optimalizované. Formát je 5 bitů sloupec a 3 bity číslo řádku.

    keyb:   push bc             ;A - kod klavesy
            push de
            ld d,8              ;pocitadlo radku
            ld c,0xF0           ;adresa portu
            ld b,0xFE           ;adresa prvniho radku
    
    keyb01: in a,(c)            ;nacteni portu
            cpl                 ;negace
            and 0x1F            ;nastaveni hornich bitu
            jp nz,keyb02        ;je stisknuta
    
            ld a,b              ;adresa dalsiho radku
            rla
            ld b,a
            dec d               ;pocitadlo radku
            jp nz,keyb01        ;dalsi radek
            pop de
            pop bc
            ret                 ;neni stisknuta zadna (A=00)
    
    keyb02: rla                 ;nalezena prvni stisknuta klavesa
            rla                 ;posun o 3 bity
            rla
            dec d
            add a,d             ;pricteni cisla radku
            pop de
            pop bc
            ret                 ;stisknuta klavesa (A=sssssrrr)

    Pro otestovvání kodů klaves jsem využil "print_hex_number"

    ENTRY_POINT      equ $8000
    ROM_OPEN_CHANNEL equ $1601
    
    AT               equ $16
    ;-------------------------------------------------------------------------------
    GOTO_XY macro X,Y
            ld   A, AT            ; řídicí kód pro specifikaci pozice psaní
            rst  0x10             ; zavolání rutiny v ROM
            ld   A, Y             ; y-ová souřadnice
            rst  0x10             ; zavolání rutiny v ROM
            ld   A, X             ; x-ová souřadnice
            rst  0x10             ; zavolání rutiny v ROM
     endm
    ;-------------------------------------------------------------------------------
    ZNAK_XY macro X,Y,kod
            ld   A, AT            ; řídicí kód pro specifikaci pozice psaní
            rst  0x10             ; zavolání rutiny v ROM
            ld   A, Y             ; y-ová souřadnice
            rst  0x10             ; zavolání rutiny v ROM
            ld   A, X             ; x-ová souřadnice
            rst  0x10             ; zavolání rutiny v ROM
            ld   A, kod           ; kód znaku '*' pro tisk
            rst  0x10             ; zavolání rutiny v ROM
     endm
    ;-------------------------------------------------------------------------------
    
            org ENTRY_POINT
    
    start:
            ld   A,2              ; číslo kanálu
            call ROM_OPEN_CHANNEL ; otevření kanálu číslo 2 (screen)
    
    main:   GOTO_XY 5,5
    
            call keyb
            call print_hex_number
    
            jp main
    
    ;-------------------------------------------------------------------------------
    
    keyb:   push bc             ;A - kod klavesy
            push de
            ld d,8              ;pocitadlo radku
            ld c,0xF0           ;adresa portu
            ld b,0xFE           ;adresa prvniho radku
    
    keyb01: in a,(c)            ;nacteni portu
            cpl                 ;negace
            and 0x1F            ;nastaveni hornich bitu
            jp nz,keyb02        ;je stisknuta
    
            ld a,b              ;adresa dalsiho radku
            rla
            ld b,a
            dec d               ;pocitadlo radku
            jp nz,keyb01        ;dalsi radek
            pop de
            pop bc
            ret                 ;neni stisknuta zadna (A=00)
    
    keyb02: rla                 ;nalezena prvni stisknuta klavesa
            rla                 ;posun o 3 bity
            rla
            dec d
            add a,d             ;pricteni cisla radku
            pop de
            pop bc
            ret                 ;stisknuta klavesa (A=sssssrrr)
    ;-------------------------------------------------------------------------------
    
    print_hex_number:
            push AF             ; uschovat A pro pozdější využití
            rrca                ; rotace o čtyři bity doprava
            rrca
            rrca
            rrca
            and  $0f            ; zamaskovat horní čtyři bity
            call print_hex_digit; vytisknout hexa číslici
    
            pop  AF             ; obnovit A
            and  $0f            ; zamaskovat horní čtyři bity
            call print_hex_digit; vytisknout hexa číslici
            ret                 ; a návrat z podprogramu
    ;-------------------------------------------------------------------------------
    print_hex_digit:
            cp   0x0a           ; test, jestli je číslice menší než 10
            jr c, print_0_to_9  ; ok, hodnota je menší než 10, budeme tedy tisknout desítkovou číslici
            add  A, 65-10-48    ; ASCII kód znaku 'A', ovšem začínáme od desítky, ne od nuly (+ update pro další ADD)
    print_0_to_9:
            add  A, 48          ; ASCII kód znaku '0'
            rst  0x10           ; zavolání rutiny v ROM pro tisk jednoho znaku
            ret                 ; návrat ze subrutiny
    ;-------------------------------------------------------------------------------
    
    end ENTRY_POINT

    No a ještě jeden program: klávesy E, S, D, X pohybují znakem po obrazovce

    ENTRY_POINT      equ $8000
    ROM_OPEN_CHANNEL equ $1601
    ROM_CLS          equ $0DAF
    
    AT               equ $16
    X0               equ 15
    Y0               equ 10
    XMIN             equ 0
    XMAX             equ 31
    YMIN             equ 0
    YMAX             equ 21
    ZNAK             equ "#"
    MEZERA           equ " "
    ;-------------------------------------------------------------------------------
    GOTO_XY macro X,Y
            ld   A, AT            ; řídicí kód pro specifikaci pozice psaní
            rst  0x10             ; zavolání rutiny v ROM
            ld   A, Y             ; y-ová souřadnice
            rst  0x10             ; zavolání rutiny v ROM
            ld   A, X             ; x-ová souřadnice
            rst  0x10             ; zavolání rutiny v ROM
     endm
    ;-------------------------------------------------------------------------------
    ZNAK_XY macro X,Y,kod
            ld   A, AT            ; řídicí kód pro specifikaci pozice psaní
            rst  0x10             ; zavolání rutiny v ROM
            ld   A, Y             ; y-ová souřadnice
            rst  0x10             ; zavolání rutiny v ROM
            ld   A, X             ; x-ová souřadnice
            rst  0x10             ; zavolání rutiny v ROM
            ld   A, kod           ; kód znaku '*' pro tisk
            rst  0x10             ; zavolání rutiny v ROM
     endm
    ;-------------------------------------------------------------------------------
    
            org ENTRY_POINT
    
    start:  call ROM_CLS
    
            ld h,X0               ;pocatecni nastaveni X,Y
            ld l,Y0
            ZNAK_XY h,l,ZNAK
    
    main:   call delay
    m01:    call keyb
    
            cp 0x26
            call z,vpravo
            cp 0x16
            call z,vlevo
            cp 0x25
            call z,nahoru
            cp 0x27
            call z,dolu
    
            jp main
    
    ;-------------------------------------------------------------------------------
    
    keyb:   push bc             ;A - kod klavesy
            push de
            ld d,8              ;pocitadlo radku
            ld c,0xF0           ;adresa portu
            ld b,0xFE           ;adresa prvniho radku
    
    keyb01: in a,(c)            ;nacteni portu
            cpl                 ;negace
            and 0x1F            ;nastaveni hornich bitu
            jp nz,keyb02        ;je stisknuta
    
            ld a,b              ;adresa dalsiho radku
            rla
            ld b,a
            dec d               ;pocitadlo radku
            jp nz,keyb01        ;dalsi radek
            pop de
            pop bc
            ret                 ;neni stisknuta zadna (A=00)
    
    keyb02: rla                 ;nalezena prvni stisknuta klavesa
            rla                 ;posun o 3 bity
            rla
            dec d
            add a,d             ;pricteni cisla radku
            pop de
            pop bc
            ret                 ;stisknuta klavesa (A=sssssrrr)
    ;-------------------------------------------------------------------------------
    vpravo:
            ZNAK_XY h,l,MEZERA
            ld a,h
            cp XMAX
            jr Z,vp0
            inc h
    vp0:    ZNAK_XY h,l,ZNAK
            ret
    
    ;-------------------------------------------------------------------------------
    vlevo:
            ZNAK_XY h,l,MEZERA
            ld a,h
            cp XMIN
            jr Z,vl0
            dec h
    vl0:    ZNAK_XY h,l,ZNAK
            ret
    
    ;-------------------------------------------------------------------------------
    dolu:
            ZNAK_XY h,l,MEZERA
            ld a,l
            cp YMAX
            jr Z,do0
            inc l
    do0:    ZNAK_XY h,l,ZNAK
            ret
    
    ;-------------------------------------------------------------------------------
    nahoru:
            ZNAK_XY h,l,MEZERA
            ld a,l
            cp YMIN
            jr Z,na0
            dec l
    na0:    ZNAK_XY h,l,ZNAK
            ret
    
    ;-------------------------------------------------------------------------------
    delay:  push bc
            push de
            ld d,40
            ld e,0
    d01:    dec e
            jr nz, d01
            dec d
            jr nz, d01
            pop de
            pop bc
            ret
    
    end ENTRY_POINT