ReactOS 0.4.15-dev-8393-g61b7fb9
kbdbios32.c File Reference
#include "ntvdm.h"
#include <debug.h>
#include "kbdbios32.h"
#include <bios/kbdbios.h>
#include "bios32p.h"
#include "int32.h"
#include "cpu/cpu.h"
#include "io.h"
#include "hardware/ps2.h"
Include dependency graph for kbdbios32.c:

Go to the source code of this file.

Macros

#define NDEBUG
 

Functions

static BOOLEAN BiosKbdBufferPush (WORD Data)
 
static BOOLEAN BiosKbdBufferTop (LPWORD Data)
 
static BOOLEAN BiosKbdBufferPop (VOID)
 
VOID WINAPI BiosKeyboardService (LPWORD Stack)
 
VOID WINAPI BiosKeyboardIrq (LPWORD Stack)
 
VOID KbdBios32Post (VOID)
 

Variables

static BYTE BiosKeyboardMap [256]
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 13 of file kbdbios32.c.

Function Documentation

◆ BiosKbdBufferPop()

static BOOLEAN BiosKbdBufferPop ( VOID  )
static

Definition at line 65 of file kbdbios32.c.

66{
67 /* If it's empty, fail */
69
70 /* Remove the value from the queue */
71 Bda->KeybdBufferHead += sizeof(WORD);
72
73 /* Check if we are at, or have passed, the end of the buffer */
75 {
76 /* Return it to the beginning */
78 }
79
80 /* Return success */
81 return TRUE;
82}
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
unsigned short WORD
Definition: ntddk_ex.h:93
WORD KeybdBufferEnd
Definition: bios.h:88
WORD KeybdBufferHead
Definition: bios.h:51
WORD KeybdBufferTail
Definition: bios.h:52
WORD KeybdBufferStart
Definition: bios.h:87
PBIOS_DATA_AREA Bda
Definition: bios.c:42

Referenced by BiosKeyboardService().

◆ BiosKbdBufferPush()

static BOOLEAN BiosKbdBufferPush ( WORD  Data)
static

Definition at line 31 of file kbdbios32.c.

32{
33 /* Get the location of the element after the tail */
34 WORD NextElement = Bda->KeybdBufferTail + sizeof(WORD);
35
36 /* Wrap it around if it's at or beyond the end */
37 if (NextElement >= Bda->KeybdBufferEnd) NextElement = Bda->KeybdBufferStart;
38
39 /* If it's full, fail */
40 if (NextElement == Bda->KeybdBufferHead)
41 {
42 DPRINT1("BIOS keyboard buffer full.\n");
43 return FALSE;
44 }
45
46 /* Put the value in the queue */
48 Bda->KeybdBufferTail = NextElement;
49
50 /* Return success */
51 return TRUE;
52}
#define DPRINT1
Definition: precomp.h:8
uint16_t * LPWORD
Definition: typedefs.h:56
uint32_t ULONG_PTR
Definition: typedefs.h:65

Referenced by BiosKeyboardIrq(), and BiosKeyboardService().

◆ BiosKbdBufferTop()

static BOOLEAN BiosKbdBufferTop ( LPWORD  Data)
static

Definition at line 54 of file kbdbios32.c.

55{
56 /* If it's empty, fail */
58
59 /* Otherwise, get the value and return success */
61
62 return TRUE;
63}

Referenced by BiosKeyboardService().

◆ 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
VOID PicIRQComplete(BYTE IntNum)
Definition: bios32.c:816
CALLBACK16 BiosContext
Definition: bios32.c:45
#define BIOS_MISC_INTERRUPT
Definition: bios32p.h:25
#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
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:2231
#define MapVirtualKey
Definition: winuser.h:5829
#define VK_CAPITAL
Definition: winuser.h:2206
int WINAPI ToAscii(_In_ UINT, _In_ UINT, _In_reads_opt_(256) CONST BYTE *, _Out_ LPWORD, _In_ UINT)
#define VK_SCROLL
Definition: winuser.h:2280
#define VK_CONTROL
Definition: winuser.h:2203
#define VK_RSHIFT
Definition: winuser.h:2283
#define VK_LSHIFT
Definition: winuser.h:2282
#define VK_LCONTROL
Definition: winuser.h:2284
#define VK_PAUSE
Definition: winuser.h:2205
#define MAPVK_VSC_TO_VK
Definition: winuser.h:2356
#define VK_RCONTROL
Definition: winuser.h:2285
#define VK_RMENU
Definition: winuser.h:2287
#define VK_NUMLOCK
Definition: winuser.h:2279
#define VK_SHIFT
Definition: winuser.h:2202
#define VK_INSERT
Definition: winuser.h:2232
#define VK_LMENU
Definition: winuser.h:2286
#define VK_MENU
Definition: winuser.h:2204
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().

◆ KbdBios32Post()

VOID KbdBios32Post ( VOID  )

Definition at line 361 of file kbdbios32.c.

362{
363 /* Initialize the BDA */
367
368 // FIXME: Fill the keyboard buffer with invalid values for diagnostic purposes...
370 BIOS_KBD_BUFFER_SIZE * sizeof(WORD), 'A');
371
372 Bda->KeybdShiftFlags = 0;
373 Bda->KeybdStatusFlags = (1 << 4); // 101/102 enhanced keyboard installed
374 Bda->KeybdLedFlags = 0;
375
376 /*
377 * Register the BIOS 32-bit Interrupts:
378 * - Software vector handler
379 * - HW vector interrupt
380 */
383}
VOID EnableHwIRQ(UCHAR hwirq, EMULATOR_INT32_PROC func)
Definition: bios32.c:802
#define RegisterBiosInt32(IntNumber, IntHandler)
Definition: bios32p.h:34
#define RtlFillMemory(Dest, Length, Fill)
Definition: winternl.h:599
VOID WINAPI BiosKeyboardIrq(LPWORD Stack)
Definition: kbdbios32.c:199
VOID WINAPI BiosKeyboardService(LPWORD Stack)
Definition: kbdbios32.c:85
#define BIOS_KBD_BUFFER_SIZE
Definition: kbdbios32.h:16
#define BIOS_KBD_INTERRUPT
Definition: kbdbios.h:14
BYTE KeybdLedFlags
Definition: bios.h:101
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255

Referenced by Bios32Post().

Variable Documentation

◆ BiosKeyboardMap

BYTE BiosKeyboardMap[256]
static

Definition at line 27 of file kbdbios32.c.

Referenced by BiosKeyboardIrq().