[NTVDM]
authorAleksandar Andrejevic <aandrejevic@reactos.org>
Sat, 13 Sep 2014 02:02:44 +0000 (02:02 +0000)
committerAleksandar Andrejevic <aandrejevic@reactos.org>
Sat, 13 Sep 2014 02:02:44 +0000 (02:02 +0000)
Start implementing the NTVDM mouse BIOS driver.

svn path=/trunk/; revision=64129

reactos/subsystems/ntvdm/CMakeLists.txt
reactos/subsystems/ntvdm/bios/bios32/bios32.c
reactos/subsystems/ntvdm/bios/bios32/moubios32.c [new file with mode: 0644]
reactos/subsystems/ntvdm/bios/bios32/moubios32.h [new file with mode: 0644]
reactos/subsystems/ntvdm/hardware/ps2.c

index 7f480dc..43ac966 100644 (file)
@@ -9,6 +9,7 @@ list(APPEND SOURCE
     bios/bios32/bios32.c
     bios/bios32/kbdbios32.c
     bios/bios32/vidbios32.c
+    bios/bios32/moubios32.c
     bios/bios.c
     bios/kbdbios.c
     bios/rom.c
index 34f6b61..7bf9a83 100644 (file)
@@ -20,6 +20,7 @@
 #include "bios32p.h"
 #include "kbdbios32.h"
 #include "vidbios32.h"
+#include "moubios32.h"
 
 #include "io.h"
 #include "hardware/cmos.h"
@@ -412,7 +413,7 @@ BOOLEAN Bios32Initialize(VOID)
     BiosHwSetup();
 
     /* Initialize the Keyboard and Video BIOS */
-    if (!KbdBios32Initialize() || !VidBios32Initialize()) return FALSE;
+    if (!KbdBios32Initialize() || !VidBios32Initialize() || !MouseBios32Initialize()) return FALSE;
 
     ///////////// MUST BE DONE AFTER IVT INITIALIZATION !! /////////////////////
 
@@ -428,6 +429,7 @@ BOOLEAN Bios32Initialize(VOID)
 
 VOID Bios32Cleanup(VOID)
 {
+    MouseBios32Cleanup();
     VidBios32Cleanup();
     KbdBios32Cleanup();
 }
diff --git a/reactos/subsystems/ntvdm/bios/bios32/moubios32.c b/reactos/subsystems/ntvdm/bios/bios32/moubios32.c
new file mode 100644 (file)
index 0000000..5a7b62e
--- /dev/null
@@ -0,0 +1,250 @@
+/*
+ * COPYRIGHT:       GPL - See COPYING in the top level directory
+ * PROJECT:         ReactOS Virtual DOS Machine
+ * FILE:            moubios32.c
+ * PURPOSE:         VDM Mouse 32-bit BIOS
+ * PROGRAMMERS:     Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
+ */
+
+/* INCLUDES *******************************************************************/
+
+#define NDEBUG
+
+#include "emulator.h"
+#include "callback.h"
+
+#include "moubios32.h"
+#include "bios32p.h"
+
+#include "io.h"
+#include "hardware/mouse.h"
+
+/* PRIVATE VARIABLES **********************************************************/
+
+static BOOLEAN DriverEnabled = TRUE;
+static MOUSE_DRIVER_STATE DriverState;
+
+/* PRIVATE FUNCTIONS **********************************************************/
+
+static VOID PaintMouseCursor(VOID)
+{
+    if (Bda->VideoMode <= 3)
+    {
+        WORD Character;
+        DWORD VideoAddress = TO_LINEAR(TEXT_VIDEO_SEG, Bda->VideoPage * Bda->VideoPageSize);
+
+        EmulatorReadMemory(&EmulatorContext,
+                           VideoAddress
+                           + (DriverState.Position.Y * Bda->ScreenColumns
+                           + DriverState.Position.X) * sizeof(WORD),
+                           (LPVOID)&Character,
+                           sizeof(WORD));
+
+        DriverState.Character = Character;
+        Character &= DriverState.TextCursor.ScreenMask;
+        Character ^= DriverState.TextCursor.CursorMask;
+
+        EmulatorWriteMemory(&EmulatorContext,
+                            VideoAddress
+                            + (DriverState.Position.Y * Bda->ScreenColumns
+                            + DriverState.Position.X) * sizeof(WORD),
+                            (LPVOID)&Character,
+                            sizeof(WORD));
+    }
+    else
+    {
+        // TODO: NOT IMPLEMENTED
+        UNIMPLEMENTED;
+    }
+}
+
+static VOID EraseMouseCursor(VOID)
+{
+    if (Bda->VideoMode <= 3)
+    {
+        DWORD VideoAddress = TO_LINEAR(TEXT_VIDEO_SEG, Bda->VideoPage * Bda->VideoPageSize);
+
+        EmulatorWriteMemory(&EmulatorContext,
+                            VideoAddress
+                            + (DriverState.Position.Y * Bda->ScreenColumns
+                            + DriverState.Position.X) * sizeof(WORD),
+                            (LPVOID)&DriverState.Character,
+                            sizeof(WORD));
+    }
+    else
+    {
+        // TODO: NOT IMPLEMENTED
+        UNIMPLEMENTED;
+    }
+}
+
+static VOID WINAPI BiosMouseService(LPWORD Stack)
+{
+    switch (getAX())
+    {
+        /* Reset Driver */
+        case 0x00:
+        {
+            DriverEnabled = TRUE;
+            DriverState.ShowCount = 0;
+
+            /* Set the default text cursor */
+            DriverState.TextCursor.ScreenMask = 0xFFFF; /* Display everything */
+            DriverState.TextCursor.CursorMask = 0xFF00; /* ... but with inverted attributes */
+
+            /* Set the default graphics cursor */
+            DriverState.GraphicsCursor.HotSpot.X = 3;
+            DriverState.GraphicsCursor.HotSpot.Y = 1;
+
+            DriverState.GraphicsCursor.ScreenMask[0] = 0xC3FF;  // 1100001111111111
+            DriverState.GraphicsCursor.ScreenMask[1] = 0xC0FF;  // 1100000011111111
+            DriverState.GraphicsCursor.ScreenMask[2] = 0xC07F;  // 1100000001111111
+            DriverState.GraphicsCursor.ScreenMask[3] = 0xC01F;  // 1100000000011111
+            DriverState.GraphicsCursor.ScreenMask[4] = 0xC00F;  // 1100000000001111
+            DriverState.GraphicsCursor.ScreenMask[5] = 0xC007;  // 1100000000000111
+            DriverState.GraphicsCursor.ScreenMask[6] = 0xC003;  // 1100000000000011
+            DriverState.GraphicsCursor.ScreenMask[7] = 0xC007;  // 1100000000000111
+            DriverState.GraphicsCursor.ScreenMask[8] = 0xC01F;  // 1100000000011111
+            DriverState.GraphicsCursor.ScreenMask[9] = 0xC01F;  // 1100000000011111
+            DriverState.GraphicsCursor.ScreenMask[10] = 0xC00F; // 1100000000001111
+            DriverState.GraphicsCursor.ScreenMask[11] = 0xC60F; // 1100011000001111
+            DriverState.GraphicsCursor.ScreenMask[12] = 0xFF07; // 1111111100000111
+            DriverState.GraphicsCursor.ScreenMask[13] = 0xFF07; // 1111111100000111
+            DriverState.GraphicsCursor.ScreenMask[14] = 0xFF87; // 1111111110000111
+            DriverState.GraphicsCursor.ScreenMask[15] = 0xFFCF; // 1111111111001111
+
+            DriverState.GraphicsCursor.CursorMask[0] = 0x0000;  // 0000000000000000
+            DriverState.GraphicsCursor.CursorMask[1] = 0x1C00;  // 0001110000000000
+            DriverState.GraphicsCursor.CursorMask[2] = 0x1F00;  // 0001111100000000
+            DriverState.GraphicsCursor.CursorMask[3] = 0x1F80;  // 0001111110000000
+            DriverState.GraphicsCursor.CursorMask[4] = 0x1FE0;  // 0001111111100000
+            DriverState.GraphicsCursor.CursorMask[5] = 0x1FF0;  // 0001111111110000
+            DriverState.GraphicsCursor.CursorMask[6] = 0x1FF8;  // 0001111111111000
+            DriverState.GraphicsCursor.CursorMask[7] = 0x1FE0;  // 0001111111100000
+            DriverState.GraphicsCursor.CursorMask[8] = 0x1FC0;  // 0001111111000000
+            DriverState.GraphicsCursor.CursorMask[9] = 0x1FC0;  // 0001111111000000
+            DriverState.GraphicsCursor.CursorMask[10] = 0x19E0; // 0001100111100000
+            DriverState.GraphicsCursor.CursorMask[11] = 0x00E0; // 0000000011100000
+            DriverState.GraphicsCursor.CursorMask[12] = 0x0070; // 0000000001110000
+            DriverState.GraphicsCursor.CursorMask[13] = 0x0070; // 0000000001110000
+            DriverState.GraphicsCursor.CursorMask[14] = 0x0030; // 0000000000110000
+            DriverState.GraphicsCursor.CursorMask[15] = 0x0000; // 0000000000000000
+
+            break;
+        }
+
+        /* Show Mouse Cursor */
+        case 0x01:
+        {
+            DriverState.ShowCount++;
+            if (DriverState.ShowCount > 0) PaintMouseCursor();
+
+            break;
+        }
+
+        /* Hide Mouse Cursor */
+        case 0x02:
+        {
+            DriverState.ShowCount--;
+            if (DriverState.ShowCount <= 0) EraseMouseCursor();
+
+            break;
+        }
+
+        /* Define Graphics Cursor */
+        case 0x09:
+        {
+            PWORD MaskBitmap = (PWORD)SEG_OFF_TO_PTR(getES(), getDX());
+
+            DriverState.GraphicsCursor.HotSpot.X = getBX();
+            DriverState.GraphicsCursor.HotSpot.Y = getCX();
+
+            RtlMoveMemory(DriverState.GraphicsCursor.ScreenMask,
+                          MaskBitmap,
+                          sizeof(DriverState.GraphicsCursor.ScreenMask));
+
+            RtlMoveMemory(DriverState.GraphicsCursor.CursorMask,
+                          &MaskBitmap[16],
+                          sizeof(DriverState.GraphicsCursor.CursorMask));
+
+            break;
+        }
+
+        /* Define Text Cursor */
+        case 0x0A:
+        {
+            DriverState.TextCursor.ScreenMask = getCX();
+            DriverState.TextCursor.CursorMask = getDX();
+
+            break;
+        }
+
+        /* Return Driver Storage Requirements */
+        case 0x15:
+        {
+            setBX(sizeof(MOUSE_DRIVER_STATE));
+            break;
+        }
+
+        /* Save Driver State */
+        case 0x16:
+        {
+            *((PMOUSE_DRIVER_STATE)SEG_OFF_TO_PTR(getES(), getDX())) = DriverState;
+            break;
+        }
+
+        /* Restore Driver State */
+        case 0x17:
+        {
+            DriverState = *((PMOUSE_DRIVER_STATE)SEG_OFF_TO_PTR(getES(), getDX()));
+            break;
+        }
+
+        /* Disable Mouse Driver */
+        case 0x1F:
+        {
+            DriverEnabled = FALSE;
+            break;
+        }
+
+        /* Enable Mouse Driver */
+        case 0x20:
+        {
+            DriverEnabled = TRUE;
+            break;
+        }
+
+        default:
+        {
+            DPRINT1("BIOS Function INT 33h, AX = 0x%04X NOT IMPLEMENTED\n", getAX());
+        }
+    }
+}
+
+/* PUBLIC FUNCTIONS ***********************************************************/
+
+VOID MouseBiosUpdatePosition(PCOORD NewPosition)
+{
+    if (DriverEnabled && (DriverState.ShowCount > 0))
+    {
+        EraseMouseCursor();
+        DriverState.Position = *NewPosition;
+        PaintMouseCursor();
+    }
+}
+
+BOOLEAN MouseBios32Initialize(VOID)
+{
+    /* Clear the state */
+    ZeroMemory(&DriverState, sizeof(DriverState));
+
+    /* Initialize the interrupt handler */
+    RegisterBiosInt32(BIOS_MOUSE_INTERRUPT, BiosMouseService);
+
+    return TRUE;
+}
+
+VOID MouseBios32Cleanup(VOID)
+{
+    if (DriverState.ShowCount > 0) EraseMouseCursor();
+}
diff --git a/reactos/subsystems/ntvdm/bios/bios32/moubios32.h b/reactos/subsystems/ntvdm/bios/bios32/moubios32.h
new file mode 100644 (file)
index 0000000..f5aa951
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * COPYRIGHT:       GPL - See COPYING in the top level directory
+ * PROJECT:         ReactOS Virtual DOS Machine
+ * FILE:            moubios32.h
+ * PURPOSE:         VDM Mouse 32-bit BIOS
+ * PROGRAMMERS:     Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
+ */
+
+#ifndef _MOUBIOS32_H_
+#define _MOUBIOS32_H_
+
+/* INCLUDES *******************************************************************/
+
+#include "ntvdm.h"
+
+/* DEFINES ********************************************************************/
+
+#define BIOS_MOUSE_INTERRUPT 0x33
+
+typedef struct _MOUSE_DRIVER_STATE
+{
+    SHORT ShowCount;
+    COORD Position;
+    WORD Character;
+
+    struct
+    {
+        WORD ScreenMask;
+        WORD CursorMask;
+    } TextCursor;
+
+    struct
+    {
+        COORD HotSpot;
+        WORD ScreenMask[16];
+        WORD CursorMask[16];
+    } GraphicsCursor;
+} MOUSE_DRIVER_STATE, *PMOUSE_DRIVER_STATE;
+
+/* FUNCTIONS ******************************************************************/
+
+VOID MouseBiosUpdatePosition(PCOORD NewPosition);
+BOOLEAN MouseBios32Initialize(VOID);
+VOID MouseBios32Cleanup(VOID);
+
+#endif // _MOUBIOS32_H_
+
+/* EOF */
index d2f27bb..7c1ed6d 100644 (file)
@@ -15,6 +15,7 @@
 #include "ps2.h"
 #include "pic.h"
 #include "mouse.h"
+#include "../bios/bios32/moubios32.h"
 
 /* PRIVATE VARIABLES **********************************************************/
 
@@ -307,8 +308,11 @@ VOID PS2Dispatch(PINPUT_RECORD InputRecord)
 
         case MOUSE_EVENT:
         {
-            // TODO: NOT IMPLEMENTED
-            UNIMPLEMENTED;
+            /* Notify the BIOS driver */
+            MouseBiosUpdatePosition(&InputRecord->Event.MouseEvent.dwMousePosition);
+
+            // TODO: PS/2, other stuff
+
             break;
         }
 
@@ -326,9 +330,7 @@ VOID GenerateKeyboardInterrupts(VOID)
 
 BOOLEAN PS2Initialize(HANDLE ConsoleInput)
 {
-#if 0
     DWORD ConInMode;
-#endif
 
     /* Create the mutex */
     QueueMutex = CreateMutex(NULL, FALSE, NULL);
@@ -337,23 +339,25 @@ BOOLEAN PS2Initialize(HANDLE ConsoleInput)
     RegisterIoPort(PS2_CONTROL_PORT, PS2ReadPort, PS2WritePort);
     RegisterIoPort(PS2_DATA_PORT   , PS2ReadPort, PS2WritePort);
 
-#if 0
     if (GetConsoleMode(ConsoleInput, &ConInMode))
     {
+#if 0
         if (MousePresent)
         {
+#endif
             /* Support mouse input events if there is a mouse on the system */
             ConInMode |= ENABLE_MOUSE_INPUT;
+#if 0
         }
         else
         {
             /* Do not support mouse input events if there is no mouse on the system */
             ConInMode &= ~ENABLE_MOUSE_INPUT;
         }
+#endif
 
         SetConsoleMode(ConsoleInput, ConInMode);
     }
-#endif
 
     return TRUE;
 }