xref: /reactos/ntoskrnl/kd/kdps2kbd.c (revision d6eebaa4)
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