mirror of
https://github.com/reactos/reactos.git
synced 2025-08-04 00:45:49 +00:00
[NTVDM]
Improve the keyboard event handling. Clean up the PS/2 code a bit. svn path=/branches/ntvdm/; revision=61229
This commit is contained in:
parent
6dde554aa8
commit
1b784a5b7b
5 changed files with 233 additions and 261 deletions
|
@ -1429,11 +1429,8 @@ VOID BiosHandleIrq(BYTE IrqNumber, LPWORD Stack)
|
|||
BYTE ScanCode, VirtualKey;
|
||||
WORD Character;
|
||||
|
||||
/* Loop while there is a scancode available */
|
||||
do
|
||||
{
|
||||
/* Get the scan code and virtual key code */
|
||||
ScanCode = KeyboardReadData();
|
||||
ScanCode = PS2ReadPort(PS2_DATA_PORT);
|
||||
VirtualKey = MapVirtualKey(ScanCode & 0x7F, MAPVK_VSC_TO_VK);
|
||||
|
||||
/* Check if this is a key press or release */
|
||||
|
@ -1468,8 +1465,6 @@ VOID BiosHandleIrq(BYTE IrqNumber, LPWORD Stack)
|
|||
/* Key release, unset the highest bit */
|
||||
BiosKeyboardMap[VirtualKey] &= ~(1 << 7);
|
||||
}
|
||||
}
|
||||
while (KeyboardReadStatus() & 1);
|
||||
|
||||
/* Clear the keyboard flags */
|
||||
Bda->KeybdShiftFlags = 0;
|
||||
|
|
|
@ -78,6 +78,7 @@ INT wmain(INT argc, WCHAR *argv[])
|
|||
DWORD LastVerticalRefresh;
|
||||
DWORD LastCyclePrintout;
|
||||
DWORD Cycles = 0;
|
||||
INT KeyboardIntCounter = 0;
|
||||
|
||||
/* Set the handler routine */
|
||||
SetConsoleCtrlHandler(ConsoleCtrlHandler, TRUE);
|
||||
|
@ -227,6 +228,13 @@ INT wmain(INT argc, WCHAR *argv[])
|
|||
LastVerticalRefresh = CurrentTickCount;
|
||||
}
|
||||
|
||||
KeyboardIntCounter++;
|
||||
if (KeyboardIntCounter == KBD_INT_CYCLES)
|
||||
{
|
||||
GenerateKeyboardInterrupts();
|
||||
KeyboardIntCounter = 0;
|
||||
}
|
||||
|
||||
/* Horizontal retrace occurs as fast as possible */
|
||||
VgaHorizontalRetrace();
|
||||
|
||||
|
|
|
@ -45,6 +45,7 @@
|
|||
|
||||
/* Processor speed */
|
||||
#define STEPS_PER_CYCLE 256
|
||||
#define KBD_INT_CYCLES 16
|
||||
|
||||
/* FUNCTIONS ******************************************************************/
|
||||
|
||||
|
|
|
@ -25,24 +25,17 @@ static BYTE KeyboardData = 0, KeyboardResponse = 0;
|
|||
static BOOLEAN KeyboardReadResponse = FALSE, KeyboardWriteResponse = FALSE;
|
||||
static BYTE KeyboardConfig = PS2_DEFAULT_CONFIG;
|
||||
static HANDLE QueueMutex = NULL;
|
||||
|
||||
static HANDLE InputThread = NULL;
|
||||
|
||||
/* PRIVATE FUNCTIONS **********************************************************/
|
||||
|
||||
static BOOLEAN KeyboardQueuePush(BYTE ScanCode)
|
||||
{
|
||||
BOOLEAN Result = TRUE;
|
||||
/* Check if the keyboard queue is full */
|
||||
if (!KeyboardQueueEmpty && (KeyboardQueueStart == KeyboardQueueEnd)) return FALSE;
|
||||
|
||||
WaitForSingleObject(QueueMutex, INFINITE);
|
||||
|
||||
/* Check if the keyboard queue is full */
|
||||
if (!KeyboardQueueEmpty && (KeyboardQueueStart == KeyboardQueueEnd))
|
||||
{
|
||||
Result = FALSE;
|
||||
goto Done;
|
||||
}
|
||||
|
||||
/* Insert the value in the queue */
|
||||
KeyboardQueue[KeyboardQueueEnd] = ScanCode;
|
||||
KeyboardQueueEnd++;
|
||||
|
@ -51,24 +44,17 @@ static BOOLEAN KeyboardQueuePush(BYTE ScanCode)
|
|||
/* Since we inserted a value, it's not empty anymore */
|
||||
KeyboardQueueEmpty = FALSE;
|
||||
|
||||
Done:
|
||||
ReleaseMutex(QueueMutex);
|
||||
return Result;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOLEAN KeyboardQueuePop(BYTE *ScanCode)
|
||||
{
|
||||
BOOLEAN Result = TRUE;
|
||||
/* Make sure the keyboard queue is not empty */
|
||||
if (KeyboardQueueEmpty) return FALSE;
|
||||
|
||||
WaitForSingleObject(QueueMutex, INFINITE);
|
||||
|
||||
/* Make sure the keyboard queue is not empty */
|
||||
if (KeyboardQueueEmpty)
|
||||
{
|
||||
Result = FALSE;
|
||||
goto Done;
|
||||
}
|
||||
|
||||
/* Get the scan code */
|
||||
*ScanCode = KeyboardQueue[KeyboardQueueStart];
|
||||
|
||||
|
@ -82,24 +68,21 @@ static BOOLEAN KeyboardQueuePop(BYTE *ScanCode)
|
|||
KeyboardQueueEmpty = TRUE;
|
||||
}
|
||||
|
||||
Done:
|
||||
ReleaseMutex(QueueMutex);
|
||||
return Result;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* PUBLIC FUNCTIONS ***********************************************************/
|
||||
|
||||
BYTE KeyboardReadStatus()
|
||||
BYTE WINAPI PS2ReadPort(ULONG Port)
|
||||
{
|
||||
if (Port == PS2_CONTROL_PORT)
|
||||
{
|
||||
BYTE Status = 0;
|
||||
|
||||
WaitForSingleObject(QueueMutex, INFINITE);
|
||||
|
||||
/* Set the first bit if the data can be read */
|
||||
if (KeyboardReadResponse || !KeyboardQueueEmpty) Status |= 1 << 0;
|
||||
|
||||
ReleaseMutex(QueueMutex);
|
||||
|
||||
/* Always set bit 2 */
|
||||
Status |= 1 << 2;
|
||||
|
||||
|
@ -108,10 +91,25 @@ BYTE KeyboardReadStatus()
|
|||
|
||||
return Status;
|
||||
}
|
||||
|
||||
VOID KeyboardWriteCommand(BYTE Command)
|
||||
else if (Port == PS2_DATA_PORT)
|
||||
{
|
||||
switch (Command)
|
||||
/* If there was a response byte from the controller, return it */
|
||||
if (KeyboardReadResponse)
|
||||
{
|
||||
KeyboardReadResponse = FALSE;
|
||||
KeyboardData = KeyboardResponse;
|
||||
}
|
||||
|
||||
return KeyboardData;
|
||||
}
|
||||
else return 0;
|
||||
}
|
||||
|
||||
VOID WINAPI PS2WritePort(ULONG Port, BYTE Data)
|
||||
{
|
||||
if (Port == PS2_CONTROL_PORT)
|
||||
{
|
||||
switch (Data)
|
||||
{
|
||||
/* Read configuration byte */
|
||||
case 0x20:
|
||||
|
@ -133,7 +131,7 @@ VOID KeyboardWriteCommand(BYTE Command)
|
|||
case 0xD4:
|
||||
{
|
||||
/* These commands require a response */
|
||||
KeyboardResponse = Command;
|
||||
KeyboardResponse = Data;
|
||||
KeyboardWriteResponse = TRUE;
|
||||
break;
|
||||
}
|
||||
|
@ -205,25 +203,7 @@ VOID KeyboardWriteCommand(BYTE Command)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
BYTE KeyboardReadData()
|
||||
{
|
||||
/* If there was a response byte from the controller, return it */
|
||||
if (KeyboardReadResponse)
|
||||
{
|
||||
KeyboardReadResponse = FALSE;
|
||||
KeyboardData = KeyboardResponse;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Otherwise, read the data from the queue */
|
||||
KeyboardQueuePop(&KeyboardData);
|
||||
}
|
||||
|
||||
return KeyboardData;
|
||||
}
|
||||
|
||||
VOID KeyboardWriteData(BYTE Data)
|
||||
else if (Port == PS2_DATA_PORT)
|
||||
{
|
||||
/* Check if the controller is waiting for a response */
|
||||
if (KeyboardWriteResponse)
|
||||
|
@ -281,23 +261,15 @@ VOID KeyboardWriteData(BYTE Data)
|
|||
|
||||
// TODO: Implement PS/2 device commands
|
||||
}
|
||||
|
||||
BYTE WINAPI PS2ReadPort(ULONG Port)
|
||||
{
|
||||
if (Port == PS2_CONTROL_PORT)
|
||||
return KeyboardReadStatus();
|
||||
else if (Port == PS2_DATA_PORT)
|
||||
return KeyboardReadData();
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
VOID WINAPI PS2WritePort(ULONG Port, BYTE Data)
|
||||
VOID GenerateKeyboardInterrupts(VOID)
|
||||
{
|
||||
if (Port == PS2_CONTROL_PORT)
|
||||
KeyboardWriteCommand(Data);
|
||||
else if (Port == PS2_DATA_PORT)
|
||||
KeyboardWriteData(Data);
|
||||
if (KeyboardQueuePop(&KeyboardData))
|
||||
{
|
||||
/* IRQ 1 */
|
||||
PicInterruptRequest(1);
|
||||
}
|
||||
}
|
||||
|
||||
DWORD WINAPI InputThreadProc(LPVOID Parameter)
|
||||
|
@ -335,8 +307,6 @@ DWORD WINAPI InputThreadProc(LPVOID Parameter)
|
|||
KeyboardQueuePush(ScanCode);
|
||||
}
|
||||
|
||||
/* Keyboard IRQ */
|
||||
PicInterruptRequest(1);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -24,13 +24,11 @@
|
|||
|
||||
/* FUNCTIONS ******************************************************************/
|
||||
|
||||
BYTE KeyboardReadStatus();
|
||||
//VOID KeyboardWriteCommand(BYTE Command);
|
||||
BYTE KeyboardReadData();
|
||||
//VOID KeyboardWriteData(BYTE Data);
|
||||
|
||||
BOOLEAN PS2Initialize(HANDLE ConsoleInput);
|
||||
VOID PS2Cleanup(VOID);
|
||||
BYTE WINAPI PS2ReadPort(ULONG Port);
|
||||
VOID WINAPI PS2WritePort(ULONG Port, BYTE Data);
|
||||
VOID GenerateKeyboardInterrupts(VOID);
|
||||
|
||||
#endif // _PS2_H_
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue