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
|
||||
{
|
||||
WORD Length; // 0x00
|
||||
WORD Length; // 0x00 - Number of bytes following
|
||||
BYTE Model; // 0x02
|
||||
BYTE SubModel; // 0x03
|
||||
BYTE Revision; // 0x04
|
||||
|
|
|
@ -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@sfr.fr)
|
||||
*/
|
||||
|
||||
/* INCLUDES *******************************************************************/
|
||||
|
@ -109,7 +110,7 @@ $fffe ; System Model ID
|
|||
|
||||
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 @@ static VOID WINAPI BiosMiscService(LPWORD Stack)
|
|||
{
|
||||
setAX(0x80);
|
||||
Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -394,8 +394,11 @@ static VOID WINAPI BiosMiscService(LPWORD Stack)
|
|||
/* 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 @@ static VOID WINAPI BiosMiscService(LPWORD Stack)
|
|||
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 @@ static VOID WINAPI BiosMiscService(LPWORD Stack)
|
|||
else
|
||||
{
|
||||
DPRINT1("BIOS Function INT 15h, AH = 0xE8 - unexpected AL = %02X, EDX = %08X\n",
|
||||
getAL(),
|
||||
getEDX());
|
||||
getAL(), getEDX());
|
||||
}
|
||||
|
||||
break;
|
||||
|
@ -773,6 +775,16 @@ static VOID BiosHwSetup(VOID)
|
|||
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 @@ static VOID InitializeBiosInt32(VOID)
|
|||
|
||||
/* 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)
|
||||
|
|
|
@ -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@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();
|
||||
|
||||
/* Reset */
|
||||
case 0x01:
|
||||
{
|
||||
break;
|
||||
}
|
||||
if (State > 2)
|
||||
{
|
||||
/* Invalid function */
|
||||
setAH(0x01);
|
||||
Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Set Sampling Rate */
|
||||
case 0x02:
|
||||
{
|
||||
break;
|
||||
}
|
||||
if (State == 0x00)
|
||||
{
|
||||
BiosMouseDisable();
|
||||
|
||||
/* Set Resolution */
|
||||
case 0x03:
|
||||
{
|
||||
break;
|
||||
}
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/* Get Type */
|
||||
case 0x04:
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
/* 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:
|
||||
{
|
||||
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;
|
||||
UCHAR Answer;
|
||||
|
||||
/* Clear the mouse queue */
|
||||
while (PS2PortQueueRead(1)) continue;
|
||||
/* Initialize PS/2 mouse port */
|
||||
// Enable the port
|
||||
IOWriteB(PS2_CONTROL_PORT, 0xA8);
|
||||
|
||||
/* Enable packet reporting */
|
||||
IOWriteB(PS2_CONTROL_PORT, 0xD4);
|
||||
IOWriteB(PS2_DATA_PORT, 0xF4);
|
||||
/* 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 */
|
||||
|
||||
/* Read the mouse ACK reply */
|
||||
PS2PortQueueRead(1);
|
||||
// FIXME: The following is temporary until
|
||||
// this is moved into the mouse driver!!
|
||||
|
||||
/* Enable IRQ12 */
|
||||
IOWriteB(PS2_CONTROL_PORT, 0x20);
|
||||
ControllerConfig = IOReadB(PS2_DATA_PORT);
|
||||
IOWriteB(PS2_CONTROL_PORT, 0x60);
|
||||
IOWriteB(PS2_DATA_PORT, ControllerConfig | 0x02);
|
||||
/* 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);
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* 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>
|
||||
*/
|
||||
|
||||
|
@ -10,6 +10,10 @@
|
|||
|
||||
#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,8 +65,80 @@ static MOUSE_DRIVER_STATE DriverState;
|
|||
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)
|
||||
{
|
||||
COORD Position = DriverState.Position;
|
||||
|
@ -273,7 +352,7 @@ static inline VOID DosUpdatePosition(PCOORD NewPosition)
|
|||
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 @@ static VOID WINAPI DosMouseIrq(LPWORD Stack)
|
|||
|
||||
/* 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 @@ static VOID WINAPI DosMouseService(LPWORD Stack)
|
|||
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
|
||||
RtlCopyMemory(DriverState.GraphicsCursor.ScreenMask,
|
||||
DefaultGfxScreenMask,
|
||||
sizeof(DriverState.GraphicsCursor.ScreenMask));
|
||||
|
||||
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.CursorMask,
|
||||
DefaultGfxCursorMask,
|
||||
sizeof(DriverState.GraphicsCursor.CursorMask));
|
||||
|
||||
/* Initialize the counters */
|
||||
DriverState.HorizCount = DriverState.VertCount = 0;
|
||||
|
@ -436,7 +489,7 @@ static VOID WINAPI DosMouseService(LPWORD Stack)
|
|||
break;
|
||||
}
|
||||
|
||||
/* Return Position And Button Status */
|
||||
/* Return Position and Button Status */
|
||||
case 0x03:
|
||||
{
|
||||
COORD Position = DriverState.Position;
|
||||
|
@ -610,6 +663,13 @@ static VOID WINAPI DosMouseService(LPWORD Stack)
|
|||
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 @@ static VOID WINAPI DosMouseService(LPWORD Stack)
|
|||
|
||||
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 @@ static VOID WINAPI DosMouseService(LPWORD Stack)
|
|||
/* 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 @@ static VOID WINAPI DosMouseService(LPWORD Stack)
|
|||
/* 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 @@ static VOID WINAPI DosMouseService(LPWORD Stack)
|
|||
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 @@ static VOID WINAPI DosMouseService(LPWORD Stack)
|
|||
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 @@ static VOID WINAPI DosMouseService(LPWORD Stack)
|
|||
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 @@ static VOID WINAPI DosMouseService(LPWORD Stack)
|
|||
case 0x20:
|
||||
{
|
||||
DosMouseEnable();
|
||||
// UCHAR BH = getBH();
|
||||
// setBH(0x01);
|
||||
// BiosPs2Service(0x00);
|
||||
// FIXME: Check for return status in AH and CF
|
||||
// setBH(BH);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -876,6 +976,10 @@ static VOID WINAPI DosMouseService(LPWORD Stack)
|
|||
{
|
||||
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
|
||||
|
@ -883,6 +987,60 @@ static VOID WINAPI DosMouseService(LPWORD Stack)
|
|||
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 @@ static VOID WINAPI DosMouseService(LPWORD Stack)
|
|||
|
||||
/* PUBLIC FUNCTIONS ***********************************************************/
|
||||
|
||||
static
|
||||
VOID DosMouseEnable(VOID)
|
||||
{
|
||||
if (DriverEnabled) return;
|
||||
|
@ -928,6 +1087,7 @@ VOID DosMouseEnable(VOID)
|
|||
MOUSE_IRQ_INT, DosMouseIrq, NULL);
|
||||
}
|
||||
|
||||
static
|
||||
VOID DosMouseDisable(VOID)
|
||||
{
|
||||
if (!DriverEnabled) return;
|
||||
|
@ -938,61 +1098,6 @@ VOID DosMouseDisable(VOID)
|
|||
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)
|
||||
{
|
||||
/* 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);
|
||||
|
||||
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 @@ VOID DosMouseCleanup(VOID)
|
|||
{
|
||||
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;
|
||||
|
|
|
@ -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 @@ typedef struct _MOUSE_DRIVER_STATE
|
|||
|
||||
/* FUNCTIONS ******************************************************************/
|
||||
|
||||
VOID DosMouseEnable(VOID);
|
||||
VOID DosMouseDisable(VOID);
|
||||
BOOLEAN DosMouseInitialize(VOID);
|
||||
VOID DosMouseCleanup(VOID);
|
||||
|
||||
|
|
|
@ -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,12 +39,12 @@ static BOOLEAN EventsOccurred = FALSE;
|
|||
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 **********************************************************/
|
||||
|
||||
static VOID MouseResetConfig(VOID)
|
||||
|
@ -73,6 +73,8 @@ static VOID MouseReset(VOID)
|
|||
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 @@ static VOID MouseGetPacket(PMOUSE_PACKET Packet)
|
|||
/* 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 @@ static VOID WINAPI MouseCommand(LPVOID Param, BYTE Command)
|
|||
/* Set Sample Rate */
|
||||
case 0xF3:
|
||||
{
|
||||
PS2QueuePush(PS2Port, MOUSE_ACK);
|
||||
DataByteWait = Command;
|
||||
PS2QueuePush(PS2Port, MOUSE_ACK);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -259,12 +261,12 @@ static VOID WINAPI MouseCommand(LPVOID Param, BYTE Command)
|
|||
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 @@ static VOID WINAPI MouseCommand(LPVOID Param, BYTE Command)
|
|||
break;
|
||||
}
|
||||
|
||||
/* Return From Wrap Mode */
|
||||
/* Return from Wrap Mode */
|
||||
case 0xEC:
|
||||
{
|
||||
if (Mode == MOUSE_WRAP_MODE)
|
||||
|
@ -300,7 +302,10 @@ static VOID WINAPI MouseCommand(LPVOID Param, BYTE Command)
|
|||
Mode = PreviousMode;
|
||||
PS2QueuePush(PS2Port, MOUSE_ACK);
|
||||
}
|
||||
else PS2QueuePush(PS2Port, MOUSE_ERROR);
|
||||
else
|
||||
{
|
||||
PS2QueuePush(PS2Port, MOUSE_ERROR);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -45,8 +45,7 @@ typedef struct _PS2_PORT
|
|||
#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 @@ static BYTE WINAPI PS2ReadPort(USHORT 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
|
||||
// no timeouts and no parity errors.
|
||||
|
@ -220,6 +227,31 @@ static VOID WINAPI PS2WritePort(USHORT Port, BYTE Data)
|
|||
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 @@ Done:
|
|||
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;
|
||||
|
|
Loading…
Reference in a new issue