430 lines
9.8 KiB
C++
430 lines
9.8 KiB
C++
#include "../Keyboard.h"
|
|
|
|
#include <go32.h>
|
|
|
|
#include "../Pic.h"
|
|
|
|
#define PIC
|
|
#define KEYB_DATA 0x60
|
|
|
|
Keyboard keyboard;
|
|
|
|
static const char *keyNames[] = {
|
|
"<unknown:00>",
|
|
"KeyEscape", // = 0x01,
|
|
"Key1", // = 0x02,
|
|
"Key2", // = 0x03,
|
|
"Key3", // = 0x04,
|
|
"Key4", // = 0x05,
|
|
"Key5", // = 0x06,
|
|
"Key6", // = 0x07,
|
|
"Key7", // = 0x08,
|
|
"Key8", // = 0x09,
|
|
"Key9", // = 0x0a,
|
|
"Key0", // = 0x0b,
|
|
"KeyMinus", // = 0x0c,
|
|
"KeyEqual", // = 0x0d,
|
|
"KeyBackspace", // = 0x0e,
|
|
"KeyTab", // = 0x0f,
|
|
|
|
"KeyQ", // = 0x10,
|
|
"KeyW", // = 0x11,
|
|
"KeyE", // = 0x12,
|
|
"KeyR", // = 0x13,
|
|
"KeyT", // = 0x14,
|
|
"KeyY", // = 0x15,
|
|
"KeyU", // = 0x16,
|
|
"KeyI", // = 0x17,
|
|
"KeyO", // = 0x18,
|
|
"KeyP", // = 0x19,
|
|
"KeyBracketLeft", // = 0x1a,
|
|
"KeyBracketRight", // = 0x1b,
|
|
"KeyEnter", // = 0x1c,
|
|
"KeyLeftCtrl", // = 0x1d,
|
|
"KeyA", // = 0x1e,
|
|
"KeyS", // = 0x1f,
|
|
|
|
"KeyD", // = 0x20,
|
|
"KeyF", // = 0x21,
|
|
"KeyG", // = 0x22,
|
|
"KeyH", // = 0x23,
|
|
"KeyJ", // = 0x24,
|
|
"KeyK", // = 0x25,
|
|
"KeyL", // = 0x26,
|
|
"KeySemicolon", // = 0x27,
|
|
"KeyApostrophe", // = 0x28,
|
|
"KeyBacktick", // = 0x29,
|
|
"KeyLeftShift", // = 0x2a,
|
|
"KeyBackslash", // = 0x2b,
|
|
"KeyZ", // = 0x2c,
|
|
"KeyX", // = 0x2d,
|
|
"KeyC", // = 0x2e,
|
|
"KeyV", // = 0x2f,
|
|
|
|
"KeyB", // = 0x30,
|
|
"KeyN", // = 0x31,
|
|
"KeyM", // = 0x32,
|
|
"KeyComma", // = 0x33,
|
|
"KeyPeriod", // = 0x34,
|
|
"KeySlash", // = 0x35,
|
|
"KeyRightShift", // = 0x36,
|
|
"KeyKeypadMultiply", // = 0x37,
|
|
"KeyLeftAlt", // = 0x38,
|
|
"KeySpace", // = 0x39,
|
|
"KeyCapsLock", // = 0x3a,
|
|
"KeyF1", // = 0x3b,
|
|
"KeyF2", // = 0x3c,
|
|
"KeyF3", // = 0x3d,
|
|
"KeyF4", // = 0x3e,
|
|
"KeyF5", // = 0x3f,
|
|
|
|
"KeyF6", // = 0x40,
|
|
"KeyF7", // = 0x41,
|
|
"KeyF8", // = 0x42,
|
|
"KeyF9", // = 0x43,
|
|
"KeyF10", // = 0x44,
|
|
"KeyNumLock", // = 0x45,
|
|
"KeyScrollLock", // = 0x46,
|
|
"KeyKeypad7", // = 0x47,
|
|
"KeyKeypad8", // = 0x48,
|
|
"KeyKeypad9", // = 0x49,
|
|
"KeyKeypadMinus", // = 0x4a,
|
|
"KeyKeypad4", // = 0x4b,
|
|
"KeyKeypad5", // = 0x4c,
|
|
"KeyKeypad6", // = 0x4d,
|
|
"KeyKeypadPlus", // = 0x4e,
|
|
"KeyKeypad1", // = 0x4f,
|
|
|
|
"KeyKeypad2", // = 0x50,
|
|
"KeyKeypad3", // = 0x51,
|
|
"KeyKeypad0", // = 0x52,
|
|
"KeyKeypadPeriod", // = 0x53,
|
|
"<unknown:54>",
|
|
"<unknown:55>",
|
|
"<unknown:56>",
|
|
"KeyF11", // = 0x57,
|
|
"KeyF12", // = 0x58,
|
|
"<unknown:59>",
|
|
"<unknown:5a>",
|
|
"<unknown:5b>",
|
|
"<unknown:5c>",
|
|
"<unknown:5d>",
|
|
"<unknown:5e>",
|
|
"<unknown:5f>",
|
|
|
|
"<unknown:60>",
|
|
"<unknown:61>",
|
|
"<unknown:62>",
|
|
"<unknown:63>",
|
|
"<unknown:64>",
|
|
"<unknown:65>",
|
|
"<unknown:66>",
|
|
"<unknown:67>",
|
|
"<unknown:68>",
|
|
"<unknown:69>",
|
|
"<unknown:6a>",
|
|
"<unknown:6b>",
|
|
"<unknown:6c>",
|
|
"<unknown:6d>",
|
|
"<unknown:6e>",
|
|
"<unknown:6f>",
|
|
|
|
"<unknown:70>",
|
|
"<unknown:71>",
|
|
"<unknown:72>",
|
|
"<unknown:73>",
|
|
"<unknown:74>",
|
|
"<unknown:75>",
|
|
"<unknown:76>",
|
|
"<unknown:77>",
|
|
"<unknown:78>",
|
|
"<unknown:79>",
|
|
"<unknown:7a>",
|
|
"<unknown:7b>",
|
|
"<unknown:7c>",
|
|
"<unknown:7d>",
|
|
"<unknown:7e>",
|
|
"<unknown:7f>",
|
|
|
|
"<unknown:80>",
|
|
"<unknown:81>",
|
|
"<unknown:82>",
|
|
"<unknown:83>",
|
|
"<unknown:84>",
|
|
"<unknown:85>",
|
|
"<unknown:86>",
|
|
"<unknown:87>",
|
|
"<unknown:88>",
|
|
"<unknown:89>",
|
|
"<unknown:8a>",
|
|
"<unknown:8b>",
|
|
"<unknown:8c>",
|
|
"<unknown:8d>",
|
|
"<unknown:8e>",
|
|
"<unknown:8f>",
|
|
|
|
"KeyMediaPrev", // = 0x90,
|
|
"<unknown:91>",
|
|
"<unknown:92>",
|
|
"<unknown:93>",
|
|
"<unknown:94>",
|
|
"<unknown:95>",
|
|
"<unknown:96>",
|
|
"<unknown:97>",
|
|
"<unknown:98>",
|
|
"KeyMediaNext", // = 0x99,
|
|
"<unknown:9a>",
|
|
"<unknown:9b>",
|
|
"KeyKeypadEnter", // = 0x9c,
|
|
"KeyRightControl", // = 0x9d,
|
|
"<unknown:9e>",
|
|
"<unknown:9f>",
|
|
|
|
"KeyMediaMute", // = 0xa0,
|
|
"KeyMediaCalculator", // = 0xa1,
|
|
"KeyMediaPlay", // = 0xa2,
|
|
"<unknown:a3>",
|
|
"KeyMediaStop", // = 0xa4,
|
|
"<unknown:a5>",
|
|
"<unknown:a6>",
|
|
"<unknown:a7>",
|
|
"<unknown:a8>",
|
|
"<unknown:a9>",
|
|
"<unknown:aa>",
|
|
"<unknown:ab>",
|
|
"<unknown:ac>",
|
|
"<unknown:ad>",
|
|
"KeyMediaVolumeDown", // = 0xae,
|
|
"<unknown:af>",
|
|
|
|
"KeyMediaVolumeUp", // = 0xb0,
|
|
"<unknown:b1>",
|
|
"KeyMediaWww", // = 0xb2,
|
|
"<unknown:b3>",
|
|
"<unknown:b4>",
|
|
"KeyKeypadDivide", // = 0xb5,
|
|
"<unknown:b6>",
|
|
"<unknown:b7>",
|
|
"KeyRightAlt", // = 0xb8,
|
|
"<unknown:b9>",
|
|
"<unknown:ba>",
|
|
"<unknown:bb>",
|
|
"<unknown:bc>",
|
|
"<unknown:bd>",
|
|
"<unknown:be>",
|
|
"<unknown:bf>",
|
|
|
|
"<unknown:c0>",
|
|
"<unknown:c1>",
|
|
"<unknown:c2>",
|
|
"<unknown:c3>",
|
|
"<unknown:c4>",
|
|
"<unknown:c5>",
|
|
"<unknown:c6>",
|
|
"KeyHome", // = 0xc7,
|
|
"KeyUp", // = 0xc8,
|
|
"KeyPageUp", // = 0xc9,
|
|
"<unknown:ca>",
|
|
"KeyLeft", // = 0xcb,
|
|
"<unknown:cc>",
|
|
"KeyRight", // = 0xcd,
|
|
"<unknown:ce>",
|
|
"KeyEnd", // = 0xcf,
|
|
|
|
"KeyDown", // = 0xd0,
|
|
"KeyPageDown", // = 0xd1,
|
|
"KeyInsert", // = 0xd2,
|
|
"KeyDelete", // = 0xd3,
|
|
"<unknown:d4>",
|
|
"<unknown:d5>",
|
|
"<unknown:d6>",
|
|
"<unknown:d7>",
|
|
"<unknown:d8>",
|
|
"<unknown:d9>",
|
|
"<unknown:da>",
|
|
"KeyLeftGui", // = 0xdb,
|
|
"KeyRightGui", // = 0xdc,
|
|
"KeyApps", // = 0xdd,
|
|
"KeyAcpiPower", // = 0xde,
|
|
"KeyAcpiSleep", // = 0xdf,
|
|
|
|
"<unknown:e0>",
|
|
"<unknown:e1>",
|
|
"<unknown:e2>",
|
|
"KeyAcpiWake", // = 0xe3,
|
|
"<unknown:e4>",
|
|
"KeyMediaWwwSearch", // = 0xe5,
|
|
"KeyMediaWwwFavorites", // = 0xe6,
|
|
"KeyMediaWwwRefresh", // = 0xe7,
|
|
"KeyMediaWwwStop", // = 0xe8,
|
|
"KeyMediaWwwForward", // = 0xe9,
|
|
"KeyMediaWwwBack", // = 0xea,
|
|
"KeyMediaMyComputer", // = 0xeb,
|
|
"KeyMediaEmail", // = 0xec,
|
|
"KeyMediaSelect", // = 0xed,
|
|
"<unknown:ee>",
|
|
"<unknown:ef>",
|
|
|
|
"<unknown:f0>",
|
|
"<unknown:f1>",
|
|
"<unknown:f2>",
|
|
"<unknown:f3>",
|
|
"<unknown:f4>",
|
|
"<unknown:f5>",
|
|
"<unknown:f6>",
|
|
"<unknown:f7>",
|
|
"<unknown:f8>",
|
|
"<unknown:f9>",
|
|
"<unknown:fa>",
|
|
"<unknown:fb>",
|
|
"<unknown:fc>",
|
|
"<unknown:fd>",
|
|
"KeyPrint", // = 0xfe,
|
|
"KeyPause", // = 0xff,
|
|
};
|
|
|
|
void keyboardIsr() {
|
|
keyboard.Isr();
|
|
}
|
|
|
|
Keyboard::Keyboard() {
|
|
_go32_dpmi_get_protected_mode_interrupt_vector(9, &_oldIsr);
|
|
|
|
_newIsr.pm_offset = (int)keyboardIsr;
|
|
_newIsr.pm_selector = _go32_my_cs();
|
|
_go32_dpmi_allocate_iret_wrapper(&_newIsr);
|
|
_go32_dpmi_set_protected_mode_interrupt_vector(9, &_newIsr);
|
|
}
|
|
|
|
Keyboard::~Keyboard() {
|
|
_go32_dpmi_set_protected_mode_interrupt_vector(9, &_oldIsr);
|
|
_go32_dpmi_free_iret_wrapper(&_newIsr);
|
|
}
|
|
|
|
Keyboard::KeyHandleFunction Keyboard::setKeyUpHandler(KeyHandleFunction handler) {
|
|
auto oldHandler = _keyUpHandler;
|
|
_keyUpHandler = handler;
|
|
return oldHandler;
|
|
}
|
|
|
|
Keyboard::KeyHandleFunction Keyboard::setKeyDownHandler(KeyHandleFunction handler) {
|
|
auto oldHandler = _keyDownHandler;
|
|
_keyDownHandler = handler;
|
|
return oldHandler;
|
|
}
|
|
|
|
Keyboard::KeyHandleFunction Keyboard::setKeyRepeatHandler(KeyHandleFunction handler) {
|
|
auto oldHandler = _keyRepeatHandler;
|
|
_keyRepeatHandler = handler;
|
|
return oldHandler;
|
|
}
|
|
|
|
const char *Keyboard::getKeyName(unsigned char keyCode) {
|
|
return keyNames[keyCode];
|
|
}
|
|
|
|
void Keyboard::Isr() {
|
|
auto code = inb(KEYB_DATA);
|
|
switch (_state) {
|
|
case Start:
|
|
if (code == 0xe0) {
|
|
_state = Extended;
|
|
break;
|
|
}
|
|
if (code == 0xe1) {
|
|
_state = PauseBegin;
|
|
break;
|
|
}
|
|
if (code & 0x80) {
|
|
_state = Start;
|
|
keyUp(code & 0x7f);
|
|
} else {
|
|
_state = Start;
|
|
keyDown(code & 0x7f);
|
|
}
|
|
break;
|
|
case Extended:
|
|
if (code == 0x2a) {
|
|
_state = PrintPressed1;
|
|
break;
|
|
}
|
|
if (code == 0xb7) {
|
|
_state = PrintReleased1;
|
|
break;
|
|
}
|
|
if (code & 0x80) {
|
|
_state = Start;
|
|
keyUp(0x80 + (code & 0x7f));
|
|
} else {
|
|
_state = Start;
|
|
keyDown(0x80 + code);
|
|
}
|
|
break;
|
|
case PauseBegin:
|
|
if (code == 0x1d) {
|
|
_state = PausePressed1;
|
|
break;
|
|
}
|
|
if (code == 0x9d) {
|
|
_state = PauseReleased1;
|
|
break;
|
|
}
|
|
_state = Start;
|
|
break;
|
|
case PausePressed1:
|
|
if (code == 45) {
|
|
keyDown(KeyPause);
|
|
}
|
|
_state = Start;
|
|
break;
|
|
case PauseReleased1:
|
|
if (code == 0xc5) {
|
|
keyUp(KeyPause);
|
|
}
|
|
_state = Start;
|
|
break;
|
|
case PrintPressed1:
|
|
if (code == 0xe0) {
|
|
_state = PrintPressed2;
|
|
break;
|
|
}
|
|
_state = Start;
|
|
break;
|
|
case PrintPressed2:
|
|
if (code == 0x37) {
|
|
keyDown(KeyPrint);
|
|
}
|
|
_state = Start;
|
|
break;
|
|
case PrintReleased1:
|
|
if (code == 0xe0) {
|
|
_state = PrintReleased2;
|
|
break;
|
|
}
|
|
_state = Start;
|
|
break;
|
|
case PrintReleased2:
|
|
if (code == 0xaa) {
|
|
keyUp(KeyPrint);
|
|
}
|
|
_state = Start;
|
|
break;
|
|
}
|
|
|
|
Pic::clearInterrupt();
|
|
}
|
|
|
|
void Keyboard::keyDown(unsigned char c) {
|
|
if (keyState[c]) {
|
|
if (_keyRepeatHandler) _keyRepeatHandler(c);
|
|
} else {
|
|
keyState[c] = true;
|
|
if (_keyDownHandler) _keyDownHandler(c);
|
|
}
|
|
}
|
|
|
|
void Keyboard::keyUp(unsigned char c) {
|
|
keyState[c] = false;
|
|
if (_keyUpHandler) _keyUpHandler(c);
|
|
}
|