home *** CD-ROM | disk | FTP | other *** search
- ;
- ;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