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