Page 1 of 2
PS/2 keyboards...
Posted: Fri May 17, 2024 6:08 am
by barnacle
I'd just like to rant and ask - what were they thinking?
Getting raw data from the keyboard is trivial (and I note that the recently purchased second hand Dell keyboard that I'm playing with both works at 3.3v and 5v, and takes so little current that it doesn't show on my power supply) but converting the output into something useful is, um, a non-trivial activity...
It probably doesn't help that I don't want to limit myself to the normal typing block - I also want to implement ctrl, alt, and ctrl-alt combinations for letters and ctrl and alt for numbers (though I'm not sure I'll ever use the latter) and definitely want the function keys and caps lock. Oh, and a pound sign '£', what with being English and all. Which isn't an ascii codepoint anyway, but lives on shift-3 on a UK keyboard.
So I've had to redefine (cough, 'extend') the ascii set to use eight bits:
Code: Select all
// control codes including cr, lf, tab etc
#define K_NULL 0x00
#define K_CTL_A 0x01
<...>
#define K_CTL_Z 0x1a
#define K_ESC 0x1b
#define K_POUND 0x1f // £ sign
// standard ascii
#define K_SPACE 0x20
<...>
#define K_DEL 0x7f
// alt letters
// 0x80
#define K_ALT_A 0x81
<...>
#define K_ALT_Z 0x9a
// control numbers
#define K_CTL_0 0xa0
<...>
#define K_CTL_9 0xa9
// alt numbers
#define K_ALT_0 0xb0
<...>
#define K_ALT_9 0xb9
// ctrl-alt letters
// 0xc0
#define K_CTRALT_A 0xc1
<...>
#define K_CTRALT_Z 0xda
// cursor keys
#define K_LEFT 0xe0
#define K_RIGHT 0xe1
#define K_UPARROW 0xe2
#define K_DOWN 0xe3
#define K_PAGEUP 0xe4
#define K_PAGEDOWN 0xe5
#define K_HOME 0xe6
#define K_END 0xe7
#define K_INSERT 0xe8
#define K_DELETE 0xe9
// function keys
// 0xf0
#define K_F1 0xf1
<...>
#define K_F12 0xfc
Code is as yet incomplete; it's in C to run on an STM arm chip which will act as an SPI slave to a 65c02 and also provide serial interfaces. The combination of press and release and oddball (unnecessary) extension codes makes it interesting.
Neil
Re: PS/2 keyboards...
Posted: Fri May 17, 2024 7:00 am
by Yuri
I'd just like to rant and ask - what were they thinking?

Might not want to ask.
I've wondered about this myself. 7-bits could transmit some 128 scan codes with a make/break bit. Most keyboards don't have that many keys, yet, keys like Home, End, etc needed an "extended" scan code..... IDK why.
It probably doesn't help that I don't want to limit myself to the normal typing block - I also want to implement ctrl, alt, and ctrl-alt combinations for letters and ctrl and alt for numbers (though I'm not sure I'll ever use the latter) and definitely want the function keys and caps lock. Oh, and a pound sign '£', what with being English and all. Which isn't an ascii codepoint anyway, but lives on shift-3 on a UK keyboard.
So I've had to redefine (cough, 'extend') the ascii set to use eight bits:
...
Code is as yet incomplete; it's in C to run on an STM arm chip which will act as an SPI slave to a 65c02 and also provide serial interfaces. The combination of press and release and oddball (unnecessary) extension codes makes it interesting.
Neil
Most of the time I've just processed the scan codes on the CPU itself. (Though that was for x86 based OSes I've tinkered with)
For 65xxx setups I've considered throwing the work onto a PIC16F871 where I can use it's own internal memory as a ring buffer, and raise an interrupt when there's data available.
Re: PS/2 keyboards...
Posted: Fri May 17, 2024 7:28 am
by barnacle
That's the plan with an STM32L073, largely because I've got a box full of the damn things
Nice that it can handle up to five serial ports as well, with internal buffering, though I'm only planning for one.
So we have an 8048 talking to an STM arm talking to a 65C02. The eighties called - they want their processors back!
Neil
p.s. The windows event loop throws (threw? I'm not current with anything 64-bit) keypresses and releases onto the event chain and lets the application sort out what it needs, but it does some pre-processing of the data so the application never sees the extended code or the release code, just a defined key code. I'm not planning on telling the 6502 when a key is released, but I am leaving an option to return raw data on request.
Re: PS/2 keyboards...
Posted: Fri May 17, 2024 7:33 am
by Yuri
p.s. The windows event loop throws (threw? I'm not current with anything 64-bit) keypresses and releases onto the event chain and lets the application sort out what it needs, but it does some pre-processing of the data so the application never sees the extended code or the release code, just a defined key code.
To some extent. (Win32 API is still the under pins Win64, so not much has changed there)
I know with DirectX you can get a lot more detail about the make/break codes. But I recall looking through the Quake 2 source code way back in the day, and as I recall, Carmack just used the normal Win32 key events; so apparently they were "good enough".
Re: PS/2 keyboards...
Posted: Fri May 17, 2024 3:44 pm
by BigDumbDinosaur
I'd just like to rant and ask - what were they thinking?

Probably a design-by-committee process got involved. You have to consider the origins of the keyboard design. IBM is/was full of committees. 
Oh, and a pound sign '£', what with being English and all...
...says the guy in Germany, where they use euros. 
Re: PS/2 keyboards...
Posted: Fri May 17, 2024 3:47 pm
by barnacle
Oh, and a pound sign '£', what with being English and all...
...says the guy in Germany, where they use euros. 
Yup! Left off the ä, ö, ü, and ß, too... UTF-8 is not in my immediate plans. I just feel that if I have a £ key, it ought to do something.
Neil
Re: PS/2 keyboards...
Posted: Fri May 17, 2024 4:17 pm
by barnacle
Getting raw data from the keyboard is trivial
Even more trivial when you plug the data wire into the correct pin on the Nucleo...
Neil
Re: PS/2 keyboards...
Posted: Fri May 17, 2024 6:27 pm
by barnacle
Encouraging. The majority of the keyboard is producing something useful, and in the majority of cases the right something. I still need to sort out the 0xe0 prefixed keys, and for some reason the numeric key pad is all over the place - probably my lookup table is incorrect.
Neil
Re: PS/2 keyboards...
Posted: Mon Jun 03, 2024 7:32 pm
by barnacle
There must be a more elegant way to handle shift and capslock... capslock has to shift the alpha characters only, unless shift is active, but the number keys have to respond to shift but ignore capslock.
Shift is true when the shift key is held; capslock is toggled whenever it's pressed. Ukupper and uklower are tables where the scancode indexes the desired keyboard mapping.
Code: Select all
// shift affects all keys; shift lock only alpha
if (shift)
{
if (!shiftlock)
{
ret = ukupper[scancode];
}
else
{
ret = uklower[scancode];
if (!isalpha(ret))
{
ret = ukupper[scancode];
}
}
}
else
{
if (!shiftlock)
{
ret = uklower[scancode];
}
else
{
ret = ukupper[scancode];
if (!isalpha(ret))
{
ret = uklower[scancode];
}
}
}
That works, but it feels ugly...
Neil
Re: PS/2 keyboards...
Posted: Mon Jun 03, 2024 8:31 pm
by barnacle
So here's a mostly complete keyboard driver to translate PS/2 keycodes - including function keys and cursor controls into a modified ascii output on key press ( key release is ignored except for the control, shift, alt etc keys which are handled internally).
A few odd keys are ignored and some may cause immediately following keys to be ignored - particularly print-screen, scroll-lock, and pause-break. This is for my Compaq keyboard - UK 104 layout; it's obvious where to change the keyboard mapping.
0x00-0x1a: ctrl-A to ctrl-Z
0x1b: ESC
0x1c: ctrl-TAB
0x1d: alt-TAB
0x1e: shift-TAB (for text editors)
0x1f: UK Pound
0x20-0x7f: normal ascii characters
0x81-0x9a: alt-A to alt-Z
0xa1-0xba: ctrl-alt-A to ctrl-alt-Z
Cursor keys:
0xe0: left
0xe1: right
0xe2: up
0xe3: down
0xe4: page up
0xe5: page down
0xe6: home
0xe7: end
0xe8: insert
And the function keys: 0xf1-0xfc.
There is no number lock; I prefer it as a number pad all the time but it's easy enough to add.
For what it's worth, the interrupt routine to grab the next bit is five lines of code and the test for completion another five...
Neil
Re: PS/2 keyboards...
Posted: Mon Jun 03, 2024 11:21 pm
by Yuri
There must be a more elegant way to handle shift and capslock... capslock has to shift the alpha characters only, unless shift is active, but the number keys have to respond to shift but ignore capslock.
Shift is true when the shift key is held; capslock is toggled whenever it's pressed. Ukupper and uklower are tables where the scancode indexes the desired keyboard mapping.
Code: Select all
// shift affects all keys; shift lock only alpha
if (shift)
{
if (!shiftlock)
{
ret = ukupper[scancode];
}
else
{
ret = uklower[scancode];
if (!isalpha(ret))
{
ret = ukupper[scancode];
}
}
}
else
{
if (!shiftlock)
{
ret = uklower[scancode];
}
else
{
ret = ukupper[scancode];
if (!isalpha(ret))
{
ret = uklower[scancode];
}
}
}
That works, but it feels ugly...
Neil
Maybe something like so?
Code: Select all
int ret = uklower[scancode];
ret = (isalpha(ret) && (shift ^ shiftlock)) | (!isalpha(ret) && shift) ? ukupper[scancode] : ret;
(Haven't tried this logic myself, but I think that might be closer to what you're looking for)
Re: PS/2 keyboards...
Posted: Tue Jun 04, 2024 5:28 am
by barnacle
Maybe something like so?
Code: Select all
int ret = uklower[scancode];
ret = (isalpha(ret) && (shift ^ shiftlock)) | (!isalpha(ret) && shift) ? ukupper[scancode] : ret;
Thanks Yuri, much tidier. Needs a || in the middle instead of a | but that's what I couldn't get my head round. (I only have a small execution stack in my head and it kept overflowing

)
I've also modified the alt/ctrl logic so that alt-alpha is now the more logical 0xc0-0xdf and ctrl-alt-alpha 0x80-0x9f.
Neil
Re: PS/2 keyboards...
Posted: Wed Jun 19, 2024 3:16 am
by jgharston
So here's a mostly complete keyboard driver to translate PS/2 keycodes - including function keys and cursor controls into a modified ascii output on key press ( key release is ignored except for the control, shift, alt etc keys which are handled internally).
...
0x00-0x1a: ctrl-A to ctrl-Z
0x1b: ESC
0x1c: ctrl-TAB
0x1d: alt-TAB
0x1e: shift-TAB (for text editors)
0x1f: UK Pound
So what does Ctrl-\ give? And Ctrl-] Ctrl-^ Ctrl-_
I use 0x80+n for function keys and 0xC0+n for editing keys with Shift,Ctrl,Alt encoded in b6-b5-b4, allowing 0xD5=Shift-TAB, 0xE5=Ctrl-TAB, 0xF5=Alt-TAB.
Re: PS/2 keyboards...
Posted: Wed Jun 19, 2024 6:56 am
by barnacle
It shouldn't give anything. I only applied the control and tab modifiers to alpha keys. Also, shift is ignored if control or alt are active.
Neil
Re: PS/2 keyboards...
Posted: Fri Jun 21, 2024 5:13 pm
by jgharston
I've also just noticed you've got: 0xe0: left, 0xe1: right, 0xe2: up, 0xe3: down.
Cursor controls are ordered 8,9,10,11 left,right,down,up so it's always useful to order input cursor controls the same, ie:
base+0:left, base+1:right, base+2:down, base+3:up, similarly:
base+0:home, base+1:end, base+2:pgdn, base+3:pgup
Eg, my code has &C8-&CF as home,end,pgdn,pgup,left,right,down,up
(quickly checks
docs... make sure I'm not talking rubbish

)