Here is the 1st half of the KBmain module, which is responsible for the keyboard keyscan-to-ascii decoding process.
The KBmain Module Part A:
More to come <img src="http://www.picbasic.co.uk/forum/images/icons/icon2.gif"> Installment #3b: KBmain module (2nd half)Code:;=============================================================================== ; modstart_keybd - Initialization Entry Point for Keyboard Decoding Module. ;=============================================================================== modstart_KBinit: Input KBCLK ' set-up keyboard clock Input KBDAT ' and keyboard data lines as digital inputs. KB_timeout = 0 ' initialize some registers... KBcnt = 0 ' No attempt will be made to reset the keyboard as it ' would still be in POST or BAT tests if power were ' applied at the same time as the PIC. ;=============================================================================== ; rstflag - Resets Status and LED Flags. ;=============================================================================== rstflag: keystat = 0 LED = 0 Goto LEDshow ;=============================================================================== ; KBmain - Main Entry Point for Keyboard Decoding Module. ;=============================================================================== KBmain: If KBindxO = KBindxI Then KBexit ' if key buffer is empty then exit ' update combined shift/ctrl/alt registers from individual registers If Lshift = 1 or Rshift =1 Then shift = 1 Else Shift = 0 Endif If L_ctrl = 1 or R_ctrl =1 Then ctrl = 1 Else ctrl = 0 Endif If L_alt = 1 or R_alt =1 Then alt = 1 Else alt = 0 Endif ' check to see if this is a key coming up If KBrelease = 1 Then release ' release code previously sent If KBextend = 1 Then extend ' extended code previously sent If KBrelextend = 1 Then rel_ext ' ext/release code previously sent ' go get keyboard byte from ring buffer for interpretation Gosub getbuf ' check for special codes Select Case scancode Case $F0 ' key has been released KBrelease = 1 Goto KBexit Case $FE ' key resend requested Gosub putkey Goto kbmain Case $FF ' keyboard error Gosub putkey Goto rstflag Case $AA ' successful completion of BAT Goto rstflag Case $E0 ' Extended key pressed KBextend = 1 Goto KBexit Case $29 ' Space bar pressed ascii = $20 Goto dec_done Case $0D ' Tab key pressed ascii = $09 Goto dec_done Case $66 ' Backspace key pressed ascii = $08 Goto dec_done Case $5A ' Enter key pressed ascii = $0D Goto dec_done Case $12 ' Left shift key pressed Lshift = 1 Case $59 ' Right shift key pressed Rshift = 1 Case $14 ' Left Ctrl key pressed L_ctrl = 1 Case $11 ' Left Alt key pressed L_alt = 1 Case $58 ' Caps lock key pressed If pcaplck = 0 Then caps pcaplck = 1 Case $77 ' Numlock key pressed If pnumlck = 0 Then nums pnumlck = 1 Case $7E ' Scroll lock key pressed If pscrlck = 0 Then scrl pscrlck = 1 End Select ' no special codes received, so verify byte as legal If scancode > $83 Then KBexit ' if it exceeds table boundry leave! ' translation of keyboard scan code to our keycode Gosub keycode_tbl ' Else, translate it to keycode If keycode = $80 Then KBexit ' Check it, and if it is un- ' decodeable then leave! If keycode < $31 Then KBmain1 ' if true, decode for ascii ' Else, this requires some fiddling... If keycode > $3F Then ' start of kepad number assignments If keycode < $4A Then ' end of keypad number assignments If numlock = 1 Then ' are we in numlock mode? If ctrl = 0 Then ' are there no control or If shift = 0 Then ' shift keys pressed? keycode = keycode - $20 ' re-index for numbers 0-9 Goto KBmain1 Endif Endif Endif Endif Endif Goto navkey KBmain1: ' if this is a ctrl+key situation then decode as such If ctrl = 1 Then If keycode < $1B Then ascii = keycode ' ascii control char If keycode > $1A Then Gosub ctrl_tbl ' special char decode Goto dec_done Endif ' Here is where we sort out the Caps-lock and Shift dilema, which is ' especially tricky when dealing with the Num Pad keys. Select Case caplock Case 0 ' cap lock OFF If shift = 0 Then If keycode < $1B Then ' if alphanumeric... ascii = keycode + $60 ' convert to ascii lowercase alpha Else ' if punctuation... Gosub noshift_tbl ' get non-shifted value Endif Else If keycode < $1B Then ' if alphanumeric... ascii = keycode + $40 ' convert to ascii uppercase alpha Else ' if punctuation... Gosub shift_tbl ' get shifted value Endif Endif Case 1 ' cap lock ON If shift = 0 Then If keycode < $1B Then ' if alphanumeric... ascii = keycode + $40 ' convert to ascii uppercase alpha Else ' if punctuation... Gosub noshift_tbl ' get non-shifted value Endif Else If keycode < $1B Then ' if alphanumeric... ascii = keycode + $60 ' convert to ascii lowercase alpha Else ' if punctuation... Gosub shift_tbl ' get shifted value Endif Endif End Select ' decoding of key is complete by the time it reaches this point dec_done: keydec = 1 'key decoded, set flag Gosub modstart_prnt2scrn ' Check to see if there are any more bytes left to process in the ' ring buffer. If there is, go get it and process it! KBexit: If KBindxO != KBindxI Then KBmain ' more bytes left Input KBCLK ' release clock line INT2IE = 1 ' re-enable IRQ Return getbuf: KBindxO = KBindxO + 1 ' increment index If KBindxO => KBbufsize Then KBindxO = 0 scancode = KBbuf[KBindxO] ' fetch next scancode Return




Bookmarks