Odpovídáte na názor k článku Ovládání hráčů ve hře klávesnicí nebo joystickem 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í.
Tady mas hned 2 varianty kdy se pouziva pro drzeni souradnic jen adresa
Prvni je delsi 91 bajtu a pouziva 8 bitovou aritmetiku. Plus prohazuje puvodni a nove souradnice pres "ex DE,HL"
ENTRY_POINT equ $8000
ATTRIBUTE_ADR equ $5800
ROM_CLS equ $0DAF
X0 equ 15
Y0 equ 10
KB_R0 equ $fe ;BC=0xFEFE ->A=...VCXZc
KB_R1 equ $fd ;BC=0xFDFE ->A=...GFDSA
KB_R2 equ $fb ;BC=0xFBFE ->A=...TREWQ
KB_R3 equ $f7 ;BC=0xF7FE ->A=...54321
KB_R4 equ $ef ;BC=0xEFFE ->A=...67890
KB_R5 equ $df ;BC=0xDFFE ->A=...YUIOP
KB_R6 equ $bf ;BC=0xBFFE ->A=...HJKLe
KB_R7 equ $7f ;BC=0x7FFE ->A=...BNMs_
Color0 equ $38
Color1 equ $48
Color2 equ $50
INIPOS equ ATTRIBUTE_ADR+32*Y0+X0
;-------------------------------------------------------------------------------
KEYB macro port
ld bc, 256*port+$fe ;adresa radku & adresa portu
in a, (c) ;vlastní čtení z portu (5 bitů)
endm
;-------------------------------------------------------------------------------
org ENTRY_POINT
start: call ROM_CLS
ld hl,INIPOS
ld (hl),Color1
;-------------------------------------------------------------------------------
main: halt
halt
KEYB KB_R3
ld d, h
ld e, l
vlevo:
rra ;1
ld c,a
jr c,vpravo
ld a,%00011111
and e
jr z,vpravo
dec e
vpravo:
rr c ;4
jr c,dolu
ld a,%11100000
or e
inc a
jr z,dolu
inc e
dolu:
rr c ;2
jr c,nahoru
; last row 0x5AE0..0x5AFF => 0101 1010 111. ....
ld a,%00011111 ;2:7
or e ;1:4
xor d ;1:4
xor ~0x5A ;2:7
jr z, nahoru ;2:7/12
ld a,%00100000 ;2:7
add a,e ;1:4
ld e,a ;1:4
adc a,d ;1:4
sub e ;1:4
ld d,a ;1:4
nahoru:
rr c ;3
jr c,palba
; first row 0x5800..0x581F => 0101 1000 000. ....
ld a,%11100000 ;2:7
and e ;1:4
xor d ;1:4
xor 0x58 ;2:7
jr z, palba ;2:7/12
ld a,e ;1:4
sub %00100000 ;2:7
ld e,a ;1:4
jr nc,palba ;2:7/12
dec d ;1:4
palba:
rr c ;5
ld a,Color1 ;klid
jr c,klid
ld a,Color2 ;palba
klid:
ld (hl),Color0
ld (de),a
ex DE,HL
jp main
;-------------------------------------------------------------------------------
end ENTRY_POINT
Druha kratsi (79 bajtu) varianta to dela pres 16 bitovou aritmetiku a kdyz to je kratsi tak 8 bitovou aritmetiku (viz "if 1"). Plus souradnice drzi jen v HL a prohazuje si to se zasobnikem.
ENTRY_POINT equ $8000
ATTRIBUTE_ADR equ $5800
ROM_CLS equ $0DAF
X0 equ 15
Y0 equ 10
KB_R0 equ $fe ;BC=0xFEFE ->A=...VCXZc
KB_R1 equ $fd ;BC=0xFDFE ->A=...GFDSA
KB_R2 equ $fb ;BC=0xFBFE ->A=...TREWQ
KB_R3 equ $f7 ;BC=0xF7FE ->A=...54321
KB_R4 equ $ef ;BC=0xEFFE ->A=...67890
KB_R5 equ $df ;BC=0xDFFE ->A=...YUIOP
KB_R6 equ $bf ;BC=0xBFFE ->A=...HJKLe
KB_R7 equ $7f ;BC=0x7FFE ->A=...BNMs_
Color0 equ $38
Color1 equ $48
Color2 equ $50
INIPOS equ ATTRIBUTE_ADR+32*Y0+X0
;-------------------------------------------------------------------------------
KEYB macro port
ld bc, 256*port+$fe ;adresa radku & adresa portu
in a, (c) ;vlastní čtení z portu (5 bitů)
endm
;-------------------------------------------------------------------------------
org ENTRY_POINT
start: call ROM_CLS
ld hl,INIPOS
ld (hl),Color1
;-------------------------------------------------------------------------------
main: halt
halt
KEYB KB_R3
push hl
ld bc, 0x0020 ;3:10 = 32
vlevo:
rra ;1
jr c,vpravo
if 1
; 31x 43 taktu, 1x 44 taktu
push af ;1:11
ld a,%00011111 ;2:7
and l ;1:4
jr z,$+3 ;2:7/12
dec l ;1:4
pop af ;1:10
else
; 50% 24 taktu, 3% 43 taktu, 47% 42 taktu
dec l ;1:4 ...0 0000-1?
bit 4,l ;2:8
jr z,vpravo ;2:7/12
inc l ;1:4 ...1 ....+1?
bit 4,l ;2:8
jr z,vpravo ;2:7/12
dec l ;1:4
endif
vpravo:
rra ;4
jr c,dolu
if 1
push af ;1:11
if 1
; o trochu rychlejsi, protoze 31x 47 taktu, 1x48 taktu
ld a,%00011111 ;2:7
inc l ;1:4
and l ;1:4
jr nz,$+3 ;2:7/12
dec l ;1:4
else
; o trochu pomalejsi, protoze 31x 48 taktu, 1x47 taktu
ld a,%11100000 ;2:7
or l ;1:4
inc a ;1:4
jr z,$+3 ;2:7/12
inc l ;1:4
endif
pop af ;1:10
else
; 50% 24 taktu, 3% 43 taktu, 47% 42 taktu
inc l ;1:4 ...1 1111+1?
bit 4,l ;2:8
jr nz,dolu ;2:7/12
dec l ;1:4 ...0 ....-1?
bit 4,l ;2:8
jr nz,dolu ;2:7/12
inc l ;1:4
endif
dolu:
rra ;2
jr c,nahoru
; last row 0x5AE0..0x5AFF => 0101 1010 111. ....
add hl,bc ;1:11 fail:0x5B ...1011; ok:0x58 ...1000,0x59 ...1001,0x5A ...1010
inc h ;1:4
bit 2,h ;2:8
jr z,nahoru-1 ;2:7/12
sbc hl,bc ;2:15
dec h ;1:4
nahoru:
rra ;3
jr c,palba
; first row 0x5800..0x581F => 0101 1000 000. ....
sbc hl,bc ;2:15 no carry! fail:0x57 ...0(1)11; ok:0x58 ...1(0)00,0x59 ...1(0)01,0x5A ...1(0)10
bit 2,h ;2:8
jr z,palba ;2:7/12
add hl,bc ;1:11
palba:
rra ;5
ld a,Color1 ;klid
jr c,klid
ld a,Color2 ;palba
klid:
ex (sp),hl ;1:19
ld (hl),Color0 ;2:10
pop hl ;1:11
ld (hl),a ;1:7
jp main
;-------------------------------------------------------------------------------
end ENTRY_POINT
Mrkni se na stranky: https://worldofspectrum.org/faq/reference/peripherals.htm pod Sinclair mas napsane:
Sinclair
The 'left' Sinclair joystick maps the joystick directions and the fire button to the 1 (left), 2 (right), 3 (down), 4 (up) and 5 (fire) keys on the ZX Spectrum keyboard, and can thus be read via port 0xf7fe;
Ty pouzivas spatne rozlozeni.
Dale:
KEYB macro port
ld c, $fe ;adresa portu
ld b, port ;adresa radku
in a, (c) ;vlastní čtení z portu (5 bitů)
endm
Muzes zkratit:
KEYB macro port
ld bc, 256*port+$fe ;adresa radku a portu
in a, (c) ;vlastní čtení z portu (5 bitů)
endm
Dale:
att_adr: ;vypocet adresy atributu 32*D+E
push bc
ld h,0
ld l,d ;Y
add hl,hl ;Y*2
add hl,hl ;Y*4
add hl,hl ;Y*8
add hl,hl ;Y*16
add hl,hl ;Y*32
ld bc, ATTRIBUTE_ADR
add hl,bc ;ADR+32*Y
ld b,0
ld c,e ;X
add hl,bc ;ADR+32*Y+X
pop bc
ret
Bych asi resil jinak, prvne me trklo ze tam 2x pouzivas konstantu nuly, kdyz to preskladas tak podruhe muzes pouzit registr obsahujici nulu.
ALe po dalsim preskladani zjistis ze ADR=0x5800
takze ADR+X udelas kdyz misto spodnich 8 bitu tam das E
att_adr: ;vypocet adresy atributu 32*D+E
push bc
ld h,0
ld l,d ;Y
add hl,hl ;Y*2
add hl,hl ;Y*4
add hl,hl ;Y*8
add hl,hl ;Y*16
add hl,hl ;Y*32
ld b, high ATTRIBUTE_ADR
ld c,e ;X
add hl,bc ;ADR+32*Y+X
pop bc
ret
slo by to zrychlit kdyz 3x zamenis "add hl,hl ;1:11" za "add a,a;1:4" ale bude to stat 1 bajt navic:
att_adr: ;vypocet adresy atributu 32*D+E
push bc
ld a,d ;Y
add a,a ;Y*2 0..+2..46
add a,a ;Y*4 0..+4..92
add a,a ;Y*8 0..+8..184
ld h,0
ld l,a ;hl=8*Y
add hl,hl ;Y*16
add hl,hl ;Y*32
ld b, high ATTRIBUTE_ADR
ld c,e ;X
add hl,bc ;ADR+32*Y+X
pop bc
ret