home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CP/M
/
CPM_CDROM.iso
/
cpm
/
debug
/
jmon100.lbr
/
JKBDST.ZZ0
/
JKBDST.Z80
Wrap
Text File
|
1988-02-16
|
6KB
|
296 lines
;
;Keyboard status
;provides label kbdst
;returns A=ASCII key,NZ else A=0,Z
;preserves all other registers
;
;MicroBee version with keyclick, fast repeat
;
;local equates
;
kbrpdly equ 28h
kbrpper equ 04h
kbcldur equ 01h
kbclper equ 24h
;
pioa equ 00h
piob equ 02h
romrd equ 0Bh
crtstat equ 0Ch
crtaddr equ 0Ch
crtdata equ 0Dh
;
lpenh equ 16
lpenl equ 17
updh equ 18
updl equ 19
clupd equ 31
;
;
kbdst: push bc
push de
push hl
;Set ROM READ
ld a,1
out (romrd),a
;
;Test if there was a previous key
ld hl,kblkey+poff
ld a,(hl)
cp 0FFh
jr z,kbnrpt ;skip if no previous key
;
;Test if previous key is still down
ld b,3Ch ;debounce delay
kbrplp: call poff+chkkey
jr z,kbrpwt ;skip if repeating
djnz kbrplp ;loop until sure not rept
jr kbscmx ;skip if not repeating
;
;Candidate for a repeating key, is it allowed to do so
kbrpwt: cp 53h ;LOCK
jr z,kbwkey
;
;Same key, so test vertical retrace state
kbsamk: ld hl,kblvrb+poff
in a,(crtstat)
and 20h
cp (hl)
jr z,kbwkey ;skip if still waiting
;
;Change in vertical retrace detected
ld (hl),a ;store current state
ld hl,kbrpcnt+poff
dec (hl) ;count down twice for each blank
jr nz,kbwkey ;skip if still waiting
;
;Key now repeating
ld (hl),kbrpper ;set up repeat period
ld a,(poff+kblkey) ;A=last key scan code
jr kbdcod
;
;Test if any key is down
kbnrpt: in a,(crtstat)
and 40h
jr z,kbnkey ;skip if no key
;
;Some key is down, scan matrix to find out which
kbscmx: ld a,lpenl ;Clear LPEN strobe
out (crtaddr),a
in a,(crtdata)
xor a ;start at matrix beginning
;
;Scan each location in keyboard matrix
kbtslp: ld b,a ;B=code
ld a,updh ;Set update reg to keyscan location
out (crtaddr),a
ld a,b
and 03h
out (crtdata),a
ld a,updl
out (crtaddr),a
ld a,b
and 0F0h
out (crtdata),a
ld a,clupd ;Clear Update strobe
out (crtaddr),a
out (crtdata),a
kbtsl1: in a,(crtstat) ;wait until update
rlca
jr nc,kbtsl1
in a,(crtstat) ;Test if LPEN strobe occurred
bit 6,a
ld a,b ;A=code
jr nz,kbgotk ;skip if got a key
add a,10h
adc a,0 ;carry to bit 0
cp 83h ;first non-key location
jp nz,kbtslp+poff ;loop for next scan
;
;No key, reset last key flag
kbnkey: ld (hl),0FFh
kbwkey: xor a ;A=0,Z
;
;Exit keyboard status
kbxt: push af
ld a,lpenl
out (crtaddr),a
in a,(crtdata)
xor a
out (romrd),a
pop af
pop hl
pop de
pop bc
ret
;
;LOCK key toggles flag
kblkky: cp (hl)
jr z,kbwkey
ld (hl),a
ld hl,kblock+poff
ld a,1
xor (hl)
ld (hl),a ;keyclick, return no code
xor a ;return A,Z
jr kbclk
;
;Test if special key
kbgotk: cp 53h ;LOCK
jr z,kblkky
;
;Calculate key scan code
call poff+chkshft
jr z,kbsh1
or 08h ;set bit 3 if shift key up
kbsh1: call poff+chkctrl
jr z,kbct1
or 04h ;set bit 2 if ctrl key up
kbct1:
;
;Store last key scan code
ld (hl),a
ld hl,kbrpcnt+poff
ld (hl),kbrpdly
;
;Decode scan matrix to ASCII
kbdcod: rrca
rrca
rrca
rrca
ld l,a ;L=last keyscancode rotr 4
and 3Fh ;A=stripped down code
cp 20h
jr c,kbalfa
cp 30h
jr c,kbnum ;else A in 30..37, GREY key
;
;Use lookup table for Grey keys
kbgrey: ld c,l ;C=flags for keys
ld hl,kbgtb0+poff
call poff+addhla
ld a,(hl)
;
;Common return endpoint
kbcom: cp 0FFh ;cause NZ to indicate key OK
;
;Click speaker, return AF
kbclk: push af
kbclp0: in a,(crtstat)
and 20h
jr z,kbclp0
ld h,kbcldur*2
kbclp1: in a,(piob)
xor 40h
out (piob),a
ld a,kbclper/2
kbclp2: dec a
jr nz,kbclp2
dec h
jr nz,kbclp1
pop af
jr kbxt
;
;Handle alphabetic keys
kbalfa: bit 6,l ;test if ctrl was pushed
jr z,kbcom ;return ctrl codes if yes
add a,60h ;lower case chars
;if non alphabetic keys, skip
cp 'a'
jr c,kbnalf
cp 'z'+1
jr nc,kbnalf
;handle caps lock on alphabetic keys
ld h,a
ld a,(poff+kblock)
or a
ld a,h
jr z,kbshky ;skip if no lock
kbswcs: xor 20h ;switch case
;if shift key pressed, switch case
kbshky: bit 7,l ;test if shift was pushed
jr nz,kbcom ;exit if no shift
xor 20h ;switch case
jr kbcom
;
;Non alphabetic keys
kbnalf: cp 7Fh ;DEL key
jr z,kbshky ;as for normal alpha keys
jr kbswcs ;switch case for [\] keys
;
;Handle numeral keys
kbnum: cp 2Ch ;don't switch case for ,./ keys
jr nc,kbpnc ;skip for punctuation keys
xor 10h ;switch case for numerals
kbpnc: bit 7,l ;test if shift was pushed
jr nz,kbcom ;skip if not pushed
xor 10h ;switch case if shift pushed
jr kbcom
;
;Lookup table for grey keys
kbgtb0 equ $-30h
db 1Bh ;ESC
db 08h ;BS
db 09h ;HT
db 0Ah ;LF
db 0Dh ;CR
db 00h ;LOCK
db 18h ;CAN
db 20h ;SP
;
;Check shift key, return Z if pressed
chkshft:push hl
ld h,0F3h
jr chkcom
;
;Check ctrl key, return Z if pressed
chkctrl:push hl
ld h,93h
jr chkcom
;
;Check keyscan code A, returns Z if keypressed
chkkey: push hl
ld h,a
;Common code
chkcom: ld l,a ;save A
;Set update reg to keyscan location
ld a,updh
out (crtaddr),a
ld a,h
and 03h
out (crtdata),a
ld a,updl
out (crtaddr),a
ld a,h
and 0F0h
out (crtdata),a
;Clear lpen flag
ld a,lpenl
out (crtaddr),a
in a,(crtdata)
;Clear update flag
ld a,clupd
out (crtaddr),a
out (crtdata),a
;Wait until update
ckwupd: in a,(crtstat)
rlca
jr nc,ckwupd
;Return NZ if no key
in a,(crtstat)
cpl
bit 6,a
;Restore A,HL
ld a,l
pop hl
ret
;
;Variable space
kblkey: db 0FFh ;last key scan code, 0FFh if no key
;bit 2=!ctrl key, bit 3=!shift key
kblock: db 0 ;0=no lock,1=caps
kblvrb: db 0 ;last vertical retrace blanking
kbrpcnt:db 1 ;repeat down counter
;
;end of include file