Author: aandrejevic
Date: Fri Dec 6 04:35:58 2013
New Revision: 61229
URL:
http://svn.reactos.org/svn/reactos?rev=61229&view=rev
Log:
[NTVDM]
Improve the keyboard event handling.
Clean up the PS/2 code a bit.
Modified:
branches/ntvdm/subsystems/ntvdm/bios.c
branches/ntvdm/subsystems/ntvdm/ntvdm.c
branches/ntvdm/subsystems/ntvdm/ntvdm.h
branches/ntvdm/subsystems/ntvdm/ps2.c
branches/ntvdm/subsystems/ntvdm/ps2.h
Modified: branches/ntvdm/subsystems/ntvdm/bios.c
URL:
http://svn.reactos.org/svn/reactos/branches/ntvdm/subsystems/ntvdm/bios.c?r…
==============================================================================
--- branches/ntvdm/subsystems/ntvdm/bios.c [iso-8859-1] (original)
+++ branches/ntvdm/subsystems/ntvdm/bios.c [iso-8859-1] Fri Dec 6 04:35:58 2013
@@ -1429,47 +1429,42 @@
BYTE ScanCode, VirtualKey;
WORD Character;
- /* Loop while there is a scancode available */
- do
+ /* Get the scan code and virtual key code */
+ ScanCode = PS2ReadPort(PS2_DATA_PORT);
+ VirtualKey = MapVirtualKey(ScanCode & 0x7F, MAPVK_VSC_TO_VK);
+
+ /* Check if this is a key press or release */
+ if (!(ScanCode & (1 << 7)))
{
- /* Get the scan code and virtual key code */
- ScanCode = KeyboardReadData();
- VirtualKey = MapVirtualKey(ScanCode & 0x7F, MAPVK_VSC_TO_VK);
-
- /* Check if this is a key press or release */
- if (!(ScanCode & (1 << 7)))
+ /* Key press */
+ if (VirtualKey == VK_NUMLOCK ||
+ VirtualKey == VK_CAPITAL ||
+ VirtualKey == VK_SCROLL ||
+ VirtualKey == VK_INSERT)
{
- /* Key press */
- if (VirtualKey == VK_NUMLOCK ||
- VirtualKey == VK_CAPITAL ||
- VirtualKey == VK_SCROLL ||
- VirtualKey == VK_INSERT)
- {
- /* For toggle keys, toggle the lowest bit in the keyboard map */
- BiosKeyboardMap[VirtualKey] ^= ~(1 << 0);
- }
-
- /* Set the highest bit */
- BiosKeyboardMap[VirtualKey] |= (1 << 7);
-
- /* Find out which character this is */
+ /* For toggle keys, toggle the lowest bit in the keyboard map */
+ BiosKeyboardMap[VirtualKey] ^= ~(1 << 0);
+ }
+
+ /* Set the highest bit */
+ BiosKeyboardMap[VirtualKey] |= (1 << 7);
+
+ /* Find out which character this is */
+ Character = 0;
+ if (ToAscii(VirtualKey, ScanCode, BiosKeyboardMap, &Character, 0) ==
0)
+ {
+ /* Not ASCII */
Character = 0;
- if (ToAscii(VirtualKey, ScanCode, BiosKeyboardMap, &Character, 0)
== 0)
- {
- /* Not ASCII */
- Character = 0;
- }
-
- /* Push it onto the BIOS keyboard queue */
- BiosKbdBufferPush(MAKEWORD(Character, ScanCode));
}
- else
- {
- /* Key release, unset the highest bit */
- BiosKeyboardMap[VirtualKey] &= ~(1 << 7);
- }
+
+ /* Push it onto the BIOS keyboard queue */
+ BiosKbdBufferPush(MAKEWORD(Character, ScanCode));
}
- while (KeyboardReadStatus() & 1);
+ else
+ {
+ /* Key release, unset the highest bit */
+ BiosKeyboardMap[VirtualKey] &= ~(1 << 7);
+ }
/* Clear the keyboard flags */
Bda->KeybdShiftFlags = 0;
Modified: branches/ntvdm/subsystems/ntvdm/ntvdm.c
URL:
http://svn.reactos.org/svn/reactos/branches/ntvdm/subsystems/ntvdm/ntvdm.c?…
==============================================================================
--- branches/ntvdm/subsystems/ntvdm/ntvdm.c [iso-8859-1] (original)
+++ branches/ntvdm/subsystems/ntvdm/ntvdm.c [iso-8859-1] Fri Dec 6 04:35:58 2013
@@ -78,6 +78,7 @@
DWORD LastVerticalRefresh;
DWORD LastCyclePrintout;
DWORD Cycles = 0;
+ INT KeyboardIntCounter = 0;
/* Set the handler routine */
SetConsoleCtrlHandler(ConsoleCtrlHandler, TRUE);
@@ -225,6 +226,13 @@
{
VgaRefreshDisplay();
LastVerticalRefresh = CurrentTickCount;
+ }
+
+ KeyboardIntCounter++;
+ if (KeyboardIntCounter == KBD_INT_CYCLES)
+ {
+ GenerateKeyboardInterrupts();
+ KeyboardIntCounter = 0;
}
/* Horizontal retrace occurs as fast as possible */
Modified: branches/ntvdm/subsystems/ntvdm/ntvdm.h
URL:
http://svn.reactos.org/svn/reactos/branches/ntvdm/subsystems/ntvdm/ntvdm.h?…
==============================================================================
--- branches/ntvdm/subsystems/ntvdm/ntvdm.h [iso-8859-1] (original)
+++ branches/ntvdm/subsystems/ntvdm/ntvdm.h [iso-8859-1] Fri Dec 6 04:35:58 2013
@@ -45,6 +45,7 @@
/* Processor speed */
#define STEPS_PER_CYCLE 256
+#define KBD_INT_CYCLES 16
/* FUNCTIONS ******************************************************************/
Modified: branches/ntvdm/subsystems/ntvdm/ps2.c
URL:
http://svn.reactos.org/svn/reactos/branches/ntvdm/subsystems/ntvdm/ps2.c?re…
==============================================================================
--- branches/ntvdm/subsystems/ntvdm/ps2.c [iso-8859-1] (original)
+++ branches/ntvdm/subsystems/ntvdm/ps2.c [iso-8859-1] Fri Dec 6 04:35:58 2013
@@ -25,23 +25,16 @@
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;
@@ -51,23 +44,16 @@
/* 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,222 +68,208 @@
KeyboardQueueEmpty = TRUE;
}
-Done:
ReleaseMutex(QueueMutex);
- return Result;
+ return TRUE;
}
/* PUBLIC FUNCTIONS ***********************************************************/
-BYTE KeyboardReadStatus()
-{
- 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;
-
- /* Set bit 3 if the next byte goes to the controller */
- if (KeyboardWriteResponse) Status |= 1 << 3;
-
- return Status;
-}
-
-VOID KeyboardWriteCommand(BYTE Command)
-{
- switch (Command)
- {
- /* Read configuration byte */
- case 0x20:
- {
- KeyboardResponse = KeyboardConfig;
- KeyboardReadResponse = TRUE;
- break;
- }
-
- /* Write configuration byte */
- case 0x60:
- /* Write controller output port */
- case 0xD1:
- /* Write keyboard output buffer */
- case 0xD2:
- /* Write mouse output buffer */
- case 0xD3:
- /* Write mouse input buffer */
- case 0xD4:
- {
- /* These commands require a response */
- KeyboardResponse = Command;
- KeyboardWriteResponse = TRUE;
- break;
- }
-
- /* Disable mouse */
- case 0xA7:
- {
- // TODO: Mouse support
- break;
- }
-
- /* Enable mouse */
- case 0xA8:
- {
- // TODO: Mouse support
- break;
- }
-
- /* Test mouse port */
- case 0xA9:
- {
- KeyboardResponse = 0;
- KeyboardReadResponse = TRUE;
- break;
- }
-
- /* Test PS/2 controller */
- case 0xAA:
- {
- KeyboardResponse = 0x55;
- KeyboardReadResponse = TRUE;
- break;
- }
-
- /* Disable keyboard */
- case 0xAD:
- {
- // TODO: Not implemented
- break;
- }
-
- /* Enable keyboard */
- case 0xAE:
- {
- // TODO: Not implemented
- break;
- }
-
- /* Read controller output port */
- case 0xD0:
- {
- // TODO: Not implemented
- break;
- }
-
- /* CPU Reset */
- case 0xF0:
- case 0xF2:
- case 0xF4:
- case 0xF6:
- case 0xF8:
- case 0xFA:
- case 0xFC:
- case 0xFE:
- {
- /* Stop the simulation */
- VdmRunning = FALSE;
- break;
- }
- }
-}
-
-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)
-{
- /* Check if the controller is waiting for a response */
- if (KeyboardWriteResponse)
- {
- KeyboardWriteResponse = FALSE;
-
- /* Check which command it was */
- switch (KeyboardResponse)
- {
+BYTE WINAPI PS2ReadPort(ULONG Port)
+{
+ if (Port == PS2_CONTROL_PORT)
+ {
+ BYTE Status = 0;
+
+ /* Set the first bit if the data can be read */
+ if (KeyboardReadResponse || !KeyboardQueueEmpty) Status |= 1 << 0;
+
+ /* Always set bit 2 */
+ Status |= 1 << 2;
+
+ /* Set bit 3 if the next byte goes to the controller */
+ if (KeyboardWriteResponse) Status |= 1 << 3;
+
+ return Status;
+ }
+ else if (Port == PS2_DATA_PORT)
+ {
+ /* 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:
+ {
+ KeyboardResponse = KeyboardConfig;
+ KeyboardReadResponse = TRUE;
+ break;
+ }
+
/* Write configuration byte */
case 0x60:
- {
- KeyboardConfig = Data;
- break;
- }
-
- /* Write controller output */
+ /* Write controller output port */
case 0xD1:
- {
- /* Check if bit 0 is unset */
- if (!(Data & (1 << 0)))
- {
- /* CPU disabled - end simulation */
- VdmRunning = FALSE;
- }
-
- /* Update the A20 line setting */
- EmulatorSetA20(Data & (1 << 1));
-
- break;
- }
+ /* Write keyboard output buffer */
+ case 0xD2:
+ /* Write mouse output buffer */
+ case 0xD3:
+ /* Write mouse input buffer */
+ case 0xD4:
+ {
+ /* These commands require a response */
+ KeyboardResponse = Data;
+ KeyboardWriteResponse = TRUE;
+ break;
+ }
+
+ /* Disable mouse */
+ case 0xA7:
+ {
+ // TODO: Mouse support
+ break;
+ }
+
+ /* Enable mouse */
+ case 0xA8:
+ {
+ // TODO: Mouse support
+ break;
+ }
+
+ /* Test mouse port */
+ case 0xA9:
+ {
+ KeyboardResponse = 0;
+ KeyboardReadResponse = TRUE;
+ break;
+ }
+
+ /* Test PS/2 controller */
+ case 0xAA:
+ {
+ KeyboardResponse = 0x55;
+ KeyboardReadResponse = TRUE;
+ break;
+ }
+
+ /* Disable keyboard */
+ case 0xAD:
+ {
+ // TODO: Not implemented
+ break;
+ }
+
+ /* Enable keyboard */
+ case 0xAE:
+ {
+ // TODO: Not implemented
+ break;
+ }
+
+ /* Read controller output port */
+ case 0xD0:
+ {
+ // TODO: Not implemented
+ break;
+ }
+
+ /* CPU Reset */
+ case 0xF0:
+ case 0xF2:
+ case 0xF4:
+ case 0xF6:
+ case 0xF8:
+ case 0xFA:
+ case 0xFC:
+ case 0xFE:
+ {
+ /* Stop the simulation */
+ VdmRunning = FALSE;
+ break;
+ }
+ }
+ }
+ else if (Port == PS2_DATA_PORT)
+ {
+ /* Check if the controller is waiting for a response */
+ if (KeyboardWriteResponse)
+ {
+ KeyboardWriteResponse = FALSE;
+
+ /* Check which command it was */
+ switch (KeyboardResponse)
+ {
+ /* Write configuration byte */
+ case 0x60:
+ {
+ KeyboardConfig = Data;
+ break;
+ }
+
+ /* Write controller output */
+ case 0xD1:
+ {
+ /* Check if bit 0 is unset */
+ if (!(Data & (1 << 0)))
+ {
+ /* CPU disabled - end simulation */
+ VdmRunning = FALSE;
+ }
+
+ /* Update the A20 line setting */
+ EmulatorSetA20(Data & (1 << 1));
+
+ break;
+ }
- case 0xD2:
- {
- /* Push the data byte to the keyboard queue */
- KeyboardQueuePush(Data);
- break;
- }
-
- case 0xD3:
- {
- // TODO: Mouse support
- break;
- }
-
- case 0xD4:
- {
- // TODO: Mouse support
- break;
- }
- }
-
- return;
- }
-
- // 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)
-{
- if (Port == PS2_CONTROL_PORT)
- KeyboardWriteCommand(Data);
- else if (Port == PS2_DATA_PORT)
- KeyboardWriteData(Data);
+ case 0xD2:
+ {
+ /* Push the data byte to the keyboard queue */
+ KeyboardQueuePush(Data);
+ break;
+ }
+
+ case 0xD3:
+ {
+ // TODO: Mouse support
+ break;
+ }
+
+ case 0xD4:
+ {
+ // TODO: Mouse support
+ break;
+ }
+ }
+
+ return;
+ }
+
+ // TODO: Implement PS/2 device commands
+ }
+}
+
+VOID GenerateKeyboardInterrupts(VOID)
+{
+ if (KeyboardQueuePop(&KeyboardData))
+ {
+ /* IRQ 1 */
+ PicInterruptRequest(1);
+ }
}
DWORD WINAPI InputThreadProc(LPVOID Parameter)
@@ -335,8 +307,6 @@
KeyboardQueuePush(ScanCode);
}
- /* Keyboard IRQ */
- PicInterruptRequest(1);
break;
}
Modified: branches/ntvdm/subsystems/ntvdm/ps2.h
URL:
http://svn.reactos.org/svn/reactos/branches/ntvdm/subsystems/ntvdm/ps2.h?re…
==============================================================================
--- branches/ntvdm/subsystems/ntvdm/ps2.h [iso-8859-1] (original)
+++ branches/ntvdm/subsystems/ntvdm/ps2.h [iso-8859-1] Fri Dec 6 04:35:58 2013
@@ -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_