[NTVDM]
[reactos.git] / reactos / subsystems / ntvdm / bios / bios32 / moubios32.c
index 5df683e..235709e 100644 (file)
@@ -11,7 +11,6 @@
 #define NDEBUG
 
 #include "emulator.h"
-#include "callback.h"
 
 #include "moubios32.h"
 #include "bios32p.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 CallMouseUserHandlers(USHORT CallMask)
-{
-    USHORT i;
-
-    /* Call handler 0 */
-    if ((DriverState.Handler0.CallMask & CallMask) != 0 &&
-         DriverState.Handler0.Callback != (ULONG)NULL)
-    {
-        /*
-         * Set the parameters for the callback.
-         * NOTE: In text modes, the row and column will be reported
-         *       as a multiple of the cell size, typically 8x8 pixels.
-         */
-        setAX(CallMask);
-        setBX(DriverState.ButtonState);
-        setCX(DriverState.Position.X);
-        setDX(DriverState.Position.Y);
-        setSI(DriverState.MickeysPerCellHoriz);
-        setDI(DriverState.MickeysPerCellVert);
-
-        DPRINT1("Calling Handler0 0x%08x with CallMask 0x%04x\n",
-                DriverState.Handler0.Callback, CallMask);
-
-        /* Call the callback */
-        RunCallback16(&BiosContext, DriverState.Handler0.Callback);
-    }
-
-    for (i = 0; i < sizeof(DriverState.Handlers)/sizeof(DriverState.Handlers[0]); ++i)
-    {
-        /* Call the suitable handlers */
-        if ((DriverState.Handlers[i].CallMask & CallMask) != 0 &&
-             DriverState.Handlers[i].Callback != (ULONG)NULL)
-        {
-            /*
-             * Set the parameters for the callback.
-             * NOTE: In text modes, the row and column will be reported
-             *       as a multiple of the cell size, typically 8x8 pixels.
-             */
-            setAX(CallMask);
-            setBX(DriverState.ButtonState);
-            setCX(DriverState.Position.X);
-            setDX(DriverState.Position.Y);
-            setSI(DriverState.MickeysPerCellHoriz);
-            setDI(DriverState.MickeysPerCellVert);
-
-            DPRINT1("Calling Handler[%d] 0x%08x with CallMask 0x%04x\n",
-                    i, DriverState.Handlers[i].Callback, CallMask);
-
-            /* Call the callback */
-            RunCallback16(&BiosContext, DriverState.Handlers[i].Callback);
-        }
-    }
-}
-
-static VOID WINAPI BiosMouseService(LPWORD Stack)
+// Mouse IRQ 12
+static VOID WINAPI BiosMouseIrq(LPWORD Stack)
 {
-    switch (getAX())
-    {
-        /* Reset Driver */
-        case 0x00:
-        {
-            SHORT i;
-
-            DriverEnabled = TRUE;
-            DriverState.ShowCount = 0;
-            DriverState.ButtonState = 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
-
-            /* Initialize the counters */
-            DriverState.HorizCount = DriverState.VertCount = 0;
-
-            for (i = 0; i < NUM_MOUSE_BUTTONS; i++)
-            {
-                DriverState.PressCount[i] = DriverState.ReleaseCount[i] = 0;
-            }
-
-            /* Initialize the resolution */
-            DriverState.MickeysPerCellHoriz = 8;
-            DriverState.MickeysPerCellVert = 16;
-
-            /* Return mouse information */
-            setAX(0xFFFF);  // Hardware & driver installed
-            setBX(NUM_MOUSE_BUTTONS);
-
-            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;
-        }
-
-        /* Return Position And Button Status */
-        case 0x03:
-        {
-            setBX(DriverState.ButtonState);
-            setCX(DriverState.Position.X);
-            setDX(DriverState.Position.Y);
-            break;
-        }
-
-        /* Position Mouse Cursor */
-        case 0x04:
-        {
-            POINT Point;
-
-            Point.x = getCX();
-            Point.y = getDX();
-
-            ClientToScreen(GetConsoleWindow(), &Point);
-            SetCursorPos(Point.x, Point.y);
-
-            break;
-        }
-
-        /* Return Button Press Data */
-        case 0x05:
-        {
-            WORD Button = getBX();
-
-            setAX(DriverState.ButtonState);
-            setBX(DriverState.PressCount[Button]);
-            setCX(DriverState.LastPress[Button].X);
-            setDX(DriverState.LastPress[Button].Y);
-
-            /* Reset the counter */
-            DriverState.PressCount[Button] = 0;
-
-            break;
-        }
-
-        /* Return Button Release Data */
-        case 0x06:
-        {
-            WORD Button = getBX();
-
-            setAX(DriverState.ButtonState);
-            setBX(DriverState.ReleaseCount[Button]);
-            setCX(DriverState.LastRelease[Button].X);
-            setDX(DriverState.LastRelease[Button].Y);
-
-            /* Reset the counter */
-            DriverState.ReleaseCount[Button] = 0;
-
-            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:
-        {
-            USHORT BX = getBX();
-
-            if (BX == 0x0000)
-            {
-                /* Define software cursor */
-                DriverState.TextCursor.ScreenMask = getCX();
-                DriverState.TextCursor.CursorMask = getDX();
-            }
-            else if (BX == 0x0001)
-            {
-                /* Define hardware cursor */
-                DPRINT1("Defining hardware cursor is unimplemented\n");
-                UNIMPLEMENTED;
-                // CX == start scan line
-                // DX == end scan line
-            }
-            else
-            {
-                DPRINT1("Invalid BX value 0x%04x\n", BX);
-            }
-
-            break;
-        }
-
-        /* Read Motion Counters */
-        case 0x0B:
-        {
-            setCX(DriverState.HorizCount);
-            setDX(DriverState.VertCount);
-
-            /* Reset the counters */
-            DriverState.HorizCount = DriverState.VertCount = 0;
-
-            break;
-        }
-
-        /* Define Interrupt Subroutine Parameters, compatible MS MOUSE v1.0+ */
-        case 0x0C:
-        {
-            DriverState.Handler0.CallMask = getCX();
-            DriverState.Handler0.Callback = MAKELONG(getDX(), getES()); // Far pointer to the callback
-            DPRINT1("Define callback 0x%04x, 0x%08x\n",
-                    DriverState.Handler0.CallMask, DriverState.Handler0.Callback);
-            break;
-        }
-
-        /* Define Mickey/Pixel Ratio */
-        case 0x0F:
-        {
-            DriverState.MickeysPerCellHoriz = getCX();
-            DriverState.MickeysPerCellVert  = getDX();
-            break;
-        }
-
-        /* Exchange Interrupt Subroutines, compatible MS MOUSE v3.0+ (see function 0x0C) */
-        case 0x14:
-        {
-            USHORT OldCallMask = DriverState.Handler0.CallMask;
-            ULONG  OldCallback = DriverState.Handler0.Callback;
-
-            DriverState.Handler0.CallMask = getCX();
-            DriverState.Handler0.Callback = MAKELONG(getDX(), getES()); // Far pointer to the callback
-
-            /* Return old callmask in CX and callback vector in ES:DX */
-            setCX(OldCallMask);
-            setES(HIWORD(OldCallback));
-            setDX(LOWORD(OldCallback));
-
-            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;
-        }
-
-        /* Set Alternate Mouse User Handler, compatible MS MOUSE v6.0+ */
-        case 0x18:
-        {
-            /*
-             * Up to three handlers can be defined by separate calls to this
-             * function, each with a different combination of shift states in
-             * the call mask; calling this function again with a call mask of
-             * 0000h undefines the specified handler (official documentation);
-             * specifying the same call mask and an address of 0000h:0000h
-             * undefines the handler (real life).
-             * See Ralf Brown: http://www.ctyme.com/intr/rb-5981.htm
-             * for more information.
-             */
-
-            USHORT i;
-            USHORT CallMask = getCX();
-            ULONG  Callback = MAKELONG(getDX(), getES()); // Far pointer to the callback
-            BOOLEAN Success = FALSE;
-
-            DPRINT1("Define v6.0+ callback 0x%04x, 0x%08x\n",
-                    CallMask, Callback);
-
-            if (CallMask == 0x0000)
-            {
-                /*
-                 * Find the handler entry corresponding to the given
-                 * callback and undefine it.
-                 */
-                for (i = 0; i < sizeof(DriverState.Handlers)/sizeof(DriverState.Handlers[0]); ++i)
-                {
-                    if (DriverState.Handlers[i].Callback == Callback)
-                    {
-                        /* Found it, undefine the handler */
-                        DriverState.Handlers[i].CallMask = 0x0000;
-                        DriverState.Handlers[i].Callback = (ULONG)NULL;
-                        Success = TRUE;
-                        break;
-                    }
-                }
-            }
-            else if (Callback == (ULONG)NULL)
-            {
-                /*
-                 * Find the handler entry corresponding to the given
-                 * callmask and undefine it.
-                 */
-                for (i = 0; i < sizeof(DriverState.Handlers)/sizeof(DriverState.Handlers[0]); ++i)
-                {
-                    if (DriverState.Handlers[i].CallMask == CallMask)
-                    {
-                        /* Found it, undefine the handler */
-                        DriverState.Handlers[i].CallMask = 0x0000;
-                        DriverState.Handlers[i].Callback = (ULONG)NULL;
-                        Success = TRUE;
-                        break;
-                    }
-                }
-            }
-            else
-            {
-                /*
-                 * Try to find a handler entry corresponding to the given
-                 * callmask to redefine it, otherwise find an empty handler
-                 * entry and set the new handler in there.
-                 */
-
-                USHORT EmptyHandler = 0xFFFF; // Invalid handler
-
-                for (i = 0; i < sizeof(DriverState.Handlers)/sizeof(DriverState.Handlers[0]); ++i)
-                {
-                    /* Find the first empty handler */
-                    if (EmptyHandler == 0xFFFF &&
-                        DriverState.Handlers[i].CallMask == 0x0000 &&
-                        DriverState.Handlers[i].Callback == (ULONG)NULL)
-                    {
-                        EmptyHandler = i;
-                    }
-
-                    if (DriverState.Handlers[i].CallMask == CallMask)
-                    {
-                        /* Found it, redefine the handler */
-                        DriverState.Handlers[i].CallMask = CallMask;
-                        DriverState.Handlers[i].Callback = Callback;
-                        Success = TRUE;
-                        break;
-                    }
-                }
-
-                /*
-                 * If we haven't found anything and we found
-                 * an empty handler, set it.
-                 */
-                if (!Success && EmptyHandler != 0xFFFF
-                    /* && EmptyHandler < sizeof(DriverState.Handlers)/sizeof(DriverState.Handlers[0]) */)
-                {
-                    DriverState.Handlers[EmptyHandler].CallMask = CallMask;
-                    DriverState.Handlers[EmptyHandler].Callback = Callback;
-                    Success = TRUE;
-                }
-            }
-
-            /* If we failed, set error code */
-            if (!Success) setAX(0xFFFF);
-
-            break;
-        }
-
-        /* Return User Alternate Interrupt Vector, compatible MS MOUSE v6.0+ */
-        case 0x19:
-        {
-            USHORT i;
-            USHORT CallMask = getCX();
-            ULONG  Callback;
-            BOOLEAN Success = FALSE;
-
-            /*
-             * Find the handler entry corresponding to the given callmask.
-             */
-            for (i = 0; i < sizeof(DriverState.Handlers)/sizeof(DriverState.Handlers[0]); ++i)
-            {
-                if (DriverState.Handlers[i].CallMask == CallMask)
-                {
-                    /* Found it */
-                    Callback = DriverState.Handlers[i].Callback;
-                    Success = TRUE;
-                    break;
-                }
-            }
-
-            if (Success)
-            {
-                /* Return the callback vector in BX:DX */
-                setBX(HIWORD(Callback));
-                setDX(LOWORD(Callback));
-            }
-            else
-            {
-                /* We failed, set error code */
-                setCX(0x0000);
-            }
-
-            break;
-        }
-
-        /* Disable Mouse Driver */
-        case 0x1F:
-        {
-            setES(0x0000);
-            setBX(0x0000);
-
-            DriverEnabled = FALSE;
-            break;
-        }
-
-        /* Enable Mouse Driver */
-        case 0x20:
-        {
-            DriverEnabled = TRUE;
-            break;
-        }
-
-        default:
-        {
-            DPRINT1("BIOS Function INT 33h, AX = 0x%04X NOT IMPLEMENTED\n", getAX());
-        }
-    }
+    PicIRQComplete(Stack);
 }
 
 /* PUBLIC FUNCTIONS ***********************************************************/
 
-VOID MouseBiosUpdatePosition(PCOORD NewPosition)
-{
-    SHORT DeltaX = NewPosition->X - DriverState.Position.X;
-    SHORT DeltaY = NewPosition->Y - DriverState.Position.Y;
-
-    if (!DriverEnabled) return;
-
-    DriverState.HorizCount += (DeltaX * (SHORT)DriverState.MickeysPerCellHoriz) / 8;
-    DriverState.VertCount  += (DeltaY * (SHORT)DriverState.MickeysPerCellVert ) / 8;
-
-    if (DriverState.ShowCount > 0)
-    {
-        EraseMouseCursor();
-        DriverState.Position = *NewPosition;
-        PaintMouseCursor();
-    }
-
-    /* Call the mouse handlers */
-    CallMouseUserHandlers(0x0001); // We use MS MOUSE v1.0+ format
-}
-
-VOID MouseBiosUpdateButtons(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 MouseBios32Initialize(VOID)
 {
-    /* Clear the state */
-    ZeroMemory(&DriverState, sizeof(DriverState));
-
-    /* Initialize the interrupt handler */
-    RegisterBiosInt32(BIOS_MOUSE_INTERRUPT, BiosMouseService);
+    /* Set up the HW vector interrupts */
+    EnableHwIRQ(12, BiosMouseIrq);
 
     return TRUE;
 }
 
 VOID MouseBios32Cleanup(VOID)
 {
-    if (DriverState.ShowCount > 0) EraseMouseCursor();
 }