ReactOS 0.4.16-dev-297-gc569aee
kbdbios.c File Reference
#include "ntvdm.h"
#include <debug.h>
#include "emulator.h"
#include "cpu/bop.h"
#include "int32.h"
#include "bios.h"
Include dependency graph for kbdbios.c:

Go to the source code of this file.

Macros

#define NDEBUG
 
#define BOP_KBD_IRQ   0x09
 
#define BOP_KBD_INT   0x16
 

Functions

VOID WINAPI BiosKeyboardIrq (LPWORD Stack)
 
static VOID WINAPI KbdBiosIRQ (LPWORD Stack)
 
VOID WINAPI BiosKeyboardService (LPWORD Stack)
 
static VOID WINAPI KbdBiosINT (LPWORD Stack)
 
BOOLEAN KbdBiosInitialize (VOID)
 
VOID KbdBiosCleanup (VOID)
 

Macro Definition Documentation

◆ BOP_KBD_INT

#define BOP_KBD_INT   0x16

Definition at line 27 of file kbdbios.c.

◆ BOP_KBD_IRQ

#define BOP_KBD_IRQ   0x09

Definition at line 26 of file kbdbios.c.

◆ NDEBUG

#define NDEBUG

Definition at line 13 of file kbdbios.c.

Function Documentation

◆ BiosKeyboardIrq()

VOID WINAPI BiosKeyboardIrq ( LPWORD  Stack)

Definition at line 199 of file kbdbios32.c.

200{
201 static BOOLEAN Extended = FALSE;
202 BOOLEAN SkipScanCode;
203 BYTE ScanCode, VirtualKey;
204 WORD Character;
205
206 /*
207 * Get the scan code from the PS/2 port, then call the
208 * INT 15h, AH=4Fh Keyboard Intercept function to try to
209 * translate the scan code. CF must be set before the call.
210 * In return, if CF is set we continue processing the scan code
211 * stored in AL, and if not, we skip it.
212 */
213 WORD AX = getAX();
214 WORD CX = getCX();
215 WORD DX = getDX();
216 WORD BX = getBX();
217 WORD BP = getBP();
218 WORD SI = getSI();
219 WORD DI = getDI();
220 WORD DS = getDS();
221 WORD ES = getES();
222
223 setCF(1);
225 setAH(0x4F);
227
228 /* Retrieve the modified scan code in AL */
229 SkipScanCode = (getCF() == 0);
230 ScanCode = getAL();
231
232 setAX(AX);
233 setCX(CX);
234 setDX(DX);
235 setBX(BX);
236 setBP(BP);
237 setSI(SI);
238 setDI(DI);
239 setDS(DS);
240 setES(ES);
241 setCF(0);
242
243 if (ScanCode == 0xE0)
244 {
245 Extended = TRUE;
246 Bda->KeybdStatusFlags |= 0x02;
247 goto Quit;
248 }
249
250 // FIXME: For diagnostic purposes. We should decide what to do then!!
251 if (ScanCode == 0xE1)
252 DPRINT1("BiosKeyboardIrq, ScanCode == 0xE1\n");
253
254 /* Check whether CF is clear. If so, skip the scan code. */
255 if (SkipScanCode) goto Quit;
256
257 /* Get the corresponding virtual key code */
258 VirtualKey = MapVirtualKey(ScanCode & 0x7F, MAPVK_VSC_TO_VK);
259
260 /* Check if this is a key press or release */
261 if (!(ScanCode & (1 << 7)))
262 {
263 /* Key press, set the highest bit */
264 BiosKeyboardMap[VirtualKey] |= (1 << 7);
265
266 switch (VirtualKey)
267 {
268 case VK_NUMLOCK:
269 case VK_CAPITAL:
270 case VK_SCROLL:
271 case VK_INSERT:
272 {
273 /* For toggle keys, toggle the lowest bit in the keyboard map */
274 BiosKeyboardMap[VirtualKey] ^= ~(1 << 0);
275 break;
276 }
277
278 case VK_SHIFT:
279 case VK_LSHIFT:
280 case VK_RSHIFT:
281 case VK_CONTROL:
282 case VK_RCONTROL:
283 case VK_LCONTROL:
284 case VK_MENU:
285 case VK_LMENU:
286 case VK_RMENU:
287 {
288 /* Modifier keys don't go in the buffer */
289 break;
290 }
291
292 default:
293 {
294 Character = Extended ? 0xE0 : 0x00;
295
296 /* If this is not an extended scancode, and ALT isn't held down, find out which character this is */
298 {
299 if (ToAscii(VirtualKey, ScanCode, BiosKeyboardMap, &Character, 0) == 0)
300 {
301 /* Not ASCII */
302 Character = 0;
303 }
304 }
305
306 /* Push it onto the BIOS keyboard queue */
308 }
309 }
310 }
311 else
312 {
313 /* Key release, unset the highest bit */
314 BiosKeyboardMap[VirtualKey] &= ~(1 << 7);
315 }
316
317 /* Clear the keyboard flags */
318 Bda->KeybdShiftFlags = 0;
319 // Release right CTRL and ALT keys
321
322 /* Set the appropriate flags based on the state */
323 // SHIFT
327 // CTRL
331 // ALT
335 // Others
346
347 /* Clear the extended key flag */
348 Extended = FALSE;
349 Bda->KeybdStatusFlags &= ~0x02; // Remove the 0xE0 code flag
350 // Bda->KeybdStatusFlags &= ~0x01; // Remove the 0xE1 code flag
351
352 DPRINT("BiosKeyboardIrq - Character = 0x%X, ScanCode = 0x%X, KeybdShiftFlags = 0x%X\n",
353 Character, ScanCode, Bda->KeybdShiftFlags);
354
355Quit:
357}
unsigned char BOOLEAN
UINT ScanCode
Definition: VirtualKey.c:24
@ DS
Definition: amd64_sup.c:16
#define DPRINT1
Definition: precomp.h:8
VOID PicIRQComplete(BYTE IntNum)
Definition: bios32.c:816
CALLBACK16 BiosContext
Definition: bios32.c:45
#define BIOS_MISC_INTERRUPT
Definition: bios32p.h:25
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
unsigned short WORD
Definition: ntddk_ex.h:93
#define DX
Definition: i386-dis.c:425
#define AX
Definition: i386-dis.c:424
VOID Int32Call(IN PCALLBACK16 Context, IN BYTE IntNumber)
Definition: int32.c:151
#define STACK_INT_NUM
Definition: int32.h:30
#define LOBYTE(W)
Definition: jmemdos.c:487
static BYTE BiosKeyboardMap[256]
Definition: kbdbios32.c:27
static BOOLEAN BiosKbdBufferPush(WORD Data)
Definition: kbdbios32.c:31
#define BDA_KBDFLAG_LCTRL
Definition: kbdbios32.h:28
#define BDA_KBDFLAG_NUMLOCK_ON
Definition: kbdbios32.h:25
#define BDA_KBDFLAG_PAUSE
Definition: kbdbios32.h:31
#define BDA_KBDFLAG_RCTRL
Definition: kbdbios32.h:21
#define BDA_KBDFLAG_LALT
Definition: kbdbios32.h:29
#define BDA_KBDFLAG_INSERT_ON
Definition: kbdbios32.h:27
#define BDA_KBDFLAG_NUMLOCK
Definition: kbdbios32.h:33
#define BDA_KBDFLAG_SYSRQ
Definition: kbdbios32.h:30
#define BDA_KBDFLAG_CAPSLOCK_ON
Definition: kbdbios32.h:26
#define BDA_KBDFLAG_CAPSLOCK
Definition: kbdbios32.h:34
#define BDA_KBDFLAG_INSERT
Definition: kbdbios32.h:35
#define BDA_KBDFLAG_CTRL
Definition: kbdbios32.h:20
#define BDA_KBDFLAG_RSHIFT
Definition: kbdbios32.h:18
#define BDA_KBDFLAG_RALT
Definition: kbdbios32.h:23
#define BDA_KBDFLAG_LSHIFT
Definition: kbdbios32.h:19
#define BDA_KBDFLAG_SCROLL
Definition: kbdbios32.h:32
#define BDA_KBDFLAG_ALT
Definition: kbdbios32.h:22
#define BDA_KBDFLAG_SCROLL_ON
Definition: kbdbios32.h:24
if(dx< 0)
Definition: linetemp.h:194
@ ES
Definition: bidi.c:78
#define PS2_DATA_PORT
Definition: ps2.h:16
#define DPRINT
Definition: sndvol32.h:73
BYTE KeybdStatusFlags
Definition: bios.h:100
WORD KeybdShiftFlags
Definition: bios.h:49
PBIOS_DATA_AREA Bda
Definition: bios.c:42
UCHAR IOReadB(USHORT Port)
Definition: io.c:64
#define MAKEWORD(a, b)
Definition: typedefs.h:248
VOID WINAPI setBX(USHORT)
Definition: registers.c:177
VOID WINAPI setCX(USHORT)
Definition: registers.c:235
VOID WINAPI setDX(USHORT)
Definition: registers.c:293
ULONG WINAPI getCF(VOID)
Definition: registers.c:566
USHORT WINAPI getBX(VOID)
Definition: registers.c:170
VOID WINAPI setAL(UCHAR)
Definition: registers.c:149
USHORT WINAPI getDS(VOID)
Definition: registers.c:508
UCHAR WINAPI getAL(VOID)
Definition: registers.c:142
VOID WINAPI setCF(ULONG)
Definition: registers.c:573
VOID WINAPI setAH(UCHAR)
Definition: registers.c:135
USHORT WINAPI getCX(VOID)
Definition: registers.c:228
USHORT WINAPI getSI(VOID)
Definition: registers.c:404
USHORT WINAPI getDX(VOID)
Definition: registers.c:286
VOID WINAPI setDS(USHORT)
Definition: registers.c:515
USHORT WINAPI getAX(VOID)
Definition: registers.c:114
USHORT WINAPI getES(VOID)
Definition: registers.c:522
USHORT WINAPI getBP(VOID)
Definition: registers.c:374
USHORT WINAPI getDI(VOID)
Definition: registers.c:434
VOID WINAPI setBP(USHORT)
Definition: registers.c:381
VOID WINAPI setAX(USHORT)
Definition: registers.c:121
VOID WINAPI setES(USHORT)
Definition: registers.c:529
VOID WINAPI setSI(USHORT)
Definition: registers.c:411
VOID WINAPI setDI(USHORT)
Definition: registers.c:441
_In_ WDFREQUEST _In_ PIO_STACK_LOCATION Stack
Definition: wdfrequest.h:639
#define VK_SNAPSHOT
Definition: winuser.h:2234
#define MapVirtualKey
Definition: winuser.h:5832
#define VK_CAPITAL
Definition: winuser.h:2209
int WINAPI ToAscii(_In_ UINT, _In_ UINT, _In_reads_opt_(256) CONST BYTE *, _Out_ LPWORD, _In_ UINT)
#define VK_SCROLL
Definition: winuser.h:2283
#define VK_CONTROL
Definition: winuser.h:2206
#define VK_RSHIFT
Definition: winuser.h:2286
#define VK_LSHIFT
Definition: winuser.h:2285
#define VK_LCONTROL
Definition: winuser.h:2287
#define VK_PAUSE
Definition: winuser.h:2208
#define MAPVK_VSC_TO_VK
Definition: winuser.h:2359
#define VK_RCONTROL
Definition: winuser.h:2288
#define VK_RMENU
Definition: winuser.h:2290
#define VK_NUMLOCK
Definition: winuser.h:2282
#define VK_SHIFT
Definition: winuser.h:2205
#define VK_INSERT
Definition: winuser.h:2235
#define VK_LMENU
Definition: winuser.h:2289
#define VK_MENU
Definition: winuser.h:2207
unsigned char BYTE
Definition: xxhash.c:193

Referenced by KbdBios32Post(), and KbdBiosIRQ().

◆ BiosKeyboardService()

VOID WINAPI BiosKeyboardService ( LPWORD  Stack)

Definition at line 85 of file kbdbios32.c.

86{
87 switch (getAH())
88 {
89 /* Wait for keystroke and read */
90 case 0x00:
91 /* Wait for extended keystroke and read */
92 case 0x10:
93 {
94 WORD Character;
95
96 /* Read the character (and wait if necessary) */
97 if (!BiosKbdBufferTop(&Character))
98 {
99 /* No key available. Set the handler CF to repeat the BOP */
100 setCF(1);
101 break;
102 }
103
104 if (getAH() == 0x00 && LOBYTE(Character) == 0xE0)
105 {
106 /* Clear the extended code */
107 Character &= 0xFF00;
108 }
109
111 setAX(Character);
112 setCF(0);
113
114 break;
115 }
116
117 /* Get keystroke status */
118 case 0x01:
119 /* Get extended keystroke status */
120 case 0x11:
121 {
122 WORD Character;
123
124 if (BiosKbdBufferTop(&Character))
125 {
126 /* There is a character, clear ZF and return it */
127 Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_ZF;
128
129 if (getAH() == 0x01 && LOBYTE(Character) == 0xE0)
130 {
131 /* Clear the extended code */
132 Character &= 0xFF00;
133 }
134
135 setAX(Character);
136 }
137 else
138 {
139 /* No character, set ZF */
141 }
142
143 break;
144 }
145
146 /* Get shift status */
147 case 0x02:
148 {
149 /* Return the lower byte of the keyboard shift status word */
151 break;
152 }
153
154 /* Reserved */
155 case 0x04:
156 {
157 DPRINT1("BIOS Function INT 16h, AH = 0x04 is RESERVED\n");
158 break;
159 }
160
161 /* Push keystroke */
162 case 0x05:
163 {
164 /* Return 0 if success, 1 if failure */
166 break;
167 }
168
169 /* Get extended shift status */
170 case 0x12:
171 {
172 /*
173 * Be careful! The returned word is similar to 'Bda->KeybdShiftFlags'
174 * but the high byte is organized differently:
175 * the bits 2 and 3 of the high byte are not the same:
176 * instead they correspond to the right CTRL and ALT keys as specified
177 * in bits 2 and 3 of LOBYTE(Bda->KeybdStatusFlags).
178 */
179 // Bda->KeybdShiftFlags & 0xF3FF;
180 WORD KeybdShiftFlags = MAKEWORD(LOBYTE(Bda->KeybdShiftFlags),
181 (HIBYTE(Bda->KeybdShiftFlags ) & 0xF3) |
182 (LOBYTE(Bda->KeybdStatusFlags) & 0x0C));
183
184 /* Return the extended keyboard shift status word */
185 setAX(KeybdShiftFlags);
186 break;
187 }
188
189 default:
190 {
191 DPRINT1("BIOS Function INT 16h, AH = 0x%02X NOT IMPLEMENTED\n",
192 getAH());
193 }
194 }
195}
#define STACK_FLAGS
Definition: int32.h:35
#define HIBYTE(W)
Definition: jmemdos.c:486
static BOOLEAN BiosKbdBufferPop(VOID)
Definition: kbdbios32.c:65
static BOOLEAN BiosKbdBufferTop(LPWORD Data)
Definition: kbdbios32.c:54
#define EMULATOR_FLAG_ZF
Definition: cpu.h:22
UCHAR WINAPI getAH(VOID)
Definition: registers.c:128

Referenced by KbdBios32Post(), and KbdBiosINT().

◆ KbdBiosCleanup()

VOID KbdBiosCleanup ( VOID  )

Definition at line 93 of file kbdbios.c.

94{
95 /* Unregister the BIOS support BOPs */
98}
VOID RegisterBop(BYTE BopCode, EMULATOR_BOP_PROC BopHandler)
Definition: bop.c:29
#define NULL
Definition: types.h:112
#define BOP_KBD_IRQ
Definition: kbdbios.c:26
#define BOP_KBD_INT
Definition: kbdbios.c:27

Referenced by Bios32Cleanup().

◆ KbdBiosInitialize()

BOOLEAN KbdBiosInitialize ( VOID  )

Definition at line 85 of file kbdbios.c.

86{
87 /* Register the BIOS support BOPs */
88 RegisterBop(BOP_KBD_IRQ, KbdBiosIRQ); // BiosKeyboardIrq in kbdbios32.c
89 RegisterBop(BOP_KBD_INT, KbdBiosINT); // BiosKeyboardService in kbdbios32.c
90 return TRUE;
91}
static VOID WINAPI KbdBiosINT(LPWORD Stack)
Definition: kbdbios.c:59
static VOID WINAPI KbdBiosIRQ(LPWORD Stack)
Definition: kbdbios.c:32

Referenced by Bios32Initialize().

◆ KbdBiosINT()

static VOID WINAPI KbdBiosINT ( LPWORD  Stack)
static

Definition at line 59 of file kbdbios.c.

60{
61 /*
62 * Set up a false stack to hardwire the BOP function (that can directly
63 * manipulate CPU registers) to the 32-bit interrupt function (which uses
64 * the stack to be able to modify the original CS:IP and FLAGS).
65 *
66 * See int32.h stack codes.
67 */
68 WORD EmuStack[4];
70
71 DPRINT1("Calling BOP KbdBiosINT\n");
72
73 EmuStack[STACK_FLAGS] = LOWORD(Flags);
74 EmuStack[STACK_CS] = getCS();
75 EmuStack[STACK_IP] = getIP();
76 EmuStack[STACK_INT_NUM] = BOP_KBD_IRQ;
77
78 BiosKeyboardService(EmuStack);
79
80 setIP(EmuStack[STACK_IP]);
81 setCS(EmuStack[STACK_CS]);
83}
unsigned long DWORD
Definition: ntddk_ex.h:95
#define STACK_IP
Definition: int32.h:33
#define STACK_CS
Definition: int32.h:34
VOID WINAPI BiosKeyboardService(LPWORD Stack)
Definition: kbdbios32.c:85
#define LOWORD(l)
Definition: pedump.c:82
#define MAKELONG(a, b)
Definition: typedefs.h:249
#define HIWORD(l)
Definition: typedefs.h:247
USHORT WINAPI getIP(VOID)
Definition: registers.c:464
VOID WINAPI setEFLAGS(ULONG)
Definition: registers.c:687
VOID WINAPI setCS(USHORT)
Definition: registers.c:487
USHORT WINAPI getCS(VOID)
Definition: registers.c:480
ULONG WINAPI getEFLAGS(VOID)
Definition: registers.c:680
VOID WINAPI setIP(USHORT)
Definition: registers.c:471
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170

Referenced by KbdBiosInitialize().

◆ KbdBiosIRQ()

static VOID WINAPI KbdBiosIRQ ( LPWORD  Stack)
static

Definition at line 32 of file kbdbios.c.

33{
34 /*
35 * Set up a false stack to hardwire the BOP function (that can directly
36 * manipulate CPU registers) to the 32-bit interrupt function (which uses
37 * the stack to be able to modify the original CS:IP and FLAGS).
38 *
39 * See int32.h stack codes.
40 */
41 WORD EmuStack[4];
43
44 DPRINT1("Calling BOP KbdBiosIRQ\n");
45
46 EmuStack[STACK_FLAGS] = LOWORD(Flags);
47 EmuStack[STACK_CS] = getCS();
48 EmuStack[STACK_IP] = getIP();
49 EmuStack[STACK_INT_NUM] = BOP_KBD_IRQ;
50
51 BiosKeyboardIrq(EmuStack);
52
53 setIP(EmuStack[STACK_IP]);
54 setCS(EmuStack[STACK_CS]);
56}
VOID WINAPI BiosKeyboardIrq(LPWORD Stack)
Definition: kbdbios32.c:199

Referenced by KbdBiosInitialize().