SUBTTL Krmilnik Tipkovnice (RPKEY.ASM) v1.1,(C)26.11.90 OLEO
TITLE REKLAMNI PANEL
.Z80 ;Procesor je Z80A (Z8400)
.XLIST
IF1
INCLUDE RPFNAMES.ASI
INCLUDE RP.ASI
ENDIF
.LIST
.SALL
PUBLIC EN_NMI
PUBLIC KEY
PUBLIC RSTXT
PUBLIC ISBRK
;Resetira XT tipkovnico, ~e je KCLK low ve~ kot 20ms
RSTXT: CLRP1 KCLKD
ld a,60 ;60*0.5ms=30ms (min)
rstxt0: ld b,154 ;500 us je
djnz $
rst CLRWDT
dec a
jr nz,rstxt0
SETP1 KCLKD
CLRP1 KDATAD
xor a ;nastavi status tipkovnice
ld (KEYSTOGGLE),a
ld (KEYSDOWN),a
call SCANXT ;ugotovi ali se tipkovnica odziva
ret ;CY=1 ~e ni odziva, A=0AAh ~e je OK
;Bere tipko po XT protokolu
;Vhod: ni~
;Izhod: A=scan coda in CY=0 ~e je koda pravilna
; CY=1 ~e scan koda ni na voljo
;Ne uporablja H,L in E registrov
SCANXT: rst CLRWDT
ld c,0 ;c register hrani sprejeti byte
ld b,5
halt ;~akaj zdaj, da ne bo nepotrebne prekinitve
SETP1 KDATAD ;omogo~i sprejem podatkov
sxt0: TSTBIT KDATA,P1 ;~akaj na start bit - 1
jr nz,sxt11
djnz sxt0
CLRP1 KDATAD
scf ;pri`gi CY ~e ni nobene kode na voljo
ret
sxt11: di ; kakor tudi ostale prekinitve
sxt1: TSTBIT KCLK,P1 ; - 2
jr z,sxt1
ld b,21 ;~akaj na D0 bit - 3, a ne ve~ kot 200us
sxt2: TSTBIT KCLK,P1 ;11+7=18T ;NMI ni za pri~akovati v tem ~asu, ker
jr z,sxt89 ;7T/12T ;smo `e prej dovolj ~akali (HALT)
djnz sxt2 ;8T/13T ;; 18+7+13=38T -> 1 loop = 9.5us
CLRP1 KDATAD ; TIME OVERRUN, zato blokiraj tipkovnico
ei ;proces je sedaj lahko prekinjen
scf ;data not available
ret ;zato se vrni
sxt89: ld a,(P1OUTMASK); izklju~i NMI
or NMIEN
out (P1),a
ld(P1OUTMASK),a
sxt8: TSTBIT KCLK,P1 ; - 2
jr z,sxt8
sxt9: TSTBIT KCLK,P1 ;~akaj na D0 bit - 3
jr nz,sxt9
sxt3: TSTBIT KCLK,P1 ; - 4
jr z,sxt3
ld b,8 ; pri~akujem 8 bitov podatkov
sxt4: TSTBIT KDATA,P1 ; berem podatek s tipkovnice
ld d,a ; shranim Kdata v D
TSTBIT KCLK,P1
jr nz,sxt4
or d ;A je bil 0
jr z,sxt5
scf ;~e je KDATA mark pri`gi CY
sxt5: rr c ;zapi{em najprej D0 nato ponovim
sxt6: TSTBIT KCLK,P1
jr z,sxt6 ;~akaj spet na naslednji bit
djnz sxt4
CLRP1 KDATAD ;blokiraj tipkovnico
call EN_NMI ;omogo~i NMI prekinitve
ei ;proces
ld a,c ;A vsebuje scan kodo
and a ;bri{i CY
ret
;vklju~i NMI prekinitve in ohrani vse registre
EN_NMI: push bc ;shrani BC
push af ;kakor tudi AF
ld a,(P1OUTMASK)
and NOT NMIEN
ld (P1OUTMASK),a ;`e prej nastavi masko
ld b,a
ld c, P1
nmiwa: in a, (c) ;12T ;~akaj na INT1
and INT1 ;7T
jr z, nmiwa ;12/7T, suma:26T=6.5us pri 4MHz
out (c),b ;potrebno je samo {e vklju~iti NMI
pop af ;obnovi registre
pop bc
ret
;konverzija scan kode v ascii
SCC MACRO code, stb ;;Scan Code Check uporablja AF
LOCAL skip1, skip2
cp code
rst CLRWDT
jr nz, skip1
set stb,(IY+KEYSDOWN-RAMSTART)
scf
rst CLRWDT
ret
skip1:
cp code OR 80h
rst CLRWDT
jr nz, skip2
res stb,(IY+KEYSDOWN-RAMSTART)
rst CLRWDT
scf
ret
skip2:
rst CLRWDT
ENDM
SCT MACRO code, stb ;;Scan Code Toggle uporablja AF
LOCAL skip1, skip2, skt0, skt1, skt2
cp code
rst CLRWDT
jr nz, skip1
bit stb,(IY+KEYSDOWN-RAMSTART)
jr nz,skt0
bit stb,(IY+KEYSTOGGLE-RAMSTART)
jr nz,skt1
res stb,(IY+KEYSTOGGLE-RAMSTART)
jr skt2
skt1:
set stb,(IY+KEYSTOGGLE-RAMSTART)
skt2:
set stb,(IY+KEYSDOWN-RAMSTART)
skt0:
scf
rst CLRWDT
ret
skip1:
cp code OR 80h
rst CLRWDT
jr nz, skip2
res stb,(IY+KEYSDOWN-RAMSTART)
rst CLRWDT
scf
ret
skip2:
rst CLRWDT
ENDM
;Konverzija scan code v ascii
;vhod A=scan code
;izhod: A=ASCI(SCANCODE), C=scan code in CY=0 ~e je uspe{na konverzija
; A=0 ~e je tipka specialna (F1..F10, Ins, ...)
; CY=1 ~e je konverzija neuspe{na (Break, Num, Shift ...)
;uporablja AF,BC,HL
SCASC:
SCC 36h,0 ;Right shift
SCC 2Ah,1 ;Left shift
SCC 1Dh,2 ;Ctrl
SCC 38h,3 ;Alt
SCT 46h,4 ;Scroll Lock
SCT 45h,5 ;Num Lock
SCT 3Ah,6 ;Caps Lock
SCT 52h,7 ;Ins
bit 7,a
jr z,scasc2 ;~e je make scan koda sko~i
scf ;pri`gi CY ~e je bila break koda
ret ; in se vrni
scasc2:
cp 03Ah ;ali je koda>3A
jr c,scasc3 ;sko~i ~e ni ve~ja
xor a ;sicer A=0
and a ; ?
ret
scasc3: ld b,0 ;BC pove koliko je offseta
ld c,a ;v tabeli scan kod
ld a,(KEYSDOWN) ;~e je shift pritisnjen
and 3
jr z,scasc0 ;potem
ld hl,XTSCTS ;je kazalec na tabelo s shiftom
jr scasc1
scasc0: ld hl,XTSCT ;sicer je brez shifta
scasc1: add hl,bc ;pri{tejem offset in
ld a,(hl) ;`e dobim asci kodo tipke
and a ;bri{i CY
ret
XTSCT: ;tabela brez SHIFTA
DEFM " 1234567890-=" ;prva vrsta
DEFB 00,00 ;BS in TAB
DEFM "qwertyuiop{|" ;druga vrsta
DEFB 00,00 ;CR,CTRL
DEFM "asdfghjkl~}#"
DEFB 00 ;2A=lshift
DEFM "`zxcvbnm,./"
DEFB 00,00,00,32,00 ;Rshift,prtsc,alt,spc,caps
XTSCTS: ;tabela s SHIFTOM
DEFM " !"">$%^&*()_+" ;prva vrsta
DEFB 00,00 ;BS in TAB
DEFM "QWERTYUIOP[\" ;druga vrsta
DEFB 13,00 ;CR,CTRL
DEFM "ASDFGHJKL^]<"
DEFB 00 ;2A=lshift
DEFM "@ZXCVBNM;:?"
DEFB 00,00,00,32,00 ;Rshift,prtsc,alt,spc,caps
;Skanira tipkovnico
;Vhod: ni~
;Izhod: A=ASCII koda, C=scan code, CY=0 ali CY=1 ~e koda ni na voljo
;
KEY: call SCANXT ;beri tipkovnico
ret c
call SCASC
ret
;Skanira tipkovnico in ~e je bila pritisnjena BREAK tipka
;vrne CY=0 ~e je bila pritisnjena tipka BREAK
ISBRK: push hl
call KEY
pop hl
ret c
iskey: jr nz,isbrk
ld a,c
cp 044h ;ali je pritisnjen break (F10)
jr nz, isbrk ;ponovi, ker ni bila prava koda
and a ;bri{i CY
ret
KTST::
call RSTXT
IF 1
ktst1: call SCANXT
jr c,ktst1
call SCASC
jr c,ktst1
VBIOS POAASC
DB NUL
jr ktst1
ELSE
ktst2: call KEY
jr c,ktst2
ld a,c
VBIOS POAHEX
DB NUL
jr ktst2
ENDIF
END