mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
962 lines
27 KiB
962 lines
27 KiB
/*++
|
|
|
|
Copyright (c) 1992 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
modeset.c
|
|
|
|
Abstract:
|
|
|
|
This is the modeset code for the VGA miniport driver.
|
|
|
|
Environment:
|
|
|
|
kernel mode only
|
|
|
|
Notes:
|
|
|
|
Revision History:
|
|
**********************************************************************
|
|
*
|
|
* COMPAQ Revision History
|
|
*
|
|
* ID DATE VER. USER
|
|
* ---- ---------- ----- --------
|
|
* $001 10/15/1993 1.001 adrianc
|
|
* I added the function VgaValidateModes. The functions validates the
|
|
* current modes based on the amount of memory available and
|
|
* whether an external monitor is connected to the video port.
|
|
* This logic used to be in the VgaQueryNumAvailableModes. It was moved
|
|
* out of there to prevent the driver from validating the modes every time
|
|
* that function was called.
|
|
* $000 10/15/1993 1.000 adrianc
|
|
* Original Release
|
|
**********************************************************************
|
|
|
|
--*/
|
|
#include "dderror.h"
|
|
#include "devioctl.h"
|
|
#include "miniport.h"
|
|
|
|
#include "ntddvdeo.h"
|
|
#include "video.h"
|
|
#include "avga.h"
|
|
#include "modeset.h"
|
|
|
|
VOID
|
|
VgaZeroVideoMemory(
|
|
PHW_DEVICE_EXTENSION HwDeviceExtension
|
|
);
|
|
|
|
|
|
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
|
|
)
|
|
|
|
/*++
|
|
|
|
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;
|
|
|
|
//
|
|
// 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 bit.
|
|
//
|
|
|
|
if (Mode->RequestedMode & VIDEO_MODE_NO_ZERO_MEMORY) {
|
|
|
|
Mode->RequestedMode &= ~VIDEO_MODE_NO_ZERO_MEMORY;
|
|
|
|
} else {
|
|
|
|
VgaZeroVideoMemory(HwDeviceExtension);
|
|
|
|
}
|
|
|
|
//
|
|
// Check to see if we are requesting a valid mode
|
|
//
|
|
|
|
if ((Mode->RequestedMode >= NUM_VIDEO_MODES) ||
|
|
(!ModesVGA[Mode->RequestedMode].ValidMode)) {
|
|
|
|
VideoDebugPrint((0,"AVGA.sys: VGASetMode - ERROR_INVALID_PARAMETER.\n"));
|
|
return ERROR_INVALID_PARAMETER;
|
|
|
|
}
|
|
|
|
pRequestedMode = &ModesVGA[Mode->RequestedMode];
|
|
HwDeviceExtension->ModeIndex = Mode->RequestedMode;
|
|
|
|
|
|
//
|
|
// Store the new mode value.
|
|
//
|
|
|
|
HwDeviceExtension->CurrentMode = pRequestedMode;
|
|
|
|
#ifdef INT10_MODE_SET
|
|
{
|
|
|
|
VIDEO_X86_BIOS_ARGUMENTS biosArguments;
|
|
UCHAR temp;
|
|
UCHAR dummy;
|
|
UCHAR bIsColor;
|
|
|
|
/***********************************************************************
|
|
*** There appears to be a problem with some application ***
|
|
*** which reset the first 16 palette registers. ***
|
|
*** Since the palette is not reset when going to and ***
|
|
*** from text modes by doing a set mode (instead of ***
|
|
*** the hardware save restore), some colors might not ***
|
|
*** appear as expected in the text modes. The bios ***
|
|
*** calls seem to reload the palette so Andre Vachon ***
|
|
*** suggested that we implement an Int10 mode set for the ***
|
|
*** text modes. ***
|
|
*** To accomplish this, we need to hard code the first ***
|
|
*** three modes in modeset.h in the following switch. ***
|
|
*** If more text modes are added to modeset.h, their ***
|
|
*** index must be added to this switch statement. ***
|
|
***********************************************************************/
|
|
VideoPortZeroMemory(&biosArguments, sizeof(VIDEO_X86_BIOS_ARGUMENTS));
|
|
switch (Mode->RequestedMode) {
|
|
case 0: // 720x400
|
|
/***********************************************************************
|
|
*** Prepare the card for the VGA mode 3+ instead of the CGA mode 3 ***
|
|
***********************************************************************/
|
|
biosArguments.Eax = 0x1202; // Select Scan line number
|
|
biosArguments.Ebx = 0x0030; // to be 400 scan lines
|
|
status = VideoPortInt10(HwDeviceExtension, &biosArguments);
|
|
|
|
/***********************************************************************
|
|
*** Set the video mode to BIOS mode 3. ***
|
|
***********************************************************************/
|
|
VideoPortZeroMemory(&biosArguments, sizeof(VIDEO_X86_BIOS_ARGUMENTS));
|
|
biosArguments.Eax = 0x03; // bios mode 0x03
|
|
status = VideoPortInt10(HwDeviceExtension, &biosArguments);
|
|
break;
|
|
case 1: // 640x350
|
|
/***********************************************************************
|
|
*** Prepare the card for the EGA mode 3* instead of the CGA mode 3 ***
|
|
***********************************************************************/
|
|
biosArguments.Eax = 0x1201; // Select Scan line number
|
|
biosArguments.Ebx = 0x0030; // to be 350 scan lines
|
|
status = VideoPortInt10(HwDeviceExtension, &biosArguments);
|
|
|
|
/***********************************************************************
|
|
*** Set the video mode to BIOS mode 3. ***
|
|
***********************************************************************/
|
|
VideoPortZeroMemory(&biosArguments, sizeof(VIDEO_X86_BIOS_ARGUMENTS));
|
|
biosArguments.Eax = 0x03; // bios mode 0x03
|
|
status = VideoPortInt10(HwDeviceExtension, &biosArguments);
|
|
break;
|
|
|
|
default: // all graphics modes are
|
|
// handled by the default case
|
|
biosArguments.Eax = pRequestedMode->Int10ModeNumber;
|
|
status = VideoPortInt10(HwDeviceExtension, &biosArguments);
|
|
break;
|
|
|
|
}
|
|
|
|
if (status != NO_ERROR) {
|
|
return status;
|
|
}
|
|
|
|
//
|
|
// Fix to get 640x350 text mode
|
|
//
|
|
|
|
if (!(pRequestedMode->fbType & VIDEO_MODE_GRAPHICS)) {
|
|
|
|
// if ((pRequestedMode->hres == 640) &&
|
|
// (pRequestedMode->vres == 350)) {
|
|
//
|
|
// VgaInterpretCmdStream(HwDeviceExtension, VGA_TEXT_1);
|
|
//
|
|
// } else {
|
|
|
|
//
|
|
// Fix to make sure we always set the colors in text mode to be
|
|
// intensity, and not flashing
|
|
// For this zero out the Mode Control Regsiter bit 3 (index 0x10
|
|
// of the Attribute controller).
|
|
//
|
|
|
|
if (VideoPortReadPortUchar(HwDeviceExtension->IOAddress +
|
|
MISC_OUTPUT_REG_READ_PORT) & 0x01) {
|
|
|
|
bIsColor = TRUE;
|
|
|
|
} else {
|
|
|
|
bIsColor = FALSE;
|
|
|
|
}
|
|
|
|
if (bIsColor) {
|
|
|
|
dummy = VideoPortReadPortUchar(HwDeviceExtension->IOAddress +
|
|
INPUT_STATUS_1_COLOR);
|
|
} else {
|
|
|
|
dummy = VideoPortReadPortUchar(HwDeviceExtension->IOAddress +
|
|
INPUT_STATUS_1_MONO);
|
|
}
|
|
|
|
VideoPortWritePortUchar(HwDeviceExtension->IOAddress +
|
|
ATT_ADDRESS_PORT, (0x10 | VIDEO_ENABLE));
|
|
temp = VideoPortReadPortUchar(HwDeviceExtension->IOAddress +
|
|
ATT_DATA_READ_PORT);
|
|
|
|
temp &= 0xF7;
|
|
|
|
if (bIsColor) {
|
|
|
|
dummy = VideoPortReadPortUchar(HwDeviceExtension->IOAddress +
|
|
INPUT_STATUS_1_COLOR);
|
|
} else {
|
|
|
|
dummy = VideoPortReadPortUchar(HwDeviceExtension->IOAddress +
|
|
INPUT_STATUS_1_MONO);
|
|
}
|
|
|
|
VideoPortWritePortUchar(HwDeviceExtension->IOAddress +
|
|
ATT_ADDRESS_PORT, (0x10 | VIDEO_ENABLE));
|
|
VideoPortWritePortUchar(HwDeviceExtension->IOAddress +
|
|
ATT_DATA_WRITE_PORT, temp);
|
|
// }
|
|
}
|
|
}
|
|
#else
|
|
VgaInterpretCmdStream(HwDeviceExtension, pRequestedMode->CmdStrings);
|
|
#endif
|
|
|
|
//
|
|
// Update the location of the physical frame buffer within video memory.
|
|
//
|
|
|
|
HwDeviceExtension->PhysicalFrameLength =
|
|
MemoryMaps[pRequestedMode->MemMap].MaxSize;
|
|
|
|
HwDeviceExtension->PhysicalFrameBase.LowPart =
|
|
MemoryMaps[pRequestedMode->MemMap].Start;
|
|
|
|
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 =
|
|
HwDeviceExtension->NumAvailableModes * 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 < NUM_VIDEO_MODES; i++, videoModes++) {
|
|
|
|
if (ModesVGA[i].ValidMode) {
|
|
|
|
videoModes->Length = sizeof(VIDEO_MODE_INFORMATION);
|
|
videoModes->ModeIndex = i;
|
|
videoModes->VisScreenWidth = ModesVGA[i].hres;
|
|
videoModes->ScreenStride = ModesVGA[i].wbytes;
|
|
videoModes->VisScreenHeight = ModesVGA[i].vres;
|
|
videoModes->NumberOfPlanes = ModesVGA[i].numPlanes;
|
|
videoModes->BitsPerPlane = ModesVGA[i].bitsPerPlane;
|
|
videoModes->Frequency = 1;
|
|
videoModes->XMillimeter = 320; // temporary hardcoded constant
|
|
videoModes->YMillimeter = 240; // temporary hardcoded constant
|
|
videoModes->NumberRedBits = 6;
|
|
videoModes->NumberGreenBits = 6;
|
|
videoModes->NumberBlueBits = 6;
|
|
videoModes->RedMask = 0;
|
|
videoModes->GreenMask = 0;
|
|
videoModes->BlueMask = 0;
|
|
videoModes->AttributeFlags = ModesVGA[i].fbType |
|
|
VIDEO_MODE_PALETTE_DRIVEN | VIDEO_MODE_MANAGED_PALETTE;
|
|
}
|
|
}
|
|
|
|
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 number of available modes in the buffer
|
|
//
|
|
|
|
NumModes->NumModes = HwDeviceExtension->NumAvailableModes;
|
|
NumModes->ModeInformationLength = sizeof(VIDEO_MODE_INFORMATION);
|
|
|
|
return NO_ERROR;
|
|
|
|
} // end VgaGetNumberOfAvailableModes()
|
|
|
|
VP_STATUS
|
|
VgaQueryCurrentMode(
|
|
PHW_DEVICE_EXTENSION HwDeviceExtension,
|
|
PVIDEO_MODE_INFORMATION ModeInformation,
|
|
ULONG ModeInformationSize,
|
|
PULONG OutputSize
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine returns a description of the current video mode.
|
|
|
|
Arguments:
|
|
|
|
HwDeviceExtension - Pointer to the miniport driver's device extension.
|
|
|
|
ModeInformation - Pointer to the output buffer supplied by the user.
|
|
This is where the current mode information 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.
|
|
|
|
--*/
|
|
|
|
{
|
|
//
|
|
// check if a mode has been set
|
|
//
|
|
|
|
if (HwDeviceExtension->CurrentMode == NULL) {
|
|
|
|
return ERROR_INVALID_FUNCTION;
|
|
|
|
}
|
|
|
|
//
|
|
// 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 (ModeInformationSize < (*OutputSize = sizeof(VIDEO_MODE_INFORMATION))) {
|
|
|
|
return ERROR_INSUFFICIENT_BUFFER;
|
|
|
|
}
|
|
|
|
//
|
|
// Store the characteristics of the current mode into the buffer.
|
|
//
|
|
|
|
ModeInformation->Length = sizeof(VIDEO_MODE_INFORMATION);
|
|
ModeInformation->ModeIndex = HwDeviceExtension->ModeIndex;
|
|
ModeInformation->VisScreenWidth = HwDeviceExtension->CurrentMode->hres;
|
|
ModeInformation->ScreenStride = HwDeviceExtension->CurrentMode->wbytes;
|
|
ModeInformation->VisScreenHeight = HwDeviceExtension->CurrentMode->vres;
|
|
ModeInformation->NumberOfPlanes = HwDeviceExtension->CurrentMode->numPlanes;
|
|
ModeInformation->BitsPerPlane = HwDeviceExtension->CurrentMode->bitsPerPlane;
|
|
|
|
ModeInformation->Frequency = 1;
|
|
ModeInformation->XMillimeter = 320; // temporary hardcoded constant
|
|
ModeInformation->YMillimeter = 240; // temporary hardcoded constant
|
|
ModeInformation->NumberRedBits = 6;
|
|
ModeInformation->NumberGreenBits = 6;
|
|
ModeInformation->NumberBlueBits = 6;
|
|
ModeInformation->RedMask = 0;
|
|
ModeInformation->GreenMask = 0;
|
|
ModeInformation->BlueMask = 0;
|
|
ModeInformation->AttributeFlags = HwDeviceExtension->CurrentMode->fbType |
|
|
VIDEO_MODE_PALETTE_DRIVEN | VIDEO_MODE_MANAGED_PALETTE;
|
|
|
|
return NO_ERROR;
|
|
|
|
} // end VgaQueryCurrentMode()
|
|
|
|
|
|
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);
|
|
|
|
//
|
|
// Zero the memory.
|
|
//
|
|
|
|
VideoPortZeroDeviceMemory(HwDeviceExtension->VideoMemoryAddress,
|
|
0xFFFF);
|
|
|
|
VgaInterpretCmdStream(HwDeviceExtension, DisableA000Color);
|
|
|
|
} // VgaZeroVideoMemory(...)
|
|
|
|
|
|
VOID
|
|
VgaValidateModes(
|
|
PHW_DEVICE_EXTENSION HwDeviceExtension
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Determines which modes are valid and which are not.
|
|
|
|
Arguments:
|
|
|
|
HwDeviceExtension - Pointer to the miniport driver's device extension.
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
{
|
|
|
|
ULONG i;
|
|
VIDEO_X86_BIOS_ARGUMENTS biosArguments;
|
|
ULONG ulAvailMemory; // Available memory on the card.
|
|
|
|
/***********************************************************************
|
|
*** On the AVGA cards, the amount of memory is hardcoded ***
|
|
*** in the BIOS. To determine the amount of memory available ***
|
|
*** on the card, we need to perform an INT 10 bios call. ***
|
|
***********************************************************************/
|
|
|
|
VideoPortZeroMemory(&biosArguments, sizeof(VIDEO_X86_BIOS_ARGUMENTS));
|
|
|
|
/***********************************************************************
|
|
*** To find out if we only have 256Kb of RAM on the board we need ***
|
|
*** to determine if 640x480x256 color modes are supported. ***
|
|
*** If the mode is supported, we have at least 512kb of RAM. ***
|
|
*** To determine if this mode is supported we need to perform ***
|
|
*** An INT 10 call to get the video environment. ***
|
|
*** AH = BFh ; AL = 03h ; BX = 00h ***
|
|
*** Then we need to test bit 6. If it is set, the mode is ***
|
|
*** supported and we have at least 512Kb on the board. ***
|
|
***********************************************************************/
|
|
|
|
biosArguments.Eax = 0xBF03;
|
|
VideoPortInt10(HwDeviceExtension, &biosArguments);
|
|
VideoDebugPrint((2,"AVGA.SYS: biosArguments.Ecx = %x\n",biosArguments.Ecx));
|
|
VideoDebugPrint((2,"AVGA.SYS: VgaValidateModes - "));
|
|
|
|
if (biosArguments.Ecx & 0x40) {
|
|
|
|
VideoDebugPrint((2,"512Kb RAM on the board.\n"));
|
|
ulAvailMemory = 0x80000;
|
|
|
|
} else {
|
|
|
|
VideoDebugPrint((2,"256Kb RAM on the board.\n"));
|
|
ulAvailMemory = 0x40000;
|
|
}
|
|
|
|
//
|
|
// Store the number of modes into the buffer.
|
|
//
|
|
|
|
HwDeviceExtension->NumAvailableModes = 0;
|
|
|
|
for (i = 0; i < NUM_VIDEO_MODES; i++) {
|
|
|
|
if (ModesVGA[i].sbytes > ulAvailMemory) { // Does the card have
|
|
|
|
ModesVGA[i].ValidMode = FALSE; // enough memory to support
|
|
continue; // this mode ?
|
|
|
|
}
|
|
|
|
if ((HwDeviceExtension->DisplayType == PANEL) &&
|
|
(ModesVGA[i].hres == 800)) {
|
|
|
|
VideoDebugPrint((2,"AVGA.sys: VgaValidateModes - 800x600 mode with PANEL = %x\n",i));
|
|
ModesVGA[i].ValidMode = FALSE;
|
|
|
|
} else {
|
|
|
|
VideoDebugPrint((2,"AVGA.sys: VgaValidateModes - Valid Mode %x\n",i));
|
|
ModesVGA[i].ValidMode = TRUE;
|
|
HwDeviceExtension->NumAvailableModes ++;
|
|
|
|
}
|
|
}
|
|
|
|
VideoDebugPrint((2,"AVGA.sys: VgaValidateModes - NumMode = %x.\n",
|
|
HwDeviceExtension->NumAvailableModes));
|
|
|
|
}
|