- Add new unified VGA/VBE miniport driver. Based on NT4 DDK Cirrus Miniport Driver Sample with my modifications (marked with // eVb) to change Cirrus parts to VGA parts if needed. Also add VBE suppor which is not in Cirrus driver, but exists in Windows VGA miniport.

- 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
This commit is contained in:
evb 2010-03-05 17:22:18 +00:00
parent 4834e2c3d5
commit 5ba4b4bbeb
11 changed files with 4063 additions and 5 deletions

View 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" />

View file

@ -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 */

View file

@ -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()
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()
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()
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()
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);
}

View file

@ -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 */

View file

@ -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 */

View file

@ -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 */

File diff suppressed because it is too large Load diff

View file

@ -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
//
// 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
//
// 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
//
// 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;
//
// 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"

View file

@ -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>

View file

@ -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>

View file

@ -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
};