#include "Keyboard.h" #include #include "Pic.h" #define PIC #define KEYB_DATA 0x60 Keyboard keyboard; static const char *keyNames[] = { "", "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, "", "", "", "KeyF11", // = 0x57, "KeyF12", // = 0x58, "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "KeyMediaPrev", // = 0x90, "", "", "", "", "", "", "", "", "KeyMediaNext", // = 0x99, "", "", "KeyKeypadEnter", // = 0x9c, "KeyRightControl", // = 0x9d, "", "", "KeyMediaMute", // = 0xa0, "KeyMediaCalculator", // = 0xa1, "KeyMediaPlay", // = 0xa2, "", "KeyMediaStop", // = 0xa4, "", "", "", "", "", "", "", "", "", "KeyMediaVolumeDown", // = 0xae, "", "KeyMediaVolumeUp", // = 0xb0, "", "KeyMediaWww", // = 0xb2, "", "", "KeyKeypadDivide", // = 0xb5, "", "", "KeyRightAlt", // = 0xb8, "", "", "", "", "", "", "", "", "", "", "", "", "", "", "KeyHome", // = 0xc7, "KeyUp", // = 0xc8, "KeyPageUp", // = 0xc9, "", "KeyLeft", // = 0xcb, "", "KeyRight", // = 0xcd, "", "KeyEnd", // = 0xcf, "KeyDown", // = 0xd0, "KeyPageDown", // = 0xd1, "KeyInsert", // = 0xd2, "KeyDelete", // = 0xd3, "", "", "", "", "", "", "", "KeyLeftGui", // = 0xdb, "KeyRightGui", // = 0xdc, "KeyApps", // = 0xdd, "KeyAcpiPower", // = 0xde, "KeyAcpiSleep", // = 0xdf, "", "", "", "KeyAcpiWake", // = 0xe3, "", "KeyMediaWwwSearch", // = 0xe5, "KeyMediaWwwFavorites", // = 0xe6, "KeyMediaWwwRefresh", // = 0xe7, "KeyMediaWwwStop", // = 0xe8, "KeyMediaWwwForward", // = 0xe9, "KeyMediaWwwBack", // = 0xea, "KeyMediaMyComputer", // = 0xeb, "KeyMediaEmail", // = 0xec, "KeyMediaSelect", // = 0xed, "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "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); }