#define NDEBUG
-#include "ps2.h"
#include "emulator.h"
+#include "io.h"
+#include "ps2.h"
#include "pic.h"
/* PRIVATE VARIABLES **********************************************************/
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;
+
+ WaitForSingleObject(QueueMutex, INFINITE);
+
/* Check if the keyboard queue is full */
if (!KeyboardQueueEmpty && (KeyboardQueueStart == KeyboardQueueEnd))
{
- return FALSE;
+ Result = FALSE;
+ goto Done;
}
/* Insert the value in the queue */
/* Since we inserted a value, it's not empty anymore */
KeyboardQueueEmpty = FALSE;
- return TRUE;
+Done:
+ ReleaseMutex(QueueMutex);
+ return Result;
}
static BOOLEAN KeyboardQueuePop(BYTE *ScanCode)
{
+ BOOLEAN Result = TRUE;
+
+ WaitForSingleObject(QueueMutex, INFINITE);
+
/* Make sure the keyboard queue is not empty */
- if (KeyboardQueueEmpty) return FALSE;
+ if (KeyboardQueueEmpty)
+ {
+ Result = FALSE;
+ goto Done;
+ }
/* Get the scan code */
*ScanCode = KeyboardQueue[KeyboardQueueStart];
KeyboardQueueEmpty = TRUE;
}
- return TRUE;
+Done:
+ ReleaseMutex(QueueMutex);
+ return Result;
}
/* PUBLIC FUNCTIONS ***********************************************************/
{
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;
{
KeyboardResponse = KeyboardConfig;
KeyboardReadResponse = TRUE;
-
break;
}
/* These commands require a response */
KeyboardResponse = Command;
KeyboardWriteResponse = TRUE;
-
break;
}
case 0xA7:
{
// TODO: Mouse support
-
break;
}
case 0xA8:
{
// TODO: Mouse support
-
break;
}
{
KeyboardResponse = 0;
KeyboardReadResponse = TRUE;
-
break;
}
{
KeyboardResponse = 0x55;
KeyboardReadResponse = TRUE;
-
break;
}
{
/* Stop the simulation */
VdmRunning = FALSE;
-
break;
}
}
{
/* Push the data byte to the keyboard queue */
KeyboardQueuePush(Data);
-
break;
}
// 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);
+}
+
DWORD WINAPI InputThreadProc(LPVOID Parameter)
{
INT i;
/* Keyboard IRQ */
PicInterruptRequest(1);
-
break;
}
{
// TODO: NOT IMPLEMENTED
UNIMPLEMENTED;
-
break;
}
return 0;
}
+BOOLEAN PS2Initialize(HANDLE ConsoleInput)
+{
+ /* Create the mutex */
+ QueueMutex = CreateMutex(NULL, FALSE, NULL);
+
+ /* Start the input thread */
+ InputThread = CreateThread(NULL, 0, &InputThreadProc, ConsoleInput, 0, NULL);
+
+ // if (InputThread == NULL) return FALSE;
+
+ /* Register the I/O Ports */
+ RegisterIoPort(PS2_CONTROL_PORT, PS2ReadPort, PS2WritePort);
+ RegisterIoPort(PS2_DATA_PORT , PS2ReadPort, PS2WritePort);
+
+ return TRUE;
+}
+
+VOID PS2Cleanup(VOID)
+{
+ /* Close the input thread handle */
+ if (InputThread != NULL) CloseHandle(InputThread);
+ InputThread = NULL;
+
+ CloseHandle(QueueMutex);
+}
+
/* EOF */