1783 lines
63 KiB
C
1783 lines
63 KiB
C
|
/*++
|
|||
|
|
|||
|
Copyright (c) 1992 Microsoft Corporation
|
|||
|
Copyright (c) 1993 Compaq Computer Corporation
|
|||
|
|
|||
|
Module Name:
|
|||
|
|
|||
|
modeset.c
|
|||
|
|
|||
|
Abstract:
|
|||
|
|
|||
|
This is the modeset code for the QVision miniport driver.
|
|||
|
|
|||
|
Environment:
|
|||
|
|
|||
|
kernel mode only
|
|||
|
|
|||
|
Notes:
|
|||
|
|
|||
|
|
|||
|
Revision History:
|
|||
|
$0007
|
|||
|
MikeD: 06/17/1994
|
|||
|
. fixed switch statement in VgaSetMode() to set proper full-screen
|
|||
|
mode (problem found in Japanese NT)
|
|||
|
$0006
|
|||
|
miked: 02/17/1994
|
|||
|
. took out conditional debug code to satisfy MSBHPD
|
|||
|
$0005 - MikeD - 02/08/94
|
|||
|
. modified to work with build 547's new display.cpl
|
|||
|
|
|||
|
$0004
|
|||
|
miked: 1/26/1994
|
|||
|
. Added debug print code without all the other DBG overhead
|
|||
|
. Added third party monitor support to force a 76Hz refresh rate
|
|||
|
|
|||
|
|
|||
|
|
|||
|
--*/
|
|||
|
#include "dderror.h"
|
|||
|
#include "devioctl.h"
|
|||
|
#include "miniport.h"
|
|||
|
|
|||
|
#include "ntddvdeo.h"
|
|||
|
#include "video.h"
|
|||
|
#include "qvision.h"
|
|||
|
#include "modeset.h"
|
|||
|
|
|||
|
|
|||
|
VOID
|
|||
|
VgaZeroVideoMemory(
|
|||
|
PHW_DEVICE_EXTENSION HwDeviceExtension
|
|||
|
);
|
|||
|
|
|||
|
|
|||
|
VOID
|
|||
|
SetQVisionBanking(
|
|||
|
PHW_DEVICE_EXTENSION HwDeviceExtension,
|
|||
|
ULONG BankNumber
|
|||
|
);
|
|||
|
|
|||
|
//---------------------------------------------------------------------------
|
|||
|
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; /* OP code for the Cmd stream */
|
|||
|
ULONG ulPort; /* address port for the command */
|
|||
|
UCHAR jValue; /* byte value to use in operation */
|
|||
|
USHORT usValue; /* word value to use in operation */
|
|||
|
ULONG culCount; /* number of values in the command */
|
|||
|
ULONG ulIndex; /* index to start from in the indexed command */
|
|||
|
ULONG ulBase; /* base */
|
|||
|
// PUSHORT pusTempMonData; /* temporary CRTCData pointer */
|
|||
|
// ULONG ulEndOfMonData; // address of the end of the MonData array
|
|||
|
|
|||
|
ULONG resIndex, monIndex; // indexes into MonData
|
|||
|
PMONRES pMonRes; // pointer to MONRES
|
|||
|
|
|||
|
VideoDebugPrint((1, "QVision.sys: VgaInterpretCmdStream - ENTRY.\n"));
|
|||
|
|
|||
|
if (pusCmdStream == NULL) {
|
|||
|
|
|||
|
VideoDebugPrint((1, "\tInvalid 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:
|
|||
|
VideoDebugPrint((2,"\tINOUT - "));
|
|||
|
|
|||
|
//
|
|||
|
// Determine type of inout instruction
|
|||
|
//
|
|||
|
|
|||
|
if (!(ulCmd & IO)) {
|
|||
|
|
|||
|
//
|
|||
|
// Out instruction. Single or multiple outs?
|
|||
|
//
|
|||
|
|
|||
|
if (!(ulCmd & MULTI)) {
|
|||
|
VideoDebugPrint((2,"SINGLE OUT - "));
|
|||
|
|
|||
|
//
|
|||
|
// Single out. Byte or word out?
|
|||
|
//
|
|||
|
|
|||
|
if (!(ulCmd & BW)) {
|
|||
|
VideoDebugPrint((2,"BYTE\n"));
|
|||
|
|
|||
|
//
|
|||
|
// Single byte out
|
|||
|
//
|
|||
|
|
|||
|
ulPort = *pusCmdStream++;
|
|||
|
jValue = (UCHAR) *pusCmdStream++;
|
|||
|
VideoPortWritePortUchar((PUCHAR)(ulBase+ulPort),
|
|||
|
jValue);
|
|||
|
|
|||
|
if (ulPort == MISC_OUTPUT_REG_WRITE_PORT) {
|
|||
|
|
|||
|
//
|
|||
|
// $0006 - MikeD - 03/04/94
|
|||
|
// Begin: add 10 millisecond delay after r/w
|
|||
|
// of 3c2
|
|||
|
//
|
|||
|
// 10000microsecs = 10ms
|
|||
|
//
|
|||
|
// I know I should not stall more than 50, but
|
|||
|
// there is no other way around this...
|
|||
|
|
|||
|
VideoPortStallExecution( 10000 );
|
|||
|
}
|
|||
|
|
|||
|
} else {
|
|||
|
|
|||
|
VideoDebugPrint((2,"WORD\n"));
|
|||
|
|
|||
|
//
|
|||
|
// Single word out
|
|||
|
//
|
|||
|
|
|||
|
ulPort = *pusCmdStream++;
|
|||
|
usValue = *pusCmdStream++;
|
|||
|
VideoPortWritePortUshort((PUSHORT)(ulBase+ulPort),
|
|||
|
usValue);
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
} else {
|
|||
|
VideoDebugPrint((2,"MULTIPLE OUTS - "));
|
|||
|
|
|||
|
//
|
|||
|
// Output a string of values
|
|||
|
// Byte or word outs?
|
|||
|
//
|
|||
|
|
|||
|
if (!(ulCmd & BW)) {
|
|||
|
VideoDebugPrint((2,"BYTES\n"));
|
|||
|
|
|||
|
//
|
|||
|
// 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 {
|
|||
|
VideoDebugPrint((2,"WORDS\n"));
|
|||
|
|
|||
|
//
|
|||
|
// String word outs
|
|||
|
//
|
|||
|
|
|||
|
ulPort = *pusCmdStream++;
|
|||
|
culCount = *pusCmdStream++;
|
|||
|
VideoPortWritePortBufferUshort((PUSHORT)
|
|||
|
(ulBase + ulPort), pusCmdStream, culCount);
|
|||
|
pusCmdStream += culCount;
|
|||
|
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
} else {
|
|||
|
VideoDebugPrint((2,"SINGLE IN - "));
|
|||
|
|
|||
|
// 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)) {
|
|||
|
VideoDebugPrint((2,"BYTE\n"));
|
|||
|
|
|||
|
//
|
|||
|
// Single byte in
|
|||
|
//
|
|||
|
|
|||
|
ulPort = *pusCmdStream++;
|
|||
|
jValue = VideoPortReadPortUchar((PUCHAR)ulBase+ulPort);
|
|||
|
|
|||
|
} else {
|
|||
|
VideoDebugPrint((2,"WORD\n"));
|
|||
|
|
|||
|
//
|
|||
|
// Single word in
|
|||
|
//
|
|||
|
|
|||
|
ulPort = *pusCmdStream++;
|
|||
|
usValue = VideoPortReadPortUshort((PUSHORT)
|
|||
|
(ulBase+ulPort));
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
break;
|
|||
|
|
|||
|
//
|
|||
|
// Higher-level input/output commands
|
|||
|
//
|
|||
|
|
|||
|
case METAOUT:
|
|||
|
VideoDebugPrint((2,"\tMETAOUT - "));
|
|||
|
|
|||
|
//
|
|||
|
// Determine type of metaout command, based on minor
|
|||
|
// command field
|
|||
|
//
|
|||
|
switch (ulCmd & 0x0F) {
|
|||
|
|
|||
|
//
|
|||
|
// Indexed outs
|
|||
|
//
|
|||
|
|
|||
|
case INDXOUT:
|
|||
|
VideoDebugPrint((2,"INDXOUT\n"));
|
|||
|
|
|||
|
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:
|
|||
|
VideoDebugPrint((2,"MASKOUT\n"));
|
|||
|
|
|||
|
ulPort = *pusCmdStream++;
|
|||
|
jValue = VideoPortReadPortUchar((PUCHAR)ulBase+ulPort);
|
|||
|
jValue &= *pusCmdStream++;
|
|||
|
jValue ^= *pusCmdStream++;
|
|||
|
VideoPortWritePortUchar((PUCHAR)ulBase + ulPort,
|
|||
|
jValue);
|
|||
|
break;
|
|||
|
|
|||
|
//
|
|||
|
// Attribute Controller out
|
|||
|
//
|
|||
|
|
|||
|
case ATCOUT:
|
|||
|
VideoDebugPrint((2,"ATCOUT\n"));
|
|||
|
|
|||
|
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;
|
|||
|
|
|||
|
|
|||
|
default:
|
|||
|
|
|||
|
return FALSE;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
break;
|
|||
|
|
|||
|
//
|
|||
|
// NOP
|
|||
|
//
|
|||
|
|
|||
|
case NCMD:
|
|||
|
VideoDebugPrint((2,"\tNCMD\n"));
|
|||
|
|
|||
|
break;
|
|||
|
|
|||
|
case QVCMD:
|
|||
|
VideoDebugPrint((2,"\tQVCMDS - "));
|
|||
|
|
|||
|
switch (ulCmd & 0x0F) {
|
|||
|
|
|||
|
//
|
|||
|
// Set the CRTC registers based on the monitor which is currently
|
|||
|
// attached to the QVision card.
|
|||
|
// HwDeviceExtension->ModeIndex contains current mode index.
|
|||
|
// HwDeviceExtension->VideoHardware.MonClass = current monitor.
|
|||
|
//
|
|||
|
|
|||
|
case SETMONCRTC:
|
|||
|
|
|||
|
VideoDebugPrint((2,"SETMONCRTC\n"));
|
|||
|
ulPort = ulBase + CRTC_ADDRESS_PORT_COLOR;
|
|||
|
|
|||
|
// $0005 - MikeD - 02/08/94
|
|||
|
// Begin:-
|
|||
|
//
|
|||
|
// implemented direct indexing...
|
|||
|
//
|
|||
|
|
|||
|
// get resolution index from requested mode
|
|||
|
resIndex =
|
|||
|
ModesVGA[HwDeviceExtension->ModeIndex].ulResIndex;
|
|||
|
|
|||
|
// get monitor index from monitor class
|
|||
|
monIndex =
|
|||
|
HwDeviceExtension->VideoHardware.MonClass;
|
|||
|
|
|||
|
// set direct pointer to specific MONRES element
|
|||
|
// for clarity
|
|||
|
pMonRes = &MonData[monIndex].MonitorResolution[resIndex];
|
|||
|
|
|||
|
//
|
|||
|
// set CRTC registers if necessary
|
|||
|
//
|
|||
|
if (pMonRes->bRegsPresent) {
|
|||
|
|
|||
|
for (ulIndex = 0; ulIndex < 25; ulIndex++) {
|
|||
|
usValue = (USHORT) (ulIndex +
|
|||
|
(ULONG) (pMonRes->crtRegisters[ulIndex] << 8));
|
|||
|
VideoPortWritePortUshort((PUSHORT)ulPort, usValue);
|
|||
|
}
|
|||
|
}
|
|||
|
//
|
|||
|
// $0005 - MikeD - 02/08/94
|
|||
|
// End:
|
|||
|
//
|
|||
|
|
|||
|
break;
|
|||
|
|
|||
|
|
|||
|
//
|
|||
|
// Set the Overflow2 register based on the monitor
|
|||
|
// which is currently attached to the QVision card.
|
|||
|
//
|
|||
|
|
|||
|
case SETMONOVFLW:
|
|||
|
|
|||
|
VideoDebugPrint((2,"SETMONOVFLW\n"));
|
|||
|
|
|||
|
ulPort = ulBase + GRAPH_ADDRESS_PORT;
|
|||
|
ulIndex = OVERFLOW_REG_2;
|
|||
|
|
|||
|
// $0005 - MikeD - 02/08/94
|
|||
|
// Begin:
|
|||
|
//
|
|||
|
// implemented direct indexing...
|
|||
|
//
|
|||
|
|
|||
|
// get resolution index from requested mode
|
|||
|
resIndex =
|
|||
|
ModesVGA[HwDeviceExtension->ModeIndex].ulResIndex;
|
|||
|
|
|||
|
// get monitor index from monitor class
|
|||
|
monIndex =
|
|||
|
HwDeviceExtension->VideoHardware.MonClass;
|
|||
|
|
|||
|
// set direct pointer to specific MONRES element
|
|||
|
// for clarity
|
|||
|
pMonRes = &MonData[monIndex].MonitorResolution[resIndex];
|
|||
|
|
|||
|
//
|
|||
|
// set Overflow register if necessary
|
|||
|
//
|
|||
|
if (pMonRes->bRegsPresent) {
|
|||
|
|
|||
|
usValue = (USHORT) (ulIndex +
|
|||
|
(ULONG) (pMonRes->Overflow << 8));
|
|||
|
VideoPortWritePortUshort((PUSHORT)ulPort, usValue);
|
|||
|
}
|
|||
|
//
|
|||
|
// $0005 - MikeD - 02/08/94
|
|||
|
// End:
|
|||
|
//
|
|||
|
break;
|
|||
|
|
|||
|
|
|||
|
//
|
|||
|
// Set the Misc out register based on the monitor which
|
|||
|
// is currently attached to the QVision card.
|
|||
|
//
|
|||
|
|
|||
|
case SETMISCOUT:
|
|||
|
|
|||
|
VideoDebugPrint((2,"SETMISCOUT\n"));
|
|||
|
ulPort = ulBase + MISC_OUTPUT_REG_WRITE_PORT;
|
|||
|
|
|||
|
// $0005 - MikeD - 02/08/94
|
|||
|
// Begin:
|
|||
|
//
|
|||
|
// implemented direct indexing...
|
|||
|
//
|
|||
|
|
|||
|
// get resolution index from requested mode
|
|||
|
resIndex =
|
|||
|
ModesVGA[HwDeviceExtension->ModeIndex].ulResIndex;
|
|||
|
|
|||
|
// get monitor index from monitor class
|
|||
|
monIndex =
|
|||
|
HwDeviceExtension->VideoHardware.MonClass;
|
|||
|
|
|||
|
// set direct pointer to specific MONRES element
|
|||
|
// for clarity
|
|||
|
pMonRes = &MonData[monIndex].MonitorResolution[resIndex];
|
|||
|
|
|||
|
//
|
|||
|
// set Misc OUT register if necessary
|
|||
|
//
|
|||
|
if (pMonRes->bRegsPresent) {
|
|||
|
|
|||
|
VideoPortWritePortUshort(
|
|||
|
(PUSHORT)ulPort,
|
|||
|
pMonRes->MiscOut);
|
|||
|
//
|
|||
|
// $0006 - MikeD - 03/04/94
|
|||
|
// Begin: add 10 millisecond delay after r/w
|
|||
|
// of 3c2
|
|||
|
//
|
|||
|
// 10000microsecs = 10ms
|
|||
|
//
|
|||
|
// I know I should not stall more than 50, but
|
|||
|
// there is no other way around this...
|
|||
|
|
|||
|
VideoPortStallExecution( 10000 );
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// $0005 - MikeD - 02/08/94
|
|||
|
// End:
|
|||
|
//
|
|||
|
break;
|
|||
|
|
|||
|
//
|
|||
|
// None of the above; error
|
|||
|
//
|
|||
|
|
|||
|
//
|
|||
|
// Write directly to the port provided. This is used for
|
|||
|
// writing to extended registers or to registers which are
|
|||
|
// not based on the IOAddress.
|
|||
|
// This can be used to write many bytes to a port if
|
|||
|
// it is auto-incremented.
|
|||
|
//
|
|||
|
|
|||
|
case BYTE2PORT:
|
|||
|
VideoDebugPrint((2,"BYTE2PORT\n"));
|
|||
|
ulPort = *pusCmdStream++;
|
|||
|
culCount = *pusCmdStream++;
|
|||
|
|
|||
|
while (culCount--) {
|
|||
|
jValue = (UCHAR) *pusCmdStream++;
|
|||
|
VideoPortWritePortUchar((PUCHAR)ulPort,
|
|||
|
jValue);
|
|||
|
|
|||
|
} // switch minor
|
|||
|
break;
|
|||
|
|
|||
|
} // switch major
|
|||
|
break;
|
|||
|
|
|||
|
//
|
|||
|
// This command initializes the ARIES memory before
|
|||
|
// the adapter is configured.
|
|||
|
//
|
|||
|
|
|||
|
case QVNEW:
|
|||
|
switch (ulCmd & 0x0F) {
|
|||
|
|
|||
|
//
|
|||
|
// We know that this is an ARIES mode. The command set
|
|||
|
// before this command unlocked the extended registers by
|
|||
|
// writing a 0x05 to 3CF.0F and a 0x28 to 3CF.10.
|
|||
|
// We need to make sure that if we are on a Juniper
|
|||
|
// we set single clock, 1024 pitch, and we disable the
|
|||
|
// advanced Juniper modes.
|
|||
|
// We also disable the Juniper extended register decode.
|
|||
|
// After we do that, we must make sure that we unlock the
|
|||
|
// Aries extended registers for safety. I don't know
|
|||
|
// if they are being locked by disabling the Juniper regs.
|
|||
|
//
|
|||
|
|
|||
|
case ARIES:
|
|||
|
|
|||
|
VideoDebugPrint((2,"\t ARIES_MODE\n"));
|
|||
|
if ((HwDeviceExtension->VideoHardware.AdapterType == JuniperIsa) ||
|
|||
|
(HwDeviceExtension->VideoHardware.AdapterType == JuniperEisa))
|
|||
|
{
|
|||
|
VideoPortWritePortUchar((PUCHAR)ARIES_CTL_1, // 1 pixel = 1 byte
|
|||
|
0x03);
|
|||
|
VideoPortWritePortUchar((PUCHAR)CTRL_REG_2, // ORION-12 register access
|
|||
|
0x10);
|
|||
|
VideoPortWritePortUchar((PUCHAR)CTRL_REG_3, // 1024 pixel pitch
|
|||
|
0x05); // 1MB memory decode
|
|||
|
|
|||
|
jValue = VideoPortReadPortUchar((PUCHAR)DAC_CMD_1);
|
|||
|
VideoPortWritePortUchar((PUCHAR)DAC_CMD_1,
|
|||
|
(UCHAR)(jValue | 0x80));
|
|||
|
VideoPortWritePortUchar((PUCHAR)(HwDeviceExtension->IOAddress +
|
|||
|
DAC_ADDRESS_WRITE_PORT),
|
|||
|
(UCHAR)(DAC_CMD_3_INDEX));
|
|||
|
|
|||
|
VideoPortWritePortUchar((PUCHAR)DAC_STATUS_REG,
|
|||
|
(UCHAR)(VideoPortReadPortUchar((PUCHAR)DAC_STATUS_REG) &
|
|||
|
~DBL_CLK));
|
|||
|
|
|||
|
VideoPortWritePortUchar((PUCHAR)CTRL_REG_2, // disable ext Juniper regs
|
|||
|
0x00);
|
|||
|
|
|||
|
jValue = VideoPortReadPortUchar((PUCHAR)DAC_CMD_0); // disable 485 modes.
|
|||
|
VideoPortWritePortUchar((PUCHAR)DAC_CMD_0,
|
|||
|
(UCHAR)(jValue & 0x7F));
|
|||
|
VideoPortWritePortUshort((PUSHORT)GRAPH_ADDRESS_PORT, // unlock ext. regs
|
|||
|
0x050f);
|
|||
|
VideoPortWritePortUshort((PUSHORT)GRAPH_ADDRESS_PORT, // enable BitBlt
|
|||
|
0x2810);
|
|||
|
} // if
|
|||
|
break;
|
|||
|
//
|
|||
|
// We know that his is a V32 mode. In this case
|
|||
|
// make sure that the clock is doubled, the pitch
|
|||
|
// is 2048 and the Juniper extended registers are accessible.
|
|||
|
//
|
|||
|
case V32:
|
|||
|
VideoDebugPrint((2,"\t JUNIPER_MODE\n"));
|
|||
|
|
|||
|
// VidalL 04/25/93
|
|||
|
//
|
|||
|
// IMPORTANT:
|
|||
|
// ==========
|
|||
|
// The AQUILLA monitor REQUIRES pixel clock 2 (value 30h)
|
|||
|
// The 60Hz and 68Hz timings require pixel clock 1
|
|||
|
// (value 20h). If this value is not set correctly for
|
|||
|
// the correct monitor, then the 1280 screen WILL NOT
|
|||
|
// SYNC !!!!! So, determine the correct value here below.
|
|||
|
//
|
|||
|
|
|||
|
// if (HwDeviceExtension->VideoHardware.MonClass==Monitor_1280)
|
|||
|
// VideoPortWritePortUchar((PUCHAR)DAC_CMD_2, 0x30);
|
|||
|
// else
|
|||
|
// VideoPortWritePortUchar((PUCHAR)DAC_CMD_2, 0x20);
|
|||
|
//
|
|||
|
//
|
|||
|
/*** $0004 ************ miked 1/26/1994 *****************************
|
|||
|
***
|
|||
|
*** Added third party monitor support to force a 76Hz refresh rate
|
|||
|
*** using the same timings as the QV200 timings.
|
|||
|
***
|
|||
|
*** Note: A new MonClass entry for 76Hz was used,
|
|||
|
*** See modeqv.h.
|
|||
|
***
|
|||
|
***********************************************************************/
|
|||
|
|
|||
|
if (HwDeviceExtension->VideoHardware.MonClass==Monitor_1280 ||
|
|||
|
HwDeviceExtension->VideoHardware.MonClass==Monitor_76Hz)
|
|||
|
VideoPortWritePortUchar((PUCHAR)DAC_CMD_2, 0x30);
|
|||
|
else
|
|||
|
VideoPortWritePortUchar((PUCHAR)DAC_CMD_2, 0x20);
|
|||
|
|
|||
|
/***********************************************************************/
|
|||
|
|
|||
|
VideoPortWritePortUchar((PUCHAR)ARIES_CTL_1, // 1 pixel = 1 byte
|
|||
|
0x03);
|
|||
|
VideoPortWritePortUchar((PUCHAR)CTRL_REG_2, // ORION-12 register access
|
|||
|
0x10);
|
|||
|
VideoPortWritePortUchar((PUCHAR)CTRL_REG_3, // 2048 pixel pitch
|
|||
|
0x09); // 2MB memory decode
|
|||
|
|
|||
|
jValue = VideoPortReadPortUchar((PUCHAR)DAC_CMD_0);
|
|||
|
|
|||
|
VideoPortWritePortUchar((PUCHAR)DAC_CMD_0,
|
|||
|
(UCHAR)(jValue | 0x80));
|
|||
|
VideoPortWritePortUchar((PUCHAR)(HwDeviceExtension->IOAddress +
|
|||
|
DAC_ADDRESS_WRITE_PORT),
|
|||
|
|
|||
|
(UCHAR)(DAC_CMD_3_INDEX));
|
|||
|
VideoPortWritePortUchar((PUCHAR)DAC_STATUS_REG,
|
|||
|
(UCHAR)(VideoPortReadPortUchar((PUCHAR)DAC_STATUS_REG) |
|
|||
|
DBL_CLK));
|
|||
|
VideoPortWritePortUshort((PUSHORT)GRAPH_ADDRESS_PORT, // unlock ext. regs
|
|||
|
0x050f);
|
|||
|
VideoPortWritePortUshort((PUSHORT)GRAPH_ADDRESS_PORT, // enable BitBlt
|
|||
|
0x2810);
|
|||
|
break;
|
|||
|
|
|||
|
//
|
|||
|
// For future V35 enhancements.
|
|||
|
//
|
|||
|
|
|||
|
case V35:
|
|||
|
|
|||
|
break;
|
|||
|
|
|||
|
case SETRAM:
|
|||
|
|
|||
|
VideoDebugPrint((2,"SETRAM\n"));
|
|||
|
|
|||
|
VideoPortReadPortUchar((PUCHAR)0x03BA);
|
|||
|
VideoPortReadPortUchar((PUCHAR)0x03DA);
|
|||
|
|
|||
|
VideoPortReadPortUchar((PUCHAR)(ulBase + ATT_ADDRESS_PORT));
|
|||
|
|
|||
|
VideoPortWritePortUchar((PUCHAR)(ulBase + DAC_PIXEL_MASK_PORT), 0x00);
|
|||
|
|
|||
|
|
|||
|
// start sync reset for the sequencer
|
|||
|
VideoPortWritePortUchar((PUCHAR)(ulBase + SEQ_ADDRESS_PORT),
|
|||
|
IND_SYNC_RESET);
|
|||
|
VideoPortWritePortUchar((PUCHAR)(ulBase + SEQ_DATA_PORT),
|
|||
|
START_SYNC_RESET_VALUE);
|
|||
|
|
|||
|
// set clock mode register 1 to 3c5.01 = 0x21 (turn off video and 8bit pixel
|
|||
|
VideoPortWritePortUchar((PUCHAR)(ulBase + SEQ_ADDRESS_PORT),
|
|||
|
0x01);
|
|||
|
VideoPortWritePortUchar((PUCHAR)(ulBase + SEQ_DATA_PORT),
|
|||
|
0x21);
|
|||
|
|
|||
|
// set sequencer memory mode register 4 to 3c5.04 = 0x0e
|
|||
|
VideoPortWritePortUchar((PUCHAR)(ulBase + SEQ_ADDRESS_PORT),
|
|||
|
IND_MEMORY_MODE);
|
|||
|
VideoPortWritePortUchar((PUCHAR)(ulBase + SEQ_DATA_PORT),
|
|||
|
0x0e);
|
|||
|
|
|||
|
// end sync reset for the sequencer
|
|||
|
VideoPortWritePortUchar((PUCHAR)(ulBase + SEQ_ADDRESS_PORT),
|
|||
|
IND_SYNC_RESET);
|
|||
|
VideoPortWritePortUchar((PUCHAR)(ulBase + SEQ_DATA_PORT),
|
|||
|
END_SYNC_RESET_VALUE);
|
|||
|
|
|||
|
// unlock graphics registers 3cf.0f = 0x05
|
|||
|
VideoPortWritePortUchar((PUCHAR)(ulBase + GRAPH_ADDRESS_PORT),
|
|||
|
0x0f);
|
|||
|
VideoPortWritePortUchar((PUCHAR)(ulBase + GRAPH_DATA_PORT),
|
|||
|
0x05);
|
|||
|
|
|||
|
// set aavga mode 3cf.40 = 0x01
|
|||
|
VideoPortWritePortUchar((PUCHAR)(ulBase + GRAPH_ADDRESS_PORT),
|
|||
|
0x40);
|
|||
|
VideoPortWritePortUchar((PUCHAR)(ulBase + GRAPH_DATA_PORT),
|
|||
|
0x01);
|
|||
|
|
|||
|
// set sequencer memory pixel write mask register 2 to 3c5.02 = 0xff
|
|||
|
VideoPortWritePortUchar((PUCHAR)(ulBase + SEQ_ADDRESS_PORT),
|
|||
|
0x02);
|
|||
|
VideoPortWritePortUchar((PUCHAR)(ulBase + SEQ_DATA_PORT),
|
|||
|
0xff);
|
|||
|
|
|||
|
// unlock BITBLT registers 3cf.10 = 0x28;
|
|||
|
VideoPortWritePortUchar((PUCHAR)(ulBase + GRAPH_ADDRESS_PORT),
|
|||
|
0x10);
|
|||
|
VideoPortWritePortUchar((PUCHAR)(ulBase + GRAPH_DATA_PORT),
|
|||
|
0x28);
|
|||
|
|
|||
|
// control register 1 63ca = 0x03
|
|||
|
VideoPortWritePortUchar((PUCHAR)ARIES_CTL_1, 0x03);
|
|||
|
|
|||
|
// misc output register 3c2 = 0x27
|
|||
|
VideoPortWritePortUchar((PUCHAR)((PUCHAR)ulBase + MISC_OUTPUT_REG_WRITE_PORT),
|
|||
|
0x27);
|
|||
|
|
|||
|
//
|
|||
|
// $0006 - MikeD - 03/04/94
|
|||
|
// Begin: add 10 millisecond delay after r/w
|
|||
|
// of 3c2
|
|||
|
//
|
|||
|
// 10000microsecs = 10ms
|
|||
|
//
|
|||
|
// I know I should not stall more than 50, but
|
|||
|
// there is no other way around this...
|
|||
|
|
|||
|
VideoPortStallExecution( 10000 );
|
|||
|
|
|||
|
// set high address registers
|
|||
|
//
|
|||
|
// adrianc 4/7/1993
|
|||
|
// We are starting off with Banking so we do not set
|
|||
|
// the HIGH ADDRESS register yet.
|
|||
|
//
|
|||
|
//$DEL$// VideoPortWritePortUchar((PUCHAR)GRAPH_ADDRESS_PORT, HIGH_ADDR_MAP);
|
|||
|
//$DEL$// VideoPortWritePortUchar((PUCHAR)GRAPH_DATA_PORT, (UCHAR)((HwDeviceExtension->PhysicalSaveAddress >> 20) & 0x0FF));
|
|||
|
//$DEL$// VideoPortWritePortUchar((PUCHAR)GRAPH_ADDRESS_PORT, HIGH_ADDR_MAP+1);
|
|||
|
//$DEL$// VideoPortWritePortUchar((PUCHAR)GRAPH_DATA_PORT, (UCHAR)((HwDeviceExtension->PhysicalSaveAddress >> 28) & 0x0FF));
|
|||
|
//
|
|||
|
|
|||
|
// set DAC registers
|
|||
|
VideoPortWritePortUchar((PUCHAR)DAC_CMD_0, 0x00);
|
|||
|
VideoPortWritePortUchar((PUCHAR)DAC_CMD_1, 0x40);
|
|||
|
VideoPortWritePortUchar((PUCHAR)DAC_CMD_2, 0x20);
|
|||
|
|
|||
|
// unlock ctrc registers
|
|||
|
VideoPortWritePortUchar((PUCHAR)((PUCHAR)ulBase + CRTC_ADDRESS_PORT_MONO + COLOR_ADJUSTMENT),
|
|||
|
(UCHAR)0x11);
|
|||
|
VideoPortWritePortUchar((PUCHAR)((PUCHAR)ulBase + CRTC_DATA_PORT_MONO + COLOR_ADJUSTMENT),
|
|||
|
0x00);
|
|||
|
|
|||
|
// set crtc registers
|
|||
|
{ UCHAR *crtc_values = "\xA1\x7F\x7F\x84\x85\x9B\x2E\xF5\x0\x60\x0\x0\x0\x0\x0\x0\x7\x8B\xFF\x80\x0\xFF\x2E\xE3\xFF";
|
|||
|
|
|||
|
for(culCount=0; culCount <= 0x18 ; culCount++, crtc_values++) {
|
|||
|
VideoPortWritePortUchar((PUCHAR)((PUCHAR)ulBase + CRTC_ADDRESS_PORT_MONO + COLOR_ADJUSTMENT),
|
|||
|
(UCHAR)culCount);
|
|||
|
VideoPortWritePortUchar((PUCHAR)((PUCHAR)ulBase + CRTC_DATA_PORT_MONO + COLOR_ADJUSTMENT),
|
|||
|
*crtc_values);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// setup crt overflow regs
|
|||
|
VideoPortWritePortUchar((PUCHAR)(ulBase + GRAPH_ADDRESS_PORT),
|
|||
|
OVERFLOW_REG_1);
|
|||
|
VideoPortWritePortUchar((PUCHAR)(ulBase + GRAPH_DATA_PORT),
|
|||
|
0x00);
|
|||
|
VideoPortWritePortUchar((PUCHAR)(ulBase + GRAPH_ADDRESS_PORT),
|
|||
|
OVERFLOW_REG_2);
|
|||
|
VideoPortWritePortUchar((PUCHAR)(ulBase + GRAPH_DATA_PORT),
|
|||
|
0x00);
|
|||
|
|
|||
|
// setup overscan color registers
|
|||
|
VideoPortWritePortUchar((PUCHAR)CO_COLOR_WRITE, 0x00);
|
|||
|
for (culCount=0; culCount<3; culCount++) {
|
|||
|
VideoPortWritePortUchar((PUCHAR)CO_COLOR_DATA, 0x00);
|
|||
|
}
|
|||
|
|
|||
|
// setup attribute controller
|
|||
|
VideoPortReadPortUchar((PUCHAR)0x3da); // reset the latch
|
|||
|
|
|||
|
for (culCount=0; culCount < 0x10; culCount++) {
|
|||
|
VideoPortWritePortUchar((PUCHAR)((PUCHAR)ulBase + ATT_ADDRESS_PORT),
|
|||
|
(UCHAR)culCount);
|
|||
|
VideoPortWritePortUchar((PUCHAR)((PUCHAR)ulBase + ATT_DATA_WRITE_PORT),
|
|||
|
(UCHAR)culCount);
|
|||
|
}
|
|||
|
VideoPortWritePortUchar((PUCHAR)(ulBase + ATT_ADDRESS_PORT), 0x10);
|
|||
|
VideoPortWritePortUchar((PUCHAR)(ulBase + ATT_DATA_WRITE_PORT),0x41);
|
|||
|
VideoPortWritePortUchar((PUCHAR)(ulBase + ATT_ADDRESS_PORT),0x11);
|
|||
|
VideoPortWritePortUchar((PUCHAR)(ulBase + ATT_DATA_WRITE_PORT),0x00);
|
|||
|
VideoPortWritePortUchar((PUCHAR)(ulBase + ATT_ADDRESS_PORT), 0x12);
|
|||
|
VideoPortWritePortUchar((PUCHAR)(ulBase + ATT_DATA_WRITE_PORT), 0x0f);
|
|||
|
VideoPortWritePortUchar((PUCHAR)(ulBase + ATT_ADDRESS_PORT), 0x13);
|
|||
|
VideoPortWritePortUchar((PUCHAR)(ulBase + ATT_DATA_WRITE_PORT), 0x00);
|
|||
|
VideoPortWritePortUchar((PUCHAR)(ulBase + ATT_ADDRESS_PORT), 0x14);
|
|||
|
VideoPortWritePortUchar((PUCHAR)(ulBase + ATT_DATA_WRITE_PORT), 0x00);
|
|||
|
|
|||
|
// setup graphics register
|
|||
|
for (culCount=0; culCount < 0x06; culCount++) {
|
|||
|
VideoPortWritePortUchar((PUCHAR)(ulBase + GRAPH_ADDRESS_PORT),
|
|||
|
(UCHAR)culCount);
|
|||
|
VideoPortWritePortUchar((PUCHAR)(ulBase + GRAPH_DATA_PORT),
|
|||
|
0x00);
|
|||
|
}
|
|||
|
VideoPortWritePortUchar((PUCHAR)(ulBase + GRAPH_ADDRESS_PORT),
|
|||
|
0x06);
|
|||
|
VideoPortWritePortUchar((PUCHAR)(ulBase + GRAPH_DATA_PORT),
|
|||
|
0x05);
|
|||
|
VideoPortWritePortUchar((PUCHAR)(ulBase + GRAPH_ADDRESS_PORT),
|
|||
|
0x07);
|
|||
|
VideoPortWritePortUchar((PUCHAR)(ulBase + GRAPH_DATA_PORT),
|
|||
|
0x0f);
|
|||
|
VideoPortWritePortUchar((PUCHAR)(ulBase + GRAPH_ADDRESS_PORT),
|
|||
|
0x08);
|
|||
|
VideoPortWritePortUchar((PUCHAR)(ulBase + GRAPH_DATA_PORT),
|
|||
|
0xff);
|
|||
|
|
|||
|
{ /* FIX VGA BUG */
|
|||
|
USHORT Port = (USHORT)(ulBase + CRTC_ADDRESS_PORT_MONO);
|
|||
|
|
|||
|
VideoPortWritePortUchar((PUCHAR)0x03C4, 0x07);
|
|||
|
|
|||
|
if (VideoPortReadPortUchar((PUCHAR)(ulBase + MISC_OUTPUT_REG_READ_PORT)) & 0x01) {
|
|||
|
|
|||
|
Port += COLOR_ADJUSTMENT;
|
|||
|
//
|
|||
|
// $0006 - MikeD - 03/04/94
|
|||
|
// Begin: add 10 millisecond delay after r/w
|
|||
|
// of 3c2
|
|||
|
//
|
|||
|
// 10000microsecs = 10ms
|
|||
|
//
|
|||
|
// I know I should not stall more than 50, but
|
|||
|
// there is no other way around this...
|
|||
|
|
|||
|
VideoPortStallExecution( 10000 );
|
|||
|
}
|
|||
|
|
|||
|
VideoPortWritePortUchar((PUCHAR)Port,
|
|||
|
0x3F);
|
|||
|
|
|||
|
VideoPortWritePortUchar((PUCHAR)Port + 1,
|
|||
|
0x01);
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
// Enable BitBlt and disable IRQ 9
|
|||
|
VideoPortWritePortUchar((PUCHAR)(ulBase + GRAPH_ADDRESS_PORT),
|
|||
|
0x10);
|
|||
|
VideoPortWritePortUchar((PUCHAR)(ulBase + GRAPH_DATA_PORT),
|
|||
|
0x68);
|
|||
|
VideoPortWritePortUchar((PUCHAR)(ulBase + GRAPH_DATA_PORT),
|
|||
|
0x28);
|
|||
|
|
|||
|
VideoPortWritePortUchar((PUCHAR)(ulBase + GRAPH_ADDRESS_PORT),
|
|||
|
0x5a);
|
|||
|
VideoPortWritePortUchar((PUCHAR)(ulBase + GRAPH_DATA_PORT),
|
|||
|
0x6);
|
|||
|
|
|||
|
// reset the Pattern registers
|
|||
|
VideoPortWritePortUchar((PUCHAR)PREG_0, 0);
|
|||
|
VideoPortWritePortUchar((PUCHAR)PREG_1, 0);
|
|||
|
VideoPortWritePortUchar((PUCHAR)PREG_2, 0);
|
|||
|
VideoPortWritePortUchar((PUCHAR)PREG_3, 0);
|
|||
|
VideoPortWritePortUchar((PUCHAR)PREG_4, 0);
|
|||
|
VideoPortWritePortUchar((PUCHAR)PREG_5, 0);
|
|||
|
VideoPortWritePortUchar((PUCHAR)PREG_6, 0);
|
|||
|
VideoPortWritePortUchar((PUCHAR)PREG_7, 0);
|
|||
|
|
|||
|
// Reset the BitBlt registers
|
|||
|
VideoPortWritePortUchar((PUCHAR)BLT_DEST_ADDR_LO, 0);
|
|||
|
VideoPortWritePortUchar((PUCHAR)BLT_DEST_ADDR_HI, 0);
|
|||
|
VideoPortWritePortUshort((PUSHORT)BITMAP_WIDTH, 0x400);
|
|||
|
VideoPortWritePortUshort((PUSHORT)BITMAP_HEIGHT, 0x3ff);
|
|||
|
VideoPortWritePortUchar((PUCHAR)BLT_CMD_1, 0xc0);
|
|||
|
VideoPortWritePortUchar((PUCHAR)BLT_CMD_0, 0x01);
|
|||
|
|
|||
|
VideoPortReadPortUchar((PUCHAR)ARIES_CTL_1);
|
|||
|
|
|||
|
// Enable BitBlt and disable IRQ 9
|
|||
|
VideoPortWritePortUchar((PUCHAR)(ulBase + GRAPH_ADDRESS_PORT),
|
|||
|
0x10);
|
|||
|
VideoPortWritePortUchar((PUCHAR)(ulBase + GRAPH_DATA_PORT),
|
|||
|
0x68);
|
|||
|
VideoPortWritePortUchar((PUCHAR)(ulBase + GRAPH_DATA_PORT),
|
|||
|
0x28);
|
|||
|
|
|||
|
break;
|
|||
|
} // switch
|
|||
|
|
|||
|
break;
|
|||
|
|
|||
|
//
|
|||
|
// Unknown command; error
|
|||
|
//
|
|||
|
|
|||
|
default:
|
|||
|
VideoDebugPrint((2,"\tdefault\n"));
|
|||
|
return FALSE;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
VideoDebugPrint((1, "QVision.sys: VgaInterpretCmdStream - EXIT.\n"));
|
|||
|
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;
|
|||
|
PUSHORT pusCmdStream;
|
|||
|
VIDEO_X86_BIOS_ARGUMENTS biosArguments;
|
|||
|
UCHAR ucTemp; // temporary register storage
|
|||
|
UCHAR temp;
|
|||
|
UCHAR dummy;
|
|||
|
UCHAR bIsColor;
|
|||
|
|
|||
|
|
|||
|
VideoDebugPrint((1,"QVision.sys: VgaSetMode - ENTRY.\n"));
|
|||
|
VideoDebugPrint((1,"\tRequested Mode = 0x%x\n",Mode->RequestedMode));
|
|||
|
|
|||
|
#ifdef QV_DBG
|
|||
|
DbgBreakPoint();
|
|||
|
#endif
|
|||
|
|
|||
|
//
|
|||
|
// Check if the size of the data in the input buffer is large enough.
|
|||
|
//
|
|||
|
|
|||
|
if (ModeSize < sizeof(VIDEO_MODE)) {
|
|||
|
|
|||
|
return ERROR_INSUFFICIENT_BUFFER;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Blank the screen prior to clearing video memory
|
|||
|
//
|
|||
|
|
|||
|
VideoPortWritePortUchar((PUCHAR)(HwDeviceExtension->IOAddress +
|
|||
|
SEQ_ADDRESS_PORT), (UCHAR) 0x01);
|
|||
|
|
|||
|
ucTemp = VideoPortReadPortUchar((PUCHAR) HwDeviceExtension->IOAddress +
|
|||
|
SEQ_DATA_PORT);
|
|||
|
|
|||
|
VideoPortWritePortUchar((PUCHAR)(HwDeviceExtension->IOAddress +
|
|||
|
SEQ_DATA_PORT), (UCHAR)(ucTemp | (UCHAR) 0x20));
|
|||
|
|
|||
|
//
|
|||
|
// 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 >= NumVideoModes) ||
|
|||
|
(!ModesVGA[Mode->RequestedMode].ValidMode) ) {
|
|||
|
|
|||
|
VideoDebugPrint((1,"\tERROR_INVALID_PARAMETER.\n"));
|
|||
|
return ERROR_INVALID_PARAMETER;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
pRequestedMode = &ModesVGA[Mode->RequestedMode];
|
|||
|
|
|||
|
//
|
|||
|
// Store the new mode value.
|
|||
|
//
|
|||
|
|
|||
|
HwDeviceExtension->CurrentMode = pRequestedMode;
|
|||
|
HwDeviceExtension->ModeIndex = Mode->RequestedMode;
|
|||
|
|
|||
|
//
|
|||
|
// $0005 - MikeD - 02/08/94
|
|||
|
// Begin:
|
|||
|
// Daytona - MikeD - 02/09/94 need to set MonClass based on requested
|
|||
|
// refresh rate.
|
|||
|
//
|
|||
|
HwDeviceExtension->VideoHardware.lFrequency = pRequestedMode->ulRefreshRate;
|
|||
|
GetMonClass(HwDeviceExtension);
|
|||
|
//
|
|||
|
// End:
|
|||
|
// Daytona - MikeD - 02/09/94
|
|||
|
//
|
|||
|
|
|||
|
|
|||
|
//
|
|||
|
// Select proper command array for adapter type
|
|||
|
//
|
|||
|
|
|||
|
#ifdef INIT_INT10
|
|||
|
{
|
|||
|
|
|||
|
VideoPortZeroMemory(&biosArguments, sizeof(VIDEO_X86_BIOS_ARGUMENTS));
|
|||
|
|
|||
|
biosArguments.Eax = pRequestedMode->usInt10ModeNum;
|
|||
|
VideoPortInt10(HwDeviceExtension, &biosArguments);
|
|||
|
}
|
|||
|
#else
|
|||
|
|
|||
|
/***********************************************************************
|
|||
|
*** 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));
|
|||
|
//
|
|||
|
// $0007 - MikeD - 06/17/94
|
|||
|
// Must key off of ulResIndex instead of Mode->RequestedMode since its
|
|||
|
// not a one-to-one relationship anymore. The Mode->RequestedMode now
|
|||
|
// acts as an index into ModesVGA[] and therefore the index used for
|
|||
|
// each monitor refresh (i.e. QV_TEXT_720x400x4_INDEX) is duplicated
|
|||
|
// across each like mode (with different refresh rates). This was
|
|||
|
// found in Japanese NT because when the vdm requests full-screen, it
|
|||
|
// is a different mode than when the U.S. NT requests a full-screen.
|
|||
|
//
|
|||
|
// OLD WAY ===> switch (Mode->RequestedMode) {
|
|||
|
switch (pRequestedMode->ulResIndex) {
|
|||
|
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
|
|||
|
VideoPortInt10(HwDeviceExtension, &biosArguments);
|
|||
|
|
|||
|
/***********************************************************************
|
|||
|
*** Set the video mode to BIOS mode 3. ***
|
|||
|
***********************************************************************/
|
|||
|
VideoPortZeroMemory(&biosArguments, sizeof(VIDEO_X86_BIOS_ARGUMENTS));
|
|||
|
biosArguments.Eax = 0x03; // bios mode 0x03
|
|||
|
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
|
|||
|
VideoPortInt10(HwDeviceExtension, &biosArguments);
|
|||
|
|
|||
|
/***********************************************************************
|
|||
|
*** Set the video mode to BIOS mode 3. ***
|
|||
|
***********************************************************************/
|
|||
|
VideoPortZeroMemory(&biosArguments, sizeof(VIDEO_X86_BIOS_ARGUMENTS));
|
|||
|
biosArguments.Eax = 0x03; // bios mode 0x03
|
|||
|
VideoPortInt10(HwDeviceExtension, &biosArguments);
|
|||
|
break;
|
|||
|
case 2: // 640x480x4
|
|||
|
biosArguments.Eax = 0x12; // bios mode 0x12
|
|||
|
VideoPortInt10(HwDeviceExtension, &biosArguments);
|
|||
|
break;
|
|||
|
|
|||
|
default: // all graphics modes are
|
|||
|
// handled by the default case
|
|||
|
pusCmdStream = pRequestedMode->CmdStrings.QVCmdStrings;
|
|||
|
VgaInterpretCmdStream(HwDeviceExtension, pusCmdStream);
|
|||
|
break;
|
|||
|
} // switch
|
|||
|
|
|||
|
//
|
|||
|
// Fix to get 640x350 text mode
|
|||
|
//
|
|||
|
|
|||
|
if (!(pRequestedMode->fbType & VIDEO_MODE_GRAPHICS)) {
|
|||
|
|
|||
|
//
|
|||
|
// 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;
|
|||
|
|
|||
|
//
|
|||
|
// $0006 - MikeD - 03/04/94
|
|||
|
// Begin: add 10 millisecond delay after r/w
|
|||
|
// of 3c2
|
|||
|
//
|
|||
|
// 10000microsecs = 10ms
|
|||
|
//
|
|||
|
// I know I should not stall more than 50, but
|
|||
|
// there is no other way around this...
|
|||
|
|
|||
|
VideoPortStallExecution( 10000 );
|
|||
|
|
|||
|
} else {
|
|||
|
|
|||
|
bIsColor = FALSE;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
if (bIsColor) {
|
|||
|
|
|||
|
dummy = VideoPortReadPortUchar(HwDeviceExtension->IOAddress +
|
|||
|
INPUT_STATUS_1_COLOR);
|
|||
|
} else {
|
|||
|
|
|||
|
dummy = VideoPortReadPortUchar(HwDeviceExtension->IOAddress +
|
|||
|
INPUT_STATUS_1_MONO);
|
|||
|
} // else
|
|||
|
|
|||
|
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);
|
|||
|
} // else
|
|||
|
|
|||
|
VideoPortWritePortUchar(HwDeviceExtension->IOAddress +
|
|||
|
ATT_ADDRESS_PORT, (0x10 | VIDEO_ENABLE));
|
|||
|
VideoPortWritePortUchar(HwDeviceExtension->IOAddress +
|
|||
|
ATT_DATA_WRITE_PORT, temp);
|
|||
|
} // if
|
|||
|
#endif
|
|||
|
|
|||
|
//
|
|||
|
// Support 256 color modes by stretching the scan lines.
|
|||
|
//
|
|||
|
|
|||
|
//
|
|||
|
// Update the location of the physical frame buffer within video memory.
|
|||
|
//
|
|||
|
|
|||
|
HwDeviceExtension->PhysicalFrameLength =
|
|||
|
MemoryMaps[pRequestedMode->MemMap].MaxSize;
|
|||
|
|
|||
|
HwDeviceExtension->PhysicalFrameBase.LowPart =
|
|||
|
MemoryMaps[pRequestedMode->MemMap].Start;
|
|||
|
|
|||
|
//
|
|||
|
// Enable memory-mapped I/O if required
|
|||
|
//
|
|||
|
|
|||
|
if ((Mode->RequestedMode != DEFAULT_MODE) &&
|
|||
|
(HwDeviceExtension->PhysicalMemoryMappedLength != 0)) {
|
|||
|
|
|||
|
VideoPortWritePortUchar((PUCHAR) CTRL_REG_2, 0x10);
|
|||
|
|
|||
|
VideoPortWritePortUchar((PUCHAR) MEMORY_MAP_BASE,
|
|||
|
(UCHAR) (HwDeviceExtension->PhysicalMemoryMappedBase.LowPart / 4096 - 0x80));
|
|||
|
|
|||
|
VideoPortWritePortUchar((PUCHAR) CTRL_REG_2, 0x11);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
//
|
|||
|
// Set the graphic cursor fg color (white)
|
|||
|
//
|
|||
|
|
|||
|
VideoPortWritePortUchar( (PUCHAR) CURSOR_COLOR_WRITE, CURSOR_COLOR_2);
|
|||
|
VideoPortWritePortUchar( (PUCHAR) CURSOR_COLOR_DATA, 0xff);
|
|||
|
VideoPortWritePortUchar( (PUCHAR) CURSOR_COLOR_DATA, 0xff);
|
|||
|
VideoPortWritePortUchar( (PUCHAR) CURSOR_COLOR_DATA, 0xff);
|
|||
|
|
|||
|
//
|
|||
|
// Set the graphic cursor bg color (black)
|
|||
|
//
|
|||
|
|
|||
|
VideoPortWritePortUchar( (PUCHAR) CURSOR_COLOR_WRITE, CURSOR_COLOR_1);
|
|||
|
VideoPortWritePortUchar( (PUCHAR) CURSOR_COLOR_DATA, 0x00);
|
|||
|
VideoPortWritePortUchar( (PUCHAR) CURSOR_COLOR_DATA, 0x00);
|
|||
|
VideoPortWritePortUchar( (PUCHAR) CURSOR_COLOR_DATA, 0x00);
|
|||
|
|
|||
|
|
|||
|
VideoDebugPrint((1,"QVision.sys: VgaSetMode - EXIT.\n"));
|
|||
|
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;
|
|||
|
|
|||
|
VideoDebugPrint((1,"QVision.sys: VgaQueryAvailableModes - ENTRY.\n"));
|
|||
|
|
|||
|
//
|
|||
|
// 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)) ) {
|
|||
|
|
|||
|
VideoDebugPrint((1,"\tERROR_INSUFFICIENT_BUFFER.\n"));
|
|||
|
VideoDebugPrint((1,"QVision.sys: VgaQueryAvailableModes - EXIT.\n"));
|
|||
|
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++) {
|
|||
|
|
|||
|
//
|
|||
|
// $0005 - MikeD - 02/08/94
|
|||
|
// Daytona support
|
|||
|
//
|
|||
|
|
|||
|
VideoDebugPrint((2,"\tVideoMode = 0x%x (%ldHz) ",i,
|
|||
|
ModesVGA[i].ulRefreshRate));
|
|||
|
|
|||
|
|
|||
|
//
|
|||
|
// If we have enough memory to support the mode, set all videoModes
|
|||
|
// values according to the data in the mode table.
|
|||
|
//
|
|||
|
|
|||
|
if (ModesVGA[i].ValidMode) {
|
|||
|
|
|||
|
VideoDebugPrint((2," - VALID MODE"));
|
|||
|
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 = ModesVGA[i].ulRefreshRate;
|
|||
|
videoModes->XMillimeter = 320; // temporary hardcoded constant
|
|||
|
videoModes->YMillimeter = 240; // temporary hardcoded constant
|
|||
|
|
|||
|
switch (videoModes->BitsPerPlane) {
|
|||
|
|
|||
|
case 4:
|
|||
|
|
|||
|
VideoDebugPrint((2," - 4BPP\n"));
|
|||
|
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;
|
|||
|
break;
|
|||
|
|
|||
|
case 8:
|
|||
|
|
|||
|
VideoDebugPrint((2," - 8BPP\n"));
|
|||
|
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;
|
|||
|
break;
|
|||
|
|
|||
|
case 16:
|
|||
|
|
|||
|
VideoDebugPrint((2," - 16BPP\n"));
|
|||
|
if ((HwDeviceExtension->VideoHardware.AdapterType != AriesEisa) &&
|
|||
|
(HwDeviceExtension->VideoHardware.AdapterType != AriesIsa)) {
|
|||
|
videoModes->ScreenStride = 2048;
|
|||
|
} // if
|
|||
|
|
|||
|
// NOTE: hard coded to 5:5:5 color format
|
|||
|
videoModes->NumberRedBits = 5;
|
|||
|
videoModes->NumberGreenBits = 5;
|
|||
|
videoModes->NumberBlueBits = 5;
|
|||
|
videoModes->RedMask = 0x7C00;
|
|||
|
videoModes->GreenMask = 0x03E0;
|
|||
|
videoModes->BlueMask = 0x001F;
|
|||
|
videoModes->AttributeFlags = ModesVGA[i].fbType;
|
|||
|
break;
|
|||
|
|
|||
|
case 32:
|
|||
|
|
|||
|
VideoDebugPrint((2," - 32BPP\n"));
|
|||
|
if ((HwDeviceExtension->VideoHardware.AdapterType != AriesEisa) &&
|
|||
|
(HwDeviceExtension->VideoHardware.AdapterType != AriesIsa)) {
|
|||
|
videoModes->ScreenStride = 2048;
|
|||
|
} // if
|
|||
|
|
|||
|
videoModes->NumberRedBits = 8;
|
|||
|
videoModes->NumberGreenBits = 8;
|
|||
|
videoModes->NumberBlueBits = 8;
|
|||
|
videoModes->RedMask = 0x000000ff;
|
|||
|
videoModes->GreenMask = 0x0000ff00;
|
|||
|
videoModes->BlueMask = 0x00ff0000;
|
|||
|
videoModes->AttributeFlags = ModesVGA[i].fbType;
|
|||
|
break;
|
|||
|
|
|||
|
default:
|
|||
|
|
|||
|
VideoDebugPrint((2," - default\n"));
|
|||
|
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;
|
|||
|
break;
|
|||
|
|
|||
|
} // switch
|
|||
|
|
|||
|
videoModes++; // next mode
|
|||
|
|
|||
|
} // end if
|
|||
|
|
|||
|
#ifdef QV_DBG
|
|||
|
|
|||
|
else {
|
|||
|
|
|||
|
VideoDebugPrint((2," - INVALID MODE\n"));
|
|||
|
|
|||
|
} // else
|
|||
|
|
|||
|
#endif
|
|||
|
|
|||
|
} // end for i
|
|||
|
|
|||
|
|
|||
|
VideoDebugPrint((1,"QVision.sys: VgaQueryAvailableModes - EXIT.\n"));
|
|||
|
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.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
USHORT i;
|
|||
|
|
|||
|
VideoDebugPrint((1,"QVision.sys: VgaQueryNumberOfAvailableModes - ENTRY.\n"));
|
|||
|
|
|||
|
//
|
|||
|
// 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)) ) {
|
|||
|
|
|||
|
VideoDebugPrint((1,"QVision.sys: VgaQueryNumberOfAvailableModes - EXIT.\n"));
|
|||
|
return ERROR_INSUFFICIENT_BUFFER;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
HwDeviceExtension->NumAvailableModes = 0; // init the number avail modes
|
|||
|
// for the current configuration
|
|||
|
for (i = 0; i < NumVideoModes; i++) {
|
|||
|
|
|||
|
//
|
|||
|
// First find out if we have enough memory for the
|
|||
|
// mode we are checking.
|
|||
|
// We also need to check if the current monitor supports
|
|||
|
// the current mode.
|
|||
|
// If both conditions are TRUE then this mode is valid.
|
|||
|
// We need to make sure that if this is the 1280 mode and
|
|||
|
// we have 2MB of RAM, the card is a Juniper and not a
|
|||
|
// FIR with a twig. FIR does not support 1280 modes.
|
|||
|
//
|
|||
|
|
|||
|
// if ((HwDeviceExtension->InstalledVmem >= ModesVGA[i].VmemRequired) &&
|
|||
|
// (fValidMode[HwDeviceExtension->VideoHardware.MonClass][i])) {
|
|||
|
|
|||
|
//
|
|||
|
// $0005 - MikeD - 02/08/94
|
|||
|
// Daytona changes.
|
|||
|
|
|||
|
if (HwDeviceExtension->InstalledVmem >= ModesVGA[i].VmemRequired) {
|
|||
|
|
|||
|
if (ModesVGA[i].hres < 1280) {
|
|||
|
VideoDebugPrint((2,"\tVALID VideoMode = 0x%x\n",i));
|
|||
|
ModesVGA[i].ValidMode = TRUE;
|
|||
|
HwDeviceExtension->NumAvailableModes++;
|
|||
|
} // if
|
|||
|
|
|||
|
else if ((HwDeviceExtension->VideoHardware.AdapterType >= JuniperEisa) ||
|
|||
|
(HwDeviceExtension->VideoHardware.AdapterType >= JuniperIsa)) {
|
|||
|
|
|||
|
VideoDebugPrint((2,"\tVALID VideoMode = 0x%x\n",i));
|
|||
|
ModesVGA[i].ValidMode = TRUE;
|
|||
|
HwDeviceExtension->NumAvailableModes++;
|
|||
|
|
|||
|
} // else
|
|||
|
|
|||
|
} // if
|
|||
|
|
|||
|
} // for
|
|||
|
|
|||
|
//
|
|||
|
// Store the number of modes into the buffer.
|
|||
|
//
|
|||
|
|
|||
|
NumModes->NumModes = HwDeviceExtension->NumAvailableModes;
|
|||
|
NumModes->ModeInformationLength = sizeof(VIDEO_MODE_INFORMATION);
|
|||
|
|
|||
|
VideoDebugPrint((2,"\tNumModes = 0x%x\n",NumModes->NumModes));
|
|||
|
|
|||
|
VideoDebugPrint((1,"QVision.sys: VgaQueryNumberOfAvailableModes - EXIT.\n"));
|
|||
|
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.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
VideoDebugPrint((1,"QVision.sys: VgaQueryCurrentMode - ENTRY.\n"));
|
|||
|
|
|||
|
//
|
|||
|
//
|
|||
|
// 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))) {
|
|||
|
|
|||
|
VideoDebugPrint((1,"QVision.sys: VgaQueryCurrentMode - EXIT.\n"));
|
|||
|
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 = HwDeviceExtension->VideoHardware.lFrequency;
|
|||
|
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;
|
|||
|
|
|||
|
VideoDebugPrint((1,"QVision.sys: VgaQueryCurrentMode - EXIT.\n"));
|
|||
|
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;
|
|||
|
ULONG i;
|
|||
|
ULONG max;
|
|||
|
|
|||
|
VideoDebugPrint((1,"QVision.sys: VgaZeroVideoMemory - ENTRY.\n"));
|
|||
|
|
|||
|
//
|
|||
|
// 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 for all pages.
|
|||
|
//
|
|||
|
//
|
|||
|
max = 4; // for QVision we assume 4 banks
|
|||
|
|
|||
|
for (i = 0; i < max; i++) {
|
|||
|
|
|||
|
SetQVisionBanking(HwDeviceExtension,i);// setup next 256k bank
|
|||
|
VideoPortZeroMemory(HwDeviceExtension->VideoMemoryAddress,
|
|||
|
0xFFFF);
|
|||
|
|
|||
|
} // end for
|
|||
|
SetQVisionBanking(HwDeviceExtension,0); // reset the banks
|
|||
|
|
|||
|
VgaInterpretCmdStream(HwDeviceExtension, DisableA000Color);
|
|||
|
|
|||
|
VideoDebugPrint((1,"QVision.sys: VgaZeroVideoMemory - EXIT.\n"));
|
|||
|
}
|
|||
|
|
|||
|
//---------------------------------------------------------------------------
|
|||
|
VOID
|
|||
|
SetQVisionBanking(
|
|||
|
PHW_DEVICE_EXTENSION HwDeviceExtension,
|
|||
|
ULONG BankNumber
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
HwDeviceExtension - Pointer to the miniport driver's device extension.
|
|||
|
|
|||
|
BankNumber - the 64k bank number to set in 1RW mode(we will set this mode).
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
vmem256k, vmem512k, or vmem1Meg ONLY ( these are defined in cirrus.h).
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
|
|||
|
VideoPortWritePortUshort((PUSHORT)(HwDeviceExtension->IOAddress +
|
|||
|
GRAPH_ADDRESS_PORT), 0x030d);
|
|||
|
|
|||
|
VideoPortWritePortUshort((PUSHORT)(HwDeviceExtension->IOAddress +
|
|||
|
GRAPH_ADDRESS_PORT), (USHORT)(0x000e + (BankNumber << (8+4))) );
|
|||
|
|
|||
|
|
|||
|
|
|||
|
} // SetQVisionBanking()
|