//----------------------------------------------------------------------------// // OS on Kaleid // // // // Desc: Basic Keyboard Driver // // // // // // Copyright © 2018-2021 The OS/K Team // // // // This file is part of OS/K. // // // // OS/K is free software: you can redistribute it and/or modify // // it under the terms of the GNU General Public License as published by // // the Free Software Foundation, either version 3 of the License, or // // any later version. // // // // OS/K is distributed in the hope that it will be useful, // // but WITHOUT ANY WARRANTY//without even the implied warranty of // // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // // GNU General Public License for more details. // // // // You should have received a copy of the GNU General Public License // // along with OS/K. If not, see . // //----------------------------------------------------------------------------// #include #include #include #include "scan.c" #define KEY(code) (table[2*(code)]) #define FLAGS(code) (table[2*(code)+1]) static bool capsLockActive = 0; static bool e0received = 0; static bool altPressed = 0; static bool altGrPressed = 0; static bool shiftPressed = 0; static bool controlPressed = 0; static void KeybPrint(uchar _code) { uint code = (uint)_code; const uint *table; if (!e0received) { table = (altPressed ? LeftAltScanCodes : (controlPressed ? LeftControlScanCodes : (shiftPressed ? LeftShiftScanCodes : (altGrPressed ? AltGrScanCodes : RegularScanCodes)))); } else { table = E0ScanCodes; e0received = 0; } if ((capsLockActive && (FLAGS(code) & CAPSLOCK)) && !(altPressed || controlPressed)) { if (shiftPressed) table = RegularScanCodes; else table = LeftShiftScanCodes; } uchar ch = KEY(code); if (!ch) { switch (code) { case 0xE0: e0received = 1; break; case 0x38: if (table == E0ScanCodes) altGrPressed = 1; else altPressed = 1; break; case 0xB8: if (table == E0ScanCodes) altGrPressed = 0; else altPressed = 0; break; case 0x36: case 0x2A: shiftPressed = 1; break; case 0xB6: case 0xAA: shiftPressed = 0; break; case 0x1D: controlPressed = 1; break; case 0x9D: controlPressed = 0; break; case 0x3A: capsLockActive = !capsLockActive; break; } return; } bputc(BStdIn, ch); } static void KeybHandler(ISRFrame_t *regs) { char status; uchar code = 0; // write EOI IoWriteByteOnPort(0x20, 0x20); status = IoReadByteFromPort(0x64); if (status & 0x01) { code = IoReadByteFromPort(0x60); } KeybPrint(code); KeSendEOItoPIC(0x21); } void IoCreateInputBuffer(void) { error_t rc; rc = BOpenPureBuf(&BStdIn, BS_RDWR, 4 * KB); if (rc) KeStartPanic("[Keyb] Couldn't create BStdIn"); //BEnableLineBuffering(BStdIn); BStdIn->flusher = bemptybuf; } void IoEnableKeyb(void) { ulong flags = KePauseIRQs(); KeRegisterISR(KeybHandler, 0x21); KeUnmaskIRQ(0x1); KeRestoreIRQs(flags); KeEnableNMI(); IoCreateInputBuffer(); }