ReactOS  0.4.13-dev-651-g5dbc677
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 */
68  if (Bda->KeybdBufferHead == Bda->KeybdBufferTail) return FALSE;
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
PBIOS_DATA_AREA Bda
Definition: bios.c:42
WORD KeybdBufferStart
Definition: bios.h:87
WORD KeybdBufferEnd
Definition: bios.h:88
WORD KeybdBufferHead
Definition: bios.h:51
unsigned short WORD
Definition: ntddk_ex.h:93
WORD KeybdBufferTail
Definition: bios.h:52

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 TRUE
Definition: types.h:120
PBIOS_DATA_AREA Bda
Definition: bios.c:42
WORD KeybdBufferStart
Definition: bios.h:87
uint32_t ULONG_PTR
Definition: typedefs.h:63
WORD KeybdBufferEnd
Definition: bios.h:88
_In_ LPGUID _In_ PVOID Data
Definition: classpnp.h:778
WORD KeybdBufferHead
Definition: bios.h:51
unsigned short WORD
Definition: ntddk_ex.h:93
WORD KeybdBufferTail
Definition: bios.h:52
uint16_t * LPWORD
Definition: typedefs.h:54
#define DPRINT1
Definition: precomp.h:8

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 */
57  if (Bda->KeybdBufferHead == Bda->KeybdBufferTail) return FALSE;
58 
59  /* Otherwise, get the value and return success */
61 
62  return TRUE;
63 }
#define TRUE
Definition: types.h:120
PBIOS_DATA_AREA Bda
Definition: bios.c:42
uint32_t ULONG_PTR
Definition: typedefs.h:63
WORD KeybdBufferHead
Definition: bios.h:51
WORD KeybdBufferTail
Definition: bios.h:52
uint16_t * LPWORD
Definition: typedefs.h:54

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 */
307  BiosKbdBufferPush(MAKEWORD(Character, ScanCode));
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 
355 Quit:
357 }
#define BDA_KBDFLAG_ALT
Definition: kbdbios32.h:22
#define BDA_KBDFLAG_NUMLOCK_ON
Definition: kbdbios32.h:25
#define STACK_INT_NUM
Definition: int32.h:30
#define PS2_DATA_PORT
Definition: ps2.h:16
#define BDA_KBDFLAG_LALT
Definition: kbdbios32.h:29
USHORT WINAPI getBX(VOID)
Definition: registers.c:170
#define TRUE
Definition: types.h:120
ULONG ScanCode
Definition: api.c:39
USHORT WINAPI getSI(VOID)
Definition: registers.c:404
#define LOBYTE(W)
Definition: jmemdos.c:487
#define MAKEWORD(a, b)
Definition: typedefs.h:247
USHORT WINAPI getCX(VOID)
Definition: registers.c:228
VOID WINAPI setAH(UCHAR)
Definition: registers.c:135
#define VK_RMENU
Definition: winuser.h:2262
#define VK_LSHIFT
Definition: winuser.h:2257
VOID WINAPI setAX(USHORT)
Definition: registers.c:121
VOID WINAPI setDS(USHORT)
Definition: registers.c:515
VOID Int32Call(IN PCALLBACK16 Context, IN BYTE IntNumber)
Definition: int32.c:151
VOID WINAPI setAL(UCHAR)
Definition: registers.c:149
PBIOS_DATA_AREA Bda
Definition: bios.c:42
#define AX
Definition: i386-dis.c:415
#define VK_INSERT
Definition: winuser.h:2207
#define VK_MENU
Definition: winuser.h:2179
UCHAR WINAPI getAL(VOID)
Definition: registers.c:142
Definition: bidi.c:78
Definition: parse.h:75
VOID WINAPI setES(USHORT)
Definition: registers.c:529
#define DX
Definition: i386-dis.c:416
WORD KeybdShiftFlags
Definition: bios.h:49
#define BDA_KBDFLAG_SYSRQ
Definition: kbdbios32.h:30
#define BDA_KBDFLAG_LCTRL
Definition: kbdbios32.h:28
VOID WINAPI setCF(ULONG)
Definition: registers.c:573
VOID WINAPI setSI(USHORT)
Definition: registers.c:411
UCHAR IOReadB(USHORT Port)
Definition: io.c:64
#define BDA_KBDFLAG_RALT
Definition: kbdbios32.h:23
#define BDA_KBDFLAG_RCTRL
Definition: kbdbios32.h:21
static BYTE BiosKeyboardMap[256]
Definition: kbdbios32.c:27
#define VK_SHIFT
Definition: winuser.h:2177
#define BDA_KBDFLAG_RSHIFT
Definition: kbdbios32.h:18
#define BIOS_MISC_INTERRUPT
Definition: bios32p.h:25
unsigned char BOOLEAN
void DPRINT(...)
Definition: polytest.cpp:61
#define BDA_KBDFLAG_CAPSLOCK_ON
Definition: kbdbios32.h:26
static BOOLEAN BiosKbdBufferPush(WORD Data)
Definition: kbdbios32.c:31
#define BDA_KBDFLAG_LSHIFT
Definition: kbdbios32.h:19
#define MAPVK_VSC_TO_VK
Definition: winuser.h:2331
BYTE KeybdStatusFlags
Definition: bios.h:100
#define BDA_KBDFLAG_PAUSE
Definition: kbdbios32.h:31
if(!(yy_init))
Definition: macro.lex.yy.c:714
#define BDA_KBDFLAG_INSERT_ON
Definition: kbdbios32.h:27
USHORT WINAPI getES(VOID)
Definition: registers.c:522
VOID PicIRQComplete(BYTE IntNum)
Definition: bios32.c:812
CALLBACK16 BiosContext
Definition: bios32.c:45
unsigned short WORD
Definition: ntddk_ex.h:93
#define BDA_KBDFLAG_NUMLOCK
Definition: kbdbios32.h:33
VOID WINAPI setBP(USHORT)
Definition: registers.c:381
VOID WINAPI setDX(USHORT)
Definition: registers.c:293
#define VK_RCONTROL
Definition: winuser.h:2260
#define VK_LMENU
Definition: winuser.h:2261
USHORT WINAPI getDX(VOID)
Definition: registers.c:286
#define VK_RSHIFT
Definition: winuser.h:2258
USHORT WINAPI getAX(VOID)
Definition: registers.c:114
unsigned char BYTE
Definition: mem.h:68
VOID WINAPI setBX(USHORT)
Definition: registers.c:177
#define BDA_KBDFLAG_INSERT
Definition: kbdbios32.h:35
#define MapVirtualKey
Definition: winuser.h:5718
VOID WINAPI setDI(USHORT)
Definition: registers.c:441
#define BDA_KBDFLAG_CTRL
Definition: kbdbios32.h:20
int WINAPI ToAscii(_In_ UINT, _In_ UINT, _In_reads_opt_(256) CONST BYTE *, _Out_ LPWORD, _In_ UINT)
#define VK_SCROLL
Definition: winuser.h:2255
#define VK_NUMLOCK
Definition: winuser.h:2254
USHORT WINAPI getDI(VOID)
Definition: registers.c:434
#define VK_CAPITAL
Definition: winuser.h:2181
#define BDA_KBDFLAG_CAPSLOCK
Definition: kbdbios32.h:34
VOID WINAPI setCX(USHORT)
Definition: registers.c:235
#define VK_CONTROL
Definition: winuser.h:2178
#define DPRINT1
Definition: precomp.h:8
#define VK_PAUSE
Definition: winuser.h:2180
USHORT WINAPI getDS(VOID)
Definition: registers.c:508
Definition: i386_sup.c:15
USHORT WINAPI getBP(VOID)
Definition: registers.c:374
#define BDA_KBDFLAG_SCROLL_ON
Definition: kbdbios32.h:24
#define VK_LCONTROL
Definition: winuser.h:2259
#define VK_SNAPSHOT
Definition: winuser.h:2206
#define BDA_KBDFLAG_SCROLL
Definition: kbdbios32.h:32
ULONG WINAPI getCF(VOID)
Definition: registers.c:566

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 */
140  Stack[STACK_FLAGS] |= EMULATOR_FLAG_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 LOBYTE(W)
Definition: jmemdos.c:487
#define MAKEWORD(a, b)
Definition: typedefs.h:247
USHORT WINAPI getCX(VOID)
Definition: registers.c:228
VOID WINAPI setAX(USHORT)
Definition: registers.c:121
#define HIBYTE(W)
Definition: jmemdos.c:486
VOID WINAPI setAL(UCHAR)
Definition: registers.c:149
PBIOS_DATA_AREA Bda
Definition: bios.c:42
UCHAR WINAPI getAH(VOID)
Definition: registers.c:128
WORD KeybdShiftFlags
Definition: bios.h:49
#define EMULATOR_FLAG_ZF
Definition: cpu.h:22
VOID WINAPI setCF(ULONG)
Definition: registers.c:573
#define STACK_FLAGS
Definition: int32.h:35
static BOOLEAN BiosKbdBufferPop(VOID)
Definition: kbdbios32.c:65
static BOOLEAN BiosKbdBufferPush(WORD Data)
Definition: kbdbios32.c:31
BYTE KeybdStatusFlags
Definition: bios.h:100
unsigned short WORD
Definition: ntddk_ex.h:93
#define DPRINT1
Definition: precomp.h:8
static BOOLEAN BiosKbdBufferTop(LPWORD Data)
Definition: kbdbios32.c:54

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 }
PBIOS_DATA_AREA Bda
Definition: bios.c:42
WORD KeybdBufferStart
Definition: bios.h:87
uint32_t ULONG_PTR
Definition: typedefs.h:63
#define RegisterBiosInt32(IntNumber, IntHandler)
Definition: bios32p.h:34
WORD KeybdShiftFlags
Definition: bios.h:49
WORD KeybdBufferEnd
Definition: bios.h:88
BYTE KeybdStatusFlags
Definition: bios.h:100
VOID EnableHwIRQ(UCHAR hwirq, EMULATOR_INT32_PROC func)
Definition: bios32.c:798
WORD KeybdBufferHead
Definition: bios.h:51
unsigned short WORD
Definition: ntddk_ex.h:93
WORD KeybdBufferTail
Definition: bios.h:52
#define BIOS_KBD_BUFFER_SIZE
Definition: kbdbios32.h:16
BYTE KeybdLedFlags
Definition: bios.h:101
VOID WINAPI BiosKeyboardService(LPWORD Stack)
Definition: kbdbios32.c:85
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:254
VOID WINAPI BiosKeyboardIrq(LPWORD Stack)
Definition: kbdbios32.c:199
#define BIOS_KBD_INTERRUPT
Definition: kbdbios.h:14
#define RtlFillMemory(Dest, Length, Fill)
Definition: winternl.h:593

Referenced by Bios32Post().

Variable Documentation

◆ BiosKeyboardMap

BYTE BiosKeyboardMap[256]
static

Definition at line 27 of file kbdbios32.c.

Referenced by BiosKeyboardIrq().