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í.
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+fire. 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...