Learn how easy it is to sync an existing GitHub or Google Code repo to a SourceForge project! See Demo

Close

Enhanced PS2 ScanCode Support

Dan Damron
2010-04-10
2013-05-30
  • Dan Damron
    Dan Damron
    2010-04-10

    I have an application which I require access to PS2 Function keys.  After examining ps2.h, I thought I would like to add a simple routine:

    function PS2ScanCode as String
    PS2ScanCode = ""
    PS2GetAnotherScanCode:
    'Get key scan code
    ScanCode = PS2ReadByte
    if ScanCode = 0 then exit function
    PS2ScanCode += ScanCode
    if ScanCode = 0xF0 then
    goto PS2GetAnotherScanCode
    end if
    if ScanCode = 0xE0 then
    goto PS2GetAnotherScanCode
    end if
    end function

    Add that to the end of ps2.h to allow your code to get the raw scancodes.

    To call it, do:

    dim scancode as string
    scancode = PS2ScanCode

    This string can be up to 3 bytes in length.
    If the first byte is 0xF0, this signifies that the key has been released.  There should always be a second byte after this one.

    If the second byte is 0xE0, this signifies a 2 byte extended key. This is how I get the F1 - F12, Left ctrl, etc.  There should always be a third byte if the second is 0xE0.

    The Third byte signifies the final scan code.
    There is a handy scan code chart at http://www.computer-engineering.org/ps2keyboard/scancodes2.html

    Kindest Regards,

    Dan Damron

     
  • Dan Damron
    Dan Damron
    2010-04-10

    I wouldn't mind rewriting this module to take advantage of a few of the existing routines.
    I'd like to propose the following functions:
    InKey as byte - just like normal
    InScanCode as string - to get the raw scancodes
    InCodetoKey(ScanCode as string) as byte - to convert (or better put, reinject) the scancode and get the inkey return form.

    By rewriting this, we can take advantage of the full keyboard.  We can get the InScanCode and test for 'special' keys like F1, F2, etc.. but also feed it back into InCodetoKey if we don't find anything useful.

    Thoughts?  Suggestions? Comments?

    Kindest Regards,

    Dan Damron

     
  • Dan Damron
    Dan Damron
    2010-04-11

    Here's a first draft (haven't tested this code yet)

    ' PS/2 Keyboard/mouse routines for Great Cow Basic
    'Original code Copyright (c) 2006 - 2010 Hugh Considine
    'Modified by Dan Damron VE6IBM
    '#define PS2Data SysTemp.0 ' Set to Data Pin
    '#define PS2Clock SysTemp.0 ' Set to Clock Pin
    #Startup InitPS2
    'Flags
    #define PS2KeyShift PS2Flags.0
    #define PS2KeyCtrl PS2Flags.1
    #define PS2KeyAlt PS2Flags.2
    #define PS2NumLock PS2Flags.3
    #define PS2CapsLock PS2Flags.4
    #define PS2ScrollLock PS2Flags.5
    #define PS2Extended PS2Flags.6
    #define PS2Release PS2Flags.7
    'Initialize
    sub InitPS2
        'Inhibit Device
        DIR PS2Clock Out
        DIR PS2Data IN
        set PS2Clock Off
    end sub
    function PS2ReadByte
        PS2ReadByte = 0
    
        'Release bus
        Dir PS2Clock In
    
        'Give device time to respond
        Wait 25 us
    
        'If no response after 200 us, exit
        PS2Bit = 0
        Do While PS2Clock = On
            If PS2Bit > 200 Then
                Goto PS2ReadByteDone
            End If
            Wait 10 us
            PS2Bit += 10
        Loop
    
        'Start Bit
        If PS2Data = ON Then Goto PS2ReadByteDone
        Wait Until PS2Clock = ON
    
        '8 data bits
        For PS2Bit = 1 to 8
            wait until PS2Clock = OFF 
            ROTATE PS2ReadByte RIGHT
            PS2ReadByte.7 = PS2Data
            wait until PS2Clock = ON
        Next
    
        'Parity bit
        wait until PS2Clock = OFF
        wait until PS2Clock = ON
    
        'End bit
        wait until PS2Clock = OFF
        wait until PS2Clock = ON
    
        'Inhibit bus
        PS2ReadByteDone:
        DIR PS2Clock Out
        Set PS2Clock Off
        Wait 100 us
    
        #ifdef PS2_DELAY
            Wait PS2_DELAY
        #endif
    
    end function
    sub PS2WriteByte (In PS2Byte)
    
        'Pull data down, then release clock
        Dir PS2Data Out
        Set PS2Data Off
        Wait 10 us
        Dir PS2Clock In
    
        'Wait up to 20 ms for device to pull clock down
        PS2Bit = 0
        Do While PS2Clock = On
            'Re-use PS2Parity to count 100 us
            For PS2Parity = 1 to 10
                Wait 10 us
                If PS2Clock = Off Then Exit Do
            Next
            PS2Bit += 1
            If PS2Bit > 200 Then Goto PS2WriteByteDone
        Loop
    
        '8 data bits
        PS2Parity = 0
        For PS2Bit = 1 to 8
            If PS2Byte.0 = Off then
                Set PS2Data off
            Else
                Set PS2Data on
                PS2Parity += 1
            End If
            ROTATE PS2Byte RIGHT
            Wait until PS2Clock = On
            wait until PS2Clock = Off
        Next
    
        'Parity
        If PS2Parity.0 = off then Set PS2Data on
        If PS2Parity.0 = on then Set PS2Data off
        wait until PS2Clock = On
        wait until PS2Clock = Off
    
        'Stop
        Dir PS2Data In
    
        'Ack
        Wait Until PS2Data = Off
        wait until PS2Clock = OFF
        wait until PS2Clock = ON
    
        'Inhibit bus
        PS2WriteByteDone:
        Dir PS2Clock Out
        Set PS2Clock Off
        Wait 100 us
    
        #ifdef PS2_DELAY
            Wait PS2_DELAY
        #endif
    
    End Sub
    Sub PS2SyncKBLeds
        'Get value
        PS2Value = 0
        If PS2NumLock Then PS2Value.1 = On
        If PS2CapsLock Then PS2Value.2 = On
        If PS2ScrollLock Then PS2Value.0 = On
    
        'Send LED command
        PS2WriteByte (0xED)
        PS2Parity = PS2ReadByte
        'Send value
        PS2WriteByte (PS2Value)
        PS2Parity = PS2ReadByte
    
    End Sub
    '''Keyboard LED setting routine
    '''@param PS2Value Value to send. Bits 0-2 control LEDs
    Sub PS2SetKBLeds (In PS2Value)
        'Send LED command
        PS2WriteByte (0xED)
        PS2Parity = PS2ReadByte
        'Send value
        PS2WriteByte (PS2Value)
        PS2Parity = PS2ReadByte
    End Sub
    function PS2ScanCode as String
        PS2ScanCode = ""
        PS2GetAnotherScanCode:
        'Get key scan code
        ScanCode = PS2ReadByte
        if ScanCode = 0 then exit function
        PS2ScanCode += ScanCode
        if ScanCode = 0xF0 then 
            goto PS2GetAnotherScanCode
        end if
        if ScanCode = 0xE0 then
            goto PS2GetAnotherScanCode
        end if
    end function
    function ScanCodetoInkey (In ScanCode As string)
        scancodeposition = 1
        ScanCodetoInkey = 0
        GetAnotherScanCode:
    
        select case ScanCode(scancodeposition)
        'Key Release
        case = 0xF0
            PS2Release = 1
            scancodeposition ++
            goto GetAnotherScanCode
    
        'Shift
        case = 0x12 'l Shift
            if PS2Release = 1 then 
                PS2KeyShift = 1
            else
                PS2KeyShift = 0
            end if
        case = 0x31 'R Shift
            if PS2Release = 1 then 
                PS2KeyShift = 1
            else
                PS2KeyShift = 0
            end if
    
        'Ctrl
        case = 0x14 'l Ctrl, R Ctrl (extended)
            if PS2Release = 1 then 
                PS2KeyCtrl = 1
            else
                PS2KeyCtrl = 0
            end if
    
        'Caps Lock
        case 0x58
            if PS2Release = 0 then
                PS2CapsLock = not PS2CapsLock
                PS2SyncKBLeds
                scancodeposition ++
                goto GetAnotherScanCode
            end if
    
        'NumLock
        case 0x77
            if PS2Release = 0 then
                PS2NumLock = not PS2NumLock
                PS2SyncKBLeds
                Scancodeposition ++
                goto GetAnotherScanCode
            end if
    
        'Scroll Lock
            if PS2Release = 0 then
                PS2ScrollLock = not PS2ScrollLock
                PS2SyncKBLeds
                ScanCodePosition ++
                goto GetAnotherScanCode
            end if
    
        'Control Chars
        case 0x5A 'Enter
            scancodetoinkey = 13
    
        case 0x66 'Backspace
            scancodetoinkey = 8
    
        case 0x76 'Esc
            scancodetoinkey = 27
        case 0x29 'Space
            scancodetoinkey = 32
    
        case = 0xE0 'Extended
            PS2Extended = 1
            scancodeposition ++
            goto GetAnotherScanCode
    
            'Letters        
        case = 0x1C 'aA
            scancodetoinkey = 65    
        case = 0x32 
            scancodetoinkey = 66
        case = 0x21 'cC
            scancodetoinkey = 67
        case = 0x23
            scancodetoinkey = 68
        case = 0x24 'eE
            scancodetoinkey = 69
        case = 0x2B
            scancodetoinkey = 70
        case = 0x34 'gG
            scancodetoinkey = 71
        case = 0x33 
            scancodetoinkey = 72
        case = 0x43 'iI
            scancodetoinkey = 73
        case = 0x3B
            scancodetoinkey = 74
        case = 0x42 'kK
            scancodetoinkey = 75
        case = 0x4B
            scancodetoinkey = 76
        case = 0x3A 'mM
            scancodetoinkey = 77
        case = 0x31
            scancodetoinkey = 78
        case = 0x44 'oO
            scancodetoinkey = 79
        case = 0x4d
            scancodetoinkey = 80
        case = 0x15 'qQ
            scancodetoinkey = 81
        case = 0x2D
            scancodetoinkey = 82
        case = 0x1B 'sS
            scancodetoinkey = 83
        case = 0x2C
            scancodetoinkey = 84
        case = 0x3C 'uU
            scancodetoinkey = 85
        case = 0x2A
            scancodetoinkey = 86
        case = 0x1D 'wW
            scancodetoinkey = 87
        case = 0x22
            scancodetoinkey = 88
        case = 0x35 'yY
            scancodetoinkey = 89
        case = 0x1A 'zZ
            scancodetoinkey = 90
        end select
    
        'if CTRL flag, reduce to ctrl characters
        if PS2KeyCtrl then
            if scancodetoinkey >= 65 and scancodetoinkey <=90 then scancodetoinkey -=64
        end if
        'If shift key and caps lock in same state, make lower case
        If PS2KeyShift = PS2CapsLock Then
            If scancodetoinkey >= 65 and scancodetoinkey <= 90 Then scancodetoinkey += 32
        End If
    
        'numbers
        if PS2KeyShift then
            if ScanCode(scancodeposition) = 0x16 then ScanCodetoInKey = "!"
            if ScanCode(scancodeposition) = 0x1E then ScanCodetoInKey = "@"
            if ScanCode(scancodeposition) = 0x26 then ScanCodetoInKey = "#"
            if ScanCode(scancodeposition) = 0x25 then ScanCodetoInKey = "$"
            if ScanCode(scancodeposition) = 0x2E then ScanCodetoInKey = "%"
            if ScanCode(scancodeposition) = 0x36 then ScanCodetoInKey = "^"
            if ScanCode(scancodeposition) = 0x3D then ScanCodetoInKey = "&"
            if ScanCode(scancodeposition) = 0x3E then ScanCodetoInKey = "*"
            if ScanCode(scancodeposition) = 0x46 then ScanCodetoInKey = "("
            if ScanCode(scancodeposition) = 0x45 then ScanCodetoInKey = ")"
        Else
            if ScanCode(scancodeposition) = 0x16 then ScanCodetoInKey = 49
            if ScanCode(scancodeposition) = 0x1E then ScanCodetoInKey = 50
            if ScanCode(scancodeposition) = 0x26 then ScanCodetoInKey = 51
            if ScanCode(scancodeposition) = 0x25 then ScanCodetoInKey = 52
            if ScanCode(scancodeposition) = 0x2E then ScanCodetoInKey = 53
            if ScanCode(scancodeposition) = 0x36 then ScanCodetoInKey = 54
            if ScanCode(scancodeposition) = 0x3D then ScanCodetoInKey = 55
            if ScanCode(scancodeposition) = 0x3E then ScanCodetoInKey = 56
            if ScanCode(scancodeposition) = 0x46 then ScanCodetoInKey = 57
            if ScanCode(scancodeposition) = 0x45 then ScanCodetoInKey = 48
        end if
    
        'Symbols
        If PS2KeyShift Then
            if ScanCode(scancodeposition) = 0x0E then ScanCodetoInKey = "~"
            if ScanCode(scancodeposition) = 0x4E then ScanCodetoInKey = "_"
            if ScanCode(scancodeposition) = 0x55 then ScanCodetoInKey = "+"
            if ScanCode(scancodeposition) = 0x5D then ScanCodetoInKey = "|"
            if ScanCode(scancodeposition) = 0x4c then ScanCodetoInKey = ":"
            if ScanCode(scancodeposition) = 0x52 then ScanCodetoInKey = 34 '"
            if ScanCode(scancodeposition) = 0x41 then ScanCodetoInKey = "<"
            if ScanCode(scancodeposition) = 0x49 then ScanCodetoInKey = ">"
            if ScanCode(scancodeposition) = 0x4A then ScanCodetoInKey = "?"
            if ScanCode(scancodeposition) = 0x54 then ScanCodetoInKey = "{"
            if ScanCode(scancodeposition) = 0x5B then ScanCodetoInKey = "}"
        Else
            if ScanCode(scancodeposition) = 0x0E then ScanCodetoInKey = 96 '`
            if ScanCode(scancodeposition) = 0x4E then ScanCodetoInKey = 45 '-
            if ScanCode(scancodeposition) = 0x55 then ScanCodetoInKey = 61 '=
            if ScanCode(scancodeposition) = 0x5D then ScanCodetoInKey = 92 '\
            if ScanCode(scancodeposition) = 0x4c then ScanCodetoInKey = 59 ';
            if ScanCode(scancodeposition) = 0x52 then ScanCodetoInKey = 39 ''
            if ScanCode(scancodeposition) = 0x41 then ScanCodetoInKey = 44 ',
            if ScanCode(scancodeposition) = 0x49 then ScanCodetoInKey = 46 '.
            if ScanCode(scancodeposition) = 0x4A then ScanCodetoInKey = 47 '/
            if ScanCode(scancodeposition) = 0x54 then ScanCodetoInKey = "["
            if ScanCode(scancodeposition) = 0x5B then ScanCodetoInKey = "]"
        End If
    End Function
    
     
  • Dan Damron
    Dan Damron
    2010-04-11

    Damn BBCode…  here it is again in a quote

    ' PS/2 Keyboard/mouse routines for Great Cow Basic
    'Original code Copyright (C) 2006 - 2010 Hugh Considine
    'Modified by Dan Damron VE6IBM

    '#define PS2Data SysTemp.0 ' Set to Data Pin
    '#define PS2Clock SysTemp.0 ' Set to Clock Pin
    #Startup InitPS2

    'Flags
    #define PS2KeyShift PS2Flags.0
    #define PS2KeyCtrl PS2Flags.1
    #define PS2KeyAlt PS2Flags.2
    #define PS2NumLock PS2Flags.3
    #define PS2CapsLock PS2Flags.4
    #define PS2ScrollLock PS2Flags.5
    #define PS2Extended PS2Flags.6
    #define PS2Release PS2Flags.7

    'Initialize
    sub InitPS2
    'Inhibit Device
    DIR PS2Clock Out
    DIR PS2Data IN
    set PS2Clock Off
    end sub

    function PS2ReadByte

    PS2ReadByte = 0

    'Release bus
    Dir PS2Clock In

    'Give device time to respond
    Wait 25 us

    'If no response after 200 us, exit
    PS2Bit = 0

    Do While PS2Clock = On
    If PS2Bit > 200 Then
    Goto PS2ReadByteDone
    End If
    Wait 10 us
    PS2Bit += 10
    Loop

    'Start Bit
    If PS2Data = ON Then Goto PS2ReadByteDone
    Wait Until PS2Clock = ON

    '8 data bits
    For PS2Bit = 1 to 8
    wait until PS2Clock = OFF
    ROTATE PS2ReadByte RIGHT
    PS2ReadByte.7 = PS2Data
    wait until PS2Clock = ON
    Next

    'Parity bit
    wait until PS2Clock = OFF
    wait until PS2Clock = ON

    'End bit
    wait until PS2Clock = OFF
    wait until PS2Clock = ON

    'Inhibit bus
    PS2ReadByteDone:
    DIR PS2Clock Out
    Set PS2Clock Off
    Wait 100 us

    #ifdef PS2_DELAY
    Wait PS2_DELAY
    #endif

    end function

    sub PS2WriteByte (In PS2Byte)

    'Pull data down, then release clock
    Dir PS2Data Out
    Set PS2Data Off
    Wait 10 us
    Dir PS2Clock In

    'Wait up to 20 ms for device to pull clock down
    PS2Bit = 0
    Do While PS2Clock = On
    'Re-use PS2Parity to count 100 us
    For PS2Parity = 1 to 10
    Wait 10 us
    If PS2Clock = Off Then Exit Do
    Next
    PS2Bit += 1
    If PS2Bit > 200 Then Goto PS2WriteByteDone
    Loop

    '8 data bits
    PS2Parity = 0
    For PS2Bit = 1 to 8
    If PS2Byte.0 = Off then
    Set PS2Data off
    Else
    Set PS2Data on
    PS2Parity += 1
    End If
    ROTATE PS2Byte RIGHT
    Wait until PS2Clock = On
    wait until PS2Clock = Off
    Next

    'Parity
    If PS2Parity.0 = off then Set PS2Data on
    If PS2Parity.0 = on then Set PS2Data off
    wait until PS2Clock = On
    wait until PS2Clock = Off

    'Stop
    Dir PS2Data In

    'Ack
    Wait Until PS2Data = Off
    wait until PS2Clock = OFF
    wait until PS2Clock = ON

    'Inhibit bus
    PS2WriteByteDone:
    Dir PS2Clock Out
    Set PS2Clock Off
    Wait 100 us

    #ifdef PS2_DELAY
    Wait PS2_DELAY
    #endif

    End Sub

    Sub PS2SyncKBLeds
    'Get value
    PS2Value = 0
    If PS2NumLock Then PS2Value.1 = On
    If PS2CapsLock Then PS2Value.2 = On
    If PS2ScrollLock Then PS2Value.0 = On

    'Send LED command
    PS2WriteByte (0xED)
    PS2Parity = PS2ReadByte
    'Send value
    PS2WriteByte (PS2Value)
    PS2Parity = PS2ReadByte

    End Sub

    '''Keyboard LED setting routine
    '''@param PS2Value Value to send. Bits 0-2 control LEDs
    Sub PS2SetKBLeds (In PS2Value)
    'Send LED command
    PS2WriteByte (0xED)
    PS2Parity = PS2ReadByte
    'Send value
    PS2WriteByte (PS2Value)
    PS2Parity = PS2ReadByte
    End Sub

    function PS2ScanCode as String
    PS2ScanCode = ""
    PS2GetAnotherScanCode:
    'Get key scan code
    ScanCode = PS2ReadByte
    if ScanCode = 0 then exit function
    PS2ScanCode += ScanCode
    if ScanCode = 0xF0 then
    goto PS2GetAnotherScanCode
    end if
    if ScanCode = 0xE0 then
    goto PS2GetAnotherScanCode
    end if
    end function

    function ScanCodetoInkey (In ScanCode As string)

    scancodeposition = 1

    ScanCodetoInkey = 0
    GetAnotherScanCode:

    select case ScanCode(scancodeposition)
    'Key Release
    case = 0xF0
    PS2Release = 1
    scancodeposition ++
    goto GetAnotherScanCode

    'Shift
    case = 0x12 'l Shift
    if PS2Release = 1 then
    PS2KeyShift = 1
    else
    PS2KeyShift = 0
    end if
    case = 0x31 'R Shift
    if PS2Release = 1 then
    PS2KeyShift = 1
    else
    PS2KeyShift = 0
    end if

    'Ctrl
    case = 0x14 'l Ctrl, R Ctrl (extended)
    if PS2Release = 1 then
    PS2KeyCtrl = 1
    else
    PS2KeyCtrl = 0
    end if

    'Caps Lock
    case 0x58
    if PS2Release = 0 then
    PS2CapsLock = not PS2CapsLock
    PS2SyncKBLeds
    scancodeposition ++
    goto GetAnotherScanCode
    end if

    'NumLock
    case 0x77
    if PS2Release = 0 then
    PS2NumLock = not PS2NumLock
    PS2SyncKBLeds
    Scancodeposition ++
    goto GetAnotherScanCode
    end if

    'Scroll Lock
    if PS2Release = 0 then
    PS2ScrollLock = not PS2ScrollLock
    PS2SyncKBLeds
    ScanCodePosition ++
    goto GetAnotherScanCode
    end if

    'Control Chars
    case 0x5A 'Enter
    scancodetoinkey = 13

    case 0x66 'Backspace
    scancodetoinkey = 8

    case 0x76 'Esc
    scancodetoinkey = 27

    case 0x29 'Space
    scancodetoinkey = 32

    case = 0xE0 'Extended
    PS2Extended = 1
    scancodeposition ++
    goto GetAnotherScanCode

    'Letters
    case = 0x1C 'aA
    scancodetoinkey = 65
    case = 0x32
    scancodetoinkey = 66
    case = 0x21 'cC
    scancodetoinkey = 67
    case = 0x23
    scancodetoinkey = 68
    case = 0x24 'eE
    scancodetoinkey = 69
    case = 0x2B
    scancodetoinkey = 70
    case = 0x34 'gG
    scancodetoinkey = 71
    case = 0x33
    scancodetoinkey = 72
    case = 0x43 'iI
    scancodetoinkey = 73
    case = 0x3B
    scancodetoinkey = 74
    case = 0x42 'kK
    scancodetoinkey = 75
    case = 0x4B
    scancodetoinkey = 76
    case = 0x3A 'mM
    scancodetoinkey = 77
    case = 0x31
    scancodetoinkey = 78
    case = 0x44 'oO
    scancodetoinkey = 79
    case = 0x4d
    scancodetoinkey = 80
    case = 0x15 'qQ
    scancodetoinkey = 81
    case = 0x2D
    scancodetoinkey = 82
    case = 0x1B 'sS
    scancodetoinkey = 83
    case = 0x2C
    scancodetoinkey = 84
    case = 0x3C 'uU
    scancodetoinkey = 85
    case = 0x2A
    scancodetoinkey = 86
    case = 0x1D 'wW
    scancodetoinkey = 87
    case = 0x22
    scancodetoinkey = 88
    case = 0x35 'yY
    scancodetoinkey = 89
    case = 0x1A 'zZ
    scancodetoinkey = 90
    end select

    'if CTRL flag, reduce to ctrl characters
    if PS2KeyCtrl then
    if scancodetoinkey >= 65 and scancodetoinkey <=90 then scancodetoinkey -=64
    end if

    'If shift key and caps lock in same state, make lower case
    If PS2KeyShift = PS2CapsLock Then
    If scancodetoinkey >= 65 and scancodetoinkey <= 90 Then scancodetoinkey += 32
    End If

    'numbers
    if PS2KeyShift then
    if ScanCode(scancodeposition) = 0x16 then ScanCodetoInKey = "!"
    if ScanCode(scancodeposition) = 0x1E then ScanCodetoInKey = "@"
    if ScanCode(scancodeposition) = 0x26 then ScanCodetoInKey = "#"
    if ScanCode(scancodeposition) = 0x25 then ScanCodetoInKey = "$"
    if ScanCode(scancodeposition) = 0x2E then ScanCodetoInKey = "%"
    if ScanCode(scancodeposition) = 0x36 then ScanCodetoInKey = "^"
    if ScanCode(scancodeposition) = 0x3D then ScanCodetoInKey = "&"
    if ScanCode(scancodeposition) = 0x3E then ScanCodetoInKey = "*"
    if ScanCode(scancodeposition) = 0x46 then ScanCodetoInKey = "("
    if ScanCode(scancodeposition) = 0x45 then ScanCodetoInKey = ")"
    Else
    if ScanCode(scancodeposition) = 0x16 then ScanCodetoInKey = 49
    if ScanCode(scancodeposition) = 0x1E then ScanCodetoInKey = 50
    if ScanCode(scancodeposition) = 0x26 then ScanCodetoInKey = 51
    if ScanCode(scancodeposition) = 0x25 then ScanCodetoInKey = 52
    if ScanCode(scancodeposition) = 0x2E then ScanCodetoInKey = 53
    if ScanCode(scancodeposition) = 0x36 then ScanCodetoInKey = 54
    if ScanCode(scancodeposition) = 0x3D then ScanCodetoInKey = 55
    if ScanCode(scancodeposition) = 0x3E then ScanCodetoInKey = 56
    if ScanCode(scancodeposition) = 0x46 then ScanCodetoInKey = 57
    if ScanCode(scancodeposition) = 0x45 then ScanCodetoInKey = 48
    end if

    'Symbols
    If PS2KeyShift Then
    if ScanCode(scancodeposition) = 0x0E then ScanCodetoInKey = "~"
    if ScanCode(scancodeposition) = 0x4E then ScanCodetoInKey = "_"
    if ScanCode(scancodeposition) = 0x55 then ScanCodetoInKey = "+"
    if ScanCode(scancodeposition) = 0x5D then ScanCodetoInKey = "|"
    if ScanCode(scancodeposition) = 0x4c then ScanCodetoInKey = ":"
    if ScanCode(scancodeposition) = 0x52 then ScanCodetoInKey = 34 '"
    if ScanCode(scancodeposition) = 0x41 then ScanCodetoInKey = "<"
    if ScanCode(scancodeposition) = 0x49 then ScanCodetoInKey = ">"
    if ScanCode(scancodeposition) = 0x4A then ScanCodetoInKey = "?"
    if ScanCode(scancodeposition) = 0x54 then ScanCodetoInKey = "{"
    if ScanCode(scancodeposition) = 0x5B then ScanCodetoInKey = "}"
    Else
    if ScanCode(scancodeposition) = 0x0E then ScanCodetoInKey = 96 '`
    if ScanCode(scancodeposition) = 0x4E then ScanCodetoInKey = 45 '-
    if ScanCode(scancodeposition) = 0x55 then ScanCodetoInKey = 61 '=
    if ScanCode(scancodeposition) = 0x5D then ScanCodetoInKey = 92 '\
    if ScanCode(scancodeposition) = 0x4c then ScanCodetoInKey = 59 ';
    if ScanCode(scancodeposition) = 0x52 then ScanCodetoInKey = 39 ''
    if ScanCode(scancodeposition) = 0x41 then ScanCodetoInKey = 44 ',
    if ScanCode(scancodeposition) = 0x49 then ScanCodetoInKey = 46 '.
    if ScanCode(scancodeposition) = 0x4A then ScanCodetoInKey = 47 '/
    if ScanCode(scancodeposition) = 0x54 then ScanCodetoInKey = "["
    if ScanCode(scancodeposition) = 0x5B then ScanCodetoInKey = "]"
    End If
    End Function

     
  • Dan Damron
    Dan Damron
    2010-04-12

    The Code above was a quick type, untested.  I found lots of problems with it, here is the updated and TESTED code:
    File is called NewPS2.h (I had to unload the old PS2.h)

    ;Startup routine
    #startup InitPS2
    ;Defines (Constants)
    #define PS2KeyShift PS2Flags.0
    #define PS2KeyCtrl PS2Flags.1
    #define PS2KeyAlt PS2Flags.2
    #define PS2NumLock PS2Flags.3
    #define PS2CapsLock PS2Flags.4
    #define PS2ScrollLock PS2Flags.5
    #define PS2Extended PS2Flags.6
    #define PS2Release PS2Flags.7
    ' PS/2 Keyboard/mouse routines for Great Cow Basic
    'Original code Copyright (c) 2006 - 2010 Hugh Considine
    'Modified by Dan Damron VE6IBM
    '#define PS2Data SysTemp.0 ' Set to Data Pin
    '#define PS2Clock SysTemp.0 ' Set to Clock Pin
    'Flags
    'Initialize
    Sub InitPS2
        'Inhibit Device
        DIR PS2Clock Out
        DIR PS2Data IN
        set PS2Clock Off
    End Sub
    Function PS2ReadByte
        PS2ReadByte = 0
        'Release bus
        Dir PS2Clock In
        'Give device time to respond
        Wait 25 us
        'If no response after 200 us, exit
        PS2Bit = 0
        Do While PS2Clock = On
            If PS2Bit > 200 Then
                Goto PS2ReadByteDone
            End If
            Wait 10 us
            PS2Bit = PS2Bit + 10
        Loop
        'Start Bit
        If PS2Data = ON then
             Goto PS2ReadByteDone
         end if
        Wait Until PS2Clock = ON
        '8 data bits
        For PS2Bit = 1 to 8
            Wait until PS2Clock = OFF
            ROTATE PS2ReadByte RIGHT
            PS2ReadByte.7 = PS2Data
            Wait until PS2Clock = ON
        Next
        'Parity bit
        Wait until PS2Clock = OFF
        Wait until PS2Clock = ON
        'End bit
        Wait until PS2Clock = OFF
        Wait until PS2Clock = ON
        'Inhibit bus
        PS2ReadByteDone:
        DIR PS2Clock Out
        Set PS2Clock Off
        Wait 100 us
        #ifdef PS2_DELAY
        Wait PS2_DELAY
        #endif
    End Function
    Sub PS2WriteByte (In PS2Byte)
        'Pull data down, then release clock
        Dir PS2Data Out
        Set PS2Data Off
        Wait 10 us
        Dir PS2Clock In
        'Wait up to 20 ms for device to pull clock down
        PS2Bit = 0
        Do While PS2Clock = On
            'Re-use PS2Parity to count 100 us
            For PS2Parity = 1 to 10
                Wait 10 us
                If PS2Clock = Off then
                     Exit Do
                 end if
            Next
            PS2Bit = PS2Bit + 1
            If PS2Bit > 200 then
                 Goto PS2WriteByteDone
             end if
        Loop
        '8 data bits
        PS2Parity = 0
        For PS2Bit = 1 to 8
            If PS2Byte.0 = Off then
                Set PS2Data off
            Else
                Set PS2Data on
                PS2Parity = PS2Parity + 1
            End If
            ROTATE PS2Byte RIGHT
            Wait until PS2Clock = On
            Wait until PS2Clock = Off
        Next
        'Parity
        If PS2Parity.0 = off then
             Set PS2Data on
         end if
        If PS2Parity.0 = on then
             Set PS2Data off
         end if
        Wait until PS2Clock = On
        Wait until PS2Clock = Off
        'Stop
        Dir PS2Data In
        'Ack
        Wait Until PS2Data = Off
        Wait until PS2Clock = OFF
        Wait until PS2Clock = ON
        'Inhibit bus
        PS2WriteByteDone:
        Dir PS2Clock Out
        Set PS2Clock Off
        Wait 100 us
        #ifdef PS2_DELAY
        Wait PS2_DELAY
        #endif
    End Sub
    Sub PS2SyncKBLeds
        'Get value
        PS2Value = 0
        If PS2NumLock then
            PS2Value.1 = On
         end if
        If PS2CapsLock then
            PS2Value.2 = On
         end if
        If PS2ScrollLock then
            PS2Value.0 = On
         end if
        'Send LED command
        PS2WriteByte (0xED)
        PS2Parity = PS2ReadByte
        'Send value
        PS2WriteByte (PS2Value)
        PS2Parity = PS2ReadByte
    End Sub
    '''Keyboard LED setting routine
    '''@param PS2Value Value to send. Bits 0-2 control LEDs
    Sub PS2SetKBLeds (In PS2Value)
        'Send LED command
        PS2WriteByte (0xED)
        PS2Parity = PS2ReadByte
        'Send value
        PS2WriteByte (PS2Value)
        PS2Parity = PS2ReadByte
    End Sub
    Function PS2ScanCode as string
        PS2Extended = 0
        PS2Release = 0
        charcounter = 1
        'Get key scan code
        MyScanCode = PS2ReadByte
        if MyScanCode = 0 then
            PS2ScanCode = ""
            exit function   
        end if
    
        Again:
        PS2ScanCode(charcounter) = MyScanCode
        if MyScanCode = 0xF0 then ' key released
            charcounter +=1
            PS2Release = 1
            Do
                MyScanCode = PS2ReadByte
            Loop While MyScanCode = 0
            goto Again      
        end if
        if MyScanCode = 0xE0 then ' extended
            charcounter +=1
            PS2Extended = 1
            Do
                MyScanCode = PS2ReadByte
            Loop While MyScanCode = 0
            Goto Again
        end if
        ps2ScanCode(0) = charcounter
    End Function
    function INKEY
        'Initialise
        INKEY = 0
    
        PS2GetAnotherKey:
    
        'Get key scan code
        ScanCode = PS2ReadByte
        if ScanCode = 0 then exit function
    
        'Set flags
        PS2Extended = 0
        PS2Release = 0
    
        '2-byte key?
        if ScanCode = 0xE0 then
            PS2Extended = 1
            Do
                ScanCode = PS2ReadByte
            Loop While ScanCode = 0
        end if
    
        'Key released?
        If ScanCode = 0xF0 Then
            PS2Release = 1
            Do
                ScanCode = PS2ReadByte
            Loop While ScanCode = 0
        End If
    
        'Extended chars
        If PS2Extended Then
    
        'Non-extended chars
        Else
            'Shift pressed/released
            If ScanCode = 0x12 or ScanCode = 0x59 then
                If PS2Release Then
                    PS2KeyShift = 0
                Else
                    PS2KeyShift = 1
                End If
                Goto PS2GetAnotherKey
            End If
    
            If PS2Release = 0 Then
                'Caps Lock pressed
                if ScanCode = 0x58 then 
                    If PS2CapsLock Then
                        PS2CapsLock = 0
                    Else
                        PS2CapsLock = 1
                    End If
                    PS2SyncKBLeds
                    Goto PS2GetAnotherKey
                end if
    
                'Num lock pressed
                if ScanCode = 0x77 then 
                    If PS2NumLock Then
                        PS2NumLock = 0
                    Else
                        PS2NumLock = 1
                    End If
                    PS2SyncKBLeds
                    Goto PS2GetAnotherKey
                end if
    
                'Scroll lock pressed
                if ScanCode = 0x7E then 
                    If PS2ScrollLock Then
                        PS2ScrollLock = 0
                    Else
                        PS2ScrollLock = 1
                    End If
                    PS2SyncKBLeds
                    Goto PS2GetAnotherKey
                end if
    
                'Translate scan code to ASCII
                'Control Chars
                if ScanCode = 0x5A then INKEY = 13  'Enter
                if ScanCode = 0x66 then INKEY = 8   'Backspace
                if ScanCode = 0x76 then INKEY = 27  'Esc
                if ScanCode = 0x29 then INKEY = 32  'Space
    
                'Arrows
    
                'Numbers
                If PS2KeyShift Then
                    if ScanCode = 0x16 then INKEY = "!"
                    if ScanCode = 0x1E then INKEY = "@"
                    if ScanCode = 0x26 then INKEY = "#"
                    if ScanCode = 0x25 then INKEY = "$"
                    if ScanCode = 0x2E then INKEY = "%"
                    if ScanCode = 0x36 then INKEY = "^"
                    if ScanCode = 0x3D then INKEY = "&"
                    if ScanCode = 0x3E then INKEY = "*"
                    if ScanCode = 0x46 then INKEY = "("
                    if ScanCode = 0x45 then INKEY = ")"
                Else
                    if ScanCode = 0x16 then INKEY = 49
                    if ScanCode = 0x1E then INKEY = 50
                    if ScanCode = 0x26 then INKEY = 51
                    if ScanCode = 0x25 then INKEY = 52
                    if ScanCode = 0x2E then INKEY = 53
                    if ScanCode = 0x36 then INKEY = 54
                    if ScanCode = 0x3D then INKEY = 55
                    if ScanCode = 0x3E then INKEY = 56
                    if ScanCode = 0x46 then INKEY = 57
                    if ScanCode = 0x45 then INKEY = 48
                End If
    
                'Letters
                if ScanCode = 0x1C then INKEY = 65 'A
                if ScanCode = 0x32 then INKEY = 66
                if ScanCode = 0x21 then INKEY = 67 'C
                if ScanCode = 0x23 then INKEY = 68
                if ScanCode = 0x24 then INKEY = 69 'E
                if ScanCode = 0x2B then INKEY = 70
                if ScanCode = 0x34 then INKEY = 71 'G
                if ScanCode = 0x33 then INKEY = 72
                if ScanCode = 0x43 then INKEY = 73 'I
                if ScanCode = 0x3B then INKEY = 74
                if ScanCode = 0x42 then INKEY = 75 'K
                if ScanCode = 0x4B then INKEY = 76
                if ScanCode = 0x3A then INKEY = 77 'M
                if ScanCode = 0x31 then INKEY = 78
                if ScanCode = 0x44 then INKEY = 79 'O
                if ScanCode = 0x4D then INKEY = 80
                if ScanCode = 0x15 then INKEY = 81 'Q
                if ScanCode = 0x2D then INKEY = 82
                if ScanCode = 0x1B then INKEY = 83 'S
                if ScanCode = 0x2C then INKEY = 84
                if ScanCode = 0x3C then INKEY = 85 'U
                if ScanCode = 0x2A then INKEY = 86
                if ScanCode = 0x1D then INKEY = 87 'W
                if ScanCode = 0x22 then INKEY = 88
                if ScanCode = 0x35 then INKEY = 89 'Y
                if ScanCode = 0x1A then INKEY = 90 'Z
    
                'If shift key and caps lock in same state, make lower case
                If PS2KeyShift = PS2CapsLock Then
                    If INKEY >= 65 and INKEY <= 90 Then INKEY += 32
                End If
    
                'Symbols
                If PS2KeyShift Then
                    if ScanCode = 0x0E then INKEY = "~"
                    if ScanCode = 0x4E then INKEY = "_"
                    if ScanCode = 0x55 then INKEY = "+"
                    if ScanCode = 0x5D then INKEY = "|"
                    if ScanCode = 0x4c then INKEY = ":"
                    if ScanCode = 0x52 then INKEY = 34 '"
                    if ScanCode = 0x41 then INKEY = "<"
                    if ScanCode = 0x49 then INKEY = ">"
                    if ScanCode = 0x4A then INKEY = "?"
                    if ScanCode = 0x54 then INKEY = "{"
                    if ScanCode = 0x5B then INKEY = "}"
                Else
                    if ScanCode = 0x0E then INKEY = 96 '`
                    if ScanCode = 0x4E then INKEY = 45 '-
                    if ScanCode = 0x55 then INKEY = 61 '=
                    if ScanCode = 0x5D then INKEY = 92 '\
                    if ScanCode = 0x4c then INKEY = 59 ';
                    if ScanCode = 0x52 then INKEY = 39 ''
                    if ScanCode = 0x41 then INKEY = 44 ',
                    if ScanCode = 0x49 then INKEY = 46 '.
                    if ScanCode = 0x4A then INKEY = 47 '/
                    if ScanCode = 0x54 then INKEY = "["
                    if ScanCode = 0x5B then INKEY = "]"
                End If
    
            End If
        End If
    
    end function
    Function ScanCodetoInkey (In ScanCode As string)
        scancodeposition = 1
        ScanCodetoInkey = 0
        'set flags
        PS2Extended = 0
        PS2Release = 0
        GetAnotherScanCode:
        if ScanCode(ScanCodePosition) = 0xE0 then
            PS2Extended = 1
            ScanCodePosition += 1
            goto GetAnotherScanCode
        end if
        if ScanCode(ScanCodePosition) = 0xF0 then
            PS2Release = 1
            ScanCodePosition += 1
            goto GetAnotherScanCode
        end if
        if PS2Extended then
            'Extended Chars
        else
            'Non Extended chars
            if ScanCode(ScanCodePosition) = 0x12 or scancode(Scancodeposition) = 0x59 then
                if PS2Release then
                    PS2KeyShift = 0
                else
                    PS2KeyShift = 1
                End If
                ScanCodePosition += 1
                goto GetAnotherScanCode
            end if
            if PS2Release = 0 then
                if ScanCode(ScanCodePosition) = 0x58 then
                    'Caps Lock pressed
                    if PS2CapsLock then
                        PS2CapsLock = 0
                    else
                        PS2CapsLock = 1
                    end if
                    PS2SyncKBLeds
                    ScanCodetoInkey = 0
                    exit function
                End If
                'Num lock pressed
                if ScanCode(ScanCodePosition) = 0x77 then 
                    If PS2NumLock Then
                        PS2NumLock = 0
                    Else
                        PS2NumLock = 1
                    End If
                    PS2SyncKBLeds
                    ScanCodetoInkey = 0
                    exit function       
                end if
                'Scroll lock pressed
                if ScanCode(ScanCodePosition) = 0x7E then 
                    If PS2ScrollLock Then
                        PS2ScrollLock = 0
                    Else
                        PS2ScrollLock = 1
                    End If
                    PS2SyncKBLeds
                    ScanCodetoInkey = 0
                    exit function
                end if          
                if ScanCode(ScanCodePosition) = 0x5A then ScanCodetoInkey = 13
                if ScanCode(ScanCodePosition) = 0x66 then ScanCodetoInkey = 8
                if ScanCode(ScanCodePosition) = 0x76 then ScanCodetoInkey = 27
                if ScanCode(ScanCodePosition) = 0x29 then ScanCodetoInkey = 32
                'numbers
                if PS2KeyShift then
                    if ScanCode(scancodeposition) = 0x16 then ScanCodetoInKey = "!"
                    if ScanCode(scancodeposition) = 0x1E then ScanCodetoInKey = "@"
                    if ScanCode(scancodeposition) = 0x26 then ScanCodetoInKey = "#"
                    if ScanCode(scancodeposition) = 0x25 then ScanCodetoInKey = "$"
                    if ScanCode(scancodeposition) = 0x2E then ScanCodetoInKey = "%"
                    if ScanCode(scancodeposition) = 0x36 then ScanCodetoInKey = "^"
                    if ScanCode(scancodeposition) = 0x3D then ScanCodetoInKey = "&"
                    if ScanCode(scancodeposition) = 0x3E then ScanCodetoInKey = "*"
                    if ScanCode(scancodeposition) = 0x46 then ScanCodetoInKey = "("
                    if ScanCode(scancodeposition) = 0x45 then ScanCodetoInKey = ")"
                Else
                    if ScanCode(scancodeposition) = 0x16 then ScanCodetoInKey = 49
                    if ScanCode(scancodeposition) = 0x1E then ScanCodetoInKey = 50
                    if ScanCode(scancodeposition) = 0x26 then ScanCodetoInKey = 51
                    if ScanCode(scancodeposition) = 0x25 then ScanCodetoInKey = 52
                    if ScanCode(scancodeposition) = 0x2E then ScanCodetoInKey = 53
                    if ScanCode(scancodeposition) = 0x36 then ScanCodetoInKey = 54
                    if ScanCode(scancodeposition) = 0x3D then ScanCodetoInKey = 55
                    if ScanCode(scancodeposition) = 0x3E then ScanCodetoInKey = 56
                    if ScanCode(scancodeposition) = 0x46 then ScanCodetoInKey = 57
                    if ScanCode(scancodeposition) = 0x45 then ScanCodetoInKey = 48
                end if
                'Letters
                if ScanCode(scancodeposition) = 0x1C then ScanCodetoInKey = 65 'A
                if ScanCode(scancodeposition) = 0x32 then ScanCodetoInKey = 66
                if ScanCode(scancodeposition) = 0x21 then ScanCodetoInKey = 67 'C
                if ScanCode(scancodeposition) = 0x23 then ScanCodetoInKey = 68
                if ScanCode(scancodeposition) = 0x24 then ScanCodetoInKey = 69 'E
                if ScanCode(scancodeposition) = 0x2B then ScanCodetoInKey = 70
                if ScanCode(scancodeposition) = 0x34 then ScanCodetoInKey = 71 'G
                if ScanCode(scancodeposition) = 0x33 then ScanCodetoInKey = 72
                if ScanCode(scancodeposition) = 0x43 then ScanCodetoInKey = 73 'I
                if ScanCode(scancodeposition) = 0x3B then ScanCodetoInKey = 74
                if ScanCode(scancodeposition) = 0x42 then ScanCodetoInKey = 75 'K
                if ScanCode(scancodeposition) = 0x4B then ScanCodetoInKey = 76
                if ScanCode(scancodeposition) = 0x3A then ScanCodetoInKey = 77 'M
                if ScanCode(scancodeposition) = 0x31 then ScanCodetoInKey = 78
                if ScanCode(scancodeposition) = 0x44 then ScanCodetoInKey = 79 'O
                if ScanCode(scancodeposition) = 0x4D then ScanCodetoInKey = 80
                if ScanCode(scancodeposition) = 0x15 then ScanCodetoInKey = 81 'Q
                if ScanCode(scancodeposition) = 0x2D then ScanCodetoInKey = 82
                if ScanCode(scancodeposition) = 0x1B then ScanCodetoInKey = 83 'S
                if ScanCode(scancodeposition) = 0x2C then ScanCodetoInKey = 84
                if ScanCode(scancodeposition) = 0x3C then ScanCodetoInKey = 85 'U
                if ScanCode(scancodeposition) = 0x2A then ScanCodetoInKey = 86
                if ScanCode(scancodeposition) = 0x1D then ScanCodetoInKey = 87 'W
                if ScanCode(scancodeposition) = 0x22 then ScanCodetoInKey = 88
                if ScanCode(scancodeposition) = 0x35 then ScanCodetoInKey = 89 'Y
                if ScanCode(scancodeposition) = 0x1A then ScanCodetoInKey = 90 'Z
                'If shift key and caps lock in same state, make lower case
                If PS2KeyShift = PS2CapsLock Then
                    If scancodetoinkey >= 65 and scancodetoinkey <= 90 then
                        scancodetoinkey += 32
                    end if
                End If
                'Symbols
                If PS2KeyShift Then
                    if ScanCode(scancodeposition) = 0x0E then ScanCodetoInKey = "~"
                    if ScanCode(scancodeposition) = 0x4E then ScanCodetoInKey = "_"
                    if ScanCode(scancodeposition) = 0x55 then ScanCodetoInKey = "+"
                    if ScanCode(scancodeposition) = 0x5D then ScanCodetoInKey = "|"
                    if ScanCode(scancodeposition) = 0x4c then ScanCodetoInKey = ":"
                    if ScanCode(scancodeposition) = 0x52 then ScanCodetoInKey = 34
                    if ScanCode(scancodeposition) = 0x41 then ScanCodetoInKey = "<"
                    if ScanCode(scancodeposition) = 0x49 then ScanCodetoInKey = ">"
                    if ScanCode(scancodeposition) = 0x4A then ScanCodetoInKey = "?"
                    if ScanCode(scancodeposition) = 0x54 then ScanCodetoInKey = "{"
                    if ScanCode(scancodeposition) = 0x5B then ScanCodetoInKey = "}"
                Else
                    if ScanCode(scancodeposition) = 0x0E then ScanCodetoInKey = 96
                    if ScanCode(scancodeposition) = 0x4E then ScanCodetoInKey = 45
                    if ScanCode(scancodeposition) = 0x55 then ScanCodetoInKey = 61
                    if ScanCode(scancodeposition) = 0x5D then ScanCodetoInKey = 92
                    if ScanCode(scancodeposition) = 0x4c then ScanCodetoInKey = 59
                    if ScanCode(scancodeposition) = 0x52 then ScanCodetoInKey = 39
                    if ScanCode(scancodeposition) = 0x41 then ScanCodetoInKey = 44
                    if ScanCode(scancodeposition) = 0x49 then ScanCodetoInKey = 46
                    if ScanCode(scancodeposition) = 0x4A then ScanCodetoInKey = 47
                    if ScanCode(scancodeposition) = 0x54 then ScanCodetoInKey = "["
                    if ScanCode(scancodeposition) = 0x5B then ScanCodetoInKey = "]"
                End If
            else
                'This is key release.
                ScanCodetoInkey = 0
            End if
        End if
    End Function
    

    My Test Program (using a 40x4 character based LCD in 2bit mode) is also attached:

    ;Chip Settings
    #chip 16F886,8
    ;Include files (Libraries)
    #include <newPS2.h>
    ;Defines (Constants)
    #define LCD_IO 2
    #define LCD_CB PORTC.4
    #define LCD_DB PORTC.5
    #define PS2DATA PORTC.6
    #define PS2CLOCK PORTC.7
    #define F1 0x05
    #define F2 0x06
    #define F3 0x04
    #define F4 0x0c
    #define F5 0x03
    #define F6 0x0b
    #define F7 0x83
    #define F8 0x0a
    #define F9 0x01
    #define F10 0x09
    #define F11 0x78
    #define F12 0x07
    #define CapsLock 0x58
    #define NumLock 0x77
    #define LShift 0x12
    #define LCtrl 0x14
    #define LAlt 0x11
    #define RShift 0x59
    #define Extended 0xe0 ' Below are extended keys (have e0 as byte 1)
    #define KPEnter 0x5a ' extended!!!
    #define RCtrl 0x14
    #define RGUI 0x27
    #define RAlt 0x11
    #define UPArrow 0x75
    #define DownArrow 0x72
    #define LeftArrow 0x6B
    #define RightArrow 0x74
    #define ESCAPE 0x76
    ;Variables
    Dim Scancode As string
    Dim KeyIn As byte
    CLS
    locate 0, 0
    print "VE6IBM"
    locate 3, 0
    Main:
    Scancode = PS2ScanCode
    if scancode(0) = 0 then
        goto main
    end if
    'We have a ScanCode.
    locate 0, 10
    print "len="
    print Scancode(0)
    for counter = 1 to scancode(0)
        locate 1, counter * 3 - 3
        lcdhex (scancode(counter))
        print ":"
    next
    print "         "
    'check for escape key
    if scancode(1) = ESCAPE then
        locate 3, 0
        print "Escape   "
    end if
    locate 3, 0
    select case scancode(1)
        case Extended
            if scancode(2) = KPEnter then
                print "KPEnter"
            end if
        case ESCAPE
            print "Escape  "
        case F1
            print "F1      "
        case F2
            print "F2      "
    
        case F3
            print "F3      "
        case else
    print "        "
    end select
    'Let's convert it to ascii
    locate 2, 0
    print "="
    LCDWritechar 34
    KeyIn = ScanCodetoInkey(ScanCode)
    'check to see if it is a valid keydown character
    if KeyIn = 0 then goto main
    LCDWritechar KeyIn
    LCDWriteChar 34
    print "   "
    'ok, at this point we should have a valid ascii character.
    goto Main
    
     
  • Dan Damron
    Dan Damron
    2010-04-12

    main program code:

    ;Chip Settings
    #chip 16F886,8

    ;Include files (Libraries)
    #include <newPS2.h>

    ;Defines (Constants)
    #define LCD_IO 2
    #define LCD_CB PORTC.4
    #define LCD_DB PORTC.5
    #define PS2DATA PORTC.6
    #define PS2CLOCK PORTC.7
    #define F1 0x05
    #define F2 0x06
    #define F3 0x04
    #define F4 0x0c
    #define F5 0x03
    #define F6 0x0b
    #define F7 0x83
    #define F8 0x0a
    #define F9 0x01
    #define F10 0x09
    #define F11 0x78
    #define F12 0x07
    #define CapsLock 0x58
    #define NumLock 0x77
    #define LShift 0x12
    #define LCtrl 0x14
    #define LAlt 0x11
    #define RShift 0x59

    #define Extended 0xe0 ' Below are extended keys (have e0 as byte 1)
    #define KPEnter 0x5a ' extended!!!
    #define RCtrl 0x14
    #define RGUI 0x27
    #define RAlt 0x11
    #define UPArrow 0x75
    #define DownArrow 0x72
    #define LeftArrow 0x6B
    #define RightArrow 0x74

    #define ESCAPE 0x76

    ;Variables
    Dim Scancode As string
    Dim KeyIn As byte

    CLS
    locate 0, 0
    print "VE6IBM"
    locate 3, 0
    Main:
    Scancode = PS2ScanCode
    if scancode(0) = 0 then
    goto main
    end if

    'We have a ScanCode.
    locate 0, 10
    print "len="
    print Scancode(0)

    for counter = 1 to scancode(0)
    locate 1, counter * 3 - 3
    lcdhex (scancode(counter))
    print ":"
    next
    print "         "
    'check for escape key
    if scancode(1) = ESCAPE then
    locate 3, 0
    print "Escape   "
    end if
    locate 3, 0
    select case scancode(1)
    case Extended
    if scancode(2) = KPEnter then
    print "KPEnter"
    end if
    case ESCAPE
    print "Escape  "

    case F1
    print "F1      "
    case F2
    print "F2      "

    case F3
    print "F3      "
    case else
    print "        "
    end select
    'Let's convert it to ascii
    locate 2, 0
    print "="
    LCDWritechar 34
    KeyIn = ScanCodetoInkey(ScanCode)
    'check to see if it is a valid keydown character
    if KeyIn = 0 then goto main
    LCDWritechar KeyIn
    LCDWriteChar 34
    print "   "
    'ok, at this point we should have a valid ascii character.

    goto Main

    NewPS2.h code:

    ;Startup routine
    #startup InitPS2

    ;Defines (Constants)
    #define PS2KeyShift PS2Flags.0
    #define PS2KeyCtrl PS2Flags.1
    #define PS2KeyAlt PS2Flags.2
    #define PS2NumLock PS2Flags.3
    #define PS2CapsLock PS2Flags.4
    #define PS2ScrollLock PS2Flags.5
    #define PS2Extended PS2Flags.6
    #define PS2Release PS2Flags.7

    ' PS/2 Keyboard/mouse routines for Great Cow Basic
    'Original code Copyright (C) 2006 - 2010 Hugh Considine
    'Modified by Dan Damron VE6IBM
    '#define PS2Data SysTemp.0 ' Set to Data Pin
    '#define PS2Clock SysTemp.0 ' Set to Clock Pin
    'Flags
    'Initialize

    Sub InitPS2
    'Inhibit Device
    DIR PS2Clock Out
    DIR PS2Data IN
    set PS2Clock Off
    End Sub

    Function PS2ReadByte
    PS2ReadByte = 0
    'Release bus
    Dir PS2Clock In

    'Give device time to respond
    Wait 25 us

    'If no response after 200 us, exit
    PS2Bit = 0
    Do While PS2Clock = On
    If PS2Bit > 200 Then
    Goto PS2ReadByteDone
    End If
    Wait 10 us
    PS2Bit = PS2Bit + 10
    Loop

    'Start Bit
    If PS2Data = ON then
    Goto PS2ReadByteDone
    end if
    Wait Until PS2Clock = ON

    '8 data bits
    For PS2Bit = 1 to 8
    Wait until PS2Clock = OFF
    ROTATE PS2ReadByte RIGHT
    PS2ReadByte.7 = PS2Data
    Wait until PS2Clock = ON
    Next

    'Parity bit
    Wait until PS2Clock = OFF
    Wait until PS2Clock = ON

    'End bit
    Wait until PS2Clock = OFF
    Wait until PS2Clock = ON

    'Inhibit bus
    PS2ReadByteDone:
    DIR PS2Clock Out
    Set PS2Clock Off
    Wait 100 us
    #ifdef PS2_DELAY
    Wait PS2_DELAY
    #endif
    End Function

    Sub PS2WriteByte (In PS2Byte)
    'Pull data down, then release clock
    Dir PS2Data Out
    Set PS2Data Off
    Wait 10 us
    Dir PS2Clock In

    'Wait up to 20 ms for device to pull clock down
    PS2Bit = 0
    Do While PS2Clock = On

    'Re-use PS2Parity to count 100 us
    For PS2Parity = 1 to 10
    Wait 10 us
    If PS2Clock = Off then
    Exit Do
    end if
    Next
    PS2Bit = PS2Bit + 1
    If PS2Bit > 200 then
    Goto PS2WriteByteDone
    end if
    Loop

    '8 data bits
    PS2Parity = 0
    For PS2Bit = 1 to 8
    If PS2Byte.0 = Off then
    Set PS2Data off
    Else
    Set PS2Data on
    PS2Parity = PS2Parity + 1
    End If
    ROTATE PS2Byte RIGHT
    Wait until PS2Clock = On
    Wait until PS2Clock = Off
    Next

    'Parity
    If PS2Parity.0 = off then
    Set PS2Data on
    end if
    If PS2Parity.0 = on then
    Set PS2Data off
    end if
    Wait until PS2Clock = On
    Wait until PS2Clock = Off

    'Stop
    Dir PS2Data In

    'Ack
    Wait Until PS2Data = Off
    Wait until PS2Clock = OFF
    Wait until PS2Clock = ON

    'Inhibit bus
    PS2WriteByteDone:
    Dir PS2Clock Out
    Set PS2Clock Off
    Wait 100 us
    #ifdef PS2_DELAY
    Wait PS2_DELAY
    #endif
    End Sub

    Sub PS2SyncKBLeds
    'Get value
    PS2Value = 0
    If PS2NumLock then
    PS2Value.1 = On
    end if
    If PS2CapsLock then
    PS2Value.2 = On
    end if
    If PS2ScrollLock then
    PS2Value.0 = On
    end if

    'Send LED command
    PS2WriteByte (0xED)
    PS2Parity = PS2ReadByte

    'Send value
    PS2WriteByte (PS2Value)
    PS2Parity = PS2ReadByte
    End Sub

    '''Keyboard LED setting routine
    '''@param PS2Value Value to send. Bits 0-2 control LEDs
    Sub PS2SetKBLeds (In PS2Value)
    'Send LED command
    PS2WriteByte (0xED)
    PS2Parity = PS2ReadByte

    'Send value
    PS2WriteByte (PS2Value)
    PS2Parity = PS2ReadByte
    End Sub

    Function PS2ScanCode as string
    PS2Extended = 0
    PS2Release = 0
    charcounter = 1
    'Get key scan code
    MyScanCode = PS2ReadByte
    if MyScanCode = 0 then
    PS2ScanCode = ""
    exit function
    end if

    Again:

    PS2ScanCode(charcounter) = MyScanCode
    if MyScanCode = 0xF0 then ' key released
    charcounter +=1
    PS2Release = 1
    Do
    MyScanCode = PS2ReadByte
    Loop While MyScanCode = 0
    goto Again
    end if
    if MyScanCode = 0xE0 then ' extended
    charcounter +=1
    PS2Extended = 1
    Do
    MyScanCode = PS2ReadByte
    Loop While MyScanCode = 0
    Goto Again
    end if
    ps2ScanCode(0) = charcounter

    End Function

    function INKEY
    'Initialise
    INKEY = 0

    PS2GetAnotherKey:

    'Get key scan code
    ScanCode = PS2ReadByte
    if ScanCode = 0 then exit function

    'Set flags
    PS2Extended = 0
    PS2Release = 0

    '2-byte key?
    if ScanCode = 0xE0 then
    PS2Extended = 1
    Do
    ScanCode = PS2ReadByte
    Loop While ScanCode = 0
    end if

    'Key released?
    If ScanCode = 0xF0 Then
    PS2Release = 1
    Do
    ScanCode = PS2ReadByte
    Loop While ScanCode = 0
    End If

    'Extended chars
    If PS2Extended Then

    'Non-extended chars
    Else
    'Shift pressed/released
    If ScanCode = 0x12 or ScanCode = 0x59 then
    If PS2Release Then
    PS2KeyShift = 0
    Else
    PS2KeyShift = 1
    End If
    Goto PS2GetAnotherKey
    End If

    If PS2Release = 0 Then
    'Caps Lock pressed
    if ScanCode = 0x58 then
    If PS2CapsLock Then
    PS2CapsLock = 0
    Else
    PS2CapsLock = 1
    End If
    PS2SyncKBLeds
    Goto PS2GetAnotherKey
    end if

    'Num lock pressed
    if ScanCode = 0x77 then
    If PS2NumLock Then
    PS2NumLock = 0
    Else
    PS2NumLock = 1
    End If
    PS2SyncKBLeds
    Goto PS2GetAnotherKey
    end if

    'Scroll lock pressed
    if ScanCode = 0x7E then
    If PS2ScrollLock Then
    PS2ScrollLock = 0
    Else
    PS2ScrollLock = 1
    End If
    PS2SyncKBLeds
    Goto PS2GetAnotherKey
    end if

    'Translate scan code to ASCII
    'Control Chars
    if ScanCode = 0x5A then INKEY = 13 'Enter
    if ScanCode = 0x66 then INKEY = 8 'Backspace
    if ScanCode = 0x76 then INKEY = 27 'Esc
    if ScanCode = 0x29 then INKEY = 32 'Space

    'Arrows

    'Numbers
    If PS2KeyShift Then
    if ScanCode = 0x16 then INKEY = "!"
    if ScanCode = 0x1E then INKEY = "@"
    if ScanCode = 0x26 then INKEY = "#"
    if ScanCode = 0x25 then INKEY = "$"
    if ScanCode = 0x2E then INKEY = "%"
    if ScanCode = 0x36 then INKEY = "^"
    if ScanCode = 0x3D then INKEY = "&"
    if ScanCode = 0x3E then INKEY = "*"
    if ScanCode = 0x46 then INKEY = "("
    if ScanCode = 0x45 then INKEY = ")"
    Else
    if ScanCode = 0x16 then INKEY = 49
    if ScanCode = 0x1E then INKEY = 50
    if ScanCode = 0x26 then INKEY = 51
    if ScanCode = 0x25 then INKEY = 52
    if ScanCode = 0x2E then INKEY = 53
    if ScanCode = 0x36 then INKEY = 54
    if ScanCode = 0x3D then INKEY = 55
    if ScanCode = 0x3E then INKEY = 56
    if ScanCode = 0x46 then INKEY = 57
    if ScanCode = 0x45 then INKEY = 48
    End If

    'Letters
    if ScanCode = 0x1C then INKEY = 65 'A
    if ScanCode = 0x32 then INKEY = 66
    if ScanCode = 0x21 then INKEY = 67 'C
    if ScanCode = 0x23 then INKEY = 68
    if ScanCode = 0x24 then INKEY = 69 'E
    if ScanCode = 0x2B then INKEY = 70
    if ScanCode = 0x34 then INKEY = 71 'G
    if ScanCode = 0x33 then INKEY = 72
    if ScanCode = 0x43 then INKEY = 73 'I
    if ScanCode = 0x3B then INKEY = 74
    if ScanCode = 0x42 then INKEY = 75 'K
    if ScanCode = 0x4B then INKEY = 76
    if ScanCode = 0x3A then INKEY = 77 'M
    if ScanCode = 0x31 then INKEY = 78
    if ScanCode = 0x44 then INKEY = 79 'O
    if ScanCode = 0x4D then INKEY = 80
    if ScanCode = 0x15 then INKEY = 81 'Q
    if ScanCode = 0x2D then INKEY = 82
    if ScanCode = 0x1B then INKEY = 83 'S
    if ScanCode = 0x2C then INKEY = 84
    if ScanCode = 0x3C then INKEY = 85 'U
    if ScanCode = 0x2A then INKEY = 86
    if ScanCode = 0x1D then INKEY = 87 'W
    if ScanCode = 0x22 then INKEY = 88
    if ScanCode = 0x35 then INKEY = 89 'Y
    if ScanCode = 0x1A then INKEY = 90 'Z

    'If shift key and caps lock in same state, make lower case
    If PS2KeyShift = PS2CapsLock Then
    If INKEY >= 65 and INKEY <= 90 Then INKEY += 32
    End If

    'Symbols
    If PS2KeyShift Then
    if ScanCode = 0x0E then INKEY = "~"
    if ScanCode = 0x4E then INKEY = "_"
    if ScanCode = 0x55 then INKEY = "+"
    if ScanCode = 0x5D then INKEY = "|"
    if ScanCode = 0x4c then INKEY = ":"
    if ScanCode = 0x52 then INKEY = 34 '"
    if ScanCode = 0x41 then INKEY = "<"
    if ScanCode = 0x49 then INKEY = ">"
    if ScanCode = 0x4A then INKEY = "?"
    if ScanCode = 0x54 then INKEY = "{"
    if ScanCode = 0x5B then INKEY = "}"
    Else
    if ScanCode = 0x0E then INKEY = 96 '`
    if ScanCode = 0x4E then INKEY = 45 '-
    if ScanCode = 0x55 then INKEY = 61 '=
    if ScanCode = 0x5D then INKEY = 92 '\
    if ScanCode = 0x4c then INKEY = 59 ';
    if ScanCode = 0x52 then INKEY = 39 ''
    if ScanCode = 0x41 then INKEY = 44 ',
    if ScanCode = 0x49 then INKEY = 46 '.
    if ScanCode = 0x4A then INKEY = 47 '/
    if ScanCode = 0x54 then INKEY = "["
    if ScanCode = 0x5B then INKEY = "]"
    End If

    End If
    End If

    end function

    Function ScanCodetoInkey (In ScanCode As string)
    scancodeposition = 1
    ScanCodetoInkey = 0
    'set flags
    PS2Extended = 0
    PS2Release = 0

    GetAnotherScanCode:

    if ScanCode(ScanCodePosition) = 0xE0 then
    PS2Extended = 1
    ScanCodePosition += 1
    goto GetAnotherScanCode
    end if

    if ScanCode(ScanCodePosition) = 0xF0 then
    PS2Release = 1
    ScanCodePosition += 1
    goto GetAnotherScanCode
    end if
    if PS2Extended then
    'Extended Chars
    else

    'Non Extended chars
    if ScanCode(ScanCodePosition) = 0x12 or scancode(Scancodeposition) = 0x59 then
    if PS2Release then
    PS2KeyShift = 0
    else
    PS2KeyShift = 1
    End If
    ScanCodePosition += 1
    goto GetAnotherScanCode
    end if
    if PS2Release = 0 then

    if ScanCode(ScanCodePosition) = 0x58 then
    'Caps Lock pressed
    if PS2CapsLock then
    PS2CapsLock = 0
    else
    PS2CapsLock = 1
    end if
    PS2SyncKBLeds
    ScanCodetoInkey = 0
    exit function
    End If
    'Num lock pressed
    if ScanCode(ScanCodePosition) = 0x77 then
    If PS2NumLock Then
    PS2NumLock = 0
    Else
    PS2NumLock = 1
    End If
    PS2SyncKBLeds
    ScanCodetoInkey = 0
    exit function
    end if
    'Scroll lock pressed
    if ScanCode(ScanCodePosition) = 0x7E then
    If PS2ScrollLock Then
    PS2ScrollLock = 0
    Else
    PS2ScrollLock = 1
    End If
    PS2SyncKBLeds
    ScanCodetoInkey = 0
    exit function
    end if
    if ScanCode(ScanCodePosition) = 0x5A then ScanCodetoInkey = 13
    if ScanCode(ScanCodePosition) = 0x66 then ScanCodetoInkey = 8
    if ScanCode(ScanCodePosition) = 0x76 then ScanCodetoInkey = 27
    if ScanCode(ScanCodePosition) = 0x29 then ScanCodetoInkey = 32
    'numbers
    if PS2KeyShift then
    if ScanCode(scancodeposition) = 0x16 then ScanCodetoInKey = "!"
    if ScanCode(scancodeposition) = 0x1E then ScanCodetoInKey = "@"
    if ScanCode(scancodeposition) = 0x26 then ScanCodetoInKey = "#"
    if ScanCode(scancodeposition) = 0x25 then ScanCodetoInKey = "$"
    if ScanCode(scancodeposition) = 0x2E then ScanCodetoInKey = "%"
    if ScanCode(scancodeposition) = 0x36 then ScanCodetoInKey = "^"
    if ScanCode(scancodeposition) = 0x3D then ScanCodetoInKey = "&"
    if ScanCode(scancodeposition) = 0x3E then ScanCodetoInKey = "*"
    if ScanCode(scancodeposition) = 0x46 then ScanCodetoInKey = "("
    if ScanCode(scancodeposition) = 0x45 then ScanCodetoInKey = ")"
    Else
    if ScanCode(scancodeposition) = 0x16 then ScanCodetoInKey = 49
    if ScanCode(scancodeposition) = 0x1E then ScanCodetoInKey = 50
    if ScanCode(scancodeposition) = 0x26 then ScanCodetoInKey = 51
    if ScanCode(scancodeposition) = 0x25 then ScanCodetoInKey = 52
    if ScanCode(scancodeposition) = 0x2E then ScanCodetoInKey = 53
    if ScanCode(scancodeposition) = 0x36 then ScanCodetoInKey = 54
    if ScanCode(scancodeposition) = 0x3D then ScanCodetoInKey = 55
    if ScanCode(scancodeposition) = 0x3E then ScanCodetoInKey = 56
    if ScanCode(scancodeposition) = 0x46 then ScanCodetoInKey = 57
    if ScanCode(scancodeposition) = 0x45 then ScanCodetoInKey = 48
    end if

    'Letters
    if ScanCode(scancodeposition) = 0x1C then ScanCodetoInKey = 65 'A
    if ScanCode(scancodeposition) = 0x32 then ScanCodetoInKey = 66
    if ScanCode(scancodeposition) = 0x21 then ScanCodetoInKey = 67 'C
    if ScanCode(scancodeposition) = 0x23 then ScanCodetoInKey = 68
    if ScanCode(scancodeposition) = 0x24 then ScanCodetoInKey = 69 'E
    if ScanCode(scancodeposition) = 0x2B then ScanCodetoInKey = 70
    if ScanCode(scancodeposition) = 0x34 then ScanCodetoInKey = 71 'G
    if ScanCode(scancodeposition) = 0x33 then ScanCodetoInKey = 72
    if ScanCode(scancodeposition) = 0x43 then ScanCodetoInKey = 73 'I
    if ScanCode(scancodeposition) = 0x3B then ScanCodetoInKey = 74
    if ScanCode(scancodeposition) = 0x42 then ScanCodetoInKey = 75 'K
    if ScanCode(scancodeposition) = 0x4B then ScanCodetoInKey = 76
    if ScanCode(scancodeposition) = 0x3A then ScanCodetoInKey = 77 'M
    if ScanCode(scancodeposition) = 0x31 then ScanCodetoInKey = 78
    if ScanCode(scancodeposition) = 0x44 then ScanCodetoInKey = 79 'O
    if ScanCode(scancodeposition) = 0x4D then ScanCodetoInKey = 80
    if ScanCode(scancodeposition) = 0x15 then ScanCodetoInKey = 81 'Q
    if ScanCode(scancodeposition) = 0x2D then ScanCodetoInKey = 82
    if ScanCode(scancodeposition) = 0x1B then ScanCodetoInKey = 83 'S
    if ScanCode(scancodeposition) = 0x2C then ScanCodetoInKey = 84
    if ScanCode(scancodeposition) = 0x3C then ScanCodetoInKey = 85 'U
    if ScanCode(scancodeposition) = 0x2A then ScanCodetoInKey = 86
    if ScanCode(scancodeposition) = 0x1D then ScanCodetoInKey = 87 'W
    if ScanCode(scancodeposition) = 0x22 then ScanCodetoInKey = 88
    if ScanCode(scancodeposition) = 0x35 then ScanCodetoInKey = 89 'Y
    if ScanCode(scancodeposition) = 0x1A then ScanCodetoInKey = 90 'Z

    'If shift key and caps lock in same state, make lower case
    If PS2KeyShift = PS2CapsLock Then
    If scancodetoinkey >= 65 and scancodetoinkey <= 90 then
    scancodetoinkey += 32
    end if
    End If

    'Symbols
    If PS2KeyShift Then
    if ScanCode(scancodeposition) = 0x0E then ScanCodetoInKey = "~"
    if ScanCode(scancodeposition) = 0x4E then ScanCodetoInKey = "_"
    if ScanCode(scancodeposition) = 0x55 then ScanCodetoInKey = "+"
    if ScanCode(scancodeposition) = 0x5D then ScanCodetoInKey = "|"
    if ScanCode(scancodeposition) = 0x4c then ScanCodetoInKey = ":"
    if ScanCode(scancodeposition) = 0x52 then ScanCodetoInKey = 34
    if ScanCode(scancodeposition) = 0x41 then ScanCodetoInKey = "<"
    if ScanCode(scancodeposition) = 0x49 then ScanCodetoInKey = ">"
    if ScanCode(scancodeposition) = 0x4A then ScanCodetoInKey = "?"
    if ScanCode(scancodeposition) = 0x54 then ScanCodetoInKey = "{"
    if ScanCode(scancodeposition) = 0x5B then ScanCodetoInKey = "}"
    Else
    if ScanCode(scancodeposition) = 0x0E then ScanCodetoInKey = 96
    if ScanCode(scancodeposition) = 0x4E then ScanCodetoInKey = 45
    if ScanCode(scancodeposition) = 0x55 then ScanCodetoInKey = 61
    if ScanCode(scancodeposition) = 0x5D then ScanCodetoInKey = 92
    if ScanCode(scancodeposition) = 0x4c then ScanCodetoInKey = 59
    if ScanCode(scancodeposition) = 0x52 then ScanCodetoInKey = 39
    if ScanCode(scancodeposition) = 0x41 then ScanCodetoInKey = 44
    if ScanCode(scancodeposition) = 0x49 then ScanCodetoInKey = 46
    if ScanCode(scancodeposition) = 0x4A then ScanCodetoInKey = 47
    if ScanCode(scancodeposition) = 0x54 then ScanCodetoInKey = "["
    if ScanCode(scancodeposition) = 0x5B then ScanCodetoInKey = "]"
    End If
    else
    'This is key release.
    ScanCodetoInkey = 0
    End if
    End if
    End Function