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.
  • 23. 5. 2023 3:00

    _dw

    Ta keyb rutina jde napsat mnohem kratsi

    ;-------------------------------------------------------------------------------
    
    keyb:   push bc             ;A - kod klavesy
            push de
            ld d,7              ;pocitadlo radku
            ld bc,0xFEF0        ;adresa prvniho radku & adresa portu
    
    keyb01: in a,(c)            ;nacteni portu
            cpl                 ;negace
            add a,a             ;posun o 3 bity
            add a,a
            add a,a
            jp nz,keyb02        ;je stisknuta
    
            dec d               ;pocitadlo radku
            rl b                ; 0xFE->FD->FB->F7->EF->DF->BF->7F
            jp  c,keyb01        ;dalsi radek
            ld  d,a             ;neni stisknuta zadna (D=A=00)
    
    keyb02: add a,d             ;pricteni cisla radku
            pop de
            pop bc
            ret                 ;stisknuta klavesa (A=sssssrrr)

    A u toho CASE vetveni ktera klavesa je stiskla muzes usetrit taky nejake bajty kdyz mas rozdily mezi vetvemi nekdy jedna.

    Misto:

    cp 0x26
    call z,vpravo
    cp 0x16
    call z,vlevo
    cp 0x25
    call z,nahoru
    cp 0x27
    call z,dolu

    To napis:

    sub 0x16
    call z,vlevo         ; 0x16
    cp 0x25-0x16
    call z,nahoru        ; 0x25
    dec a
    call z,vpravo        ; 0x26
    dec a
    call z,dolu          ; 0x27

    Ale mas tam chybu, ze v tech podrutinach prepisujes registr A. Takze ti to funguje jen nahodou.

    Kdyz se nad tim zamyslis, tak ten zpusob cteni klavesnice neni idealni. Protoze najdes prvni stisklou klavesu a ukoncis cteni klavesnice, ale ty pro tu hru spis potrebujes zjistit i vic klaves, napriklad nahoru+doprava+fi­re. Takze bud nejake 40 bitove pole a nebo jeste lepe pro kazdou konkretni klavesu mit znovu cteni. Mas tam 4 az 5 klaves.

    Nejak takto treba na 110 bajtu (z puvodnich 203):

    ENTRY_POINT      equ $8000
    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 " "
    
    
            org ENTRY_POINT
    
    start:  call ROM_CLS
    
            ld hl,256*X0+Y0       ;pocatecni nastaveni X,Y
            ld de,ZNAK*257        ;D=E=znak
            call print_yx_hl_e
    main:   halt
            halt
    
            ld bc,0xFB02     ; Q
            call checkpress
            call nz,nahoru
    
            ld b,0xFD        ; A, C=0x02
            call checkpress
            call nz,dolu
    
            ld bc,0xDF04     ; O
            call checkpress
            call nz,vlevo
    
            ld c,0x02        ; P, B=0xEF
            call checkpress
            call nz,vpravo
    
            jr main
    
    ;-------------------------------------------------------------------------------
    
    ;in:
    ;B=0x7F C= ..BNMs_.
    ;B=0xBF C= ..HJKLe.
    ;B=0xDF C= ..YUIOP.
    ;B=0xEF C= ..67890.
    ;B=0xF7 C= ..54321.
    ;B=0xFB C= ..TREWQ.
    ;B=0xFD C= ..GFDSA.
    ;B=0xFE C= ..VCXZc.
    
    ;out: nz=press
    checkpress:
            in a,(c)            ;nacteni portu
            cpl                 ;negace
            add a,a             ;posun o 3 bity
            and c
            ret
    ;-------------------------------------------------------------------------------
    
    vpravo:
            ld a,h
            cp XMAX
            ret Z
            call print_yx_hl_space
            inc h
            ld e,d
            jr print_yx_hl_e
    
    ;-------------------------------------------------------------------------------
    vlevo:
      if (XMIN=0)
            inc h
            dec h
      else
            ld a,h
            cp XMIN
      endif
            ret Z
            call print_yx_hl_space
            dec h
            ld e,d
            jr print_yx_hl_e
    
    ;-------------------------------------------------------------------------------
    dolu:
            ld a,l
            cp YMAX
            ret Z
            call print_yx_hl_space
            inc l
            ld e,d
            jr print_yx_hl_e
    
    ;-------------------------------------------------------------------------------
    nahoru:
      if (XMIN=0)
            inc l
            dec l
      else
            ld a,l
            cp YMIN
      endif
            ret Z
            call print_yx_hl_space
            dec l
            ld e,d
            jr print_yx_hl_e
    
    ;-------------------------------------------------------------------------------
    print_yx_hl_space:
            ld   E,' '            ; 1e20
    print_yx_hl_e:
            ld   A, AT            ; řídicí kód pro specifikaci pozice psaní
            rst  0x10             ; zavolání rutiny v ROM
            ld   A, L             ; y-ová souřadnice
            rst  0x10             ; zavolání rutiny v ROM
            ld   A, H             ; x-ová souřadnice
            rst  0x10             ; zavolání rutiny v ROM
            ld   A, E             ; kód znaku '*' pro tisk
            rst  0x10             ; zavolání rutiny v ROM
            ret
    
    ;-------------------------------------------------------------------------------
    
    end ENTRY_POINT

    PS: Ja zase pouzivam v C masku klavesy co chci tisknout vynasobenou dvema. V emulatorou to funguje, ale na realnem ZX netusim... Z toho obrazku obvodu a ze jsou pri nejakych kombinacich vyvolany duchove je uz mimo muj level. Proste HW...