[NTVDM]
authorHermès Bélusca-Maïto <hermes.belusca-maito@reactos.org>
Sat, 27 Sep 2014 02:17:54 +0000 (02:17 +0000)
committerHermès Bélusca-Maïto <hermes.belusca-maito@reactos.org>
Sat, 27 Sep 2014 02:17:54 +0000 (02:17 +0000)
Implement INT 15h, AH=4Fh "Keyboard intercept", which is used by INT 9h / IRQ 1 to possibly translate scan code before any further treatment. The default implementation is a trivial one, do it à la DosBox.

svn path=/trunk/; revision=64324

reactos/subsystems/ntvdm/bios/bios32/bios32.c
reactos/subsystems/ntvdm/bios/bios32/kbdbios32.c
reactos/subsystems/ntvdm/dos/dem.c
reactos/subsystems/ntvdm/hardware/keyboard.c

index aab15d3..b012d90 100644 (file)
@@ -146,6 +146,16 @@ static VOID WINAPI BiosMiscService(LPWORD Stack)
 {
     switch (getAH())
     {
+        /* Keyboard intercept */
+        case 0x4F:
+        {
+            /* CF should be set but let's just set it again just in case */
+            /* Do not modify AL (the hardware scan code), but set CF to continue processing */
+            // setCF(1);
+            Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
+            break;
+        }
+
         /* Wait */
         case 0x86:
         {
@@ -493,7 +503,7 @@ static VOID InitializeBiosInfo(VOID)
     Bct->Model      = BIOS_MODEL;
     Bct->SubModel   = BIOS_SUBMODEL;
     Bct->Revision   = BIOS_REVISION;
-    Bct->Feature[0] = 0x64; // At the moment we don't support "INT 15/AH=4Fh called upon INT 09h" nor "wait for external event (INT 15/AH=41h) supported"; see http://www.ctyme.com/intr/rb-1594.htm#Table510
+    Bct->Feature[0] = 0x70; // At the moment we don't support "wait for external event (INT 15/AH=41h)", we also don't have any "extended BIOS area allocated (usually at top of RAM)"; see http://www.ctyme.com/intr/rb-1594.htm#Table510
     Bct->Feature[1] = 0x00; // We don't support anything from here; see http://www.ctyme.com/intr/rb-1594.htm#Table511
     Bct->Feature[2] = 0x00;
     Bct->Feature[3] = 0x00;
index 70b0513..0c60a54 100644 (file)
@@ -197,8 +197,26 @@ static VOID WINAPI BiosKeyboardIrq(LPWORD Stack)
     BYTE ScanCode, VirtualKey;
     WORD Character;
 
-    /* Get the scan code and virtual key code */
-    ScanCode   = IOReadB(PS2_DATA_PORT);
+    /*
+     * Get the scan code from the PS/2 port, then call the
+     * INT 15h, AH=4Fh Keyboard Intercept function to try to
+     * translate the scan code. CF must be set before the call.
+     * In return, if CF is set we continue processing the scan code
+     * stored in AL, and if not, we skip it.
+     */
+    setCF(1);
+    setAL(IOReadB(PS2_DATA_PORT));
+    setAH(0x4F);
+    Int32Call(&BiosContext, BIOS_MISC_INTERRUPT);
+
+    /* Check whether CL is clear. If so, skip the scan code. */
+    if (getCF() == 0) goto Quit;
+    /**/setCF(0);/**/ // FIXME: HACK: Reset CF otherwise we enter in an infinite loop.
+
+    /* Retrieve the modified scan code in AL */
+    ScanCode = getAL();
+
+    /* Get the corresponding virtual key code */
     VirtualKey = MapVirtualKey(ScanCode & 0x7F, MAPVK_VSC_TO_VK);
 
     /* Check if this is a key press or release */
@@ -255,6 +273,10 @@ static VOID WINAPI BiosKeyboardIrq(LPWORD Stack)
     if (BiosKeyboardMap[VK_CAPITAL]  & (1 << 7)) Bda->KeybdShiftFlags |= BDA_KBDFLAG_CAPSLOCK;
     if (BiosKeyboardMap[VK_INSERT]   & (1 << 7)) Bda->KeybdShiftFlags |= BDA_KBDFLAG_INSERT;
 
+    DPRINT("BiosKeyboardIrq - Character = 0x%X, ScanCode = 0x%X, KeybdShiftFlags = 0x%X\n",
+           Character, ScanCode, Bda->KeybdShiftFlags);
+
+Quit:
     PicIRQComplete(Stack);
 }
 
index b751e4b..4b75d85 100644 (file)
@@ -91,7 +91,6 @@ Quit:
 
         default:
         {
-
             DPRINT1("Unknown DOS System BOP Function: 0x%02X\n", FuncNum);
             // setCF(1); // Disable, otherwise we enter an infinite loop
             break;
index 7ce2aa2..5e98bf7 100644 (file)
@@ -40,6 +40,8 @@ VOID KeyboardEventHandler(PKEY_EVENT_RECORD KeyEvent)
         PS2QueuePush(PS2Port, ScanCode);
     }
 
+    DPRINT("Press 0x%X\n", ScanCode);
+
     // PicInterruptRequest(1);
 }