#define NDEBUG
+#include "ntvdm.h"
#include "emulator.h"
+
#include "cpu/cpu.h"
#include "int32.h"
#include "hardware/mouse.h"
/* PRIVATE VARIABLES **********************************************************/
-#define MICKEYS_PER_CELL_HORIZ 8
-#define MICKEYS_PER_CELL_VERT 16
+// FIXME: Because I don't know a better place to store the string
+// I temporarily put it in BIOS space. This need to be moved to a
+// proper place when this driver is interfaced correctly with DOS.
+#define COPYRIGHT_POINTER MAKELONG(0xE100, 0xF000)
+static const CHAR MouseCopyright[] = "ROS PS/2 16/32-bit Mouse Driver Compatible MS-MOUSE 6.26 Copyright (C) ReactOS Team 1996-2015";
+
+// See FIXME from above.
+#define VERSION_POINTER MAKELONG(0xE160, 0xF000)
+static PWORD Version;
+
+#define MICKEYS_PER_CELL_HORIZ 8
+#define MICKEYS_PER_CELL_VERT 16
static BOOLEAN DriverEnabled = FALSE;
static MOUSE_DRIVER_STATE DriverState;
static DWORD OldIrqHandler;
+static DWORD OldIntHandler;
/* PRIVATE FUNCTIONS **********************************************************/
-extern VOID WINAPI BiosMouseIrq(LPWORD Stack);
-
static VOID PaintMouseCursor(VOID)
{
COORD Position = DriverState.Position;
setDI(DI);
}
- for (i = 0; i < sizeof(DriverState.Handlers)/sizeof(DriverState.Handlers[0]); ++i)
+ for (i = 0; i < ARRAYSIZE(DriverState.Handlers); ++i)
{
/* Call the suitable handlers */
if ((DriverState.Handlers[i].CallMask & CallMask) != 0 &&
break;
}
+ /* Define Double-Speed Threshold */
+ case 0x13:
+ {
+ DPRINT1("INT 33h, AH=13h: Mouse double-speed threshold is UNSUPPORTED\n");
+ break;
+ }
+
/* Exchange Interrupt Subroutines, compatible MS MOUSE v3.0+ (see function 0x0C) */
case 0x14:
{
* Find the handler entry corresponding to the given
* callback and undefine it.
*/
- for (i = 0; i < sizeof(DriverState.Handlers)/sizeof(DriverState.Handlers[0]); ++i)
+ for (i = 0; i < ARRAYSIZE(DriverState.Handlers); ++i)
{
if (DriverState.Handlers[i].Callback == Callback)
{
* Find the handler entry corresponding to the given
* callmask and undefine it.
*/
- for (i = 0; i < sizeof(DriverState.Handlers)/sizeof(DriverState.Handlers[0]); ++i)
+ for (i = 0; i < ARRAYSIZE(DriverState.Handlers); ++i)
{
if (DriverState.Handlers[i].CallMask == CallMask)
{
USHORT EmptyHandler = 0xFFFF; // Invalid handler
- for (i = 0; i < sizeof(DriverState.Handlers)/sizeof(DriverState.Handlers[0]); ++i)
+ for (i = 0; i < ARRAYSIZE(DriverState.Handlers); ++i)
{
/* Find the first empty handler */
if (EmptyHandler == 0xFFFF &&
* an empty handler, set it.
*/
if (!Success && EmptyHandler != 0xFFFF
- /* && EmptyHandler < sizeof(DriverState.Handlers)/sizeof(DriverState.Handlers[0]) */)
+ /* && EmptyHandler < ARRAYSIZE(DriverState.Handlers) */)
{
DriverState.Handlers[EmptyHandler].CallMask = CallMask;
DriverState.Handlers[EmptyHandler].Callback = Callback;
/*
* Find the handler entry corresponding to the given callmask.
*/
- for (i = 0; i < sizeof(DriverState.Handlers)/sizeof(DriverState.Handlers[0]); ++i)
+ for (i = 0; i < ARRAYSIZE(DriverState.Handlers); ++i)
{
if (DriverState.Handlers[i].CallMask == CallMask)
{
break;
}
+ /* Set Mouse Sensitivity */
+ case 0x1A:
+ {
+ DPRINT1("INT 33h, AH=1Ah: Mouse sensitivity is UNSUPPORTED\n");
+ break;
+ }
+
+ /* Return Mouse Sensitivity */
+ case 0x1B:
+ {
+ DPRINT1("INT 33h, AH=1Bh: Mouse sensitivity is UNSUPPORTED\n");
+
+ /* Return default values */
+ setBX(50); // Horizontal speed
+ setCX(50); // Vertical speed
+ setDX(50); // Double speed threshold
+ break;
+ }
+
/* Disable Mouse Driver */
case 0x1F:
{
- setES(0x0000);
- setBX(0x0000);
+ /* INT 33h vector before the mouse driver was first installed */
+ setES(HIWORD(OldIntHandler));
+ setBX(LOWORD(OldIntHandler));
DosMouseDisable();
break;
break;
}
+ /* Software Reset */
+ case 0x21:
+ {
+ /*
+ * See: http://www.htl-steyr.ac.at/~morg/pcinfo/hardware/interrupts/inte3sq8.htm
+ * for detailed information and differences with respect to subfunction 0x00:
+ * http://www.htl-steyr.ac.at/~morg/pcinfo/hardware/interrupts/inte3j74.htm
+ */
+
+ SHORT i;
+
+ DriverState.ShowCount = 0;
+ DriverState.ButtonState = 0;
+
+ /* Initialize the default clipping range */
+ DriverState.MinX = 0;
+ DriverState.MaxX = MOUSE_MAX_HORIZ - 1;
+ DriverState.MinY = 0;
+ DriverState.MaxY = MOUSE_MAX_VERT - 1;
+
+ /* Initialize the counters */
+ DriverState.HorizCount = DriverState.VertCount = 0;
+
+ for (i = 0; i < NUM_MOUSE_BUTTONS; i++)
+ {
+ DriverState.PressCount[i] = DriverState.ReleaseCount[i] = 0;
+ }
+
+ /* Return mouse information */
+ setAX(0xFFFF); // Hardware & driver installed
+ setBX(NUM_MOUSE_BUTTONS);
+
+ break;
+ }
+
+ /* Get Software Version, Mouse Type, and IRQ Number, compatible MS MOUSE v6.26+ */
+ case 0x24:
+ {
+ setBX(MOUSE_VERSION); // Version Number
+
+ // FIXME: To be determined at runtime!
+ setCH(0x04); // PS/2 Type
+ setCL(0x00); // PS/2 Interrupt
+
+ break;
+ }
+
+ /* Return Pointer to Copyright String */
+ case 0x4D:
+ {
+ setES(HIWORD(COPYRIGHT_POINTER));
+ setDI(LOWORD(COPYRIGHT_POINTER));
+ break;
+ }
+
+ /* Get Version String (pointer) */
+ case 0x6D:
+ {
+ /*
+ * The format of the version "string" is:
+ * Offset Size Description
+ * 00h BYTE major version
+ * 01h BYTE minor version (BCD)
+ */
+ setES(HIWORD(VERSION_POINTER));
+ setDI(LOWORD(VERSION_POINTER));
+ break;
+ }
+
default:
{
DPRINT1("BIOS Function INT 33h, AX = 0x%04X NOT IMPLEMENTED\n", getAX());
/* Clear the state */
RtlZeroMemory(&DriverState, sizeof(DriverState));
+ /* Setup the version variable in BCD format, compatible MS-MOUSE */
+ Version = (PWORD)FAR_POINTER(VERSION_POINTER);
+ *Version = MAKEWORD(MOUSE_VERSION/0x0100, MOUSE_VERSION%0x0100);
+
+ /* Mouse Driver Copyright */
+ RtlCopyMemory(FAR_POINTER(COPYRIGHT_POINTER), MouseCopyright, sizeof(MouseCopyright)-1);
+
+ /* Get the old mouse service interrupt handler */
+ OldIntHandler = ((PDWORD)BaseAddress)[DOS_MOUSE_INTERRUPT];
+
/* Initialize the interrupt handler */
RegisterDosInt32(DOS_MOUSE_INTERRUPT, DosMouseService);
VOID DosMouseCleanup(VOID)
{
+ /* Restore the old mouse service interrupt handler */
+ ((PDWORD)BaseAddress)[DOS_MOUSE_INTERRUPT] = OldIntHandler;
+
if (DriverState.ShowCount > 0) EraseMouseCursor();
DosMouseDisable();
}