Windows NT 4.0 source code leak
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.
 
 
 
 
 
 

2647 lines
83 KiB

/*++
Copyright (c) 1990-1992 Microsoft Corporation
Copyright (c) 1994 FirePower Systems, Inc.
Module Name:
psidisp.c - based on Microsoft's jzvxl484.csource code.
Abstract:
This module contains the code that implements the display kernel
video driver for the PSI's DCC (display controller chip) and Bt445.
Author:
Neil Ogura (9-7-1994)
Environment:
Version history:
--*/
/*
* Copyright (c) 1995 FirePower Systems, Inc.
* DO NOT DISTRIBUTE without permission
*
* $RCSfile: psidisp.c $
* $Revision: 1.2 $
* $Date: 1996/04/24 00:07:50 $
* $Locker: $
*/
/** This flag is to crease full cached version of display driver - need to be matching with
FULLCACHE flag in ppc/ladj.h for PSIDISP.DLL **/
#define FULLCACHE FALSE
/** This flag is to control if display driver will change BAT or not, if HAL starts setting BAT
for framebuffer with cache enabled, this should be set to FALSE, otherwise TRUE **/
#define WRITEBAT FALSE
/** This flag is to use wrap around frame buffer address or not **/
/** When it's set to FALSE, display driver assumes the HAL not to add PCI_MEMORY_PHYSICAL_BASE if
the mapping physical address is the VRAM (0x70000000). When it's set to TRUE, display driver
passes the physical address to map by subtracting PCI_MEMORY_PHYSICAL_BASE (0xc0000000) in order
to get correct mapping after the offset addition by the HAL when mapping. So, the version of
display driver and the HAL has to be matching when it's set to FALSE **/
#define WRAPADDRESS FALSE
/** These flags are to control if display driver sets system regiosters.
SYSTEMREGS_1 is for memory timing, memory refresh and system interrupt -> should be FALSE always
SYSTEMREGS_2 is for memory config -> should be TRUE until HAL stops writing it. After HAL stops writing to
the register (only POST sets it), this flag should be FALSE.
SYSTEMREGS_3 is for VRAM control register -> should be TRUE always
**/
#define SYSTEMREGS_1 FALSE
#define SYSTEMREGS_2 TRUE
#define SYSTEMREGS_3 TRUE
/** This flag is to enable checking both "Powerized Graphics" and "display" string for device identifier.
If it's FALSE, only "Powerized Graphics" is checked. **/
#define CHECK_DISPLAY_STRING FALSE
/** This flag is to activate verification for GPIO_B 1MB VRAM work around bit.
We can turn this to FALSE after POST is responsible for setting the bit correctly. **/
#define VERIFY_DCC_1MB_BIT TRUE
#define STANDARD_DEBUG_PREFIX "Powerized" // All debug output is prefixed
#define DBGLVL_0 0
#define DBGLVL_1 1
#define DBGLVL_2 2
#define DBGLVL_3 3
#define DBGLVL_4 4
#define DBGLVL_5 5
#define DBGLVL_TR 6
#define DBGLVL_OUT 7
#include "dderror.h"
#include "devioctl.h"
#include "miniport.h"
#include "ntddvdeo.h"
#include "video.h"
#include "psidcc.h"
#include "psidisp.h"
#include "pcomm.h"
#include "psiinit.h"
#define DCC_NAME_1 L"Powerized Graphics"
#define DCC_NAME_LENGTH_1 36
#define DCC_NAME_2 L"display"
#define DCC_NAME_LENGTH_2 14
#if defined(ALLOC_PRAGMA)
#pragma alloc_text(PAGE,DriverEntry)
#pragma alloc_text(PAGE,DCCRegistryCallback)
#pragma alloc_text(PAGE,DCCFindAdapter)
#pragma alloc_text(PAGE,DCCGetDeviceDataCallback)
#pragma alloc_text(PAGE,DCCInitialize)
#pragma alloc_text(PAGE,DCCStartIO)
#pragma alloc_text(PAGE,DCCSetMode)
#pragma alloc_text(PAGE,DCCWrite)
#pragma alloc_text(PAGE,DCCRead)
#pragma alloc_text(PAGE,DCCWriteShort)
#pragma alloc_text(PAGE,BtWrite)
#pragma alloc_text(PAGE,BtRead)
#pragma alloc_text(PAGE,Bt445UpdateLUT
#endif
//
// Define device extension structure.
//
typedef struct _HW_DEVICE_EXTENSION {
PHYSICAL_ADDRESS PhysicalVRAMAddress;
PUCHAR VRAMAddress;
PUCHAR VRAMuserMappedAddress;
PUCHAR DCCAddress;
PUCHAR Bt445Address;
PUCHAR VRAMDetectRegAddress1;
PUCHAR VRAMDetectRegAddress2;
PUCHAR VRAMCtrlRegAddress;
PUCHAR MemBank7ConfigRegAddress;
PUCHAR VRAMTimingRegAddress;
PUCHAR MemRefreshRegAddress;
PULONG SystemInterruptRegAddress;
PUSHORT PCIDeviceIDRegisterAddress;
ULONG VRAMLength;
DCC_VRAM_WIDTH VRAMWidth;
USHORT FirstEntry;
USHORT LastEntry;
USHORT HorizontalResolution;
USHORT HorizontalDisplayTime;
USHORT HorizontalBackPorch;
USHORT HorizontalFrontPorch;
USHORT HorizontalSync;
USHORT HorizontalScreenSize;
USHORT VerticalResolution;
USHORT VerticalBackPorch;
USHORT VerticalFrontPorch;
USHORT VerticalSync;
USHORT VerticalScreenSize;
UCHAR UpdateColorMap;
DCC_MODE_LIST ModeNumber;
ULONG NumAvailableModes;
PSI_MODELS PSIModelID;
ULONG L1cacheEntry;
ULONG SetSize;
ULONG NumberOfSet;
USHORT VRAM1MBWorkAround;
USHORT AvoidConversion;
ULONG CPUKind;
USHORT DBAT_Mbit;
USHORT CacheFlushCTRL;
union {
VIDEO_CLUTDATA RgbData;
ULONG RgbLong;
} ColorMap[NUMBER_OF_COLORS];
} HW_DEVICE_EXTENSION, *PHW_DEVICE_EXTENSION;
//
// Function Prototypes
//
#if FULLCACHE
VOID
DCCInitializeCacheFlush(PVOID p, ULONG numcacheentry);
#endif
VP_STATUS
DCCFindAdapter(
PVOID HwDeviceExtension,
PVOID HwContext,
PWSTR ArgumentString,
PVIDEO_PORT_CONFIG_INFO ConfigInfo,
PUCHAR Again
);
BOOLEAN
DCCInitialize(
PVOID HwDeviceExtension
);
/***************** Interrupt is not used in this version **************************
BOOLEAN
DCCInterruptService (
PVOID HwDeviceExtension
);
***********************************************************************************/
BOOLEAN
DCCStartIO(
PVOID HwDeviceExtension,
PVIDEO_REQUEST_PACKET RequestPacket
);
//
// Define device driver procedure prototypes.
//
VP_STATUS
DCCGetDeviceDataCallback(
PVOID HwDeviceExtension,
PVOID Context,
VIDEO_DEVICE_DATA_TYPE DeviceDataType,
PVOID Identifier,
ULONG IdentifierLength,
PVOID ConfigurationData,
ULONG ConfigurationDataLength,
PVOID ComponentInformation,
ULONG ComponentInformationLength
);
VOID
DCCSetMode(
PHW_DEVICE_EXTENSION hwDeviceExtension
);
VOID
DCCWrite(
UCHAR Index,
UCHAR Data
);
UCHAR
DCCRead(
UCHAR Index
);
VOID
DCCWriteShort(
UCHAR Index,
USHORT Data
);
VOID
BtWrite(
UCHAR Index,
ULONG Offset,
UCHAR Data,
UCHAR Mask
);
UCHAR
BtRead(
UCHAR Index,
ULONG Offset
);
VOID
Bt445UpdateLUT(
PHW_DEVICE_EXTENSION hwDeviceExtension
);
// Register Base Address to be used for DCCWrite, DCCRead, DCCWriteShort, BtWrite, BtRead
static PUCHAR DCCRegisterBase;
static PUCHAR BtRegisterBase;
ULONG loadpvr();
ULONG loadbat(
ULONG rgnumber,
ULONG cpukind
);
VOID storebat(
ULONG rgnumber,
ULONG value,
ULONG cpukind
);
#if INVESTIGATE || DBG
VOID
DbgBreakPoint(
VOID
);
#endif
#if INVESTIGATE
static LARGE_INTEGER StartTime, CurrentTime, Frequency;
static ULONG tickperms, highpartms, work;
LARGE_INTEGER KeQueryPerformanceCounter(
PLARGE_INTEGER PerformanceFrequency
);
VOID
DisplayBat(ULONG cpu
)
{
ULONG i, hi, low;
ULONG bepi, bl, wbit, ibit, mbit, gbit, pp, brpn, vs, vp;
if(cpu == 0) { // 601
for(i=0; i<4; ++i) {
hi = loadbat(i*2,0);
low = loadbat(i*2+1,0);
bepi = hi>>17;
bl = low&0x3f;
vs = (hi&0x08)>>3;
vp = (hi&0x04)>>2;
brpn = low>>17;
wbit = (hi&0x40)>>6;
ibit = (hi&0x20)>>5;
mbit = (hi&0x10)>>4;
gbit = (low&0x40)>>6;
pp = (hi&0x03);
VideoDebugPrint((DBGLVL_1, "%s: BAT %d = %08x:%08x BEPI:0x%08x (0x%08x), BL:%x, Vs:%d, Vp:%d\n",
STANDARD_DEBUG_PREFIX, i, hi, low, bepi, bepi<<17, bl, vs, vp));
VideoDebugPrint((DBGLVL_1, "%s: BRPN:0x%08x (0x%08x), WIM:%d%d%d, PP:%x, V:%d\n",
STANDARD_DEBUG_PREFIX, brpn, brpn<<17, wbit, ibit, mbit, pp, gbit));
}
} else { // 603 or later
for(i=0; i<4; ++i) {
hi = loadbat(i*2, 1);
low = loadbat(i*2+1, 1);
bepi = hi>>17;
bl = (hi&0x1ffc)>>2;
vs = (hi&0x02)>>1;
vp = (hi&0x01);
brpn = low>>17;
wbit = (low&0x40)>>6;
ibit = (low&0x20)>>5;
mbit = (low&0x10)>>4;
gbit = (low&0x08)>>3;
pp = (low&0x03);
VideoDebugPrint((DBGLVL_1, "%s: DBAT %d = %08x:%08x BEPI:0x%08x (0x%08x), BL:%x, Vs:%d, Vp:%d\n",
STANDARD_DEBUG_PREFIX, i, hi, low, bepi, bepi<<17, bl, vs, vp));
VideoDebugPrint((DBGLVL_1, "%s: BRPN:0x%08x (0x%08x), WIMG:%d%d%d%d, PP:%x\n",
STANDARD_DEBUG_PREFIX, brpn, brpn<<17, wbit, ibit, mbit, gbit, pp));
}
}
}
#endif
#if DBG
BOOLEAN HWDevExtDisplay = FALSE;
VOID
DisplayHWDevExt(
PHW_DEVICE_EXTENSION hwDevExt
)
{
ULONG i;
if(! HWDevExtDisplay)
return;
HWDevExtDisplay = FALSE;
VideoPortDebugPrint(DBGLVL_1, "PhysicalVRAMAddress = 0x%08x - 0x%08x\n",
hwDevExt->PhysicalVRAMAddress.HighPart, hwDevExt->PhysicalVRAMAddress.LowPart);
VideoPortDebugPrint(DBGLVL_1, "VRAMAddress = 0x%08x\n", hwDevExt->VRAMAddress);
VideoPortDebugPrint(DBGLVL_1, "DCCAddress = 0x%08x\n", hwDevExt->DCCAddress);
VideoPortDebugPrint(DBGLVL_1, "Bt445Address = 0x%08x\n", hwDevExt->Bt445Address);
VideoPortDebugPrint(DBGLVL_1, "VRAMDetectRegAddress1 = 0x%08x\n",
hwDevExt->VRAMDetectRegAddress1);
VideoPortDebugPrint(DBGLVL_1, "VRAMDetectRegAddress2 = 0x%08x\n",
hwDevExt->VRAMDetectRegAddress2);
#if SYSTEMREGS_1
VideoPortDebugPrint(DBGLVL_1, "VRAMTimingRegAddress = 0x%08x\n",
hwDevExt->VRAMTimingRegAddress);
VideoPortDebugPrint(DBGLVL_1, "MemRefreshRegAddress = 0x%08x\n",
hwDevExt->MemRefreshRegAddress);
VideoPortDebugPrint(DBGLVL_1, "SystemInterruptRegAddress = 0x%08x\n",
hwDevExt->SystemInterruptRegAddress);
#endif
#if SYSTEMREGS_3
VideoPortDebugPrint(DBGLVL_1, "VRAMCtrlRegAddress = 0x%08x\n", hwDevExt->VRAMCtrlRegAddress);
#endif
#if SYSTEMREGS_2
VideoPortDebugPrint(DBGLVL_1, "MemBank7ConfigRegAddress = 0x%08x\n",
hwDevExt->MemBank7ConfigRegAddress);
#endif
VideoPortDebugPrint(DBGLVL_1, "PCIDeviceIDRegister = 0x%08x\n",
hwDevExt->PCIDeviceIDRegisterAddress);
VideoPortDebugPrint(DBGLVL_1, "VRAMLength = 0x%x (%d)\n",
hwDevExt->VRAMLength, hwDevExt->VRAMLength);
VideoPortDebugPrint(DBGLVL_1, "VRAMWidth = %d\n", hwDevExt->VRAMWidth);
VideoPortDebugPrint(DBGLVL_1, "Entry = %d - %d\n", hwDevExt->FirstEntry, hwDevExt->LastEntry);
VideoPortDebugPrint(DBGLVL_1, "Resolution = %d X %d\n",
hwDevExt->HorizontalResolution, hwDevExt->VerticalResolution);
VideoPortDebugPrint(DBGLVL_1, "Screen Size = %d X %d\n",
hwDevExt->HorizontalScreenSize, hwDevExt->VerticalScreenSize);
VideoPortDebugPrint(DBGLVL_1, "Horizontal Display:%d, BackPorch:%d, FrontPorch:%d, Sync:%d\n",
hwDevExt->HorizontalDisplayTime, hwDevExt->HorizontalBackPorch,
hwDevExt->HorizontalFrontPorch, hwDevExt->HorizontalSync);
VideoPortDebugPrint(DBGLVL_1, "Vertical BackPorch:%d, FrontPorch:%d, Sync:%d\n",
hwDevExt->VerticalBackPorch, hwDevExt->VerticalFrontPorch,
hwDevExt->VerticalSync);
VideoPortDebugPrint(DBGLVL_1, "Update Color Map = %d\n", hwDevExt->UpdateColorMap);
VideoPortDebugPrint(DBGLVL_1, "Mode Number = %d\n", hwDevExt->ModeNumber);
VideoPortDebugPrint(DBGLVL_1, "Num Avail Mode = %d\n", hwDevExt->NumAvailableModes);
VideoPortDebugPrint(DBGLVL_1, "PSI Model ID = %d\n", hwDevExt->PSIModelID);
VideoPortDebugPrint(DBGLVL_1, "L1 cache entry = %d\n", hwDevExt->L1cacheEntry);
VideoPortDebugPrint(DBGLVL_1, "Set size = %d\n", hwDevExt->SetSize);
VideoPortDebugPrint(DBGLVL_1, "Number of set = %d\n", hwDevExt->NumberOfSet);
VideoPortDebugPrint(DBGLVL_1, "1MB VRAM work around = %d\n", hwDevExt->VRAM1MBWorkAround);
VideoPortDebugPrint(DBGLVL_1, "Avoid conversion = %d\n", hwDevExt->AvoidConversion);
VideoPortDebugPrint(DBGLVL_1, "DBAT M bit = %x\n", hwDevExt->DBAT_Mbit);
VideoPortDebugPrint(DBGLVL_1, "Cache flush control = %d\n", hwDevExt->CacheFlushCTRL);
VideoPortDebugPrint(DBGLVL_1, "CPU kind = %d\n", hwDevExt->CPUKind);
for(i=0; i<NUMBER_OF_COLORS; ++i) {
VideoPortDebugPrint(DBGLVL_1, "%03d:%03d,%03d,%03d", i, hwDevExt->ColorMap[i].RgbData.Red,
hwDevExt->ColorMap[i].RgbData.Green, hwDevExt->ColorMap[i].RgbData.Blue);
if(i%4 != 3)
VideoPortDebugPrint(DBGLVL_1, " ");
else
VideoPortDebugPrint(DBGLVL_1, "\n");
}
}
#endif
ULONG
DriverEntry (
PVOID Context1,
PVOID Context2
)
/*++
Routine Description:
Installable driver initialization entry point.
This entry point is called directly by the I/O system.
Arguments:
Context1 - First context value passed by the operating system. This is
the value with which the miniport driver calls VideoPortInitialize().
Context2 - Second context value passed by the operating system. This is
the value with which the miniport driver calls VideoPortInitialize().
Return Value:
Status from VideoPortInitialize()
--*/
{
VIDEO_HW_INITIALIZATION_DATA hwInitData;
VP_STATUS status;
VideoDebugPrint((DBGLVL_TR, "%s: === PSIDISP.SYS: Entering DCCDriverEntry ===\n", STANDARD_DEBUG_PREFIX));
#if INVESTIGATE
StartTime = KeQueryPerformanceCounter(&Frequency); // Record start time
if(Frequency.HighPart != 0) {
VideoDebugPrint((DBGLVL_0, "%s: #### Timer Frequency Too High to measure ####\n", STANDARD_DEBUG_PREFIX));
tickperms = 1;
} else {
// tickperms = Frequency.LowPart/10000; // 0.1 milli second unit
tickperms = Frequency.LowPart/100000; // 0.01 milli second unit
}
highpartms = (0x80000000 / tickperms) * 2; // number of units for 1 high part
#endif
//
// Zero out structure.
//
VideoPortZeroMemory(&hwInitData, sizeof(VIDEO_HW_INITIALIZATION_DATA));
//
// Specify sizes of structure and extension.
//
hwInitData.HwInitDataSize = sizeof(VIDEO_HW_INITIALIZATION_DATA);
//
// Set entry points.
//
hwInitData.HwFindAdapter = DCCFindAdapter;
hwInitData.HwInitialize = DCCInitialize;
// hwInitData.HwInterrupt = DCCInterruptService;
hwInitData.HwInterrupt = NULL; // Don't use interrupt for this release
hwInitData.HwStartIO = DCCStartIO;
//
// Determine the size we require for the device extension.
//
hwInitData.HwDeviceExtensionSize = sizeof(HW_DEVICE_EXTENSION);
//
// Always start with parameters for device0 in this case.
//
// hwInitData.StartingDeviceNumber = 0;
//
// This device only supports the internal bus type. So return the status
// value directly to the operating system.
//
hwInitData.AdapterInterfaceType = Isa;
status = VideoPortInitialize(Context1,
Context2,
&hwInitData,
NULL);
VideoDebugPrint((DBGLVL_TR, "%s: ... PSIDISP.SYS: Exiting DCCDriverEntry ...\n", STANDARD_DEBUG_PREFIX));
return (status);
} // end DriverEntry()
VP_STATUS
DCCRegistryCallback(
PVOID HwDeviceExtension,
PVOID Context,
PWSTR ValueName,
PVOID ValueData,
ULONG ValueLength
)
/*++
Routine Description:
This routine determines if the 1MB VRAM WORK AROUND was requested via
the registry.
Arguments:
HwDeviceExtension - Supplies a pointer to the miniport's device extension.
Context - Context value passed to the get registry paramters routine.
ValueName - Name of the value requested.
ValueData - Pointer to the requested data.
ValueLength - Length of the requested data.
Return Value:
returns NO_ERROR if the paramter was TRUE.
returns ERROR_INVALID_PARAMETER otherwise.
--*/
{
if (ValueLength && *((PULONG)ValueData)) {
return NO_ERROR;
} else {
return ERROR_INVALID_PARAMETER;
}
}
VP_STATUS
DCCFindAdapter(
PVOID HwDeviceExtension,
PVOID HwContext,
PWSTR ArgumentString,
PVIDEO_PORT_CONFIG_INFO ConfigInfo,
PUCHAR Again
)
/*++
Routine Description:
This routine is called to determine if the adapter for this driver
is present in the system.
If it is present, the function fills out some information describing
the adapter.
Arguments:
HwDeviceExtension - Supplies the miniport driver's adapter storage. This
storage is initialized to zero before this call.
HwContext - Supplies the context value which was passed to
VideoPortInitialize().
ArgumentString - Supplies a NULL terminated ASCII string. This string
originates from the user.
ConfigInfo - Returns the configuration information structure which is
filled by the miniport driver. This structure is initialized with
any known configuration information (such as SystemIoBusNumber) by
the port driver. Where possible, drivers should have one set of
defaults which do not require any supplied configuration information.
Again - Indicates if the miniport driver wants the port driver to call
its VIDEO_HW_FIND_ADAPTER function again with a new device extension
and the same config info. This is used by the miniport drivers which
can search for several adapters on a bus.
Return Value:
This routine must return:
NO_ERROR - Indicates a host adapter was found and the
configuration information was successfully determined.
ERROR_INVALID_PARAMETER - Indicates an adapter was found but there was an
error obtaining the configuration information. If possible an error
should be logged.
ERROR_DEV_NOT_EXIST - Indicates no host adapter was found for the
supplied configuration information.
--*/
{
UCHAR VramDetect01, VramDetect23;
USHORT Pciid;
UCHAR RamDacId;
PHW_DEVICE_EXTENSION hwDeviceExtension = HwDeviceExtension;
VP_STATUS status;
VideoDebugPrint((DBGLVL_TR, "%s: === PSIDISP.SYS: Entering FindAdaptor ===\n", STANDARD_DEBUG_PREFIX));
VideoDebugPrint((DBGLVL_1, "%s: Argument String = %S\n", STANDARD_DEBUG_PREFIX, ArgumentString));
VideoDebugPrint((DBGLVL_1, "%s: Length = %d\n", STANDARD_DEBUG_PREFIX, ConfigInfo->Length));
VideoDebugPrint((DBGLVL_1, "%s: SystemIOBusNumber = %d\n", STANDARD_DEBUG_PREFIX, ConfigInfo->SystemIoBusNumber));
VideoDebugPrint((DBGLVL_1, "%s: AdaptorInterfaceType = %d\n", STANDARD_DEBUG_PREFIX, ConfigInfo->AdapterInterfaceType));
VideoDebugPrint((DBGLVL_1, "%s: InterruptMode = %d\n", STANDARD_DEBUG_PREFIX, ConfigInfo->InterruptMode));
//
// Make sure the size of the structure is at least as large as what we
// are expecting (check version of the config info structure).
//
if (ConfigInfo->Length < sizeof(VIDEO_PORT_CONFIG_INFO)) {
VideoDebugPrint((DBGLVL_0, "%s: ### FindAdaptor: Config Length Error ###\n", STANDARD_DEBUG_PREFIX));
return ERROR_INVALID_PARAMETER;
}
if (VideoPortGetDeviceData(hwDeviceExtension,
VpControllerData,
&DCCGetDeviceDataCallback,
ConfigInfo)) {
VideoDebugPrint((DBGLVL_0, "%s: FindAdaptor: VideoPort get controller info failed\n", STANDARD_DEBUG_PREFIX));
return ERROR_DEV_NOT_EXIST;
}
VideoDebugPrint((DBGLVL_1, "%s: FindAdaptor: VideoPort get controller info succeeded\n", STANDARD_DEBUG_PREFIX));
/**********
if (VideoPortGetDeviceData(hwDeviceExtension,
VpMonitorData,
&DCCGetDeviceDataCallback,
NULL)) {
VideoDebugPrint((DBGLVL_0, "%s: FindAdaptor: VideoPort get monitor info failed\n", STANDARD_DEBUG_PREFIX));
return ERROR_INVALID_PARAMETER;
}
**********/
//
// Check to see if there is a hardware resource conflict.
//
status = VideoPortVerifyAccessRanges(HwDeviceExtension,
NUM_ACCESS_RANGE_CHECK,
accessRanges);
if (status != NO_ERROR) {
VideoDebugPrint((DBGLVL_0, "%s: ### Veryfy Access range error ###\n", STANDARD_DEBUG_PREFIX));
return status;
}
//
// Map the DCC registers into the system virtual address space.
//
if ( (hwDeviceExtension->DCCAddress =
VideoPortGetDeviceBase(hwDeviceExtension,
accessRanges[1].RangeStart, // DCC
accessRanges[1].RangeLength,
accessRanges[1].RangeInIoSpace)) == NULL) {
VideoDebugPrint((DBGLVL_0, "%s: ### VideoPortGetDeviceBase 1 error ###\n", STANDARD_DEBUG_PREFIX));
return ERROR_INVALID_PARAMETER;
}
VideoDebugPrint((DBGLVL_1, "%s: Base DCC: %08x:%08x (%x) %d -> %x\n", STANDARD_DEBUG_PREFIX,
accessRanges[1].RangeStart.HighPart, accessRanges[1].RangeStart.LowPart,
accessRanges[1].RangeLength, accessRanges[1].RangeInIoSpace,
hwDeviceExtension->DCCAddress));
//
// Map the Bt445 registers into the system virtual address space.
//
if ( (hwDeviceExtension->Bt445Address =
VideoPortGetDeviceBase(hwDeviceExtension,
accessRanges[2].RangeStart, // Bt445
accessRanges[2].RangeLength,
accessRanges[2].RangeInIoSpace)) == NULL) {
VideoDebugPrint((DBGLVL_0, "%s: ### VideoPortGetDeviceBase 2 error ###\n", STANDARD_DEBUG_PREFIX));
return ERROR_INVALID_PARAMETER;
}
VideoDebugPrint((DBGLVL_1, "%s: Base Bt445: %08x:%08x (%x) %d -> %x\n", STANDARD_DEBUG_PREFIX,
accessRanges[2].RangeStart.HighPart, accessRanges[2].RangeStart.LowPart,
accessRanges[2].RangeLength, accessRanges[2].RangeInIoSpace,
hwDeviceExtension->Bt445Address));
//
// Map the VRAM detect registers into the system virtual address space.
//
if ( (hwDeviceExtension->VRAMDetectRegAddress1 =
VideoPortGetDeviceBase(hwDeviceExtension,
accessRanges[3].RangeStart, // VRAM detect registers
accessRanges[3].RangeLength,
accessRanges[3].RangeInIoSpace)) == NULL) {
VideoDebugPrint((DBGLVL_0, "%s: ### VideoPortGetDeviceBase 3 error ###\n", STANDARD_DEBUG_PREFIX));
return ERROR_INVALID_PARAMETER;
}
VideoDebugPrint((DBGLVL_1, "%s: Base VRAMDetectRegAddress1: %08x:%08x (%x) %d -> %x\n", STANDARD_DEBUG_PREFIX,
accessRanges[3].RangeStart.HighPart, accessRanges[3].RangeStart.LowPart,
accessRanges[3].RangeLength, accessRanges[3].RangeInIoSpace,
hwDeviceExtension->VRAMDetectRegAddress1));
if ( (hwDeviceExtension->VRAMDetectRegAddress2 =
VideoPortGetDeviceBase(hwDeviceExtension,
accessRanges[4].RangeStart, // VRAM detect registers
accessRanges[4].RangeLength,
accessRanges[4].RangeInIoSpace)) == NULL) {
VideoDebugPrint((DBGLVL_0, "%s: ### VideoPortGetDeviceBase 4 error ###\n", STANDARD_DEBUG_PREFIX));
return ERROR_INVALID_PARAMETER;
}
VideoDebugPrint((DBGLVL_1, "%s: Base VRAMDetectRegAddress2: %08x:%08x (%x) %d -> %x\n", STANDARD_DEBUG_PREFIX,
accessRanges[4].RangeStart.HighPart, accessRanges[4].RangeStart.LowPart,
accessRanges[4].RangeLength, accessRanges[4].RangeInIoSpace,
hwDeviceExtension->VRAMDetectRegAddress2));
#if SYSTEMREGS_3
//
// Map the VRAM control registers into the system virtual address space.
//
if ( (hwDeviceExtension->VRAMCtrlRegAddress =
VideoPortGetDeviceBase(hwDeviceExtension,
accessRanges[5].RangeStart, // VRAM control registers
accessRanges[5].RangeLength,
accessRanges[5].RangeInIoSpace)) == NULL) {
VideoDebugPrint((DBGLVL_0, "%s: ### VideoPortGetDeviceBase 5 error ###\n", STANDARD_DEBUG_PREFIX));
return ERROR_INVALID_PARAMETER;
}
VideoDebugPrint((DBGLVL_1, "%s: Base VRAMCtrlRegAddress: %08x:%08x (%x) %d -> %x\n", STANDARD_DEBUG_PREFIX,
accessRanges[5].RangeStart.HighPart, accessRanges[5].RangeStart.LowPart,
accessRanges[5].RangeLength, accessRanges[5].RangeInIoSpace,
hwDeviceExtension->VRAMCtrlRegAddress));
#endif
#if SYSTEMREGS_2
//
// Map the Memory Bank 6 & 7 config registers into the system virtual address space.
//
if ( (hwDeviceExtension->MemBank7ConfigRegAddress =
VideoPortGetDeviceBase(hwDeviceExtension,
accessRanges[6].RangeStart, // Mem6 config registers
accessRanges[6].RangeLength,
accessRanges[6].RangeInIoSpace)) == NULL) {
VideoDebugPrint((DBGLVL_0, "%s: ### VideoPortGetDeviceBase 6 error ###\n", STANDARD_DEBUG_PREFIX));
return ERROR_INVALID_PARAMETER;
}
VideoDebugPrint((DBGLVL_1, "%s: Base MemBank7ConfigRegAddress: %08x:%08x (%x) %d -> %x\n", STANDARD_DEBUG_PREFIX,
accessRanges[6].RangeStart.HighPart, accessRanges[6].RangeStart.LowPart,
accessRanges[6].RangeLength, accessRanges[6].RangeInIoSpace,
hwDeviceExtension->MemBank7ConfigRegAddress));
#endif
#if SYSTEMREGS_1
//
// Map the VRAM timing registers into the system virtual address space.
//
if ( (hwDeviceExtension->VRAMTimingRegAddress =
VideoPortGetDeviceBase(hwDeviceExtension,
accessRanges[7].RangeStart, // VRAM timing registers
accessRanges[7].RangeLength,
accessRanges[7].RangeInIoSpace)) == NULL) {
VideoDebugPrint((DBGLVL_0, "%s: ### VideoPortGetDeviceBase 7 error ###\n", STANDARD_DEBUG_PREFIX));
return ERROR_INVALID_PARAMETER;
}
VideoDebugPrint((DBGLVL_1, "%s: Base VRAMTimingRegAddress: %08x:%08x (%x) %d -> %x\n", STANDARD_DEBUG_PREFIX,
accessRanges[7].RangeStart.HighPart, accessRanges[7].RangeStart.LowPart,
accessRanges[7].RangeLength, accessRanges[7].RangeInIoSpace,
hwDeviceExtension->VRAMTimingRegAddress));
//
// Map the memory refresh interval register into the system virtual address space.
//
if ( (hwDeviceExtension->MemRefreshRegAddress =
VideoPortGetDeviceBase(hwDeviceExtension,
accessRanges[8].RangeStart, // Mem refresh registers
accessRanges[8].RangeLength,
accessRanges[8].RangeInIoSpace)) == NULL) {
VideoDebugPrint((DBGLVL_0, "%s: ### VideoPortGetDeviceBase 8 error ###\n", STANDARD_DEBUG_PREFIX));
return ERROR_INVALID_PARAMETER;
}
VideoDebugPrint((DBGLVL_1, "%s: Base MemRefreshRegAddress: %08x:%08x (%x) %d -> %x\n", STANDARD_DEBUG_PREFIX,
accessRanges[8].RangeStart.HighPart, accessRanges[8].RangeStart.LowPart,
accessRanges[8].RangeLength, accessRanges[8].RangeInIoSpace,
hwDeviceExtension->MemRefreshRegAddress));
//
// Map interrupt register into the system virtual address space.
//
if ( (hwDeviceExtension->SystemInterruptRegAddress =
VideoPortGetDeviceBase(hwDeviceExtension,
accessRanges[9].RangeStart, // System interrupt register
accessRanges[9].RangeLength,
accessRanges[9].RangeInIoSpace)) == NULL) {
VideoDebugPrint((DBGLVL_0, "%s: ### VideoPortGetDeviceBase 9 error ###\n", STANDARD_DEBUG_PREFIX));
return ERROR_INVALID_PARAMETER;
}
VideoDebugPrint((DBGLVL_1, "%s: Base SystemInterrupt: %08x:%08x (%x) %d -> %x\n", STANDARD_DEBUG_PREFIX,
accessRanges[9].RangeStart.HighPart, accessRanges[9].RangeStart.LowPart,
accessRanges[9].RangeLength, accessRanges[9].RangeInIoSpace,
hwDeviceExtension->SystemInterruptRegAddress));
#endif // SYSTEMREGS_1
//
// Map the PCI Device ID registers into the system virtual address space.
//
if ( (hwDeviceExtension->PCIDeviceIDRegisterAddress =
VideoPortGetDeviceBase(hwDeviceExtension,
accessRanges[10].RangeStart, // PCI ID register
accessRanges[10].RangeLength,
accessRanges[10].RangeInIoSpace)) == NULL) {
VideoDebugPrint((DBGLVL_0, "%s: ### VideoPortGetDeviceBase 10 error ###\n", STANDARD_DEBUG_PREFIX));
return ERROR_INVALID_PARAMETER;
}
VideoDebugPrint((DBGLVL_1, "%s: Base PCIDeviceIDRegisterAddress: %08x:%08x (%x) %d -> %x\n", STANDARD_DEBUG_PREFIX,
accessRanges[10].RangeStart.HighPart, accessRanges[10].RangeStart.LowPart,
accessRanges[10].RangeLength, accessRanges[10].RangeInIoSpace,
hwDeviceExtension->PCIDeviceIDRegisterAddress));
// Set register base variables
DCCRegisterBase = hwDeviceExtension->DCCAddress;
BtRegisterBase = hwDeviceExtension->Bt445Address;
//
// Clear out the Emulator entries and the state size since this driver
// does not support them.
//
ConfigInfo->NumEmulatorAccessEntries = 0;
ConfigInfo->EmulatorAccessEntries = NULL;
ConfigInfo->EmulatorAccessEntriesContext = 0;
ConfigInfo->VdmPhysicalVideoMemoryAddress.LowPart = 0x00000000;
ConfigInfo->VdmPhysicalVideoMemoryAddress.HighPart = 0x00000000;
ConfigInfo->VdmPhysicalVideoMemoryLength = 0x00000000;
ConfigInfo->HardwareStateSize = 0;
//
// Initialize the color map update information.
//
hwDeviceExtension->FirstEntry = 0;
hwDeviceExtension->LastEntry = NUMBER_OF_COLORS-1;
hwDeviceExtension->UpdateColorMap = 0;
//
// Determine the model type
//
Pciid = VideoPortReadPortUshort(hwDeviceExtension->PCIDeviceIDRegisterAddress + ADDRESS_MUNGE_FOR_SHORT);
if(Pciid == PCI_ID_FOR_POWER_PRO)
hwDeviceExtension->PSIModelID = POWER_PRO;
else
hwDeviceExtension->PSIModelID = POWER_TOP;
VideoDebugPrint((DBGLVL_0, "%s: PCI ID register = 0x%04x - %s\n", STANDARD_DEBUG_PREFIX, Pciid, (Pciid == PCI_ID_FOR_POWER_TOP) ? "MX" : "ES"));
//
// Read VRAM Detect registers
//
VramDetect01 = VideoPortReadPortUchar(hwDeviceExtension->VRAMDetectRegAddress1);
VideoDebugPrint((DBGLVL_1, "%s: VRAM01=0x%02x\n", STANDARD_DEBUG_PREFIX, VramDetect01));
if(hwDeviceExtension->PSIModelID == POWER_TOP) {
if((VramDetect01 & 0xf0) == 0xf0 || (VramDetect01 & 0x0f) == 0x0f) { // No standard VRAM existing -> return error
VideoDebugPrint((DBGLVL_0, "%s: ### Exiting DCCFindAdapter due to less than 2MB VRAM error ###\n", STANDARD_DEBUG_PREFIX));
return(ERROR_DEV_NOT_EXIST);
} else {
VramDetect23 = VideoPortReadPortUchar(hwDeviceExtension->VRAMDetectRegAddress2);
VideoDebugPrint((DBGLVL_1, "%s: VRAM23=0x%02x\n", STANDARD_DEBUG_PREFIX, VramDetect23));
if((VramDetect23 & 0xf0) == 0xf0 || (VramDetect23 & 0x0f) == 0x0f) { // No VRAM expansion -> 2MB
hwDeviceExtension->VRAMLength = MEM2MB;
hwDeviceExtension->VRAMWidth = VRAM_64BIT;
} else { // Additional VRAM installed -> 4MB
hwDeviceExtension->VRAMLength = MEM4MB;
hwDeviceExtension->VRAMWidth = VRAM_128BIT;
}
}
} else { // Power Pro
if((VramDetect01 & 0x0f) == 0x0f) { // No standard VRAM existing -> return error
VideoDebugPrint((DBGLVL_0, "%s: ### Exiting DCCFindAdapter due to no VRAM error ...\n", STANDARD_DEBUG_PREFIX));
return(ERROR_DEV_NOT_EXIST);
} else {
if((VramDetect01 & 0xf0) == 0xf0) { // No VRAM expansion -> 1MB
hwDeviceExtension->VRAMLength = MEM1MB;
hwDeviceExtension->VRAMWidth = VRAM_32BIT;
} else { // Additional VRAM installed -> 2MB
hwDeviceExtension->VRAMLength = MEM2MB;
hwDeviceExtension->VRAMWidth = VRAM_64BIT;
}
}
}
//
// Save in device extension
//
hwDeviceExtension->PhysicalVRAMAddress.HighPart = accessRanges[0].RangeStart.HighPart;
hwDeviceExtension->PhysicalVRAMAddress.LowPart = accessRanges[0].RangeStart.LowPart;
//
// Map the VRAM into the system virtual address space.
//
if ( (hwDeviceExtension->VRAMAddress =
VideoPortGetDeviceBase(hwDeviceExtension,
accessRanges[0].RangeStart, // VRAM
hwDeviceExtension->VRAMLength,
accessRanges[0].RangeInIoSpace)) == NULL) {
VideoDebugPrint((DBGLVL_0, "%s: ### VideoPortGetDeviceBase 0 error ###\n", STANDARD_DEBUG_PREFIX));
return ERROR_INVALID_PARAMETER;
}
VideoDebugPrint((DBGLVL_1, "%s: Base VRAM: %08x:%08x (%x) %d -> %x\n", STANDARD_DEBUG_PREFIX,
accessRanges[0].RangeStart.HighPart, accessRanges[0].RangeStart.LowPart,
accessRanges[0].RangeLength, accessRanges[0].RangeInIoSpace,
hwDeviceExtension->VRAMAddress));
hwDeviceExtension->VRAM1MBWorkAround = 0;
if(hwDeviceExtension->PSIModelID == POWER_PRO) {
if (NO_ERROR == VideoPortGetRegistryParameters(hwDeviceExtension,
L"WorkAroundFor1MB_VRAM",
FALSE,
DCCRegistryCallback,
NULL)) {
VideoDebugPrint((DBGLVL_0, "%s: WorkAroundFor1MB_VRAM registry = TRUE\n", STANDARD_DEBUG_PREFIX));
hwDeviceExtension->VRAM1MBWorkAround = 1;
}
}
hwDeviceExtension->CacheFlushCTRL = 0;
if(hwDeviceExtension->PSIModelID == POWER_TOP) {
if (NO_ERROR == VideoPortGetRegistryParameters(hwDeviceExtension,
L"CacheFlushControl",
FALSE,
DCCRegistryCallback,
NULL)) {
VideoDebugPrint((DBGLVL_0, "%s: CacheFlushControl registry = TRUE\n", STANDARD_DEBUG_PREFIX));
hwDeviceExtension->CacheFlushCTRL = 1;
}
}
hwDeviceExtension->AvoidConversion = 0;
if (NO_ERROR == VideoPortGetRegistryParameters(hwDeviceExtension,
L"AvoidConversion",
FALSE,
DCCRegistryCallback,
NULL)) {
VideoDebugPrint((DBGLVL_0, "%s: AvoidConversion registry = TRUE\n", STANDARD_DEBUG_PREFIX));
hwDeviceExtension->AvoidConversion = 1;
}
VideoPortSetRegistryParameters(hwDeviceExtension,
L"HardwareInformation.ChipType",
L"Powerized Graphics",
sizeof(L"Powerized Graphics"));
if((RamDacId = BtRead(BT445_GROUP0_ID_INDEX, BT445_GROUP0_REG_OFFSET)) == BT445_ID) {
VideoPortSetRegistryParameters(hwDeviceExtension,
L"HardwareInformation.DacType",
L"Brooktree Bt445",
sizeof(L"Brooktree Bt445"));
} else {
VideoDebugPrint((DBGLVL_0, "%s: RAMDAC ID = %02x\n", STANDARD_DEBUG_PREFIX, RamDacId));
VideoPortSetRegistryParameters(hwDeviceExtension,
L"HardwareInformation.DacType",
L"Unknown",
sizeof(L"Unknown"));
}
VideoPortSetRegistryParameters(hwDeviceExtension,
L"HardwareInformation.MemorySize",
&hwDeviceExtension->VRAMLength,
sizeof(ULONG));
VideoPortSetRegistryParameters(hwDeviceExtension,
L"HardwareInformation.AdapterString",
L"Powerized Motherboard",
sizeof(L"Powerized Motherboard"));
//
// Indicate we do not wish to be called over
//
*Again = 0;
//
// Indicate a successful completion status.
//
VideoDebugPrint((DBGLVL_TR, "%s: ... PSIDISP.SYS: Exiting FindAdaptor ...\n", STANDARD_DEBUG_PREFIX));
return NO_ERROR;
} // end DCCFindAdapter()
VP_STATUS
DCCGetDeviceDataCallback(
PVOID HwDeviceExtension,
PVOID Context,
VIDEO_DEVICE_DATA_TYPE DeviceDataType,
PVOID Identifier,
ULONG IdentifierLength,
PVOID ConfigurationData,
ULONG ConfigurationDataLength,
PVOID ComponentInformation,
ULONG ComponentInformationLength
)
/*++
Routine Description:
Callback routine for the VideoPortGetDeviceData function.
Arguments:
HwDeviceExtension - Pointer to the miniport drivers device extension.
Context - Context value passed to the VideoPortGetDeviceData function.
DeviceDataType - The type of data that was requested in
VideoPortGetDeviceData.
Identifier - Pointer to a string that contains the name of the device,
as setup by the ROM or ntdetect.
IdentifierLength - Length of the Identifier string.
ConfigurationData - Pointer to the configuration data for the device or
BUS.
ConfigurationDataLength - Length of the data in the configurationData
field.
ComponentInformation - Undefined.
ComponentInformationLength - Undefined.
Return Value:
Returns NO_ERROR if the function completed properly.
Returns ERROR_DEV_NOT_EXIST if we did not find the device.
Returns ERROR_INVALID_PARAMETER otherwise.
--*/
{
PHW_DEVICE_EXTENSION hwDeviceExtension = HwDeviceExtension;
PVIDEO_PORT_CONFIG_INFO ConfigInfo = Context;
PWCHAR identifier = Identifier;
PDCC_CONFIGURATION_DATA DCCConfigData = ConfigurationData;
PMONITOR_CONFIG_DATA monitorConfigData = ConfigurationData;
switch (DeviceDataType) {
case VpControllerData:
//
// BUGBUG because we had a RESOURCE LIST header at the top.
// + 8 should be the offset of the paertial resource descriptor
// in a full resource descriptor.
//
DCCConfigData = (PDCC_CONFIGURATION_DATA)(((PUCHAR)DCCConfigData) + 8);
VideoDebugPrint((DBGLVL_1, "%s: DCCCallBack: getting controller information\n", STANDARD_DEBUG_PREFIX));
VideoDebugPrint((DBGLVL_1, "%s: Version = %d, Revision=%d\n", STANDARD_DEBUG_PREFIX,
DCCConfigData->Version, DCCConfigData->Revision));
VideoDebugPrint((DBGLVL_1, "%s: Irql = %d, Vector=%d\n", STANDARD_DEBUG_PREFIX,
DCCConfigData->Irql, DCCConfigData->Vector));
VideoDebugPrint((DBGLVL_1, "%s: Control Base = 0x%08x\n", STANDARD_DEBUG_PREFIX, DCCConfigData->ControlBase));
VideoDebugPrint((DBGLVL_1, "%s: Control Size = 0x%08x\n", STANDARD_DEBUG_PREFIX, DCCConfigData->ControlSize));
VideoDebugPrint((DBGLVL_1, "%s: Cursor Base = 0x%08x\n", STANDARD_DEBUG_PREFIX, DCCConfigData->CursorBase));
VideoDebugPrint((DBGLVL_1, "%s: Cursor Size = 0x%08x\n", STANDARD_DEBUG_PREFIX, DCCConfigData->CursorSize));
VideoDebugPrint((DBGLVL_1, "%s: Frame Base = 0x%08x\n", STANDARD_DEBUG_PREFIX, DCCConfigData->FrameBase));
VideoDebugPrint((DBGLVL_1, "%s: Frame Size = 0x%08x\n", STANDARD_DEBUG_PREFIX, DCCConfigData->FrameSize));
VideoDebugPrint((DBGLVL_1, "%s: Identifier = %S\n", STANDARD_DEBUG_PREFIX, identifier));
//
// Compare the name to what is should be. If it is wrong, then return
// an error and initialization will fail.
// What is the right way of doing this??
//
if(identifier == NULL) {
VideoDebugPrint((DBGLVL_0, "%s: CallBack: Identifier is NULL\n", STANDARD_DEBUG_PREFIX));
return ERROR_DEV_NOT_EXIST;
}
if ( DCC_NAME_LENGTH_1 != VideoPortCompareMemory(identifier,
DCC_NAME_1,
DCC_NAME_LENGTH_1)) {
VideoDebugPrint((DBGLVL_0, "%s: CallBack: Identifier don't match string 1\n", STANDARD_DEBUG_PREFIX));
#if CHECK_DISPLAY_STRING
if ( DCC_NAME_LENGTH_2 != VideoPortCompareMemory(identifier,
DCC_NAME_2,
DCC_NAME_LENGTH_2)) {
VideoDebugPrint((DBGLVL_0, "%s: CallBack: Identifier don't match string 2\n", STANDARD_DEBUG_PREFIX));
return ERROR_DEV_NOT_EXIST;
}
}
VideoDebugPrint((DBGLVL_1, "%s: CallBack: Returning normal\n", STANDARD_DEBUG_PREFIX));
#else // CHECK_DISPLAY_STRING
return ERROR_DEV_NOT_EXIST;
}
#endif // CHECK_DISPLAY_STRING
return NO_ERROR;
break;
/******
case VpMonitorData:
//
// BUGBUG because we had a RESOURCE LIST header at the top.
// + 8 should be the offset of the paertial resource descriptor
// in a full resource descriptor.
//
monitorConfigData = (PMONITOR_CONFIG_DATA)(((PUCHAR)monitorConfigData) + 8);
VideoDebugPrint((DBGLVL_1, "%s: DCCCallBack: getting moniotr information\n", STANDARD_DEBUG_PREFIX));
VideoDebugPrint((DBGLVL_1, "%s: Version = %d, Revision=%d\n", STANDARD_DEBUG_PREFIX,
monitorConfigData->Version, monitorConfigData->Revision));
VideoDebugPrint((DBGLVL_1, "%s: Resolution = %d X %d\n", STANDARD_DEBUG_PREFIX,
monitorConfigData->HorizontalResolution, monitorConfigData->VerticalResolution));
VideoDebugPrint((DBGLVL_1, "%s: Screen Size = %d X %d\n", STANDARD_DEBUG_PREFIX,
monitorConfigData->HorizontalScreenSize, monitorConfigData->VerticalScreenSize));
VideoDebugPrint((DBGLVL_1, "%s: H-Display = %d\n", STANDARD_DEBUG_PREFIX,
monitorConfigData->HorizontalDisplayTime));
VideoDebugPrint((DBGLVL_1, "%s: H-FrontPorch = %d\n", STANDARD_DEBUG_PREFIX,
monitorConfigData->HorizontalFrontPorch));
VideoDebugPrint((DBGLVL_1, "%s: H-BackPorch = %d\n", STANDARD_DEBUG_PREFIX,
monitorConfigData->HorizontalBackPorch));
VideoDebugPrint((DBGLVL_1, "%s: H-Sync = %d\n", STANDARD_DEBUG_PREFIX, monitorConfigData->HorizontalSync));
VideoDebugPrint((DBGLVL_1, "%s: V-FrontPorch = %d\n", STANDARD_DEBUG_PREFIX,
monitorConfigData->VerticalFrontPorch));
VideoDebugPrint((DBGLVL_1, "%s: V-BackPorch = %d\n", STANDARD_DEBUG_PREFIX, monitorConfigData->VerticalBackPorch));
VideoDebugPrint((DBGLVL_1, "%s: V-Sync = %d\n", STANDARD_DEBUG_PREFIX, monitorConfigData->VerticalSync));
VideoDebugPrint((DBGLVL_1, "%s: Identifier = %S\n", STANDARD_DEBUG_PREFIX, identifier));
//
// Initialize the monitor parameters.
//
VideoDebugPrint((DBGLVL_2, "%s: CallBack: (Monitor) Normally returning\n", STANDARD_DEBUG_PREFIX));
return NO_ERROR;
break;
*********/
default:
VideoDebugPrint((DBGLVL_0, "%s: CallBack: Invalid Parameter --> returning\n", STANDARD_DEBUG_PREFIX));
return ERROR_INVALID_PARAMETER;
}
} //end DCCGetDeviceDataCallback()
BOOLEAN
DCCInitialize(
PVOID HwDeviceExtension
)
/*++
Routine Description:
This routine does one time initialization of the device.
Arguments:
HwDeviceExtension - Supplies a pointer to the miniport's device extension.
Return Value:
Always returns TRUE since this routine can never fail.
--*/
{
LONG index, i;
ULONG pvr;
PHW_DEVICE_EXTENSION hwDeviceExtension = HwDeviceExtension;
VideoDebugPrint((DBGLVL_TR, "%s: === PSIDISP.SYS: Entering DCCInitialize ===\n", STANDARD_DEBUG_PREFIX));
if(hwDeviceExtension->VRAMWidth == VRAM_32BIT) { // Patch table contents
BtReg1Init[0][PIXEL_8].Gr1_StartPos = 0x40; // MSB start position
BtReg1Init[0][PIXEL_8].Gr1_FmtCtrl = 0x00; // Use MSB unpacking
if(hwDeviceExtension->VRAM1MBWorkAround) {
VideoDebugPrint((DBGLVL_0, "%s: 1MB VRAM work around for 16 bits activated\n", STANDARD_DEBUG_PREFIX));
BtReg1Init[0][PIXEL_15].Gr1_StartPos = 0x40; // MSB start position
BtReg1Init[0][PIXEL_15].Gr1_FmtCtrl = 0x00; // Use MSB unpacking
BtReg1Init[0][PIXEL_15].CFG_RedPos = 0x03;
BtReg1Init[0][PIXEL_15].CFG_GreenPos = 0x0f;
BtReg1Init[0][PIXEL_15].CFG_BluePos = 0x0b;
BtReg1Init[0][PIXEL_15].CFG_RedWidth = BtReg1Init[0][PIXEL_15].CFG_GreenWidth = BtReg1Init[0][PIXEL_15].CFG_BlueWidth = 4;
for(i=0; i<NUMBER_OF_MODES; ++i) {
if(DccModes[i].pixelType == PIXEL_15) {
DccModes[i].modeInformation.BitsPerPlane = 12;
DccModes[i].modeInformation.RedMask = 0x00000f00;
DccModes[i].modeInformation.GreenMask = 0x000000f0;
DccModes[i].modeInformation.BlueMask = 0x0000000f;
}
}
}
}
pvr = loadpvr();
VideoDebugPrint((DBGLVL_1, "%s: PVR = %x\n", STANDARD_DEBUG_PREFIX, pvr));
hwDeviceExtension->CPUKind = (pvr >> 16);
switch(pvr & 0xffff0000) {
case 0x00010000: // 601
hwDeviceExtension->L1cacheEntry = 8*64*2;
hwDeviceExtension->SetSize = 64*2*32;
hwDeviceExtension->NumberOfSet = 8;
hwDeviceExtension->CPUKind = 0; // Use CPUKind 0 for 601
break;
case 0x00030000: // 603
hwDeviceExtension->L1cacheEntry = 2*128;
hwDeviceExtension->SetSize = 128*32;
hwDeviceExtension->NumberOfSet = 2;
break;
case 0x00040000: // 604
case 0x00060000: // 606 (603E)
hwDeviceExtension->L1cacheEntry = 4*128;
hwDeviceExtension->SetSize = 128*32;
hwDeviceExtension->NumberOfSet = 4;
break;
default: // 609 (Sirocco), 620 or later
hwDeviceExtension->L1cacheEntry = 8*128;
hwDeviceExtension->SetSize = 128*32;
hwDeviceExtension->NumberOfSet = 8;
break;
}
//
// Calculated the number of valid modes
//
hwDeviceExtension->NumAvailableModes = 0;
for (i = 0; i < NUMBER_OF_MODES; i++) {
if (DccModes[i].minimumMemoryRequired <= hwDeviceExtension->VRAMLength) {
#if SUPPORT_565
if(hwDeviceExtension->VRAMWidth == VRAM_32BIT && hwDeviceExtension->VRAM1MBWorkAround
&& DccModes[i].pixelType == PIXEL_16)
continue;
#endif
hwDeviceExtension->NumAvailableModes++;
}
}
VideoDebugPrint((DBGLVL_1, "%s: Num of Available Modes = %d\n", STANDARD_DEBUG_PREFIX,
hwDeviceExtension->NumAvailableModes));
//
// Initialize the color map copy in the device extension.
//
for (index = 0; index < NUMBER_OF_COLORS; index++) {
hwDeviceExtension->ColorMap[index].RgbData.Red =
(UCHAR)(((index & 0x7) << 2) | ((index & 0x7) << 5));
hwDeviceExtension->ColorMap[index].RgbData.Green =
(UCHAR)(((index & 0x38) >> 1) | ((index & 0x38) << 2));
hwDeviceExtension->ColorMap[index].RgbData.Blue =
(UCHAR)(((index & 0xc0) >> 6) | ((index & 0xc0) >> 4) |
((index & 0xc0) >> 2) | (index & 0xc0));
}
//
// Set colors for map entries 0 and 1 which are used by text output
// and the hardware cursor.
//
hwDeviceExtension->ColorMap[0].RgbData.Red = 255;
hwDeviceExtension->ColorMap[0].RgbData.Green = 255;
hwDeviceExtension->ColorMap[0].RgbData.Blue = 255;
hwDeviceExtension->ColorMap[1].RgbData.Red = 0;
hwDeviceExtension->ColorMap[1].RgbData.Green = 0;
hwDeviceExtension->ColorMap[1].RgbData.Blue = 0x90;
//
// Set color map update parameters and enable update on next vertical
// retrace interrupt.
//
hwDeviceExtension->FirstEntry = 0;
hwDeviceExtension->LastEntry = NUMBER_OF_COLORS - 1;
hwDeviceExtension->UpdateColorMap = TRUE;
/*************** This version doesn't use interrupt, instead do it now **************
//
// Enable the vertical retrace interrupt to set up color map.
//
VideoPortEnableInterrupt(hwDeviceExtension);
VideoPortWritePortUchar(+DCC_INDEX_REGISTER_OFFSET, DCC_INTERRUPT_STATUS_INDEX);
VideoPortWritePortUchar(+DCC_DATA_REGISTER_OFFSET, DCC_INTERRUPT_CLEAR_AND_ENABLE);
*************************************************************************************/
// Bt445UpdateLUT(hwDeviceExtension);
#if FULLCACHE
DCCInitializeCacheFlush(hwDeviceExtension, hwDeviceExtension->L1cacheEntry);
#endif
VideoDebugPrint((DBGLVL_TR, "%s: ... PSIDISP.SYS: Exiting DCCInitialize ...\n", STANDARD_DEBUG_PREFIX));
return TRUE;
} // end DCCInitialize()
BOOLEAN
DCCStartIO(
PVOID HwDeviceExtension,
PVIDEO_REQUEST_PACKET RequestPacket
)
/*++
Routine Description:
This routine is the main execution routine for the miniport driver. It
accepts a Video Request Packet, performs the request, and then returns
with the appropriate status.
Arguments:
HwDeviceExtension - Supplies a pointer to the miniport's device extension.
RequestPacket - Pointer to the video request packet. This structure
contains all the parameters passed to the VideoIoControl function.
Return Value:
--*/
{
VP_STATUS status;
PHW_DEVICE_EXTENSION hwDeviceExtension = HwDeviceExtension;
ULONG inIoSpace;
PULONG colorSource;
PVIDEO_MODE_INFORMATION modeInformation;
PVIDEO_MEMORY_INFORMATION memoryInformation;
PVIDEO_CLUT clutBuffer;
USHORT index1;
UCHAR turnOnInterrupts = FALSE;
LONG i;
ULONG modeToSet;
ULONG modeCount;
ULONG low, hi;
#if WRITEBAT
char *cp;
#else
ULONG Ibit, vp, pp, blocksize, sizetoset;
#endif
//
// Switch on the IoContolCode in the RequestPacket. It indicates which
// function must be performed by the driver.
//
// VideoDebugPrint((DBGLVL_TR, "%s: === PSIDISP.SYS: Entering DCCStartIO ===\n", STANDARD_DEBUG_PREFIX));
switch (RequestPacket->IoControlCode) {
case IOCTL_VIDEO_MAP_VIDEO_MEMORY:
VideoDebugPrint((DBGLVL_TR, "%s: DCCStartIO - MapVideoMemory\n", STANDARD_DEBUG_PREFIX));
if ( (RequestPacket->OutputBufferLength <
(RequestPacket->StatusBlock->Information =
sizeof(VIDEO_MEMORY_INFORMATION))) ||
(RequestPacket->InputBufferLength < sizeof(VIDEO_MEMORY)) ) {
VideoDebugPrint((DBGLVL_0, "%s: Insufficient buffer for IOCTL_VIDEO_MAP_VIDEO_MEMORY\n", STANDARD_DEBUG_PREFIX));
status = ERROR_INSUFFICIENT_BUFFER;
} else {
memoryInformation = RequestPacket->OutputBuffer;
memoryInformation->VideoRamBase = ((PVIDEO_MEMORY)
(RequestPacket->InputBuffer))->RequestedVirtualAddress;
memoryInformation->VideoRamLength =
hwDeviceExtension->VRAMLength;
inIoSpace = 0;
VideoDebugPrint((DBGLVL_1, "%s: VideoPortMapMemory: %08x:%08x (%x) %d -> %x\n", STANDARD_DEBUG_PREFIX,
hwDeviceExtension->PhysicalVRAMAddress.HighPart,
hwDeviceExtension->PhysicalVRAMAddress.LowPart,
memoryInformation->VideoRamLength, inIoSpace,
memoryInformation->VideoRamBase));
status = VideoPortMapMemory(hwDeviceExtension,
hwDeviceExtension->PhysicalVRAMAddress,
&(memoryInformation->VideoRamLength),
&inIoSpace,
&(memoryInformation->VideoRamBase));
//
// The frame buffer and virtual memory are equivalent in this
// case.
//
memoryInformation->FrameBufferBase = hwDeviceExtension->VRAMuserMappedAddress =
memoryInformation->VideoRamBase;
memoryInformation->FrameBufferLength =
memoryInformation->VideoRamLength;
VideoDebugPrint((DBGLVL_1, "%s: VideoPortMapMemory Done: status=%d, RamBase=0x%08x, Length=0x%08x\n", STANDARD_DEBUG_PREFIX,
status, memoryInformation->FrameBufferBase, memoryInformation->FrameBufferLength));
}
break;
case IOCTL_VIDEO_UNMAP_VIDEO_MEMORY:
VideoDebugPrint((DBGLVL_TR, "%s: DCCStartIO - UnMapVideoMemory\n", STANDARD_DEBUG_PREFIX));
if (RequestPacket->InputBufferLength < sizeof(VIDEO_MEMORY)) {
VideoDebugPrint((DBGLVL_0, "%s: Insufficient buffer for IOCTL_VIDEO_UNMAP_VIDEO_MEMORY\n", STANDARD_DEBUG_PREFIX));
status = ERROR_INSUFFICIENT_BUFFER;
} else {
status = VideoPortUnmapMemory(hwDeviceExtension,
((PVIDEO_MEMORY)
(RequestPacket->InputBuffer))->
RequestedVirtualAddress,
0);
}
break;
case IOCTL_VIDEO_QUERY_AVAIL_MODES:
VideoDebugPrint((DBGLVL_TR, "%s: DCCStartIO - QueryAvailableModes\n", STANDARD_DEBUG_PREFIX));
if (RequestPacket->OutputBufferLength <
(RequestPacket->StatusBlock->Information =
hwDeviceExtension->NumAvailableModes *
sizeof(VIDEO_MODE_INFORMATION)) ) {
VideoDebugPrint((DBGLVL_0, "%s: Insufficient buffer for IOCTL_VIDEO_QUERY_AVAIL_MODES\n", STANDARD_DEBUG_PREFIX));
status = ERROR_INSUFFICIENT_BUFFER;
} else {
modeInformation = RequestPacket->OutputBuffer;
modeCount = hwDeviceExtension->NumAvailableModes;
for (i = 0; i < NUMBER_OF_MODES; i++) {
if (DccModes[i].minimumMemoryRequired <= hwDeviceExtension->VRAMLength) {
#if SUPPORT_565
if(hwDeviceExtension->VRAMWidth == VRAM_32BIT
&& hwDeviceExtension->VRAM1MBWorkAround
&& DccModes[i].pixelType == PIXEL_16)
continue;
#endif
*modeInformation = DccModes[i].modeInformation;
modeInformation++;
modeCount--;
if(! modeCount)
break; // Limit check just in case
}
}
status = NO_ERROR;
}
break;
case IOCTL_VIDEO_QUERY_CURRENT_MODE:
VideoDebugPrint((DBGLVL_TR, "%s: DCCStartIO - Query Current Modes\n", STANDARD_DEBUG_PREFIX));
if (RequestPacket->OutputBufferLength <
(RequestPacket->StatusBlock->Information =
sizeof(VIDEO_MODE_INFORMATION)) ) {
VideoDebugPrint((DBGLVL_0, "%s: Insufficient buffer for IOCTL_VIDEO_QUERY_CURRENT_MODE\n", STANDARD_DEBUG_PREFIX));
status = ERROR_INSUFFICIENT_BUFFER;
} else {
*((PVIDEO_MODE_INFORMATION)RequestPacket->OutputBuffer) =
DccModes[hwDeviceExtension->ModeNumber].modeInformation;
status = NO_ERROR;
VideoDebugPrint((DBGLVL_1, "%s: Returned Modes = %d\n", STANDARD_DEBUG_PREFIX, hwDeviceExtension->ModeNumber));
}
break;
case IOCTL_VIDEO_QUERY_NUM_AVAIL_MODES:
VideoDebugPrint((DBGLVL_TR, "%s: DCCStartIO - QueryNumAvailableModes\n", STANDARD_DEBUG_PREFIX));
//
// 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 (RequestPacket->OutputBufferLength <
(RequestPacket->StatusBlock->Information =
sizeof(VIDEO_NUM_MODES)) ) {
VideoDebugPrint((DBGLVL_0, "%s: Insufficient buffer for IOCTL_VIDEO_QUERY_NUM_AVAIL_MODES\n", STANDARD_DEBUG_PREFIX));
status = ERROR_INSUFFICIENT_BUFFER;
} else {
((PVIDEO_NUM_MODES)RequestPacket->OutputBuffer)->NumModes =
hwDeviceExtension->NumAvailableModes;
((PVIDEO_NUM_MODES)RequestPacket->OutputBuffer)->ModeInformationLength =
sizeof(VIDEO_MODE_INFORMATION);
VideoDebugPrint((DBGLVL_1, "%s: Returned NumModes = %d\n", STANDARD_DEBUG_PREFIX,
hwDeviceExtension->NumAvailableModes));
status = NO_ERROR;
}
break;
case IOCTL_VIDEO_SET_CURRENT_MODE:
VideoDebugPrint((DBGLVL_TR, "%s: DCCStartIO - SetCurrentMode\n", STANDARD_DEBUG_PREFIX));
modeToSet = *(ULONG *)(RequestPacket->InputBuffer);
VideoDebugPrint((DBGLVL_1, "%s: Mode To Set = %d\n", STANDARD_DEBUG_PREFIX, modeToSet));
if(modeToSet >= NUMBER_OF_MODES ||
DccModes[modeToSet].minimumMemoryRequired > hwDeviceExtension->VRAMLength) {
VideoDebugPrint((DBGLVL_0, "%s: ### Unsupported mode error %d\n", STANDARD_DEBUG_PREFIX, modeToSet));
status = ERROR_INVALID_PARAMETER;
break;
}
#if SUPPORT_565
if(hwDeviceExtension->VRAMWidth == VRAM_32BIT && hwDeviceExtension->VRAM1MBWorkAround
&& DccModes[modeToSet].pixelType == PIXEL_16) {
VideoDebugPrint((DBGLVL_0, "%s: ### Unsupported mode error %d\n", STANDARD_DEBUG_PREFIX, modeToSet));
status = ERROR_INVALID_PARAMETER;
break;
}
#endif
hwDeviceExtension->ModeNumber = modeToSet;
DCCSetMode(hwDeviceExtension);
status = NO_ERROR;
break;
case IOCTL_VIDEO_RESET_DEVICE:
VideoDebugPrint((DBGLVL_TR, "%s: DCCStartIO - VideoResetMode\n", STANDARD_DEBUG_PREFIX));
hwDeviceExtension->ModeNumber = mode640_480_8_72;
DCCSetMode(hwDeviceExtension);
status = NO_ERROR;
break;
case IOCTL_VIDEO_SET_COLOR_REGISTERS:
VideoDebugPrint((DBGLVL_TR, "%s: DCCStartIO - SetColorRegs\n", STANDARD_DEBUG_PREFIX));
clutBuffer = RequestPacket->InputBuffer;
//
// Check if the size of the data in the input buffer is large enough.
//
if ( (RequestPacket->InputBufferLength < sizeof(VIDEO_CLUT) -
sizeof(ULONG)) ||
(RequestPacket->InputBufferLength < sizeof(VIDEO_CLUT) +
(sizeof(ULONG) * (clutBuffer->NumEntries - 1)) ) ) { // One entry is in VIDEO_CLUT structure size
VideoDebugPrint((DBGLVL_0, "%s: Insufficient buffer for IOCTL_VIDEO_SET_COLOR_REGISTERS\n", STANDARD_DEBUG_PREFIX));
status = ERROR_INSUFFICIENT_BUFFER;
break;
}
//
// Check to see if the parameters are valid.
//
VideoDebugPrint((DBGLVL_1, "%s: First Entry = %d\n", STANDARD_DEBUG_PREFIX, clutBuffer->FirstEntry));
VideoDebugPrint((DBGLVL_1, "%s: Last Entry = %d\n", STANDARD_DEBUG_PREFIX,
clutBuffer->FirstEntry + clutBuffer->NumEntries - 1));
if ((clutBuffer->NumEntries == 0) ||
(clutBuffer->FirstEntry + clutBuffer->NumEntries > NUMBER_OF_COLORS)) {
VideoDebugPrint((DBGLVL_0, "%s: ### Invalid palette entry %d (%d)\n", STANDARD_DEBUG_PREFIX, clutBuffer->FirstEntry, clutBuffer->NumEntries));
status = ERROR_INVALID_PARAMETER;
break;
}
index1 = clutBuffer->FirstEntry;
hwDeviceExtension->FirstEntry = index1;
hwDeviceExtension->LastEntry = index1 + clutBuffer->NumEntries -1;
colorSource = (PULONG)&(clutBuffer->LookupTable[0]);
while (index1 <= hwDeviceExtension->LastEntry) {
hwDeviceExtension->ColorMap[index1++].RgbLong = *colorSource++;
}
Bt445UpdateLUT(hwDeviceExtension);
/************* This version won't use interrupt **************************
//
// Enable the verticle retrace interrupt to perform the update.
//
hwDeviceExtension->UpdateColorMap = TRUE;
turnOnInterrupts = TRUE;
**************************************************************************/
status = NO_ERROR;
break;
case IOCTL_VIDEO_QUERY_PSIDISP:
VideoDebugPrint((DBGLVL_TR, "%s: DCCStartIO - QueryPSIDisp\n", STANDARD_DEBUG_PREFIX));
//
// Return the amount of video memory installed.
//
if (RequestPacket->OutputBufferLength <
(RequestPacket->StatusBlock->Information = sizeof(VIDEO_PSIDISP_INFO)) ) {
VideoDebugPrint((DBGLVL_0, "%s: Insufficient buffer for IOCTL_VIDEO_QUERY_PSIDISP\n", STANDARD_DEBUG_PREFIX));
status = ERROR_INSUFFICIENT_BUFFER;
} else {
#if INVESTIGATE
DisplayBat(hwDeviceExtension->CPUKind);
#endif
for(i=7; i>0; i-=2) {
low = loadbat(i, hwDeviceExtension->CPUKind);
if((low & 0xfffe0000) == VRAM_PHYSICAL_ADDRESS_BASE)
break;
}
if(i > 0) { // DBAT is used to map VRAM
#if WRITEBAT
if(hwDeviceExtension->CPUKind) { // 603 or later
hi = loadbat(i-1, hwDeviceExtension->CPUKind);
hi &= 0xfffe0000;
cp = (char *)hi;
// low &= 0xffffff87;
hwDeviceExtension->DBAT_Mbit = low & 0x10;
low &= 0xffffff97; // Not to clear M bit
switch(hwDeviceExtension->VRAMLength) {
case MEM1MB:
hi |= 0x1f;
break;
case MEM2MB:
hi |= 0x3f;
break;
default: // 4MB VRAM
hi |= 0x7f;
break;
}
} else { // 601
hi = loadbat(i-1, hwDeviceExtension->CPUKind);
hi &= 0xfffe0000;
cp = (char *)hi;
hi = loadbat(i-1, hwDeviceExtension->CPUKind);
// hi &= 0xffffff8c;
hwDeviceExtension->DBAT_Mbit = hi & 0x10;
hi &= 0xffffff9c; // Not to clear M bit
hi |= 0x00000002;
low &= 0xffffff80;
switch(hwDeviceExtension->VRAMLength) {
case MEM1MB:
low |= 0x47;
break;
case MEM2MB:
low |= 0x4f;
break;
default: // 4MB VRAM
low |= 0x5f;
break;
}
}
VideoDebugPrint((DBGLVL_1, "%s: BAT%d set to map VRAM cacheable 0x%08x, M-bit = %d\n", STANDARD_DEBUG_PREFIX, i/2, cp, (hwDeviceExtension->DBAT_Mbit)?1:0));
storebat(i-1, hi, hwDeviceExtension->CPUKind);
storebat(i, low, hwDeviceExtension->CPUKind);
#if INVESTIGATE
DisplayBat(hwDeviceExtension->CPUKind);
#endif
((PVIDEO_PSIDISP_INFO)RequestPacket->OutputBuffer)->pjCachedScreen = cp;
#else // WRITEBAT
hi = loadbat(i-1, hwDeviceExtension->CPUKind);
if(hwDeviceExtension->CPUKind) { // 603 or later
Ibit = low & 0x20;
hwDeviceExtension->DBAT_Mbit = (USHORT) (low & 0x10);
vp = hi & 0x01;
pp = low & 0x03;
blocksize = (hi & 0x1ffc) >> 2;
} else { // 601 unified BAT
Ibit = hi & 0x20;
hwDeviceExtension->DBAT_Mbit = (USHORT) (hi & 0x10);
vp = hi & 0x04;
pp = hi & 0x03;
blocksize = low & 0x3f;
}
switch(hwDeviceExtension->VRAMLength) {
case MEM1MB:
sizetoset = 0x07;
break;
case MEM2MB:
sizetoset = 0x0f;
break;
default: // 4MB VRAM
sizetoset = 0x1f;
break;
}
blocksize &= sizetoset;
if(Ibit || pp != 0x02 || (! vp) || blocksize != sizetoset) { // BAT not appropriate
VideoDebugPrint((DBGLVL_0, "%s: DBAT setting is not appropriate\n", STANDARD_DEBUG_PREFIX));
VideoDebugPrint((DBGLVL_0, "%s: BAT%d: Cache %s, M-bit %d, User mode access %s, PP=%d, Block size=%x\n", STANDARD_DEBUG_PREFIX,
i/2, Ibit?"inhibited":"enabled", (hwDeviceExtension->DBAT_Mbit)?1:0, vp?"allowed":"not allowed", pp, blocksize));
((PVIDEO_PSIDISP_INFO)RequestPacket->OutputBuffer)->pjCachedScreen = hwDeviceExtension->VRAMuserMappedAddress;
hwDeviceExtension->DBAT_Mbit = 0; // Can not use cached VRAM anyway
} else {
hi &= 0xfffe0000;
((PVIDEO_PSIDISP_INFO)RequestPacket->OutputBuffer)->pjCachedScreen = (char *)hi;
}
#endif // WRITEBAT
} else {
VideoDebugPrint((DBGLVL_0, "%s: DBAT mapping VRAM not found\n", STANDARD_DEBUG_PREFIX));
((PVIDEO_PSIDISP_INFO)RequestPacket->OutputBuffer)->pjCachedScreen = hwDeviceExtension->VRAMuserMappedAddress;
hwDeviceExtension->DBAT_Mbit = 0; // Can not use cached VRAM
}
((PVIDEO_PSIDISP_INFO)RequestPacket->OutputBuffer)->VideoMemoryLength = hwDeviceExtension->VRAMLength;
((PVIDEO_PSIDISP_INFO)RequestPacket->OutputBuffer)->VideoMemoryWidth = hwDeviceExtension->VRAMWidth;
((PVIDEO_PSIDISP_INFO)RequestPacket->OutputBuffer)->PSIModelID = hwDeviceExtension->PSIModelID;
((PVIDEO_PSIDISP_INFO)RequestPacket->OutputBuffer)->L1cacheEntry = hwDeviceExtension->L1cacheEntry;
((PVIDEO_PSIDISP_INFO)RequestPacket->OutputBuffer)->SetSize = hwDeviceExtension->SetSize;
((PVIDEO_PSIDISP_INFO)RequestPacket->OutputBuffer)->NumberOfSet = hwDeviceExtension->NumberOfSet;
((PVIDEO_PSIDISP_INFO)RequestPacket->OutputBuffer)->VRAM1MBWorkAround = hwDeviceExtension->VRAM1MBWorkAround;
((PVIDEO_PSIDISP_INFO)RequestPacket->OutputBuffer)->AvoidConversion = hwDeviceExtension->AvoidConversion;
((PVIDEO_PSIDISP_INFO)RequestPacket->OutputBuffer)->DBAT_Mbit = hwDeviceExtension->DBAT_Mbit;
((PVIDEO_PSIDISP_INFO)RequestPacket->OutputBuffer)->CacheFlushCTRL = hwDeviceExtension->CacheFlushCTRL;
status = NO_ERROR;
}
break ;
#if INVESTIGATE
case IOCTL_GET_TIMER_COUNTER:
#if DBG
DisplayHWDevExt(HwDeviceExtension);
#endif
VideoDebugPrint((DBGLVL_4, "%s: DCCStartIO - QueryTimer\n", STANDARD_DEBUG_PREFIX));
//
// Return timer counter.
//
if (RequestPacket->OutputBufferLength <
(RequestPacket->StatusBlock->Information = sizeof(PULONG)) ) {
VideoDebugPrint((DBGLVL_0, "%s: Insufficient buffer for IOCTL_GET_TIMER_COUNTER\n", STANDARD_DEBUG_PREFIX));
status = ERROR_INSUFFICIENT_BUFFER;
} else {
CurrentTime = KeQueryPerformanceCounter(&Frequency); // Get current time
if(StartTime.HighPart == CurrentTime.HighPart) {
*((PULONG)RequestPacket->OutputBuffer) =
(CurrentTime.LowPart - StartTime.LowPart)/tickperms;
} else {
work = (CurrentTime.HighPart - StartTime.HighPart) * highpartms;
*((PULONG)RequestPacket->OutputBuffer) =
work + CurrentTime.LowPart/tickperms - StartTime.LowPart/tickperms;
}
status = NO_ERROR;
}
break ;
case IOCTL_VIDEO_QUERY_PUBLIC_ACCESS_RANGES:
VideoDebugPrint((DBGLVL_TR, "%s: DCCStartIO - QueryPublicAccessRanges\n", STANDARD_DEBUG_PREFIX));
{
PVIDEO_PUBLIC_ACCESS_RANGES portAccess;
ULONG physicalPortLength;
if ( RequestPacket->OutputBufferLength <
(RequestPacket->StatusBlock->Information =
sizeof(VIDEO_PUBLIC_ACCESS_RANGES)) ) {
VideoDebugPrint((DBGLVL_0, "%s: Insufficient buffer for IOCTL_VIDEO_QUERY_PUBLIC_ACCESS_RANGES\n", STANDARD_DEBUG_PREFIX));
status = ERROR_INSUFFICIENT_BUFFER;
break;
}
portAccess = RequestPacket->OutputBuffer;
portAccess->VirtualAddress = (PVOID) NULL; // Requested VA
portAccess->InIoSpace = TscStatusRegAccessRange.RangeInIoSpace;
portAccess->MappedInIoSpace = portAccess->InIoSpace;
physicalPortLength = TscStatusRegAccessRange.RangeLength;
status = VideoPortMapMemory(hwDeviceExtension,
TscStatusRegAccessRange.RangeStart,
&physicalPortLength,
&(portAccess->MappedInIoSpace),
&(portAccess->VirtualAddress));
}
break;
case IOCTL_VIDEO_FREE_PUBLIC_ACCESS_RANGES:
VideoDebugPrint((DBGLVL_TR, "%s: DCCStartIO - FreePublicAccessRanges\n", STANDARD_DEBUG_PREFIX));
{
PVIDEO_MEMORY mappedMemory;
if (RequestPacket->InputBufferLength < sizeof(VIDEO_MEMORY)) {
VideoDebugPrint((DBGLVL_0, "%s: Insufficient buffer for IOCTL_VIDEO_FREE_PUBLIC_ACCESS_RANGES\n", STANDARD_DEBUG_PREFIX));
status = ERROR_INSUFFICIENT_BUFFER;
break;
}
status = NO_ERROR;
mappedMemory = RequestPacket->InputBuffer;
if (mappedMemory->RequestedVirtualAddress != NULL) {
status = VideoPortUnmapMemory(hwDeviceExtension,
mappedMemory->
RequestedVirtualAddress,
0);
}
}
break;
#endif
//
// if we get here, an invalid IoControlCode was specified.
//
default:
VideoDebugPrint((DBGLVL_0, "%s: DCCStartIO - Unexpected Function (0x%x)\n", STANDARD_DEBUG_PREFIX,
RequestPacket->IoControlCode));
status = ERROR_INVALID_FUNCTION;
break;
}
/****************** This version won't support interrupt *********************
if (turnOnInterrupts) {
VideoPortWritePortUchar(hwDeviceExtension->DCCAddress+DCC_INDEX_REGISTER_OFFSET,
DCC_INTERRUPT_STATUS_INDEX);
VideoPortWritePortUchar(hwDeviceExtension->DCCAddress+DCC_DATA_REGISTER_OFFSET,
DCC_INTERRUPT_CLEAR_AND_ENABLE);
}
*******************************************************************************/
RequestPacket->StatusBlock->Status = status;
// VideoDebugPrint((DBGLVL_TR, "%s: ... PSIDISP.SYS: Exiting DCCStartIO ...\n", STANDARD_DEBUG_PREFIX));
return TRUE;
} // end DCCStartIO()
/***************** Interrupt is not used in this version **************************
BOOLEAN
DCCInterruptService(
PVOID HwDeviceExtension
)
****/
/*++
Routine Description:
This routine is the interrupt service routine for the DCC kernel video
driver.
Arguments:
HwDeviceExtension - Pointer to the miniport driver's adapter information.
Return Value:
TRUE since the interrupt is always serviced.
--*/
/****
{
PHW_DEVICE_EXTENSION hwDeviceExtension = HwDeviceExtension;
UCHAR savedDCCIndex;
UCHAR savedBtIndex;
UCHAR DCCInterrupt;
ULONG InterruptSource;
//
// Read the interrupt source before disabling interrupts
//
InterruptSource =
VideoPortReadPortUlong(hwDeviceExtension->SystemInterruptRegAddress + ADDRESS_MUNGE_FOR_WORD);
if (! (InterruptSource & SYSTEM_INTERRUPT_DISPLAY_BIT)) { // Not Display interrupt
return (FALSE);
}
savedDCCIndex =
VideoPortReadPortUchar(hwDeviceExtension->DCCAddress+DCC_INDEX_REGISTER_OFFSET);
VideoPortWritePortUchar(hwDeviceExtension->DCCAddress+DCC_INDEX_REGISTER_OFFSET,
DCC_INTERRUPT_STATUS_INDEX);
DCCInterrupt = VideoPortReadPortUchar(hwDeviceExtension->DCCAddress+DCC_DATA_REGISTER_OFFSET);
if (DCCInterrupt & DCC_INTERRUPT_DETECTED) { // DCC Interrupt
VideoPortWritePortUchar(hwDeviceExtension->DCCAddress+DCC_INDEX_REGISTER_OFFSET,
DCC_INTERRUPT_STATUS_INDEX);
VideoPortWritePortUchar(hwDeviceExtension->DCCAddress+DCC_DATA_REGISTER_OFFSET,
DCC_INTERRUPT_CLEAR_AND_DISABLE);
//
// If the color map should be updated, then load the color map into the
// Bt445 Display controller.
//
if (hwDeviceExtension->UpdateColorMap == TRUE) {
savedBtIndex =
VideoPortReadPortUchar(hwDeviceExtension->Bt445Address+BT445_ADDRESS_REG_OFFSET);
//
// Init the Bt445 Palette Write Address register to the first
// palette location to be updated.
//
Bt445UpdateLUT(hwDeviceExtension);
hwDeviceExtension->UpdateColorMap = FALSE;
VideoPortWritePortUchar(hwDeviceExtension->Bt445Address+BT445_ADDRESS_REG_OFFSET,
savedBtIndex);
VideoPortWritePortUchar(hwDeviceExtension->DCCAddress+DCC_INDEX_REGISTER_OFFSET,
savedDCCIndex);
return (TRUE);
}
} else {
VideoPortWritePortUchar(hwDeviceExtension->DCCAddress+DCC_INDEX_REGISTER_OFFSET,
savedDCCIndex);
return (FALSE);
}
} // End DCCInterrupt
************************************************************************************/
VOID
DCCSetMode(
PHW_DEVICE_EXTENSION hwDeviceExtension
)
/*++
Routine Description:
Set the current mode based on the video mode number selected in the device extension.
Arguments:
HwDeviceExtension - Supplies a pointer to the miniport's device extension.
Return Value:
None.
--*/
{
UCHAR OrigData, Data;
PSI_MODELS model = hwDeviceExtension->PSIModelID;
DCC_MODE_LIST mode = hwDeviceExtension->ModeNumber;
DCC_PIXEL_TYPE pType = DccModes[mode].pixelType;
DCC_VRAM_WIDTH vramWidth = hwDeviceExtension->VRAMWidth;
ULONG TableIndex = (vramWidth == VRAM_32BIT)? 0 : 1;
ULONG fullVRAM;
ULONG i, *up;
if(model == POWER_PRO)
fullVRAM = TableIndex;
else
fullVRAM = (vramWidth == VRAM_64BIT) ? 0 : 1;
// (0) disable display
BtWrite(BT445_GROUP0_READ_ENABLE_INDEX, BT445_GROUP0_REG_OFFSET, 0x00, NO_MASK);
// (1) set system registers related to VRAM
#if SYSTEMREGS_3
Data = SysRegInit[model][fullVRAM].VramControl;
if(model == POWER_PRO && fullVRAM == 0 && (pType == PIXEL_8 || hwDeviceExtension->VRAM1MBWorkAround)) {
VideoDebugPrint((DBGLVL_1, "%s: Use MSB unpacking for 1MB VRAM for 8 bit or 12 bit mode.\n", STANDARD_DEBUG_PREFIX));
Data = 0x03; // for MSB unpacking
}
OrigData = VideoPortReadPortUchar(hwDeviceExtension->VRAMCtrlRegAddress + ADDRESS_MUNGE_FOR_BYTE);
OrigData &= (~VRAM_CTRL_REGISTER_MASK);
Data &= VRAM_CTRL_REGISTER_MASK;
Data |= OrigData;
VideoPortWritePortUchar(hwDeviceExtension->VRAMCtrlRegAddress + ADDRESS_MUNGE_FOR_BYTE, Data);
#endif
#if SYSTEMREGS_1
Data = SysRegInit[model][fullVRAM].VramTiming;
OrigData = VideoPortReadPortUchar(hwDeviceExtension->VRAMTimingRegAddress + ADDRESS_MUNGE_FOR_BYTE);
OrigData &= (~VRAM_TIMING_REGISTER_MASK);
Data &= VRAM_TIMING_REGISTER_MASK;
Data |= OrigData;
VideoPortWritePortUchar(hwDeviceExtension->VRAMTimingRegAddress + ADDRESS_MUNGE_FOR_BYTE, Data);
#endif
#if SYSTEMREGS_2
Data = SysRegInit[model][fullVRAM].Mem7Config;
OrigData = VideoPortReadPortUchar(hwDeviceExtension->MemBank7ConfigRegAddress + ADDRESS_MUNGE_FOR_BYTE);
VideoDebugPrint((DBGLVL_1, "%s: Memory bank 7 config register: current = %02x\n", STANDARD_DEBUG_PREFIX, OrigData));
if((OrigData & MEM_BANK7_CONFIG_REGISTER_MASK) != (Data & MEM_BANK7_CONFIG_REGISTER_MASK)) {
VideoPortWritePortUchar(hwDeviceExtension->MemBank7ConfigRegAddress + ADDRESS_MUNGE_FOR_BYTE,
(UCHAR) ((OrigData & (~MEM_BANK7_CONFIG_REGISTER_MASK)) | (Data & MEM_BANK7_CONFIG_REGISTER_MASK)));
VideoDebugPrint((DBGLVL_1, "%s: Memory bank 7 config register: new = %02x\n", STANDARD_DEBUG_PREFIX,
(OrigData & (~MEM_BANK7_CONFIG_REGISTER_MASK)) | (Data & MEM_BANK7_CONFIG_REGISTER_MASK)));
}
#endif
#if SYSTEMREGS_1
VideoPortWritePortUchar(hwDeviceExtension->MemRefreshRegAddress + ADDRESS_MUNGE_FOR_BYTE,
SysRegInit[model][fullVRAM].MemRefresh);
#endif // SYSTEMREGS_1
// (2) clear VRAM
up = (ULONG *)hwDeviceExtension->VRAMAddress;
for(i=0; i<(hwDeviceExtension->VRAMLength)/sizeof(ULONG); ++i)
*(up+i) = 0;
// (3) initialize mode independent portion of DCC registers
#if VERIFY_DCC_1MB_BIT
if(hwDeviceExtension->PSIModelID == POWER_PRO && (! hwDeviceExtension->VRAM1MBWorkAround)) {
// 1MB VRAM work around is not selected -->
// Need to verify that GPIO of DCC is correctly set
OrigData = DCCRead(DCC_GPIO_B_INDEX);
VideoDebugPrint((DBGLVL_1, "%s: DCC GPIO_B current = %02x\n", STANDARD_DEBUG_PREFIX, OrigData));
if(vramWidth == VRAM_32BIT) {
if((OrigData & (~DCC_GPIO_B_MASK)) != DCC_GPIO_B_1MB_VRAM_MODE) {
DCCWrite(DCC_GPIO_B_INDEX, (UCHAR) ((OrigData & DCC_GPIO_B_MASK) | DCC_GPIO_B_1MB_VRAM_MODE));
VideoDebugPrint((DBGLVL_1, "%s: DCC GPIO_B new = %02x\n", STANDARD_DEBUG_PREFIX, (OrigData & DCC_GPIO_B_MASK) | DCC_GPIO_B_1MB_VRAM_MODE));
}
} else {
if((OrigData & (~DCC_GPIO_B_MASK)) != DCC_GPIO_B_2MB_VRAM_MODE) {
DCCWrite(DCC_GPIO_B_INDEX, (CHAR) ((OrigData & DCC_GPIO_B_MASK) | DCC_GPIO_B_2MB_VRAM_MODE));
VideoDebugPrint((DBGLVL_1, "%s: DCC GPIO_B new = %02x\n", STANDARD_DEBUG_PREFIX, (OrigData & DCC_GPIO_B_MASK) | DCC_GPIO_B_2MB_VRAM_MODE));
}
}
}
#endif
DCCWrite(DCC_CONFIG_B_INDEX,
DCCFixedRegInit[vramWidth].ConfigB_Pre); // Set Halt bit
DCCWrite(DCC_INTERRUPT_STATUS_INDEX,
DCCFixedRegInit[vramWidth].Interrupt);
DCCWrite(DCC_CONFIG_A_INDEX,
DCCFixedRegInit[vramWidth].ConfigA);
// (4) initialize mode dependent portion of DCC registers
DCCWrite(DCC_TIMING_A_INDEX, DCCRegInit[TableIndex][mode].TimingA);
DCCWrite(DCC_HORIZ_SYNC_STOP_INDEX, DCCRegInit[TableIndex][mode].HorizSyncStop);
DCCWrite(DCC_VERT_SYNC_STOP_INDEX, DCCRegInit[TableIndex][mode].VertSyncStop);
DCCWrite(DCC_VERT_BLANK_STOP_INDEX, DCCRegInit[TableIndex][mode].VertBlankStop);
DCCWriteShort(DCC_HORIZ_COUNT_L_INDEX,DCCRegInit[TableIndex][mode].HorizCount);
DCCWriteShort(DCC_VERT_COUNT_L_INDEX, DCCRegInit[TableIndex][mode].VertCount);
DCCWriteShort(DCC_HORIZ_BLANK_STOP_L_INDEX, DCCRegInit[TableIndex][mode].HorizBlankStop);
DCCWriteShort(DCC_HORIZ_DATA_STOP_L_INDEX, DCCRegInit[TableIndex][mode].HorizDataStop);
DCCWriteShort(DCC_VERT_DATA_STOP_L_INDEX, DCCRegInit[TableIndex][mode].VertDataStop);
DCCWriteShort(DCC_INTERRUPT_TRIGGER_L_INDEX, DCCRegInit[TableIndex][mode].InterruptTrigger);
DCCWrite(DCC_CONFIG_B_INDEX,
DCCFixedRegInit[vramWidth].ConfigB_Post); // Write CONFIG-B register last
// (5) initialize fixed portion of Bt445 registers
BtWrite(BT445_GROUP0_BLINK_ENABLE_INDEX, BT445_GROUP0_REG_OFFSET,
BtFixedRegInit.Gr0_BlinkEnable, NO_MASK);
BtWrite(BT445_GROUP0_COMMAND_INDEX, BT445_GROUP0_REG_OFFSET,
BtFixedRegInit.Gr0_Command, BT445_GROUP0_COMMAND_MASK);
BtWrite(BT445_CONFIG_OVLAY_POS_INDEX, BT445_CONFIG_REG_OFFSET,
BtFixedRegInit.CFG_OvlayPos, NO_MASK);
BtWrite(BT445_CONFIG_OVLAY_WIDTH_INDEX, BT445_CONFIG_REG_OFFSET,
BtFixedRegInit.CFG_OvlayWidth, NO_MASK);
BtWrite(BT445_CONFIG_OVLAY_ENABLE_INDEX, BT445_CONFIG_REG_OFFSET,
BtFixedRegInit.CFG_OvlayEnable, BT445_CONFIG_OVLAY_ENABLE_MASK);
BtWrite(BT445_CONFIG_OVLAY_BLINK_INDEX, BT445_CONFIG_REG_OFFSET,
BtFixedRegInit.CFG_OvlayBlink, BT445_CONFIG_OVLAY_BLINK_MASK);
BtWrite(BT445_CONFIG_CSR_POS_INDEX, BT445_CONFIG_REG_OFFSET,
BtFixedRegInit.CFG_CursorPos, NO_MASK);
BtWrite(BT445_CONFIG_CSR_WIDTH_INDEX, BT445_CONFIG_REG_OFFSET,
BtFixedRegInit.CFG_CursorWidth, NO_MASK);
BtWrite(BT445_CONFIG_CSR_ENABLE_INDEX, BT445_CONFIG_REG_OFFSET,
BtFixedRegInit.CFG_CursorEnable, BT445_CONFIG_CSR_ENABLE_MASK);
BtWrite(BT445_CONFIG_CSR_BLINK_INDEX, BT445_CONFIG_REG_OFFSET,
BtFixedRegInit.CFG_CursorBlink, BT445_CONFIG_CSR_BLINK_MASK);
BtWrite(BT445_GROUP1_COMMAND_INDEX, BT445_GROUP1_REG_OFFSET,
BtFixedRegInit.Gr1_Command, BT445_GROUP1_COMMAND_MASK);
BtWrite(BT445_GROUP1_DOUT_CTRL_INDEX, BT445_GROUP1_REG_OFFSET,
BtFixedRegInit.Gr1_DoutCtrl, BT445_GROUP1_DOUT_CTRL_MASK);
BtWrite(BT445_GROUP1_LOAD_CTRL_INDEX, BT445_GROUP1_REG_OFFSET,
BtFixedRegInit.Gr1_LoadCtrl, BT445_GROUP1_LOAD_CTRL_MASK);
BtWrite(BT445_GROUP1_LUT_BYPS_POS_INDEX, BT445_GROUP1_REG_OFFSET,
BtFixedRegInit.Gr1_LutBypsPos, NO_MASK);
BtWrite(BT445_GROUP1_LUT_BYPS_WID_INDEX, BT445_GROUP1_REG_OFFSET,
BtFixedRegInit.Gr1_LutBypsWidth, NO_MASK);
// (6) initialize pixel type dependent portion of Bt445 registers
BtWrite(BT445_CONFIG_RED_POS_INDEX, BT445_CONFIG_REG_OFFSET,
BtReg1Init[TableIndex][pType].CFG_RedPos, NO_MASK);
BtWrite(BT445_CONFIG_RED_WIDTH_INDEX, BT445_CONFIG_REG_OFFSET,
BtReg1Init[TableIndex][pType].CFG_RedWidth, NO_MASK);
BtWrite(BT445_CONFIG_GREEN_POS_INDEX, BT445_CONFIG_REG_OFFSET,
BtReg1Init[TableIndex][pType].CFG_GreenPos, NO_MASK);
BtWrite(BT445_CONFIG_GREEN_WIDTH_INDEX, BT445_CONFIG_REG_OFFSET,
BtReg1Init[TableIndex][pType].CFG_GreenWidth, NO_MASK);
BtWrite(BT445_CONFIG_BLUE_POS_INDEX, BT445_CONFIG_REG_OFFSET,
BtReg1Init[TableIndex][pType].CFG_BluePos, NO_MASK);
BtWrite(BT445_CONFIG_BLUE_WIDTH_INDEX, BT445_CONFIG_REG_OFFSET,
BtReg1Init[TableIndex][pType].CFG_BlueWidth, NO_MASK);
BtWrite(BT445_GROUP1_VIDCLK_INDEX, BT445_GROUP1_REG_OFFSET,
BtReg1Init[TableIndex][pType].Gr1_VidClk, BT445_GROUP1_VIDCLK_MASK);
BtWrite(BT445_GROUP1_MPX_RATE_INDEX, BT445_GROUP1_REG_OFFSET,
BtReg1Init[TableIndex][pType].Gr1_MPXRate, BT445_GROUP1_MPX_RATE_MASK);
BtWrite(BT445_GROUP1_DEPTH_CTRL_INDEX, BT445_GROUP1_REG_OFFSET,
BtReg1Init[TableIndex][pType].Gr1_DepthCtrl, NO_MASK);
BtWrite(BT445_GROUP1_START_POS_INDEX, BT445_GROUP1_REG_OFFSET,
BtReg1Init[TableIndex][pType].Gr1_StartPos, NO_MASK);
BtWrite(BT445_GROUP1_FMT_CTRL_INDEX, BT445_GROUP1_REG_OFFSET,
BtReg1Init[TableIndex][pType].Gr1_FmtCtrl, BT445_GROUP1_FMT_CTRL_MASK);
// (7) initialize mode dependent portion of Bt445 registers
BtWrite(BT445_GROUP1_PLL_RATE_0_INDEX, BT445_GROUP1_REG_OFFSET,
BtReg2Init[mode].Gr1_PllRate0, BT445_GROUP1_PLL_RATE_0_MASK);
BtWrite(BT445_GROUP1_PLL_RATE_1_INDEX, BT445_GROUP1_REG_OFFSET,
BtReg2Init[mode].Gr1_PllRate1, BT445_GROUP1_PLL_RATE_1_MASK);
BtWrite(BT445_GROUP1_PLL_CTRL_INDEX, BT445_GROUP1_REG_OFFSET,
BtReg2Init[mode].Gr1_PllCtrl, NO_MASK);
// (8) initialize palette for 16-bit and 32-bit mode
// This setting is only for FrameBuf display driver. PSIDISP.DLL over writes the
// 16 bits or 32 bits palette using gamma curve in bInitSURF.
if(pType != PIXEL_8) {
VideoPortWritePortUchar(BtRegisterBase+BT445_ADDRESS_REG_OFFSET, 0);
for (i = 0; i < 256; ++i) {
VideoPortWritePortUchar(BtRegisterBase+BT445_PRIMARY_CLUT_REG_OFFSET, (UCHAR) i);
VideoPortWritePortUchar(BtRegisterBase+BT445_PRIMARY_CLUT_REG_OFFSET, (UCHAR) i);
VideoPortWritePortUchar(BtRegisterBase+BT445_PRIMARY_CLUT_REG_OFFSET, (UCHAR) i);
}
}
// (9) finally, enable display
BtWrite(BT445_GROUP0_READ_ENABLE_INDEX, BT445_GROUP0_REG_OFFSET,
BtFixedRegInit.Gr0_ReadEnable, NO_MASK);
}
VOID
DCCWrite(
UCHAR Index,
UCHAR Data
)
/*++
Routine Description:
Write a byte data to DCC's corresponding register specified by the index.
Arguments:
Index - Give the index value of the register.
Data - Byte data to write.
Return Value:
None.
--*/
{
VideoDebugPrint((DBGLVL_OUT, "%s: DCC Write Byte 0x%02x at 0x%02x\n", STANDARD_DEBUG_PREFIX, Data, Index));
VideoPortWritePortUchar(DCCRegisterBase+DCC_INDEX_REGISTER_OFFSET, Index);
VideoPortWritePortUchar(DCCRegisterBase+DCC_DATA_REGISTER_OFFSET, Data);
};
UCHAR
DCCRead(
UCHAR Index
)
/*++
Routine Description:
Read a byte data from DCC's corresponding register specified by the index.
Arguments:
Index - Give the index value of the register.
Return Value:
Byte data read.
--*/
{
VideoPortWritePortUchar(DCCRegisterBase+DCC_INDEX_REGISTER_OFFSET, Index);
return (VideoPortReadPortUchar(DCCRegisterBase+DCC_DATA_REGISTER_OFFSET));
};
VOID
DCCWriteShort(
UCHAR Index,
USHORT Data
)
/*++
Routine Description:
Write a 2-byte data to DCC's corresponding register specified by the index
and the following register.
Arguments:
Index - Give the index value of the register.
Data - 2 byte data to write.
Return Value:
None.
--*/
{
VideoDebugPrint((DBGLVL_OUT, "%s: DCC Write Word %d (0x%02x & 0x%02x) at 0x%02x\n", STANDARD_DEBUG_PREFIX, Data, Data>>8, Data&0xff, Index));
VideoPortWritePortUchar(DCCRegisterBase+DCC_INDEX_REGISTER_OFFSET, Index);
VideoPortWritePortUchar(DCCRegisterBase+DCC_DATA_REGISTER_OFFSET, (UCHAR) (Data&0xff));
VideoPortWritePortUchar(DCCRegisterBase+DCC_INDEX_REGISTER_OFFSET, (UCHAR) (Index+1));
VideoPortWritePortUchar(DCCRegisterBase+DCC_DATA_REGISTER_OFFSET, (UCHAR) (Data>>8));
};
VOID
BtWrite(
UCHAR Index,
ULONG Offset,
UCHAR Data,
UCHAR Mask
)
/*++
Routine Description:
Write a byte data to Bt445's corresponding register specified by the Index and Offset.
Optional Mask will allow to write only unmasked bits.
Arguments:
Index - Give the index value of the register in the register group.
Offset - Give the offset of the register group.
Data - Byte data to write.
Mask - If Mask is not zero, only 1 bits in the mask pattern has to be written.
Return Value:
None.
--*/
{
UCHAR OrigData;
VideoDebugPrint((DBGLVL_OUT, "%s: Bt Write Byte 0x%02x at 0x%02x,0x%02x with MASK of 0x%02x\n", STANDARD_DEBUG_PREFIX,
Data, Offset, Index, Mask));
VideoPortWritePortUchar(BtRegisterBase+BT445_ADDRESS_REG_OFFSET, Index);
if(Mask) { // Need to keep masked bits
OrigData = VideoPortReadPortUchar(BtRegisterBase+Offset);
OrigData &= (~Mask);
Data &= Mask;
Data |= OrigData;
}
VideoPortWritePortUchar(BtRegisterBase+Offset, Data);
};
UCHAR
BtRead(
UCHAR Index,
ULONG Offset
)
/*++
Routine Description:
Read a byte data from Bt445's corresponding register specified by the Index and Offset.
Arguments:
Index - Give the index value of the register in the register group.
Offset - Give the offset of the register group.
Return Value:
Byte data read.
--*/
{
VideoPortWritePortUchar(BtRegisterBase+BT445_ADDRESS_REG_OFFSET, Index);
return (VideoPortReadPortUchar(BtRegisterBase+Offset));
};
VOID
Bt445UpdateLUT(
PHW_DEVICE_EXTENSION hwDeviceExtension
)
/*++
Routine Description:
Write color palette data to Bt445's corresponding register.
Arguments:
None: All necessary data is in hwDeviceExtension.
Return Value:
None.
--*/
{
USHORT index;
//
// Update all entries by performing three writes to each location, R,G,B
//
//
// Init the Bt445 Palette Write Address register to the first
// palette location to be updated.
//
VideoDebugPrint((DBGLVL_1, "%s: Palette set %d ~ %d\n", STANDARD_DEBUG_PREFIX,
hwDeviceExtension->FirstEntry, hwDeviceExtension->LastEntry));
VideoPortWritePortUchar(hwDeviceExtension->Bt445Address+BT445_ADDRESS_REG_OFFSET,
(UCHAR)hwDeviceExtension->FirstEntry);
for (index = hwDeviceExtension->FirstEntry;
index <= hwDeviceExtension->LastEntry; index++) {
VideoPortWritePortUchar(hwDeviceExtension->Bt445Address+BT445_PRIMARY_CLUT_REG_OFFSET,
hwDeviceExtension->ColorMap[index].RgbData.Red);
VideoPortWritePortUchar(hwDeviceExtension->Bt445Address+BT445_PRIMARY_CLUT_REG_OFFSET,
hwDeviceExtension->ColorMap[index].RgbData.Green);
VideoPortWritePortUchar(hwDeviceExtension->Bt445Address+BT445_PRIMARY_CLUT_REG_OFFSET,
hwDeviceExtension->ColorMap[index].RgbData.Blue);
}
}