- Add new unified VGA/VBE miniport driver. Based on NT4 DDK Cirrus Miniport Driver...
authorevb <evb@svn.reactos.org>
Fri, 5 Mar 2010 17:22:18 +0000 (17:22 +0000)
committerevb <evb@svn.reactos.org>
Fri, 5 Mar 2010 17:22:18 +0000 (17:22 +0000)
- Work-in-progress, can boot to GUI with VMWare, but banked modes not yet supported, no VDM, no Mode-X, etc...
- Thanks to sir_richard for help with headers, comments and other English stuff.
- Driver is only built, not yet used.
- NOTE: Some parts of BootVid seem to use functions copied from this sample (VgaInterpretCmdStream) but under "GPL", and also buggy (Chain4 Mode test will not work on most cards and VgaIsPresent == FALSE). Someone should fix.

svn path=/trunk/; revision=45873

reactos/drivers/video/miniport/directory.rbuild
reactos/drivers/video/miniport/vga_new/cmdcnst.h [new file with mode: 0644]
reactos/drivers/video/miniport/vga_new/modeset.c [new file with mode: 0644]
reactos/drivers/video/miniport/vga_new/vbe.c [new file with mode: 0644]
reactos/drivers/video/miniport/vga_new/vbe.h [new file with mode: 0644]
reactos/drivers/video/miniport/vga_new/vbemodes.c [new file with mode: 0644]
reactos/drivers/video/miniport/vga_new/vga.c [new file with mode: 0644]
reactos/drivers/video/miniport/vga_new/vga.h [new file with mode: 0644]
reactos/drivers/video/miniport/vga_new/vga.rbuild [new file with mode: 0644]
reactos/drivers/video/miniport/vga_new/vga.rc [new file with mode: 0644]
reactos/drivers/video/miniport/vga_new/vgadata.c [new file with mode: 0644]

index 2575e1a..b61f80c 100644 (file)
@@ -1,11 +1,8 @@
 <?xml version="1.0"?>
 <!DOCTYPE group SYSTEM "../../../tools/rbuild/project.dtd">
 <group xmlns:xi="http://www.w3.org/2001/XInclude">
-       <directory name="vbe">
-               <xi:include href="vbe/vbemp.rbuild" />
-       </directory>
-       <directory name="vga">
-               <xi:include href="vga/vgamp.rbuild" />
+       <directory name="vga_new">
+               <xi:include href="vga_new/vga.rbuild" />
        </directory>
        <directory name="vmx_svga">
                <xi:include href="vmx_svga/vmx_svga.rbuild" />
diff --git a/reactos/drivers/video/miniport/vga_new/cmdcnst.h b/reactos/drivers/video/miniport/vga_new/cmdcnst.h
new file mode 100644 (file)
index 0000000..c818b49
--- /dev/null
@@ -0,0 +1,92 @@
+/*
+ * PROJECT:         ReactOS VGA Miniport Driver
+ * LICENSE:         Microsoft NT4 DDK Sample Code License
+ * FILE:            boot/drivers/video/miniport/vga/cmdcnst.h
+ * PURPOSE:         Command Code Definitions for VGA Command Streams
+ * PROGRAMMERS:     Copyright (c) 1992  Microsoft Corporation
+ */
+
+//--------------------------------------------------------------------------
+//   Definition of the set/clear mode command language.
+//
+//   Each command is composed of a major portion and a minor portion.
+//   The major portion of a command can be found in the most significant
+//   nibble of a command byte, while the minor portion is in the least
+//   significant portion of a command byte.
+//
+//   maj  minor      Description
+//   ---- -----      --------------------------------------------
+//   00              End of data
+//
+//   10              in and out type commands as described by flags
+//        flags:
+//
+//        xxxx
+//        ||||
+//        |||+-------- unused
+//        ||+--------- 0/1 single/multiple values to output (in's are always 
+//        |+---------- 0/1 8/16 bit operation                  single)
+//        +----------- 0/1 out/in instruction
+//
+//       Outs
+//       ----------------------------------------------
+//       0           reg:W val:B
+//       2           reg:W cnt:W val1:B val2:B...valN:B
+//       4           reg:W val:W
+//       6           reg:W cnt:W val1:W val2:W...valN:W
+//
+//       Ins
+//       ----------------------------------------------
+//       8           reg:W
+//       a           reg:W cnt:W
+//       c           reg:W
+//       e           reg:W cnt:W
+//
+//   20              Special purpose outs
+//       00          do indexed outs for seq, crtc, and gdc
+//                   indexreg:W cnt:B startindex:B val1:B val2:B...valN:B
+//       01          do indexed outs for atc
+//                   index-data_reg:W cnt:B startindex:B val1:B val2:B...valN:B
+//       02          do masked outs
+//                   indexreg:W andmask:B xormask:B
+//
+//   F0              Nop
+//
+//---------------------------------------------------------------------------
+
+// some useful equates - major commands
+
+#define EOD     0x000                   // end of data
+#define INOUT   0x010                   // do ins or outs
+#define METAOUT 0x020                   // do special types of outs
+#define NCMD    0x0f0                   // Nop command
+
+
+// flags for INOUT major command
+
+//#define UNUSED    0x01                    // reserved
+#define MULTI   0x02                    // multiple or single outs
+#define BW      0x04                    // byte/word size of operation
+#define IO      0x08                    // out/in instruction
+
+// minor commands for metout
+
+#define INDXOUT 0x00                    // do indexed outs
+#define ATCOUT  0x01                    // do indexed outs for atc
+#define MASKOUT 0x02                    // do masked outs using and-xor masks
+
+
+// composite inout type commands
+
+#define OB      (INOUT)                 // output 8 bit value
+#define OBM     (INOUT+MULTI)           // output multiple bytes
+#define OW      (INOUT+BW)              // output single word value
+#define OWM     (INOUT+BW+MULTI)        // output multiple words
+
+#define IB      (INOUT+IO)              // input byte
+#define IBM     (INOUT+IO+MULTI)        // input multiple bytes
+#define IW      (INOUT+IO+BW)           // input word
+#define IWM     (INOUT+IO+BW+MULTI)     // input multiple words
+/* EOF */
diff --git a/reactos/drivers/video/miniport/vga_new/modeset.c b/reactos/drivers/video/miniport/vga_new/modeset.c
new file mode 100644 (file)
index 0000000..83c0001
--- /dev/null
@@ -0,0 +1,747 @@
+/*
+ * PROJECT:         ReactOS VGA Miniport Driver
+ * LICENSE:         Microsoft NT4 DDK Sample Code License
+ * FILE:            boot/drivers/video/miniport/vga/modeset.c
+ * PURPOSE:         Handles switching to Standard VGA Modes for compatible cards
+ * PROGRAMMERS:     Copyright (c) 1992  Microsoft Corporation
+ *                  ReactOS Portable Systems Group
+ */
+
+#include "vga.h"
+
+VP_STATUS
+VgaInterpretCmdStream(
+    PHW_DEVICE_EXTENSION HwDeviceExtension,
+    PUSHORT pusCmdStream
+    );
+
+VP_STATUS
+VgaSetMode(
+    PHW_DEVICE_EXTENSION HwDeviceExtension,
+    PVIDEO_MODE Mode,
+    ULONG ModeSize,
+// eVb: 2.1 [SET MODE] - Add new output parameter for framebuffer update functionality
+    PULONG PhysPtrChange
+// eVb: 2.1 [END]
+    );
+
+VP_STATUS
+VgaQueryAvailableModes(
+    PHW_DEVICE_EXTENSION HwDeviceExtension,
+    PVIDEO_MODE_INFORMATION ModeInformation,
+    ULONG ModeInformationSize,
+    PULONG OutputSize
+    );
+
+VP_STATUS
+VgaQueryNumberOfAvailableModes(
+    PHW_DEVICE_EXTENSION HwDeviceExtension,
+    PVIDEO_NUM_MODES NumModes,
+    ULONG NumModesSize,
+    PULONG OutputSize
+    );
+
+VOID
+VgaZeroVideoMemory(
+    PHW_DEVICE_EXTENSION HwDeviceExtension
+    );
+
+#if defined(ALLOC_PRAGMA)
+#pragma alloc_text(PAGE,VgaInterpretCmdStream)
+#pragma alloc_text(PAGE,VgaSetMode)
+#pragma alloc_text(PAGE,VgaQueryAvailableModes)
+#pragma alloc_text(PAGE,VgaQueryNumberOfAvailableModes)
+#pragma alloc_text(PAGE,VgaZeroVideoMemory)
+#endif
+
+//---------------------------------------------------------------------------
+VP_STATUS
+VgaInterpretCmdStream(
+    PHW_DEVICE_EXTENSION HwDeviceExtension,
+    PUSHORT pusCmdStream
+    )
+
+/*++
+
+Routine Description:
+
+    Interprets the appropriate command array to set up VGA registers for the
+    requested mode. Typically used to set the VGA into a particular mode by
+    programming all of the registers
+
+Arguments:
+
+    HwDeviceExtension - Pointer to the miniport driver's device extension.
+
+    pusCmdStream - array of commands to be interpreted.
+
+Return Value:
+
+    The status of the operation (can only fail on a bad command); TRUE for
+    success, FALSE for failure.
+
+--*/
+
+{
+    ULONG ulCmd;
+    ULONG ulPort;
+    UCHAR jValue;
+    USHORT usValue;
+    ULONG culCount;
+    ULONG ulIndex;
+    ULONG ulBase;
+
+    if (pusCmdStream == NULL) {
+
+        VideoDebugPrint((1, "VgaInterpretCmdStream - Invalid pusCmdStream\n"));
+        return TRUE;
+    }
+
+    ulBase = (ULONG)HwDeviceExtension->IOAddress;
+
+    //
+    // Now set the adapter to the desired mode.
+    //
+
+    while ((ulCmd = *pusCmdStream++) != EOD) {
+
+        //
+        // Determine major command type
+        //
+
+        switch (ulCmd & 0xF0) {
+
+            //
+            // Basic input/output command
+            //
+
+            case INOUT:
+
+                //
+                // Determine type of inout instruction
+                //
+
+                if (!(ulCmd & IO)) {
+
+                    //
+                    // Out instruction. Single or multiple outs?
+                    //
+
+                    if (!(ulCmd & MULTI)) {
+
+                        //
+                        // Single out. Byte or word out?
+                        //
+
+                        if (!(ulCmd & BW)) {
+
+                            //
+                            // Single byte out
+                            //
+
+                            ulPort = *pusCmdStream++;
+                            jValue = (UCHAR) *pusCmdStream++;
+                            VideoPortWritePortUchar((PUCHAR)(ulBase+ulPort),
+                                    jValue);
+
+                        } else {
+
+                            //
+                            // Single word out
+                            //
+
+                            ulPort = *pusCmdStream++;
+                            usValue = *pusCmdStream++;
+                            VideoPortWritePortUshort((PUSHORT)(ulBase+ulPort),
+                                    usValue);
+
+                        }
+
+                    } else {
+
+                        //
+                        // Output a string of values
+                        // Byte or word outs?
+                        //
+
+                        if (!(ulCmd & BW)) {
+
+                            //
+                            // String byte outs. Do in a loop; can't use
+                            // VideoPortWritePortBufferUchar because the data
+                            // is in USHORT form
+                            //
+
+                            ulPort = ulBase + *pusCmdStream++;
+                            culCount = *pusCmdStream++;
+
+                            while (culCount--) {
+                                jValue = (UCHAR) *pusCmdStream++;
+                                VideoPortWritePortUchar((PUCHAR)ulPort,
+                                        jValue);
+
+                            }
+
+                        } else {
+
+                            //
+                            // String word outs
+                            //
+
+                            ulPort = *pusCmdStream++;
+                            culCount = *pusCmdStream++;
+                            VideoPortWritePortBufferUshort((PUSHORT)
+                                    (ulBase + ulPort), pusCmdStream, culCount);
+                            pusCmdStream += culCount;
+
+                        }
+                    }
+
+                } else {
+
+                    // In instruction
+                    //
+                    // Currently, string in instructions aren't supported; all
+                    // in instructions are handled as single-byte ins
+                    //
+                    // Byte or word in?
+                    //
+
+                    if (!(ulCmd & BW)) {
+                        //
+                        // Single byte in
+                        //
+
+                        ulPort = *pusCmdStream++;
+                        jValue = VideoPortReadPortUchar((PUCHAR)ulBase+ulPort);
+
+                    } else {
+
+                        //
+                        // Single word in
+                        //
+
+                        ulPort = *pusCmdStream++;
+                        usValue = VideoPortReadPortUshort((PUSHORT)
+                                (ulBase+ulPort));
+
+                    }
+
+                }
+
+                break;
+
+            //
+            // Higher-level input/output commands
+            //
+
+            case METAOUT:
+
+                //
+                // Determine type of metaout command, based on minor
+                // command field
+                //
+                switch (ulCmd & 0x0F) {
+
+                    //
+                    // Indexed outs
+                    //
+
+                    case INDXOUT:
+
+                        ulPort = ulBase + *pusCmdStream++;
+                        culCount = *pusCmdStream++;
+                        ulIndex = *pusCmdStream++;
+
+                        while (culCount--) {
+
+                            usValue = (USHORT) (ulIndex +
+                                      (((ULONG)(*pusCmdStream++)) << 8));
+                            VideoPortWritePortUshort((PUSHORT)ulPort, usValue);
+
+                            ulIndex++;
+
+                        }
+
+                        break;
+
+                    //
+                    // Masked out (read, AND, XOR, write)
+                    //
+
+                    case MASKOUT:
+
+                        ulPort = *pusCmdStream++;
+                        jValue = VideoPortReadPortUchar((PUCHAR)ulBase+ulPort);
+                        jValue &= *pusCmdStream++;
+                        jValue ^= *pusCmdStream++;
+                        VideoPortWritePortUchar((PUCHAR)ulBase + ulPort,
+                                jValue);
+                        break;
+
+                    //
+                    // Attribute Controller out
+                    //
+
+                    case ATCOUT:
+
+                        ulPort = ulBase + *pusCmdStream++;
+                        culCount = *pusCmdStream++;
+                        ulIndex = *pusCmdStream++;
+
+                        while (culCount--) {
+
+                            // Write Attribute Controller index
+                            VideoPortWritePortUchar((PUCHAR)ulPort,
+                                    (UCHAR)ulIndex);
+
+                            // Write Attribute Controller data
+                            jValue = (UCHAR) *pusCmdStream++;
+                            VideoPortWritePortUchar((PUCHAR)ulPort, jValue);
+
+                            ulIndex++;
+
+                        }
+
+                        break;
+
+                    //
+                    // None of the above; error
+                    //
+                    default:
+
+                        return FALSE;
+
+                }
+
+
+                break;
+
+            //
+            // NOP
+            //
+
+            case NCMD:
+
+                break;
+
+            //
+            // Unknown command; error
+            //
+
+            default:
+
+                return FALSE;
+
+        }
+
+    }
+
+    return TRUE;
+
+} // end VgaInterpretCmdStream()
+
+\f
+VP_STATUS
+VgaSetMode(
+    PHW_DEVICE_EXTENSION HwDeviceExtension,
+    PVIDEO_MODE Mode,
+    ULONG ModeSize,
+// eVb: 2.2 [SET MODE] - Add new output parameter for framebuffer update functionality
+    PULONG PhysPtrChange
+// eVb: 2.2 [END]
+    )
+
+/*++
+
+Routine Description:
+
+    This routine sets the vga into the requested mode.
+
+Arguments:
+
+    HwDeviceExtension - Pointer to the miniport driver's device extension.
+
+    Mode - Pointer to the structure containing the information about the
+        font to be set.
+
+    ModeSize - Length of the input buffer supplied by the user.
+
+Return Value:
+
+    ERROR_INSUFFICIENT_BUFFER if the input buffer was not large enough
+        for the input data.
+
+    ERROR_INVALID_PARAMETER if the mode number is invalid.
+
+    NO_ERROR if the operation completed successfully.
+
+--*/
+
+{
+    PVIDEOMODE pRequestedMode;
+    VP_STATUS status;
+    ULONG RequestedModeNum;
+// eVb: 2.3 [SET MODE] - Add new output parameter for framebuffer update functionality
+    *PhysPtrChange = FALSE;
+// eVb: 2.3 [END]
+    //
+    // Check if the size of the data in the input buffer is large enough.
+    //
+
+    if (ModeSize < sizeof(VIDEO_MODE))
+    {
+        return ERROR_INSUFFICIENT_BUFFER;
+    }
+
+    //
+    // Extract the clear memory, and map linear bits.
+    //
+
+    RequestedModeNum = Mode->RequestedMode &
+        ~(VIDEO_MODE_NO_ZERO_MEMORY | VIDEO_MODE_MAP_MEM_LINEAR);
+
+
+    if (!(Mode->RequestedMode & VIDEO_MODE_NO_ZERO_MEMORY))
+    {
+#if defined(_X86_)
+        VgaZeroVideoMemory(HwDeviceExtension);
+#endif
+    }
+
+    //
+    // Check to see if we are requesting a valid mode
+    //
+// eVb: 2.4 [CIRRUS] - Remove Cirrus-specific check for valid mode
+    if ( (RequestedModeNum >= NumVideoModes) )
+// eVb: 2.4 [END]
+    {
+        VideoDebugPrint((0, "Invalide Mode Number = %d!\n", RequestedModeNum));
+
+        return ERROR_INVALID_PARAMETER;
+    }
+
+    VideoDebugPrint((2, "Attempting to set mode %d\n",
+                        RequestedModeNum));
+// eVb: 2.5 [VBE] - Use dynamic VBE mode list instead of hard-coded VGA list
+    pRequestedMode = &VgaModeList[RequestedModeNum];
+// eVb: 2.5 [END]
+    VideoDebugPrint((2, "Info on Requested Mode:\n"
+                        "\tResolution: %dx%d\n",
+                        pRequestedMode->hres,
+                        pRequestedMode->vres ));
+
+    //
+    // VESA BIOS mode switch
+    //
+// eVb: 2.6 [VBE] - VBE Mode Switch Support 
+    status = VbeSetMode(HwDeviceExtension, pRequestedMode, PhysPtrChange);
+    if (status == ERROR_INVALID_FUNCTION)
+    {
+        //
+        // VGA mode switch
+        //
+
+        if (!pRequestedMode->CmdStream) return ERROR_INVALID_FUNCTION;
+        if (!VgaInterpretCmdStream(HwDeviceExtension, pRequestedMode->CmdStream)) return ERROR_INVALID_FUNCTION;
+        goto Cleanup;
+    }
+    else if (status != NO_ERROR) return status;
+// eVb: 2.6 [END]
+// eVb: 2.7 [MODE-X] - Windows VGA Miniport Supports Mode-X, we should too
+    //
+    // ModeX check
+    //
+    
+    if (pRequestedMode->hres == 320)
+    {
+        VideoPortDebugPrint(0, "ModeX not support!!!\n");
+        return ERROR_INVALID_PARAMETER;
+    }
+// eVb: 2.7 [END]
+    //
+    // Text mode check
+    //
+    
+    if (!(pRequestedMode->fbType & VIDEO_MODE_GRAPHICS))
+    {
+// eVb: 2.8 [TODO] - This code path is not implemented yet
+        VideoPortDebugPrint(0, "Text-mode not support!!!\n");
+        return ERROR_INVALID_PARAMETER;
+// eVb: 2.8 [END]
+    }
+
+Cleanup:
+    //
+    // Update the location of the physical frame buffer within video memory.
+    //
+// eVb: 2.9 [VBE] - Linear and banked support is unified in VGA, unlike Cirrus
+    HwDeviceExtension->PhysicalVideoMemoryBase.LowPart = pRequestedMode->PhysBase;
+    HwDeviceExtension->PhysicalVideoMemoryLength = pRequestedMode->PhysSize;
+
+    HwDeviceExtension->PhysicalFrameLength =
+            pRequestedMode->FrameBufferSize;
+
+    HwDeviceExtension->PhysicalFrameOffset.LowPart =
+            pRequestedMode->FrameBufferBase;
+// eVb: 2.9 [END]
+
+    //
+    // Store the new mode value.
+    //
+
+    HwDeviceExtension->CurrentMode = pRequestedMode;
+    HwDeviceExtension->ModeIndex = Mode->RequestedMode;
+
+    return NO_ERROR;
+
+} //end VgaSetMode()
+\f
+VP_STATUS
+VgaQueryAvailableModes(
+    PHW_DEVICE_EXTENSION HwDeviceExtension,
+    PVIDEO_MODE_INFORMATION ModeInformation,
+    ULONG ModeInformationSize,
+    PULONG OutputSize
+    )
+
+/*++
+
+Routine Description:
+
+    This routine returns the list of all available available modes on the
+    card.
+
+Arguments:
+
+    HwDeviceExtension - Pointer to the miniport driver's device extension.
+
+    ModeInformation - Pointer to the output buffer supplied by the user.
+        This is where the list of all valid modes is stored.
+
+    ModeInformationSize - Length of the output buffer supplied by the user.
+
+    OutputSize - Pointer to a buffer in which to return the actual size of
+        the data in the buffer. If the buffer was not large enough, this
+        contains the minimum required buffer size.
+
+Return Value:
+
+    ERROR_INSUFFICIENT_BUFFER if the output buffer was not large enough
+        for the data being returned.
+
+    NO_ERROR if the operation completed successfully.
+
+--*/
+
+{
+    PVIDEO_MODE_INFORMATION videoModes = ModeInformation;
+    ULONG i;
+
+    //
+    // Find out the size of the data to be put in the buffer and return
+    // that in the status information (whether or not the information is
+    // there). If the buffer passed in is not large enough return an
+    // appropriate error code.
+    //
+
+    if (ModeInformationSize < (*OutputSize =
+// eVb: 2.10 [VBE] - We store VBE/VGA mode count in this global, not in DevExt like Cirrus
+            NumVideoModes *
+// eVb: 2.10 [END]
+            sizeof(VIDEO_MODE_INFORMATION)) ) {
+
+        return ERROR_INSUFFICIENT_BUFFER;
+
+    }
+
+    //
+    // For each mode supported by the card, store the mode characteristics
+    // in the output buffer.
+    //
+
+    for (i = 0; i < NumVideoModes; i++)
+    {
+        videoModes->Length = sizeof(VIDEO_MODE_INFORMATION);
+        videoModes->ModeIndex  = i;
+// eVb: 2.11 [VBE] - Use dynamic VBE mode list instead of hard-coded VGA list
+        videoModes->VisScreenWidth = VgaModeList[i].hres;
+        videoModes->ScreenStride = VgaModeList[i].wbytes;
+        videoModes->VisScreenHeight = VgaModeList[i].vres;
+        videoModes->NumberOfPlanes = VgaModeList[i].numPlanes;
+        videoModes->BitsPerPlane = VgaModeList[i].bitsPerPlane;
+        videoModes->Frequency = VgaModeList[i].Frequency;
+        videoModes->XMillimeter = 320;        // temporary hardcoded constant
+        videoModes->YMillimeter = 240;        // temporary hardcoded constant
+        videoModes->AttributeFlags = VgaModeList[i].fbType;
+// eVb: 2.11 [END]
+
+        if ((VgaModeList[i].bitsPerPlane == 32) ||
+            (VgaModeList[i].bitsPerPlane == 24))
+        {
+
+            videoModes->NumberRedBits = 8;
+            videoModes->NumberGreenBits = 8;
+            videoModes->NumberBlueBits = 8;
+            videoModes->RedMask = 0xff0000;
+            videoModes->GreenMask = 0x00ff00;
+            videoModes->BlueMask = 0x0000ff;
+
+        }
+        else if (VgaModeList[i].bitsPerPlane == 16)
+        {
+
+            videoModes->NumberRedBits = 6;
+            videoModes->NumberGreenBits = 6;
+            videoModes->NumberBlueBits = 6;
+            videoModes->RedMask = 0x1F << 11;
+            videoModes->GreenMask = 0x3F << 5;
+            videoModes->BlueMask = 0x1F;
+
+        }
+// eVb: 2.12 [VGA] - Add support for 15bpp modes, which Cirrus doesn't support
+        else if (VgaModeList[i].bitsPerPlane == 15)
+        {
+
+            videoModes->NumberRedBits = 6;
+            videoModes->NumberGreenBits = 6;
+            videoModes->NumberBlueBits = 6;
+            videoModes->RedMask = 0x3E << 9;
+            videoModes->GreenMask = 0x1F << 5;
+            videoModes->BlueMask = 0x1F;
+        }
+// eVb: 2.12 [END]
+        else
+        {
+
+            videoModes->NumberRedBits = 6;
+            videoModes->NumberGreenBits = 6;
+            videoModes->NumberBlueBits = 6;
+            videoModes->RedMask = 0;
+            videoModes->GreenMask = 0;
+            videoModes->BlueMask = 0;
+        }
+
+// eVb: 2.13 [VGA] - All modes are palette managed/driven, unlike Cirrus
+        videoModes->AttributeFlags |= VIDEO_MODE_PALETTE_DRIVEN |
+             VIDEO_MODE_MANAGED_PALETTE;
+// eVb: 2.13 [END]
+        videoModes++;
+
+    }
+
+    return NO_ERROR;
+
+} // end VgaGetAvailableModes()
+\f
+VP_STATUS
+VgaQueryNumberOfAvailableModes(
+    PHW_DEVICE_EXTENSION HwDeviceExtension,
+    PVIDEO_NUM_MODES NumModes,
+    ULONG NumModesSize,
+    PULONG OutputSize
+    )
+
+/*++
+
+Routine Description:
+
+    This routine returns the number of available modes for this particular
+    video card.
+
+Arguments:
+
+    HwDeviceExtension - Pointer to the miniport driver's device extension.
+
+    NumModes - Pointer to the output buffer supplied by the user. This is
+        where the number of modes is stored.
+
+    NumModesSize - Length of the output buffer supplied by the user.
+
+    OutputSize - Pointer to a buffer in which to return the actual size of
+        the data in the buffer.
+
+Return Value:
+
+    ERROR_INSUFFICIENT_BUFFER if the output buffer was not large enough
+        for the data being returned.
+
+    NO_ERROR if the operation completed successfully.
+
+--*/
+
+{
+    //
+    // Find out the size of the data to be put in the the buffer and return
+    // that in the status information (whether or not the information is
+    // there). If the buffer passed in is not large enough return an
+    // appropriate error code.
+    //
+
+    if (NumModesSize < (*OutputSize = sizeof(VIDEO_NUM_MODES)) ) {
+
+        return ERROR_INSUFFICIENT_BUFFER;
+
+    }
+
+    //
+    // Store the number of modes into the buffer.
+    //
+
+// eVb: 2.14 [VBE] - We store VBE/VGA mode count in this global, not in DevExt like Cirrus
+    NumModes->NumModes = NumVideoModes;
+// eVb: 2.14 [END]
+    NumModes->ModeInformationLength = sizeof(VIDEO_MODE_INFORMATION);
+
+    return NO_ERROR;
+
+} // end VgaGetNumberOfAvailableModes()
+\f
+VOID
+VgaZeroVideoMemory(
+    PHW_DEVICE_EXTENSION HwDeviceExtension
+    )
+
+/*++
+
+Routine Description:
+
+    This routine zeros the first 256K on the VGA.
+
+Arguments:
+
+    HwDeviceExtension - Pointer to the miniport driver's device extension.
+
+
+Return Value:
+
+    None.
+
+--*/
+{
+    UCHAR temp;
+
+    //
+    // Map font buffer at A0000
+    //
+
+    VgaInterpretCmdStream(HwDeviceExtension, EnableA000Data);
+
+    //
+    // Enable all planes.
+    //
+
+    VideoPortWritePortUchar(HwDeviceExtension->IOAddress + SEQ_ADDRESS_PORT,
+            IND_MAP_MASK);
+
+    temp = VideoPortReadPortUchar(HwDeviceExtension->IOAddress +
+            SEQ_DATA_PORT) | (UCHAR)0x0F;
+
+    VideoPortWritePortUchar(HwDeviceExtension->IOAddress + SEQ_DATA_PORT,
+            temp);
+
+    VideoPortZeroDeviceMemory(HwDeviceExtension->VideoMemoryAddress, 0xFFFF);
+
+    VgaInterpretCmdStream(HwDeviceExtension, DisableA000Color);
+
+}
diff --git a/reactos/drivers/video/miniport/vga_new/vbe.c b/reactos/drivers/video/miniport/vga_new/vbe.c
new file mode 100644 (file)
index 0000000..a2c593d
--- /dev/null
@@ -0,0 +1,196 @@
+/*
+ * PROJECT:         ReactOS VGA Miniport Driver
+ * LICENSE:         BSD - See COPYING.ARM in the top level directory
+ * FILE:            boot/drivers/video/miniport/vga/vbe.c
+ * PURPOSE:         Main VESA VBE 1.02+ SVGA Miniport Handling Code
+ * PROGRAMMERS:     ReactOS Portable Systems Group
+ */
+
+/* INCLUDES *******************************************************************/
+
+#include "vga.h"
+
+/* GLOBALS ********************************************************************/
+
+static const PCHAR Nv11Board = "NV11 (GeForce2) Board";
+static const PCHAR Nv11Chip = "Chip Rev B2";
+static const PCHAR Nv11Vendor = "NVidia Corporation";
+static const PCHAR IntelBrookdale = "Brookdale-G Graphics Controller";
+static const PCHAR BrokenVesaBiosList[] =
+{
+    "SiS 5597",
+    "MGA-G100",
+    "3Dfx Banshee",
+    "Voodoo3 2000 LC ",
+    "Voodoo3 3000 LC ",
+    "Voodoo4 4500 ",
+    "ArtX I",
+    "ATI S1-370TL"
+};
+
+BOOLEAN g_bIntelBrookdaleBIOS;
+
+/* FUNCTIONS ******************************************************************/
+
+BOOLEAN
+NTAPI
+IsVesaBiosOk(IN PVIDEO_PORT_INT10_INTERFACE Interface,
+             IN ULONG OemRevision,
+             IN PCHAR Vendor,
+             IN PCHAR Product,
+             IN PCHAR Revision)
+{
+    ULONG i;
+    CHAR Version[21];
+    
+    /* If the broken VESA bios found, turn VESA off */
+    VideoPortDebugPrint(0, "Vendor: %s Product: %s Revision: %s (%lx)\n", Vendor, Product, Revision, OemRevision);
+    for (i = 0; i < (sizeof(BrokenVesaBiosList) / sizeof(PCHAR)); i++)
+    {
+        if (!strncmp(Product, BrokenVesaBiosList[i], sizeof(BrokenVesaBiosList[i]))) return FALSE;
+    }
+
+    /* For Brookdale-G (Intel), special hack used */
+    g_bIntelBrookdaleBIOS = !strncmp(Product, IntelBrookdale, sizeof(IntelBrookdale));
+    
+    /* For NVIDIA make sure */
+    if (!(strncmp(Vendor, Nv11Vendor, sizeof(Nv11Vendor))) &&
+        !(strncmp(Product, Nv11Board, sizeof(Nv11Board))) &&
+        !(strncmp(Revision, Nv11Chip, sizeof(Nv11Chip))) &&
+        (OemRevision == 0x311))
+    {
+        /* Read version */
+        if (Interface->Int10ReadMemory(Interface->Context,
+                                       0xC000,
+                                       345,
+                                       Version,
+                                       sizeof(Version))) return FALSE;                                        
+        if (!strncmp(Version, "Version 3.11.01.24N16", sizeof(Version))) return FALSE;
+    }
+    
+    /* VESA ok */
+    //VideoPortDebugPrint(0, "Vesa ok\n");
+    return TRUE;
+}
+
+BOOLEAN
+NTAPI
+ValidateVbeInfo(IN PHW_DEVICE_EXTENSION VgaExtension,
+                IN PVBE_INFO VbeInfo)
+{
+    BOOLEAN VesaBiosOk;
+    PVOID Context;
+    CHAR ProductRevision[80];
+    CHAR OemString[80];
+    CHAR ProductName[80];
+    CHAR VendorName[80];
+    VP_STATUS Status;
+    
+    /* Set default */
+    VesaBiosOk = FALSE;
+    Context = VgaExtension->Int10Interface.Context;
+    
+    /* Check magic and version */
+    if (strncmp(VbeInfo->Info.Signature, "VESA", 4)) return VesaBiosOk;
+    if (VbeInfo->Info.Version < 0x102) return VesaBiosOk;
+
+    /* Read strings */
+    Status = VgaExtension->Int10Interface.Int10ReadMemory(Context,
+                                                          HIWORD(VbeInfo->Info.OemStringPtr),
+                                                          LOWORD(VbeInfo->Info.OemStringPtr),
+                                                          OemString,
+                                                          sizeof(OemString));
+    if (Status != NO_ERROR) return VesaBiosOk;
+    Status = VgaExtension->Int10Interface.Int10ReadMemory(Context,
+                                                          HIWORD(VbeInfo->Info.OemVendorNamePtr),
+                                                          LOWORD(VbeInfo->Info.OemVendorNamePtr),
+                                                          VendorName,
+                                                          sizeof(VendorName));
+    if (Status != NO_ERROR) return VesaBiosOk;
+    Status = VgaExtension->Int10Interface.Int10ReadMemory(Context,
+                                                          HIWORD(VbeInfo->Info.OemProductNamePtr),
+                                                          LOWORD(VbeInfo->Info.OemProductNamePtr),
+                                                          ProductName,
+                                                          sizeof(ProductName));
+    if (Status != NO_ERROR) return VesaBiosOk;
+    Status = VgaExtension->Int10Interface.Int10ReadMemory(Context,
+                                                          HIWORD(VbeInfo->Info.OemProductRevPtr),
+                                                          LOWORD(VbeInfo->Info.OemProductRevPtr),
+                                                          ProductRevision,
+                                                          sizeof(ProductRevision));
+    if (Status != NO_ERROR) return VesaBiosOk;
+
+    /* Null-terminate strings */
+    VendorName[sizeof(OemString) - 1] = ANSI_NULL;
+    ProductName[sizeof(OemString) - 1] = ANSI_NULL;
+    ProductRevision[sizeof(OemString) - 1] = ANSI_NULL;
+    OemString[sizeof(OemString) - 1] = ANSI_NULL;
+                
+    /* Check for known bad BIOS */
+    VesaBiosOk = IsVesaBiosOk(&VgaExtension->Int10Interface,
+                              VbeInfo->Info.OemSoftwareRevision,
+                              VendorName,
+                              ProductName,
+                              ProductRevision);        
+    VgaExtension->VesaBiosOk = VesaBiosOk;
+    return VesaBiosOk;
+}
+
+VP_STATUS
+NTAPI
+VbeSetColorLookup(IN PHW_DEVICE_EXTENSION VgaExtension,
+                  IN PVIDEO_CLUT ClutBuffer)
+{
+    PVBE_COLOR_REGISTER VesaClut;
+    INT10_BIOS_ARGUMENTS BiosArguments;
+    PVOID Context;
+    ULONG Entries;
+    ULONG BufferSize = 4 * 1024;
+    USHORT TrampolineMemorySegment, TrampolineMemoryOffset;
+    VP_STATUS Status;
+    USHORT i;
+
+    Entries = ClutBuffer->NumEntries;
+      
+    /* Allocate INT10 context/buffer */
+    VesaClut = VideoPortAllocatePool(VgaExtension, 1, sizeof(ULONG) * Entries, 0x20616756u);
+    if (!VesaClut) return ERROR_INVALID_PARAMETER;
+    if (!VgaExtension->Int10Interface.Size) return ERROR_INVALID_PARAMETER;
+    Context = VgaExtension->Int10Interface.Context;
+    Status = VgaExtension->Int10Interface.Int10AllocateBuffer(Context,
+                                                            &TrampolineMemorySegment,
+                                                            &TrampolineMemoryOffset,
+                                                            &BufferSize);
+    if (Status != NO_ERROR) return ERROR_INVALID_PARAMETER;
+
+    /* VESA has color registers backward! */
+    for (i = 0; i < Entries; i++)
+    {
+        VesaClut[i].Blue = ClutBuffer->LookupTable[i].RgbArray.Blue;
+        VesaClut[i].Green = ClutBuffer->LookupTable[i].RgbArray.Green;
+        VesaClut[i].Red = ClutBuffer->LookupTable[i].RgbArray.Red;
+        VesaClut[i].Pad = 0;
+    }
+    Status = VgaExtension->Int10Interface.Int10WriteMemory(Context,
+                                                         TrampolineMemorySegment,
+                                                         TrampolineMemoryOffset,
+                                                         VesaClut,
+                                                         Entries * sizeof(ULONG));
+    if (Status != NO_ERROR) return ERROR_INVALID_PARAMETER;
+
+    /* Write new palette */                                                      
+    BiosArguments.Ebx = 0;
+    BiosArguments.Ecx = Entries;
+    BiosArguments.Edx = ClutBuffer->FirstEntry;
+    BiosArguments.Edi = TrampolineMemoryOffset;
+    BiosArguments.SegEs = TrampolineMemorySegment;
+    BiosArguments.Eax = VBE_SET_GET_PALETTE_DATA;
+    Status = VgaExtension->Int10Interface.Int10CallBios(Context, &BiosArguments);
+    if (Status != NO_ERROR) return ERROR_INVALID_PARAMETER;
+    VideoPortFreePool(VgaExtension, VesaClut);
+    VideoPortDebugPrint(Error, "VBE Status: %lx\n", BiosArguments.Eax);
+    if (BiosArguments.Eax == VBE_SUCCESS) return NO_ERROR;
+    return ERROR_INVALID_PARAMETER;
+}
+
+/* EOF */
diff --git a/reactos/drivers/video/miniport/vga_new/vbe.h b/reactos/drivers/video/miniport/vga_new/vbe.h
new file mode 100644 (file)
index 0000000..8802a5e
--- /dev/null
@@ -0,0 +1,217 @@
+/*
+ * PROJECT:         VGA Miniport Driver
+ * LICENSE:         BSD - See COPYING.ARM in the top level directory
+ * FILE:            boot/drivers/video/miniport/vga/vbe.h
+ * PURPOSE:         VESA VBE Registers and Structures
+ * PROGRAMMERS:     ReactOS Portable Systems Group
+ */
+
+
+#define LOWORD(l)      ((USHORT)((ULONG_PTR)(l)))
+#define HIWORD(l)      ((USHORT)(((ULONG_PTR)(l)>>16)&0xFFFF))
+
+
+/*
+ * VBE Command Definitions
+ */
+
+#define VBE_GET_CONTROLLER_INFORMATION       0x4F00
+#define VBE_GET_MODE_INFORMATION             0x4F01
+#define VBE_SET_VBE_MODE                     0x4F02
+#define VBE_GET_CURRENT_VBE_MODE             0x4F03
+#define VBE_SAVE_RESTORE_STATE               0x4F04
+#define VBE_DISPLAY_WINDOW_CONTROL           0x4F05
+#define VBE_SET_GET_LOGICAL_SCAN_LINE_LENGTH 0x4F06
+#define VBE_SET_GET_DISPLAY_START            0x4F07
+#define VBE_SET_GET_DAC_PALETTE_FORMAT       0x4F08
+#define VBE_SET_GET_PALETTE_DATA             0x4F09
+
+/* VBE 2.0+ */
+#define VBE_RETURN_PROTECTED_MODE_INTERFACE  0x4F0A
+#define VBE_GET_SET_PIXEL_CLOCK              0x4F0B
+
+/* Extensions */
+#define VBE_POWER_MANAGEMENT_EXTENSIONS      0x4F10
+#define VBE_FLAT_PANEL_INTERFACE_EXTENSIONS  0x4F11
+#define VBE_AUDIO_INTERFACE_EXTENSIONS       0x4F12
+#define VBE_OEM_EXTENSIONS                   0x4F13
+#define VBE_DISPLAY_DATA_CHANNEL             0x4F14
+#define VBE_DDC                              0x4F15
+
+/*
+ * VBE DDC Sub-Functions
+ */
+
+#define VBE_DDC_READ_EDID                      0x01
+#define VBE_DDC_REPORT_CAPABILITIES            0x10
+#define VBE_DDC_BEGIN_SCL_SDA_CONTROL          0x11
+#define VBE_DDC_END_SCL_SDA_CONTROL            0x12
+#define VBE_DDC_WRITE_SCL_CLOCK_LINE           0x13
+#define VBE_DDC_WRITE_SDA_DATA_LINE            0x14
+#define VBE_DDC_READ_SCL_CLOCK_LINE            0x15
+#define VBE_DDC_READ_SDA_DATA_LINE             0x16
+
+/*
+ * VBE Video Mode Information Definitions
+ */
+#define VBE_MODEATTR_VALID                      0x01
+#define VBE_MODEATTR_COLOR                      0x08
+#define VBE_MODEATTR_GRAPHICS                   0x10
+#define VBE_MODEATTR_NON_VGA                    0x20
+#define VBE_MODEATTR_NO_BANK_SWITCH             0x40
+#define VBE_MODEATTR_LINEAR                     0x80
+
+#define VBE_MODE_BITS                           8
+#define VBE_MODE_RESERVED_1                     0x200
+#define VBE_MODE_RESERVED_2                     0x400
+#define VBE_MODE_REFRESH_CONTROL                0x800
+#define VBE_MODE_ACCELERATED_1                  0x1000
+#define VBE_MODE_ACCELERATED_2                  0x2000
+#define VBE_MODE_LINEAR_FRAMEBUFFER             0x4000
+#define VBE_MODE_PRESERVE_DISPLAY               0x8000
+#define VBE_MODE_MASK                           ((1 << (VBE_MODE_BITS + 1)) - 1)
+
+#define VBE_MEMORYMODEL_PACKEDPIXEL            0x04
+#define VBE_MEMORYMODEL_DIRECTCOLOR            0x06
+
+/*
+ * VBE Return Codes
+ */
+
+#define VBE_SUCCESS                            0x4F
+#define VBE_UNSUCCESSFUL                      0x14F
+#define VBE_NOT_SUPPORTED                     0x24F
+#define VBE_FUNCTION_INVALID                  0x34F
+
+#define VBE_GETRETURNCODE(x) (x & 0xFFFF)
+
+#include <pshpack1.h>
+
+/*
+ * VBE specification defined structure for general adapter info
+ * returned by function VBE_GET_CONTROLLER_INFORMATION command.
+ */
+
+typedef struct _VBE_CONTROLLER_INFO
+{
+   CHAR Signature[4];
+   USHORT Version;
+   ULONG OemStringPtr;
+   LONG Capabilities;
+   ULONG VideoModePtr;
+   USHORT TotalMemory;
+   USHORT OemSoftwareRevision;
+   ULONG OemVendorNamePtr;
+   ULONG OemProductNamePtr;
+   ULONG OemProductRevPtr;
+   CHAR Reserved[222];
+   CHAR OemData[256];
+} VBE_CONTROLLER_INFO, *PVBE_CONTROLLER_INFO;
+
+/*
+ * VBE specification defined structure for specific video mode
+ * info returned by function VBE_GET_MODE_INFORMATION command.
+ */
+
+typedef struct _VBE_MODE_INFO
+{
+   /* Mandatory information for all VBE revisions */
+   USHORT ModeAttributes;
+   UCHAR WinAAttributes;
+   UCHAR WinBAttributes;
+   USHORT WinGranularity;
+   USHORT WinSize;
+   USHORT WinASegment;
+   USHORT WinBSegment;
+   ULONG WinFuncPtr;
+   USHORT BytesPerScanLine;
+
+   /* Mandatory information for VBE 1.2 and above */
+   USHORT XResolution;
+   USHORT YResolution;
+   UCHAR XCharSize;
+   UCHAR YCharSize;
+   UCHAR NumberOfPlanes;
+   UCHAR BitsPerPixel;
+   UCHAR NumberOfBanks;
+   UCHAR MemoryModel;
+   UCHAR BankSize;
+   UCHAR NumberOfImagePages;
+   UCHAR Reserved1;
+
+   /* Direct Color fields (required for Direct/6 and YUV/7 memory models) */
+   UCHAR RedMaskSize;
+   UCHAR RedFieldPosition;
+   UCHAR GreenMaskSize;
+   UCHAR GreenFieldPosition;
+   UCHAR BlueMaskSize;
+   UCHAR BlueFieldPosition;
+   UCHAR ReservedMaskSize;
+   UCHAR ReservedFieldPosition;
+   UCHAR DirectColorModeInfo;
+
+   /* Mandatory information for VBE 2.0 and above */
+   ULONG PhysBasePtr;
+   ULONG Reserved2;
+   USHORT Reserved3;
+
+   /* Mandatory information for VBE 3.0 and above */
+   USHORT LinBytesPerScanLine;
+   UCHAR BnkNumberOfImagePages;
+   UCHAR LinNumberOfImagePages;
+   UCHAR LinRedMaskSize;
+   UCHAR LinRedFieldPosition;
+   UCHAR LinGreenMaskSize;
+   UCHAR LinGreenFieldPosition;
+   UCHAR LinBlueMaskSize;
+   UCHAR LinBlueFieldPosition;
+   UCHAR LinReservedMaskSize;
+   UCHAR LinReservedFieldPosition;
+   ULONG MaxPixelClock;
+
+   CHAR Reserved4[190];
+} VBE_MODE_INFO, *PVBE_MODE_INFO;
+
+#include <poppack.h>
+
+typedef struct _VBE_INFO
+{
+    VBE_CONTROLLER_INFO Info;
+    VBE_MODE_INFO Modes;
+    USHORT ModeArray[129];
+} VBE_INFO, *PVBE_INFO;
+
+C_ASSERT(sizeof(VBE_CONTROLLER_INFO) == 0x200);
+C_ASSERT(sizeof(VBE_MODE_INFO) == 0x100);
+
+typedef struct _VBE_COLOR_REGISTER
+{
+    UCHAR Blue;
+    UCHAR Green;
+    UCHAR Red;
+    UCHAR Pad;
+} VBE_COLOR_REGISTER, *PVBE_COLOR_REGISTER;
+
+VOID
+NTAPI
+InitializeModeTable(IN PHW_DEVICE_EXTENSION VgaExtension);
+
+VP_STATUS
+NTAPI
+VbeSetMode(IN PHW_DEVICE_EXTENSION VgaDeviceExtension,
+         IN PVIDEOMODE VgaMode,
+         OUT PULONG PhysPtrChange);
+
+VP_STATUS
+NTAPI
+VbeSetColorLookup(IN PHW_DEVICE_EXTENSION VgaExtension,
+            IN PVIDEO_CLUT ClutBuffer);
+
+BOOLEAN
+NTAPI
+ValidateVbeInfo(IN PHW_DEVICE_EXTENSION VgaExtension,
+                IN PVBE_INFO VbeInfo);
+
+extern BOOLEAN g_bIntelBrookdaleBIOS;
+
+/* EOF */
diff --git a/reactos/drivers/video/miniport/vga_new/vbemodes.c b/reactos/drivers/video/miniport/vga_new/vbemodes.c
new file mode 100644 (file)
index 0000000..39537c6
--- /dev/null
@@ -0,0 +1,449 @@
+/*
+ * PROJECT:         ReactOS VGA Miniport Driver
+ * LICENSE:         BSD - See COPYING.ARM in the top level directory
+ * FILE:            boot/drivers/video/miniport/vga/vbemodes.c
+ * PURPOSE:         Mode Initialization and Mode Set for VBE-compatible cards
+ * PROGRAMMERS:     ReactOS Portable Systems Group
+ */
+
+/* INCLUDES *******************************************************************/
+
+#include "vga.h"
+
+/* FUNCTIONS ******************************************************************/
+
+ULONG
+NTAPI
+RaiseToPower2Ulong(IN ULONG Value)
+{
+    ULONG SquaredResult = Value;
+    if ((Value - 1) & Value) for (SquaredResult = 1; (SquaredResult < Value) && (SquaredResult); SquaredResult *= 2);
+    return SquaredResult;
+}
+
+ULONG
+NTAPI
+RaiseToPower2(IN USHORT Value)
+{
+    ULONG SquaredResult = Value;
+    if ((Value - 1) & Value) for (SquaredResult = 1; (SquaredResult < Value) && (SquaredResult); SquaredResult *= 2); 
+    return SquaredResult;
+}
+
+ULONG
+NTAPI
+VbeGetVideoMemoryBaseAddress(IN PHW_DEVICE_EXTENSION VgaExtension,
+                             IN PVIDEOMODE VgaMode)
+{ 
+    ULONG Length = 4 * 1024;
+    USHORT TrampolineMemorySegment, TrampolineMemoryOffset;
+    PVOID Context;
+    INT10_BIOS_ARGUMENTS BiosArguments;
+    PVBE_MODE_INFO VbeModeInfo;
+    ULONG BaseAddress;
+    VP_STATUS Status;
+
+    /* Need linear and INT10 interface */
+    if (!(VgaMode->fbType & VIDEO_MODE_BANKED)) return 0;
+    if (VgaExtension->Int10Interface.Size) return 0;
+    
+    /* Allocate scratch area and context */
+    VbeModeInfo = VideoPortAllocatePool(VgaExtension, 1, sizeof(VBE_MODE_INFO), ' agV');
+    if (!VbeModeInfo) return 0;
+    Context = VgaExtension->Int10Interface.Context;
+    Status = VgaExtension->Int10Interface.Int10AllocateBuffer(Context,
+                                                              &TrampolineMemorySegment,
+                                                              &TrampolineMemoryOffset,
+                                                              &Length);
+    if (Status != NO_ERROR) return 0;
+
+    /* Ask VBE BIOS for mode info */
+    BiosArguments.Ecx = HIWORD(VgaMode->Mode);
+    BiosArguments.Edi = TrampolineMemorySegment;
+    BiosArguments.SegEs = TrampolineMemoryOffset;
+    BiosArguments.Eax = VBE_GET_MODE_INFORMATION;
+    Status = VgaExtension->Int10Interface.Int10CallBios(Context, &BiosArguments);
+    if (Status != NO_ERROR) return 0;
+    if (BiosArguments.Eax != VBE_SUCCESS) return 0;
+    Status = VgaExtension->Int10Interface.Int10ReadMemory(Context,
+                                                          TrampolineMemorySegment,
+                                                          TrampolineMemoryOffset,
+                                                          VbeModeInfo,
+                                                          sizeof(VBE_MODE_INFO));
+    if (Status != NO_ERROR) return 0;
+    
+    /* Return phys address and cleanup */
+    BaseAddress = VbeModeInfo->PhysBasePtr;
+    VgaExtension->Int10Interface.Int10FreeBuffer(Context,
+                                                 TrampolineMemorySegment,
+                                                 TrampolineMemoryOffset);
+    VideoPortFreePool(VgaExtension, VbeModeInfo);
+    return BaseAddress;
+}
+
+VP_STATUS
+NTAPI
+VbeSetMode(IN PHW_DEVICE_EXTENSION VgaDeviceExtension,
+           IN PVIDEOMODE VgaMode,
+           OUT PULONG PhysPtrChange)
+{
+    VP_STATUS Status;
+    VIDEO_X86_BIOS_ARGUMENTS BiosArguments;
+    ULONG ModeIndex;
+    ULONG BaseAddress;
+    
+    VideoPortZeroMemory(&BiosArguments, sizeof(BiosArguments));     
+    ModeIndex = VgaMode->Mode;
+    BiosArguments.Eax = ModeIndex & 0x0000FFFF;
+    BiosArguments.Ebx = ModeIndex >> 16;
+    VideoPortDebugPrint(0, "Switching to %lx %lx\n", BiosArguments.Eax, BiosArguments.Ebx);
+    Status = VideoPortInt10(VgaDeviceExtension, &BiosArguments);
+    if (Status != NO_ERROR) return Status;
+
+    /* Check for VESA mode */  
+    if (ModeIndex >> 16)
+    {
+        /* Mode set fail */
+        if (BiosArguments.Eax != VBE_SUCCESS) return ERROR_INVALID_PARAMETER;
+        
+        /* Check current mode is desired mode */
+        BiosArguments.Eax = VBE_GET_CURRENT_VBE_MODE;
+        Status = VideoPortInt10(VgaDeviceExtension, &BiosArguments);
+        if ((Status == NO_ERROR) &&
+            (BiosArguments.Eax == VBE_SUCCESS) &&
+            ((BiosArguments.Ebx ^ (ModeIndex >> 16)) & VBE_MODE_BITS))
+        {
+            return ERROR_INVALID_PARAMETER;
+        }
+
+        /* Set logical scanline width if different from physical */
+        if (VgaMode->LogicalWidth != VgaMode->hres)
+        {
+            /* Check setting works after being set */
+            BiosArguments.Eax = VBE_SET_GET_LOGICAL_SCAN_LINE_LENGTH;
+            BiosArguments.Ecx = VgaMode->LogicalWidth;
+            BiosArguments.Ebx = 0;
+            Status = VideoPortInt10(VgaDeviceExtension, &BiosArguments);
+            if ((Status != NO_ERROR) ||
+                (BiosArguments.Eax != VBE_SUCCESS) ||
+                (BiosArguments.Ecx != VgaMode->LogicalWidth))
+            {
+                return ERROR_INVALID_PARAMETER;
+            }
+        }
+    }
+    
+    /* Get VRAM address to update changes */
+    BaseAddress = VbeGetVideoMemoryBaseAddress(VgaDeviceExtension, VgaMode);
+    if ((BaseAddress) && (VgaMode->PhysBase != BaseAddress))
+    {
+        *PhysPtrChange = TRUE;
+        VgaMode->PhysBase = BaseAddress;
+    }
+    
+    return NO_ERROR;   
+}
+
+VOID
+NTAPI
+InitializeModeTable(IN PHW_DEVICE_EXTENSION VgaExtension)
+{
+    ULONG ModeCount = 0;
+    ULONG Length = 4 * 1024;
+    ULONG TotalMemory;
+    VP_STATUS Status;
+    INT10_BIOS_ARGUMENTS BiosArguments;
+    PVBE_INFO VbeInfo;
+    PVBE_MODE_INFO VbeModeInfo;
+    PVOID Context;
+    USHORT TrampolineMemorySegment;
+    USHORT TrampolineMemoryOffset;
+    ULONG VbeVersion;
+    ULONG NewModes = 0;
+    BOOLEAN FourBppModeFound = FALSE;
+    USHORT ModeResult;
+    USHORT Mode;
+    PUSHORT ThisMode;
+    BOOLEAN LinearAddressing;
+    ULONG Size, ScreenSize;
+    PVIDEOMODE VgaMode;
+    PVOID BaseAddress;
+    ULONG ScreenStride = 0;
+    PHYSICAL_ADDRESS PhysicalAddress;
+
+    /* Enable only default vga modes if no vesa */
+    VgaModeList = ModesVGA;
+    if (VideoPortIsNoVesa())
+    {
+        VgaExtension->Int10Interface.Size = 0;
+        VgaExtension->Int10Interface.Version = 0;
+        return;
+    }
+    
+    /* Query INT10 interface */
+    VgaExtension->Int10Interface.Version = VIDEO_PORT_INT10_INTERFACE_VERSION_1;
+    VgaExtension->Int10Interface.Size = sizeof(VIDEO_PORT_INT10_INTERFACE);
+    if (VideoPortQueryServices(VgaExtension,
+                               VideoPortServicesInt10,
+                               (PINTERFACE)&VgaExtension->Int10Interface))
+    {
+        VgaExtension->Int10Interface.Size = 0;
+        VgaExtension->Int10Interface.Version = 0;
+    }
+    
+    /* Add ref */
+    //VideoPortDebugPrint(0, "have int10 iface\n");
+    VgaExtension->Int10Interface.InterfaceReference(VgaExtension->Int10Interface.Context);
+    Context = VgaExtension->Int10Interface.Context;
+    
+    /* Allocate scratch area and context */
+    Status = VgaExtension->Int10Interface.Int10AllocateBuffer(Context,
+                                                              &TrampolineMemorySegment,
+                                                              &TrampolineMemoryOffset,
+                                                              &Length);
+    if (Status != NO_ERROR) return;
+    VbeInfo = VideoPortAllocatePool(VgaExtension, 1, sizeof(VBE_INFO), ' agV');
+    VbeModeInfo = &VbeInfo->Modes;
+    if (!VbeInfo) return;
+
+    /* Init VBE data and write to card buffer */
+    //VideoPortDebugPrint(0, "have int10 data\n");
+    VbeInfo->ModeArray[128] = 0xFFFF;
+    strcpy(VbeInfo->Info.Signature, "VBE2");
+    Status = VgaExtension->Int10Interface.Int10WriteMemory(Context,
+                                                           TrampolineMemorySegment,
+                                                           TrampolineMemoryOffset,
+                                                           VbeInfo,
+                                                           512);
+    if (Status != NO_ERROR) return;
+
+    /* Get controller info */
+    BiosArguments.Edi = TrampolineMemoryOffset;
+    BiosArguments.SegEs = TrampolineMemorySegment;
+    BiosArguments.Eax = VBE_GET_CONTROLLER_INFORMATION;
+    Status = VgaExtension->Int10Interface.Int10CallBios(Context, &BiosArguments);
+    if (Status != NO_ERROR) return;
+    if (BiosArguments.Eax != VBE_SUCCESS) return;
+    Status = VgaExtension->Int10Interface.Int10ReadMemory(Context,
+                                                          TrampolineMemorySegment,
+                                                          TrampolineMemoryOffset,
+                                                          VbeInfo,
+                                                          512);
+    if (Status != NO_ERROR) return;
+
+    /* Check correct VBE BIOS */
+    //VideoPortDebugPrint(0, "have vbe data\n");
+    TotalMemory = VbeInfo->Info.TotalMemory << 16;
+    VbeVersion = VbeInfo->Info.Version;
+    VideoPortDebugPrint(0, "vbe version %lx memory %lx\n", VbeVersion, TotalMemory);
+    if (!ValidateVbeInfo(VgaExtension, VbeInfo)) return;
+    
+    /* Read modes */
+    //VideoPortDebugPrint(0, "read modes from %p\n", VbeInfo->Info.VideoModePtr);
+    Status = VgaExtension->Int10Interface.Int10ReadMemory(Context,
+                                                          HIWORD(VbeInfo->Info.VideoModePtr),
+                                                          LOWORD(VbeInfo->Info.VideoModePtr),
+                                                          VbeInfo->ModeArray,
+                                                          128 * sizeof(USHORT));
+    if (Status != NO_ERROR) return;
+    //VideoPortDebugPrint(0, "Read modes at: %p\n", VbeInfo->ModeArray);
+
+    /* Count modes, check for new 4bpp SVGA modes */
+    ThisMode = VbeInfo->ModeArray;
+    ModeResult = VbeInfo->ModeArray[0];
+    while (ModeResult != 0xFFFF)
+    {
+        Mode = ModeResult & 0x1FF;
+        //VideoPortDebugPrint(0, "Mode found: %lx\n", Mode);
+        if ((Mode == 0x102) || (Mode == 0x6A)) FourBppModeFound = TRUE;
+        ModeResult = *++ThisMode;
+        NewModes++;
+    }
+    
+    /* Remove the built-in mode if not supported by card and check max modes */
+    if (!FourBppModeFound) --NumVideoModes;
+    if ((NewModes >= 128) && (NumVideoModes > 8)) goto Cleanup;
+    
+    /* Switch to new SVGA mode list, copy VGA modes */
+    VgaModeList = VideoPortAllocatePool(VgaExtension, 1, (NewModes + NumVideoModes) * sizeof(VIDEOMODE), ' agV');
+    if (!VgaModeList) goto Cleanup;
+    VideoPortMoveMemory(VgaModeList, ModesVGA, NumVideoModes * sizeof(VIDEOMODE));
+
+    /* Apply fixup for Intel Brookdale */
+    if (g_bIntelBrookdaleBIOS)
+    {
+        VideoPortDebugPrint(0, "Intel Brookdale-G Video BIOS Not Support!\n");
+        while (TRUE);
+    }
+    
+    /* Scan SVGA modes */
+//    VideoPortDebugPrint(0, "Static modes: %d\n", NumVideoModes);
+    VgaMode = &VgaModeList[NumVideoModes];
+    ThisMode = VbeInfo->ModeArray;
+    //VideoPortDebugPrint(0, "new modes: %d\n", NewModes);
+    while (NewModes--)
+    {
+        /* Get info on mode */
+        BiosArguments.Eax = VBE_GET_MODE_INFORMATION;
+        BiosArguments.Ecx = *ThisMode;
+        BiosArguments.Edi = TrampolineMemoryOffset;
+        BiosArguments.SegEs = TrampolineMemorySegment;
+        Status = VgaExtension->Int10Interface.Int10CallBios(Context, &BiosArguments);
+        if (Status != NO_ERROR) goto Next;
+        if (BiosArguments.Eax != VBE_SUCCESS) goto Next;
+        Status = VgaExtension->Int10Interface.Int10ReadMemory(Context,
+                                                              TrampolineMemorySegment,
+                                                              TrampolineMemoryOffset,
+                                                              VbeModeInfo,
+                                                              256);
+        if (Status != NO_ERROR) goto Next;
+
+        /* Parse graphics modes only if linear framebuffer support */
+        //VideoPortDebugPrint(0, "attr: %lx\n", VbeModeInfo->ModeAttributes);
+        if (!(VbeModeInfo->ModeAttributes & (VBE_MODEATTR_VALID |
+                                             VBE_MODEATTR_GRAPHICS))) goto Next;
+        LinearAddressing = ((VbeVersion >= 0x200) &&
+                            (VbeModeInfo->PhysBasePtr) &&
+                            (VbeModeInfo->ModeAttributes & VBE_MODEATTR_LINEAR)) ?
+                            TRUE : FALSE;
+
+        /* Check SVGA modes if 8bpp or higher */
+        //VideoPortDebugPrint(0, "PhysBase: %lx\n", VbeModeInfo->PhysBasePtr);
+        if ((VbeModeInfo->XResolution >= 640) &&
+            (VbeModeInfo->YResolution >= 480) &&
+            (VbeModeInfo->NumberOfPlanes >= 1) &&
+            (VbeModeInfo->BitsPerPixel >= 8))
+        {
+            /* Copy VGA mode info */
+            VideoPortZeroMemory(VgaMode, sizeof(VIDEOMODE));
+            VgaMode->numPlanes = VbeModeInfo->NumberOfPlanes;
+            VgaMode->hres = VbeModeInfo->XResolution;
+            VgaMode->vres = VbeModeInfo->YResolution;
+            VgaMode->Frequency = 1;
+            VgaMode->Mode = (*ThisMode << 16) | VBE_SET_VBE_MODE;
+            VgaMode->Granularity = VbeModeInfo->WinGranularity << 10;
+            //VideoPortDebugPrint(0, "Mode %lx (Granularity %d)\n", VgaMode->Mode, VgaMode->Granularity);
+
+            /* Set flags */
+            if (VbeModeInfo->ModeAttributes & VBE_MODEATTR_COLOR) VgaMode->fbType |= VIDEO_MODE_COLOR;
+            if (VbeModeInfo->ModeAttributes & VBE_MODEATTR_GRAPHICS) VgaMode->fbType |= VIDEO_MODE_GRAPHICS;
+            if (VbeModeInfo->ModeAttributes & VBE_MODEATTR_NON_VGA) VgaMode->NonVgaMode = TRUE;
+            
+            /* If no char data, say 80x25 */
+            VgaMode->col = VbeModeInfo->XCharSize ? VbeModeInfo->XResolution / VbeModeInfo->XCharSize : 80;
+            VgaMode->row = VbeModeInfo->YCharSize ? VbeModeInfo->YResolution / VbeModeInfo->YCharSize : 25;
+            //VideoPortDebugPrint(0, "%d by %d rows\n", VgaMode->Columns, VgaMode->Rows);
+
+            /* Check RGB555 (15bpp only) */
+            VgaMode->bitsPerPlane = VbeModeInfo->BitsPerPixel / VbeModeInfo->NumberOfPlanes;
+            if ((VgaMode->bitsPerPlane == 16) && (VbeModeInfo->GreenMaskSize == 5)) VgaMode->bitsPerPlane = 15;
+            //VideoPortDebugPrint(0, "BPP: %d\n", VgaMode->BitsPerPlane);
+            
+            /* Do linear or banked frame buffers */ 
+            VgaMode->FrameBufferBase = 0;
+            if (!LinearAddressing)
+            {
+                /* Read the screen stride (scanline size) */
+                ScreenStride = RaiseToPower2(VbeModeInfo->BytesPerScanLine);
+                VgaMode->wbytes = ScreenStride;
+                //VideoPortDebugPrint(0, "ScanLines: %lx Stride: %lx\n", VbeModeInfo->BytesPerScanLine, VgaMode->Stride);
+            
+                /* Size of frame buffer is Height X ScanLine, align to bank/page size */
+                ScreenSize = VgaMode->hres * ScreenStride;
+                //VideoPortDebugPrint(0, "Size: %lx\n", ScreenSize);
+                Size = (ScreenSize + ((64 * 1024) - 1)) & ((64 * 1024) - 1);
+                //VideoPortDebugPrint(0, "Size: %lx\n", ScreenSize);
+                if (Size > TotalMemory) Size = (Size + ((4 * 1024) - 1)) & ((4 * 1024) - 1);
+                //VideoPortDebugPrint(0, "Size: %lx\n", ScreenSize);
+             
+                /* Banked VGA at 0xA0000 (64K) */
+                //VideoPortDebugPrint(0, "Final size: %lx\n", Size);
+                VgaMode->fbType |= VIDEO_MODE_BANKED;
+                VgaMode->sbytes = Size;
+                VgaMode->PhysSize = 64 * 1024;
+                VgaMode->FrameBufferSize = 64 * 1024;
+                VgaMode->NoBankSwitch = TRUE;
+                VgaMode->PhysBase = 0xA0000;
+                VgaMode->LogicalWidth = RaiseToPower2(VgaMode->hres);
+            }
+            else
+            {
+                /* VBE 3.00+ has specific field, read legacy field if not */
+                //VideoPortDebugPrint(0, "LINEAR MODE!!!\n");
+                ScreenStride = (VbeVersion >= 0x300) ? VbeModeInfo->LinBytesPerScanLine : 0;
+                if (!ScreenStride) ScreenStride = VbeModeInfo->BytesPerScanLine;
+                VgaMode->wbytes = ScreenStride;
+                //VideoPortDebugPrint(0, "ScanLines: %lx Stride: %lx\n", VbeModeInfo->BytesPerScanLine, VgaMode->Stride);
+           
+                /* Size of frame buffer is Height X ScanLine, align to page size */
+                ScreenSize = VgaMode->hres * LOWORD(VgaMode->wbytes);
+                //VideoPortDebugPrint(0, "Size: %lx\n", ScreenSize);
+                Size = RaiseToPower2Ulong(ScreenSize);
+                //VideoPortDebugPrint(0, "Size: %lx\n", ScreenSize);
+                if (Size > TotalMemory) Size = (Size + ((4 * 1024) - 1)) & ((4 * 1024) - 1);
+                //VideoPortDebugPrint(0, "Size: %lx\n", ScreenSize);
+           
+                /* Linear VGA must read settings from VBE */
+                VgaMode->fbType |= VIDEO_MODE_LINEAR;
+                VgaMode->sbytes = Size;
+                VgaMode->PhysSize = Size;
+                VgaMode->FrameBufferSize = Size;
+                VgaMode->NoBankSwitch = FALSE;
+                VgaMode->PhysBase = VbeModeInfo->PhysBasePtr;
+                VgaMode->LogicalWidth = VgaMode->hres;
+                
+                /* Make VBE_SET_VBE_MODE command use Linear Framebuffer Select */
+                VgaMode->Mode |= (VBE_MODE_LINEAR_FRAMEBUFFER << 16);
+            }
+            
+            /* Override bank switch if not support by card */
+            if (VbeModeInfo->ModeAttributes & VBE_MODEATTR_NO_BANK_SWITCH) VgaMode->NoBankSwitch = TRUE;
+            
+            /* Next */
+            if (ScreenSize <= TotalMemory)
+            {
+                VgaMode++;
+                ModeCount++;
+            }
+        }
+Next:
+        /* Next */
+        ThisMode++;
+    }
+
+    /* Check if last mode was color to do test */
+    VideoPortDebugPrint(0, "mode scan complete. Total modes: %d\n", ModeCount);
+    if (--VgaMode->fbType & VIDEO_MODE_COLOR)
+    {
+        /* Try map physical buffer and free if worked */
+        PhysicalAddress.QuadPart = VgaMode->PhysBase;
+        BaseAddress = VideoPortGetDeviceBase(VgaExtension, PhysicalAddress, 4 * 1024, FALSE);
+        if (BaseAddress)
+        {
+            VideoPortFreeDeviceBase(VgaExtension, BaseAddress);
+        }
+        else
+        {
+            /* Not work, so throw out VBE data */
+            ModeCount = 0;
+        }
+    }
+
+    /* Cleanup sucess path */
+    VideoPortFreePool(VgaExtension, VbeInfo);
+    VgaExtension->Int10Interface.Int10FreeBuffer(Context,
+                                                 TrampolineMemorySegment,
+                                                 TrampolineMemoryOffset);
+    NumVideoModes += ModeCount;
+    return;
+
+Cleanup:
+    /* Cleanup failure path, reset standard VGA and free memory */
+    VgaModeList = ModesVGA;
+    VideoPortFreePool(VgaExtension, VbeInfo);
+    VgaExtension->Int10Interface.Int10FreeBuffer(Context,
+                                                 TrampolineMemorySegment,
+                                                 TrampolineMemoryOffset);
+}
+
+/* EOF */
diff --git a/reactos/drivers/video/miniport/vga_new/vga.c b/reactos/drivers/video/miniport/vga_new/vga.c
new file mode 100644 (file)
index 0000000..5b59b53
--- /dev/null
@@ -0,0 +1,1401 @@
+/*
+ * PROJECT:         ReactOS VGA Miniport Driver
+ * LICENSE:         Microsoft NT4 DDK Sample Code License
+ * FILE:            boot/drivers/video/miniport/vga/vga.c
+ * PURPOSE:         Main Standard VGA-compatible Minport Handling Code
+ * PROGRAMMERS:     Copyright (c) 1992  Microsoft Corporation
+ *                  ReactOS Portable Systems Group
+ */
+
+//---------------------------------------------------------------------------
+
+#include "vga.h"
+
+//---------------------------------------------------------------------------
+//
+// Function declarations
+//
+// Functions that start with 'VGA' are entry points for the OS port driver.
+//
+
+VP_STATUS
+VgaFindAdapter(
+    PVOID HwDeviceExtension,
+    PVOID HwContext,
+    PWSTR ArgumentString,
+    PVIDEO_PORT_CONFIG_INFO ConfigInfo,
+    PUCHAR Again
+    );
+
+BOOLEAN
+VgaInitialize(
+    PVOID HwDeviceExtension
+    );
+
+BOOLEAN
+VgaStartIO(
+    PVOID HwDeviceExtension,
+    PVIDEO_REQUEST_PACKET RequestPacket
+    );
+
+//
+// Private function prototypes.
+//
+
+VP_STATUS
+VgaQueryAvailableModes(
+    PHW_DEVICE_EXTENSION HwDeviceExtension,
+    PVIDEO_MODE_INFORMATION ModeInformation,
+    ULONG ModeInformationSize,
+    PULONG OutputSize
+    );
+
+VP_STATUS
+VgaQueryNumberOfAvailableModes(
+    PHW_DEVICE_EXTENSION HwDeviceExtension,
+    PVIDEO_NUM_MODES NumModes,
+    ULONG NumModesSize,
+    PULONG OutputSize
+    );
+
+VP_STATUS
+VgaSetMode(
+    PHW_DEVICE_EXTENSION HwDeviceExtension,
+    PVIDEO_MODE Mode,
+    ULONG ModeSize,
+// eVb: 1.1 [SET MODE] - Add new output parameter for framebuffer update functionality
+    PULONG PhysPtrChange
+// eVb: 1.1 [END]
+    );
+
+BOOLEAN
+VgaIsPresent(
+    PHW_DEVICE_EXTENSION HwDeviceExtension
+    );
+
+VOID
+VgaInterpretCmdStream(
+    PVOID HwDeviceExtension,
+    PUSHORT pusCmdStream
+    );
+
+VP_STATUS
+VgaSetColorLookup(
+    PHW_DEVICE_EXTENSION HwDeviceExtension,
+    PVIDEO_CLUT ClutBuffer,
+    ULONG ClutBufferSize
+    );
+
+VP_STATUS
+GetDeviceDataCallback(
+   PVOID HwDeviceExtension,
+   PVOID Context,
+   VIDEO_DEVICE_DATA_TYPE DeviceDataType,
+   PVOID Identifier,
+   ULONG IdentifierLength,
+   PVOID ConfigurationData,
+   ULONG ConfigurationDataLength,
+   PVOID ComponentInformation,
+   ULONG ComponentInformationLength
+   );
+
+// eVb: 1.2 [RESOURCE] - Add new function for acquiring VGA resources (I/O, memory)
+VP_STATUS
+VgaAcquireResources(
+    PHW_DEVICE_EXTENSION DeviceExtension
+    );
+// eVb: 1.2 [END]
+
+#if defined(ALLOC_PRAGMA)
+#pragma alloc_text(PAGE,DriverEntry)
+#pragma alloc_text(PAGE,VgaFindAdapter)
+#pragma alloc_text(PAGE,VgaInitialize)
+#pragma alloc_text(PAGE,VgaStartIO)
+#pragma alloc_text(PAGE,VgaIsPresent)
+#pragma alloc_text(PAGE,VgaSetColorLookup)
+#endif
+
+\f
+//---------------------------------------------------------------------------
+ULONG
+// eVb: 1.3 [GCC] - Add NTAPI for GCC support
+NTAPI
+// eVb: 1.3 [END]
+DriverEntry(
+    PVOID Context1,
+    PVOID Context2
+    )
+
+/*++
+
+Routine Description:
+
+    Installable driver initialization entry point.
+    This entry point is called directly by the I/O system.
+
+Arguments:
+
+    Context1 - First context value passed by the operating system. This is
+        the value with which the miniport driver calls VideoPortInitialize().
+
+    Context2 - Second context value passed by the operating system. This is
+        the value with which the miniport driver calls 3VideoPortInitialize().
+
+Return Value:
+
+    Status from VideoPortInitialize()
+
+--*/
+
+{
+
+    VIDEO_HW_INITIALIZATION_DATA hwInitData;
+    ULONG status;
+    ULONG initializationStatus = (ULONG) -1;
+
+    //
+    // Zero out structure.
+    //
+
+    VideoPortZeroMemory(&hwInitData, sizeof(VIDEO_HW_INITIALIZATION_DATA));
+
+    //
+    // Specify sizes of structure and extension.
+    //
+
+    hwInitData.HwInitDataSize = sizeof(VIDEO_HW_INITIALIZATION_DATA);
+
+    //
+    // Set entry points.
+    //
+
+    hwInitData.HwFindAdapter = VgaFindAdapter;
+    hwInitData.HwInitialize = VgaInitialize;
+    hwInitData.HwInterrupt = NULL;
+    hwInitData.HwStartIO = VgaStartIO;
+
+    //
+    // Determine the size we require for the device extension.
+    //
+
+    hwInitData.HwDeviceExtensionSize = sizeof(HW_DEVICE_EXTENSION);
+
+    //
+    // Always start with parameters for device0 in this case.
+    // We can leave it like this since we know we will only ever find one
+    // VGA type adapter in a machine.
+    //
+
+    // hwInitData.StartingDeviceNumber = 0;
+
+    //
+    // Once all the relevant information has been stored, call the video
+    // port driver to do the initialization.
+    // For this device we will repeat this call three times, for ISA, EISA
+    // and PCI.
+    // We will return the minimum of all return values.
+    //
+
+    //
+    // We will try the PCI bus first so that our ISA detection does'nt claim
+    // PCI cards (since it is impossible to differentiate between the two
+    // by looking at the registers).
+    //
+
+    //
+    // NOTE: since this driver only supports one adapter, we will return
+    // as soon as we find a device, without going on to the following buses.
+    // Normally one would call for each bus type and return the smallest
+    // value.
+    //
+
+#if !defined(_ALPHA_)
+
+    //
+    // Before we can enable this on ALPHA we need to find a way to map a
+    // sparse view of a 4MB region successfully.
+    //
+
+    hwInitData.AdapterInterfaceType = PCIBus;
+
+    initializationStatus = VideoPortInitialize(Context1,
+                                               Context2,
+                                               &hwInitData,
+                                               NULL);
+
+    if (initializationStatus == NO_ERROR)
+    {
+        return initializationStatus;
+    }
+
+#endif
+
+    hwInitData.AdapterInterfaceType = MicroChannel;
+
+    initializationStatus = VideoPortInitialize(Context1,
+                                               Context2,
+                                               &hwInitData,
+                                               NULL);
+
+    //
+    // Return immediately instead of checkin for smallest return code.
+    //
+
+    if (initializationStatus == NO_ERROR)
+    {
+        return initializationStatus;
+    }
+
+
+    hwInitData.AdapterInterfaceType = Internal;
+
+    initializationStatus = VideoPortInitialize(Context1,
+                                               Context2,
+                                               &hwInitData,
+                                               NULL);
+
+    if (initializationStatus == NO_ERROR)
+    {
+        return initializationStatus;
+    }
+
+
+    hwInitData.AdapterInterfaceType = Isa;
+
+    initializationStatus = VideoPortInitialize(Context1,
+                                               Context2,
+                                               &hwInitData,
+                                               NULL);
+
+    if (initializationStatus == NO_ERROR)
+    {
+        return initializationStatus;
+    }
+
+
+
+    hwInitData.AdapterInterfaceType = Eisa;
+
+    status = VideoPortInitialize(Context1,
+                                 Context2,
+                                 &hwInitData,
+                                 NULL);
+
+    if (initializationStatus > status) {
+        initializationStatus = status;
+    }
+
+    return initializationStatus;
+
+} // end DriverEntry()
+\f
+//---------------------------------------------------------------------------
+VP_STATUS
+VgaFindAdapter(
+    PVOID HwDeviceExtension,
+    PVOID HwContext,
+    PWSTR ArgumentString,
+    PVIDEO_PORT_CONFIG_INFO ConfigInfo,
+    PUCHAR Again
+    )
+
+/*++
+
+Routine Description:
+
+    This routine is called to determine if the adapter for this driver
+    is present in the system.
+    If it is present, the function fills out some information describing
+    the adapter.
+
+Arguments:
+
+    HwDeviceExtension - Supplies the miniport driver's adapter storage. This
+        storage is initialized to zero before this call.
+
+    HwContext - Supplies the context value which was passed to
+        VideoPortInitialize().
+
+    ArgumentString - Supplies a NULL terminated ASCII string. This string
+        originates from the user.
+
+    ConfigInfo - Returns the configuration information structure which is
+        filled by the miniport driver. This structure is initialized with
+        any known configuration information (such as SystemIoBusNumber) by
+        the port driver. Where possible, drivers should have one set of
+        defaults which do not require any supplied configuration information.
+
+    Again - Indicates if the miniport driver wants the port driver to call
+        its VIDEO_HW_FIND_ADAPTER function again with a new device extension
+        and the same config info. This is used by the miniport drivers which
+        can search for several adapters on a bus.
+
+Return Value:
+
+    This routine must return:
+
+    NO_ERROR - Indicates a host adapter was found and the
+        configuration information was successfully determined.
+
+    ERROR_INVALID_PARAMETER - Indicates an adapter was found but there was an
+        error obtaining the configuration information. If possible an error
+        should be logged.
+
+    ERROR_DEV_NOT_EXIST - Indicates no host adapter was found for the
+        supplied configuration information.
+
+--*/
+
+{
+
+    PHW_DEVICE_EXTENSION hwDeviceExtension = HwDeviceExtension;
+
+    //
+    // Make sure the size of the structure is at least as large as what we
+    // are expecting (check version of the config info structure).
+    //
+
+    if (ConfigInfo->Length < sizeof(VIDEO_PORT_CONFIG_INFO)) {
+
+        return ERROR_INVALID_PARAMETER;
+
+    }
+// eVb: 1.4 [CIRRUS] - Remove CIRRUS-specific support
+    //
+    // Check internal VGA (MIPS and ARM systems)
+    //
+
+    if ((ConfigInfo->AdapterInterfaceType == Internal) &&
+        (VideoPortGetDeviceData(HwDeviceExtension,
+                                VpControllerData,
+                                &GetDeviceDataCallback,
+                                VgaAccessRange) != NO_ERROR))
+    {
+        return ERROR_INVALID_PARAMETER;
+    }
+// eVb: 1.4 [END]
+    //
+    // No interrupt information is necessary.
+    //
+
+    //
+    // Check to see if there is a hardware resource conflict.
+    //
+// eVb: 1.5 [RESOURCE] - Use new function for acquiring VGA resources (I/O, memory)
+    if (VgaAcquireResources(hwDeviceExtension) != NO_ERROR) return ERROR_INVALID_PARAMETER;
+// eVb: 1.5 [END]
+    //
+    // Get logical IO port addresses.
+    //
+
+    if ((hwDeviceExtension->IOAddress =
+         VideoPortGetDeviceBase(hwDeviceExtension,
+         VgaAccessRange->RangeStart,
+         VGA_MAX_IO_PORT - VGA_BASE_IO_PORT + 1,
+         VgaAccessRange->RangeInIoSpace)) == NULL)
+    {
+        VideoDebugPrint((2, "VgaFindAdapter - Fail to get io address\n"));
+
+        return ERROR_INVALID_PARAMETER;
+    }
+
+    //
+    // Determine whether a VGA is present.
+    //
+
+    if (!VgaIsPresent(hwDeviceExtension)) {
+
+        VideoDebugPrint((0, "VgaFindAdapter - VGA Failed\n"));
+        return ERROR_DEV_NOT_EXIST;
+    }
+
+    //
+    // Minimum size of the buffer required to store the hardware state
+    // information returned by IOCTL_VIDEO_SAVE_HARDWARE_STATE.
+    //
+
+    ConfigInfo->HardwareStateSize = VGA_TOTAL_STATE_SIZE;
+
+    //
+    // Pass a pointer to the emulator range we are using.
+    //
+// eVb: 1.6 [VDM] - Disable VDM for now
+    ConfigInfo->NumEmulatorAccessEntries = 0;
+    ConfigInfo->EmulatorAccessEntries = NULL;
+    ConfigInfo->EmulatorAccessEntriesContext = 0;
+// eVb: 1.6 [END]
+    //
+    // BUGBUG
+    //
+    // There is really no reason to have the frame buffer mapped. On an
+    // x86 we use if for save/restore (supposedly) but even then we
+    // would only need to map a 64K window, not all 16 Meg!
+    //
+
+#ifdef _X86_
+
+    //
+    // Map the video memory into the system virtual address space so we can
+    // clear it out and use it for save and restore.
+    //
+
+    if ( (hwDeviceExtension->VideoMemoryAddress =
+              VideoPortGetDeviceBase(hwDeviceExtension,
+                                     VgaAccessRange[2].RangeStart,
+                                     VgaAccessRange[2].RangeLength,
+                                     FALSE)) == NULL)
+    {
+        VideoDebugPrint((1, "VgaFindAdapter - Fail to get memory address\n"));
+
+        return ERROR_INVALID_PARAMETER;
+    }
+
+    VideoPortDebugPrint(0, "vga mapped at %x\n", hwDeviceExtension->VideoMemoryAddress);
+#endif
+// eVb: 1.7 [VDM] - Disable VDM for now
+    ConfigInfo->VdmPhysicalVideoMemoryAddress.QuadPart = 0;
+    ConfigInfo->VdmPhysicalVideoMemoryLength = 0;
+// eVb: 1.7 [END]
+    //
+    // Indicate we do not wish to be called again for another initialization.
+    //
+
+    *Again = 0;
+
+    //
+    // Indicate a successful completion status.
+    //
+
+    return NO_ERROR;
+
+
+} // VgaFindAdapter()
+\f
+//---------------------------------------------------------------------------
+BOOLEAN
+VgaInitialize(
+    PVOID HwDeviceExtension
+    )
+
+/*++
+
+Routine Description:
+
+    This routine does one time initialization of the device.
+
+Arguments:
+
+    HwDeviceExtension - Pointer to the miniport driver's adapter information.
+
+Return Value:
+
+    None.
+
+--*/
+
+{
+    PHW_DEVICE_EXTENSION hwDeviceExtension = HwDeviceExtension;
+
+    //
+    // set up the default cursor position and type.
+    //
+
+    hwDeviceExtension->CursorPosition.Column = 0;
+    hwDeviceExtension->CursorPosition.Row = 0;
+    hwDeviceExtension->CursorTopScanLine = 0;
+    hwDeviceExtension->CursorBottomScanLine = 31;
+    hwDeviceExtension->CursorEnable = TRUE;
+
+// eVb: 1.8 [VBE] - Initialize VBE modes
+    InitializeModeTable(hwDeviceExtension);
+// eVb: 1.8 [END]
+    return TRUE;
+
+} // VgaInitialize()
+\f
+//---------------------------------------------------------------------------
+BOOLEAN
+VgaStartIO(
+    PVOID HwDeviceExtension,
+    PVIDEO_REQUEST_PACKET RequestPacket
+    )
+
+/*++
+
+Routine Description:
+
+    This routine is the main execution routine for the miniport driver. It
+    accepts a Video Request Packet, performs the request, and then returns
+    with the appropriate status.
+
+Arguments:
+
+    HwDeviceExtension - Pointer to the miniport driver's adapter information.
+
+    RequestPacket - Pointer to the video request packet. This structure
+        contains all the parameters passed to the VideoIoControl function.
+
+Return Value:
+
+    This routine will return error codes from the various support routines
+    and will also return ERROR_INSUFFICIENT_BUFFER for incorrectly sized
+    buffers and ERROR_INVALID_FUNCTION for unsupported functions.
+
+--*/
+
+{
+    PHW_DEVICE_EXTENSION hwDeviceExtension = HwDeviceExtension;
+    VP_STATUS status;
+    VIDEO_MODE videoMode;
+    PVIDEO_MEMORY_INFORMATION memoryInformation;
+    ULONG inIoSpace;
+    ULONG Result;
+
+    //
+    // Switch on the IoContolCode in the RequestPacket. It indicates which
+    // function must be performed by the driver.
+    //
+// eVb: 1.9 [IOCTL] - Remove IOCTLs not needed yet
+    switch (RequestPacket->IoControlCode)
+    {
+    case IOCTL_VIDEO_SHARE_VIDEO_MEMORY:
+
+        VideoDebugPrint((2, "VgaStartIO - ShareVideoMemory\n"));
+
+         status = ERROR_INVALID_FUNCTION;
+
+         break;
+
+    case IOCTL_VIDEO_UNSHARE_VIDEO_MEMORY:
+
+        VideoDebugPrint((2, "VgaStartIO - UnshareVideoMemory\n"));
+
+        status = ERROR_INVALID_FUNCTION;
+
+        break;
+
+
+    case IOCTL_VIDEO_MAP_VIDEO_MEMORY:
+
+        VideoDebugPrint((2, "VgaStartIO - MapVideoMemory\n"));
+
+        if ( (RequestPacket->OutputBufferLength <
+              (RequestPacket->StatusBlock->Information =
+                                     sizeof(VIDEO_MEMORY_INFORMATION))) ||
+             (RequestPacket->InputBufferLength < sizeof(VIDEO_MEMORY)) )
+        {
+            status = ERROR_INSUFFICIENT_BUFFER;
+        }
+
+        memoryInformation = RequestPacket->OutputBuffer;
+
+        memoryInformation->VideoRamBase = ((PVIDEO_MEMORY)
+                (RequestPacket->InputBuffer))->RequestedVirtualAddress;
+
+        //
+        // We reserved 16 meg for the frame buffer, however, it makes
+        // no sense to map more memory than there is on the card.  So
+        // only map the amount of memory we have on the card.
+        //
+// eVb: 1.10 [CIRRUS] - On VGA, we have VRAM size since boot, use it
+        memoryInformation->VideoRamLength =
+                hwDeviceExtension->PhysicalVideoMemoryLength;
+// eVb: 1.10 [END]
+        //
+        // If you change to using a dense space frame buffer, make this
+        // value a 4 for the ALPHA.
+        //
+
+        inIoSpace = 0;
+
+        status = VideoPortMapMemory(hwDeviceExtension,
+                                    hwDeviceExtension->PhysicalVideoMemoryBase,
+// eVb: 1.11 [CIRRUS] - On VGA, we have VRAM size since boot, use it
+                                    &memoryInformation->VideoRamLength,
+// eVb: 1.11 [END]
+                                    &inIoSpace,
+                                    &(memoryInformation->VideoRamBase));
+
+        if (status != NO_ERROR) {
+            VideoDebugPrint((0, "VgaStartIO - IOCTL_VIDEO_MAP_VIDEO_MEMORY failed VideoPortMapMemory (%x)\n", status));
+        }
+
+        memoryInformation->FrameBufferBase =
+            ((PUCHAR) (memoryInformation->VideoRamBase)) +
+            hwDeviceExtension->PhysicalFrameOffset.LowPart;
+
+        memoryInformation->FrameBufferLength =
+            hwDeviceExtension->PhysicalFrameLength ?
+            hwDeviceExtension->PhysicalFrameLength :
+            memoryInformation->VideoRamLength;
+
+
+        VideoDebugPrint((2, "physical VideoMemoryBase %08lx\n", hwDeviceExtension->PhysicalVideoMemoryBase));
+        VideoDebugPrint((2, "physical VideoMemoryLength %08lx\n", hwDeviceExtension->PhysicalVideoMemoryLength));
+        VideoDebugPrint((2, "VideoMemoryBase %08lx\n", memoryInformation->VideoRamBase));
+        VideoDebugPrint((2, "VideoMemoryLength %08lx\n", memoryInformation->VideoRamLength));
+
+        VideoDebugPrint((2, "physical framebuf offset %08lx\n", hwDeviceExtension->PhysicalFrameOffset.LowPart));
+        VideoDebugPrint((2, "framebuf base %08lx\n", memoryInformation->FrameBufferBase));
+        VideoDebugPrint((2, "physical framebuf len %08lx\n", hwDeviceExtension->PhysicalFrameLength));
+        VideoDebugPrint((2, "framebuf length %08lx\n", memoryInformation->FrameBufferLength));
+
+        break;
+
+    case IOCTL_VIDEO_UNMAP_VIDEO_MEMORY:
+
+        VideoDebugPrint((2, "VgaStartIO - UnMapVideoMemory\n"));
+
+        status = ERROR_INVALID_FUNCTION;
+
+        break;
+
+
+    case IOCTL_VIDEO_QUERY_AVAIL_MODES:
+
+        VideoDebugPrint((2, "VgaStartIO - QueryAvailableModes\n"));
+
+        status = VgaQueryAvailableModes(HwDeviceExtension,
+                                        (PVIDEO_MODE_INFORMATION)
+                                            RequestPacket->OutputBuffer,
+                                        RequestPacket->OutputBufferLength,
+                                        &RequestPacket->StatusBlock->Information);
+
+        break;
+
+
+    case IOCTL_VIDEO_QUERY_NUM_AVAIL_MODES:
+
+        VideoDebugPrint((2, "VgaStartIO - QueryNumAvailableModes\n"));
+
+        status = VgaQueryNumberOfAvailableModes(HwDeviceExtension,
+                                                (PVIDEO_NUM_MODES)
+                                                    RequestPacket->OutputBuffer,
+                                                RequestPacket->OutputBufferLength,
+                                                &RequestPacket->StatusBlock->Information);
+
+        break;
+
+
+    case IOCTL_VIDEO_QUERY_CURRENT_MODE:
+
+        VideoDebugPrint((2, "VgaStartIO - QueryCurrentMode\n"));
+
+        status = ERROR_INVALID_FUNCTION;
+
+        break;
+
+
+    case IOCTL_VIDEO_SET_CURRENT_MODE:
+
+        VideoDebugPrint((2, "VgaStartIO - SetCurrentModes\n"));
+
+        status = VgaSetMode(HwDeviceExtension,
+                              (PVIDEO_MODE) RequestPacket->InputBuffer,
+                              RequestPacket->InputBufferLength,
+// eVb: 1.12 [SET MODE] - Use new output parameter for framebuffer update functionality
+                              &Result);
+// eVb: 1.12 [END]
+
+        break;
+
+
+    case IOCTL_VIDEO_RESET_DEVICE:
+
+        VideoDebugPrint((2, "VgaStartIO - Reset Device\n"));
+
+        videoMode.RequestedMode = 0;
+
+        VgaSetMode(HwDeviceExtension,
+                        (PVIDEO_MODE) &videoMode,
+                        sizeof(videoMode),
+// eVb: 1.13 [SET MODE] - Use new output parameter for framebuffer update functionality
+                        &Result);
+// eVb: 1.13 [END]
+
+        //
+        // Always return succcess since settings the text mode will fail on
+        // non-x86.
+        //
+        // Also, failiure to set the text mode is not fatal in any way, since
+        // this operation must be followed by another set mode operation.
+        //
+
+        status = NO_ERROR;
+
+        break;
+
+
+    case IOCTL_VIDEO_LOAD_AND_SET_FONT:
+
+        VideoDebugPrint((2, "VgaStartIO - LoadAndSetFont\n"));
+
+        status = ERROR_INVALID_FUNCTION;
+
+        break;
+
+
+    case IOCTL_VIDEO_QUERY_CURSOR_POSITION:
+
+        VideoDebugPrint((2, "VgaStartIO - QueryCursorPosition\n"));
+
+        status = ERROR_INVALID_FUNCTION;
+
+        break;
+
+
+    case IOCTL_VIDEO_SET_CURSOR_POSITION:
+
+        VideoDebugPrint((2, "VgaStartIO - SetCursorPosition\n"));
+
+        status = ERROR_INVALID_FUNCTION;
+
+        break;
+
+
+    case IOCTL_VIDEO_QUERY_CURSOR_ATTR:
+
+        VideoDebugPrint((2, "VgaStartIO - QueryCursorAttributes\n"));
+
+        status = ERROR_INVALID_FUNCTION;
+
+        break;
+
+
+    case IOCTL_VIDEO_SET_CURSOR_ATTR:
+
+        VideoDebugPrint((2, "VgaStartIO - SetCursorAttributes\n"));
+
+        status = ERROR_INVALID_FUNCTION;
+
+        break;
+
+
+    case IOCTL_VIDEO_SET_PALETTE_REGISTERS:
+
+        VideoDebugPrint((2, "VgaStartIO - SetPaletteRegs\n"));
+
+        status = ERROR_INVALID_FUNCTION;
+
+        break;
+
+
+    case IOCTL_VIDEO_SET_COLOR_REGISTERS:
+
+        VideoDebugPrint((2, "VgaStartIO - SetColorRegs\n"));
+
+        status = VgaSetColorLookup(HwDeviceExtension,
+                                   (PVIDEO_CLUT) RequestPacket->InputBuffer,
+                                   RequestPacket->InputBufferLength);
+
+        break;
+
+
+    case IOCTL_VIDEO_ENABLE_VDM:
+
+        VideoDebugPrint((2, "VgaStartIO - EnableVDM\n"));
+
+        status = ERROR_INVALID_FUNCTION;
+
+        break;
+
+
+    case IOCTL_VIDEO_RESTORE_HARDWARE_STATE:
+
+        VideoDebugPrint((2, "VgaStartIO - RestoreHardwareState\n"));
+
+        status = ERROR_INVALID_FUNCTION;
+
+        break;
+
+
+    case IOCTL_VIDEO_SAVE_HARDWARE_STATE:
+
+        VideoDebugPrint((2, "VgaStartIO - SaveHardwareState\n"));
+
+        status = ERROR_INVALID_FUNCTION;
+
+        break;
+
+    case IOCTL_VIDEO_GET_BANK_SELECT_CODE:
+
+        VideoDebugPrint((2, "VgaStartIO - GetBankSelectCode\n"));
+
+        status = ERROR_INVALID_FUNCTION;
+        break;
+
+    case IOCTL_VIDEO_QUERY_PUBLIC_ACCESS_RANGES:
+    case IOCTL_VIDEO_FREE_PUBLIC_ACCESS_RANGES:
+
+    //
+    // if we get here, an invalid IoControlCode was specified.
+    //
+
+    default:
+
+        VideoDebugPrint((0, "Fell through vga startIO routine - invalid command\n"));
+
+        status = ERROR_INVALID_FUNCTION;
+
+        break;
+
+    }
+// eVb: 1.9 [END]
+    RequestPacket->StatusBlock->Status = status;
+
+    return TRUE;
+
+} // VgaStartIO()
+
+\f
+//---------------------------------------------------------------------------
+//
+// private routines
+//
+
+\f
+//---------------------------------------------------------------------------
+BOOLEAN
+VgaIsPresent(
+    PHW_DEVICE_EXTENSION HwDeviceExtension
+    )
+
+/*++
+
+Routine Description:
+
+    This routine returns TRUE if a VGA is present. Determining whether a VGA
+    is present is a two-step process. First, this routine walks bits through
+    the Bit Mask register, to establish that there are readable indexed
+    registers (EGAs normally don't have readable registers, and other adapters
+    are unlikely to have indexed registers). This test is done first because
+    it's a non-destructive EGA rejection test (correctly rejects EGAs, but
+    doesn't potentially mess up the screen or the accessibility of display
+    memory). Normally, this would be an adequate test, but some EGAs have
+    readable registers, so next, we check for the existence of the Chain4 bit
+    in the Memory Mode register; this bit doesn't exist in EGAs. It's
+    conceivable that there are EGAs with readable registers and a register bit
+    where Chain4 is stored, although I don't know of any; if a better test yet
+    is needed, memory could be written to in Chain4 mode, and then examined
+    plane by plane in non-Chain4 mode to make sure the Chain4 bit did what it's
+    supposed to do. However, the current test should be adequate to eliminate
+    just about all EGAs, and 100% of everything else.
+
+    If this function fails to find a VGA, it attempts to undo any damage it
+    may have inadvertently done while testing. The underlying assumption for
+    the damage control is that if there's any non-VGA adapter at the tested
+    ports, it's an EGA or an enhanced EGA, because: a) I don't know of any
+    other adapters that use 3C4/5 or 3CE/F, and b), if there are other
+    adapters, I certainly don't know how to restore their original states. So
+    all error recovery is oriented toward putting an EGA back in a writable
+    state, so that error messages are visible. The EGA's state on entry is
+    assumed to be text mode, so the Memory Mode register is restored to the
+    default state for text mode.
+
+    If a VGA is found, the VGA is returned to its original state after
+    testing is finished.
+
+Arguments:
+
+    None.
+
+Return Value:
+
+    TRUE if a VGA is present, FALSE if not.
+
+--*/
+
+{
+    UCHAR originalGCAddr;
+    UCHAR originalSCAddr;
+    UCHAR originalBitMask;
+    UCHAR originalReadMap;
+    UCHAR originalMemoryMode;
+    UCHAR testMask;
+    BOOLEAN returnStatus;
+
+    //
+    // Remember the original state of the Graphics Controller Address register.
+    //
+
+    originalGCAddr = VideoPortReadPortUchar(HwDeviceExtension->IOAddress +
+            GRAPH_ADDRESS_PORT);
+
+    //
+    // Write the Read Map register with a known state so we can verify
+    // that it isn't changed after we fool with the Bit Mask. This ensures
+    // that we're dealing with indexed registers, since both the Read Map and
+    // the Bit Mask are addressed at GRAPH_DATA_PORT.
+    //
+
+    VideoPortWritePortUchar(HwDeviceExtension->IOAddress +
+            GRAPH_ADDRESS_PORT, IND_READ_MAP);
+
+    //
+    // If we can't read back the Graphics Address register setting we just
+    // performed, it's not readable and this isn't a VGA.
+    //
+
+    if ((VideoPortReadPortUchar(HwDeviceExtension->IOAddress +
+        GRAPH_ADDRESS_PORT) & GRAPH_ADDR_MASK) != IND_READ_MAP) {
+
+        return FALSE;
+    }
+
+    //
+    // Set the Read Map register to a known state.
+    //
+
+    originalReadMap = VideoPortReadPortUchar(HwDeviceExtension->IOAddress +
+            GRAPH_DATA_PORT);
+    VideoPortWritePortUchar(HwDeviceExtension->IOAddress +
+            GRAPH_DATA_PORT, READ_MAP_TEST_SETTING);
+
+    if (VideoPortReadPortUchar(HwDeviceExtension->IOAddress +
+            GRAPH_DATA_PORT) != READ_MAP_TEST_SETTING) {
+
+        //
+        // The Read Map setting we just performed can't be read back; not a
+        // VGA. Restore the default Read Map state.
+        //
+
+        VideoPortWritePortUchar(HwDeviceExtension->IOAddress +
+                GRAPH_DATA_PORT, READ_MAP_DEFAULT);
+
+        return FALSE;
+    }
+
+    //
+    // Remember the original setting of the Bit Mask register.
+    //
+
+    VideoPortWritePortUchar(HwDeviceExtension->IOAddress +
+            GRAPH_ADDRESS_PORT, IND_BIT_MASK);
+    if ((VideoPortReadPortUchar(HwDeviceExtension->IOAddress +
+                GRAPH_ADDRESS_PORT) & GRAPH_ADDR_MASK) != IND_BIT_MASK) {
+
+        //
+        // The Graphics Address register setting we just made can't be read
+        // back; not a VGA. Restore the default Read Map state.
+        //
+
+        VideoPortWritePortUchar(HwDeviceExtension->IOAddress +
+                GRAPH_ADDRESS_PORT, IND_READ_MAP);
+        VideoPortWritePortUchar(HwDeviceExtension->IOAddress +
+                GRAPH_DATA_PORT, READ_MAP_DEFAULT);
+
+        return FALSE;
+    }
+
+    originalBitMask = VideoPortReadPortUchar(HwDeviceExtension->IOAddress +
+            GRAPH_DATA_PORT);
+
+    //
+    // Set up the initial test mask we'll write to and read from the Bit Mask.
+    //
+
+    testMask = 0xBB;
+
+    do {
+
+        //
+        // Write the test mask to the Bit Mask.
+        //
+
+        VideoPortWritePortUchar(HwDeviceExtension->IOAddress +
+                GRAPH_DATA_PORT, testMask);
+
+        //
+        // Make sure the Bit Mask remembered the value.
+        //
+
+        if (VideoPortReadPortUchar(HwDeviceExtension->IOAddress +
+                    GRAPH_DATA_PORT) != testMask) {
+
+            //
+            // The Bit Mask is not properly writable and readable; not a VGA.
+            // Restore the Bit Mask and Read Map to their default states.
+            //
+
+            VideoPortWritePortUchar(HwDeviceExtension->IOAddress +
+                    GRAPH_DATA_PORT, BIT_MASK_DEFAULT);
+            VideoPortWritePortUchar(HwDeviceExtension->IOAddress +
+                    GRAPH_ADDRESS_PORT, IND_READ_MAP);
+            VideoPortWritePortUchar(HwDeviceExtension->IOAddress +
+                    GRAPH_DATA_PORT, READ_MAP_DEFAULT);
+
+            return FALSE;
+        }
+
+        //
+        // Cycle the mask for next time.
+        //
+
+        testMask >>= 1;
+
+    } while (testMask != 0);
+
+    //
+    // There's something readable at GRAPH_DATA_PORT; now switch back and
+    // make sure that the Read Map register hasn't changed, to verify that
+    // we're dealing with indexed registers.
+    //
+
+    VideoPortWritePortUchar(HwDeviceExtension->IOAddress +
+            GRAPH_ADDRESS_PORT, IND_READ_MAP);
+    if (VideoPortReadPortUchar(HwDeviceExtension->IOAddress +
+                GRAPH_DATA_PORT) != READ_MAP_TEST_SETTING) {
+
+        //
+        // The Read Map is not properly writable and readable; not a VGA.
+        // Restore the Bit Mask and Read Map to their default states, in case
+        // this is an EGA, so subsequent writes to the screen aren't garbled.
+        //
+
+        VideoPortWritePortUchar(HwDeviceExtension->IOAddress +
+                GRAPH_DATA_PORT, READ_MAP_DEFAULT);
+        VideoPortWritePortUchar(HwDeviceExtension->IOAddress +
+                GRAPH_ADDRESS_PORT, IND_BIT_MASK);
+        VideoPortWritePortUchar(HwDeviceExtension->IOAddress +
+                GRAPH_DATA_PORT, BIT_MASK_DEFAULT);
+
+        return FALSE;
+    }
+
+    //
+    // We've pretty surely verified the existence of the Bit Mask register.
+    // Put the Graphics Controller back to the original state.
+    //
+
+    VideoPortWritePortUchar(HwDeviceExtension->IOAddress +
+            GRAPH_DATA_PORT, originalReadMap);
+    VideoPortWritePortUchar(HwDeviceExtension->IOAddress +
+            GRAPH_ADDRESS_PORT, IND_BIT_MASK);
+    VideoPortWritePortUchar(HwDeviceExtension->IOAddress +
+            GRAPH_DATA_PORT, originalBitMask);
+    VideoPortWritePortUchar(HwDeviceExtension->IOAddress +
+            GRAPH_ADDRESS_PORT, originalGCAddr);
+
+    //
+    // Now, check for the existence of the Chain4 bit.
+    //
+
+    //
+    // Remember the original states of the Sequencer Address and Memory Mode
+    // registers.
+    //
+
+    originalSCAddr = VideoPortReadPortUchar(HwDeviceExtension->IOAddress +
+            SEQ_ADDRESS_PORT);
+    VideoPortWritePortUchar(HwDeviceExtension->IOAddress +
+            SEQ_ADDRESS_PORT, IND_MEMORY_MODE);
+    if ((VideoPortReadPortUchar(HwDeviceExtension->IOAddress +
+            SEQ_ADDRESS_PORT) & SEQ_ADDR_MASK) != IND_MEMORY_MODE) {
+
+        //
+        // Couldn't read back the Sequencer Address register setting we just
+        // performed.
+        //
+
+        return FALSE;
+    }
+    originalMemoryMode = VideoPortReadPortUchar(HwDeviceExtension->IOAddress +
+            SEQ_DATA_PORT);
+
+    //
+    // Toggle the Chain4 bit and read back the result. This must be done during
+    // sync reset, since we're changing the chaining state.
+    //
+
+    //
+    // Begin sync reset.
+    //
+
+    VideoPortWritePortUshort((PUSHORT)(HwDeviceExtension->IOAddress +
+             SEQ_ADDRESS_PORT),
+             (IND_SYNC_RESET + (START_SYNC_RESET_VALUE << 8)));
+
+    //
+    // Toggle the Chain4 bit.
+    //
+
+    VideoPortWritePortUchar(HwDeviceExtension->IOAddress +
+            SEQ_ADDRESS_PORT, IND_MEMORY_MODE);
+    VideoPortWritePortUchar(HwDeviceExtension->IOAddress +
+            SEQ_DATA_PORT, (UCHAR)(originalMemoryMode ^ CHAIN4_MASK));
+
+    if (VideoPortReadPortUchar(HwDeviceExtension->IOAddress +
+                SEQ_DATA_PORT) != (UCHAR) (originalMemoryMode ^ CHAIN4_MASK)) {
+
+        //
+        // Chain4 bit not there; not a VGA.
+        // Set text mode default for Memory Mode register.
+        //
+
+        VideoPortWritePortUchar(HwDeviceExtension->IOAddress +
+                SEQ_DATA_PORT, MEMORY_MODE_TEXT_DEFAULT);
+        //
+        // End sync reset.
+        //
+
+        VideoPortWritePortUshort((PUSHORT) (HwDeviceExtension->IOAddress +
+                SEQ_ADDRESS_PORT),
+                (IND_SYNC_RESET + (END_SYNC_RESET_VALUE << 8)));
+
+        returnStatus = FALSE;
+
+    } else {
+
+        //
+        // It's a VGA.
+        //
+
+        //
+        // Restore the original Memory Mode setting.
+        //
+
+        VideoPortWritePortUchar(HwDeviceExtension->IOAddress +
+                SEQ_DATA_PORT, originalMemoryMode);
+
+        //
+        // End sync reset.
+        //
+
+        VideoPortWritePortUshort((PUSHORT)(HwDeviceExtension->IOAddress +
+                SEQ_ADDRESS_PORT),
+                (USHORT)(IND_SYNC_RESET + (END_SYNC_RESET_VALUE << 8)));
+
+        //
+        // Restore the original Sequencer Address setting.
+        //
+
+        VideoPortWritePortUchar(HwDeviceExtension->IOAddress +
+                SEQ_ADDRESS_PORT, originalSCAddr);
+
+        returnStatus = TRUE;
+    }
+
+    return returnStatus;
+
+} // VgaIsPresent()
+\f
+
+//---------------------------------------------------------------------------
+VP_STATUS
+VgaSetColorLookup(
+    PHW_DEVICE_EXTENSION HwDeviceExtension,
+    PVIDEO_CLUT ClutBuffer,
+    ULONG ClutBufferSize
+    )
+
+/*++
+
+Routine Description:
+
+    This routine sets a specified portion of the DAC color lookup table
+    settings.
+
+Arguments:
+
+    HwDeviceExtension - Pointer to the miniport driver's device extension.
+
+    ClutBufferSize - Length of the input buffer supplied by the user.
+
+    ClutBuffer - Pointer to the structure containing the color lookup table.
+
+Return Value:
+
+    NO_ERROR - information returned successfully
+
+    ERROR_INSUFFICIENT_BUFFER - input buffer not large enough for input data.
+
+    ERROR_INVALID_PARAMETER - invalid clut size.
+
+--*/
+
+{
+    PVIDEOMODE CurrentMode = HwDeviceExtension->CurrentMode;
+    USHORT i;
+    
+    //
+    // Check if the size of the data in the input buffer is large enough.
+    //
+
+    if ( (ClutBufferSize < sizeof(VIDEO_CLUT) - sizeof(ULONG)) ||
+         (ClutBufferSize < sizeof(VIDEO_CLUT) +
+                     (sizeof(ULONG) * (ClutBuffer->NumEntries - 1)) ) ) {
+
+        return ERROR_INSUFFICIENT_BUFFER;
+
+    }
+
+    //
+    // Check to see if the parameters are valid.
+    //
+
+    if ( (ClutBuffer->NumEntries == 0) ||
+         (ClutBuffer->FirstEntry > VIDEO_MAX_COLOR_REGISTER) ||
+         (ClutBuffer->FirstEntry + ClutBuffer->NumEntries >
+             VIDEO_MAX_COLOR_REGISTER + 1) ) {
+
+        return ERROR_INVALID_PARAMETER;
+
+    }
+// eVb: 1.14 [VBE] - Add VBE color support
+    //
+    // Check SVGA mode
+    //
+    
+    if (CurrentMode->bitsPerPlane >= 8) return VbeSetColorLookup(HwDeviceExtension, ClutBuffer);
+// eVb: 1.14 [END]    
+    //
+    // Path for VGA mode
+    //
+// eVb: 1.15 [VBE] - Add VBE support for non-VGA-compatible detected modes
+    if (!CurrentMode->NonVgaMode)
+    {
+// eVb: 1.15 [END]
+        //
+        //  Set CLUT registers directly on the hardware
+        //
+
+        VideoPortWritePortUchar(HwDeviceExtension->IOAddress +
+                DAC_ADDRESS_WRITE_PORT, (UCHAR) ClutBuffer->FirstEntry);
+
+        for (i = 0; i < ClutBuffer->NumEntries; i++) {
+            VideoPortWritePortUchar(HwDeviceExtension->IOAddress +
+                                    DAC_ADDRESS_WRITE_PORT,
+                                    (UCHAR)(i + ClutBuffer->FirstEntry));
+
+            VideoPortWritePortUchar(HwDeviceExtension->IOAddress +
+                                    DAC_DATA_REG_PORT,
+                                    ClutBuffer->LookupTable[i].RgbArray.Red);
+
+            VideoPortWritePortUchar(HwDeviceExtension->IOAddress +
+                                    DAC_DATA_REG_PORT,
+                                    ClutBuffer->LookupTable[i].RgbArray.Green);
+
+            VideoPortWritePortUchar(HwDeviceExtension->IOAddress +
+                                    DAC_DATA_REG_PORT,
+                                    ClutBuffer->LookupTable[i].RgbArray.Blue);
+        }
+        return NO_ERROR;
+    }
+
+    return ERROR_INVALID_PARAMETER;
+
+} // end VgaSetColorLookup()
+\f
+VP_STATUS
+GetDeviceDataCallback(
+    PVOID HwDeviceExtension,
+    PVOID Context,
+    VIDEO_DEVICE_DATA_TYPE DeviceDataType,
+    PVOID Identifier,
+    ULONG IdentifierLength,
+    PVOID ConfigurationData,
+    ULONG ConfigurationDataLength,
+    PVOID ComponentInformation,
+    ULONG ComponentInformationLength
+    )
+
+/*++
+
+Routine Description:
+
+    Callback routine for the VideoPortGetDeviceData function.
+
+Arguments:
+
+    HwDeviceExtension - Pointer to the miniport drivers device extension.
+
+    Context - Context value passed to the VideoPortGetDeviceData function.
+
+    DeviceDataType - The type of data that was requested in
+        VideoPortGetDeviceData.
+
+    Identifier - Pointer to a string that contains the name of the device,
+        as setup by the ROM or ntdetect.
+
+    IdentifierLength - Length of the Identifier string.
+
+    ConfigurationData - Pointer to the configuration data for the device or
+        BUS.
+
+    ConfigurationDataLength - Length of the data in the configurationData
+        field.
+
+    ComponentInformation - Undefined.
+
+    ComponentInformationLength - Undefined.
+
+Return Value:
+
+    Returns NO_ERROR if the function completed properly.
+    Returns ERROR_DEV_NOT_EXIST if we did not find the device.
+    Returns ERROR_INVALID_PARAMETER otherwise.
+
+--*/
+
+{
+    VideoPortDebugPrint(Error, "Detected internal VGA chip on embedded board, todo\n");
+    while (TRUE);
+    return NO_ERROR;
+
+} //end GetDeviceDataCallback()
+
+// eVb: 1.16 [RESOURCE] - Add new function for acquiring VGA resources (I/O, memory)
+VP_STATUS
+VgaAcquireResources(
+    PHW_DEVICE_EXTENSION DeviceExtension
+    )
+{
+    VP_STATUS Status = NO_ERROR;
+    ULONG Ranges, i;
+    
+    //
+    // Try exclusive ranges (vga + ati)
+    //
+    
+    Ranges = NUM_VGA_ACCESS_RANGES;
+    for (i = 0; i < Ranges; i++) VgaAccessRange[i].RangeShareable = FALSE;
+    if (VideoPortVerifyAccessRanges(DeviceExtension, Ranges, VgaAccessRange) != NO_ERROR)
+    {
+        //
+        // Not worked, try vga only
+        //
+        
+        Ranges = 3;
+        if (VideoPortVerifyAccessRanges(DeviceExtension, Ranges, VgaAccessRange) != NO_ERROR)
+        {
+            //
+            // Still not, try shared ranges
+            //
+            
+            for (i = 0; i < Ranges; i++) VgaAccessRange[i].RangeShareable = TRUE;
+            Status = VideoPortVerifyAccessRanges(DeviceExtension, Ranges, VgaAccessRange);
+            if (Status == NO_ERROR)
+            {
+                //
+                // It did work
+                //
+                
+                VideoPortVerifyAccessRanges(DeviceExtension, 0, 0);
+                Status = NO_ERROR;
+            }
+        }
+    }
+
+    if (Status == NO_ERROR)
+    {
+        //
+        // Worked with exclusive, also try shared
+        //
+        
+        for (i = 0; i < Ranges; i++) VgaAccessRange[i].RangeShareable = TRUE;
+        Status = VideoPortVerifyAccessRanges(DeviceExtension, Ranges, VgaAccessRange);
+    }
+
+    return Status;
+}
+// eVb: 1.16 [END]
diff --git a/reactos/drivers/video/miniport/vga_new/vga.h b/reactos/drivers/video/miniport/vga_new/vga.h
new file mode 100644 (file)
index 0000000..21e4115
--- /dev/null
@@ -0,0 +1,446 @@
+/*
+ * PROJECT:         ReactOS VGA Miniport Driver
+ * LICENSE:         Microsoft NT4 DDK Sample Code License
+ * FILE:            boot/drivers/video/miniport/vga/vga.h
+ * PURPOSE:         Main Header File
+ * PROGRAMMERS:     Copyright (c) 1992  Microsoft Corporation
+ *                  ReactOS Portable Systems Group
+ */
+
+#include "ntdef.h"
+#include "dderror.h"
+#include "devioctl.h"
+#include "miniport.h"
+#include "ntddvdeo.h"
+#include "video.h"
+#include "cmdcnst.h"
+
+//
+// Base address of VGA memory range.  Also used as base address of VGA
+// memory when loading a font, which is done with the VGA mapped at A0000.
+//
+
+#define MEM_VGA      0xA0000
+#define MEM_VGA_SIZE 0x20000
+
+//
+// For memory mapped IO
+//
+
+#define MEMORY_MAPPED_IO_OFFSET (0xB8000 - 0xA0000)
+
+//
+// Port definitions for filling the ACCESS_RANGES structure in the miniport
+// information, defines the range of I/O ports the VGA spans.
+// There is a break in the IO ports - a few ports are used for the parallel
+// port. Those cannot be defined in the ACCESS_RANGE, but are still mapped
+// so all VGA ports are in one address range.
+//
+
+#define VGA_BASE_IO_PORT      0x000003B0
+#define VGA_START_BREAK_PORT  0x000003BB
+#define VGA_END_BREAK_PORT    0x000003C0
+#define VGA_MAX_IO_PORT       0x000003DF
+
+//
+// VGA register definitions
+//
+// eVb: 3.1 [VGA] - Use offsets from the VGA Port Address instead of absolute
+#define CRTC_ADDRESS_PORT_MONO      0x0004  // CRT Controller Address and
+#define CRTC_DATA_PORT_MONO         0x0005  // Data registers in mono mode
+#define FEAT_CTRL_WRITE_PORT_MONO   0x000A  // Feature Control write port
+                                            // in mono mode
+#define INPUT_STATUS_1_MONO         0x000A  // Input Status 1 register read
+                                            // port in mono mode
+#define ATT_INITIALIZE_PORT_MONO    INPUT_STATUS_1_MONO
+                                            // Register to read to reset
+                                            // Attribute Controller index/data
+
+#define ATT_ADDRESS_PORT            0x0010  // Attribute Controller Address and
+#define ATT_DATA_WRITE_PORT         0x0010  // Data registers share one port
+                                            // for writes, but only Address is
+                                            // readable at 0x3C0
+#define ATT_DATA_READ_PORT          0x0011  // Attribute Controller Data reg is
+                                            // readable here
+#define MISC_OUTPUT_REG_WRITE_PORT  0x0012  // Miscellaneous Output reg write
+                                            // port
+#define INPUT_STATUS_0_PORT         0x0012  // Input Status 0 register read
+                                            // port
+#define VIDEO_SUBSYSTEM_ENABLE_PORT 0x0013  // Bit 0 enables/disables the
+                                            // entire VGA subsystem
+#define SEQ_ADDRESS_PORT            0x0014  // Sequence Controller Address and
+#define SEQ_DATA_PORT               0x0015  // Data registers
+#define DAC_PIXEL_MASK_PORT         0x0016  // DAC pixel mask reg
+#define DAC_ADDRESS_READ_PORT       0x0017  // DAC register read index reg,
+                                            // write-only
+#define DAC_STATE_PORT              0x0017  // DAC state (read/write),
+                                            // read-only
+#define DAC_ADDRESS_WRITE_PORT      0x0018  // DAC register write index reg
+#define DAC_DATA_REG_PORT           0x0019  // DAC data transfer reg
+#define FEAT_CTRL_READ_PORT         0x001A  // Feature Control read port
+#define MISC_OUTPUT_REG_READ_PORT   0x001C  // Miscellaneous Output reg read
+                                            // port
+#define GRAPH_ADDRESS_PORT          0x001E  // Graphics Controller Address
+#define GRAPH_DATA_PORT             0x001F  // and Data registers
+
+#define CRTC_ADDRESS_PORT_COLOR     0x0024  // CRT Controller Address and
+#define CRTC_DATA_PORT_COLOR        0x0025  // Data registers in color mode
+#define FEAT_CTRL_WRITE_PORT_COLOR  0x002A  // Feature Control write port
+#define INPUT_STATUS_1_COLOR        0x002A  // Input Status 1 register read
+                                            // port in color mode
+// eVb: 3.2 [END]
+#define ATT_INITIALIZE_PORT_COLOR   INPUT_STATUS_1_COLOR
+                                            // Register to read to reset
+                                            // Attribute Controller index/data
+                                            // toggle in color mode
+
+//
+// Offsets in HardwareStateHeader->PortValue[] of save areas for non-indexed
+// VGA registers.
+//
+
+#define CRTC_ADDRESS_MONO_OFFSET      0x04
+#define FEAT_CTRL_WRITE_MONO_OFFSET   0x0A
+#define ATT_ADDRESS_OFFSET            0x10
+#define MISC_OUTPUT_REG_WRITE_OFFSET  0x12
+#define VIDEO_SUBSYSTEM_ENABLE_OFFSET 0x13
+#define SEQ_ADDRESS_OFFSET            0x14
+#define DAC_PIXEL_MASK_OFFSET         0x16
+#define DAC_STATE_OFFSET              0x17
+#define DAC_ADDRESS_WRITE_OFFSET      0x18
+#define GRAPH_ADDRESS_OFFSET          0x1E
+#define CRTC_ADDRESS_COLOR_OFFSET     0x24
+#define FEAT_CTRL_WRITE_COLOR_OFFSET  0x2A
+
+                                            // toggle in color mode
+//
+// VGA indexed register indexes.
+//
+
+// CL-GD542x specific registers:
+//
+#define IND_CL_EXTS_ENB         0x06    // index in Sequencer to enable exts
+#define IND_NORD_SCRATCH_PAD    0x09    // index in Seq of Nordic scratch pad
+#define IND_CL_SCRATCH_PAD      0x0A    // index in Seq of 542x scratch pad
+#define IND_ALP_SCRATCH_PAD     0x15    // index in Seq of Alpine scratch pad
+#define IND_CL_REV_REG          0x25    // index in CRTC of ID Register
+#define IND_CL_ID_REG           0x27    // index in CRTC of ID Register
+//
+#define IND_CURSOR_START        0x0A    // index in CRTC of the Cursor Start
+#define IND_CURSOR_END          0x0B    //  and End registers
+#define IND_CURSOR_HIGH_LOC     0x0E    // index in CRTC of the Cursor Location
+#define IND_CURSOR_LOW_LOC      0x0F    //  High and Low Registers
+#define IND_VSYNC_END           0x11    // index in CRTC of the Vertical Sync
+                                        //  End register, which has the bit
+                                        //  that protects/unprotects CRTC
+                                        //  index registers 0-7
+#define IND_CR2C                0x2C    // Nordic LCD Interface Register
+#define IND_CR2D                0x2D    // Nordic LCD Display Control
+#define IND_SET_RESET_ENABLE    0x01    // index of Set/Reset Enable reg in GC
+#define IND_DATA_ROTATE         0x03    // index of Data Rotate reg in GC
+#define IND_READ_MAP            0x04    // index of Read Map reg in Graph Ctlr
+#define IND_GRAPH_MODE          0x05    // index of Mode reg in Graph Ctlr
+#define IND_GRAPH_MISC          0x06    // index of Misc reg in Graph Ctlr
+#define IND_BIT_MASK            0x08    // index of Bit Mask reg in Graph Ctlr
+#define IND_SYNC_RESET          0x00    // index of Sync Reset reg in Seq
+#define IND_MAP_MASK            0x02    // index of Map Mask in Sequencer
+#define IND_MEMORY_MODE         0x04    // index of Memory Mode reg in Seq
+#define IND_CRTC_PROTECT        0x11    // index of reg containing regs 0-7 in
+                                        //  CRTC
+#define IND_CRTC_COMPAT         0x34    // index of CRTC Compatibility reg
+                                        //  in CRTC
+#define IND_PERF_TUNING         0x16    // index of performance tuning in Seq
+#define START_SYNC_RESET_VALUE  0x01    // value for Sync Reset reg to start
+                                        //  synchronous reset
+#define END_SYNC_RESET_VALUE    0x03    // value for Sync Reset reg to end
+                                        //  synchronous reset
+
+//
+// Value to write to Extensions Control register values extensions.
+//
+
+#define CL64xx_EXTENSION_ENABLE_INDEX     0x0A     // GR0A to be exact!
+#define CL64xx_EXTENSION_ENABLE_VALUE     0xEC
+#define CL64xx_EXTENSION_DISABLE_VALUE    0xCE
+#define CL64xx_TRISTATE_CONTROL_REG       0xA1
+
+#define CL6340_ENABLE_READBACK_REGISTER   0xE0
+#define CL6340_ENABLE_READBACK_ALLSEL_VALUE 0xF0
+#define CL6340_ENABLE_READBACK_OFF_VALUE  0x00
+#define CL6340_IDENTIFICATION_REGISTER    0xE9
+//
+// Values for Attribute Controller Index register to turn video off
+// and on, by setting bit 5 to 0 (off) or 1 (on).
+//
+
+#define VIDEO_DISABLE 0
+#define VIDEO_ENABLE  0x20
+
+#define INDEX_ENABLE_AUTO_START 0x31
+
+// Masks to keep only the significant bits of the Graphics Controller and
+// Sequencer Address registers. Masking is necessary because some VGAs, such
+// as S3-based ones, don't return unused bits set to 0, and some SVGAs use
+// these bits if extensions are enabled.
+//
+
+#define GRAPH_ADDR_MASK 0x0F
+#define SEQ_ADDR_MASK   0x07
+
+//
+// Mask used to toggle Chain4 bit in the Sequencer's Memory Mode register.
+//
+
+#define CHAIN4_MASK 0x08
+
+//
+// Value written to the Read Map register when identifying the existence of
+// a VGA in VgaInitialize. This value must be different from the final test
+// value written to the Bit Mask in that routine.
+//
+
+#define READ_MAP_TEST_SETTING 0x03
+
+//
+// Default text mode setting for various registers, used to restore their
+// states if VGA detection fails after they've been modified.
+//
+
+#define MEMORY_MODE_TEXT_DEFAULT 0x02
+#define BIT_MASK_DEFAULT 0xFF
+#define READ_MAP_DEFAULT 0x00
+
+\f
+//
+// Palette-related info.
+//
+
+//
+// Highest valid DAC color register index.
+//
+
+#define VIDEO_MAX_COLOR_REGISTER  0xFF
+
+//
+// Highest valid palette register index
+//
+
+#define VIDEO_MAX_PALETTE_REGISTER 0x0F
+
+//
+// Driver Specific Attribute Flags
+//
+
+#define CAPS_NO_HOST_XFER       0x00000002   // Do not use host xfers to
+                                             //   the blt engine.
+#define CAPS_SW_POINTER         0x00000004   // Use software pointer.
+#define CAPS_TRUE_COLOR         0x00000008   // Set upper color registers.
+#define CAPS_MM_IO              0x00000010   // Use memory mapped IO.
+#define CAPS_BLT_SUPPORT        0x00000020   // BLTs are supported
+#define CAPS_IS_542x            0x00000040   // This is a 542x
+#define CAPS_IS_5436            0x00000080   // This is a 5436
+#define CAPS_CURSOR_VERT_EXP    0x00000100   // Flag set if 8x6 panel,
+                                             //   but 6x4 resolution
+
+//
+// Structure used to describe each video mode in ModesVGA[].
+//
+
+typedef struct {
+    USHORT  fbType; // color or monochrome, text or graphics, via
+                    //  VIDEO_MODE_COLOR and VIDEO_MODE_GRAPHICS
+    USHORT  numPlanes;    // # of video memory planes
+    USHORT  bitsPerPlane; // # of bits of color in each plane
+    SHORT   col;    // # of text columns across screen with default font
+    SHORT   row;    // # of text rows down screen with default font
+    USHORT  hres;   // # of pixels across screen
+    USHORT  vres;   // # of scan lines down screen
+// eVb: 3.2 [VGA] - Store frequency next to resolution data
+    ULONG   Frequency;         // Vertical Frequency
+// eVb: 3.2 [END]
+    USHORT  wbytes; // # of bytes from start of one scan line to start of next
+    ULONG   sbytes; // total size of addressable display memory in bytes
+// eVb: 3.3 [VBE] - Add VBE mode and bank flag
+    ULONG NoBankSwitch;
+    ULONG Mode;
+// eVb: 3.3 [VBE]
+    PUSHORT CmdStream;   // pointer to array of register-setting commands to
+                                         //  set up mode
+// eVb: 3.4 [VBE] - Add fields to track linear addresses/sizes and flags                      
+    ULONG PhysBase;
+    ULONG FrameBufferBase;
+    ULONG FrameBufferSize;
+    ULONG PhysSize;
+    ULONG LogicalWidth;
+    ULONG NonVgaMode;
+    ULONG Granularity;
+// eVb: 3.4 [END]
+} VIDEOMODE, *PVIDEOMODE;
+
+//
+// Mode into which to put the VGA before starting a VDM, so it's a plain
+// vanilla VGA.  (This is the mode's index in ModesVGA[], currently standard
+// 80x25 text mode.)
+//
+
+#define DEFAULT_MODE 0
+
+\f
+//
+// Info used by the Validator functions and save/restore code.
+// Structure used to trap register accesses that must be done atomically.
+//
+
+#define VGA_MAX_VALIDATOR_DATA             100
+
+#define VGA_VALIDATOR_UCHAR_ACCESS   1
+#define VGA_VALIDATOR_USHORT_ACCESS  2
+#define VGA_VALIDATOR_ULONG_ACCESS   3
+
+typedef struct _VGA_VALIDATOR_DATA {
+   ULONG Port;
+   UCHAR AccessType;
+   ULONG Data;
+} VGA_VALIDATOR_DATA, *PVGA_VALIDATOR_DATA;
+
+//
+// Number of bytes to save in each plane.
+//
+
+#define VGA_PLANE_SIZE 0x10000
+
+//
+// Number of each type of indexed register in a standard VGA, used by
+// validator and state save/restore functions.
+//
+// Note: VDMs currently only support basic VGAs only.
+//
+
+#define VGA_NUM_SEQUENCER_PORTS     5
+#define VGA_NUM_CRTC_PORTS         25
+#define VGA_NUM_GRAPH_CONT_PORTS    9
+#define VGA_NUM_ATTRIB_CONT_PORTS  21
+#define VGA_NUM_DAC_ENTRIES       256
+
+#define EXT_NUM_GRAPH_CONT_PORTS    0
+#define EXT_NUM_SEQUENCER_PORTS     0
+#define EXT_NUM_CRTC_PORTS          0
+#define EXT_NUM_ATTRIB_CONT_PORTS   0
+#define EXT_NUM_DAC_ENTRIES         0
+
+//
+// These constants determine the offsets within the
+// VIDEO_HARDWARE_STATE_HEADER structure that are used to save and
+// restore the VGA's state.
+//
+
+#define VGA_HARDWARE_STATE_SIZE sizeof(VIDEO_HARDWARE_STATE_HEADER)
+
+#define VGA_BASIC_SEQUENCER_OFFSET (VGA_HARDWARE_STATE_SIZE + 0)
+#define VGA_BASIC_CRTC_OFFSET (VGA_BASIC_SEQUENCER_OFFSET + \
+         VGA_NUM_SEQUENCER_PORTS)
+#define VGA_BASIC_GRAPH_CONT_OFFSET (VGA_BASIC_CRTC_OFFSET + \
+         VGA_NUM_CRTC_PORTS)
+#define VGA_BASIC_ATTRIB_CONT_OFFSET (VGA_BASIC_GRAPH_CONT_OFFSET + \
+         VGA_NUM_GRAPH_CONT_PORTS)
+#define VGA_BASIC_DAC_OFFSET (VGA_BASIC_ATTRIB_CONT_OFFSET + \
+         VGA_NUM_ATTRIB_CONT_PORTS)
+#define VGA_BASIC_LATCHES_OFFSET (VGA_BASIC_DAC_OFFSET + \
+         (3 * VGA_NUM_DAC_ENTRIES))
+
+#define VGA_EXT_SEQUENCER_OFFSET (VGA_BASIC_LATCHES_OFFSET + 4)
+#define VGA_EXT_CRTC_OFFSET (VGA_EXT_SEQUENCER_OFFSET + \
+         EXT_NUM_SEQUENCER_PORTS)
+#define VGA_EXT_GRAPH_CONT_OFFSET (VGA_EXT_CRTC_OFFSET + \
+         EXT_NUM_CRTC_PORTS)
+#define VGA_EXT_ATTRIB_CONT_OFFSET (VGA_EXT_GRAPH_CONT_OFFSET +\
+         EXT_NUM_GRAPH_CONT_PORTS)
+#define VGA_EXT_DAC_OFFSET (VGA_EXT_ATTRIB_CONT_OFFSET + \
+         EXT_NUM_ATTRIB_CONT_PORTS)
+
+#define VGA_VALIDATOR_OFFSET (VGA_EXT_DAC_OFFSET + 4 * EXT_NUM_DAC_ENTRIES)
+
+#define VGA_VALIDATOR_AREA_SIZE  sizeof (ULONG) + (VGA_MAX_VALIDATOR_DATA * \
+                                 sizeof (VGA_VALIDATOR_DATA)) +             \
+                                 sizeof (ULONG) +                           \
+                                 sizeof (ULONG) +                           \
+                                 sizeof (PVIDEO_ACCESS_RANGE)
+
+#define VGA_MISC_DATA_AREA_OFFSET VGA_VALIDATOR_OFFSET + VGA_VALIDATOR_AREA_SIZE
+
+#define VGA_MISC_DATA_AREA_SIZE  0
+
+#define VGA_PLANE_0_OFFSET VGA_MISC_DATA_AREA_OFFSET + VGA_MISC_DATA_AREA_SIZE
+
+#define VGA_PLANE_1_OFFSET VGA_PLANE_0_OFFSET + VGA_PLANE_SIZE
+#define VGA_PLANE_2_OFFSET VGA_PLANE_1_OFFSET + VGA_PLANE_SIZE
+#define VGA_PLANE_3_OFFSET VGA_PLANE_2_OFFSET + VGA_PLANE_SIZE
+
+//
+// Space needed to store all state data.
+//
+
+#define VGA_TOTAL_STATE_SIZE VGA_PLANE_3_OFFSET + VGA_PLANE_SIZE
+
+\f
+//
+// Device extension for the driver object.  This data is only used
+// locally, so this structure can be added to as needed.
+//
+
+typedef struct _HW_DEVICE_EXTENSION {
+
+    PHYSICAL_ADDRESS PhysicalVideoMemoryBase; // physical memory address and
+    PHYSICAL_ADDRESS PhysicalFrameOffset;     // physical memory address and
+    ULONG PhysicalVideoMemoryLength;          // length of display memory
+    ULONG PhysicalFrameLength;                // length of display memory for
+                                              // the current mode.
+
+    PUCHAR  IOAddress;            // base I/O address of VGA ports
+    PUCHAR  VideoMemoryAddress;   // base virtual memory address of VGA memory
+    ULONG   ModeIndex;            // index of current mode in ModesVGA[]
+    PVIDEOMODE  CurrentMode;      // pointer to VIDEOMODE structure for
+                                  // current mode
+
+    VIDEO_CURSOR_POSITION CursorPosition;  // current cursor position
+
+    UCHAR CursorEnable;           // whether cursor is enabled or not
+    UCHAR CursorTopScanLine;      // Cursor Start register setting (top scan)
+    UCHAR CursorBottomScanLine;   // Cursor End register setting (bottom scan)
+// eVb: 3.5 [VBE] - Add fields for VBE support and XP+ INT10 interface  
+    VIDEO_PORT_INT10_INTERFACE Int10Interface;
+    BOOLEAN VesaBiosOk;
+// eVb: 3.5 [END]
+} HW_DEVICE_EXTENSION, *PHW_DEVICE_EXTENSION;
+
+\f
+//
+// Function prototypes.
+//
+
+//
+// Entry points for the VGA validator. Used in VgaEmulatorAccessEntries[].
+//
+
+
+//
+// Vga init scripts for font loading
+//
+
+extern USHORT EnableA000Data[];
+extern USHORT DisableA000Color[];
+
+//
+// Mode Information
+//
+
+extern ULONG NumVideoModes;
+extern VIDEOMODE ModesVGA[];
+extern PVIDEOMODE VgaModeList;
+
+// eVb: 3.5 [VGA] - Add ATI/Mach64 Access Range    
+#define NUM_VGA_ACCESS_RANGES  5
+// eVb: 3.5 [END]
+extern VIDEO_ACCESS_RANGE VgaAccessRange[];
+
+#include "vbe.h"
diff --git a/reactos/drivers/video/miniport/vga_new/vga.rbuild b/reactos/drivers/video/miniport/vga_new/vga.rbuild
new file mode 100644 (file)
index 0000000..622440d
--- /dev/null
@@ -0,0 +1,18 @@
+<?xml version="1.0"?>
+<!DOCTYPE module SYSTEM "../../../../tools/rbuild/project.dtd">
+<module name="vga" type="kernelmodedriver" installbase="system32/drivers" installname="vga.sys">
+       <include base="vga">.</include>
+       <library>videoprt</library>
+       <library>libcntpr</library>
+       <file>modeset.c</file>
+       <file>vgadata.c</file>
+       <file>vga.c</file>
+       <file>vbemodes.c</file>
+       <file>vbe.c</file>
+       <file>vga.rc</file>
+       <pch>vga.h</pch>
+       <group compilerset="gcc">
+        <compilerflag>-mrtd</compilerflag>
+        <compilerflag>-fno-builtin</compilerflag>
+    </group>
+</module>
diff --git a/reactos/drivers/video/miniport/vga_new/vga.rc b/reactos/drivers/video/miniport/vga_new/vga.rc
new file mode 100644 (file)
index 0000000..4aac6fd
--- /dev/null
@@ -0,0 +1,5 @@
+#define REACTOS_VERSION_DLL
+#define REACTOS_STR_FILE_DESCRIPTION   "VGA Miniport Device Driver\0"
+#define REACTOS_STR_INTERNAL_NAME          "vga\0"
+#define REACTOS_STR_ORIGINAL_FILENAME  "vga.sys\0"
+#include <reactos/version.rc>
diff --git a/reactos/drivers/video/miniport/vga_new/vgadata.c b/reactos/drivers/video/miniport/vga_new/vgadata.c
new file mode 100644 (file)
index 0000000..6f9ea0f
--- /dev/null
@@ -0,0 +1,490 @@
+/*
+ * PROJECT:         ReactOS VGA Miniport Driver
+ * LICENSE:         Microsoft NT4 DDK Sample Code License
+ * FILE:            boot/drivers/video/miniport/vga/vgadata.c
+ * PURPOSE:         Handles switching to VGA Modes and holds VGA Built-in Modes
+ * PROGRAMMERS:     Copyright (c) 1992  Microsoft Corporation
+ *                  ReactOS Portable Systems Group
+ */
+
+#include "vga.h"
+
+//
+// This structure describes to which ports access is required.
+//
+
+VIDEO_ACCESS_RANGE VgaAccessRange[] = {
+{
+    {{VGA_BASE_IO_PORT, 0x00000000}},            // 64-bit linear base address
+                                                 // of range
+    VGA_START_BREAK_PORT - VGA_BASE_IO_PORT + 1, // # of ports
+    1,                                           // range is in I/O space
+    1,                                           // range should be visible
+    0                                            // range should be shareable
+},
+{
+    {{VGA_END_BREAK_PORT, 0x00000000}},
+    VGA_MAX_IO_PORT - VGA_END_BREAK_PORT + 1,
+    1,
+    1,
+    0
+},
+
+//
+// This next region also includes Memory mapped IO.  In MMIO, the ports are
+// repeated every 256 bytes from b8000 to bff00.
+//
+
+{
+    {{MEM_VGA, 0x00000000}},
+    MEM_VGA_SIZE,
+    0,
+    1,
+    0
+},
+// eVb: 4.1 [VGA] - Add ATI/Mach64 VGA registers
+//
+// ATI Registers
+//
+
+{
+    {{0x1CE, 0x00000000}},
+    2,
+    1,
+    1,
+    0
+},
+{
+    {{0x2E8, 0x00000000}},
+    8,
+    1,
+    1,
+    0
+}
+// eVb: 4.1 [END]
+};
+
+//
+// 640x480 256-color 60Hz mode (BIOS mode 12) set command string for
+// VGA.
+//
+// eVb: 4.2 [VGA] - Add VGA command streams instead of Cirrus
+USHORT VGA_640x480[] = {
+    OWM,                            // begin setmode
+    SEQ_ADDRESS_PORT,
+    5,                              // count
+    0x100,                          // start sync reset
+    0x0101,0x0F02,0x0003,0x0604,    // program up sequencer
+
+    OB,                             // misc. register
+    MISC_OUTPUT_REG_WRITE_PORT,
+    0xE3,
+
+    OW,                             // text/graphics bit
+    GRAPH_ADDRESS_PORT,
+    0x506,
+    
+    OW,                             // end sync reset
+    SEQ_ADDRESS_PORT,
+    IND_SYNC_RESET,
+
+    OB,
+    SEQ_DATA_PORT,
+    END_SYNC_RESET_VALUE,
+
+    OW,                             // unprotect crtc 0-7
+    CRTC_ADDRESS_PORT_COLOR,
+    0x511,                        
+
+    METAOUT+INDXOUT,                // program gdc registers
+    GRAPH_ADDRESS_PORT,
+    VGA_NUM_CRTC_PORTS,0,            // count, startindex
+    0x5F,0x4F,0x50,0x82,0x54,0x80,0x0B,0x3E,0x00,0x40,0x0,0x0,0x0,0x0,0x0,0x0,
+    0xEA,0x8C,0xDF,0x28,0x0,0xE7,0x4,0xE3,0xFF,
+
+    IB,                             // prepare atc for writing
+    INPUT_STATUS_1_COLOR,
+
+    METAOUT+ATCOUT,                 // program atc registers
+    ATT_ADDRESS_PORT,
+    VGA_NUM_ATTRIB_CONT_PORTS,0,    // count, startindex
+    0x00, 0x01, 0x02, 0x03, 0x04, 0x05,
+    0x17, 0x38, 0x39, 0x3A, 0x3B, 0x3C,
+    0x3D, 0x3E, 0x3F, 0x3F, 0x01, 0x00,
+    0x0F, 0x00, 0x00,
+
+    METAOUT+INDXOUT,                // program gdc registers
+    GRAPH_ADDRESS_PORT,
+    VGA_NUM_GRAPH_CONT_PORTS,0,     // count, startindex
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+    0x05, 0x0F, 0xFF,
+
+    OB,
+    DAC_PIXEL_MASK_PORT,
+    0xFF,
+
+    IB,                             // prepare atc for writing
+    INPUT_STATUS_1_COLOR,
+    
+    OB,                             // turn video on.
+    ATT_ADDRESS_PORT,
+    VIDEO_ENABLE,
+
+    EOD
+};
+
+//
+// 720x400 color text mode (BIOS mode 3) set command string for
+// VGA.
+//
+
+USHORT VGA_TEXT_0[] = {
+    OWM,                            // begin setmode
+    SEQ_ADDRESS_PORT,
+    5,                              // count
+    0x100,                          // start sync reset
+    0x0101,0x0302,0x0003,0x0204,    // program up sequencer
+
+    OB,                             // misc. register
+    MISC_OUTPUT_REG_WRITE_PORT,
+    0x67,
+
+    OW,                             // text/graphics bit
+    GRAPH_ADDRESS_PORT,
+    0x0e06,
+    
+    OW,                             // end sync reset
+    SEQ_ADDRESS_PORT,
+    IND_SYNC_RESET,
+
+    OB,
+    SEQ_DATA_PORT,
+    END_SYNC_RESET_VALUE,
+
+    OW,                             // unprotect crtc 0-7
+    CRTC_ADDRESS_PORT_COLOR,
+    0xE11,                        
+
+    METAOUT+INDXOUT,                // program gdc registers
+    GRAPH_ADDRESS_PORT,
+    VGA_NUM_CRTC_PORTS,0,           // count, startindex
+    0x5F,0x4F,0x50,0x82,0x55,0x81,0xBF,0x1F,0x00,0x4F,0xD,0xE,0x0,0x0,0x0,0x0,
+    0x9c,0x8E,0x8F,0x28,0x1F,0x96,0xB9,0xA3,0xFF,
+
+    IB,                             // prepare atc for writing
+    INPUT_STATUS_1_COLOR,
+
+    METAOUT+ATCOUT,                 // program atc registers
+    ATT_ADDRESS_PORT,
+    VGA_NUM_ATTRIB_CONT_PORTS,0,    // count, startindex
+    0x00, 0x01, 0x02, 0x03, 0x04, 0x05,
+    0x17, 0x38, 0x39, 0x3A, 0x3B, 0x3C,
+    0x3D, 0x3E, 0x3F, 0x3F, 0x04, 0x00,
+    0x0F, 0x08, 0x00,
+
+    METAOUT+INDXOUT,                // program gdc registers
+    GRAPH_ADDRESS_PORT,
+    VGA_NUM_GRAPH_CONT_PORTS,0,     // count, startindex
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
+    0x0E, 0x00, 0xFF,
+
+    OB,
+    DAC_PIXEL_MASK_PORT,
+    0xFF,
+
+    IB,                             // prepare atc for writing
+    INPUT_STATUS_1_COLOR,
+    
+    OB,                             // turn video on.
+    ATT_ADDRESS_PORT,
+    VIDEO_ENABLE,
+
+    EOD
+};
+
+//
+// 640x400 color text mode (BIOS mode 3) set command string for
+// VGA.
+//
+
+USHORT VGA_TEXT_1[] = {
+    OWM,                            // begin setmode
+    SEQ_ADDRESS_PORT,
+    5,                              // count
+    0x100,                          // start sync reset
+    0x0101,0x0302,0x0003,0x0204,    // program up sequencer
+
+    OB,                             // misc. register
+    MISC_OUTPUT_REG_WRITE_PORT,
+    0xA3,
+
+    OW,                             // text/graphics bit
+    GRAPH_ADDRESS_PORT,
+    0x0e06,
+    
+    OW,                             // end sync reset
+    SEQ_ADDRESS_PORT,
+    IND_SYNC_RESET,
+
+    OB,
+    SEQ_DATA_PORT,
+    END_SYNC_RESET_VALUE,
+
+    OW,                             // unprotect crtc 0-7
+    CRTC_ADDRESS_PORT_COLOR,
+    0x511,                        
+
+    METAOUT+INDXOUT,                // program gdc registers
+    GRAPH_ADDRESS_PORT,
+    VGA_NUM_CRTC_PORTS,0,           // count, startindex
+    0x5F,0x4F,0x50,0x82,0x55,0x81,0xBF,0x1F,0x00,0x4D,0xB,0xC,0x0,0x0,0x0,0x0,
+    0x83,0x85,0x5D,0x28,0x1F,0x63,0xBA,0xA3,0xFF,
+
+    IB,                             // prepare atc for writing
+    INPUT_STATUS_1_COLOR,
+
+    METAOUT+ATCOUT,                 // program atc registers
+    ATT_ADDRESS_PORT,
+    VGA_NUM_ATTRIB_CONT_PORTS,0,    // count, startindex
+    0x00, 0x01, 0x02, 0x03, 0x04, 0x05,
+    0x17, 0x38, 0x39, 0x3A, 0x3B, 0x3C,
+    0x3D, 0x3E, 0x3F, 0x3F, 0x04, 0x00,
+    0x0F, 0x00, 0x00,
+
+    METAOUT+INDXOUT,                // program gdc registers
+    GRAPH_ADDRESS_PORT,
+    VGA_NUM_GRAPH_CONT_PORTS,0,     // count, startindex
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
+    0x0E, 0x00, 0xFF,
+
+    OB,
+    DAC_PIXEL_MASK_PORT,
+    0xFF,
+
+    IB,                             // prepare atc for writing
+    INPUT_STATUS_1_COLOR,
+    
+    OB,                             // turn video on.
+    ATT_ADDRESS_PORT,
+    VIDEO_ENABLE,
+
+    EOD
+};
+// eVb: 4.2 [END]  
+//
+// Video mode table - contains information and commands for initializing each
+// mode. These entries must correspond with those in VIDEO_MODE_VGA. The first
+// entry is commented; the rest follow the same format, but are not so
+// heavily commented.
+//
+// eVb: 4.3 [VGA] - Add VGA, ModeX and SVGA mode instead of Cirrus Modes
+VIDEOMODE ModesVGA[] =
+{
+    // Color text mode 3, 720x400, 9x16 char cell (VGA).
+    //
+    {
+       VIDEO_MODE_BANKED | VIDEO_MODE_COLOR,  // flags that this mode is a color mode, but not graphics
+        4,                 // four planes
+        1,                 // one bit of colour per plane
+        80, 25,            // 80x25 text resolution
+        720, 400,          // 720x400 pixels on screen
+        1,                 // only support one frequency, non-interlaced
+        160, 0x10000,      // 160 bytes per scan line, 64K of CPU-addressable bitmap
+        FALSE,
+        0x3, VGA_TEXT_0,   // Mode 3, I/O initialization stream
+        0xA0000,           // Physical address at 0xA0000
+        0x18000, 0x8000,
+        0x20000,           // 2 banks of 64K, 128KB total memory
+        720,               // 720 pixels per scan line
+        FALSE,
+        0
+    },
+    
+    //
+    // Color text mode 3, 640x350, 8x14 char cell (EGA).
+    //
+    {
+        VIDEO_MODE_BANKED | VIDEO_MODE_COLOR,
+        4, 1,
+        80, 25, 
+        640, 350,
+        1,
+        160, 0x10000,
+        FALSE,
+        0x3, VGA_TEXT_1,
+        0xA0000,
+        0x18000, 0x8000,
+        0x20000,
+        640,
+        FALSE,
+        0
+    },
+    
+    //
+    //
+    // Standard VGA Color graphics mode 0x12, 640x480 16 colors.
+    //
+    {
+        VIDEO_MODE_BANKED | VIDEO_MODE_COLOR | VIDEO_MODE_GRAPHICS,
+        4, 1,
+        80, 30, 
+        640, 480,
+        1,
+        80, 0x10000,
+        FALSE,
+        0x12, VGA_640x480,
+        0xA0000,
+        0, 0x20000,
+        0x20000,
+        640,
+        FALSE,
+        0
+    },
+
+    {
+        VIDEO_MODE_BANKED | VIDEO_MODE_COLOR | VIDEO_MODE_GRAPHICS,
+        8, 1,
+        0, 0, 
+        320, 200,
+        70,
+        80, 0x10000,
+        FALSE,
+        0x3, NULL,
+        0xA0000,
+        0, 0x20000,
+        0x20000,
+        320,
+        FALSE,
+        0
+    },
+    
+    {
+        VIDEO_MODE_BANKED | VIDEO_MODE_COLOR | VIDEO_MODE_GRAPHICS,
+        8, 1,
+        0, 0, 
+        320, 240,
+        60,
+        80, 0x10000,
+        FALSE,
+        0x3, NULL,
+        0xA0000,
+        0, 0x20000,
+        0x20000,
+        320,
+        FALSE,
+        0
+    },
+    
+    {
+        VIDEO_MODE_BANKED | VIDEO_MODE_COLOR | VIDEO_MODE_GRAPHICS,
+        8, 1,
+        0, 0, 
+        320, 400,
+        70,
+        80, 0x10000,
+        FALSE,
+        0x3, NULL,
+        0xA0000,
+        0, 0x20000,
+        0x20000,
+        320,
+        FALSE,
+        0
+    },
+
+    {
+        VIDEO_MODE_BANKED | VIDEO_MODE_COLOR | VIDEO_MODE_GRAPHICS,
+        8, 1,
+        0, 0, 
+        320, 480,
+        60,
+        80, 0x10000,
+        FALSE,
+        0x3, NULL,
+        0xA0000,
+        0, 0x20000,
+        0x20000,
+        320,
+        FALSE,
+        0
+    },
+    
+    //
+    // 800x600 16 colors.
+    //
+    {
+        VIDEO_MODE_BANKED | VIDEO_MODE_COLOR | VIDEO_MODE_GRAPHICS,
+        4, 1,
+        100, 37,
+        800, 600,
+        1,
+        100, 0x10000,
+        FALSE,
+        (0x102 << 16) | VBE_SET_VBE_MODE, NULL,
+        0xA0000,
+        0, 0x20000,
+        0x20000,
+        800,
+        FALSE,
+        0
+    },
+};
+
+ULONG NumVideoModes = sizeof(ModesVGA) / sizeof(VIDEOMODE);
+PVIDEOMODE VgaModeList;
+// eVb: 4.3 [END]
+
+//
+//
+// Data used to set the Graphics and Sequence Controllers to put the
+// VGA into a planar state at A0000 for 64K, with plane 2 enabled for
+// reads and writes, so that a font can be loaded, and to disable that mode.
+//
+
+// Settings to enable planar mode with plane 2 enabled.
+//
+
+USHORT EnableA000Data[] = {
+    OWM,
+    SEQ_ADDRESS_PORT,
+    1,
+    0x0100,
+
+    OWM,
+    GRAPH_ADDRESS_PORT,
+    3,
+    0x0204,     // Read Map = plane 2
+    0x0005, // Graphics Mode = read mode 0, write mode 0
+    0x0406, // Graphics Miscellaneous register = A0000 for 64K, not odd/even,
+            //  graphics mode
+    OWM,
+    SEQ_ADDRESS_PORT,
+    3,
+    0x0402, // Map Mask = write to plane 2 only
+    0x0404, // Memory Mode = not odd/even, not full memory, graphics mode
+    0x0300,  // end sync reset
+    EOD
+};
+
+//
+// Settings to disable the font-loading planar mode.
+//
+
+USHORT DisableA000Color[] = {
+    OWM,
+    SEQ_ADDRESS_PORT,
+    1,
+    0x0100,
+
+    OWM,
+    GRAPH_ADDRESS_PORT,
+    3,
+    0x0004, 0x1005, 0x0E06,
+
+    OWM,
+    SEQ_ADDRESS_PORT,
+    3,
+    0x0302, 0x0204, 0x0300,  // end sync reset
+    EOD
+
+};