Author: hbelusca
Date: Fri Aug 7 16:10:18 2015
New Revision: 68613
URL:
http://svn.reactos.org/svn/reactos?rev=68613&view=rev
Log:
[NTVDM]
PS2:
- By default all the PS/2 ports are disabled. They become enabled by the BIOS at the POST
step.
- Similarly it is the BIOS POST that sets up the PS/2 controller configuration byte.
- Synchronize the value of bit 2 "System flag" and bit 4 "Keyboard enable
flag" in the status register, according to what is set in the controller
configuration register. What is the "keyboard enable flag" ? See
http://www.os2museum.com/wp/the-dos-4-0-shell-mouse-mystery/ for more details...
HW MOUSE:
- Resetting the mouse sends also an ACKnowledge byte too...
BIOS32:
- Fix the reported number of bytes in the BIOS configuration table.
- Enable the PS/2 ports in the POST.
- Implement the "Pointing Device BIOS Interface" INT 15h, AH=C2h, AL=00h...09h
based on VBox OSE & SeaBIOS; we should make our PS/2 mouse driver use it.
The real call to INT 15h, AH=C2h function is still disabled because our mouse driver
doesn't react well with it, when we run some applications like MS Diagnostics.
PS2 MOUSE DRV:
- Update copyright notice;
- Remove 2 useless functions;
- I've put in comments in the code the places where calls to the BIOS ps/2 mouse
interface are needed.
Modified:
trunk/reactos/subsystems/mvdm/ntvdm/bios/bios.h
trunk/reactos/subsystems/mvdm/ntvdm/bios/bios32/bios32.c
trunk/reactos/subsystems/mvdm/ntvdm/bios/bios32/moubios32.c
trunk/reactos/subsystems/mvdm/ntvdm/dos/mouse32.c
trunk/reactos/subsystems/mvdm/ntvdm/dos/mouse32.h
trunk/reactos/subsystems/mvdm/ntvdm/hardware/mouse.c
trunk/reactos/subsystems/mvdm/ntvdm/hardware/ps2.c
Modified: trunk/reactos/subsystems/mvdm/ntvdm/bios/bios.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/mvdm/ntvdm/bios…
==============================================================================
--- trunk/reactos/subsystems/mvdm/ntvdm/bios/bios.h [iso-8859-1] (original)
+++ trunk/reactos/subsystems/mvdm/ntvdm/bios/bios.h [iso-8859-1] Fri Aug 7 16:10:18 2015
@@ -142,7 +142,7 @@
*/
typedef struct _BIOS_CONFIG_TABLE
{
- WORD Length; // 0x00
+ WORD Length; // 0x00 - Number of bytes following
BYTE Model; // 0x02
BYTE SubModel; // 0x03
BYTE Revision; // 0x04
Modified: trunk/reactos/subsystems/mvdm/ntvdm/bios/bios32/bios32.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/mvdm/ntvdm/bios…
==============================================================================
--- trunk/reactos/subsystems/mvdm/ntvdm/bios/bios32/bios32.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/mvdm/ntvdm/bios/bios32/bios32.c [iso-8859-1] Fri Aug 7
16:10:18 2015
@@ -4,6 +4,7 @@
* FILE: bios32.c
* PURPOSE: VDM 32-bit BIOS
* PROGRAMMERS: Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
+ * Hermes Belusca-Maito (hermes.belusca(a)sfr.fr)
*/
/* INCLUDES *******************************************************************/
@@ -109,7 +110,7 @@
static const BIOS_CONFIG_TABLE BiosConfigTable =
{
- sizeof(BIOS_CONFIG_TABLE), // Length
+ sizeof(BIOS_CONFIG_TABLE) - sizeof(((BIOS_CONFIG_TABLE*)0)->Length), // Length:
Number of bytes following
BIOS_MODEL, // BIOS Model
BIOS_SUBMODEL, // BIOS Sub-Model
@@ -325,7 +326,6 @@
{
setAX(0x80);
Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
-
break;
}
@@ -394,8 +394,11 @@
/* Pointing Device BIOS Interface (PS) */
case 0xC2:
{
- BiosMousePs2Interface(Stack);
- UNIMPLEMENTED; // Remove it when BiosMousePs2Interface is implemented!
+ // FIXME: Reenable this call when we understand why
+ // our included mouse driver doesn't correctly reeanble
+ // mouse reporting!
+ // BiosMousePs2Interface(Stack);
+ // break;
goto Default;
}
@@ -429,7 +432,7 @@
ULONG Above1M = (min(MAX_ADDRESS, 0x01000000) - 0x00100000) >> 10;
/* The amount of memory above 16M, in 64K blocks */
- ULONG Above16M = (MAX_ADDRESS > 0x01000000) ? (MAX_ADDRESS -
0x01000000) >> 16: 0;
+ ULONG Above16M = (MAX_ADDRESS > 0x01000000) ? ((MAX_ADDRESS -
0x01000000) >> 16) : 0;
setAX(Above1M);
setBX(Above16M);
@@ -476,8 +479,7 @@
else
{
DPRINT1("BIOS Function INT 15h, AH = 0xE8 - unexpected AL = %02X,
EDX = %08X\n",
- getAL(),
- getEDX());
+ getAL(), getEDX());
}
break;
@@ -773,6 +775,16 @@
IOWriteB(PIT_DATA_PORT(2), 0x97);
IOWriteB(PIT_DATA_PORT(2), 0x0A);
+
+ /* Initialize PS/2 keyboard port */
+ // Enable the port
+ IOWriteB(PS2_CONTROL_PORT, 0xAE);
+ IOWriteB(PS2_CONTROL_PORT, 0x60);
+ // Port interrupts and clock enabled,
+ // enable keyboard scancode translation.
+ // POST passed, force keyboard unlocking.
+ IOWriteB(PS2_DATA_PORT , 0x4D);
+
EnableHwIRQ(0, BiosTimerIrq);
}
@@ -785,7 +797,10 @@
/* Register the default BIOS interrupt vectors */
- /* Zero out all of the IVT (0x00 -- 0xFF) */
+ /*
+ * Zero out all of the IVT (0x00 -- 0xFF). Some applications
+ * indeed expect to have free vectors at the end of the IVT.
+ */
RtlZeroMemory(BaseAddress, 0x0100 * sizeof(ULONG));
#if defined(ADVANCED_DEBUGGING) && (ADVANCED_DEBUGGING_LEVEL >= 3)
Modified: trunk/reactos/subsystems/mvdm/ntvdm/bios/bios32/moubios32.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/mvdm/ntvdm/bios…
==============================================================================
--- trunk/reactos/subsystems/mvdm/ntvdm/bios/bios32/moubios32.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/mvdm/ntvdm/bios/bios32/moubios32.c [iso-8859-1] Fri Aug 7
16:10:18 2015
@@ -2,8 +2,11 @@
* COPYRIGHT: GPL - See COPYING in the top level directory
* PROJECT: ReactOS Virtual DOS Machine
* FILE: moubios32.c
- * PURPOSE: VDM Mouse 32-bit BIOS
+ * PURPOSE: VDM 32-bit PS/2 Mouse BIOS
* PROGRAMMERS: Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
+ * Hermes Belusca-Maito (hermes.belusca(a)sfr.fr)
+ *
+ * NOTE: Based from VirtualBox OSE ROM BIOS, and SeaBIOS.
*/
/* INCLUDES *******************************************************************/
@@ -12,118 +15,512 @@
#include "ntvdm.h"
#include "emulator.h"
+#include "cpu/cpu.h" // for EMULATOR_FLAG_CF
#include "moubios32.h"
#include "bios32p.h"
#include "io.h"
+#include "hardware/mouse.h"
#include "hardware/ps2.h"
/* PRIVATE VARIABLES **********************************************************/
+#define MOUSE_IRQ_INT 0x74
+
+static BOOLEAN MouseEnabled = FALSE;
+static DWORD OldIrqHandler;
+
+/*
+ * Far pointer to a device handler. In compatible PS/2, it is stored in the EBDA.
+ *
+ * See Ralf Brown:
http://www.ctyme.com/intr/rb-1603.htm
+ * for more information. In particular:
+ * when the subroutine is called, it is given 4 WORD values on the stack;
+ * the handler should return with a FAR return without popping the stack.
+ */
+static ULONG DeviceHandler = 0;
+
/* PRIVATE FUNCTIONS **********************************************************/
+
+static VOID DisableMouseInt(VOID)
+{
+ BYTE ControllerConfig;
+
+ /* Clear the mouse queue */
+ while (PS2PortQueueRead(1)) ; // NOTE: Should be a IOReadB! But see r67231
+
+ /* Disable mouse interrupt and events */
+ IOWriteB(PS2_CONTROL_PORT, 0x20);
+ ControllerConfig = IOReadB(PS2_DATA_PORT);
+ ControllerConfig &= ~0x02; // Turn off IRQ12
+ ControllerConfig |= 0x20; // Disable mouse clock line
+ IOWriteB(PS2_CONTROL_PORT, 0x60);
+ IOWriteB(PS2_DATA_PORT, ControllerConfig);
+}
+
+static VOID EnableMouseInt(VOID)
+{
+ BYTE ControllerConfig;
+
+ /* Clear the mouse queue */
+ while (PS2PortQueueRead(1)) ; // NOTE: Should be a IOReadB! But see r67231
+
+ /* Enable mouse interrupt and events */
+ IOWriteB(PS2_CONTROL_PORT, 0x20);
+ ControllerConfig = IOReadB(PS2_DATA_PORT);
+ ControllerConfig |= 0x02; // Turn on IRQ12
+ ControllerConfig &= ~0x20; // Enable mouse clock line
+ IOWriteB(PS2_CONTROL_PORT, 0x60);
+ IOWriteB(PS2_DATA_PORT, ControllerConfig);
+}
+
+static inline
+VOID SendMouseCommand(UCHAR Command)
+{
+ /* Clear the mouse queue */
+ while (PS2PortQueueRead(1)) ; // NOTE: Should be a IOReadB! But see r67231
+
+ /* Send the command */
+ IOWriteB(PS2_CONTROL_PORT, 0xD4);
+ IOWriteB(PS2_DATA_PORT, Command);
+}
+
+static inline
+UCHAR ReadMouseData(VOID)
+{
+ PS2PortQueueRead(1); // NOTE: Should be a IOReadB! But see r67231
+ return IOReadB(PS2_DATA_PORT);
+}
+
+
+static
+VOID BiosMouseEnable(VOID)
+{
+ if (MouseEnabled) return;
+
+ MouseEnabled = TRUE;
+
+ /* Get the old IRQ handler */
+ OldIrqHandler = ((PDWORD)BaseAddress)[MOUSE_IRQ_INT];
+
+ /* Set the IRQ handler */
+ //RegisterInt32(MAKELONG(FIELD_OFFSET(MOUSE_DRIVER, MouseIrqInt16Stub),
MouseDataSegment),
+ // MOUSE_IRQ_INT, DosMouseIrq, NULL);
+}
+
+static
+VOID BiosMouseDisable(VOID)
+{
+ if (!MouseEnabled) return;
+
+ /* Restore the old IRQ handler */
+ // ((PDWORD)BaseAddress)[MOUSE_IRQ_INT] = OldIrqHandler;
+
+ MouseEnabled = FALSE;
+}
+
// Mouse IRQ 12
static VOID WINAPI BiosMouseIrq(LPWORD Stack)
{
+ DPRINT1("PS/2 Mouse IRQ! DeviceHandler = 0x%04X:0x%04X\n",
+ HIWORD(DeviceHandler), LOWORD(DeviceHandler));
+
+ if (DeviceHandler != 0)
+ {
+ /*
+ * Prepare the stack for the mouse device handler:
+ * push Status, X and Y data, and a zero word.
+ */
+ setSP(getSP() - sizeof(WORD));
+ *((LPWORD)SEG_OFF_TO_PTR(getSS(), getSP())) = 0; // Status
+ setSP(getSP() - sizeof(WORD));
+ *((LPWORD)SEG_OFF_TO_PTR(getSS(), getSP())) = 0; // X data (high byte = 0)
+ setSP(getSP() - sizeof(WORD));
+ *((LPWORD)SEG_OFF_TO_PTR(getSS(), getSP())) = 0; // Y data (high byte = 0)
+ setSP(getSP() - sizeof(WORD));
+ *((LPWORD)SEG_OFF_TO_PTR(getSS(), getSP())) = 0; // Zero
+
+ /* Call the device handler */
+ RunCallback16(&BiosContext, DeviceHandler);
+
+ /* Pop the stack */
+ setSP(getSP() + 4*sizeof(WORD));
+ }
+
PicIRQComplete(LOBYTE(Stack[STACK_INT_NUM]));
}
VOID BiosMousePs2Interface(LPWORD Stack)
{
- DPRINT1("INT 15h, AH = C2h must be implemented in order to support vendor mouse
drivers\n");
+ /* Disable mouse interrupt and events */
+ DisableMouseInt();
switch (getAL())
{
/* Enable / Disable */
case 0x00:
{
- break;
+ UCHAR State = getBH();
+
+ if (State > 2)
+ {
+ /* Invalid function */
+ setAH(0x01);
+ Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
+ break;
+ }
+
+ if (State == 0x00)
+ {
+ BiosMouseDisable();
+
+ /* Disable packet reporting */
+ SendMouseCommand(0xF5);
+ }
+ else // if (State == 0x01)
+ {
+ /* Check for the presence of the device handler */
+ if (DeviceHandler == 0)
+ {
+ /* No device handler installed */
+ setAH(0x05);
+ Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
+ break;
+ }
+
+ BiosMouseEnable();
+
+ /* Enable packet reporting */
+ SendMouseCommand(0xF4);
+ }
+
+ if (ReadMouseData() != MOUSE_ACK)
+ {
+ /* Failure */
+ setAH(0x03);
+ Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
+ break;
+ }
+
+ /* Success */
+ setAH(0x00);
+ Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
+ break;
+ }
+
+ /* Initialize */
+ case 0x05:
+ {
+ // Fall through
}
/* Reset */
case 0x01:
{
+ UCHAR Answer;
+
+ SendMouseCommand(0xFF);
+ Answer = ReadMouseData();
+ /* A "Resend" (0xFE) signal is sent if no mouse is attached */
+ if (Answer == 0xFE)
+ {
+ /* Resend */
+ setAH(0x04);
+ Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
+ break;
+ }
+ else if (Answer != MOUSE_ACK)
+ {
+ /* Failure */
+ setAH(0x03);
+ Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
+ break;
+ }
+
+ setBL(ReadMouseData()); // Should be MOUSE_BAT_SUCCESS
+ setBH(ReadMouseData()); // Mouse ID
+
+ /* Success */
+ setAH(0x00);
+ Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
break;
}
/* Set Sampling Rate */
case 0x02:
{
+ UCHAR SampleRate = 0;
+
+ switch (getBH())
+ {
+ case 0x00: SampleRate = 10; break; // 10 reports/sec
+ case 0x01: SampleRate = 20; break; // 20 " "
+ case 0x02: SampleRate = 40; break; // 40 " "
+ case 0x03: SampleRate = 60; break; // 60 " "
+ case 0x04: SampleRate = 80; break; // 80 " "
+ case 0x05: SampleRate = 100; break; // 100 " "
+ case 0x06: SampleRate = 200; break; // 200 " "
+ default: SampleRate = 0;
+ }
+
+ if (SampleRate == 0)
+ {
+ /* Invalid input */
+ setAH(0x02);
+ Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
+ break;
+ }
+
+ SendMouseCommand(0xF3);
+ if (ReadMouseData() != MOUSE_ACK)
+ {
+ /* Failure */
+ setAH(0x03);
+ Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
+ break;
+ }
+
+ SendMouseCommand(SampleRate);
+ if (ReadMouseData() != MOUSE_ACK)
+ {
+ /* Failure */
+ setAH(0x03);
+ Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
+ break;
+ }
+
+ /* Success */
+ setAH(0x00);
+ Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
break;
}
/* Set Resolution */
case 0x03:
{
+ UCHAR Resolution = getBH();
+
+ /*
+ * 0: 25 dpi, 1 count per millimeter
+ * 1: 50 dpi, 2 counts per millimeter
+ * 2: 100 dpi, 4 counts per millimeter
+ * 3: 200 dpi, 8 counts per millimeter
+ */
+ if (Resolution > 3)
+ {
+ /* Invalid input */
+ setAH(0x02);
+ Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
+ break;
+ }
+
+ SendMouseCommand(0xE8);
+ if (ReadMouseData() != MOUSE_ACK)
+ {
+ /* Failure */
+ setAH(0x03);
+ Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
+ break;
+ }
+
+ SendMouseCommand(Resolution);
+ if (ReadMouseData() != MOUSE_ACK)
+ {
+ /* Failure */
+ setAH(0x03);
+ Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
+ break;
+ }
+
+ /* Success */
+ setAH(0x00);
+ Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
break;
}
/* Get Type */
case 0x04:
{
- break;
- }
-
- /* Initialize */
- case 0x05:
- {
- break;
- }
-
- /* Extended Commands */
+ SendMouseCommand(0xF2);
+ if (ReadMouseData() != MOUSE_ACK)
+ {
+ /* Failure */
+ setAH(0x03);
+ Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
+ break;
+ }
+
+ setBH(ReadMouseData());
+
+ /* Success */
+ setAH(0x00);
+ Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
+ break;
+ }
+
+ /* Extended Commands (Return Status and Set Scaling Factor) */
case 0x06:
{
+ UCHAR Command = getBH();
+
+ switch (Command)
+ {
+ /* Return Status */
+ case 0x00:
+ {
+ SendMouseCommand(0xE9);
+ if (ReadMouseData() != MOUSE_ACK)
+ {
+ /* Failure */
+ setAH(0x03);
+ Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
+ }
+
+ setBL(ReadMouseData()); // Status
+ setCL(ReadMouseData()); // Resolution
+ setDL(ReadMouseData()); // Sample rate
+
+ /* Success */
+ setAH(0x00);
+ Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
+ break;
+ }
+
+ /* Set Scaling Factor to 1:1 */
+ case 0x01:
+ /* Set Scaling Factor to 2:1 */
+ case 0x02:
+ {
+ SendMouseCommand(Command == 0x01 ? 0xE6 : 0xE7);
+ if (ReadMouseData() != MOUSE_ACK)
+ {
+ /* Failure */
+ setAH(0x03);
+ Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
+ }
+
+ /* Success */
+ setAH(0x00);
+ Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
+ break;
+ }
+
+ default:
+ {
+ /* Invalid function */
+ setAH(0x01);
+ Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
+ break;
+ }
+ }
+
break;
}
/* Set Device Handler Address */
case 0x07:
{
+ /* ES:BX == 0000h:0000h removes the device handler */
+ DeviceHandler = MAKELONG(getBX(), getES());
+
+ /* Success */
+ setAH(0x00);
+ Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
break;
}
/* Write to Pointer Port */
case 0x08:
{
+ SendMouseCommand(getBL());
+ if (ReadMouseData() != MOUSE_ACK)
+ {
+ /* Failure */
+ setAH(0x03);
+ Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
+ break;
+ }
+
+ /* Success */
+ setAH(0x00);
+ Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
break;
}
/* Read from Pointer Port */
case 0x09:
{
+ setBL(ReadMouseData());
+ setCL(ReadMouseData());
+ setDL(ReadMouseData());
+
+ /* Success */
+ setAH(0x00);
+ Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
break;
}
default:
{
- DPRINT1("INT 15h, AH = C2h, AL = 0x%02X NOT IMPLEMENTED\n",
+ DPRINT1("INT 15h, AH = C2h, AL = %02Xh NOT IMPLEMENTED\n",
getAL());
+
+ /* Unknown function */
+ setAH(0x01);
+ Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
}
}
+
+ /* Reenable mouse interrupt and events */
+ EnableMouseInt();
}
/* PUBLIC FUNCTIONS ***********************************************************/
VOID MouseBios32Post(VOID)
{
- BYTE ControllerConfig;
-
- /* Clear the mouse queue */
- while (PS2PortQueueRead(1)) continue;
-
- /* Enable packet reporting */
- IOWriteB(PS2_CONTROL_PORT, 0xD4);
- IOWriteB(PS2_DATA_PORT, 0xF4);
-
- /* Read the mouse ACK reply */
- PS2PortQueueRead(1);
-
- /* Enable IRQ12 */
- IOWriteB(PS2_CONTROL_PORT, 0x20);
- ControllerConfig = IOReadB(PS2_DATA_PORT);
- IOWriteB(PS2_CONTROL_PORT, 0x60);
- IOWriteB(PS2_DATA_PORT, ControllerConfig | 0x02);
+ UCHAR Answer;
+
+ /* Initialize PS/2 mouse port */
+ // Enable the port
+ IOWriteB(PS2_CONTROL_PORT, 0xA8);
+
+ /* Detect mouse presence by attempting a reset */
+ SendMouseCommand(0xFF);
+ Answer = ReadMouseData();
+ /* If no mouse attached, it will return RESEND (0xFE) */
+ if (Answer == 0xFE)
+ {
+ DPRINT1("No mouse present!\n");
+ }
+ else if (Answer != MOUSE_ACK)
+ {
+ DPRINT1("Mouse reset failure!\n");
+ }
+ else
+ {
+ /* Mouse present, try to completely enable it */
+
+ // FIXME: The following is temporary until
+ // this is moved into the mouse driver!!
+
+ /* Enable packet reporting */
+ SendMouseCommand(0xF4);
+ if (ReadMouseData() != MOUSE_ACK)
+ {
+ DPRINT1("Failed to enable mouse!\n");
+ }
+ else
+ {
+ /* Enable mouse interrupt and events */
+ EnableMouseInt();
+ }
+ }
+
+ /* No mouse driver available so far */
+ RegisterBiosInt32(0x33, NULL);
/* Set up the HW vector interrupts */
EnableHwIRQ(12, BiosMouseIrq);
Modified: trunk/reactos/subsystems/mvdm/ntvdm/dos/mouse32.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/mvdm/ntvdm/dos/…
==============================================================================
--- trunk/reactos/subsystems/mvdm/ntvdm/dos/mouse32.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/mvdm/ntvdm/dos/mouse32.c [iso-8859-1] Fri Aug 7 16:10:18
2015
@@ -2,13 +2,17 @@
* COPYRIGHT: GPL - See COPYING in the top level directory
* PROJECT: ReactOS Virtual DOS Machine
* FILE: mouse32.c
- * PURPOSE: VDM 32-bit compatible
MOUSE.COM driver
+ * PURPOSE: VDM 32-bit compatible PS/2
MOUSE.COM driver
* PROGRAMMERS: Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
*/
/* INCLUDES *******************************************************************/
#define NDEBUG
+
+/* Driver Version number and Copyright */
+#include <reactos/buildno.h>
+#include <reactos/version.h>
#include "ntvdm.h"
#include "emulator.h"
@@ -30,7 +34,10 @@
/* PRIVATE VARIABLES **********************************************************/
-static const CHAR MouseCopyright[] = "ROS PS/2 16/32-bit Mouse Driver Compatible
MS-MOUSE 6.26 Copyright (C) ReactOS Team 1996-2015\0";
+static const CHAR MouseCopyright[] =
+ "ReactOS PS/2 16/32-bit Mouse Driver Compatible MS-MOUSE 6.26\r\n"
+ "Version "KERNEL_VERSION_STR" (Build
"KERNEL_VERSION_BUILD_STR")\r\n"
+ "Copyright (C) ReactOS Team 1996-"COPYRIGHT_YEAR"\0";
#pragma pack(push, 1)
@@ -58,7 +65,79 @@
static DWORD OldIrqHandler;
static DWORD OldIntHandler;
+static WORD DefaultGfxScreenMask[16] =
+{
+ 0xC3FF, // 1100001111111111
+ 0xC0FF, // 1100000011111111
+ 0xC07F, // 1100000001111111
+ 0xC01F, // 1100000000011111
+ 0xC00F, // 1100000000001111
+ 0xC007, // 1100000000000111
+ 0xC003, // 1100000000000011
+ 0xC007, // 1100000000000111
+ 0xC01F, // 1100000000011111
+ 0xC01F, // 1100000000011111
+ 0xC00F, // 1100000000001111
+ 0xC60F, // 1100011000001111
+ 0xFF07, // 1111111100000111
+ 0xFF07, // 1111111100000111
+ 0xFF87, // 1111111110000111
+ 0xFFCF, // 1111111111001111
+};
+
+static WORD DefaultGfxCursorMask[16] =
+{
+ 0x0000, // 0000000000000000
+ 0x1C00, // 0001110000000000
+ 0x1F00, // 0001111100000000
+ 0x1F80, // 0001111110000000
+ 0x1FE0, // 0001111111100000
+ 0x1FF0, // 0001111111110000
+ 0x1FF8, // 0001111111111000
+ 0x1FE0, // 0001111111100000
+ 0x1FC0, // 0001111111000000
+ 0x1FC0, // 0001111111000000
+ 0x19E0, // 0001100111100000
+ 0x00E0, // 0000000011100000
+ 0x0070, // 0000000001110000
+ 0x0070, // 0000000001110000
+ 0x0030, // 0000000000110000
+ 0x0000, // 0000000000000000
+};
+
/* PRIVATE FUNCTIONS **********************************************************/
+
+/* static */
+VOID BiosPs2Service(UCHAR Function)
+{
+ /* Save AX and BX */
+ USHORT AX = getAX();
+ // USHORT BX = getBX();
+
+ /*
+ * Set the parameters:
+ * AL contains the character to print (already set),
+ * BL contains the character attribute,
+ * BH contains the video page to use.
+ */
+ // setBL(DOS_CHAR_ATTRIBUTE);
+ // setBH(Bda->VideoPage);
+ setAL(Function);
+
+ /* Call the BIOS INT 15h, AH=C2h "Pointing Device BIOS Interface (PS)" */
+ setAH(0xC2);
+ Int32Call(&MouseContext, BIOS_MISC_INTERRUPT);
+
+ /* Restore AX and BX */
+ // setBX(BX);
+ setAX(AX);
+}
+
+
+
+static VOID DosMouseEnable(VOID);
+static VOID DosMouseDisable(VOID);
+
static VOID PaintMouseCursor(VOID)
{
@@ -273,7 +352,7 @@
CallMouseUserHandlers(0x0001); // We use MS MOUSE v1.0+ format
}
-static inline VOID DosUpdateButtons(BYTE ButtonState)
+static inline VOID DosUpdateButtons(BYTE ButtonState) // WORD ButtonState
{
USHORT i;
USHORT CallMask = 0x0000; // We use MS MOUSE v1.0+ format
@@ -316,9 +395,9 @@
/* Read the whole packet at once */
Flags = IOReadB(PS2_DATA_PORT);
- PS2PortQueueRead(1);
+ PS2PortQueueRead(1); // NOTE: Should be a IOReadB! But see r67231
DeltaX = IOReadB(PS2_DATA_PORT);
- PS2PortQueueRead(1);
+ PS2PortQueueRead(1); // NOTE: Should be a IOReadB! But see r67231
DeltaY = IOReadB(PS2_DATA_PORT);
/* Adjust the sign */
@@ -369,39 +448,13 @@
DriverState.GraphicsCursor.HotSpot.X = 3;
DriverState.GraphicsCursor.HotSpot.Y = 1;
- DriverState.GraphicsCursor.ScreenMask[0] = 0xC3FF; // 1100001111111111
- DriverState.GraphicsCursor.ScreenMask[1] = 0xC0FF; // 1100000011111111
- DriverState.GraphicsCursor.ScreenMask[2] = 0xC07F; // 1100000001111111
- DriverState.GraphicsCursor.ScreenMask[3] = 0xC01F; // 1100000000011111
- DriverState.GraphicsCursor.ScreenMask[4] = 0xC00F; // 1100000000001111
- DriverState.GraphicsCursor.ScreenMask[5] = 0xC007; // 1100000000000111
- DriverState.GraphicsCursor.ScreenMask[6] = 0xC003; // 1100000000000011
- DriverState.GraphicsCursor.ScreenMask[7] = 0xC007; // 1100000000000111
- DriverState.GraphicsCursor.ScreenMask[8] = 0xC01F; // 1100000000011111
- DriverState.GraphicsCursor.ScreenMask[9] = 0xC01F; // 1100000000011111
- DriverState.GraphicsCursor.ScreenMask[10] = 0xC00F; // 1100000000001111
- DriverState.GraphicsCursor.ScreenMask[11] = 0xC60F; // 1100011000001111
- DriverState.GraphicsCursor.ScreenMask[12] = 0xFF07; // 1111111100000111
- DriverState.GraphicsCursor.ScreenMask[13] = 0xFF07; // 1111111100000111
- DriverState.GraphicsCursor.ScreenMask[14] = 0xFF87; // 1111111110000111
- DriverState.GraphicsCursor.ScreenMask[15] = 0xFFCF; // 1111111111001111
-
- DriverState.GraphicsCursor.CursorMask[0] = 0x0000; // 0000000000000000
- DriverState.GraphicsCursor.CursorMask[1] = 0x1C00; // 0001110000000000
- DriverState.GraphicsCursor.CursorMask[2] = 0x1F00; // 0001111100000000
- DriverState.GraphicsCursor.CursorMask[3] = 0x1F80; // 0001111110000000
- DriverState.GraphicsCursor.CursorMask[4] = 0x1FE0; // 0001111111100000
- DriverState.GraphicsCursor.CursorMask[5] = 0x1FF0; // 0001111111110000
- DriverState.GraphicsCursor.CursorMask[6] = 0x1FF8; // 0001111111111000
- DriverState.GraphicsCursor.CursorMask[7] = 0x1FE0; // 0001111111100000
- DriverState.GraphicsCursor.CursorMask[8] = 0x1FC0; // 0001111111000000
- DriverState.GraphicsCursor.CursorMask[9] = 0x1FC0; // 0001111111000000
- DriverState.GraphicsCursor.CursorMask[10] = 0x19E0; // 0001100111100000
- DriverState.GraphicsCursor.CursorMask[11] = 0x00E0; // 0000000011100000
- DriverState.GraphicsCursor.CursorMask[12] = 0x0070; // 0000000001110000
- DriverState.GraphicsCursor.CursorMask[13] = 0x0070; // 0000000001110000
- DriverState.GraphicsCursor.CursorMask[14] = 0x0030; // 0000000000110000
- DriverState.GraphicsCursor.CursorMask[15] = 0x0000; // 0000000000000000
+ RtlCopyMemory(DriverState.GraphicsCursor.ScreenMask,
+ DefaultGfxScreenMask,
+ sizeof(DriverState.GraphicsCursor.ScreenMask));
+
+ RtlCopyMemory(DriverState.GraphicsCursor.CursorMask,
+ DefaultGfxCursorMask,
+ sizeof(DriverState.GraphicsCursor.CursorMask));
/* Initialize the counters */
DriverState.HorizCount = DriverState.VertCount = 0;
@@ -436,7 +489,7 @@
break;
}
- /* Return Position And Button Status */
+ /* Return Position and Button Status */
case 0x03:
{
COORD Position = DriverState.Position;
@@ -610,6 +663,13 @@
break;
}
+ /* Set Exclusion Area */
+ //
http://www.ctyme.com/intr/rb-5972.htm
+ //
http://www.techhelpmanual.com/849-int_33h_0010h__set_exclusion_area.html
+ //case 0x10:
+ //{
+ //}
+
/* Define Double-Speed Threshold */
case 0x13:
{
@@ -625,12 +685,18 @@
DriverState.Handler0.CallMask = getCX();
DriverState.Handler0.Callback = MAKELONG(getDX(), getES()); // Far pointer to
the callback
+ DPRINT1("Exchange old callback 0x%04X, %04X:%04X with new callback
0x%04X, %04X:%04X\n",
+ OldCallMask,
+ HIWORD(OldCallback),
+ LOWORD(OldCallback),
+ DriverState.Handler0.CallMask,
+ HIWORD(DriverState.Handler0.Callback),
+ LOWORD(DriverState.Handler0.Callback));
/* Return old callmask in CX and callback vector in ES:DX */
setCX(OldCallMask);
setES(HIWORD(OldCallback));
setDX(LOWORD(OldCallback));
-
break;
}
@@ -644,6 +710,9 @@
/* Save Driver State */
case 0x16:
{
+ /* Check whether the user buffer has correct size and fail if not */
+ if (getBX() != sizeof(MOUSE_DRIVER_STATE)) break;
+
*((PMOUSE_DRIVER_STATE)SEG_OFF_TO_PTR(getES(), getDX())) = DriverState;
break;
}
@@ -651,6 +720,9 @@
/* Restore Driver State */
case 0x17:
{
+ /* Check whether the user buffer has correct size and fail if not */
+ if (getBX() != sizeof(MOUSE_DRIVER_STATE)) break;
+
DriverState = *((PMOUSE_DRIVER_STATE)SEG_OFF_TO_PTR(getES(), getDX()));
break;
}
@@ -803,6 +875,15 @@
case 0x1A:
{
DPRINT1("INT 33h, AH=1Ah: Mouse sensitivity is UNSUPPORTED\n");
+
+ // FIXME: Do that at runtime!
+
+ // UCHAR BH = getBH();
+ // setBH(0x00);
+ // BiosPs2Service(0x00);
+ // FIXME: Check for return status in AH and CF
+ // setBH(BH);
+
break;
}
@@ -815,6 +896,15 @@
setBX(50); // Horizontal speed
setCX(50); // Vertical speed
setDX(50); // Double speed threshold
+
+ // FIXME: Get that at runtime!
+
+ // UCHAR BH = getBH();
+ // setBH(0x00);
+ // BiosPs2Service(0x00);
+ // FIXME: Check for return status in AH and CF
+ // setBH(BH);
+
break;
}
@@ -826,6 +916,11 @@
setBX(LOWORD(OldIntHandler));
DosMouseDisable();
+ // UCHAR BH = getBH();
+ // setBH(0x00);
+ // BiosPs2Service(0x00);
+ // FIXME: Check for return status in AH and CF
+ // setBH(BH);
break;
}
@@ -833,6 +928,11 @@
case 0x20:
{
DosMouseEnable();
+ // UCHAR BH = getBH();
+ // setBH(0x01);
+ // BiosPs2Service(0x00);
+ // FIXME: Check for return status in AH and CF
+ // setBH(BH);
break;
}
@@ -876,12 +976,70 @@
{
setBX(MOUSE_VERSION); // Version Number
+ /*
+ * See Ralf Brown:
http://www.ctyme.com/intr/rb-5993.htm
+ * for the list of possible values.
+ */
// FIXME: To be determined at runtime!
setCH(0x04); // PS/2 Type
setCL(0x00); // PS/2 Interrupt
break;
}
+
+ // BIOS Function INT 33h, AX = 0x0025 NOT IMPLEMENTED
+ case 0x25:
+ {
+ setAX(0);
+ setBX(0);
+ setCX(0);
+ setDX(0);
+ UNIMPLEMENTED;
+ break;
+ }
+
+ /* Get Maximum Virtual Coordinates */
+ case 0x26:
+ {
+ setBX(!DriverEnabled);
+ // FIXME: In fact the MaxX and MaxY here are
+ // theoretical values for the current video mode.
+ // They therefore can be different from the current
+ // min/max values.
+ // See
http://www.ctyme.com/intr/rb-5995.htm
+ // for more details.
+ setCX(DriverState.MaxX);
+ setDX(DriverState.MaxY);
+ break;
+ }
+
+ /* Get Current Minimum/Maximum Virtual Coordinates */
+ case 0x31:
+ {
+ setAX(DriverState.MinX);
+ setBX(DriverState.MinY);
+ setCX(DriverState.MaxX);
+ setDX(DriverState.MaxY);
+ break;
+ }
+
+#if 0
+ case 0x33:
+ {
+ /*
+ * Related to
http://www.ctyme.com/intr/rb-5985.htm
+ * INT 33h, AX=001Ch "SET INTERRUPT RATE":
+
+ * Values for mouse interrupt rate:
+ * BX = rate
+ 00h no interrupts allowed
+ 01h 30 per second
+ 02h 50 per second
+ 03h 100 per second
+ 04h 200 per second
+ */
+ }
+#endif
/* Return Pointer to Copyright String */
case 0x4D:
@@ -914,6 +1072,7 @@
/* PUBLIC FUNCTIONS ***********************************************************/
+static
VOID DosMouseEnable(VOID)
{
if (DriverEnabled) return;
@@ -928,6 +1087,7 @@
MOUSE_IRQ_INT, DosMouseIrq, NULL);
}
+static
VOID DosMouseDisable(VOID)
{
if (!DriverEnabled) return;
@@ -936,61 +1096,6 @@
((PDWORD)BaseAddress)[MOUSE_IRQ_INT] = OldIrqHandler;
DriverEnabled = FALSE;
-}
-
-VOID DosMouseUpdatePosition(PCOORD NewPosition)
-{
- SHORT DeltaX = NewPosition->X - DriverState.Position.X;
- SHORT DeltaY = NewPosition->Y - DriverState.Position.Y;
-
- if (!DriverEnabled) return;
-
- DriverState.HorizCount += (DeltaX * MICKEYS_PER_CELL_HORIZ) / 8;
- DriverState.VertCount += (DeltaY * MICKEYS_PER_CELL_VERT) / 8;
-
- if (DriverState.ShowCount > 0) EraseMouseCursor();
- DriverState.Position = *NewPosition;
- if (DriverState.ShowCount > 0) PaintMouseCursor();
-
- /* Call the mouse handlers */
- // if (DeltaX || DeltaY)
- CallMouseUserHandlers(0x0001); // We use MS MOUSE v1.0+ format
-}
-
-VOID DosMouseUpdateButtons(WORD ButtonState)
-{
- USHORT i;
- USHORT CallMask = 0x0000; // We use MS MOUSE v1.0+ format
-
- if (!DriverEnabled) return;
-
- for (i = 0; i < NUM_MOUSE_BUTTONS; i++)
- {
- BOOLEAN OldState = (DriverState.ButtonState >> i) & 1;
- BOOLEAN NewState = (ButtonState >> i) & 1;
-
- if (NewState > OldState)
- {
- /* Mouse press */
- DriverState.PressCount[i]++;
- DriverState.LastPress[i] = DriverState.Position;
-
- CallMask |= (1 << (2 * i + 1));
- }
- else if (NewState < OldState)
- {
- /* Mouse release */
- DriverState.ReleaseCount[i]++;
- DriverState.LastRelease[i] = DriverState.Position;
-
- CallMask |= (1 << (2 * i + 2));
- }
- }
-
- DriverState.ButtonState = ButtonState;
-
- /* Call the mouse handlers */
- CallMouseUserHandlers(CallMask);
}
BOOLEAN DosMouseInitialize(VOID)
@@ -1020,6 +1125,12 @@
DOS_MOUSE_INTERRUPT, DosMouseService, NULL);
DosMouseEnable();
+ // UCHAR BH = getBH();
+ // setBH(0x01);
+ // BiosPs2Service(0x00);
+ // FIXME: Check for return status in AH and CF
+ // setBH(BH);
+
return TRUE;
}
@@ -1027,6 +1138,11 @@
{
if (DriverState.ShowCount > 0) EraseMouseCursor();
DosMouseDisable();
+ // UCHAR BH = getBH();
+ // setBH(0x00);
+ // BiosPs2Service(0x00);
+ // FIXME: Check for return status in AH and CF
+ // setBH(BH);
/* Restore the old mouse service interrupt handler */
((PDWORD)BaseAddress)[DOS_MOUSE_INTERRUPT] = OldIntHandler;
Modified: trunk/reactos/subsystems/mvdm/ntvdm/dos/mouse32.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/mvdm/ntvdm/dos/…
==============================================================================
--- trunk/reactos/subsystems/mvdm/ntvdm/dos/mouse32.h [iso-8859-1] (original)
+++ trunk/reactos/subsystems/mvdm/ntvdm/dos/mouse32.h [iso-8859-1] Fri Aug 7 16:10:18
2015
@@ -2,7 +2,7 @@
* COPYRIGHT: GPL - See COPYING in the top level directory
* PROJECT: ReactOS Virtual DOS Machine
* FILE: mouse32.h
- * PURPOSE: VDM 32-bit compatible
MOUSE.COM driver
+ * PURPOSE: VDM 32-bit compatible PS/2
MOUSE.COM driver
* PROGRAMMERS: Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
*/
@@ -12,7 +12,7 @@
/* DEFINES ********************************************************************/
//
-// We are ROS PS/2 Mouse Driver Version 6.26, compatible MS-MOUSE 6.26
+// We are ReactOS PS/2 Mouse Driver Version 6.26, compatible MS-MOUSE 6.26
//
#define MOUSE_VERSION MAKEWORD(0x26, 0x06)
@@ -75,8 +75,6 @@
/* FUNCTIONS ******************************************************************/
-VOID DosMouseEnable(VOID);
-VOID DosMouseDisable(VOID);
BOOLEAN DosMouseInitialize(VOID);
VOID DosMouseCleanup(VOID);
Modified: trunk/reactos/subsystems/mvdm/ntvdm/hardware/mouse.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/mvdm/ntvdm/hard…
==============================================================================
--- trunk/reactos/subsystems/mvdm/ntvdm/hardware/mouse.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/mvdm/ntvdm/hardware/mouse.c [iso-8859-1] Fri Aug 7 16:10:18
2015
@@ -2,7 +2,7 @@
* COPYRIGHT: GPL - See COPYING in the top level directory
* PROJECT: ReactOS Virtual DOS Machine
* FILE: mouse.c
- * PURPOSE: Mouse emulation
+ * PURPOSE: PS/2 Mouse emulation
* PROGRAMMERS: Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
*/
@@ -39,11 +39,11 @@
static BYTE DataByteWait = 0;
static BYTE ScrollMagicCounter = 0, ExtraButtonMagicCounter = 0;
+static UINT MouseCycles = 10;
+
static BYTE PS2Port = 1;
/* PUBLIC VARIABLES ***********************************************************/
-
-UINT MouseCycles = 10;
/* PRIVATE FUNCTIONS **********************************************************/
@@ -73,6 +73,8 @@
MouseId = 0;
ScrollMagicCounter = ExtraButtonMagicCounter = 0;
+ PS2QueuePush(PS2Port, MOUSE_ACK);
+
/* Send the Basic Assurance Test success code and the device ID */
PS2QueuePush(PS2Port, MOUSE_BAT_SUCCESS);
PS2QueuePush(PS2Port, MouseId);
@@ -118,7 +120,7 @@
/* Set the button flags */
if (ButtonState & FROM_LEFT_1ST_BUTTON_PRESSED) Packet->Flags |=
MOUSE_LEFT_BUTTON;
if (ButtonState & FROM_LEFT_2ND_BUTTON_PRESSED) Packet->Flags |=
MOUSE_MIDDLE_BUTTON;
- if (ButtonState & RIGHTMOST_BUTTON_PRESSED) Packet->Flags |=
MOUSE_RIGHT_BUTTON;
+ if (ButtonState & RIGHTMOST_BUTTON_PRESSED) Packet->Flags |=
MOUSE_RIGHT_BUTTON;
if (MouseId == 4)
{
@@ -250,8 +252,8 @@
/* Set Sample Rate */
case 0xF3:
{
- PS2QueuePush(PS2Port, MOUSE_ACK);
DataByteWait = Command;
+ PS2QueuePush(PS2Port, MOUSE_ACK);
break;
}
@@ -259,12 +261,12 @@
case 0xE9:
{
BYTE Status = ButtonState & 7;
- PS2QueuePush(PS2Port, MOUSE_ACK);
if (Scaling) Status |= 1 << 4;
if (Reporting) Status |= 1 << 5;
if (Mode == MOUSE_REMOTE_MODE) Status |= 1 << 6;
+ PS2QueuePush(PS2Port, MOUSE_ACK);
PS2QueuePush(PS2Port, Status);
PS2QueuePush(PS2Port, Resolution);
PS2QueuePush(PS2Port, (BYTE)(1000 / MouseCycles));
@@ -290,7 +292,7 @@
break;
}
- /* Return From Wrap Mode */
+ /* Return from Wrap Mode */
case 0xEC:
{
if (Mode == MOUSE_WRAP_MODE)
@@ -300,7 +302,10 @@
Mode = PreviousMode;
PS2QueuePush(PS2Port, MOUSE_ACK);
}
- else PS2QueuePush(PS2Port, MOUSE_ERROR);
+ else
+ {
+ PS2QueuePush(PS2Port, MOUSE_ERROR);
+ }
break;
}
Modified: trunk/reactos/subsystems/mvdm/ntvdm/hardware/ps2.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/mvdm/ntvdm/hard…
==============================================================================
--- trunk/reactos/subsystems/mvdm/ntvdm/hardware/ps2.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/mvdm/ntvdm/hardware/ps2.c [iso-8859-1] Fri Aug 7 16:10:18
2015
@@ -45,8 +45,7 @@
#define PS2_PORTS 2
static PS2_PORT Ports[PS2_PORTS];
-#define PS2_DEFAULT_CONFIG 0x45
-static BYTE ControllerConfig = PS2_DEFAULT_CONFIG;
+static BYTE ControllerConfig = 0x00;
static BYTE ControllerCommand = 0x00;
static BYTE StatusRegister = 0x00;
@@ -69,8 +68,16 @@
{
if (Port == PS2_CONTROL_PORT)
{
- /* Be sure bit 2 is always set */
- StatusRegister |= 1 << 2;
+ /*
+ * Be sure bit 4 "Keyboard enable flag" is always set.
+ * Keyboard enable (or keyboard lock) flag values are:
+ * 0: Locked; 1: Not locked.
+ * On IBM PC-ATs this is the state of the hardware keyboard
+ * lock mechanism. It is not widely used, but some programs
+ * still use it: see for example:
+ *
http://www.os2museum.com/wp/the-dos-4-0-shell-mouse-mystery/
+ */
+ StatusRegister |= (1 << 4);
// FIXME: Should clear bits 6 and 7 because there are
// no timeouts and no parity errors.
@@ -220,6 +227,31 @@
case 0x60:
{
ControllerConfig = Data;
+
+ /*
+ * Update bit 2 "System flag" of the status register
+ * with bit 2 of the controller configuration byte.
+ * See:
http://www.win.tue.nl/~aeb/linux/kbd/scancodes-11.html#kccb2
+ * for more details.
+ */
+ if (ControllerConfig & (1 << 2))
+ StatusRegister |= (1 << 2);
+ else
+ StatusRegister &= ~(1 << 2);
+
+ /*
+ * Update bit 4 "Keyboard enable flag" of the status
register
+ * with bit 3 "Ignore keyboard lock" of the controller
+ * configuration byte (if set), then reset the latter one.
+ * See:
http://www.win.tue.nl/~aeb/linux/kbd/scancodes-11.html#kccb3
+ * for more details.
+ */
+ if (ControllerConfig & (1 << 3))
+ {
+ StatusRegister |= (1 << 4);
+ ControllerConfig &= ~(1 << 3);
+ }
+
break;
}
@@ -399,13 +431,13 @@
BOOLEAN PS2Initialize(VOID)
{
/* Initialize the PS/2 ports */
- Ports[0].IsEnabled = TRUE;
+ Ports[0].IsEnabled = FALSE;
Ports[0].QueueEmpty = TRUE;
Ports[0].QueueStart = 0;
Ports[0].QueueEnd = 0;
Ports[0].QueueMutex = CreateMutex(NULL, FALSE, NULL);
- Ports[1].IsEnabled = TRUE;
+ Ports[1].IsEnabled = FALSE;
Ports[1].QueueEmpty = TRUE;
Ports[1].QueueStart = 0;
Ports[1].QueueEnd = 0;