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:
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
More to come <img src="http://www.picbasic.co.uk/forum/images/icons/icon2.gif"> Installment #3b: KBmain module (2nd half)