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.
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
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Here's a first draft (haven't tested this code yet)
' PS/2 Keyboard/mouse routines for Great Cow Basic'OriginalcodeCopyright(c)2006-2010HughConsidine'Modified by Dan Damron VE6IBM'#definePS2DataSysTemp.0' Set to Data Pin'#definePS2ClockSysTemp.0' Set to Clock Pin#Startup InitPS2'Flags#definePS2KeyShiftPS2Flags.0#definePS2KeyCtrlPS2Flags.1#definePS2KeyAltPS2Flags.2#definePS2NumLockPS2Flags.3#definePS2CapsLockPS2Flags.4#definePS2ScrollLockPS2Flags.5#definePS2ExtendedPS2Flags.6#definePS2ReleasePS2Flags.7'Initializesub InitPS2 'InhibitDeviceDIRPS2ClockOutDIRPS2DataINsetPS2ClockOffendsubfunctionPS2ReadBytePS2ReadByte=0'Release bus Dir PS2Clock In 'GivedevicetimetorespondWait25us'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 'StartBitIfPS2Data=ONThenGotoPS2ReadByteDoneWaitUntilPS2Clock=ON'8 data bits For PS2Bit = 1 to 8 wait until PS2Clock = OFF ROTATE PS2ReadByte RIGHT PS2ReadByte.7 = PS2Data wait until PS2Clock = ON Next 'ParitybitwaituntilPS2Clock=OFFwaituntilPS2Clock=ON'End bit wait until PS2Clock = OFF wait until PS2Clock = ON 'InhibitbusPS2ReadByteDone:
DIRPS2ClockOutSetPS2ClockOffWait100us#ifdefPS2_DELAYWaitPS2_DELAY#endifendfunctionsubPS2WriteByte(InPS2Byte)'Pull data down, then release clock Dir PS2Data Out Set PS2Data Off Wait 10 us Dir PS2Clock In 'Waitupto20msfordevicetopullclockdownPS2Bit=0DoWhilePS2Clock=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 '8databitsPS2Parity=0ForPS2Bit=1to8IfPS2Byte.0=OffthenSetPS2DataoffElseSetPS2DataonPS2Parity+=1EndIfROTATEPS2ByteRIGHTWaituntilPS2Clock=OnwaituntilPS2Clock=OffNext'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 'StopDirPS2DataIn'Ack Wait Until PS2Data = Off wait until PS2Clock = OFF wait until PS2Clock = ON 'InhibitbusPS2WriteByteDone:
DirPS2ClockOutSetPS2ClockOffWait100us#ifdefPS2_DELAYWaitPS2_DELAY#endifEndSubSubPS2SyncKBLeds'Get value PS2Value = 0 If PS2NumLock Then PS2Value.1 = On If PS2CapsLock Then PS2Value.2 = On If PS2ScrollLock Then PS2Value.0 = On 'SendLEDcommandPS2WriteByte(0xED)PS2Parity=PS2ReadByte'Send value PS2WriteByte (PS2Value) PS2Parity = PS2ReadByteEnd Sub'''KeyboardLEDsettingroutine'''@param PS2Value Value to send. Bits 0-2 control LEDsSub PS2SetKBLeds (In PS2Value) 'SendLEDcommandPS2WriteByte(0xED)PS2Parity=PS2ReadByte'Send value PS2WriteByte (PS2Value) PS2Parity = PS2ReadByteEnd Subfunction PS2ScanCode as String PS2ScanCode = "" PS2GetAnotherScanCode: 'GetkeyscancodeScanCode=PS2ReadByteifScanCode=0thenexitfunctionPS2ScanCode+=ScanCodeifScanCode=0xF0thengotoPS2GetAnotherScanCodeendififScanCode=0xE0thengotoPS2GetAnotherScanCodeendifendfunctionfunctionScanCodetoInkey(InScanCodeAsstring)scancodeposition=1ScanCodetoInkey=0GetAnotherScanCode:
selectcaseScanCode(scancodeposition)'Key Release case = 0xF0 PS2Release = 1 scancodeposition ++ goto GetAnotherScanCode 'Shiftcase=0x12'l Shift if PS2Release = 1 then PS2KeyShift = 1 else PS2KeyShift = 0 end if case = 0x31 'RShiftifPS2Release=1thenPS2KeyShift=1elsePS2KeyShift=0endif'Ctrl case = 0x14 'lCtrl,RCtrl(extended)ifPS2Release=1thenPS2KeyCtrl=1elsePS2KeyCtrl=0endif'Caps Lock case 0x58 if PS2Release = 0 then PS2CapsLock = not PS2CapsLock PS2SyncKBLeds scancodeposition ++ goto GetAnotherScanCode end if 'NumLockcase0x77ifPS2Release=0thenPS2NumLock=notPS2NumLockPS2SyncKBLedsScancodeposition++gotoGetAnotherScanCodeendif'Scroll Lock if PS2Release = 0 then PS2ScrollLock = not PS2ScrollLock PS2SyncKBLeds ScanCodePosition ++ goto GetAnotherScanCode end if 'ControlCharscase0x5A'Enter scancodetoinkey = 13 case 0x66 'Backspacescancodetoinkey=8case0x76'Esc scancodetoinkey = 27 case 0x29 'Spacescancodetoinkey=32case=0xE0'Extended PS2Extended = 1 scancodeposition ++ goto GetAnotherScanCode 'Letterscase=0x1C'aA scancodetoinkey = 65 case = 0x32 scancodetoinkey = 66 case = 0x21 'cCscancodetoinkey=67case=0x23scancodetoinkey=68case=0x24'eE scancodetoinkey = 69 case = 0x2B scancodetoinkey = 70 case = 0x34 'gGscancodetoinkey=71case=0x33scancodetoinkey=72case=0x43'iI scancodetoinkey = 73 case = 0x3B scancodetoinkey = 74 case = 0x42 'kKscancodetoinkey=75case=0x4Bscancodetoinkey=76case=0x3A'mM scancodetoinkey = 77 case = 0x31 scancodetoinkey = 78 case = 0x44 'oOscancodetoinkey=79case=0x4dscancodetoinkey=80case=0x15'qQ scancodetoinkey = 81 case = 0x2D scancodetoinkey = 82 case = 0x1B 'sSscancodetoinkey=83case=0x2Cscancodetoinkey=84case=0x3C'uU scancodetoinkey = 85 case = 0x2A scancodetoinkey = 86 case = 0x1D 'wWscancodetoinkey=87case=0x22scancodetoinkey=88case=0x35'yY scancodetoinkey = 89 case = 0x1A 'zZscancodetoinkey=90endselect'if CTRL flag, reduce to ctrl characters if PS2KeyCtrl then if scancodetoinkey >= 65 and scancodetoinkey <=90 then scancodetoinkey -=64 end if 'Ifshiftkeyandcapslockinsamestate,makelowercaseIfPS2KeyShift=PS2CapsLockThenIfscancodetoinkey>=65andscancodetoinkey<=90Thenscancodetoinkey+=32EndIf'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 'SymbolsIfPS2KeyShiftThenifScanCode(scancodeposition)=0x0EthenScanCodetoInKey="~"ifScanCode(scancodeposition)=0x4EthenScanCodetoInKey="_"ifScanCode(scancodeposition)=0x55thenScanCodetoInKey="+"ifScanCode(scancodeposition)=0x5DthenScanCodetoInKey="|"ifScanCode(scancodeposition)=0x4cthenScanCodetoInKey=":"ifScanCode(scancodeposition)=0x52thenScanCodetoInKey=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 IfEnd Function
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
'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
'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
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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)
;Startuproutine#startupInitPS2;Defines(Constants)#definePS2KeyShiftPS2Flags.0#definePS2KeyCtrlPS2Flags.1#definePS2KeyAltPS2Flags.2#definePS2NumLockPS2Flags.3#definePS2CapsLockPS2Flags.4#definePS2ScrollLockPS2Flags.5#definePS2ExtendedPS2Flags.6#definePS2ReleasePS2Flags.7' PS/2 Keyboard/mouse routines for Great Cow Basic'OriginalcodeCopyright(c)2006-2010HughConsidine'Modified by Dan Damron VE6IBM'#definePS2DataSysTemp.0' Set to Data Pin'#definePS2ClockSysTemp.0' Set to Clock Pin'Flags'InitializeSub InitPS2 'InhibitDeviceDIRPS2ClockOutDIRPS2DataINsetPS2ClockOffEndSubFunctionPS2ReadBytePS2ReadByte=0'Release bus Dir PS2Clock In 'GivedevicetimetorespondWait25us'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 'StartBitIfPS2Data=ONthenGotoPS2ReadByteDoneendifWaitUntilPS2Clock=ON'8 data bits For PS2Bit = 1 to 8 Wait until PS2Clock = OFF ROTATE PS2ReadByte RIGHT PS2ReadByte.7 = PS2Data Wait until PS2Clock = ON Next 'ParitybitWaituntilPS2Clock=OFFWaituntilPS2Clock=ON'End bit Wait until PS2Clock = OFF Wait until PS2Clock = ON 'InhibitbusPS2ReadByteDone:
DIRPS2ClockOutSetPS2ClockOffWait100us#ifdefPS2_DELAYWaitPS2_DELAY#endifEndFunctionSubPS2WriteByte(InPS2Byte)'Pull data down, then release clock Dir PS2Data Out Set PS2Data Off Wait 10 us Dir PS2Clock In 'Waitupto20msfordevicetopullclockdownPS2Bit=0DoWhilePS2Clock=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 '8databitsPS2Parity=0ForPS2Bit=1to8IfPS2Byte.0=OffthenSetPS2DataoffElseSetPS2DataonPS2Parity=PS2Parity+1EndIfROTATEPS2ByteRIGHTWaituntilPS2Clock=OnWaituntilPS2Clock=OffNext'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 'StopDirPS2DataIn'Ack Wait Until PS2Data = Off Wait until PS2Clock = OFF Wait until PS2Clock = ON 'InhibitbusPS2WriteByteDone:
DirPS2ClockOutSetPS2ClockOffWait100us#ifdefPS2_DELAYWaitPS2_DELAY#endifEndSubSubPS2SyncKBLeds'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 'SendLEDcommandPS2WriteByte(0xED)PS2Parity=PS2ReadByte'Send value PS2WriteByte (PS2Value) PS2Parity = PS2ReadByteEnd Sub'''KeyboardLEDsettingroutine'''@param PS2Value Value to send. Bits 0-2 control LEDsSub PS2SetKBLeds (In PS2Value) 'SendLEDcommandPS2WriteByte(0xED)PS2Parity=PS2ReadByte'Send value PS2WriteByte (PS2Value) PS2Parity = PS2ReadByteEnd SubFunction PS2ScanCode as string PS2Extended = 0 PS2Release = 0 charcounter = 1 'GetkeyscancodeMyScanCode=PS2ReadByteifMyScanCode=0thenPS2ScanCode=""exitfunctionendifAgain:
PS2ScanCode(charcounter)=MyScanCodeifMyScanCode=0xF0then' key released charcounter +=1 PS2Release = 1 Do MyScanCode = PS2ReadByte Loop While MyScanCode = 0 goto Again end if if MyScanCode = 0xE0 then 'extendedcharcounter+=1PS2Extended=1DoMyScanCode=PS2ReadByteLoopWhileMyScanCode=0GotoAgainendifps2ScanCode(0)=charcounterEndFunctionfunctionINKEY'Initialise INKEY = 0 PS2GetAnotherKey: 'GetkeyscancodeScanCode=PS2ReadByteifScanCode=0thenexitfunction'Set flags PS2Extended = 0 PS2Release = 0 '2-bytekey?ifScanCode=0xE0thenPS2Extended=1DoScanCode=PS2ReadByteLoopWhileScanCode=0endif'Key released? If ScanCode = 0xF0 Then PS2Release = 1 Do ScanCode = PS2ReadByte Loop While ScanCode = 0 End If 'ExtendedcharsIfPS2ExtendedThen'Non-extended chars Else 'Shiftpressed/releasedIfScanCode=0x12orScanCode=0x59thenIfPS2ReleaseThenPS2KeyShift=0ElsePS2KeyShift=1EndIfGotoPS2GetAnotherKeyEndIfIfPS2Release=0Then'Caps Lock pressed if ScanCode = 0x58 then If PS2CapsLock Then PS2CapsLock = 0 Else PS2CapsLock = 1 End If PS2SyncKBLeds Goto PS2GetAnotherKey end if 'NumlockpressedifScanCode=0x77thenIfPS2NumLockThenPS2NumLock=0ElsePS2NumLock=1EndIfPS2SyncKBLedsGotoPS2GetAnotherKeyendif'Scroll lock pressed if ScanCode = 0x7E then If PS2ScrollLock Then PS2ScrollLock = 0 Else PS2ScrollLock = 1 End If PS2SyncKBLeds Goto PS2GetAnotherKey end if 'TranslatescancodetoASCII'Control Chars if ScanCode = 0x5A then INKEY = 13 'EnterifScanCode=0x66thenINKEY=8'Backspace if ScanCode = 0x76 then INKEY = 27 'EscifScanCode=0x29thenINKEY=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 'LettersifScanCode=0x1CthenINKEY=65'A if ScanCode = 0x32 then INKEY = 66 if ScanCode = 0x21 then INKEY = 67 'CifScanCode=0x23thenINKEY=68ifScanCode=0x24thenINKEY=69'E if ScanCode = 0x2B then INKEY = 70 if ScanCode = 0x34 then INKEY = 71 'GifScanCode=0x33thenINKEY=72ifScanCode=0x43thenINKEY=73'I if ScanCode = 0x3B then INKEY = 74 if ScanCode = 0x42 then INKEY = 75 'KifScanCode=0x4BthenINKEY=76ifScanCode=0x3AthenINKEY=77'M if ScanCode = 0x31 then INKEY = 78 if ScanCode = 0x44 then INKEY = 79 'OifScanCode=0x4DthenINKEY=80ifScanCode=0x15thenINKEY=81'Q if ScanCode = 0x2D then INKEY = 82 if ScanCode = 0x1B then INKEY = 83 'SifScanCode=0x2CthenINKEY=84ifScanCode=0x3CthenINKEY=85'U if ScanCode = 0x2A then INKEY = 86 if ScanCode = 0x1D then INKEY = 87 'WifScanCode=0x22thenINKEY=88ifScanCode=0x35thenINKEY=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 'SymbolsIfPS2KeyShiftThenifScanCode=0x0EthenINKEY="~"ifScanCode=0x4EthenINKEY="_"ifScanCode=0x55thenINKEY="+"ifScanCode=0x5DthenINKEY="|"ifScanCode=0x4cthenINKEY=":"ifScanCode=0x52thenINKEY=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 Ifend functionFunction 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 ifEnd Function
My Test Program (using a 40x4 character based LCD in 2bit mode) is also attached:
;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.
' 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
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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
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
Here's a first draft (haven't tested this code yet)
Damn BBCode… here it is again in a quote
'#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
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)
My Test Program (using a 40x4 character based LCD in 2bit mode) is also attached:
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