mirror of
https://github.com/reactos/reactos.git
synced 2024-08-01 09:01:13 +00:00
[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. svn path=/trunk/; revision=68613
This commit is contained in:
parent
33d53d44da
commit
f6fbd83783
|
@ -142,7 +142,7 @@ C_ASSERT(sizeof(USER_DATA_AREA) == 0x34);
|
||||||
*/
|
*/
|
||||||
typedef struct _BIOS_CONFIG_TABLE
|
typedef struct _BIOS_CONFIG_TABLE
|
||||||
{
|
{
|
||||||
WORD Length; // 0x00
|
WORD Length; // 0x00 - Number of bytes following
|
||||||
BYTE Model; // 0x02
|
BYTE Model; // 0x02
|
||||||
BYTE SubModel; // 0x03
|
BYTE SubModel; // 0x03
|
||||||
BYTE Revision; // 0x04
|
BYTE Revision; // 0x04
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
* FILE: bios32.c
|
* FILE: bios32.c
|
||||||
* PURPOSE: VDM 32-bit BIOS
|
* PURPOSE: VDM 32-bit BIOS
|
||||||
* PROGRAMMERS: Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
|
* PROGRAMMERS: Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
|
||||||
|
* Hermes Belusca-Maito (hermes.belusca@sfr.fr)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* INCLUDES *******************************************************************/
|
/* INCLUDES *******************************************************************/
|
||||||
|
@ -109,7 +110,7 @@ $fffe ; System Model ID
|
||||||
|
|
||||||
static const BIOS_CONFIG_TABLE BiosConfigTable =
|
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_MODEL, // BIOS Model
|
||||||
BIOS_SUBMODEL, // BIOS Sub-Model
|
BIOS_SUBMODEL, // BIOS Sub-Model
|
||||||
|
@ -325,7 +326,6 @@ static VOID WINAPI BiosMiscService(LPWORD Stack)
|
||||||
{
|
{
|
||||||
setAX(0x80);
|
setAX(0x80);
|
||||||
Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
|
Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -394,8 +394,11 @@ static VOID WINAPI BiosMiscService(LPWORD Stack)
|
||||||
/* Pointing Device BIOS Interface (PS) */
|
/* Pointing Device BIOS Interface (PS) */
|
||||||
case 0xC2:
|
case 0xC2:
|
||||||
{
|
{
|
||||||
BiosMousePs2Interface(Stack);
|
// FIXME: Reenable this call when we understand why
|
||||||
UNIMPLEMENTED; // Remove it when BiosMousePs2Interface is implemented!
|
// our included mouse driver doesn't correctly reeanble
|
||||||
|
// mouse reporting!
|
||||||
|
// BiosMousePs2Interface(Stack);
|
||||||
|
// break;
|
||||||
goto Default;
|
goto Default;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -429,7 +432,7 @@ static VOID WINAPI BiosMiscService(LPWORD Stack)
|
||||||
ULONG Above1M = (min(MAX_ADDRESS, 0x01000000) - 0x00100000) >> 10;
|
ULONG Above1M = (min(MAX_ADDRESS, 0x01000000) - 0x00100000) >> 10;
|
||||||
|
|
||||||
/* The amount of memory above 16M, in 64K blocks */
|
/* 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);
|
setAX(Above1M);
|
||||||
setBX(Above16M);
|
setBX(Above16M);
|
||||||
|
@ -476,8 +479,7 @@ static VOID WINAPI BiosMiscService(LPWORD Stack)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DPRINT1("BIOS Function INT 15h, AH = 0xE8 - unexpected AL = %02X, EDX = %08X\n",
|
DPRINT1("BIOS Function INT 15h, AH = 0xE8 - unexpected AL = %02X, EDX = %08X\n",
|
||||||
getAL(),
|
getAL(), getEDX());
|
||||||
getEDX());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
@ -773,6 +775,16 @@ static VOID BiosHwSetup(VOID)
|
||||||
IOWriteB(PIT_DATA_PORT(2), 0x97);
|
IOWriteB(PIT_DATA_PORT(2), 0x97);
|
||||||
IOWriteB(PIT_DATA_PORT(2), 0x0A);
|
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);
|
EnableHwIRQ(0, BiosTimerIrq);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -785,7 +797,10 @@ static VOID InitializeBiosInt32(VOID)
|
||||||
|
|
||||||
/* Register the default BIOS interrupt vectors */
|
/* 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));
|
RtlZeroMemory(BaseAddress, 0x0100 * sizeof(ULONG));
|
||||||
|
|
||||||
#if defined(ADVANCED_DEBUGGING) && (ADVANCED_DEBUGGING_LEVEL >= 3)
|
#if defined(ADVANCED_DEBUGGING) && (ADVANCED_DEBUGGING_LEVEL >= 3)
|
||||||
|
|
|
@ -2,8 +2,11 @@
|
||||||
* COPYRIGHT: GPL - See COPYING in the top level directory
|
* COPYRIGHT: GPL - See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS Virtual DOS Machine
|
* PROJECT: ReactOS Virtual DOS Machine
|
||||||
* FILE: moubios32.c
|
* 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>
|
* PROGRAMMERS: Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
|
||||||
|
* Hermes Belusca-Maito (hermes.belusca@sfr.fr)
|
||||||
|
*
|
||||||
|
* NOTE: Based from VirtualBox OSE ROM BIOS, and SeaBIOS.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* INCLUDES *******************************************************************/
|
/* INCLUDES *******************************************************************/
|
||||||
|
@ -12,118 +15,512 @@
|
||||||
|
|
||||||
#include "ntvdm.h"
|
#include "ntvdm.h"
|
||||||
#include "emulator.h"
|
#include "emulator.h"
|
||||||
|
#include "cpu/cpu.h" // for EMULATOR_FLAG_CF
|
||||||
|
|
||||||
#include "moubios32.h"
|
#include "moubios32.h"
|
||||||
#include "bios32p.h"
|
#include "bios32p.h"
|
||||||
|
|
||||||
#include "io.h"
|
#include "io.h"
|
||||||
|
#include "hardware/mouse.h"
|
||||||
#include "hardware/ps2.h"
|
#include "hardware/ps2.h"
|
||||||
|
|
||||||
/* PRIVATE VARIABLES **********************************************************/
|
/* 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 **********************************************************/
|
/* 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
|
// Mouse IRQ 12
|
||||||
static VOID WINAPI BiosMouseIrq(LPWORD Stack)
|
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]));
|
PicIRQComplete(LOBYTE(Stack[STACK_INT_NUM]));
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID BiosMousePs2Interface(LPWORD Stack)
|
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())
|
switch (getAL())
|
||||||
{
|
{
|
||||||
/* Enable / Disable */
|
/* Enable / Disable */
|
||||||
case 0x00:
|
case 0x00:
|
||||||
{
|
{
|
||||||
break;
|
UCHAR State = getBH();
|
||||||
}
|
|
||||||
|
|
||||||
/* Reset */
|
if (State > 2)
|
||||||
case 0x01:
|
{
|
||||||
{
|
/* Invalid function */
|
||||||
break;
|
setAH(0x01);
|
||||||
}
|
Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
/* Set Sampling Rate */
|
if (State == 0x00)
|
||||||
case 0x02:
|
{
|
||||||
{
|
BiosMouseDisable();
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Set Resolution */
|
/* Disable packet reporting */
|
||||||
case 0x03:
|
SendMouseCommand(0xF5);
|
||||||
{
|
}
|
||||||
break;
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
/* Get Type */
|
BiosMouseEnable();
|
||||||
case 0x04:
|
|
||||||
{
|
/* 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;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Initialize */
|
/* Initialize */
|
||||||
case 0x05:
|
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;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Extended Commands */
|
/* 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:
|
||||||
|
{
|
||||||
|
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:
|
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;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set Device Handler Address */
|
/* Set Device Handler Address */
|
||||||
case 0x07:
|
case 0x07:
|
||||||
{
|
{
|
||||||
|
/* ES:BX == 0000h:0000h removes the device handler */
|
||||||
|
DeviceHandler = MAKELONG(getBX(), getES());
|
||||||
|
|
||||||
|
/* Success */
|
||||||
|
setAH(0x00);
|
||||||
|
Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Write to Pointer Port */
|
/* Write to Pointer Port */
|
||||||
case 0x08:
|
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;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read from Pointer Port */
|
/* Read from Pointer Port */
|
||||||
case 0x09:
|
case 0x09:
|
||||||
{
|
{
|
||||||
|
setBL(ReadMouseData());
|
||||||
|
setCL(ReadMouseData());
|
||||||
|
setDL(ReadMouseData());
|
||||||
|
|
||||||
|
/* Success */
|
||||||
|
setAH(0x00);
|
||||||
|
Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
DPRINT1("INT 15h, AH = C2h, AL = 0x%02X NOT IMPLEMENTED\n",
|
DPRINT1("INT 15h, AH = C2h, AL = %02Xh NOT IMPLEMENTED\n",
|
||||||
getAL());
|
getAL());
|
||||||
|
|
||||||
|
/* Unknown function */
|
||||||
|
setAH(0x01);
|
||||||
|
Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Reenable mouse interrupt and events */
|
||||||
|
EnableMouseInt();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* PUBLIC FUNCTIONS ***********************************************************/
|
/* PUBLIC FUNCTIONS ***********************************************************/
|
||||||
|
|
||||||
VOID MouseBios32Post(VOID)
|
VOID MouseBios32Post(VOID)
|
||||||
{
|
{
|
||||||
BYTE ControllerConfig;
|
UCHAR Answer;
|
||||||
|
|
||||||
/* Clear the mouse queue */
|
/* Initialize PS/2 mouse port */
|
||||||
while (PS2PortQueueRead(1)) continue;
|
// Enable the port
|
||||||
|
IOWriteB(PS2_CONTROL_PORT, 0xA8);
|
||||||
|
|
||||||
/* Enable packet reporting */
|
/* Detect mouse presence by attempting a reset */
|
||||||
IOWriteB(PS2_CONTROL_PORT, 0xD4);
|
SendMouseCommand(0xFF);
|
||||||
IOWriteB(PS2_DATA_PORT, 0xF4);
|
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 */
|
||||||
|
|
||||||
/* Read the mouse ACK reply */
|
// FIXME: The following is temporary until
|
||||||
PS2PortQueueRead(1);
|
// this is moved into the mouse driver!!
|
||||||
|
|
||||||
/* Enable IRQ12 */
|
/* Enable packet reporting */
|
||||||
IOWriteB(PS2_CONTROL_PORT, 0x20);
|
SendMouseCommand(0xF4);
|
||||||
ControllerConfig = IOReadB(PS2_DATA_PORT);
|
if (ReadMouseData() != MOUSE_ACK)
|
||||||
IOWriteB(PS2_CONTROL_PORT, 0x60);
|
{
|
||||||
IOWriteB(PS2_DATA_PORT, ControllerConfig | 0x02);
|
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 */
|
/* Set up the HW vector interrupts */
|
||||||
EnableHwIRQ(12, BiosMouseIrq);
|
EnableHwIRQ(12, BiosMouseIrq);
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
* COPYRIGHT: GPL - See COPYING in the top level directory
|
* COPYRIGHT: GPL - See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS Virtual DOS Machine
|
* PROJECT: ReactOS Virtual DOS Machine
|
||||||
* FILE: mouse32.c
|
* 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>
|
* PROGRAMMERS: Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -10,6 +10,10 @@
|
||||||
|
|
||||||
#define NDEBUG
|
#define NDEBUG
|
||||||
|
|
||||||
|
/* Driver Version number and Copyright */
|
||||||
|
#include <reactos/buildno.h>
|
||||||
|
#include <reactos/version.h>
|
||||||
|
|
||||||
#include "ntvdm.h"
|
#include "ntvdm.h"
|
||||||
#include "emulator.h"
|
#include "emulator.h"
|
||||||
|
|
||||||
|
@ -30,7 +34,10 @@
|
||||||
|
|
||||||
/* PRIVATE VARIABLES **********************************************************/
|
/* 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)
|
#pragma pack(push, 1)
|
||||||
|
|
||||||
|
@ -58,8 +65,80 @@ static MOUSE_DRIVER_STATE DriverState;
|
||||||
static DWORD OldIrqHandler;
|
static DWORD OldIrqHandler;
|
||||||
static DWORD OldIntHandler;
|
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 **********************************************************/
|
/* 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)
|
static VOID PaintMouseCursor(VOID)
|
||||||
{
|
{
|
||||||
COORD Position = DriverState.Position;
|
COORD Position = DriverState.Position;
|
||||||
|
@ -273,7 +352,7 @@ static inline VOID DosUpdatePosition(PCOORD NewPosition)
|
||||||
CallMouseUserHandlers(0x0001); // We use MS MOUSE v1.0+ format
|
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 i;
|
||||||
USHORT CallMask = 0x0000; // We use MS MOUSE v1.0+ format
|
USHORT CallMask = 0x0000; // We use MS MOUSE v1.0+ format
|
||||||
|
@ -316,9 +395,9 @@ static VOID WINAPI DosMouseIrq(LPWORD Stack)
|
||||||
|
|
||||||
/* Read the whole packet at once */
|
/* Read the whole packet at once */
|
||||||
Flags = IOReadB(PS2_DATA_PORT);
|
Flags = IOReadB(PS2_DATA_PORT);
|
||||||
PS2PortQueueRead(1);
|
PS2PortQueueRead(1); // NOTE: Should be a IOReadB! But see r67231
|
||||||
DeltaX = IOReadB(PS2_DATA_PORT);
|
DeltaX = IOReadB(PS2_DATA_PORT);
|
||||||
PS2PortQueueRead(1);
|
PS2PortQueueRead(1); // NOTE: Should be a IOReadB! But see r67231
|
||||||
DeltaY = IOReadB(PS2_DATA_PORT);
|
DeltaY = IOReadB(PS2_DATA_PORT);
|
||||||
|
|
||||||
/* Adjust the sign */
|
/* Adjust the sign */
|
||||||
|
@ -369,39 +448,13 @@ static VOID WINAPI DosMouseService(LPWORD Stack)
|
||||||
DriverState.GraphicsCursor.HotSpot.X = 3;
|
DriverState.GraphicsCursor.HotSpot.X = 3;
|
||||||
DriverState.GraphicsCursor.HotSpot.Y = 1;
|
DriverState.GraphicsCursor.HotSpot.Y = 1;
|
||||||
|
|
||||||
DriverState.GraphicsCursor.ScreenMask[0] = 0xC3FF; // 1100001111111111
|
RtlCopyMemory(DriverState.GraphicsCursor.ScreenMask,
|
||||||
DriverState.GraphicsCursor.ScreenMask[1] = 0xC0FF; // 1100000011111111
|
DefaultGfxScreenMask,
|
||||||
DriverState.GraphicsCursor.ScreenMask[2] = 0xC07F; // 1100000001111111
|
sizeof(DriverState.GraphicsCursor.ScreenMask));
|
||||||
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
|
RtlCopyMemory(DriverState.GraphicsCursor.CursorMask,
|
||||||
DriverState.GraphicsCursor.CursorMask[1] = 0x1C00; // 0001110000000000
|
DefaultGfxCursorMask,
|
||||||
DriverState.GraphicsCursor.CursorMask[2] = 0x1F00; // 0001111100000000
|
sizeof(DriverState.GraphicsCursor.CursorMask));
|
||||||
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
|
|
||||||
|
|
||||||
/* Initialize the counters */
|
/* Initialize the counters */
|
||||||
DriverState.HorizCount = DriverState.VertCount = 0;
|
DriverState.HorizCount = DriverState.VertCount = 0;
|
||||||
|
@ -436,7 +489,7 @@ static VOID WINAPI DosMouseService(LPWORD Stack)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return Position And Button Status */
|
/* Return Position and Button Status */
|
||||||
case 0x03:
|
case 0x03:
|
||||||
{
|
{
|
||||||
COORD Position = DriverState.Position;
|
COORD Position = DriverState.Position;
|
||||||
|
@ -610,6 +663,13 @@ static VOID WINAPI DosMouseService(LPWORD Stack)
|
||||||
break;
|
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 */
|
/* Define Double-Speed Threshold */
|
||||||
case 0x13:
|
case 0x13:
|
||||||
{
|
{
|
||||||
|
@ -625,12 +685,18 @@ static VOID WINAPI DosMouseService(LPWORD Stack)
|
||||||
|
|
||||||
DriverState.Handler0.CallMask = getCX();
|
DriverState.Handler0.CallMask = getCX();
|
||||||
DriverState.Handler0.Callback = MAKELONG(getDX(), getES()); // Far pointer to the callback
|
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 */
|
/* Return old callmask in CX and callback vector in ES:DX */
|
||||||
setCX(OldCallMask);
|
setCX(OldCallMask);
|
||||||
setES(HIWORD(OldCallback));
|
setES(HIWORD(OldCallback));
|
||||||
setDX(LOWORD(OldCallback));
|
setDX(LOWORD(OldCallback));
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -644,6 +710,9 @@ static VOID WINAPI DosMouseService(LPWORD Stack)
|
||||||
/* Save Driver State */
|
/* Save Driver State */
|
||||||
case 0x16:
|
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;
|
*((PMOUSE_DRIVER_STATE)SEG_OFF_TO_PTR(getES(), getDX())) = DriverState;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -651,6 +720,9 @@ static VOID WINAPI DosMouseService(LPWORD Stack)
|
||||||
/* Restore Driver State */
|
/* Restore Driver State */
|
||||||
case 0x17:
|
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()));
|
DriverState = *((PMOUSE_DRIVER_STATE)SEG_OFF_TO_PTR(getES(), getDX()));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -803,6 +875,15 @@ static VOID WINAPI DosMouseService(LPWORD Stack)
|
||||||
case 0x1A:
|
case 0x1A:
|
||||||
{
|
{
|
||||||
DPRINT1("INT 33h, AH=1Ah: Mouse sensitivity is UNSUPPORTED\n");
|
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;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -815,6 +896,15 @@ static VOID WINAPI DosMouseService(LPWORD Stack)
|
||||||
setBX(50); // Horizontal speed
|
setBX(50); // Horizontal speed
|
||||||
setCX(50); // Vertical speed
|
setCX(50); // Vertical speed
|
||||||
setDX(50); // Double speed threshold
|
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;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -826,6 +916,11 @@ static VOID WINAPI DosMouseService(LPWORD Stack)
|
||||||
setBX(LOWORD(OldIntHandler));
|
setBX(LOWORD(OldIntHandler));
|
||||||
|
|
||||||
DosMouseDisable();
|
DosMouseDisable();
|
||||||
|
// UCHAR BH = getBH();
|
||||||
|
// setBH(0x00);
|
||||||
|
// BiosPs2Service(0x00);
|
||||||
|
// FIXME: Check for return status in AH and CF
|
||||||
|
// setBH(BH);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -833,6 +928,11 @@ static VOID WINAPI DosMouseService(LPWORD Stack)
|
||||||
case 0x20:
|
case 0x20:
|
||||||
{
|
{
|
||||||
DosMouseEnable();
|
DosMouseEnable();
|
||||||
|
// UCHAR BH = getBH();
|
||||||
|
// setBH(0x01);
|
||||||
|
// BiosPs2Service(0x00);
|
||||||
|
// FIXME: Check for return status in AH and CF
|
||||||
|
// setBH(BH);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -876,6 +976,10 @@ static VOID WINAPI DosMouseService(LPWORD Stack)
|
||||||
{
|
{
|
||||||
setBX(MOUSE_VERSION); // Version Number
|
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!
|
// FIXME: To be determined at runtime!
|
||||||
setCH(0x04); // PS/2 Type
|
setCH(0x04); // PS/2 Type
|
||||||
setCL(0x00); // PS/2 Interrupt
|
setCL(0x00); // PS/2 Interrupt
|
||||||
|
@ -883,6 +987,60 @@ static VOID WINAPI DosMouseService(LPWORD Stack)
|
||||||
break;
|
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 */
|
/* Return Pointer to Copyright String */
|
||||||
case 0x4D:
|
case 0x4D:
|
||||||
{
|
{
|
||||||
|
@ -914,6 +1072,7 @@ static VOID WINAPI DosMouseService(LPWORD Stack)
|
||||||
|
|
||||||
/* PUBLIC FUNCTIONS ***********************************************************/
|
/* PUBLIC FUNCTIONS ***********************************************************/
|
||||||
|
|
||||||
|
static
|
||||||
VOID DosMouseEnable(VOID)
|
VOID DosMouseEnable(VOID)
|
||||||
{
|
{
|
||||||
if (DriverEnabled) return;
|
if (DriverEnabled) return;
|
||||||
|
@ -928,6 +1087,7 @@ VOID DosMouseEnable(VOID)
|
||||||
MOUSE_IRQ_INT, DosMouseIrq, NULL);
|
MOUSE_IRQ_INT, DosMouseIrq, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static
|
||||||
VOID DosMouseDisable(VOID)
|
VOID DosMouseDisable(VOID)
|
||||||
{
|
{
|
||||||
if (!DriverEnabled) return;
|
if (!DriverEnabled) return;
|
||||||
|
@ -938,61 +1098,6 @@ VOID DosMouseDisable(VOID)
|
||||||
DriverEnabled = FALSE;
|
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)
|
BOOLEAN DosMouseInitialize(VOID)
|
||||||
{
|
{
|
||||||
/* Initialize some memory for storing our data that should be available to DOS */
|
/* Initialize some memory for storing our data that should be available to DOS */
|
||||||
|
@ -1020,6 +1125,12 @@ BOOLEAN DosMouseInitialize(VOID)
|
||||||
DOS_MOUSE_INTERRUPT, DosMouseService, NULL);
|
DOS_MOUSE_INTERRUPT, DosMouseService, NULL);
|
||||||
|
|
||||||
DosMouseEnable();
|
DosMouseEnable();
|
||||||
|
// UCHAR BH = getBH();
|
||||||
|
// setBH(0x01);
|
||||||
|
// BiosPs2Service(0x00);
|
||||||
|
// FIXME: Check for return status in AH and CF
|
||||||
|
// setBH(BH);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1027,6 +1138,11 @@ VOID DosMouseCleanup(VOID)
|
||||||
{
|
{
|
||||||
if (DriverState.ShowCount > 0) EraseMouseCursor();
|
if (DriverState.ShowCount > 0) EraseMouseCursor();
|
||||||
DosMouseDisable();
|
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 */
|
/* Restore the old mouse service interrupt handler */
|
||||||
((PDWORD)BaseAddress)[DOS_MOUSE_INTERRUPT] = OldIntHandler;
|
((PDWORD)BaseAddress)[DOS_MOUSE_INTERRUPT] = OldIntHandler;
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
* COPYRIGHT: GPL - See COPYING in the top level directory
|
* COPYRIGHT: GPL - See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS Virtual DOS Machine
|
* PROJECT: ReactOS Virtual DOS Machine
|
||||||
* FILE: mouse32.h
|
* 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>
|
* PROGRAMMERS: Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@
|
||||||
/* DEFINES ********************************************************************/
|
/* 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)
|
#define MOUSE_VERSION MAKEWORD(0x26, 0x06)
|
||||||
|
|
||||||
|
@ -75,8 +75,6 @@ typedef struct _MOUSE_DRIVER_STATE
|
||||||
|
|
||||||
/* FUNCTIONS ******************************************************************/
|
/* FUNCTIONS ******************************************************************/
|
||||||
|
|
||||||
VOID DosMouseEnable(VOID);
|
|
||||||
VOID DosMouseDisable(VOID);
|
|
||||||
BOOLEAN DosMouseInitialize(VOID);
|
BOOLEAN DosMouseInitialize(VOID);
|
||||||
VOID DosMouseCleanup(VOID);
|
VOID DosMouseCleanup(VOID);
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
* COPYRIGHT: GPL - See COPYING in the top level directory
|
* COPYRIGHT: GPL - See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS Virtual DOS Machine
|
* PROJECT: ReactOS Virtual DOS Machine
|
||||||
* FILE: mouse.c
|
* FILE: mouse.c
|
||||||
* PURPOSE: Mouse emulation
|
* PURPOSE: PS/2 Mouse emulation
|
||||||
* PROGRAMMERS: Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
|
* PROGRAMMERS: Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -39,12 +39,12 @@ static BOOLEAN EventsOccurred = FALSE;
|
||||||
static BYTE DataByteWait = 0;
|
static BYTE DataByteWait = 0;
|
||||||
static BYTE ScrollMagicCounter = 0, ExtraButtonMagicCounter = 0;
|
static BYTE ScrollMagicCounter = 0, ExtraButtonMagicCounter = 0;
|
||||||
|
|
||||||
|
static UINT MouseCycles = 10;
|
||||||
|
|
||||||
static BYTE PS2Port = 1;
|
static BYTE PS2Port = 1;
|
||||||
|
|
||||||
/* PUBLIC VARIABLES ***********************************************************/
|
/* PUBLIC VARIABLES ***********************************************************/
|
||||||
|
|
||||||
UINT MouseCycles = 10;
|
|
||||||
|
|
||||||
/* PRIVATE FUNCTIONS **********************************************************/
|
/* PRIVATE FUNCTIONS **********************************************************/
|
||||||
|
|
||||||
static VOID MouseResetConfig(VOID)
|
static VOID MouseResetConfig(VOID)
|
||||||
|
@ -73,6 +73,8 @@ static VOID MouseReset(VOID)
|
||||||
MouseId = 0;
|
MouseId = 0;
|
||||||
ScrollMagicCounter = ExtraButtonMagicCounter = 0;
|
ScrollMagicCounter = ExtraButtonMagicCounter = 0;
|
||||||
|
|
||||||
|
PS2QueuePush(PS2Port, MOUSE_ACK);
|
||||||
|
|
||||||
/* Send the Basic Assurance Test success code and the device ID */
|
/* Send the Basic Assurance Test success code and the device ID */
|
||||||
PS2QueuePush(PS2Port, MOUSE_BAT_SUCCESS);
|
PS2QueuePush(PS2Port, MOUSE_BAT_SUCCESS);
|
||||||
PS2QueuePush(PS2Port, MouseId);
|
PS2QueuePush(PS2Port, MouseId);
|
||||||
|
@ -118,7 +120,7 @@ static VOID MouseGetPacket(PMOUSE_PACKET Packet)
|
||||||
/* Set the button flags */
|
/* Set the button flags */
|
||||||
if (ButtonState & FROM_LEFT_1ST_BUTTON_PRESSED) Packet->Flags |= MOUSE_LEFT_BUTTON;
|
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 & 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)
|
if (MouseId == 4)
|
||||||
{
|
{
|
||||||
|
@ -250,8 +252,8 @@ static VOID WINAPI MouseCommand(LPVOID Param, BYTE Command)
|
||||||
/* Set Sample Rate */
|
/* Set Sample Rate */
|
||||||
case 0xF3:
|
case 0xF3:
|
||||||
{
|
{
|
||||||
PS2QueuePush(PS2Port, MOUSE_ACK);
|
|
||||||
DataByteWait = Command;
|
DataByteWait = Command;
|
||||||
|
PS2QueuePush(PS2Port, MOUSE_ACK);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -259,12 +261,12 @@ static VOID WINAPI MouseCommand(LPVOID Param, BYTE Command)
|
||||||
case 0xE9:
|
case 0xE9:
|
||||||
{
|
{
|
||||||
BYTE Status = ButtonState & 7;
|
BYTE Status = ButtonState & 7;
|
||||||
PS2QueuePush(PS2Port, MOUSE_ACK);
|
|
||||||
|
|
||||||
if (Scaling) Status |= 1 << 4;
|
if (Scaling) Status |= 1 << 4;
|
||||||
if (Reporting) Status |= 1 << 5;
|
if (Reporting) Status |= 1 << 5;
|
||||||
if (Mode == MOUSE_REMOTE_MODE) Status |= 1 << 6;
|
if (Mode == MOUSE_REMOTE_MODE) Status |= 1 << 6;
|
||||||
|
|
||||||
|
PS2QueuePush(PS2Port, MOUSE_ACK);
|
||||||
PS2QueuePush(PS2Port, Status);
|
PS2QueuePush(PS2Port, Status);
|
||||||
PS2QueuePush(PS2Port, Resolution);
|
PS2QueuePush(PS2Port, Resolution);
|
||||||
PS2QueuePush(PS2Port, (BYTE)(1000 / MouseCycles));
|
PS2QueuePush(PS2Port, (BYTE)(1000 / MouseCycles));
|
||||||
|
@ -290,7 +292,7 @@ static VOID WINAPI MouseCommand(LPVOID Param, BYTE Command)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return From Wrap Mode */
|
/* Return from Wrap Mode */
|
||||||
case 0xEC:
|
case 0xEC:
|
||||||
{
|
{
|
||||||
if (Mode == MOUSE_WRAP_MODE)
|
if (Mode == MOUSE_WRAP_MODE)
|
||||||
|
@ -300,7 +302,10 @@ static VOID WINAPI MouseCommand(LPVOID Param, BYTE Command)
|
||||||
Mode = PreviousMode;
|
Mode = PreviousMode;
|
||||||
PS2QueuePush(PS2Port, MOUSE_ACK);
|
PS2QueuePush(PS2Port, MOUSE_ACK);
|
||||||
}
|
}
|
||||||
else PS2QueuePush(PS2Port, MOUSE_ERROR);
|
else
|
||||||
|
{
|
||||||
|
PS2QueuePush(PS2Port, MOUSE_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,8 +45,7 @@ typedef struct _PS2_PORT
|
||||||
#define PS2_PORTS 2
|
#define PS2_PORTS 2
|
||||||
static PS2_PORT Ports[PS2_PORTS];
|
static PS2_PORT Ports[PS2_PORTS];
|
||||||
|
|
||||||
#define PS2_DEFAULT_CONFIG 0x45
|
static BYTE ControllerConfig = 0x00;
|
||||||
static BYTE ControllerConfig = PS2_DEFAULT_CONFIG;
|
|
||||||
static BYTE ControllerCommand = 0x00;
|
static BYTE ControllerCommand = 0x00;
|
||||||
|
|
||||||
static BYTE StatusRegister = 0x00;
|
static BYTE StatusRegister = 0x00;
|
||||||
|
@ -69,8 +68,16 @@ static BYTE WINAPI PS2ReadPort(USHORT Port)
|
||||||
{
|
{
|
||||||
if (Port == PS2_CONTROL_PORT)
|
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
|
// FIXME: Should clear bits 6 and 7 because there are
|
||||||
// no timeouts and no parity errors.
|
// no timeouts and no parity errors.
|
||||||
|
@ -220,6 +227,31 @@ static VOID WINAPI PS2WritePort(USHORT Port, BYTE Data)
|
||||||
case 0x60:
|
case 0x60:
|
||||||
{
|
{
|
||||||
ControllerConfig = Data;
|
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;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -399,13 +431,13 @@ Done:
|
||||||
BOOLEAN PS2Initialize(VOID)
|
BOOLEAN PS2Initialize(VOID)
|
||||||
{
|
{
|
||||||
/* Initialize the PS/2 ports */
|
/* Initialize the PS/2 ports */
|
||||||
Ports[0].IsEnabled = TRUE;
|
Ports[0].IsEnabled = FALSE;
|
||||||
Ports[0].QueueEmpty = TRUE;
|
Ports[0].QueueEmpty = TRUE;
|
||||||
Ports[0].QueueStart = 0;
|
Ports[0].QueueStart = 0;
|
||||||
Ports[0].QueueEnd = 0;
|
Ports[0].QueueEnd = 0;
|
||||||
Ports[0].QueueMutex = CreateMutex(NULL, FALSE, NULL);
|
Ports[0].QueueMutex = CreateMutex(NULL, FALSE, NULL);
|
||||||
|
|
||||||
Ports[1].IsEnabled = TRUE;
|
Ports[1].IsEnabled = FALSE;
|
||||||
Ports[1].QueueEmpty = TRUE;
|
Ports[1].QueueEmpty = TRUE;
|
||||||
Ports[1].QueueStart = 0;
|
Ports[1].QueueStart = 0;
|
||||||
Ports[1].QueueEnd = 0;
|
Ports[1].QueueEnd = 0;
|
||||||
|
|
Loading…
Reference in a new issue