[FAST486]
authorAleksandar Andrejevic <aandrejevic@reactos.org>
Sun, 27 Oct 2013 00:37:01 +0000 (00:37 +0000)
committerAleksandar Andrejevic <aandrejevic@reactos.org>
Sun, 27 Oct 2013 00:37:01 +0000 (00:37 +0000)
Separate external interrupts from interrupt signals (which are
interrupts whose number is not known until they can be serviced,
just like hardware interrupts on a real CPU).
[NTVDM]
Improve the PIC emulation code (IRQ priorities, etc...).
Instead of checking for interrupts in the main loop, move the
PS/2 input parsing to a different thread.
Improve BIOS keyboard IRQ handling.

svn path=/branches/ntvdm/; revision=60761

include/reactos/libs/fast486/fast486.h
lib/fast486/fast486.c
lib/fast486/opcodes.c
subsystems/ntvdm/bios.c
subsystems/ntvdm/emulator.c
subsystems/ntvdm/emulator.h
subsystems/ntvdm/ntvdm.c
subsystems/ntvdm/pic.c
subsystems/ntvdm/pic.h
subsystems/ntvdm/ps2.c
subsystems/ntvdm/ps2.h

index c2501f7..618a291 100644 (file)
@@ -145,6 +145,13 @@ typedef enum _FAST486_EXCEPTIONS
     FAST486_EXCEPTION_MC = 0x12
 } FAST486_EXCEPTIONS, *PFAST486_EXCEPTIONS;
 
     FAST486_EXCEPTION_MC = 0x12
 } FAST486_EXCEPTIONS, *PFAST486_EXCEPTIONS;
 
+typedef enum _FAST486_INT_STATUS
+{
+    FAST486_INT_NONE = 0,
+    FAST486_INT_EXECUTE = 1,
+    FAST486_INT_SIGNAL = 2
+} FAST486_INT_STATUS, *PFAST486_INT_STATUS;
+
 typedef
 BOOLEAN
 (NTAPI *FAST486_MEM_READ_PROC)
 typedef
 BOOLEAN
 (NTAPI *FAST486_MEM_READ_PROC)
@@ -200,6 +207,13 @@ VOID
     USHORT BopCode
 );
 
     USHORT BopCode
 );
 
+typedef
+UCHAR
+(NTAPI *FAST486_INT_ACK_PROC)
+(
+    PFAST486_STATE State
+);
+
 typedef union _FAST486_REG
 {
     union
 typedef union _FAST486_REG
 {
     union
@@ -352,6 +366,7 @@ struct _FAST486_STATE
     FAST486_IO_WRITE_PROC IoWriteCallback;
     FAST486_IDLE_PROC IdleCallback;
     FAST486_BOP_PROC BopCallback;
     FAST486_IO_WRITE_PROC IoWriteCallback;
     FAST486_IDLE_PROC IdleCallback;
     FAST486_BOP_PROC BopCallback;
+    FAST486_INT_ACK_PROC IntAckCallback;
     FAST486_REG GeneralRegs[FAST486_NUM_GEN_REGS];
     FAST486_SEG_REG SegmentRegs[FAST486_NUM_SEG_REGS];
     FAST486_REG InstPtr, SavedInstPtr;
     FAST486_REG GeneralRegs[FAST486_NUM_GEN_REGS];
     FAST486_SEG_REG SegmentRegs[FAST486_NUM_SEG_REGS];
     FAST486_REG InstPtr, SavedInstPtr;
@@ -362,7 +377,7 @@ struct _FAST486_STATE
     ULONG ExceptionCount;
     ULONG PrefixFlags;
     FAST486_SEG_REGS SegmentOverride;
     ULONG ExceptionCount;
     ULONG PrefixFlags;
     FAST486_SEG_REGS SegmentOverride;
-    BOOLEAN HardwareInt;
+    FAST486_INT_STATUS IntStatus;
     UCHAR PendingIntNum;
 };
 
     UCHAR PendingIntNum;
 };
 
@@ -396,6 +411,10 @@ VOID
 NTAPI
 Fast486Interrupt(PFAST486_STATE State, UCHAR Number);
 
 NTAPI
 Fast486Interrupt(PFAST486_STATE State, UCHAR Number);
 
+VOID
+NTAPI
+Fast486InterruptSignal(PFAST486_STATE State);
+
 VOID
 NTAPI
 Fast486ExecuteAt(PFAST486_STATE State, USHORT Segment, ULONG Offset);
 VOID
 NTAPI
 Fast486ExecuteAt(PFAST486_STATE State, USHORT Segment, ULONG Offset);
index d271a86..04a8776 100644 (file)
@@ -61,11 +61,23 @@ Fast486ExecutionControl(PFAST486_STATE State, INT Command)
         {
             State->SavedInstPtr = State->InstPtr;
 
         {
             State->SavedInstPtr = State->InstPtr;
 
-            /* Check if interrupts are enabled and there is an interrupt pending */
-            if (State->Flags.If && State->HardwareInt)
+            /*
+             * Check if there is an interrupt to execute, or a hardware interrupt signal
+             * while interrupts are enabled.
+             */
+            if ((State->IntStatus == FAST486_INT_EXECUTE)
+                || (State->Flags.If
+                && (State->IntAckCallback != NULL)
+                && (State->IntStatus == FAST486_INT_SIGNAL)))
             {
                 FAST486_IDT_ENTRY IdtEntry;
 
             {
                 FAST486_IDT_ENTRY IdtEntry;
 
+                if (State->IntStatus == FAST486_INT_SIGNAL)
+                {
+                    /* Acknowledge the interrupt to get the number */
+                    State->PendingIntNum = State->IntAckCallback(State);
+                }
+
                 /* Get the interrupt vector */
                 if (Fast486GetIntVector(State, State->PendingIntNum, &IdtEntry))
                 {
                 /* Get the interrupt vector */
                 if (Fast486GetIntVector(State, State->PendingIntNum, &IdtEntry))
                 {
@@ -76,8 +88,8 @@ Fast486ExecutionControl(PFAST486_STATE State, INT Command)
                                              IdtEntry.Type);
                 }
 
                                              IdtEntry.Type);
                 }
 
-                /* Clear the interrupt pending flag */
-                State->HardwareInt = FALSE;
+                /* Clear the interrupt status */
+                State->IntStatus = FAST486_INT_NONE;
             }
         }
 
             }
         }
 
@@ -243,6 +255,7 @@ Fast486Reset(PFAST486_STATE State)
     FAST486_IO_WRITE_PROC IoWriteCallback = State->IoWriteCallback;
     FAST486_IDLE_PROC IdleCallback = State->IdleCallback;
     FAST486_BOP_PROC BopCallback = State->BopCallback;
     FAST486_IO_WRITE_PROC IoWriteCallback = State->IoWriteCallback;
     FAST486_IDLE_PROC IdleCallback = State->IdleCallback;
     FAST486_BOP_PROC BopCallback = State->BopCallback;
+    FAST486_INT_ACK_PROC IntAckCallback = State->IntAckCallback;
 
     /* Clear the entire structure */
     RtlZeroMemory(State, sizeof(*State));
 
     /* Clear the entire structure */
     RtlZeroMemory(State, sizeof(*State));
@@ -278,17 +291,26 @@ Fast486Reset(PFAST486_STATE State)
     State->IoWriteCallback = IoWriteCallback;
     State->IdleCallback = IdleCallback;
     State->BopCallback = BopCallback;
     State->IoWriteCallback = IoWriteCallback;
     State->IdleCallback = IdleCallback;
     State->BopCallback = BopCallback;
+    State->IntAckCallback = IntAckCallback;
 }
 
 VOID
 NTAPI
 Fast486Interrupt(PFAST486_STATE State, UCHAR Number)
 {
 }
 
 VOID
 NTAPI
 Fast486Interrupt(PFAST486_STATE State, UCHAR Number)
 {
-    /* Set the hardware interrupt flag */
-    State->HardwareInt = TRUE;
+    /* Set the interrupt status and the number */
+    State->IntStatus = FAST486_INT_EXECUTE;
     State->PendingIntNum = Number;
 }
 
     State->PendingIntNum = Number;
 }
 
+VOID
+NTAPI
+Fast486InterruptSignal(PFAST486_STATE State)
+{
+    /* Set the interrupt status */
+    State->IntStatus = FAST486_INT_SIGNAL;
+}
+
 VOID
 NTAPI
 Fast486ExecuteAt(PFAST486_STATE State, USHORT Segment, ULONG Offset)
 VOID
 NTAPI
 Fast486ExecuteAt(PFAST486_STATE State, USHORT Segment, ULONG Offset)
index db9c90d..083c349 100644 (file)
@@ -876,7 +876,7 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeHalt)
     }
 
     /* Halt */
     }
 
     /* Halt */
-    while (!State->HardwareInt) State->IdleCallback(State);
+    while (State->IntStatus != FAST486_INT_SIGNAL) State->IdleCallback(State);
 
     /* Return success */
     return TRUE;
 
     /* Return success */
     return TRUE;
index 0005b65..61e6beb 100644 (file)
@@ -1092,40 +1092,41 @@ VOID BiosHandleIrq(BYTE IrqNumber, LPWORD Stack)
             BYTE ScanCode, VirtualKey;
             WORD Character;
             
             BYTE ScanCode, VirtualKey;
             WORD Character;
             
-            /* Check if there is a scancode available */
-            if (!(KeyboardReadStatus() & 1)) break;
-
-            /* 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)))
+            /* Loop while there is a scancode available */
+            while (KeyboardReadStatus() & 1)
             {
             {
-                /* Key press */
-                if (VirtualKey == VK_NUMLOCK
-                    || VirtualKey == VK_CAPITAL
-                    || VirtualKey == VK_SCROLL)
+                /* 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)))
                 {
                 {
-                    /* For toggle keys, toggle the lowest bit in the keyboard map */
-                    BiosKeyboardMap[VirtualKey] ^= ~(1 << 0);
+                    /* Key press */
+                    if (VirtualKey == VK_NUMLOCK
+                        || VirtualKey == VK_CAPITAL
+                        || VirtualKey == VK_SCROLL)
+                    {
+                        /* 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 */
+                    if (ToAscii(VirtualKey, ScanCode, BiosKeyboardMap, &Character, 0) > 0)
+                    {
+                        /* Push it onto the BIOS keyboard queue */
+                        BiosKbdBufferPush((ScanCode << 8) | (Character & 0xFF));
+                    }
                 }
                 }
-
-                /* Set the highest bit */
-                BiosKeyboardMap[VirtualKey] |= (1 << 7);
-
-                /* Find out which character this is */
-                if (ToAscii(VirtualKey, ScanCode, BiosKeyboardMap, &Character, 0) > 0)
+                else
                 {
                 {
-                    /* Push it onto the BIOS keyboard queue */
-                    BiosKbdBufferPush((ScanCode << 8) | (Character & 0xFF));
+                    /* Key release, unset the highest bit */
+                    BiosKeyboardMap[VirtualKey] &= ~(1 << 7);
                 }
             }
                 }
             }
-            else
-            {
-                /* Key release, unset the highest bit */
-                BiosKeyboardMap[VirtualKey] &= ~(1 << 7);
-            }
 
             break;
         }
 
             break;
         }
index fb0e643..7081c58 100644 (file)
@@ -329,6 +329,14 @@ static VOID WINAPI EmulatorBiosOperation(PFAST486_STATE State, WORD Code)
     }
 }
 
     }
 }
 
+static BYTE WINAPI EmulatorIntAcknowledge(PFAST486_STATE State)
+{
+    UNREFERENCED_PARAMETER(State);
+
+    /* Get the interrupt number from the PIC */
+    return PicGetInterrupt();
+}
+
 /* PUBLIC FUNCTIONS ***********************************************************/
 
 BOOLEAN EmulatorInitialize()
 /* PUBLIC FUNCTIONS ***********************************************************/
 
 BOOLEAN EmulatorInitialize()
@@ -342,7 +350,8 @@ BOOLEAN EmulatorInitialize()
     EmulatorContext.MemWriteCallback = (FAST486_MEM_WRITE_PROC)EmulatorWriteMemory;
     EmulatorContext.IoReadCallback = (FAST486_IO_READ_PROC)EmulatorReadIo;
     EmulatorContext.IoWriteCallback = (FAST486_IO_WRITE_PROC)EmulatorWriteIo;
     EmulatorContext.MemWriteCallback = (FAST486_MEM_WRITE_PROC)EmulatorWriteMemory;
     EmulatorContext.IoReadCallback = (FAST486_IO_READ_PROC)EmulatorReadIo;
     EmulatorContext.IoWriteCallback = (FAST486_IO_WRITE_PROC)EmulatorWriteIo;
-    EmulatorContext.BopCallback = (FAST486_BOP_PROC)EmulatorBiosOperation;
+    EmulatorContext.BopCallback = EmulatorBiosOperation;
+    EmulatorContext.IntAckCallback = EmulatorIntAcknowledge;
 
     /* Reset the CPU */
     Fast486Reset(&EmulatorContext);
 
     /* Reset the CPU */
     Fast486Reset(&EmulatorContext);
@@ -371,10 +380,10 @@ VOID EmulatorInterrupt(BYTE Number)
     Fast486Interrupt(&EmulatorContext, Number);
 }
 
     Fast486Interrupt(&EmulatorContext, Number);
 }
 
-VOID EmulatorExternalInterrupt(BYTE Number)
+VOID EmulatorInterruptSignal(VOID)
 {
     /* Call the Fast486 API */
 {
     /* Call the Fast486 API */
-    Fast486Interrupt(&EmulatorContext, Number);
+    Fast486InterruptSignal(&EmulatorContext);
 }
 
 ULONG EmulatorGetRegister(ULONG Register)
 }
 
 ULONG EmulatorGetRegister(ULONG Register)
index 0906c7d..fcfb071 100644 (file)
@@ -88,7 +88,7 @@ BOOLEAN EmulatorInitialize();
 VOID EmulatorSetStack(WORD Segment, DWORD Offset);
 VOID EmulatorExecute(WORD Segment, WORD Offset);
 VOID EmulatorInterrupt(BYTE Number);
 VOID EmulatorSetStack(WORD Segment, DWORD Offset);
 VOID EmulatorExecute(WORD Segment, WORD Offset);
 VOID EmulatorInterrupt(BYTE Number);
-VOID EmulatorExternalInterrupt(BYTE Number);
+VOID EmulatorInterruptSignal(VOID);
 ULONG EmulatorGetRegister(ULONG Register);
 ULONG EmulatorGetProgramCounter(VOID);
 VOID EmulatorSetRegister(ULONG Register, ULONG Value);
 ULONG EmulatorGetRegister(ULONG Register);
 ULONG EmulatorGetProgramCounter(VOID);
 VOID EmulatorSetRegister(ULONG Register, ULONG Value);
index 7212309..60d7898 100644 (file)
@@ -79,12 +79,12 @@ INT wmain(INT argc, WCHAR *argv[])
     INT i;
     CHAR CommandLine[DOS_CMDLINE_LENGTH];
     DWORD CurrentTickCount;
     INT i;
     CHAR CommandLine[DOS_CMDLINE_LENGTH];
     DWORD CurrentTickCount;
-    DWORD LastTickCount = GetTickCount();
     DWORD Cycles = 0;
     DWORD LastCyclePrintout = GetTickCount();
     DWORD LastVerticalRefresh = GetTickCount();
     LARGE_INTEGER Frequency, LastTimerTick, Counter;
     LONGLONG TimerTicks;
     DWORD Cycles = 0;
     DWORD LastCyclePrintout = GetTickCount();
     DWORD LastVerticalRefresh = GetTickCount();
     LARGE_INTEGER Frequency, LastTimerTick, Counter;
     LONGLONG TimerTicks;
+    HANDLE InputThread = NULL;
 
     /* Set the handler routine */
     SetConsoleCtrlHandler(ConsoleCtrlHandler, TRUE);
 
     /* Set the handler routine */
     SetConsoleCtrlHandler(ConsoleCtrlHandler, TRUE);
@@ -141,6 +141,9 @@ INT wmain(INT argc, WCHAR *argv[])
         DisplayMessage(L"Could not start program: %S", CommandLine);
         return -1;
     }
         DisplayMessage(L"Could not start program: %S", CommandLine);
         return -1;
     }
+
+    /* Start the input thread */
+    InputThread = CreateThread(NULL, 0, &InputThreadProc, NULL, 0, NULL);
  
     /* Set the last timer tick to the current time */
     QueryPerformanceCounter(&LastTimerTick);
  
     /* Set the last timer tick to the current time */
     QueryPerformanceCounter(&LastTimerTick);
@@ -162,13 +165,6 @@ INT wmain(INT argc, WCHAR *argv[])
         for (i = 0; i < TimerTicks; i++) PitDecrementCount();
         LastTimerTick = Counter;
 
         for (i = 0; i < TimerTicks; i++) PitDecrementCount();
         LastTimerTick = Counter;
 
-        /* Check for console input events every millisecond */
-        if (CurrentTickCount != LastTickCount)
-        {
-            CheckForInputEvents();
-            LastTickCount = CurrentTickCount;
-        }
-
         /* Check for vertical retrace */
         if ((CurrentTickCount - LastVerticalRefresh) >= 16)
         {
         /* Check for vertical retrace */
         if ((CurrentTickCount - LastVerticalRefresh) >= 16)
         {
@@ -198,6 +194,7 @@ INT wmain(INT argc, WCHAR *argv[])
     VgaRefreshDisplay();
 
 Cleanup:
     VgaRefreshDisplay();
 
 Cleanup:
+    if (InputThread != NULL) CloseHandle(InputThread);
     BiosCleanup();
     EmulatorCleanup();
 
     BiosCleanup();
     EmulatorCleanup();
 
index 51d2feb..de7a0a1 100644 (file)
@@ -35,8 +35,8 @@ BYTE PicReadCommand(BYTE Port)
     }
     else
     {
     }
     else
     {
-        /* The IRR is always 0, as the emulated CPU receives the interrupt instantly */
-        return 0;
+        /* Read the interrupt request register */
+        return Pic->IntRequestRegister;
     }
 }
 
     }
 }
 
@@ -167,9 +167,9 @@ VOID PicInterruptRequest(BYTE Number)
         /* Check if the interrupt is masked */
         if (MasterPic.MaskRegister & (1 << Number)) return;
 
         /* Check if the interrupt is masked */
         if (MasterPic.MaskRegister & (1 << Number)) return;
 
-        /* Set the appropriate bit in the ISR and interrupt the CPU */
-        if (!MasterPic.AutoEoi) MasterPic.InServiceRegister |= 1 << Number;
-        EmulatorExternalInterrupt(MasterPic.IntOffset + Number);
+        /* Set the appropriate bit in the IRR and interrupt the CPU */
+        MasterPic.IntRequestRegister |= 1 << Number;
+        EmulatorInterruptSignal();
     }
     else if (Number >= 8 && Number < 16)
     {
     }
     else if (Number >= 8 && Number < 16)
     {
@@ -187,7 +187,7 @@ VOID PicInterruptRequest(BYTE Number)
 
         /* Check if any of the higher-priorirty interrupts are busy */
         if (MasterPic.InServiceRegister != 0) return;
 
         /* Check if any of the higher-priorirty interrupts are busy */
         if (MasterPic.InServiceRegister != 0) return;
-        for (i = 0; i <= Number ; i++)
+        for (i = 0; i <= Number; i++)
         {
             if (SlavePic.InServiceRegister & (1 << Number)) return;
         }
         {
             if (SlavePic.InServiceRegister & (1 << Number)) return;
         }
@@ -196,12 +196,57 @@ VOID PicInterruptRequest(BYTE Number)
         if (SlavePic.MaskRegister & (1 << Number)) return;
 
         /* Set the IRQ 2 bit in the master ISR */
         if (SlavePic.MaskRegister & (1 << Number)) return;
 
         /* Set the IRQ 2 bit in the master ISR */
-        if (!MasterPic.AutoEoi) MasterPic.InServiceRegister |= 1 << 2;
+        if (!MasterPic.AutoEoi) MasterPic.InServiceRegister |= (1 << 2);
+
+        /* Set the appropriate bit in the IRR and interrupt the CPU */
+        SlavePic.IntRequestRegister |= 1 << Number;
+        EmulatorInterruptSignal();
+    }
+}
+
+BYTE PicGetInterrupt(VOID)
+{
+    INT i, j;
+
+    /* Search interrupts by priority */
+    for (i = 0; i < 8; i++)
+    {
+        /* Check if this line is cascaded to the slave PIC */
+        if ((i == 2)
+            && MasterPic.CascadeRegister & (1 << 2)
+            && SlavePic.Slave
+            && (SlavePic.CascadeRegister == 2))
+        {
+            /* Search the slave PIC interrupts by priority */
+            for (j = 0; j < 8; j++) if ((j != 1) && SlavePic.IntRequestRegister & (1 << j))
+            {
+                /* Clear the IRR flag */
+                SlavePic.IntRequestRegister &= ~(1 << j);
+
+                /* Set the ISR flag, unless AEOI is enabled */
+                if (!SlavePic.AutoEoi) SlavePic.InServiceRegister |= (1 << j);
+    
+                /* Return the interrupt number */
+                return SlavePic.IntOffset + j;
+            }
+        }
 
 
-        /* Set the appropriate bit in the ISR and interrupt the CPU */
-        if (!SlavePic.AutoEoi) SlavePic.InServiceRegister |= 1 << Number;
-        EmulatorExternalInterrupt(SlavePic.IntOffset + Number);
+        if (MasterPic.IntRequestRegister & (1 << i))
+        {
+            /* Clear the IRR flag */
+            MasterPic.IntRequestRegister &= ~(1 << i);
+
+            /* Set the ISR flag, unless AEOI is enabled */
+            if (!MasterPic.AutoEoi) MasterPic.InServiceRegister |= (1 << i);
+
+            /* Return the interrupt number */
+            return MasterPic.IntOffset + i;
+        }
     }
     }
+    
+    /* Spurious interrupt */
+    if (MasterPic.InServiceRegister & (1 << 2)) return SlavePic.IntOffset + 7;
+    else return MasterPic.IntOffset + 7;
 }
 
 /* EOF */
 }
 
 /* EOF */
index adc47e4..ef60b61 100644 (file)
@@ -34,6 +34,7 @@ typedef struct _PIC
 {
     BOOLEAN Initialization;
     BYTE MaskRegister;
 {
     BOOLEAN Initialization;
     BYTE MaskRegister;
+    BYTE IntRequestRegister;
     BYTE InServiceRegister;
     BYTE IntOffset;
     BYTE ConfigRegister;
     BYTE InServiceRegister;
     BYTE IntOffset;
     BYTE ConfigRegister;
@@ -51,6 +52,7 @@ VOID PicWriteCommand(BYTE Port, BYTE Value);
 BYTE PicReadData(BYTE Port);
 VOID PicWriteData(BYTE Port, BYTE Value);
 VOID PicInterruptRequest(BYTE Number);
 BYTE PicReadData(BYTE Port);
 VOID PicWriteData(BYTE Port, BYTE Value);
 VOID PicInterruptRequest(BYTE Number);
+BYTE PicGetInterrupt(VOID);
 
 #endif // _PIC_H_
 
 
 #endif // _PIC_H_
 
index 276cce7..ed8e82a 100644 (file)
@@ -265,49 +265,64 @@ VOID KeyboardWriteData(BYTE Data)
     // TODO: Implement PS/2 device commands
 }
 
     // TODO: Implement PS/2 device commands
 }
 
-VOID CheckForInputEvents()
+DWORD WINAPI InputThreadProc(LPVOID Parameter)
 {
 {
-    PINPUT_RECORD Buffer;
+    INT i;
     HANDLE ConsoleInput = GetStdHandle(STD_INPUT_HANDLE);
     HANDLE ConsoleInput = GetStdHandle(STD_INPUT_HANDLE);
-    DWORD i, j, Count, TotalEvents;
-    BYTE ScanCode;
-    BOOLEAN Interrupt = FALSE;
+    INPUT_RECORD InputRecord;
+    DWORD Count;
 
 
-    /* Get the number of input events */
-    if (!GetNumberOfConsoleInputEvents(ConsoleInput, &Count)) return;
-    if (Count == 0) return;
+    while (VdmRunning)
+    {
+        /* Wait for an input record */
+        if (!ReadConsoleInput(ConsoleInput, &InputRecord, 1, &Count))
+        {
+            DPRINT1("Error reading console input\n");
+            return GetLastError();
+        }
 
 
-    /* Allocate the buffer */
-    Buffer = (PINPUT_RECORD)HeapAlloc(GetProcessHeap(), 0, Count * sizeof(INPUT_RECORD));
-    if (Buffer == NULL) return;
+        ASSERT(Count != 0);
 
 
-    /* Peek the input events */
-    if (!ReadConsoleInput(ConsoleInput, Buffer, Count, &TotalEvents)) goto Cleanup;
+        /* Check the event type */
+        switch (InputRecord.EventType)
+        {
+            case KEY_EVENT:
+            {
+                BYTE ScanCode = (BYTE)InputRecord.Event.KeyEvent.wVirtualScanCode;
 
 
-    for (i = 0; i < TotalEvents; i++)
-    {
-        /* Check if this is a key event */
-        if (Buffer[i].EventType != KEY_EVENT) continue;
+                /* If this is a key release, set the highest bit in the scan code */
+                if (!InputRecord.Event.KeyEvent.bKeyDown) ScanCode |= 0x80;
 
 
-        /* Get the scan code */
-        ScanCode = (BYTE)Buffer[i].Event.KeyEvent.wVirtualScanCode;
+                /* Push the scan code onto the keyboard queue */
+                for (i = 0; i < InputRecord.Event.KeyEvent.wRepeatCount; i++)
+                {
+                    KeyboardQueuePush(ScanCode);
+                }
 
 
-        /* If this is a key release, set the highest bit in the scan code */
-        if (!Buffer[i].Event.KeyEvent.bKeyDown) ScanCode |= 0x80;
+                /* Keyboard IRQ */
+                PicInterruptRequest(1);
 
 
-        /* Push the scan code onto the keyboard queue */
-        for (j = 0; j < Buffer[i].Event.KeyEvent.wRepeatCount; j++)
-        {
-            KeyboardQueuePush(ScanCode);
-        }
+                break;
+            }
 
 
-        Interrupt = TRUE;
-    }
+            case MOUSE_EVENT:
+            {
+                // TODO: NOT IMPLEMENTED
+                UNIMPLEMENTED;
+
+                break;
+            }
 
 
-    if (Interrupt) PicInterruptRequest(1);
+            default:
+            {
+                /* Ignored */
+                break;
+            }
+        }
+    }
 
 
-Cleanup:
-    HeapFree(GetProcessHeap(), 0, Buffer);
+    return 0;
 }
 
 /* EOF */
 }
 
 /* EOF */
index 94d68a1..67799a6 100644 (file)
@@ -28,7 +28,7 @@ BYTE KeyboardReadStatus();
 VOID KeyboardWriteCommand(BYTE Command);
 BYTE KeyboardReadData();
 VOID KeyboardWriteData(BYTE Data);
 VOID KeyboardWriteCommand(BYTE Command);
 BYTE KeyboardReadData();
 VOID KeyboardWriteData(BYTE Data);
-VOID CheckForInputEvents();
+DWORD WINAPI InputThreadProc(LPVOID Parameter);
 
 #endif // _PS2_H_
 
 
 #endif // _PS2_H_