2 * COPYRIGHT: GPL - See COPYING in the top level directory
3 * PROJECT: ReactOS Virtual DOS Machine
4 * FILE: subsystems/mvdm/ntvdm/hardware/keyboard.c
5 * PURPOSE: Keyboard emulation
6 * PROGRAMMERS: Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
9 /* INCLUDES *******************************************************************/
19 /* PRIVATE VARIABLES **********************************************************/
21 static BOOLEAN Reporting
= FALSE
;
22 static BYTE KeyboardId
= 0; // We only support basic old-type keyboard
23 static BYTE DataByteWait
= 0;
25 static BYTE PS2Port
= 0;
27 /* PRIVATE FUNCTIONS **********************************************************/
29 static VOID WINAPI
KeyboardCommand(LPVOID Param
, BYTE Command
)
31 /* Check if we were waiting for a data byte */
34 PS2QueuePush(PS2Port
, KEYBOARD_ACK
);
38 /* Set/Reset Mode Indicators */
41 // Ignore setting the keyboard LEDs
45 /* PS/2 Select/Read Alternate Scan Code Sets */
47 /* Set Typematic Rate/Delay */
50 // FIXME: UNIMPLEMENTED; just return ACKnowledge.
51 // This unblocks some programs that want to initialize
52 // the keyboard by sending keyboard commands and then
53 // performing polling on the port until "valid" data
55 DPRINT1("KeyboardCommand(0x%02X) NOT IMPLEMENTED\n", DataByteWait
);
61 /* Shouldn't happen */
72 /* Set/Reset Mode Indicators */
74 /* PS/2 Select/Read Alternate Scan Code Sets */
76 /* Set Typematic Rate/Delay */
79 DataByteWait
= Command
;
80 PS2QueuePush(PS2Port
, KEYBOARD_ACK
);
84 /* Echo test command */
87 PS2QueuePush(PS2Port
, 0xEE);
94 PS2QueuePush(PS2Port
, KEYBOARD_ACK
);
95 PS2QueuePush(PS2Port
, KeyboardId
);
99 /* Enable Reporting */
103 PS2QueuePush(PS2Port
, KEYBOARD_ACK
);
107 /* Disable Reporting */
111 PS2QueuePush(PS2Port
, KEYBOARD_ACK
);
118 // So far, nothing to reset
119 PS2QueuePush(PS2Port
, KEYBOARD_ACK
);
123 /* PS/2 Typematic & Make/Break key modes */
124 case 0xF7: case 0xF8: case 0xF9:
125 case 0xFA: case 0xFB: case 0xFC: case 0xFD:
128 * Unsupported on PC-AT, they are just ignored
129 * and acknowledged as discussed in:
130 * http://stanislavs.org/helppc/keyboard_commands.html
132 PS2QueuePush(PS2Port
, KEYBOARD_ACK
);
138 PS2QueuePush(PS2Port
, KEYBOARD_ACK
);
146 /* Send ACKnowledge */
147 PS2QueuePush(PS2Port
, KEYBOARD_ACK
);
149 // So far, nothing to reset
151 /* Send the Basic Assurance Test success code and the device ID */
152 PS2QueuePush(PS2Port
, KEYBOARD_BAT_SUCCESS
);
153 PS2QueuePush(PS2Port
, KeyboardId
);
157 /* Unknown command */
160 PS2QueuePush(PS2Port
, KEYBOARD_ERROR
);
165 /* PUBLIC FUNCTIONS ***********************************************************/
167 VOID
KeyboardEventHandler(PKEY_EVENT_RECORD KeyEvent
)
170 BYTE ScanCode
= (BYTE
)KeyEvent
->wVirtualScanCode
;
172 /* Check if we're not reporting */
173 if (!Reporting
) return;
175 /* If this is a key release, set the highest bit in the scan code */
176 if (!KeyEvent
->bKeyDown
) ScanCode
|= 0x80;
178 /* Push the scan code into the PS/2 queue */
179 for (i
= 0; i
< KeyEvent
->wRepeatCount
; i
++)
181 if (KeyEvent
->dwControlKeyState
& ENHANCED_KEY
) PS2QueuePush(PS2Port
, 0xE0);
182 PS2QueuePush(PS2Port
, ScanCode
);
185 DPRINT("Press 0x%X\n", ScanCode
);
188 BOOLEAN
KeyboardInit(BYTE PS2Connector
)
190 /* Finish to plug the keyboard to the specified PS/2 port */
191 PS2Port
= PS2Connector
;
192 PS2SetDeviceCmdProc(PS2Port
, NULL
, KeyboardCommand
);