NT4/private/ntos/nthals/halr98mp/mips/jxdisp.c
2020-09-30 17:12:29 +02:00

3133 lines
76 KiB
C

#ident "@(#) NEC jxdisp.c 1.19 95/07/05 16:32:19"
/* #pragma comment(exestr, "@(#) NEC(MIPS) jxdisp.c 1.10 93/12/01 12:18:22" ) */
/* #pragma comment(exestr, "@(#) NEC(MIPS) jxdisp.c 1.9 93/11/19 13:48:37" ) */
/* #pragma comment(exestr, "@(#) NEC(MIPS) jxdisp.c 1.7 93/11/18 14:57:07" ) */
/*++
Copyright (c) 1991-1994 Microsoft Corporation
Module Name:
jxdisp.c
Abstract:
This module implements the HAL display initialization and output routines
for a MIPS R3000 or R4000 Jazz system.
History:
--*/
/*
* M001 1993.10.28 A. Kuriyama@oa2
*
* - Modify for R96 MIPS R4400
*
* Add : Initialize routine for Cirrus CL5428.
*
* Notes : HalpCirrusInterpretCmdStream() based on VgaInterpretCmdStream()
* in Cirrus Miniport Driver.
*
* M002 1993.11.10 M. Kusano
*
* - initialize bug fixed
*
* Add : Color palette initialize sequence.
*
* - scroll bug fixed
*
* Add : 32bit Move Memory routine.
*
* M003 1993.11.18 A. Kuriyama@oa2
*
* - Exchanged HalpMoveMemory32()
*
* Add : HalpMoveMemory32()
*
* M004 1993.11.18 M. Kusano
*
* - Modefy HalpMoveMemory32()
*
* Bug fix
*
*
* M005 1993.11.30 M.Kusano
*
* - Modefy Display Identifier
* Cirrus GD5428 -> necvdfrb
*
* #if defined(DBCS) && defined(_MIPS_)
*
* M006 1994.10.29 T.Samezima
*
* - Add display mode on vga
*
* #endif // DBCS && _MIPS_
*
* Revision History in Cirrus Miniport Driver as follows:
*
* L001 1993.10.15 Kuroki
*
* - Modify for R96 MIPS R4400 in Miniport Driver
*
* Delete : Micro channel Bus Initialize.
* VDM & Text, Fullscreen mode support.
* Banking routine.
* CL64xx Chip support.
* 16-color mode.
*
* Add : Liner Addressing.
*
***************************************************************
*
* S001 1994.06/06 T.Samezima
*
* - Modify for R98 MIPS R4400
*
* Change : memory and I/O Address
*
***********************************************************************
*
* S002 1994.6/10 T.Samezima
*
* Del Compile err
*
***************************************************************
*
* S003 1994.07/12 T.Samezima
*
* Change : I/O Address
*
*
* K000 94/10/11 N.Kugimoto
* fix 807 base
* K001 94/10/13 N.Kugimoto
* Chg resest-->reset
*
* S004 94/10/25 T.Samezima
* Add define _DUO_
*
* S005 94/11/23 T.Samezima
* Add Marge TGA(DEC21030) initialize rotine (program by T.Katoh 1994.11/15)
*
* S006 94/11/29 T.Katoh
* Bug Fix
*
* S007 94/12/07 T.Samezima
* Chg Color palet change.
*
* S008 94/12/12 T.Samezima
* Add Config read function.
* Chg Change PCI configuration read function from READ_REGISTER_ULONG
* to PciReadConfigUlong.
*
* S009 94/12/24-95/1/9 T.Samezima
* Add ESM logic.
*
* S00a 95/01/14 T.Samezima
* Chg Display string into nvram.
*
* S00b 95/03/14 T.Samezima
* Chg TGA parametor change.
* Add stall execution.
* Del Warning
* S00c 95/04/4 T.Samezima
* Chg TGA parametor change for adjust standard of VESA
* Windows-NT 3.51
* K1001 '95.7.5 N.Kugimoto
* Chg TGA parametor change for adjust standard of VESA
*
*/
#include "halp.h"
#include "jazzvdeo.h"
#include "jzvxl484.h"
#include <jaginit.h>
/* START M001 */
#include "cirrus.h"
#include "modeset.h"
#include "mode542x.h"
/* END M001 */
#include "string.h"
/* START S005 */
#include <tga.h>
/* END S005 */
#define _DUO_ // S004
//
// Put all code for HAL initialization in the INIT section. It will be
// deallocated by memory management when phase 1 initialization is
// completed.
//
#if defined(ALLOC_PRAGMA)
#pragma alloc_text(INIT, HalpInitializeDisplay0)
#pragma alloc_text(INIT, HalpInitializeDisplay1)
#endif
//
// Define forward referenced procedure prototypes.
//
VOID
HalpDisplayCharacter (
IN UCHAR Character
);
VOID
HalpOutputCharacter(
IN PUCHAR Glyph
);
VOID
HalpDisplayG300Setup (
VOID
);
VOID
HalpDisplayG364Setup (
VOID
);
VOID
HalpDisplayVxlSetup (
VOID
);
/* START M001 */
VOID
HalpDisplayCirrusSetup (
VOID
);
BOOLEAN
HalpCirrusInterpretCmdStream (
PUSHORT pusCmdStream
);
/* END M001 */
/* START M002 */
VOID
Write_Dbg_Uchar(
PUCHAR,
UCHAR
);
/* END M002 */
/* START M003 */
VOID
HalpMoveMemory32 (
PUCHAR Destination,
PUCHAR Source,
ULONG Length
);
/* END M003 */
/* START S005 */
VOID
HalpDisplayTgaSetup(
VOID
);
/* END S005 */
//
// Define virtual address of the video memory and control registers.
//
#define VIDEO_MEMORY_BASE 0x40000000
#define G300_VIDEO_CONTROL ((PG300_VIDEO_REGISTERS)0x403ff000)
#define G364_VIDEO_CONTROL ((PG364_VIDEO_REGISTERS)0x403ff000)
#define G364_VIDEO_RESET ((PVIDEO_REGISTER)0x403fe000)
//
// Define memory access constants for VXL
//
#define VXL_VIDEO_MEMORY_BASE 0x40000000
#define BT484_BASE ((PBT484_REGISTERS)0x403fd000)
#define CLOCK_BASE ((PUCHAR)0x403fe000)
#define JAGUAR_BASE ((PJAGUAR_REGISTERS)0x403ff000)
/* START M001 */
/* Start S001 */
#define CIRRUS_BASE ((PJAGUAR_REGISTERS)0x403ff000)
/* End S001 */
#define CIRRUS_OFFSET ((PUSHORT)0x3b0)
/* END M001 */
/* START S005 */
#define KSEG1_BASE 0xa0000000
#define TGA_REGISTER_BASE ((ULONG)0x403ff000) // S006
#define R98_PCI_SPACE_BASE ((ULONG)0xc0000000) // S006
#define R98_PCI1_ID ((PULONG)(0x18ca8800 | KSEG1_BASE))
#define R98_PCI1_MEM_BASE ((PULONG)(0x18ca8810 | KSEG1_BASE))
#define R98_PCI1_CS_REG ((PULONG)(0x18ca8804 | KSEG1_BASE))
#define R98_PCI2_ID ((PULONG)(0x18ca9000 | KSEG1_BASE))
#define R98_PCI2_MEM_BASE ((PULONG)(0x18ca9010 | KSEG1_BASE))
#define R98_PCI2_CS_REG ((PULONG)(0x18ca9004 | KSEG1_BASE))
#define R98_PCI3_ID ((PULONG)(0x18ca9800 | KSEG1_BASE))
#define R98_PCI3_MEM_BASE ((PULONG)(0x18ca9810 | KSEG1_BASE))
#define R98_PCI3_CS_REG ((PULONG)(0x18ca9804 | KSEG1_BASE))
/* END S005 */
//
// The three type of g364 boards we support
//
#define JAZZG364 1
#define MIPSG364 2
#define OLIVETTIG364 3
//
// Define controller setup routine type.
//
typedef
VOID
(*PHALP_CONTROLLER_SETUP) (
VOID
);
//
// Define OEM font variables.
//
ULONG HalpBytesPerRow;
ULONG HalpCharacterHeight;
ULONG HalpCharacterWidth;
ULONG HalpColumn;
ULONG HalpDisplayText;
ULONG HalpDisplayWidth;
POEM_FONT_FILE_HEADER HalpFontHeader;
ULONG HalpRow;
ULONG HalpScrollLength;
ULONG HalpScrollLine;
//
// Define display variables.
//
BOOLEAN HalpDisplayOwnedByHal;
ENTRYLO HalpDisplayPte;
ULONG HalpDisplayControlBase = 0;
ULONG HalpDisplayResetRegisterBase = 0;
ULONG HalpDisplayVxlClockRegisterBase = 0;
ULONG HalpDisplayVxlBt484RegisterBase = 0;
ULONG HalpDisplayVxlJaguarRegisterBase = 0;
PHALP_CONTROLLER_SETUP HalpDisplayControllerSetup = NULL;
MONITOR_CONFIGURATION_DATA HalpMonitorConfigurationData;
BOOLEAN HalpDisplayTypeUnknown = FALSE;
ULONG HalpG364Type = 0;
/* START M001 */
LARGE_INTEGER HalpCirrusPhigicalVideo = {0,0};
/* END M001 */
// S008 vvv
ULONG
PciReadConfigUlong(
PULONG Addr
)
{
ULONG reg;
ULONG regTmp;
ULONG returnValue;
reg = READ_REGISTER_ULONG( &( LR_CONTROL2 )->iREN );
WRITE_REGISTER_ULONG( &( LR_CONTROL2 )->iREN, (reg & 0xffbfffff));
returnValue = READ_PORT_ULONG( Addr );
regTmp = READ_REGISTER_ULONG( &( LR_CONTROL1 )->ERRS );
if( regTmp & 0x80000000 ){
WRITE_REGISTER_ULONG( &( LR_CONTROL1 )->ERRS, 0x80000000);
regTmp = READ_REGISTER_ULONG( &( LR_CONTROL2 )->iRRE );
WRITE_REGISTER_ULONG( &( LR_CONTROL2 )->iRRE, (regTmp & 0xffbfffff) );
returnValue = 0xffffffff;
}
WRITE_REGISTER_ULONG( &( LR_CONTROL2 )->iREN, reg);
return returnValue;
}
// S008 ^^^
BOOLEAN
HalpInitializeDisplay0 (
IN PLOADER_PARAMETER_BLOCK LoaderBlock
)
/*++
Routine Description:
This routine maps the video memory and control registers into the user
part of the idle process address space, initializes the video control
registers, and clears the video screen.
Arguments:
LoaderBlock - Supplies a pointer to the loader parameter block.
Return Value:
If the initialization is successfully completed, than a value of TRUE
is returned. Otherwise, a value of FALSE is returned.
--*/
{
PCONFIGURATION_COMPONENT_DATA Child;
PCONFIGURATION_COMPONENT_DATA ConfigurationEntry;
POEM_FONT_FILE_HEADER FontHeader;
ULONG Index;
ULONG MatchKey;
PMEMORY_ALLOCATION_DESCRIPTOR MemoryDescriptor;
PLIST_ENTRY NextEntry;
PENTRYLO PageFrame;
ENTRYLO Pte;
ULONG StartingPfn;
//
// Set the address of the font file header and compute display variables.
//
// N.B. The font information suppled by the OS Loader is used during phase
// 0 initialization. During phase 1 initialization, a pool buffer is
// allocated and the font information is copied from the OS Loader
// heap into pool.
//
FontHeader = (POEM_FONT_FILE_HEADER)LoaderBlock->OemFontFile;
HalpFontHeader = FontHeader;
HalpBytesPerRow = (FontHeader->PixelWidth + 7) / 8;
HalpCharacterHeight = FontHeader->PixelHeight;
HalpCharacterWidth = FontHeader->PixelWidth;
//
// Find the configuration entry for the first display controller.
//
/* START M002 */
#if defined (R96DBG)
DbgPrint("HalpInitializeDisplay0\n");
#endif
/* END M002 */
MatchKey = 0;
ConfigurationEntry = KeFindConfigurationEntry(LoaderBlock->ConfigurationRoot,
ControllerClass,
DisplayController,
&MatchKey);
/* START M002 */
#if defined (R96DBG)
DbgPrint("ConfigurationEntry Found\n");
#endif
/* END M002 */
if (ConfigurationEntry == NULL) {
/* START S005 */
MatchKey = 1;
ConfigurationEntry = KeFindConfigurationEntry(LoaderBlock->ConfigurationRoot,
ControllerClass,
DisplayController,
&MatchKey);
if (ConfigurationEntry == NULL) {
/* END S005 */
return FALSE;
/* START S005 */
}
/* END S005 */
}
//
// Determine which video controller is present in the system.
// Copy the display controller and monitor parameters in case they are
// needed later to reinitialize the display to output a message.
//
if (!strcmp(ConfigurationEntry->ComponentEntry.Identifier,
"Jazz G300")) {
HalpDisplayControllerSetup = HalpDisplayG300Setup;
HalpDisplayControlBase =
((PJAZZ_G300_CONFIGURATION_DATA)
(ConfigurationEntry->ConfigurationData))->ControlBase;
} else {
if (!strcmp(ConfigurationEntry->ComponentEntry.Identifier,
"Jazz G364")) {
HalpDisplayControllerSetup = HalpDisplayG364Setup;
HalpG364Type = JAZZG364;
HalpDisplayControlBase = 0x60080000;
// HalpDisplayControlBase =
// ((PJAZZ_G364_CONFIGURATION_DATA)
// (ConfigurationEntry->ConfigurationData))->ControlBase;
HalpDisplayResetRegisterBase = 0x60180000;
// HalpDisplayResetRegisterBase =
// ((PJAZZ_G364_CONFIGURATION_DATA)
// (ConfigurationEntry->ConfigurationData))->ResetRegister;
} else {
if (!strcmp(ConfigurationEntry->ComponentEntry.Identifier,
"Mips G364")) {
HalpDisplayControllerSetup = HalpDisplayG364Setup;
HalpG364Type = MIPSG364;
HalpDisplayControlBase = 0x60080000;
// HalpDisplayControlBase =
// ((PJAZZ_G364_CONFIGURATION_DATA)
// (ConfigurationEntry->ConfigurationData))->ControlBase;
HalpDisplayResetRegisterBase = 0x60180000;
// HalpDisplayResetRegisterBase =
// ((PJAZZ_G364_CONFIGURATION_DATA)
// (ConfigurationEntry->ConfigurationData))->ResetRegister;
} else {
if (!strcmp(ConfigurationEntry->ComponentEntry.Identifier,
"OLIVETTI_G364")) {
HalpDisplayControllerSetup = HalpDisplayG364Setup;
HalpG364Type = OLIVETTIG364;
HalpDisplayControlBase = 0x60080000;
// HalpDisplayControlBase =
// ((PJAZZ_G364_CONFIGURATION_DATA)
// (ConfigurationEntry->ConfigurationData))->ControlBase;
HalpDisplayResetRegisterBase = 0x60180000;
// HalpDisplayResetRegisterBase =
// ((PJAZZ_G364_CONFIGURATION_DATA)
// (ConfigurationEntry->ConfigurationData))->ResetRegister;
} else {
if (!strcmp(ConfigurationEntry->ComponentEntry.Identifier,
"VXL")) {
/* START M002 */
#if defined (R96DBG)
DbgPrint("VXL config found\n");
#endif
/* END M002 */
HalpDisplayControllerSetup = HalpDisplayVxlSetup;
HalpDisplayVxlBt484RegisterBase = 0x60100000;
HalpDisplayVxlClockRegisterBase = 0x60200000;
HalpDisplayVxlJaguarRegisterBase = 0x60300000;
/* START M001 */
} else {
if (!strcmp(ConfigurationEntry->ComponentEntry.Identifier,
"necvdfrb")) { /* M005 */
/* START M002 */
#if defined (R96DBG)
DbgPrint("necvdfrb Config found\n"); /* M005 */
#endif
/* END M002 */
HalpDisplayControllerSetup = HalpDisplayCirrusSetup;
/* Start S001,S003 */
HalpDisplayControlBase = 0x18cc0000;
/* End S001,S003 */
/* END M001 */
} else {
/* START S005 */
if (!strcmp(ConfigurationEntry->ComponentEntry.Identifier,
"10110004")) {
HalpDisplayControllerSetup = HalpDisplayTgaSetup;
if (PciReadConfigUlong(R98_PCI1_ID) == 0x00041011) { // S006
if ((PciReadConfigUlong(R98_PCI1_CS_REG) & 0x00000002) == 2){ // S006
HalpDisplayControlBase
= (PciReadConfigUlong(R98_PCI1_MEM_BASE) & 0xfffffff0)
| R98_PCI_SPACE_BASE // S006
+ TGA_REG_SPC_OFFSET;
} else {
return FALSE;
}
} else if (PciReadConfigUlong(R98_PCI2_ID) == 0x00041011) { // S006
if ((PciReadConfigUlong(R98_PCI2_CS_REG) & 0x00000002) == 2){ // S006
HalpDisplayControlBase
= (PciReadConfigUlong(R98_PCI2_MEM_BASE) & 0xfffffff0)
| R98_PCI_SPACE_BASE // S006
+ TGA_REG_SPC_OFFSET;
} else {
return FALSE;
}
} else if (PciReadConfigUlong(R98_PCI3_ID) == 0x00041011) { // S006
if ((PciReadConfigUlong(R98_PCI3_CS_REG) & 0x00000002) == 2){ // S006
HalpDisplayControlBase
= (PciReadConfigUlong(R98_PCI3_MEM_BASE) & 0xfffffff0)
| R98_PCI_SPACE_BASE // S006
+ TGA_REG_SPC_OFFSET;
} else {
return FALSE;
}
}
} else {
/* END S005 */
/* START M002 */
#if defined (R96DBG)
DbgPrint("DisplayTypeUnknown\n");
#endif
/* END M002 */
HalpDisplayTypeUnknown = TRUE;
/* START S005 */
}
/* END S005 */
}
/* START M001 */
}
/* END M001 */
}
}
}
}
Child = ConfigurationEntry->Child;
/* START M002 */
#if defined (R96DBG)
DbgPrint("parameters read start\n");
#endif
/* END M002 */
RtlMoveMemory((PVOID)&HalpMonitorConfigurationData,
Child->ConfigurationData,
Child->ComponentEntry.ConfigurationDataLength);
//
// Compute character output display parameters.
//
HalpDisplayText =
HalpMonitorConfigurationData.VerticalResolution / HalpCharacterHeight;
/* START M002 */
if(HalpDisplayControllerSetup == HalpDisplayCirrusSetup){
HalpScrollLine =
1024 * HalpCharacterHeight;
}else{
/* END M002 */
HalpScrollLine =
HalpMonitorConfigurationData.HorizontalResolution * HalpCharacterHeight;
/* START M002 */
}
/* END M002 */
HalpScrollLength = HalpScrollLine * (HalpDisplayText - 1);
/* START M002 */
if(HalpDisplayControllerSetup == HalpDisplayCirrusSetup){
HalpDisplayWidth =
1024 / HalpCharacterWidth;
}else{
/* END M002 */
HalpDisplayWidth =
HalpMonitorConfigurationData.HorizontalResolution / HalpCharacterWidth;
/* START M002 */
}
/* END M002 */
//
// Scan the memory allocation descriptors and allocate a free page
// to map the video memory and control registers, and initialize the
// PDE entry.
//
/* START M002 */
#if defined (R96DBG)
DbgPrint("Mem get \n");
#endif
/* END M002 */
NextEntry = LoaderBlock->MemoryDescriptorListHead.Flink;
while (NextEntry != &LoaderBlock->MemoryDescriptorListHead) {
MemoryDescriptor = CONTAINING_RECORD(NextEntry,
MEMORY_ALLOCATION_DESCRIPTOR,
ListEntry);
if ((MemoryDescriptor->MemoryType == LoaderFree) &&
(MemoryDescriptor->PageCount > 1)) {
StartingPfn = MemoryDescriptor->BasePage;
MemoryDescriptor->BasePage += 1;
MemoryDescriptor->PageCount -= 1;
break;
}
NextEntry = NextEntry->Flink;
}
ASSERT(NextEntry != &LoaderBlock->MemoryDescriptorListHead);
Pte.X1 = 0;
Pte.PFN = StartingPfn;
Pte.G = 0;
Pte.V = 1;
Pte.D = 1;
#if defined(R3000)
Pte.N = 1;
#endif
#if defined(R4000)
Pte.C = UNCACHED_POLICY;
#endif
//
// Save the page table page PTE for use in displaying information and
// map the appropriate PTE in the current page directory page to address
// the display controller page table page.
//
HalpDisplayPte = Pte;
*((PENTRYLO)(PDE_BASE |
((VIDEO_MEMORY_BASE >> (PDI_SHIFT - 2)) & 0xffc))) = Pte;
//
// Initialize the page table page.
//
PageFrame = (PENTRYLO)(PTE_BASE |
(VIDEO_MEMORY_BASE >> (PDI_SHIFT - PTI_SHIFT)));
/* START M001 */
if (HalpDisplayControllerSetup == HalpDisplayCirrusSetup) {
/* Start S001 */
HalpCirrusPhigicalVideo.HighPart = 0;
HalpCirrusPhigicalVideo.LowPart = MEM_VGA | EISA_MEMORY_PHYSICAL_BASE;
/* End S001 */
Pte.PFN = (HalpCirrusPhigicalVideo.LowPart >> PAGE_SHIFT) &
(0x7fffffff >> PAGE_SHIFT-1) |
HalpCirrusPhigicalVideo.HighPart << (32 - PAGE_SHIFT);
}
else {
/* END M001 */
/* START S005 */
if (HalpDisplayControllerSetup == HalpDisplayTgaSetup) {
Pte.PFN = (HalpDisplayControlBase - TGA_REG_SPC_OFFSET + TGA_DSP_BUF_OFFSET) >> PAGE_SHIFT;
} else {
/* END S005 */
Pte.PFN = VIDEO_MEMORY_BASE >> PAGE_SHIFT;
/* START S005 */
}
/* END S005 */
/* START M001 */
}
/* END M001 */
Pte.G = 0;
Pte.V = 1;
Pte.D = 1;
#if defined(R3000)
Pte.N = 1;
#endif
#if defined(R4000)
Pte.C = UNCACHED_POLICY;
#endif
//
// Page table entries of the video memory.
//
for (Index = 0; Index < ((PAGE_SIZE / sizeof(ENTRYLO)) - 1); Index += 1) {
*PageFrame++ = Pte;
Pte.PFN += 1;
}
if (HalpDisplayControllerSetup == HalpDisplayVxlSetup) {
//
// If this is VXL then map a page for the
// brooktree base
// Clock base
// jaguar base
//
Pte.PFN = ((ULONG)HalpDisplayVxlBt484RegisterBase) >> PAGE_SHIFT;
*(PageFrame - 2) = Pte;
Pte.PFN = ((ULONG)HalpDisplayVxlClockRegisterBase) >> PAGE_SHIFT;
*(PageFrame - 1) = Pte;
Pte.PFN = ((ULONG)HalpDisplayVxlJaguarRegisterBase) >> PAGE_SHIFT;
*PageFrame = Pte;
} else {
//
// If we have a G364, use the page before last to map the reset register.
//
if (HalpDisplayControllerSetup == HalpDisplayG364Setup) {
Pte.PFN = ((ULONG)HalpDisplayResetRegisterBase) >> PAGE_SHIFT;
*(PageFrame - 1) = Pte;
}
//
// Page table for the video registers.
//
Pte.PFN = ((ULONG)HalpDisplayControlBase) >> PAGE_SHIFT;
*PageFrame = Pte;
}
//
// Initialize the display controller.
//
HalpDisplayControllerSetup();
HalpInitDisplayStringIntoNvram(); // S009
return TRUE;
}
BOOLEAN
HalpInitializeDisplay1 (
IN PLOADER_PARAMETER_BLOCK LoaderBlock
)
/*++
Routine Description:
This routine allocates pool for the OEM font file and copies the font
information from the OS Loader heap into the allocated pool.
Arguments:
LoaderBlock - Supplies a pointer to the loader parameter block.
Return Value:
If the initialization is successfully completed, than a value of TRUE
is returned. Otherwise, a value of FALSE is returned.
--*/
{
PVOID FontHeader;
//
// Allocate a pool block and copy the OEM font information from the
// OS Loader heap into the pool block.
//
FontHeader = ExAllocatePool(NonPagedPool, HalpFontHeader->FileSize);
if (FontHeader == NULL) {
return FALSE;
}
RtlMoveMemory(FontHeader, HalpFontHeader, HalpFontHeader->FileSize);
HalpFontHeader = (POEM_FONT_FILE_HEADER)FontHeader;
HalpSetInitDisplayTimeStamp(); // S009
return TRUE;
}
VOID
HalAcquireDisplayOwnership (
IN PHAL_RESET_DISPLAY_PARAMETERS ResetDisplayParameters //K001
)
/*++
Routine Description:
This routine switches ownership of the display away from the HAL to
the system display driver. It is called when the system has reached
a point during bootstrap where it is self supporting and can output
its own messages. Once ownership has passed to the system display
driver any attempts to output messages using HalDisplayString must
result in ownership of the display reverting to the HAL and the
display hardware reinitialized for use by the HAL.
Arguments:
ResetDisplayParameters - if non-NULL the address of a function
the hal can call to reset the video card. The function returns
TRUE if the display was reset.
Return Value:
None.
--*/
{
HalpSuccessOsStartUp(); // S009
//
// Set HAL ownership of the display to false.
//
HalpDisplayOwnedByHal = FALSE;
return;
}
VOID
HalpDisplayG300Setup (
VOID
)
/*++
Routine Description:
This routine initializes the G300B display controller chip.
Arguments:
None.
Return Value:
None.
--*/
{
ULONG BackPorch;
PULONG Buffer;
ULONG DataLong;
ULONG FrontPorch;
ULONG HalfLineTime;
ULONG HalfSync;
ULONG Index;
ULONG Limit;
ULONG MultiplierValue;
ULONG ScreenUnitRate;
ULONG VerticalBlank;
ULONG ShortDisplay;
ULONG TransferDelay;
//
// Disable the G300B display controller.
//
DataLong = 0;
((PG300_VIDEO_PARAMETERS)(&DataLong))->PlainWave = 1;
WRITE_REGISTER_ULONG(&G300_VIDEO_CONTROL->Parameters.Long, DataLong);
//
// Initialize the G300B boot register value.
//
ScreenUnitRate =
(HalpMonitorConfigurationData.HorizontalDisplayTime * 1000 * 4) /
(HalpMonitorConfigurationData.HorizontalResolution);
MultiplierValue = 125000 / (ScreenUnitRate / 4);
DataLong = 0;
((PG300_VIDEO_BOOT)(&DataLong))->Multiplier = MultiplierValue;
((PG300_VIDEO_BOOT)(&DataLong))->ClockSelect = 1;
WRITE_REGISTER_ULONG(&G300_VIDEO_CONTROL->Boot.Long, DataLong);
//
// Wait for phase locked loop to stablize.
//
KeStallExecutionProcessor(50);
//
// Initialize the G300B operational values.
//
HalfSync =
(HalpMonitorConfigurationData.HorizontalSync * 1000) / ScreenUnitRate / 2;
WRITE_REGISTER_ULONG(&G300_VIDEO_CONTROL->HorizonalSync.Long, HalfSync);
BackPorch =
(HalpMonitorConfigurationData.HorizontalBackPorch * 1000) / ScreenUnitRate;
WRITE_REGISTER_ULONG(&G300_VIDEO_CONTROL->BackPorch.Long, BackPorch);
WRITE_REGISTER_ULONG(&G300_VIDEO_CONTROL->Display.Long,
HalpMonitorConfigurationData.HorizontalResolution / 4);
HalfLineTime = ((HalpMonitorConfigurationData.HorizontalSync +
HalpMonitorConfigurationData.HorizontalFrontPorch +
HalpMonitorConfigurationData.HorizontalBackPorch +
HalpMonitorConfigurationData.HorizontalDisplayTime) * 1000) / ScreenUnitRate / 2;
WRITE_REGISTER_ULONG(&G300_VIDEO_CONTROL->LineTime.Long, HalfLineTime * 2);
FrontPorch =
(HalpMonitorConfigurationData.HorizontalFrontPorch * 1000) / ScreenUnitRate;
ShortDisplay = HalfLineTime - ((HalfSync * 2) + BackPorch + FrontPorch);
WRITE_REGISTER_ULONG(&G300_VIDEO_CONTROL->ShortDisplay.Long, ShortDisplay);
WRITE_REGISTER_ULONG(&G300_VIDEO_CONTROL->BroadPulse.Long,
HalfLineTime - FrontPorch);
WRITE_REGISTER_ULONG(&G300_VIDEO_CONTROL->VerticalSync.Long,
HalpMonitorConfigurationData.VerticalSync * 2);
VerticalBlank = (HalpMonitorConfigurationData.VerticalFrontPorch +
HalpMonitorConfigurationData.VerticalBackPorch -
(HalpMonitorConfigurationData.VerticalSync * 2)) * 2;
WRITE_REGISTER_ULONG(&G300_VIDEO_CONTROL->VerticalBlank.Long,
VerticalBlank);
WRITE_REGISTER_ULONG(&G300_VIDEO_CONTROL->VerticalDisplay.Long,
HalpMonitorConfigurationData.VerticalResolution * 2);
WRITE_REGISTER_ULONG(&G300_VIDEO_CONTROL->LineStart.Long, LINE_START_VALUE);
if (BackPorch < ShortDisplay) {
TransferDelay = BackPorch - 1;
} else {
TransferDelay = ShortDisplay - 1;
}
WRITE_REGISTER_ULONG(&G300_VIDEO_CONTROL->TransferDelay.Long, TransferDelay);
WRITE_REGISTER_ULONG(&G300_VIDEO_CONTROL->DmaDisplay.Long,
1024 - TransferDelay);
WRITE_REGISTER_ULONG(&G300_VIDEO_CONTROL->PixelMask.Long, G300_PIXEL_MASK_VALUE);
//
// Initialize the G300B control parameters.
//
DataLong = 0;
((PG300_VIDEO_PARAMETERS)(&DataLong))->EnableVideo = 1;
((PG300_VIDEO_PARAMETERS)(&DataLong))->PlainWave = 1;
((PG300_VIDEO_PARAMETERS)(&DataLong))->SeparateSync = 1;
((PG300_VIDEO_PARAMETERS)(&DataLong))->DelaySync = G300_DELAY_SYNC_CYCLES;
((PG300_VIDEO_PARAMETERS)(&DataLong))->BlankOutput = 1;
((PG300_VIDEO_PARAMETERS)(&DataLong))->BitsPerPixel = EIGHT_BITS_PER_PIXEL;
((PG300_VIDEO_PARAMETERS)(&DataLong))->AddressStep = 2;
WRITE_REGISTER_ULONG(&G300_VIDEO_CONTROL->Parameters.Long, DataLong);
//
// Set up the color map for two colors.
//
WRITE_REGISTER_ULONG(&G300_VIDEO_CONTROL->ColorMapData[0], 0xffffff);
WRITE_REGISTER_ULONG(&G300_VIDEO_CONTROL->ColorMapData[1], 0x900000);
//
// Set the video memory to address color one.
//
Buffer = (PULONG)VIDEO_MEMORY_BASE;
Limit = (HalpMonitorConfigurationData.HorizontalResolution *
HalpMonitorConfigurationData.VerticalResolution) / sizeof(ULONG);
for (Index = 0; Index < Limit; Index += 1) {
*Buffer++ = 0x01010101;
}
//
// Initialize the current display column, row, and ownership values.
//
HalpColumn = 0;
HalpRow = 0;
HalpDisplayOwnedByHal = TRUE;
return;
}
VOID
HalpDisplayG364Setup(
VOID
)
/*++
Routine Description:
This routine initializes the G364 display controller chip.
Arguments:
None.
Return Value:
None.
--*/
{
ULONG videoClock;
ULONG videoPeriod;
ULONG backPorch;
ULONG dataLong;
ULONG frontPorch;
ULONG halfLineTime;
ULONG halfSync;
PULONG buffer;
ULONG index;
ULONG limit;
ULONG multiplierValue;
ULONG screenUnitRate;
ULONG shortDisplay;
ULONG transferDelay;
ULONG verticalBlank;
//
// Reset the G364 display controller.
//
WRITE_REGISTER_ULONG(&G364_VIDEO_RESET->Long,
0);
//
// Initialize the G364 boot register value.
//
if (HalpG364Type == MIPSG364) {
videoClock = 5000000;
} else {
videoClock = 8000000;
}
videoPeriod = 1000000000 / (videoClock / 1000);
screenUnitRate = (HalpMonitorConfigurationData.HorizontalDisplayTime * 1000 * 4) /
(HalpMonitorConfigurationData.HorizontalResolution);
multiplierValue = videoPeriod / (screenUnitRate / 4);
dataLong = 0;
((PG364_VIDEO_BOOT)(&dataLong))->Multiplier = multiplierValue;
((PG364_VIDEO_BOOT)(&dataLong))->ClockSelect = 1;
((PG364_VIDEO_BOOT)(&dataLong))->MicroPort64Bits = 1;
WRITE_REGISTER_ULONG(&G364_VIDEO_CONTROL->Boot.Long,
dataLong);
//
// Wait for phase locked loop to stablize.
//
KeStallExecutionProcessor(50);
//
// Initialize the G364 control parameters.
//
dataLong = 0;
((PG364_VIDEO_PARAMETERS)(&dataLong))->DelaySync = G364_DELAY_SYNC_CYCLES;
((PG364_VIDEO_PARAMETERS)(&dataLong))->BitsPerPixel = EIGHT_BITS_PER_PIXEL;
((PG364_VIDEO_PARAMETERS)(&dataLong))->AddressStep = G364_ADDRESS_STEP_INCREMENT;
((PG364_VIDEO_PARAMETERS)(&dataLong))->DisableCursor = 1;
if (HalpG364Type == OLIVETTIG364) {
//
// Initialize the G364 control parameters for VDR1 with patch for HSync
// problem during the VBlank. The control register is set to 0xB03041
// according to the hardware specs. @msu, Olivetti, 5/14/92
//
((PG364_VIDEO_PARAMETERS)(&dataLong))->VideoOnly = 1;
} else {
//
// Only set tesselated sync in non-olivetti G364 cards when
// vertical frontporch is set to 1
//
if (HalpMonitorConfigurationData.VerticalFrontPorch != 1) {
((PG364_VIDEO_PARAMETERS)(&dataLong))->PlainSync = 1;
}
}
WRITE_REGISTER_ULONG(&G364_VIDEO_CONTROL->Parameters.Long,
dataLong);
//
// Initialize the G364 operational values.
//
halfSync = (HalpMonitorConfigurationData.HorizontalSync * 1000) / screenUnitRate / 2;
WRITE_REGISTER_ULONG(&G364_VIDEO_CONTROL->HorizontalSync.Long,
halfSync);
backPorch = (HalpMonitorConfigurationData.HorizontalBackPorch * 1000) / screenUnitRate;
WRITE_REGISTER_ULONG(&G364_VIDEO_CONTROL->BackPorch.Long,
backPorch);
WRITE_REGISTER_ULONG(&G364_VIDEO_CONTROL->Display.Long,
HalpMonitorConfigurationData.HorizontalResolution / 4);
halfLineTime = ((HalpMonitorConfigurationData.HorizontalSync +
HalpMonitorConfigurationData.HorizontalFrontPorch +
HalpMonitorConfigurationData.HorizontalBackPorch +
HalpMonitorConfigurationData.HorizontalDisplayTime) * 1000) /
screenUnitRate / 2;
WRITE_REGISTER_ULONG(&G364_VIDEO_CONTROL->LineTime.Long,
halfLineTime * 2);
frontPorch = (HalpMonitorConfigurationData.HorizontalFrontPorch * 1000) /
screenUnitRate;
shortDisplay = halfLineTime - ((halfSync * 2) + backPorch + frontPorch);
WRITE_REGISTER_ULONG(&G364_VIDEO_CONTROL->ShortDisplay.Long,
shortDisplay);
if (HalpG364Type == OLIVETTIG364) {
//
// Initialize Broad Pulse, Vertical PreEqualize and Vertical
// PostEqualize registers to work with Olivetti monitors.
// @msu, Olivetti, 5/14/92
//
WRITE_REGISTER_ULONG(&G364_VIDEO_CONTROL->BroadPulse.Long,
0x30);
WRITE_REGISTER_ULONG(&G364_VIDEO_CONTROL->VerticalPreEqualize.Long,
2);
WRITE_REGISTER_ULONG(&G364_VIDEO_CONTROL->VerticalPostEqualize.Long,
2);
} else {
WRITE_REGISTER_ULONG(&G364_VIDEO_CONTROL->BroadPulse.Long,
halfLineTime - frontPorch);
// NOTE: changed the order to simplify if statement .
WRITE_REGISTER_ULONG(&G364_VIDEO_CONTROL->VerticalPreEqualize.Long,
HalpMonitorConfigurationData.VerticalFrontPorch * 2);
WRITE_REGISTER_ULONG(&G364_VIDEO_CONTROL->VerticalPostEqualize.Long,
2);
}
WRITE_REGISTER_ULONG(&G364_VIDEO_CONTROL->VerticalSync.Long,
HalpMonitorConfigurationData.VerticalSync * 2);
verticalBlank = (HalpMonitorConfigurationData.VerticalBackPorch - 1) * 2;
WRITE_REGISTER_ULONG(&G364_VIDEO_CONTROL->VerticalBlank.Long,
verticalBlank);
WRITE_REGISTER_ULONG(&G364_VIDEO_CONTROL->VerticalDisplay.Long,
HalpMonitorConfigurationData.VerticalResolution * 2);
WRITE_REGISTER_ULONG(&G364_VIDEO_CONTROL->LineStart.Long,
LINE_START_VALUE);
if (HalpG364Type == OLIVETTIG364) {
//
// Fixes for Olivetti monitors, @msu, Olivetti
//
transferDelay = 30; // @msu
} else {
if (backPorch < shortDisplay) {
transferDelay = backPorch - 1;
} else {
transferDelay = shortDisplay - 4;
}
}
WRITE_REGISTER_ULONG(&G364_VIDEO_CONTROL->TransferDelay.Long,
transferDelay);
WRITE_REGISTER_ULONG(&G364_VIDEO_CONTROL->DmaDisplay.Long,
1024 - transferDelay);
WRITE_REGISTER_ULONG(&G364_VIDEO_CONTROL->PixelMask.Long,
0xFFFFFF);
//
// Enable video
//
((PG364_VIDEO_PARAMETERS)(&dataLong))->EnableVideo = 1;
WRITE_REGISTER_ULONG(&G364_VIDEO_CONTROL->Parameters.Long,
dataLong);
//
// Set up the color map for two colors.
// NOTE: this device is not RGB but BGR.
//
WRITE_REGISTER_ULONG(&G364_VIDEO_CONTROL->ColorMapData[0], 0xffffff);
WRITE_REGISTER_ULONG(&G364_VIDEO_CONTROL->ColorMapData[1], 0x000090);
//
// Set the video memory to address color one.
//
buffer = (PULONG)VIDEO_MEMORY_BASE;
limit = (HalpMonitorConfigurationData.HorizontalResolution *
HalpMonitorConfigurationData.VerticalResolution) / sizeof(ULONG);
for (index = 0; index < limit; index += 1) {
*buffer++ = 0x01010101;
}
//
// Initialize the current display column, row, and ownership values.
//
HalpColumn = 0;
HalpRow = 0;
HalpDisplayOwnedByHal = TRUE;
return;
}
VOID
HalpDisplayVxlSetup(
VOID
)
/*++
Routine Description:
This routine initializes the JazzVxl Graphics accelerator.
Arguments:
None
Return Value:
None
--*/
{
UCHAR DataChar;
UCHAR CmdReg0;
ULONG Status;
PULONG Buffer;
LONG Limit;
LONG Index;
//
// Define clock value for the ICS part (pS)
//
LONG ClockResList[32] = { 4, 4, 4, 4, 4, 4, 4, 4,
4, 4,42918,40984,38760,36724,33523,31017,
29197,27548,24882,23491,22482,21468,20509,19920,
18692,18054,16722,15015,14773,14053,13040, 4};
JAGUAR_REG_INIT JagInitData;
LONG HorDisplayTime;
LONG HorResolutionDiv;
LONG RequestedClockPeriod;
LONG CurrentClockError;
LONG MinErrorValue;
USHORT MinErrorIndex;
LONG ShiftClockPeriod;
USHORT BoardTypeBt485;
//
// Determine if this is a Bt484 or Bt485 board. To do this write a 1 to command
// register bit 07 then write 01 to the address register 0. This will enable
// read/writes to command register 3 on a Bt485 but not on a Bt484. Clear
// Command register 3 then read it back. On a Bt485 the return value will be 0x00,
// on a Bt484 it will be 0x40.
//
// Get the value in command register 0, then set bit 07
//
DataChar = READ_REGISTER_UCHAR(&BT484_BASE->Command0.Byte);
DataChar |= 0x80;
WRITE_REGISTER_UCHAR(&BT484_BASE->Command0.Byte,DataChar);
//
// Write 0x01 to the address register
//
WRITE_REGISTER_UCHAR(&BT484_BASE->PaletteCursorWrAddress.Byte,0x01);
//
// Clear command register 3
//
WRITE_REGISTER_UCHAR(&BT484_BASE->Status.Byte,0x00);
//
// Read Command Register 3 back and compare
//
DataChar = READ_REGISTER_UCHAR(&BT484_BASE->Status.Byte);
if (DataChar != 0x00) {
//
// This is a Bt484
//
BoardTypeBt485 = 0;
JagInitData.Bt485Multiply = 0;
} else {
//
// This is a Bt485
//
BoardTypeBt485 = 1;
JagInitData.Bt485Multiply = 0;
}
//
// Calculate the requested clock frequency then find the closest match in the
// ICS clock frequency table. The requested clock frequency in picoseconds =
//
// Horizontal display time * 1000000
// ---------------------------------
// horizontal resolution
//
//
HorDisplayTime = HalpMonitorConfigurationData.HorizontalDisplayTime * 1000;
HorResolutionDiv = HalpMonitorConfigurationData.HorizontalResolution;
RequestedClockPeriod = HorDisplayTime / HorResolutionDiv;
//
// Check for a Bt485 frequency
//
if ((BoardTypeBt485 == 1) && (RequestedClockPeriod < ClockResList[30])) {
RequestedClockPeriod = RequestedClockPeriod * 2;
JagInitData.Bt485Multiply = 1;
}
MinErrorIndex = 0;
//
// Gaurentee a maximum starting error
//
MinErrorValue = RequestedClockPeriod + 1;
for (Index = 0; Index < 32; Index++) {
//
// Calculate the absolute value of clock error and find the
// closest match in the array of clock values
//
CurrentClockError = RequestedClockPeriod - ClockResList[Index];
if (CurrentClockError < 0) {
CurrentClockError *= -1;
}
if (CurrentClockError < MinErrorValue) {
MinErrorValue = CurrentClockError;
MinErrorIndex = (USHORT)Index;
}
}
//
// We now have a closest match in the clock array, now calculate the
// values for the Bt484/Bt485 register values
//
JagInitData.ClockFreq = (UCHAR)MinErrorIndex; // S002
JagInitData.BitBltControl = 1;
JagInitData.TopOfScreen = 0;
JagInitData.XferLength = 0x200;
JagInitData.VerticalInterruptLine = 4;
JagInitData.HorizontalDisplay = HalpMonitorConfigurationData.HorizontalResolution;
//
// All jaguar timing values are based on the brooktree shift clock value which
// is the clock frequency divided by 4. (period * 4) If this is a Bt485 using
// its internal 2x clock multiplier than is is period * 2; (freq * 2 / 4)
//
if (JagInitData.Bt485Multiply == 1) {
ShiftClockPeriod = ClockResList[MinErrorIndex] * 2;
} else {
ShiftClockPeriod = ClockResList[MinErrorIndex] * 4;
}
JagInitData.HorizontalBlank = (USHORT)( ((HalpMonitorConfigurationData.HorizontalBackPorch +
HalpMonitorConfigurationData.HorizontalSync +
HalpMonitorConfigurationData.HorizontalFrontPorch) * 1000)
/ ShiftClockPeriod); // S002
JagInitData.HorizontalBeginSync = (USHORT)((HalpMonitorConfigurationData.HorizontalFrontPorch * 1000)
/ ShiftClockPeriod); // S002
JagInitData.HorizontalEndSync = (USHORT)(((HalpMonitorConfigurationData.HorizontalSync +
HalpMonitorConfigurationData.HorizontalFrontPorch) * 1000)
/ ShiftClockPeriod); // S002
JagInitData.HorizontalLine = JagInitData.HorizontalBlank +
(HalpMonitorConfigurationData.HorizontalResolution / 4);
JagInitData.VerticalBlank = HalpMonitorConfigurationData.VerticalBackPorch +
HalpMonitorConfigurationData.VerticalSync +
HalpMonitorConfigurationData.VerticalFrontPorch;
JagInitData.VerticalBeginSync = HalpMonitorConfigurationData.VerticalFrontPorch;
JagInitData.VerticalEndSync = HalpMonitorConfigurationData.VerticalFrontPorch +
HalpMonitorConfigurationData.VerticalSync;
JagInitData.VerticalLine = HalpMonitorConfigurationData.VerticalBackPorch +
HalpMonitorConfigurationData.VerticalSync +
HalpMonitorConfigurationData.VerticalFrontPorch +
HalpMonitorConfigurationData.VerticalResolution;
//
// Start ICS Clock pll and stabilize.
//
WRITE_REGISTER_UCHAR(CLOCK_BASE,JagInitData.ClockFreq);
//
// Wait 10 uS for PLL clock to stabilize on the video board
//
for (Index = 0; Index < 10; Index++) {
READ_REGISTER_UCHAR(CLOCK_BASE);
}
//
// Initialize Bt484 Command Register 0 to:
//
// 8 Bit DAC Resolution
//
CmdReg0 = 0;
((PBT484_COMMAND0)(&CmdReg0))->DacResolution = 1;
((PBT484_COMMAND0)(&CmdReg0))->GreenSyncEnable = 1;
((PBT484_COMMAND0)(&CmdReg0))->SetupEnable = 1;
WRITE_REGISTER_UCHAR(&BT484_BASE->Command0.Byte,CmdReg0);
//
// Initialize Command Register 1 to:
//
DataChar = 0;
((PBT484_COMMAND1)(&DataChar))->BitsPerPixel = VXL_EIGHT_BITS_PER_PIXEL;
WRITE_REGISTER_UCHAR(&BT484_BASE->Command1.Byte,DataChar);
//
// Initialize Command Register 2 to:
//
// SCLK Enabled
// TestMode disabled
// PortselMask Non Masked
// PCLK 1
// NonInterlaced
//
DataChar = 0;
((PBT484_COMMAND2)(&DataChar))->SclkDisable = 0;
((PBT484_COMMAND2)(&DataChar))->TestEnable = 0;
((PBT484_COMMAND2)(&DataChar))->PortselMask = 1;
((PBT484_COMMAND2)(&DataChar))->PclkSelect = 1;
((PBT484_COMMAND2)(&DataChar))->InterlacedDisplay = 0;
((PBT484_COMMAND2)(&DataChar))->PaletteIndexing = CONTIGUOUS_PALETTE;
((PBT484_COMMAND2)(&DataChar))->CursorMode = BT_CURSOR_WINDOWS;
WRITE_REGISTER_UCHAR(&BT484_BASE->Command2.Byte,DataChar);
//
// if JagInitData.ClockFreq bit 8 is set then this is a Bt485 mode that requires
// the internal 2x clock multiplier to be enabled.
//
if (JagInitData.Bt485Multiply == 1) {
//
// To access cmd register 3, first set bit CR17 in command register 0
//
CmdReg0 |= 0x80;
WRITE_REGISTER_UCHAR(&BT484_BASE->Command0.Byte,CmdReg0);
//
// Write a 0x01 to Address register
//
WRITE_REGISTER_UCHAR(&BT484_BASE->PaletteCursorWrAddress.Byte,0x01);
//
// Write to cmd register 3 in the status register location. Cmd3 is initialized
// to turn on the 2x clock multiplier.
//
DataChar = 0;
((PBT484_COMMAND3)(&DataChar))->ClockMultiplier = 1;
WRITE_REGISTER_UCHAR(&BT484_BASE->Status.Byte,DataChar);
//
// Allow 10 uS for the 2x multiplier to stabilize
//
for (Index = 0; Index < 10; Index++) {
READ_REGISTER_UCHAR(CLOCK_BASE);
}
}
//
// Initialize Color Palette. Only init the first 2 entries
//
WRITE_REGISTER_UCHAR(&BT484_BASE->PaletteCursorWrAddress.Byte,0);
//
// Entry 0 red
//
WRITE_REGISTER_UCHAR(&BT484_BASE->PaletteColor.Byte,0xff);
//
// Entry 0 green
//
WRITE_REGISTER_UCHAR(&BT484_BASE->PaletteColor.Byte,0xff);
//
// Entry 0 blue
//
WRITE_REGISTER_UCHAR(&BT484_BASE->PaletteColor.Byte,0xff);
//
// Entry 1 red
//
WRITE_REGISTER_UCHAR(&BT484_BASE->PaletteColor.Byte,0x00);
//
// Entry 1 green
//
WRITE_REGISTER_UCHAR(&BT484_BASE->PaletteColor.Byte,0x00);
//
// Entry 1 blue
//
WRITE_REGISTER_UCHAR(&BT484_BASE->PaletteColor.Byte,0x90);
//
// Initialize Cursor and Overscan color.
//
// Set address pointer base.
// Zero 4 entries.
//
WRITE_REGISTER_UCHAR(&BT484_BASE->CursorColorWrAddress.Byte,0);
for (Index = 0; Index < 4*3; Index++) {
WRITE_REGISTER_UCHAR(&BT484_BASE->CursorColor.Byte,0);
}
//
// Initialize cursor RAM
//
// Set address pointer to base of ram.
// Clear both planes
//
WRITE_REGISTER_UCHAR(&BT484_BASE->PaletteCursorWrAddress.Byte,0);
for (Index = 0; Index < 256; Index++) {
WRITE_REGISTER_UCHAR(&BT484_BASE->CursorRam.Byte,0);
}
//
// Initialize cursor position registers--cursor off.
//
WRITE_REGISTER_UCHAR(&BT484_BASE->CursorXLow.Byte,0);
WRITE_REGISTER_UCHAR(&BT484_BASE->CursorXHigh.Byte,0);
WRITE_REGISTER_UCHAR(&BT484_BASE->CursorYLow.Byte,0);
WRITE_REGISTER_UCHAR(&BT484_BASE->CursorYHigh.Byte,0);
//
// Initialize pixel mask.
//
WRITE_REGISTER_UCHAR(&BT484_BASE->PixelMask.Byte,0xFF);
//
// Init Jaguar Registers
//
WRITE_REGISTER_USHORT(&JAGUAR_BASE->TopOfScreen.Short,
JagInitData.TopOfScreen);
WRITE_REGISTER_USHORT(&JAGUAR_BASE->HorizontalBlank.Short,
JagInitData.HorizontalBlank);
WRITE_REGISTER_USHORT(&JAGUAR_BASE->HorizontalBeginSync.Short,
JagInitData.HorizontalBeginSync);
WRITE_REGISTER_USHORT(&JAGUAR_BASE->HorizontalEndSync.Short,
JagInitData.HorizontalEndSync);
WRITE_REGISTER_USHORT(&JAGUAR_BASE->HorizontalLine.Short,
JagInitData.HorizontalLine);
WRITE_REGISTER_USHORT(&JAGUAR_BASE->VerticalBlank.Short,
JagInitData.VerticalBlank);
WRITE_REGISTER_USHORT(&JAGUAR_BASE->VerticalBeginSync.Short,
JagInitData.VerticalBeginSync);
WRITE_REGISTER_USHORT(&JAGUAR_BASE->VerticalEndSync.Short,
JagInitData.VerticalEndSync);
WRITE_REGISTER_USHORT(&JAGUAR_BASE->VerticalLine.Short,
JagInitData.VerticalLine);
WRITE_REGISTER_USHORT(&JAGUAR_BASE->XferLength.Short,
JagInitData.XferLength);
WRITE_REGISTER_USHORT(&JAGUAR_BASE->VerticalInterruptLine.Short,
JagInitData.VerticalInterruptLine);
WRITE_REGISTER_USHORT(&JAGUAR_BASE->HorizontalDisplay.Short,
JagInitData.HorizontalDisplay);
WRITE_REGISTER_UCHAR(&JAGUAR_BASE->BitBltControl.Byte,
JagInitData.BitBltControl);
//
// Enable timing.
//
WRITE_REGISTER_UCHAR(&JAGUAR_BASE->MonitorControl,MONITOR_TIMING_ENABLE);
//
// Set the video memory to address color one.
//
Buffer = (PULONG)VXL_VIDEO_MEMORY_BASE;
Limit = (HalpMonitorConfigurationData.HorizontalResolution *
HalpMonitorConfigurationData.VerticalResolution) / sizeof(ULONG);
for (Index = 0; Index < Limit; Index += 1) {
*Buffer++ = 0x01010101;
}
//
// Initialize the current display column, row, and ownership values.
//
HalpColumn = 0;
HalpRow = 0;
HalpDisplayOwnedByHal = TRUE;
return;
}
/* START M001 */
VOID
HalpDisplayCirrusSetup(
VOID
)
/*++
Routine Description:
This routine initializes the Cirrus VGA display controlleer.
Arguments:
None
Return Value:
None
--*/
{
PULONG Buffer;
LONG Limit;
LONG Index;
ULONG dac_address, dac_reg;
#if defined(DBCS) && defined(_MIPS_)
// M006 vvv
ULONG verticalFrequency;
ULONG horizontalTotal;
ULONG verticalTotal;
//
// Calculate vertical frequency.
//
horizontalTotal = ( HalpMonitorConfigurationData.HorizontalDisplayTime
+HalpMonitorConfigurationData.HorizontalBackPorch
+HalpMonitorConfigurationData.HorizontalFrontPorch
+HalpMonitorConfigurationData.HorizontalSync );
verticalTotal = ( HalpMonitorConfigurationData.VerticalResolution
+HalpMonitorConfigurationData.VerticalBackPorch
+HalpMonitorConfigurationData.VerticalFrontPorch
+HalpMonitorConfigurationData.VerticalSync );
verticalFrequency = 1000000000 / ( horizontalTotal * verticalTotal);
switch (HalpMonitorConfigurationData.HorizontalResolution) {
case 640:
if( verticalFrequency < 66 ) {
#if defined (R96DBG)
DbgPrint("HAL: 640x480 60Hz setup\n");
#endif
HalpCirrusInterpretCmdStream(CL542x_640x480_256_60);
HalpCirrusInterpretCmdStream(HalpCirrus_MODESET_1K_WIDE);
} else {
#if defined (R96DBG)
DbgPrint("HAL: 640x480 72Hz setup\n");
#endif
HalpCirrusInterpretCmdStream(CL542x_640x480_256_72);
HalpCirrusInterpretCmdStream(HalpCirrus_MODESET_1K_WIDE);
}
break;
case 800:
if( verticalFrequency < 58 ) {
#if defined (R96DBG)
DbgPrint("HAL: 800x600 56Hz setup\n");
#endif
HalpCirrusInterpretCmdStream(CL542x_800x600_256_56);
HalpCirrusInterpretCmdStream(HalpCirrus_MODESET_1K_WIDE);
} else if( verticalFrequency < 66 ) {
#if defined (R96DBG)
DbgPrint("HAL: 800x600 60Hz setup\n");
#endif
HalpCirrusInterpretCmdStream(CL542x_800x600_256_60);
HalpCirrusInterpretCmdStream(HalpCirrus_MODESET_1K_WIDE);
} else {
#if defined (R96DBG)
DbgPrint("HAL: 800x600 72Hz setup\n");
#endif
HalpCirrusInterpretCmdStream(CL542x_800x600_256_72);
HalpCirrusInterpretCmdStream(HalpCirrus_MODESET_1K_WIDE);
}
break;
case 1024:
// S005 vvv
if( verticalFrequency < 52 ) {
#if defined (R96DBG)
DbgPrint("HAL: 1024x768 87Hz setup\n");
#endif
HalpCirrusInterpretCmdStream(CL542x_1024x768_256_87);
HalpCirrusInterpretCmdStream(HalpCirrus_MODESET_1K_WIDE);
} else
// S005 ^^^
if( verticalFrequency < 65 ) {
#if defined (R96DBG)
DbgPrint("HAL: 1024x768 60Hz setup\n");
#endif
HalpCirrusInterpretCmdStream(CL542x_1024x768_256_60);
HalpCirrusInterpretCmdStream(HalpCirrus_MODESET_1K_WIDE);
} else if( verticalFrequency < 78 ) {
#if defined (R96DBG)
DbgPrint("HAL: 1024x768 70Hz setup\n");
#endif
HalpCirrusInterpretCmdStream(CL542x_1024x768_256_70);
HalpCirrusInterpretCmdStream(HalpCirrus_MODESET_1K_WIDE);
} else {
#if defined (R96DBG)
DbgPrint("HAL: 1024x768 87Hz setup\n");
#endif
HalpCirrusInterpretCmdStream(CL542x_1024x768_256_87);
HalpCirrusInterpretCmdStream(HalpCirrus_MODESET_1K_WIDE);
}
break;
default:
// S005 vvv
#if defined (R96DBG)
DbgPrint("HAL: 640x480 60Hz setup\n");
#endif
HalpCirrusInterpretCmdStream(CL542x_640x480_256_60);
HalpCirrusInterpretCmdStream(HalpCirrus_MODESET_1K_WIDE);
// return;
// S005 ^^^
}
// M006 ^^^
#else // defined(DBCS) && defined(_MIPS_)
switch (HalpMonitorConfigurationData.HorizontalResolution) {
case 640:
/* START M002 */
#if defined (R96DBG)
DbgPrint("640x480 setup\n");
#endif
/* END M002 */
HalpCirrusInterpretCmdStream(HalpCirrus_640x480_256);
HalpCirrusInterpretCmdStream(HalpCirrus_MODESET_1K_WIDE);
break;
case 800:
/* START M002 */
#if defined (R96DBG)
DbgPrint("800x600 setup\n");
#endif
/* END M002 */
HalpCirrusInterpretCmdStream(HalpCirrus_800x600_256);
HalpCirrusInterpretCmdStream(HalpCirrus_MODESET_1K_WIDE);
break;
case 1024:
/* START M002 */
#if defined (R96DBG)
DbgPrint("1024x768 setup\n");
#endif
/* END M002 */
HalpCirrusInterpretCmdStream(HalpCirrus_1024x768_256);
HalpCirrusInterpretCmdStream(HalpCirrus_MODESET_1K_WIDE);
break;
default:
return;
}
#endif // defined(DBCS) && defined(_MIPS_)
/* START M002 */
#if defined (R96DBG)
DbgPrint("color set\n");
#endif
dac_address = (ULONG)CIRRUS_BASE + 0x3b0 + DAC_ADDRESS_WRITE_PORT;
dac_reg = (ULONG)CIRRUS_BASE + 0x3b0 + DAC_DATA_REG_PORT;
Write_Dbg_Uchar((PUCHAR)dac_address, (UCHAR)0x0);
Write_Dbg_Uchar((PUCHAR)dac_reg, (UCHAR)0x3f);
Write_Dbg_Uchar((PUCHAR)dac_reg, (UCHAR)0x3f);
Write_Dbg_Uchar((PUCHAR)dac_reg, (UCHAR)0x3f);
Write_Dbg_Uchar((PUCHAR)dac_address, (UCHAR)0x1);
Write_Dbg_Uchar((PUCHAR)dac_reg, (UCHAR)0x00);
Write_Dbg_Uchar((PUCHAR)dac_reg, (UCHAR)0x00);
Write_Dbg_Uchar((PUCHAR)dac_reg, (UCHAR)(0x90 >> 2));
/* END M002 */
//
// Set the video memory to address color one.
//
Buffer = (PULONG)VIDEO_MEMORY_BASE;
// Limit = (HalpMonitorConfigurationData.HorizontalResolution *
// HalpMonitorConfigurationData.VerticalResolution) / sizeof(ULONG);
/* START M002 */
Limit = (1024 *
HalpMonitorConfigurationData.VerticalResolution) / sizeof(ULONG);
/* END M002 */
for (Index = 0; Index < Limit; Index += 1) {
*Buffer++ = 0x01010101;
}
//
// Initialize the current display column, row, and ownership values.
//
HalpColumn = 0;
HalpRow = 0;
HalpDisplayOwnedByHal = TRUE;
return;
}
BOOLEAN
HalpCirrusInterpretCmdStream(
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:
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.
Revision History:
--*/
{
ULONG ulCmd;
ULONG ulPort;
UCHAR jValue;
USHORT usValue;
ULONG culCount;
ULONG ulIndex;
ULONG ulBase;
if (pusCmdStream == NULL) {
return TRUE;
}
ulBase = (ULONG)CIRRUS_BASE+0x3b0;
//
// Now set the adapter to the desired mode.
//
while ((ulCmd = *pusCmdStream++) != EOD) {
//
// Determine major command type
//
switch (ulCmd & 0xF0) {
//
// Basic input/output command
//
case INOUT:
//
// Determine type of inout instruction
//
if (!(ulCmd & IO)) {
//
// Out instruction. Single or multiple outs?
//
if (!(ulCmd & MULTI)) {
//
// Single out. Byte or word out?
//
if (!(ulCmd & BW)) {
//
// Single byte out
//
ulPort = *pusCmdStream++;
jValue = (UCHAR) *pusCmdStream++;
/* START M002 */
Write_Dbg_Uchar((PUCHAR)(ulBase+ulPort),
jValue);
/* END M002 */
} else {
//
// Single word out
//
ulPort = *pusCmdStream++;
usValue = *pusCmdStream++;
/* START M002 */
Write_Dbg_Uchar((PUCHAR)(ulBase+ulPort), (UCHAR)(usValue & 0x00ff));
/* END M002 */
/* START M002 */
Write_Dbg_Uchar((PUCHAR)(ulBase+ulPort+1 ), (UCHAR)(usValue >> 8));
/* END M002 */
}
} else {
//
// Output a string of values
// Byte or word outs?
//
if (!(ulCmd & BW)) {
//
// String byte outs. Do in a loop; can't use
// VideoPortWritePortBufferUchar because the data
// is in USHORT form
//
ulPort = ulBase + *pusCmdStream++;
culCount = *pusCmdStream++;
while (culCount--) {
jValue = (UCHAR) *pusCmdStream++;
/* START M002 */
Write_Dbg_Uchar((PUCHAR)ulPort,
jValue);
/* END M002 */
}
} else {
//
// String word outs
//
ulPort = *pusCmdStream++;
culCount = *pusCmdStream++;
//
// Buffering out is not use on the Miniport Driver for R96 machine.
//
/* START L001 */
while(culCount--)
{
usValue = *pusCmdStream++;
/* START M002 */
Write_Dbg_Uchar((PUCHAR)
(ulBase + ulPort), (UCHAR) (usValue & 0x00ff));
Write_Dbg_Uchar((PUCHAR)
(ulBase + ulPort+1), (UCHAR) (usValue >> 8));
/* END M002 */
}
/* END L001 */
}
}
} else {
// In instruction
//
// Currently, string in instructions aren't supported; all
// in instructions are handled as single-byte ins
//
// Byte or word in?
//
if (!(ulCmd & BW)) {
//
// Single byte in
//
ulPort = *pusCmdStream++;
jValue = READ_REGISTER_UCHAR((PUCHAR)ulBase+ulPort);
} else {
//
// Single word in
//
ulPort = *pusCmdStream++;
usValue = READ_REGISTER_USHORT((PUSHORT)
(ulBase+ulPort));
}
}
break;
//
// Higher-level input/output commands
//
case METAOUT:
//
// Determine type of metaout command, based on minor
// command field
//
switch (ulCmd & 0x0F) {
//
// Indexed outs
//
case INDXOUT:
ulPort = ulBase + *pusCmdStream++;
culCount = *pusCmdStream++;
ulIndex = *pusCmdStream++;
while (culCount--) {
usValue = (USHORT) (ulIndex +
(((ULONG)(*pusCmdStream++)) << 8));
/* START M002 */
Write_Dbg_Uchar((PUCHAR)ulPort, (UCHAR) (usValue & 0x00ff));
/* END M002 */
/* START M002 */
Write_Dbg_Uchar((PUCHAR)ulPort+1, (UCHAR) (usValue >> 8));
/* END M002 */
ulIndex++;
}
break;
//
// Masked out (read, AND, XOR, write)
//
case MASKOUT:
ulPort = *pusCmdStream++;
jValue = READ_REGISTER_UCHAR((PUCHAR)ulBase+ulPort);
jValue &= *pusCmdStream++;
jValue ^= *pusCmdStream++;
/* START M002 */
Write_Dbg_Uchar((PUCHAR)ulBase + ulPort,
jValue);
/* END M002 */
break;
//
// Attribute Controller out
//
case ATCOUT:
ulPort = ulBase + *pusCmdStream++;
culCount = *pusCmdStream++;
ulIndex = *pusCmdStream++;
while (culCount--) {
// Write Attribute Controller index
/* START M002 */
Write_Dbg_Uchar((PUCHAR)ulPort,
(UCHAR)ulIndex);
/* END M002 */
// Write Attribute Controller data
jValue = (UCHAR) *pusCmdStream++;
/* START M002 */
Write_Dbg_Uchar((PUCHAR)ulPort, jValue);
/* END M002 */
ulIndex++;
}
break;
//
// None of the above; error
//
default:
return FALSE;
}
break;
//
// NOP
//
case NCMD:
break;
//
// Unknown command; error
//
default:
return FALSE;
}
}
return TRUE;
} // end HalpCirrusInterpretCmdStream()
/* END M001 */
/* START S005 */
VOID
HalpDisplayTgaSetup(
VOID
)
/*++
Routine Description:
This routine initializes the Tga(DEC21030) Graphics accelerator.
Arguments:
None
Return Value:
None
--*/
{
PUCHAR PLLbits;
ULONG i, j;
ULONG PLLdata;
ULONG ColorData;
PULONG Buffer;
LONG Limit;
LONG Index;
ULONG VerticalFrequency;
ULONG horizontalTotal;
ULONG verticalTotal;
// Start S006
// ULONG NowDisplayControlBase;
// PENTRYLO PageFrame;
// ENTRYLO Pte;
// End S006
// S00b vvv
const UCHAR PLLbits640x480_72[7] = { 0x80, 0x04, 0x80, 0xa4, 0x51, 0x80, 0x70 };
const UCHAR PLLbits640x480_60[7] = { 0x80, 0x04, 0x80, 0xa5, 0xc4, 0x10, 0x78 };
const UCHAR PLLbits800x600_72[7] = { 0x80, 0x08, 0x80, 0x24, 0xf1, 0x60, 0x38 }; // S00c
const UCHAR PLLbits800x600_60[7] = { 0x80, 0x04, 0x80, 0xa5, 0x78, 0x20, 0x08 };
const UCHAR PLLbits1024x768_60[7] = { 0x80, 0x00, 0x80, 0x24, 0x48, 0x20, 0x98 };
// S00b ^^^
const UCHAR Vga_Ini_ColorTable[48] =
{ VGA_INI_PALETTE_HI_WHITE_R, VGA_INI_PALETTE_HI_WHITE_G, VGA_INI_PALETTE_HI_WHITE_B, // S006, S007
VGA_INI_PALETTE_BLUE_R, VGA_INI_PALETTE_BLUE_G, VGA_INI_PALETTE_BLUE_B, // S006
VGA_INI_PALETTE_GREEN_R, VGA_INI_PALETTE_GREEN_B, VGA_INI_PALETTE_GREEN_G,
VGA_INI_PALETTE_YELLOW_R, VGA_INI_PALETTE_YELLOW_G, VGA_INI_PALETTE_YELLOW_B,
VGA_INI_PALETTE_RED_R, VGA_INI_PALETTE_RED_G, VGA_INI_PALETTE_RED_B, // S006
VGA_INI_PALETTE_MAGENTA_R, VGA_INI_PALETTE_MAGENTA_G, VGA_INI_PALETTE_MAGENTA_B,
VGA_INI_PALETTE_CYAN_R, VGA_INI_PALETTE_CYAN_G, VGA_INI_PALETTE_CYAN_B,
VGA_INI_PALETTE_BLACK_R, VGA_INI_PALETTE_BLACK_G, VGA_INI_PALETTE_BLACK_B, // S006
VGA_INI_PALETTE_WHITE_R, VGA_INI_PALETTE_WHITE_G, VGA_INI_PALETTE_WHITE_B, // S006, S007
VGA_INI_PALETTE_HI_BLUE_R, VGA_INI_PALETTE_HI_BLUE_G, VGA_INI_PALETTE_HI_BLUE_B, // S006
VGA_INI_PALETTE_HI_GREEN_R, VGA_INI_PALETTE_HI_GREEN_G, VGA_INI_PALETTE_HI_GREEN_B,
VGA_INI_PALETTE_HI_YELLOW_R, VGA_INI_PALETTE_HI_YELLOW_G, VGA_INI_PALETTE_HI_YELLOW_B,
VGA_INI_PALETTE_HI_RED_R, VGA_INI_PALETTE_HI_RED_G, VGA_INI_PALETTE_HI_RED_B, // S006
VGA_INI_PALETTE_HI_MAGENTA_R, VGA_INI_PALETTE_HI_MAGENTA_G, VGA_INI_PALETTE_HI_MAGENTA_B,
VGA_INI_PALETTE_HI_CYAN_R, VGA_INI_PALETTE_HI_CYAN_G, VGA_INI_PALETTE_HI_CYAN_B,
VGA_INI_PALETTE_HI_BLACK_R, VGA_INI_PALETTE_HI_BLACK_G, VGA_INI_PALETTE_HI_BLACK_B // S006
};
// Start S006
////
//// Check Phisical Address and reinitialize PTE
////
//
//if (READ_REGISTER_ULONG(R98_PCI1_ID) == 0x10110004) {
// NowDisplayControlBase = (READ_REGISTER_ULONG(R98_PCI1_MEM_BASE) & 0xfffffff0)
// + R98_PCI_SPACE_BASE + TGA_REG_SPC_OFFSET;
//} else if (READ_REGISTER_ULONG(R98_PCI2_ID) == 0x10110004) {
// NowDisplayControlBase = (READ_REGISTER_ULONG(R98_PCI2_MEM_BASE) & 0xfffffff0)
// + R98_PCI_SPACE_BASE + TGA_REG_SPC_OFFSET;
//} else if (READ_REGISTER_ULONG(R98_PCI3_ID) == 0x10110004) {
// NowDisplayControlBase = (READ_REGISTER_ULONG(R98_PCI3_MEM_BASE) & 0xfffffff0)
// + R98_PCI_SPACE_BASE + TGA_REG_SPC_OFFSET;
//}
//
//if (HalpDisplayControlBase != NowDisplayControlBase){
// // Called by OS, so reinitialize PTE
// HalpDisplayControlBase = NowDisplayControlBase;
//
// Pte.G = 0;
// Pte.V = 1;
// Pte.D = 1;
//
//#if defined(R3000)
// Pte.N = 1;
//#endif
//#if defined(R4000)
// Pte.C = UNCACHED_POLICY;
//#endif
// PageFrame = (PENTRYLO)(PTE_BASE | (VIDEO_MEMORY_BASE >> (PDI_SHIFT - PTI_SHIFT)));
// Pte.PFN = (HalpDisplayControlBase - TGA_REG_SPC_OFFSET + TGA_DSP_BUF_OFFSET) >> PAGE_SHIFT;
//
// for (Index = 0; Index < ((PAGE_SIZE / sizeof(ENTRYLO)) - 1); Index += 1) {
// *PageFrame++ = Pte;
// Pte.PFN += 1;
// }
//
// Pte.PFN = ((ULONG)HalpDisplayControlBase) >> PAGE_SHIFT;
// *PageFrame = Pte;
//}
// End S006
//
// Calculate vertical frequency.
//
horizontalTotal = ( HalpMonitorConfigurationData.HorizontalDisplayTime
+HalpMonitorConfigurationData.HorizontalBackPorch
+HalpMonitorConfigurationData.HorizontalFrontPorch
+HalpMonitorConfigurationData.HorizontalSync );
verticalTotal = ( HalpMonitorConfigurationData.VerticalResolution
+HalpMonitorConfigurationData.VerticalBackPorch
+HalpMonitorConfigurationData.VerticalFrontPorch
+HalpMonitorConfigurationData.VerticalSync );
VerticalFrequency = 1000000000 / ( horizontalTotal * verticalTotal);
//
// Write the PLL
//
// Select PLL Data
if( HalpMonitorConfigurationData.HorizontalResolution == 640
&& HalpMonitorConfigurationData.VerticalResolution == 480 ){
if( VerticalFrequency > 66 ){
PLLbits = (PVOID)PLLbits640x480_72; // S00b
} else {
PLLbits = (PVOID)PLLbits640x480_60; // S00b
}
} else if( HalpMonitorConfigurationData.HorizontalResolution == 800
&& HalpMonitorConfigurationData.VerticalResolution == 600 ){
if( VerticalFrequency > 66 ){
PLLbits = (PVOID)PLLbits800x600_72; // S00b
} else {
PLLbits = (PVOID)PLLbits800x600_60; // S00b
}
} else if( HalpMonitorConfigurationData.HorizontalResolution == 1024
&& HalpMonitorConfigurationData.VerticalResolution == 768 ){
PLLbits = (PVOID)PLLbits1024x768_60; // S00b
} else {
PLLbits = (PVOID)PLLbits640x480_60; // S00b
}
// Set PLL Data
for( i = 0; i <= 6; i++ ){
for( j = 0; j <= 7; j++ ){
PLLdata = (PLLbits[i] >> (7-j)) & 1;
if( i == 6 && j == 7 )
PLLdata |= 2; // Set ~HOLD bit on last write
WRITE_REGISTER_ULONG( (PULONG)(TGA_REGISTER_BASE + CLOCK), PLLdata);
}
}
// Verify 21030 is idle ( check busy bit on Command Status Register )
while( (READ_REGISTER_ULONG( (PULONG)(TGA_REGISTER_BASE + COMMAND_STATUS) ) & 1) == 1 ){ // S006
}
// Set to Deep Register
WRITE_REGISTER_ULONG( (PULONG)(TGA_REGISTER_BASE + DEEP), 0x00014000 );
// Verify 21030 is idle ( check busy bit on Command Status Register )
while( (READ_REGISTER_ULONG( (PULONG)(TGA_REGISTER_BASE + COMMAND_STATUS) ) & 1) == 1 ){ // S006
}
// Start S006
// Set to Video Base Address Register
WRITE_REGISTER_ULONG( (PULONG)(TGA_REGISTER_BASE + VIDEO_BASE), 0x00000000 );
// End S006
// Set to Plane Mask Register
WRITE_REGISTER_ULONG( (PULONG)(TGA_REGISTER_BASE + PLANE_MASK), 0xffffffff );
// Set to Pixel Mask Register
WRITE_REGISTER_ULONG( (PULONG)(TGA_REGISTER_BASE + ONE_SHOT_PIXEL_MASK), 0xffffffff );
// Set to Raster Operation
WRITE_REGISTER_ULONG( (PULONG)(TGA_REGISTER_BASE + RASTER_OP), 0x03 );
// Set to Mode Register
WRITE_REGISTER_ULONG( (PULONG)(TGA_REGISTER_BASE + MODE), 0x0000200d );
// Set to Block Color Register 0
WRITE_REGISTER_ULONG( (PULONG)(TGA_REGISTER_BASE + BLK_COLOR_R0), 0x12345678 );
// Set to Block Color Register 1
WRITE_REGISTER_ULONG( (PULONG)(TGA_REGISTER_BASE + BLK_COLOR_R1), 0x12345678 );
//
// Init. video timing registers for each resolution
//
if( HalpMonitorConfigurationData.HorizontalResolution == 640
&& HalpMonitorConfigurationData.VerticalResolution == 480 ){
if( VerticalFrequency > 66 ){
WRITE_REGISTER_ULONG( (PULONG)(TGA_REGISTER_BASE + H_CONT), 0x3c294a0 ); // K1001
WRITE_REGISTER_ULONG( (PULONG)(TGA_REGISTER_BASE + V_CONT), 0x070349e0 );
} else {
WRITE_REGISTER_ULONG( (PULONG)(TGA_REGISTER_BASE + H_CONT), 0xe64ca0 ); // K1001
WRITE_REGISTER_ULONG( (PULONG)(TGA_REGISTER_BASE + V_CONT), 0x064211e0 );
}
} else if( HalpMonitorConfigurationData.HorizontalResolution == 800
&& HalpMonitorConfigurationData.VerticalResolution == 600 ){
if( VerticalFrequency > 66 ){
WRITE_REGISTER_ULONG( (PULONG)(TGA_REGISTER_BASE + H_CONT), 0x1a7a4c8 ); // K1001
WRITE_REGISTER_ULONG( (PULONG)(TGA_REGISTER_BASE + V_CONT), 0x05c6fa58 );
} else {
WRITE_REGISTER_ULONG( (PULONG)(TGA_REGISTER_BASE + H_CONT), 0x2681cc8 ); // K1001
WRITE_REGISTER_ULONG( (PULONG)(TGA_REGISTER_BASE + V_CONT), 0x05c40a58 );
}
} else if( HalpMonitorConfigurationData.HorizontalResolution == 1024
&& HalpMonitorConfigurationData.VerticalResolution == 768 ){
//60Hz Only
WRITE_REGISTER_ULONG( (PULONG)(TGA_REGISTER_BASE + H_CONT), 0x4889300 ); // // K1001
WRITE_REGISTER_ULONG( (PULONG)(TGA_REGISTER_BASE + V_CONT), 0x07461b00 );
} else {
WRITE_REGISTER_ULONG( (PULONG)(TGA_REGISTER_BASE + H_CONT), 0xe64ca0 ); // K1001
WRITE_REGISTER_ULONG( (PULONG)(TGA_REGISTER_BASE + V_CONT), 0x064211e0 );
}
// Set to Raster Operation Register
WRITE_REGISTER_ULONG( (PULONG)(TGA_REGISTER_BASE + RASTER_OP), 0x03 );
// Set to Mode Register
WRITE_REGISTER_ULONG( (PULONG)(TGA_REGISTER_BASE + MODE), 0x00002000 );
KeStallExecutionProcessor(10000L); // S00b
// Set to Palette and DAC Setup & Data Register
WRITE_REGISTER_ULONG( (PULONG)(TGA_REGISTER_BASE + RAMDAC_SETUP), 0x0c );
WRITE_REGISTER_ULONG( (PULONG)(TGA_REGISTER_BASE + RAMDAC_DATA), 0x0ca2 );
WRITE_REGISTER_ULONG( (PULONG)(TGA_REGISTER_BASE + RAMDAC_SETUP), 0x10 );
WRITE_REGISTER_ULONG( (PULONG)(TGA_REGISTER_BASE + RAMDAC_DATA), 0x1040 );
WRITE_REGISTER_ULONG( (PULONG)(TGA_REGISTER_BASE + RAMDAC_SETUP), 0x12 );
WRITE_REGISTER_ULONG( (PULONG)(TGA_REGISTER_BASE + RAMDAC_DATA), 0x1220 );
WRITE_REGISTER_ULONG( (PULONG)(TGA_REGISTER_BASE + RAMDAC_SETUP), 0x00 );
WRITE_REGISTER_ULONG( (PULONG)(TGA_REGISTER_BASE + RAMDAC_DATA), 0x01 );
WRITE_REGISTER_ULONG( (PULONG)(TGA_REGISTER_BASE + RAMDAC_SETUP), 0x14 );
WRITE_REGISTER_ULONG( (PULONG)(TGA_REGISTER_BASE + RAMDAC_DATA), 0x1410 );
//
// set pass thru on off & on again to verify operation
//
// EEPROM Write Register
WRITE_REGISTER_ULONG( (PULONG)(TGA_REGISTER_BASE + EEPROM_WRITE), 0x00000001 );
//
// Fill palette
//
// Set to Palette and DAC Setup & Data Register
WRITE_REGISTER_ULONG( (PULONG)(TGA_REGISTER_BASE + RAMDAC_SETUP), 0x00 );
WRITE_REGISTER_ULONG( (PULONG)(TGA_REGISTER_BASE + RAMDAC_DATA), 0x00 );
WRITE_REGISTER_ULONG( (PULONG)(TGA_REGISTER_BASE + RAMDAC_SETUP), 0x02 );
for( i = 0; i < 48; i++ ){
ColorData = Vga_Ini_ColorTable[i];
ColorData |= 0x200;
WRITE_REGISTER_ULONG( (PULONG)(TGA_REGISTER_BASE + RAMDAC_DATA), ColorData );
}
for( i = 48; i < 768; i++ ){ // S006
WRITE_REGISTER_ULONG( (PULONG)(TGA_REGISTER_BASE + RAMDAC_DATA), 0x200 );
}
// Set to Video Valid Register
WRITE_REGISTER_ULONG( (PULONG)(TGA_REGISTER_BASE + VIDEO_VALID), 0x01 );
//
// Set Video Memory to address color one.
//
Buffer = (PULONG)VIDEO_MEMORY_BASE;
Limit = (HalpMonitorConfigurationData.HorizontalResolution *
HalpMonitorConfigurationData.VerticalResolution) / sizeof(ULONG);
for (Index = 0; Index < Limit; Index += 1) {
*Buffer++ = 0x01010101;
}
//
// Initialize the current display column, row, and ownership values.
//
HalpColumn = 0;
HalpRow = 0;
HalpDisplayOwnedByHal = TRUE;
return;
}
/* END S005 */
VOID
HalDisplayString (
PUCHAR String
)
/*++
Routine Description:
This routine displays a character string on the display screen.
Arguments:
String - Supplies a pointer to the characters that are to be displayed.
Return Value:
None.
--*/
{
KIRQL OldIrql;
ENTRYLO SavedPte;
// Start S006
ULONG NowDisplayControlBase;
PENTRYLO PageFrame;
ENTRYLO Pte;
LONG Index;
// End S006
//
// Raise IRQL to the highest level, acquire the display adapter spin lock,
// flush the TB, and map the display frame buffer into the address space
// of the current process.
//
/* START M002 */
#if defined (R96DBG)
DbgPrint("HalDisplayString\n");
#endif
/* END M002 */
KeRaiseIrql(HIGH_LEVEL, &OldIrql);
#if defined(_DUO_)
KiAcquireSpinLock(&HalpDisplayAdapterLock);
#endif
SavedPte = *((PENTRYLO)(PDE_BASE |
((VIDEO_MEMORY_BASE >> (PDI_SHIFT - 2)) & 0xffc)));
KeFlushCurrentTb();
*((PENTRYLO)(PDE_BASE |
((VIDEO_MEMORY_BASE >> (PDI_SHIFT - 2)) & 0xffc))) = HalpDisplayPte;
// Start S006
if (HalpDisplayControllerSetup == HalpDisplayTgaSetup) {
if (PciReadConfigUlong(R98_PCI1_ID) == 0x00041011) {
NowDisplayControlBase = (PciReadConfigUlong(R98_PCI1_MEM_BASE) & 0xfffffff0)
| R98_PCI_SPACE_BASE
+ TGA_REG_SPC_OFFSET;
} else if (PciReadConfigUlong(R98_PCI2_ID) == 0x00041011) {
NowDisplayControlBase = (PciReadConfigUlong(R98_PCI2_MEM_BASE) & 0xfffffff0)
| R98_PCI_SPACE_BASE
+ TGA_REG_SPC_OFFSET;
} else if (PciReadConfigUlong(R98_PCI3_ID) == 0x00041011) {
NowDisplayControlBase = (PciReadConfigUlong(R98_PCI3_MEM_BASE) & 0xfffffff0)
| R98_PCI_SPACE_BASE
+ TGA_REG_SPC_OFFSET;
}
if (HalpDisplayControlBase != NowDisplayControlBase){
HalpDisplayControlBase = NowDisplayControlBase;
Pte.G = 0;
Pte.V = 1;
Pte.D = 1;
#if defined(R3000)
Pte.N = 1;
#endif
#if defined(R4000)
Pte.C = UNCACHED_POLICY;
#endif
PageFrame = (PENTRYLO)(PTE_BASE | (VIDEO_MEMORY_BASE >> (PDI_SHIFT - PTI_SHIFT)));
Pte.PFN = (HalpDisplayControlBase - TGA_REG_SPC_OFFSET + TGA_DSP_BUF_OFFSET) >> PAGE_SHIFT;
for (Index = 0; Index < ((PAGE_SIZE / sizeof(ENTRYLO)) - 1); Index += 1) {
*PageFrame++ = Pte;
Pte.PFN += 1;
}
Pte.PFN = ((ULONG)HalpDisplayControlBase) >> PAGE_SHIFT;
*PageFrame = Pte;
}
}
// End S006
//
// If ownership of the display has been switched to the system display
// driver, then reinitialize the display controller and revert ownership
// to the HAL.
//
if (HalpDisplayOwnedByHal == FALSE) {
HalpDisplayControllerSetup();
HalpInitDisplayStringIntoNvram(); // S009
HalpResetX86DisplayAdapter(); //K000
}
// HalpStringIntoNvram(HalpColumn, HalpRow, String); // S009, S00a
HalStringIntoBufferStart( HalpColumn, HalpRow ); // S00a
//
// Display characters until a null byte is encountered.
//
while (*String != 0) {
HalpDisplayCharacter(*String++);
}
HalpStringBufferCopyToNvram(); // S00a
//
// Restore the previous mapping for the current process, flush the TB,
// release the display adapter spin lock, and lower IRQL to its previous
// level.
//
KeFlushCurrentTb();
*((PENTRYLO)(PDE_BASE | ((VIDEO_MEMORY_BASE >> (PDI_SHIFT - 2)) & 0xffc))) = SavedPte;
#if defined(_DUO_)
KiReleaseSpinLock(&HalpDisplayAdapterLock);
#endif
KeLowerIrql(OldIrql);
return;
}
VOID
HalpDisplayCharacter (
IN UCHAR Character
)
/*++
Routine Description:
This routine displays a character at the current x and y positions in
the frame buffer. If a newline is encounter, then the frame buffer is
scrolled. If characters extend below the end of line, then they are not
displayed.
Arguments:
Character - Supplies a character to be displayed.
Return Value:
None.
--*/
{
PUCHAR Destination;
ULONG Index;
//
// If the character is a newline, then scroll the screen up, blank the
// bottom line, and reset the x position.
//
if (Character == '\n') {
HalpColumn = 0;
if (HalpRow < (HalpDisplayText - 1)) {
HalpRow += 1;
} else {
/* START M002 */
HalpMoveMemory32((PUCHAR)VIDEO_MEMORY_BASE,
(PUCHAR)(VIDEO_MEMORY_BASE + HalpScrollLine),
HalpScrollLength);
/* END M002 */
Destination = (PUCHAR)VIDEO_MEMORY_BASE + HalpScrollLength;
for (Index = 0; Index < HalpScrollLine; Index += 1) {
*Destination++ = 1;
}
}
HalpStringBufferCopyToNvram(); // S00a
HalStringIntoBufferStart( HalpColumn, HalpRow ); // S00a
} else if (Character == '\r') {
HalpColumn = 0;
HalpStringBufferCopyToNvram(); // S00a
HalStringIntoBufferStart( HalpColumn, HalpRow ); // S00a
} else {
HalStringIntoBuffer( Character ); // S00a
if ((Character < HalpFontHeader->FirstCharacter) ||
(Character > HalpFontHeader->LastCharacter)) {
Character = HalpFontHeader->DefaultCharacter;
}
Character -= HalpFontHeader->FirstCharacter;
HalpOutputCharacter((PUCHAR)HalpFontHeader + HalpFontHeader->Map[Character].Offset);
}
return;
}
VOID
HalQueryDisplayParameters (
OUT PULONG WidthInCharacters,
OUT PULONG HeightInLines,
OUT PULONG CursorColumn,
OUT PULONG CursorRow
)
/*++
Routine Description:
This routine return information about the display area and current
cursor position.
Arguments:
WidthInCharacter - Supplies a pointer to a varible that receives
the width of the display area in characters.
HeightInLines - Supplies a pointer to a variable that receives the
height of the display area in lines.
CursorColumn - Supplies a pointer to a variable that receives the
current display column position.
CursorRow - Supplies a pointer to a variable that receives the
current display row position.
Return Value:
None.
--*/
{
//
// Set the display parameter values and return.
//
*WidthInCharacters = HalpDisplayWidth;
*HeightInLines = HalpDisplayText;
*CursorColumn = HalpColumn;
*CursorRow = HalpRow;
return;
}
VOID
HalSetDisplayParameters (
IN ULONG CursorColumn,
IN ULONG CursorRow
)
/*++
Routine Description:
This routine set the current cursor position on the display area.
Arguments:
CursorColumn - Supplies the new display column position.
CursorRow - Supplies a the new display row position.
Return Value:
None.
--*/
{
//
// Set the display parameter values and return.
//
if (CursorColumn > HalpDisplayWidth) {
CursorColumn = HalpDisplayWidth;
}
if (CursorRow > HalpDisplayText) {
CursorRow = HalpDisplayText;
}
HalpColumn = CursorColumn;
HalpRow = CursorRow;
return;
}
VOID
HalpOutputCharacter(
IN PUCHAR Glyph
)
/*++
Routine Description:
This routine insert a set of pixels into the display at the current x
cursor position. If the current x cursor position is at the end of the
line, then a newline is displayed before the specified character.
Arguments:
Character - Supplies a character to be displayed.
Return Value:
None.
--*/
{
PUCHAR Destination;
ULONG FontValue;
ULONG I;
ULONG J;
//
// If the current x cursor position is at the end of the line, then
// output a line feed before displaying the character.
//
if (HalpColumn == HalpDisplayWidth) {
HalpDisplayCharacter('\n');
}
//
// Output the specified character and update the x cursor position.
//
Destination = (PUCHAR)(VIDEO_MEMORY_BASE +
(HalpRow * HalpScrollLine) + (HalpColumn * HalpCharacterWidth));
for (I = 0; I < HalpCharacterHeight; I += 1) {
FontValue = 0;
for (J = 0; J < HalpBytesPerRow; J += 1) {
FontValue |= *(Glyph + (J * HalpCharacterHeight)) << (24 - (J * 8));
}
Glyph += 1;
for (J = 0; J < HalpCharacterWidth ; J += 1) {
*Destination++ = (UCHAR)((FontValue >> 31) ^ 1); // S002
FontValue <<= 1;
}
if(HalpDisplayControllerSetup == HalpDisplayCirrusSetup){
Destination +=
(1024 - HalpCharacterWidth);
}else{
Destination +=
(HalpMonitorConfigurationData.HorizontalResolution - HalpCharacterWidth);
}
}
HalpColumn += 1;
return;
}
/* START M002 */
VOID
Write_Dbg_Uchar(
PUCHAR Ioadress,
UCHAR Moji
)
{
#if defined (R96DBG)
DbgPrint("Disply I/O Adress %x Char %x \n",Ioadress,Moji);
#endif
WRITE_PORT_UCHAR(Ioadress,Moji);
}
/* END M002 */
/* START M003 */
VOID
HalpMoveMemory32 (
PUCHAR Destination,
PUCHAR Source,
ULONG Length
)
/*++
Routine Description:
This function moves blocks of memory.
Arguments:
Destination - Supplies a pointer to the destination address of
the move operation.
Source - Supplies a pointer to the source address of the move
operation.
Length - Supplies the length, in bytes, of the memory to be moved.
Return Value:
None.
--*/
{
UCHAR Remainder;
PUCHAR Dstend; /* M004 */
PUCHAR Srcend; /* M004 */
if ( (Source == Destination) || (Length == 0) ) { /* M004 */
return;
}
if ((Source < Destination)&((Source + Length) > Destination)) { /* M004 vvv */
if((Destination - Source) > 4){
Remainder = (UCHAR)(Length &0x03); // S002
Length = Length / 4;
Dstend = Destination + Length - 4 ;
Srcend = Source + Length -4;
for (; Length > 0; Length--) {
*(PULONG)(Dstend) = *(PULONG)(Srcend);
Dstend -= 4;
Srcend -= 4;
}
for (; Remainder > 0; Remainder--) {
*Dstend = *Srcend;
Dstend--;
Srcend--;
}
return;
}
for (; Length > 0; Length--) {
*Dstend = *Srcend;
Dstend--;
Srcend--;
}
return;
}
else {
if( (Source - Destination) > 4 ){
Remainder = (UCHAR)(Length &0x03); // S002
Length = Length / 4;
for (; Length > 0; Length--) {
*(PULONG)(Destination) = *(PULONG)(Source);
Destination += 4;
Source += 4;
}
for (; Remainder > 0; Remainder--) {
*Destination = *Source;
Destination++;
Source++;
}
return;
}
for (; Length > 0; Length--) {
*Destination = *Source;
Destination++;
Source++; /* M004 ^^^*/
}
}
}
/* END M003 */