Author: hbelusca
Date: Tue Sep 16 00:51:15 2014
New Revision: 64168
URL:
http://svn.reactos.org/svn/reactos?rev=64168&view=rev
Log:
[NTVDM]
- Move the mouse driver to DOS since it's our 32bit version of
mouse.com, in some
sense,
- Temporarily disable the mouse user callbacks because currently they went called in a
parallel thread than the CPU one, that caused CPU corruption,
- In the same way we currently trigger IRQ1 interrupts, we do the same for IRQ12,
- Make the console input pump more modular (and mouse presence detection code is WIP),
- Put keyboard code into a dedicated file (as done for the mouse),
- Adapt the existing PS/2 emulation code to support two PS/2 ports controlled by 1
controller. Please note that some documentations precise that the response byte (answer to
a PS/2 controller command) is written directly to the PS/2 output port.
Added:
trunk/reactos/subsystems/ntvdm/dos/mouse32.c
- copied, changed from r64138,
trunk/reactos/subsystems/ntvdm/bios/bios32/moubios32.c
trunk/reactos/subsystems/ntvdm/dos/mouse32.h
- copied, changed from r64138,
trunk/reactos/subsystems/ntvdm/bios/bios32/moubios32.h
trunk/reactos/subsystems/ntvdm/hardware/keyboard.c (with props)
trunk/reactos/subsystems/ntvdm/hardware/keyboard.h (with props)
Modified:
trunk/reactos/subsystems/ntvdm/CMakeLists.txt
trunk/reactos/subsystems/ntvdm/bios/bios32/moubios32.c
trunk/reactos/subsystems/ntvdm/clock.c
trunk/reactos/subsystems/ntvdm/dos/dem.c
trunk/reactos/subsystems/ntvdm/emulator.c
trunk/reactos/subsystems/ntvdm/hardware/mouse.c
trunk/reactos/subsystems/ntvdm/hardware/mouse.h
trunk/reactos/subsystems/ntvdm/hardware/ps2.c
trunk/reactos/subsystems/ntvdm/hardware/ps2.h
trunk/reactos/subsystems/ntvdm/hardware/vga.c
trunk/reactos/subsystems/ntvdm/hardware/vga.h
trunk/reactos/subsystems/ntvdm/ntvdm.c
trunk/reactos/subsystems/ntvdm/ntvdm.h
Modified: trunk/reactos/subsystems/ntvdm/CMakeLists.txt
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/ntvdm/CMakeList…
==============================================================================
--- trunk/reactos/subsystems/ntvdm/CMakeLists.txt [iso-8859-1] (original)
+++ trunk/reactos/subsystems/ntvdm/CMakeLists.txt [iso-8859-1] Tue Sep 16 00:51:15 2014
@@ -15,15 +15,17 @@
bios/rom.c
bios/vidbios.c
hardware/cmos.c
+ hardware/keyboard.c
+ hardware/mouse.c
hardware/pic.c
hardware/ps2.c
hardware/speaker.c
hardware/timer.c
hardware/vga.c
- hardware/mouse.c
dos/dos32krnl/bios.c
dos/dos32krnl/dos.c
dos/dos32krnl/dosfiles.c
+ dos/mouse32.c
dos/dem.c
bop.c
callback.c
Modified: trunk/reactos/subsystems/ntvdm/bios/bios32/moubios32.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/ntvdm/bios/bios…
==============================================================================
--- trunk/reactos/subsystems/ntvdm/bios/bios32/moubios32.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/ntvdm/bios/bios32/moubios32.c [iso-8859-1] Tue Sep 16
00:51:15 2014
@@ -21,618 +21,24 @@
/* PRIVATE VARIABLES **********************************************************/
-static BOOLEAN DriverEnabled = TRUE;
-static MOUSE_DRIVER_STATE DriverState;
-
/* PRIVATE FUNCTIONS **********************************************************/
-static VOID PaintMouseCursor(VOID)
+// Mouse IRQ 12
+static VOID WINAPI BiosMouseIrq(LPWORD Stack)
{
- 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)
-{
- 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();
}
Modified: trunk/reactos/subsystems/ntvdm/clock.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/ntvdm/clock.c?r…
==============================================================================
--- trunk/reactos/subsystems/ntvdm/clock.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/ntvdm/clock.c [iso-8859-1] Tue Sep 16 00:51:15 2014
@@ -37,7 +37,8 @@
/* Processor speed */
#define STEPS_PER_CYCLE 256
-#define KBD_INT_CYCLES 16
+#define IRQ1_CYCLES 16
+#define IRQ12_CYCLES 16
/* VARIABLES ******************************************************************/
@@ -48,7 +49,9 @@
DWORD StartTickCount, CurrentTickCount;
DWORD LastClockUpdate;
DWORD LastVerticalRefresh;
-INT KeyboardIntCounter = 0;
+
+UINT Irq1Counter = 0;
+UINT Irq12Counter = 0;
#ifdef IPS_DISPLAY
DWORD LastCyclePrintout;
@@ -118,10 +121,16 @@
LastVerticalRefresh = CurrentTickCount;
}
- if (++KeyboardIntCounter == KBD_INT_CYCLES)
+ if (++Irq1Counter == IRQ1_CYCLES)
{
- GenerateKeyboardInterrupts();
- KeyboardIntCounter = 0;
+ GenerateIrq1();
+ Irq1Counter = 0;
+ }
+
+ if (++Irq12Counter == IRQ12_CYCLES)
+ {
+ GenerateIrq12();
+ Irq12Counter = 0;
}
/* Horizontal retrace occurs as fast as possible */
Modified: trunk/reactos/subsystems/ntvdm/dos/dem.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/ntvdm/dos/dem.c…
==============================================================================
--- trunk/reactos/subsystems/ntvdm/dos/dem.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/ntvdm/dos/dem.c [iso-8859-1] Tue Sep 16 00:51:15 2014
@@ -21,6 +21,7 @@
#include "bop.h"
#include "bios/bios.h"
+#include "mouse32.h"
/* Extra PSDK/NDK Headers */
#include <ndk/obtypes.h>
@@ -234,6 +235,7 @@
BOOLEAN Result;
Result = DosBIOSInitialize();
+ DosMouseInitialize(); // FIXME: Should be done by the DOS BIOS
// Result &= DosKRNLInitialize();
return Result;
Copied: trunk/reactos/subsystems/ntvdm/dos/mouse32.c (from r64138,
trunk/reactos/subsystems/ntvdm/bios/bios32/moubios32.c)
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/ntvdm/dos/mouse…
==============================================================================
--- trunk/reactos/subsystems/ntvdm/bios/bios32/moubios32.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/ntvdm/dos/mouse32.c [iso-8859-1] Tue Sep 16 00:51:15 2014
@@ -1,8 +1,8 @@
/*
* COPYRIGHT: GPL - See COPYING in the top level directory
* PROJECT: ReactOS Virtual DOS Machine
- * FILE: moubios32.c
- * PURPOSE: VDM Mouse 32-bit BIOS
+ * FILE: mouse32.c
+ * PURPOSE: VDM 32-bit compatible
MOUSE.COM driver
* PROGRAMMERS: Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
*/
@@ -13,11 +13,11 @@
#include "emulator.h"
#include "callback.h"
-#include "moubios32.h"
-#include "bios32p.h"
+#include "mouse32.h"
+#include "bios/bios.h"
#include "io.h"
-#include "hardware/mouse.h"
+#include "dos32krnl/dos.h"
/* PRIVATE VARIABLES **********************************************************/
@@ -80,7 +80,9 @@
static VOID CallMouseUserHandlers(USHORT CallMask)
{
+#if 0
USHORT i;
+ USHORT AX, BX, CX, DX, SI, DI;
/* Call handler 0 */
if ((DriverState.Handler0.CallMask & CallMask) != 0 &&
@@ -91,6 +93,14 @@
* NOTE: In text modes, the row and column will be reported
* as a multiple of the cell size, typically 8x8 pixels.
*/
+
+ AX = getAX();
+ BX = getBX();
+ CX = getCX();
+ DX = getDX();
+ SI = getSI();
+ DI = getDI();
+
setAX(CallMask);
setBX(DriverState.ButtonState);
setCX(DriverState.Position.X);
@@ -102,7 +112,14 @@
DriverState.Handler0.Callback, CallMask);
/* Call the callback */
- RunCallback16(&BiosContext, DriverState.Handler0.Callback);
+ RunCallback16(&DosContext, DriverState.Handler0.Callback);
+
+ setAX(AX);
+ setBX(BX);
+ setCX(CX);
+ setDX(DX);
+ setSI(SI);
+ setDI(DI);
}
for (i = 0; i < sizeof(DriverState.Handlers)/sizeof(DriverState.Handlers[0]);
++i)
@@ -116,6 +133,14 @@
* NOTE: In text modes, the row and column will be reported
* as a multiple of the cell size, typically 8x8 pixels.
*/
+
+ AX = getAX();
+ BX = getBX();
+ CX = getCX();
+ DX = getDX();
+ SI = getSI();
+ DI = getDI();
+
setAX(CallMask);
setBX(DriverState.ButtonState);
setCX(DriverState.Position.X);
@@ -127,9 +152,17 @@
i, DriverState.Handlers[i].Callback, CallMask);
/* Call the callback */
- RunCallback16(&BiosContext, DriverState.Handlers[i].Callback);
- }
- }
+ RunCallback16(&DosContext, DriverState.Handlers[i].Callback);
+
+ setAX(AX);
+ setBX(BX);
+ setCX(CX);
+ setDX(DX);
+ setSI(SI);
+ setDI(DI);
+ }
+ }
+#endif
}
static VOID WINAPI BiosMouseService(LPWORD Stack)
@@ -621,18 +654,18 @@
CallMouseUserHandlers(CallMask);
}
-BOOLEAN MouseBios32Initialize(VOID)
+BOOLEAN DosMouseInitialize(VOID)
{
/* Clear the state */
ZeroMemory(&DriverState, sizeof(DriverState));
/* Initialize the interrupt handler */
- RegisterBiosInt32(BIOS_MOUSE_INTERRUPT, BiosMouseService);
+ RegisterDosInt32(BIOS_MOUSE_INTERRUPT, BiosMouseService);
return TRUE;
}
-VOID MouseBios32Cleanup(VOID)
+VOID DosMouseCleanup(VOID)
{
if (DriverState.ShowCount > 0) EraseMouseCursor();
}
Copied: trunk/reactos/subsystems/ntvdm/dos/mouse32.h (from r64138,
trunk/reactos/subsystems/ntvdm/bios/bios32/moubios32.h)
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/ntvdm/dos/mouse…
==============================================================================
--- trunk/reactos/subsystems/ntvdm/bios/bios32/moubios32.h [iso-8859-1] (original)
+++ trunk/reactos/subsystems/ntvdm/dos/mouse32.h [iso-8859-1] Tue Sep 16 00:51:15 2014
@@ -1,13 +1,13 @@
/*
* COPYRIGHT: GPL - See COPYING in the top level directory
* PROJECT: ReactOS Virtual DOS Machine
- * FILE: moubios32.h
- * PURPOSE: VDM Mouse 32-bit BIOS
+ * FILE: mouse32.h
+ * PURPOSE: VDM 32-bit compatible
MOUSE.COM driver
* PROGRAMMERS: Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
*/
-#ifndef _MOUBIOS32_H_
-#define _MOUBIOS32_H_
+#ifndef _MOUSE32_H_
+#define _MOUSE32_H_
/* INCLUDES *******************************************************************/
@@ -74,9 +74,10 @@
VOID MouseBiosUpdatePosition(PCOORD NewPosition);
VOID MouseBiosUpdateButtons(WORD ButtonStatus);
-BOOLEAN MouseBios32Initialize(VOID);
-VOID MouseBios32Cleanup(VOID);
-#endif // _MOUBIOS32_H_
+BOOLEAN DosMouseInitialize(VOID);
+VOID DosMouseCleanup(VOID);
+
+#endif // _MOUSE32_H_
/* EOF */
Modified: trunk/reactos/subsystems/ntvdm/emulator.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/ntvdm/emulator.…
==============================================================================
--- trunk/reactos/subsystems/ntvdm/emulator.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/ntvdm/emulator.c [iso-8859-1] Tue Sep 16 00:51:15 2014
@@ -16,6 +16,8 @@
#include "clock.h"
#include "bios/rom.h"
#include "hardware/cmos.h"
+#include "hardware/keyboard.h"
+#include "hardware/mouse.h"
#include "hardware/pic.h"
#include "hardware/ps2.h"
#include "hardware/speaker.h"
@@ -335,6 +337,95 @@
// SpeakerChange();
}
+
+static DWORD
+WINAPI
+PumpConsoleInput(LPVOID Parameter)
+{
+ HANDLE ConsoleInput = (HANDLE)Parameter;
+ INPUT_RECORD InputRecord;
+ DWORD Count;
+
+ while (VdmRunning)
+ {
+ /* Make sure the task event is signaled */
+ WaitForSingleObject(VdmTaskEvent, INFINITE);
+
+ /* Wait for an input record */
+ if (!ReadConsoleInput(ConsoleInput, &InputRecord, 1, &Count))
+ {
+ DWORD LastError = GetLastError();
+ DPRINT1("Error reading console input (0x%p, %lu) - Error %lu\n",
ConsoleInput, Count, LastError);
+ return LastError;
+ }
+
+ ASSERT(Count != 0);
+
+ /* Check the event type */
+ switch (InputRecord.EventType)
+ {
+ /*
+ * Hardware events
+ */
+ case KEY_EVENT:
+ KeyboardEventHandler(&InputRecord.Event.KeyEvent);
+ break;
+
+ case MOUSE_EVENT:
+ MouseEventHandler(&InputRecord.Event.MouseEvent);
+ break;
+
+ case WINDOW_BUFFER_SIZE_EVENT:
+ ScreenEventHandler(&InputRecord.Event.WindowBufferSizeEvent);
+ break;
+
+ /*
+ * Interface events
+ */
+ case MENU_EVENT:
+ MenuEventHandler(&InputRecord.Event.MenuEvent);
+ break;
+
+ case FOCUS_EVENT:
+ FocusEventHandler(&InputRecord.Event.FocusEvent);
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ return 0;
+}
+
+static VOID EnableExtraHardware(HANDLE ConsoleInput)
+{
+ DWORD ConInMode;
+
+ if (GetConsoleMode(ConsoleInput, &ConInMode))
+ {
+#if 0
+ // GetNumberOfConsoleMouseButtons();
+ // GetSystemMetrics(SM_CMOUSEBUTTONS);
+ // GetSystemMetrics(SM_MOUSEPRESENT);
+ 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);
+ }
+}
+
/* PUBLIC FUNCTIONS ***********************************************************/
VOID DumpMemory(VOID)
@@ -420,8 +511,6 @@
DPRINT1("Memory dump done\n");
}
-
-DWORD WINAPI PumpConsoleInput(LPVOID Parameter);
BOOLEAN EmulatorInitialize(HANDLE ConsoleInput, HANDLE ConsoleOutput)
{
@@ -476,8 +565,14 @@
SetConsoleMode(ConsoleInput, ENABLE_PROCESSED_INPUT /* | ENABLE_WINDOW_INPUT */);
// SetConsoleMode(ConsoleOutput, ENABLE_PROCESSED_OUTPUT |
ENABLE_WRAP_AT_EOL_OUTPUT);
- /* Initialize the PS2 port */
- PS2Initialize(ConsoleInput);
+ /**/EnableExtraHardware(ConsoleInput);/**/
+
+ /* Initialize the PS/2 port */
+ PS2Initialize();
+
+ /* Initialize the keyboard and mouse and connect them to their PS/2 ports */
+ KeyboardInit(0);
+ MouseInit(1);
/**************** ATTACH INPUT WITH CONSOLE *****************/
/* Start the input thread */
Added: trunk/reactos/subsystems/ntvdm/hardware/keyboard.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/ntvdm/hardware/…
==============================================================================
--- trunk/reactos/subsystems/ntvdm/hardware/keyboard.c (added)
+++ trunk/reactos/subsystems/ntvdm/hardware/keyboard.c [iso-8859-1] Tue Sep 16 00:51:15
2014
@@ -0,0 +1,46 @@
+/*
+ * COPYRIGHT: GPL - See COPYING in the top level directory
+ * PROJECT: ReactOS Virtual DOS Machine
+ * FILE: keyboard.c
+ * PURPOSE: Keyboard emulation
+ * PROGRAMMERS: Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
+ */
+
+/* INCLUDES *******************************************************************/
+
+#define NDEBUG
+
+#include "keyboard.h"
+#include "ps2.h"
+
+static BYTE PS2Port = 0;
+
+/* PUBLIC FUNCTIONS ***********************************************************/
+
+VOID KeyboardEventHandler(PKEY_EVENT_RECORD KeyEvent)
+{
+ WORD i;
+ BYTE ScanCode = (BYTE)KeyEvent->wVirtualScanCode;
+
+ /* If this is a key release, set the highest bit in the scan code */
+ if (!KeyEvent->bKeyDown) ScanCode |= 0x80;
+
+ /* Push the scan code into the PS/2 queue */
+ for (i = 0; i < KeyEvent->wRepeatCount; i++)
+ {
+ PS2QueuePush(PS2Port, ScanCode);
+ }
+
+ // PicInterruptRequest(1);
+}
+
+VOID KeyboardCommand(BYTE Command)
+{
+ UNIMPLEMENTED;
+}
+
+BOOLEAN KeyboardInit(BYTE PS2Connector)
+{
+ PS2Port = PS2Connector;
+ return TRUE;
+}
Propchange: trunk/reactos/subsystems/ntvdm/hardware/keyboard.c
------------------------------------------------------------------------------
svn:eol-style = native
Added: trunk/reactos/subsystems/ntvdm/hardware/keyboard.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/ntvdm/hardware/…
==============================================================================
--- trunk/reactos/subsystems/ntvdm/hardware/keyboard.h (added)
+++ trunk/reactos/subsystems/ntvdm/hardware/keyboard.h [iso-8859-1] Tue Sep 16 00:51:15
2014
@@ -0,0 +1,28 @@
+/*
+ * COPYRIGHT: GPL - See COPYING in the top level directory
+ * PROJECT: ReactOS Virtual DOS Machine
+ * FILE: keyboard.h
+ * PURPOSE: Keyboard emulation
+ * PROGRAMMERS: Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
+ */
+
+#ifndef _KEYBOARD_H_
+#define _KEYBOARD_H_
+
+/* INCLUDES *******************************************************************/
+
+#include "ntvdm.h"
+
+/* DEFINES ********************************************************************/
+
+/* Command responses */
+#define KEYBOARD_ACK 0xFA
+#define KEYBOARD_RESEND 0xFE
+
+/* FUNCTIONS ******************************************************************/
+
+VOID KeyboardEventHandler(PKEY_EVENT_RECORD KeyEvent);
+VOID KeyboardCommand(BYTE Command);
+BOOLEAN KeyboardInit(BYTE PS2Connector);
+
+#endif // _KEYBOARD_H_
Propchange: trunk/reactos/subsystems/ntvdm/hardware/keyboard.h
------------------------------------------------------------------------------
svn:eol-style = native
Modified: trunk/reactos/subsystems/ntvdm/hardware/mouse.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/ntvdm/hardware/…
==============================================================================
--- trunk/reactos/subsystems/ntvdm/hardware/mouse.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/ntvdm/hardware/mouse.c [iso-8859-1] Tue Sep 16 00:51:15 2014
@@ -12,6 +12,9 @@
#include "mouse.h"
#include "ps2.h"
+
+// HACK: For the PS/2 bypass and
MOUSE.COM driver direct call
+#include "dos/mouse32.h"
/* PRIVATE VARIABLES **********************************************************/
@@ -28,6 +31,8 @@
static SHORT VertCounter;
static CHAR ScrollCounter;
+static BYTE PS2Port = 1;
+
/* PRIVATE FUNCTIONS **********************************************************/
static VOID MouseResetConfig(VOID)
@@ -56,8 +61,8 @@
MouseId = 0;
/* Send the Basic Assurance Test success code and the device ID */
- KeyboardQueuePush(MOUSE_BAT_SUCCESS);
- KeyboardQueuePush(MouseId);
+ PS2QueuePush(PS2Port, MOUSE_BAT_SUCCESS);
+ PS2QueuePush(PS2Port, MouseId);
}
#if 0
@@ -116,9 +121,7 @@
}
#endif
-/* PUBLIC FUNCTIONS ***********************************************************/
-
-VOID MouseUpdatePosition(PCOORD NewPosition)
+/*static*/ VOID MouseUpdatePosition(PCOORD NewPosition)
{
/* Update the counters */
HorzCounter += ((NewPosition->X - Position.X) * WidthMm * Resolution) /
WidthPixels;
@@ -128,9 +131,23 @@
Position = *NewPosition;
}
-VOID MouseUpdateButtons(ULONG NewButtonState)
+/*static*/ VOID MouseUpdateButtons(ULONG NewButtonState)
{
ButtonState = NewButtonState;
+}
+
+/* PUBLIC FUNCTIONS ***********************************************************/
+
+VOID MouseEventHandler(PMOUSE_EVENT_RECORD MouseEvent)
+{
+ // FIXME: Sync our private data
+
+ // HACK: Bypass PS/2 and instead, notify the
MOUSE.COM driver directly
+ MouseBiosUpdatePosition(&MouseEvent->dwMousePosition);
+ MouseBiosUpdateButtons(LOWORD(MouseEvent->dwButtonState));
+
+ // PS2QueuePush(PS2Port, Data);
+ // PicInterruptRequest(12);
}
VOID MouseScroll(LONG Direction)
@@ -151,7 +168,7 @@
case 0xE6:
{
Scaling = FALSE;
- KeyboardQueuePush(MOUSE_ACK);
+ PS2QueuePush(PS2Port, MOUSE_ACK);
break;
}
@@ -159,7 +176,7 @@
case 0xE7:
{
Scaling = TRUE;
- KeyboardQueuePush(MOUSE_ACK);
+ PS2QueuePush(PS2Port, MOUSE_ACK);
break;
}
@@ -185,7 +202,7 @@
MouseResetCounters();
Mode = MOUSE_STREAMING_MODE;
- KeyboardQueuePush(MOUSE_ACK);
+ PS2QueuePush(PS2Port, MOUSE_ACK);
break;
}
@@ -205,9 +222,9 @@
/* Restore the previous mode */
MouseResetCounters();
Mode = PreviousMode;
- KeyboardQueuePush(MOUSE_ACK);
+ PS2QueuePush(PS2Port, MOUSE_ACK);
}
- else KeyboardQueuePush(MOUSE_ERROR);
+ else PS2QueuePush(PS2Port, MOUSE_ERROR);
break;
}
@@ -224,7 +241,7 @@
MouseResetCounters();
Mode = MOUSE_WRAP_MODE;
- KeyboardQueuePush(MOUSE_ACK);
+ PS2QueuePush(PS2Port, MOUSE_ACK);
break;
}
@@ -234,15 +251,15 @@
MouseResetCounters();
Mode = MOUSE_REMOTE_MODE;
- KeyboardQueuePush(MOUSE_ACK);
+ PS2QueuePush(PS2Port, MOUSE_ACK);
break;
}
/* Get Mouse ID */
case 0xF2:
{
- KeyboardQueuePush(MOUSE_ACK);
- KeyboardQueuePush(MouseId);
+ PS2QueuePush(PS2Port, MOUSE_ACK);
+ PS2QueuePush(PS2Port, MouseId);
break;
}
@@ -258,7 +275,7 @@
case 0xF4:
{
Reporting = TRUE;
- KeyboardQueuePush(MOUSE_ACK);
+ PS2QueuePush(PS2Port, MOUSE_ACK);
break;
}
@@ -266,7 +283,7 @@
case 0xF5:
{
Reporting = FALSE;
- KeyboardQueuePush(MOUSE_ACK);
+ PS2QueuePush(PS2Port, MOUSE_ACK);
break;
}
@@ -297,12 +314,12 @@
/* Unknown command */
default:
{
- KeyboardQueuePush(MOUSE_ERROR);
- }
- }
-}
-
-BOOLEAN MouseInit(VOID)
+ PS2QueuePush(PS2Port, MOUSE_ERROR);
+ }
+ }
+}
+
+BOOLEAN MouseInit(BYTE PS2Connector)
{
HWND hWnd;
HDC hDC;
@@ -324,6 +341,8 @@
/* Release the device context */
ReleaseDC(hWnd, hDC);
+ PS2Port = PS2Connector;
+
MouseReset();
return TRUE;
}
Modified: trunk/reactos/subsystems/ntvdm/hardware/mouse.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/ntvdm/hardware/…
==============================================================================
--- trunk/reactos/subsystems/ntvdm/hardware/mouse.h [iso-8859-1] (original)
+++ trunk/reactos/subsystems/ntvdm/hardware/mouse.h [iso-8859-1] Tue Sep 16 00:51:15 2014
@@ -68,11 +68,12 @@
/* FUNCTIONS ******************************************************************/
-VOID MouseUpdatePosition(PCOORD NewPosition);
-VOID MouseUpdateButtons(ULONG NewButtonState);
+VOID MouseEventHandler(PMOUSE_EVENT_RECORD MouseEvent);
+
VOID MouseScroll(LONG Direction);
COORD MouseGetPosition(VOID);
+
VOID MouseCommand(BYTE Command);
-BOOLEAN MouseInit(VOID);
+BOOLEAN MouseInit(BYTE PS2Connector);
#endif // _MOUSE_H_
Modified: trunk/reactos/subsystems/ntvdm/hardware/ps2.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/ntvdm/hardware/…
==============================================================================
--- trunk/reactos/subsystems/ntvdm/hardware/ps2.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/ntvdm/hardware/ps2.c [iso-8859-1] Tue Sep 16 00:51:15 2014
@@ -4,6 +4,7 @@
* FILE: ps2.c
* PURPOSE: PS/2 controller emulation
* PROGRAMMERS: Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
+ * Hermes Belusca-Maito (hermes.belusca(a)sfr.fr)
*/
/* INCLUDES *******************************************************************/
@@ -14,19 +15,39 @@
#include "io.h"
#include "ps2.h"
#include "pic.h"
+
+#include "keyboard.h"
#include "mouse.h"
-#include "../bios/bios32/moubios32.h"
/* PRIVATE VARIABLES **********************************************************/
-static BYTE KeyboardQueue[KEYBOARD_BUFFER_SIZE];
-static BOOLEAN KeyboardQueueEmpty = TRUE;
-static UINT KeyboardQueueStart = 0;
-static UINT KeyboardQueueEnd = 0;
-static BYTE KeyboardData = 0, KeyboardResponse = 0;
-static BOOLEAN KeyboardReadResponse = FALSE, KeyboardWriteResponse = FALSE;
-static BYTE KeyboardConfig = PS2_DEFAULT_CONFIG;
-static HANDLE QueueMutex = NULL;
+#define BUFFER_SIZE 32
+
+typedef struct _PS2_PORT
+{
+ BOOLEAN IsEnabled;
+
+ BOOLEAN QueueEmpty;
+ BYTE Queue[BUFFER_SIZE];
+ UINT QueueStart;
+ UINT QueueEnd;
+ HANDLE QueueMutex;
+} PS2_PORT, *PPS2_PORT;
+
+/*
+ * Port 1: Keyboard
+ * Port 2: Mouse
+ */
+#define PS2_PORTS 2
+static PS2_PORT Ports[PS2_PORTS];
+
+#define PS2_DEFAULT_CONFIG 0x47
+static BYTE ControllerConfig = PS2_DEFAULT_CONFIG;
+static BYTE ControllerCommand = 0x00;
+
+static BYTE StatusRegister = 0x00;
+// static BYTE InputBuffer = 0x00; // PS/2 Input Buffer
+static BYTE OutputBuffer = 0x00; // PS/2 Output Buffer
/* PRIVATE FUNCTIONS **********************************************************/
@@ -34,31 +55,28 @@
{
if (Port == PS2_CONTROL_PORT)
{
- BYTE Status = 0;
-
- /* Set the first bit if the data can be read */
- if (KeyboardReadResponse || !KeyboardQueueEmpty) Status |= 1 << 0;
-
- /* Always set bit 2 */
- Status |= 1 << 2;
-
- /* Set bit 3 if the next byte goes to the controller */
- if (KeyboardWriteResponse) Status |= 1 << 3;
-
- return Status;
+ /* Be sure bit 2 is always set */
+ StatusRegister |= 1 << 2;
+
+ // FIXME: Should clear bits 6 and 7 because there are
+ // no timeouts and no parity errors.
+
+ return StatusRegister;
}
else if (Port == PS2_DATA_PORT)
{
- /* If there was a response byte from the controller, return it */
- if (KeyboardReadResponse)
- {
- KeyboardReadResponse = FALSE;
- KeyboardData = KeyboardResponse;
- }
-
- return KeyboardData;
- }
- else return 0;
+ /*
+ * If there is something to read (response byte from the
+ * controller or data from a PS/2 device), read it.
+ */
+ if (StatusRegister & (1 << 0)) // || StatusRegister & (1
<< 5) for second PS/2 port
+ StatusRegister &= ~(1 << 0); // StatusRegister &= ~(1
<< 5);
+
+ /* Always return the available byte stored in the output buffer */
+ return OutputBuffer;
+ }
+
+ return 0;
}
static VOID WINAPI PS2WritePort(ULONG Port, BYTE Data)
@@ -70,8 +88,8 @@
/* Read configuration byte */
case 0x20:
{
- KeyboardResponse = KeyboardConfig;
- KeyboardReadResponse = TRUE;
+ OutputBuffer = ControllerConfig;
+ StatusRegister |= (1 << 0); // There is something to read
break;
}
@@ -79,60 +97,68 @@
case 0x60:
/* Write controller output port */
case 0xD1:
- /* Write keyboard output buffer */
+ /* Write to the first PS/2 port output buffer */
case 0xD2:
- /* Write mouse output buffer */
+ /* Write to the second PS/2 port output buffer */
case 0xD3:
- /* Write mouse input buffer */
+ /* Write to the second PS/2 port input buffer */
case 0xD4:
{
/* These commands require a response */
- KeyboardResponse = Data;
- KeyboardWriteResponse = TRUE;
- break;
- }
-
- /* Disable mouse */
+ ControllerCommand = Data;
+ StatusRegister |= (1 << 3); // This is a controller command
+ break;
+ }
+
+ /* Disable second PS/2 port */
case 0xA7:
{
- // TODO: Not implemented
- break;
- }
-
- /* Enable mouse */
+ Ports[1].IsEnabled = FALSE;
+ break;
+ }
+
+ /* Enable second PS/2 port */
case 0xA8:
{
- // TODO: Not implemented
- break;
- }
-
- /* Test mouse port */
+ Ports[1].IsEnabled = TRUE;
+ break;
+ }
+
+ /* Test second PS/2 port */
case 0xA9:
{
- KeyboardResponse = 0;
- KeyboardReadResponse = TRUE;
+ OutputBuffer = 0x00; // Success code
+ StatusRegister |= (1 << 0); // There is something to read
break;
}
/* Test PS/2 controller */
case 0xAA:
{
- KeyboardResponse = 0x55;
- KeyboardReadResponse = TRUE;
- break;
- }
-
- /* Disable keyboard */
+ OutputBuffer = 0x55; // Success code
+ StatusRegister |= (1 << 0); // There is something to read
+ break;
+ }
+
+ /* Test first PS/2 port */
+ case 0xAB:
+ {
+ OutputBuffer = 0x00; // Success code
+ StatusRegister |= (1 << 0); // There is something to read
+ break;
+ }
+
+ /* Disable first PS/2 port */
case 0xAD:
{
- // TODO: Not implemented
- break;
- }
-
- /* Enable keyboard */
+ Ports[0].IsEnabled = FALSE;
+ break;
+ }
+
+ /* Enable first PS/2 port */
case 0xAE:
{
- // TODO: Not implemented
+ Ports[0].IsEnabled = TRUE;
break;
}
@@ -162,17 +188,17 @@
else if (Port == PS2_DATA_PORT)
{
/* Check if the controller is waiting for a response */
- if (KeyboardWriteResponse)
+ if (StatusRegister & (1 << 3)) // If we have data for the controller
{
- KeyboardWriteResponse = FALSE;
+ StatusRegister &= ~(1 << 3);
/* Check which command it was */
- switch (KeyboardResponse)
+ switch (ControllerCommand)
{
/* Write configuration byte */
case 0x60:
{
- KeyboardConfig = Data;
+ ControllerConfig = Data;
break;
}
@@ -191,23 +217,31 @@
break;
}
-
+
+ /* Push the data byte into the first PS/2 port queue */
case 0xD2:
{
- /* Push the data byte to the keyboard queue */
- KeyboardQueuePush(Data);
- break;
- }
-
+ PS2QueuePush(0, Data);
+ break;
+ }
+
+ /* Push the data byte into the second PS/2 port queue */
case 0xD3:
{
- // TODO: Mouse support
- break;
- }
-
+ PS2QueuePush(1, Data);
+ break;
+ }
+
+ /*
+ * Send a command to the second PS/2 port (by default
+ * it is a command for the first PS/2 port)
+ */
case 0xD4:
{
- MouseCommand(Data);
+ if (Ports[1].IsEnabled)
+ // Ports[1].Function
+ MouseCommand(Data);
+
break;
}
}
@@ -216,156 +250,148 @@
}
// TODO: Implement PS/2 device commands
- }
-}
-
-/* PUBLIC FUNCTIONS ***********************************************************/
-
-BOOLEAN KeyboardQueuePush(BYTE ScanCode)
+ if (Ports[0].IsEnabled)
+ // Ports[0].Function
+ KeyboardCommand(Data);
+ }
+}
+
+static BOOLEAN PS2PortQueueRead(BYTE PS2Port)
{
BOOLEAN Result = TRUE;
-
- WaitForSingleObject(QueueMutex, INFINITE);
-
- /* Check if the keyboard queue is full */
- if (!KeyboardQueueEmpty && (KeyboardQueueStart == KeyboardQueueEnd))
+ PPS2_PORT Port;
+
+ if (PS2Port >= PS2_PORTS) return FALSE;
+ Port = &Ports[PS2Port];
+
+ if (!Port->IsEnabled) return FALSE;
+
+ /* Make sure the queue is not empty (fast check) */
+ if (Port->QueueEmpty) return FALSE;
+
+ WaitForSingleObject(Port->QueueMutex, INFINITE);
+
+ /*
+ * Recheck whether the queue is not empty (it may
+ * have changed after having grabbed the mutex).
+ */
+ if (Port->QueueEmpty)
{
Result = FALSE;
goto Done;
}
- /* Insert the value in the queue */
- KeyboardQueue[KeyboardQueueEnd] = ScanCode;
- KeyboardQueueEnd++;
- KeyboardQueueEnd %= KEYBOARD_BUFFER_SIZE;
-
- /* Since we inserted a value, it's not empty anymore */
- KeyboardQueueEmpty = FALSE;
+ /* Get the data */
+ OutputBuffer = Port->Queue[Port->QueueStart];
+ StatusRegister |= (1 << 0); // There is something to read
+ // Sometimes StatusRegister |= (1 << 5); for the second PS/2 port
+
+ /* Remove the value from the queue */
+ Port->QueueStart++;
+ Port->QueueStart %= BUFFER_SIZE;
+
+ /* Check if the queue is now empty */
+ if (Port->QueueStart == Port->QueueEnd)
+ Port->QueueEmpty = TRUE;
Done:
- ReleaseMutex(QueueMutex);
+ ReleaseMutex(Port->QueueMutex);
return Result;
}
-BOOLEAN KeyboardQueuePop(BYTE *ScanCode)
+/* PUBLIC FUNCTIONS ***********************************************************/
+
+// PS2SendToPort
+BOOLEAN PS2QueuePush(BYTE PS2Port, BYTE Data)
{
BOOLEAN Result = TRUE;
-
- /* Make sure the keyboard queue is not empty (fast check) */
- if (KeyboardQueueEmpty) return FALSE;
-
- WaitForSingleObject(QueueMutex, INFINITE);
-
- /*
- * Recheck whether keyboard queue is not empty (it
- * may have changed after having grabbed the mutex).
- */
- if (KeyboardQueueEmpty)
+ PPS2_PORT Port;
+
+ if (PS2Port >= PS2_PORTS) return FALSE;
+ Port = &Ports[PS2Port];
+
+ if (!Port->IsEnabled) return FALSE;
+
+ WaitForSingleObject(Port->QueueMutex, INFINITE);
+
+ /* Check if the queue is full */
+ if (!Port->QueueEmpty && (Port->QueueStart == Port->QueueEnd))
{
Result = FALSE;
goto Done;
}
- /* Get the scan code */
- *ScanCode = KeyboardQueue[KeyboardQueueStart];
-
- /* Remove the value from the queue */
- KeyboardQueueStart++;
- KeyboardQueueStart %= KEYBOARD_BUFFER_SIZE;
-
- /* Check if the queue is now empty */
- if (KeyboardQueueStart == KeyboardQueueEnd)
- {
- KeyboardQueueEmpty = TRUE;
- }
+ /* Insert the value in the queue */
+ Port->Queue[Port->QueueEnd] = Data;
+ Port->QueueEnd++;
+ Port->QueueEnd %= BUFFER_SIZE;
+
+ /* Since we inserted a value, it's not empty anymore */
+ Port->QueueEmpty = FALSE;
+
+/*
+ // Get the data
+ OutputBuffer = Port->Queue[Port->QueueStart];
+ StatusRegister |= (1 << 0); // There is something to read
+ // FIXME: Sometimes StatusRegister |= (1 << 5); for the second PS/2 port
+
+ if (PS2Port == 0)
+ PicInterruptRequest(1);
+ else if (PS2Port == 1)
+ PicInterruptRequest(12);
+*/
Done:
- ReleaseMutex(QueueMutex);
+ ReleaseMutex(Port->QueueMutex);
return Result;
}
-VOID PS2Dispatch(PINPUT_RECORD InputRecord)
-{
- /* Check the event type */
- switch (InputRecord->EventType)
- {
- case KEY_EVENT:
- {
- WORD i;
- BYTE ScanCode = (BYTE)InputRecord->Event.KeyEvent.wVirtualScanCode;
-
- /* If this is a key release, set the highest bit in the scan code */
- if (!InputRecord->Event.KeyEvent.bKeyDown) ScanCode |= 0x80;
-
- /* Push the scan code onto the keyboard queue */
- for (i = 0; i < InputRecord->Event.KeyEvent.wRepeatCount; i++)
- {
- KeyboardQueuePush(ScanCode);
- }
-
- break;
- }
-
- case MOUSE_EVENT:
- {
- /* Notify the BIOS driver */
-
MouseBiosUpdatePosition(&InputRecord->Event.MouseEvent.dwMousePosition);
-
MouseBiosUpdateButtons(LOWORD(InputRecord->Event.MouseEvent.dwButtonState));
-
- // TODO: PS/2, other stuff
-
- break;
- }
-
- /* We ignore all the rest */
- default:
- break;
- }
-}
-
-VOID GenerateKeyboardInterrupts(VOID)
-{
- /* Generate an IRQ 1 if there is a key ready in the queue */
- if (KeyboardQueuePop(&KeyboardData)) PicInterruptRequest(1);
-}
-
-BOOLEAN PS2Initialize(HANDLE ConsoleInput)
-{
- DWORD ConInMode;
-
- /* Create the mutex */
- QueueMutex = CreateMutex(NULL, FALSE, NULL);
+VOID GenerateIrq1(VOID)
+{
+ /* Generate an interrupt if interrupts for the first PS/2 port are enabled */
+ if (ControllerConfig & 0x01)
+ {
+ /* Generate an IRQ 1 if there is data ready in the output queue */
+ if (PS2PortQueueRead(0)) PicInterruptRequest(1);
+ }
+}
+
+VOID GenerateIrq12(VOID)
+{
+ /* Generate an interrupt if interrupts for the second PS/2 port are enabled */
+ if (ControllerConfig & 0x02)
+ {
+ /* Generate an IRQ 12 if there is data ready in the output queue */
+ if (PS2PortQueueRead(1)) PicInterruptRequest(12);
+ }
+}
+
+BOOLEAN PS2Initialize(VOID)
+{
+ /* Initialize the PS/2 ports */
+ Ports[0].IsEnabled = TRUE;
+ 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].QueueEmpty = TRUE;
+ Ports[1].QueueStart = 0;
+ Ports[1].QueueEnd = 0;
+ Ports[1].QueueMutex = CreateMutex(NULL, FALSE, NULL);
/* Register the I/O Ports */
RegisterIoPort(PS2_CONTROL_PORT, PS2ReadPort, PS2WritePort);
RegisterIoPort(PS2_DATA_PORT , PS2ReadPort, PS2WritePort);
- 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);
- }
-
return TRUE;
}
VOID PS2Cleanup(VOID)
{
- CloseHandle(QueueMutex);
+ CloseHandle(Ports[1].QueueMutex);
+ CloseHandle(Ports[0].QueueMutex);
}
/* EOF */
Modified: trunk/reactos/subsystems/ntvdm/hardware/ps2.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/ntvdm/hardware/…
==============================================================================
--- trunk/reactos/subsystems/ntvdm/hardware/ps2.h [iso-8859-1] (original)
+++ trunk/reactos/subsystems/ntvdm/hardware/ps2.h [iso-8859-1] Tue Sep 16 00:51:15 2014
@@ -4,6 +4,7 @@
* FILE: ps2.h
* PURPOSE: PS/2 controller emulation
* PROGRAMMERS: Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
+ * Hermes Belusca-Maito (hermes.belusca(a)sfr.fr)
*/
#ifndef _PS2_H_
@@ -15,21 +16,17 @@
/* DEFINES ********************************************************************/
-#define KEYBOARD_BUFFER_SIZE 32
-#define PS2_DATA_PORT 0x60
-#define PS2_CONTROL_PORT 0x64
-#define PS2_DEFAULT_CONFIG 0x05
-#define KEYBOARD_ACK 0xFA
-#define KEYBOARD_RESEND 0xFE
+#define PS2_DATA_PORT 0x60
+#define PS2_CONTROL_PORT 0x64
/* FUNCTIONS ******************************************************************/
-BOOLEAN KeyboardQueuePush(BYTE ScanCode);
-BOOLEAN KeyboardQueuePop(BYTE *ScanCode);
-VOID PS2Dispatch(PINPUT_RECORD InputRecord);
-VOID GenerateKeyboardInterrupts(VOID);
+BOOLEAN PS2QueuePush(BYTE PS2Port, BYTE Data);
-BOOLEAN PS2Initialize(HANDLE ConsoleInput);
+VOID GenerateIrq1(VOID);
+VOID GenerateIrq12(VOID);
+
+BOOLEAN PS2Initialize(VOID);
VOID PS2Cleanup(VOID);
#endif // _PS2_H_
Modified: trunk/reactos/subsystems/ntvdm/hardware/vga.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/ntvdm/hardware/…
==============================================================================
--- trunk/reactos/subsystems/ntvdm/hardware/vga.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/ntvdm/hardware/vga.c [iso-8859-1] Tue Sep 16 00:51:15 2014
@@ -1917,6 +1917,11 @@
+VOID ScreenEventHandler(PWINDOW_BUFFER_SIZE_RECORD ScreenEvent)
+{
+ DPRINT1("Screen events not handled\n");
+}
+
BOOL VgaAttachToConsole(VOID)
{
//
Modified: trunk/reactos/subsystems/ntvdm/hardware/vga.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/ntvdm/hardware/…
==============================================================================
--- trunk/reactos/subsystems/ntvdm/hardware/vga.h [iso-8859-1] (original)
+++ trunk/reactos/subsystems/ntvdm/hardware/vga.h [iso-8859-1] Tue Sep 16 00:51:15 2014
@@ -250,6 +250,7 @@
/* FUNCTIONS ******************************************************************/
+VOID ScreenEventHandler(PWINDOW_BUFFER_SIZE_RECORD ScreenEvent);
BOOL VgaAttachToConsole(VOID);
VOID VgaDetachFromConsole(BOOL ChangeMode);
Modified: trunk/reactos/subsystems/ntvdm/ntvdm.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/ntvdm/ntvdm.c?r…
==============================================================================
--- trunk/reactos/subsystems/ntvdm/ntvdm.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/ntvdm/ntvdm.c [iso-8859-1] Tue Sep 16 00:51:15 2014
@@ -328,69 +328,32 @@
if (ConsoleInput != INVALID_HANDLE_VALUE) CloseHandle(ConsoleInput);
}
-DWORD
-WINAPI
-PumpConsoleInput(LPVOID Parameter)
-{
- HANDLE ConsoleInput = (HANDLE)Parameter;
- INPUT_RECORD InputRecord;
- DWORD Count;
-
- while (VdmRunning)
- {
- /* Make sure the task event is signaled */
- WaitForSingleObject(VdmTaskEvent, INFINITE);
-
- /* Wait for an input record */
- if (!ReadConsoleInput(ConsoleInput, &InputRecord, 1, &Count))
- {
- DWORD LastError = GetLastError();
- DPRINT1("Error reading console input (0x%p, %lu) - Error %lu\n",
ConsoleInput, Count, LastError);
- return LastError;
- }
-
- ASSERT(Count != 0);
-
- /* Check the event type */
- switch (InputRecord.EventType)
- {
- case KEY_EVENT:
- case MOUSE_EVENT:
- /* Send it to the PS/2 controller */
- PS2Dispatch(&InputRecord);
- break;
-
- case MENU_EVENT:
- {
- switch (InputRecord.Event.MenuEvent.dwCommandId)
- {
- case ID_SHOWHIDE_MOUSE:
- ShowHideMousePointer(ConsoleOutput, ShowPointer);
- ShowPointer = !ShowPointer;
- break;
-
- case ID_VDM_DUMPMEM:
- DumpMemory();
- break;
-
- case ID_VDM_QUIT:
- /* Stop the VDM */
- EmulatorTerminate();
- break;
-
- default:
- break;
- }
-
- break;
- }
-
- default:
- break;
- }
- }
-
- return 0;
+VOID MenuEventHandler(PMENU_EVENT_RECORD MenuEvent)
+{
+ switch (MenuEvent->dwCommandId)
+ {
+ case ID_SHOWHIDE_MOUSE:
+ ShowHideMousePointer(ConsoleOutput, ShowPointer);
+ ShowPointer = !ShowPointer;
+ break;
+
+ case ID_VDM_DUMPMEM:
+ DumpMemory();
+ break;
+
+ case ID_VDM_QUIT:
+ /* Stop the VDM */
+ EmulatorTerminate();
+ break;
+
+ default:
+ break;
+ }
+}
+
+VOID FocusEventHandler(PFOCUS_EVENT_RECORD FocusEvent)
+{
+ DPRINT1("Focus events not handled\n");
}
#ifndef STANDALONE
Modified: trunk/reactos/subsystems/ntvdm/ntvdm.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/ntvdm/ntvdm.h?r…
==============================================================================
--- trunk/reactos/subsystems/ntvdm/ntvdm.h [iso-8859-1] (original)
+++ trunk/reactos/subsystems/ntvdm/ntvdm.h [iso-8859-1] Tue Sep 16 00:51:15 2014
@@ -46,6 +46,9 @@
extern HANDLE VdmTaskEvent;
+/*
+ * Interface functions
+ */
VOID DisplayMessage(LPCWSTR Format, ...);
/*static*/ VOID
@@ -53,6 +56,9 @@
/*static*/ VOID
DestroyVdmMenu(VOID);
+VOID MenuEventHandler(PMENU_EVENT_RECORD MenuEvent);
+VOID FocusEventHandler(PFOCUS_EVENT_RECORD FocusEvent);
+
#endif // _NTVDM_H_
/* EOF */