1 /* 2 * PROJECT: ReactOS KDBG Kernel Debugger Terminal Driver 3 * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later) 4 * PURPOSE: PS/2 Keyboard driver 5 * COPYRIGHT: Copyright 2001 David Welch <welch@cwcom.net> 6 * Copyright 2004 Art Yerkes <ayerkes@speakeasy.net> 7 * Copyright 2005 Gregor Anich <blight@blight.eu.org> 8 * Copyright 2009-2011 Dmitry Gorbachev <gorbachev@reactos.org> 9 * 10 * NOTE: Adapted from historic PS/2 keyboard driver authored by 11 * Victor Kirhenshtein <sauros@iname.com> and Jason Filby <jasonfilby@yahoo.com> 12 */ 13 14 /* INCLUDES ******************************************************************/ 15 16 #include <ntoskrnl.h> 17 18 #define KBD_STATUS_REG 0x64 19 #define KBD_CNTL_REG 0x64 20 #define KBD_DATA_REG 0x60 21 22 #define KBD_STAT_OBF 0x01 23 #define KBD_STAT_IBF 0x02 24 25 #define CTRL_WRITE_MOUSE 0xD4 26 #define MOU_ENAB 0xF4 27 #define MOU_DISAB 0xF5 28 #define MOUSE_ACK 0xFA 29 30 #define KBD_DISABLE_MOUSE 0xA7 31 #define KBD_ENABLE_MOUSE 0xA8 32 33 #define kbd_write_command(cmd) WRITE_PORT_UCHAR((PUCHAR)KBD_CNTL_REG,cmd) 34 #define kbd_write_data(cmd) WRITE_PORT_UCHAR((PUCHAR)KBD_DATA_REG,cmd) 35 #define kbd_read_input() READ_PORT_UCHAR((PUCHAR)KBD_DATA_REG) 36 #define kbd_read_status() READ_PORT_UCHAR((PUCHAR)KBD_STATUS_REG) 37 38 static unsigned char keyb_layout[2][128] = 39 { 40 "\000\0331234567890-=\177\t" /* 0x00 - 0x0f */ 41 "qwertyuiop[]\r\000as" /* 0x10 - 0x1f */ 42 "dfghjkl;'`\000\\zxcv" /* 0x20 - 0x2f */ 43 "bnm,./\000*\000 \000\201\202\203\204\205" /* 0x30 - 0x3f */ 44 "\206\207\210\211\212\000\000789-456+1" /* 0x40 - 0x4f */ 45 "230\177\000\000\213\214\000\000\000\000\000\000\000\000\000\000" /* 0x50 - 0x5f */ 46 "\r\000/" /* 0x60 - 0x6f */ 47 , 48 "\000\033!@#$%^&*()_+\177\t" /* 0x00 - 0x0f */ 49 "QWERTYUIOP{}\r\000AS" /* 0x10 - 0x1f */ 50 "DFGHJKL:\"`\000\\ZXCV" /* 0x20 - 0x2f */ 51 "BNM<>?\000*\000 \000\201\202\203\204\205" /* 0x30 - 0x3f */ 52 "\206\207\210\211\212\000\000789-456+1" /* 0x40 - 0x4f */ 53 "230\177\000\000\213\214\000\000\000\000\000\000\000\000\000\000" /* 0x50 - 0x5f */ 54 "\r\000/" /* 0x60 - 0x6f */ 55 }; 56 57 typedef UCHAR byte_t; 58 59 /* FUNCTIONS *****************************************************************/ 60 61 static VOID 62 KbdSendCommandToMouse(UCHAR Command) 63 { 64 ULONG Retry = 20000; 65 66 while (kbd_read_status() & KBD_STAT_OBF && Retry--) 67 { 68 kbd_read_input(); 69 KeStallExecutionProcessor(50); 70 } 71 72 Retry = 20000; 73 while (kbd_read_status() & KBD_STAT_IBF && Retry--) 74 KeStallExecutionProcessor(50); 75 76 kbd_write_command(CTRL_WRITE_MOUSE); 77 78 Retry = 20000; 79 while (kbd_read_status() & KBD_STAT_IBF && Retry--) 80 KeStallExecutionProcessor(50); 81 82 kbd_write_data(Command); 83 84 Retry = 20000; 85 while (!(kbd_read_status() & KBD_STAT_OBF) && Retry--) 86 KeStallExecutionProcessor(50); 87 88 if (kbd_read_input() != MOUSE_ACK) { ; } 89 90 return; 91 } 92 93 VOID KbdEnableMouse(VOID) 94 { 95 KbdSendCommandToMouse(MOU_ENAB); 96 } 97 98 VOID KbdDisableMouse(VOID) 99 { 100 KbdSendCommandToMouse(MOU_DISAB); 101 } 102 103 CHAR 104 KdbpTryGetCharKeyboard(PULONG ScanCode, ULONG Retry) 105 { 106 static byte_t last_key = 0; 107 static byte_t shift = 0; 108 char c; 109 BOOLEAN KeepRetrying = (Retry == 0); 110 111 while (KeepRetrying || Retry-- > 0) 112 { 113 while (kbd_read_status() & KBD_STAT_OBF) 114 { 115 byte_t scancode; 116 117 scancode = kbd_read_input(); 118 119 /* check for SHIFT-keys */ 120 if (((scancode & 0x7F) == 42) || ((scancode & 0x7F) == 54)) 121 { 122 shift = !(scancode & 0x80); 123 continue; 124 } 125 126 /* ignore all other RELEASED-codes */ 127 if (scancode & 0x80) 128 { 129 last_key = 0; 130 } 131 else if (last_key != scancode) 132 { 133 //printf("kbd: %d, %d, %c\n", scancode, last_key, keyb_layout[shift][scancode]); 134 last_key = scancode; 135 c = keyb_layout[shift][scancode]; 136 *ScanCode = scancode; 137 138 if (c > 0) 139 return c; 140 } 141 } 142 } 143 144 return -1; 145 } 146 147 /* EOF */ 148