3545 lines
103 KiB
C
3545 lines
103 KiB
C
|
/*++
|
|||
|
|
|||
|
Copyright (c) 1991-1994 Microsoft Corporation
|
|||
|
|
|||
|
Module Name:
|
|||
|
|
|||
|
jxdisp.c
|
|||
|
|
|||
|
Abstract:
|
|||
|
|
|||
|
This module implements the HAL display initialization and output routines
|
|||
|
for a MIPS R4000 or R10000 R98x system.
|
|||
|
|
|||
|
History:
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
/*
|
|||
|
* NEW CODE for R98B
|
|||
|
* 1995/09/11 K.Kitagaki
|
|||
|
*
|
|||
|
* S001 1995/11/10 T.Samezima
|
|||
|
* add x86 bios and GLiNT logic
|
|||
|
*
|
|||
|
*/
|
|||
|
|
|||
|
#include "halp.h"
|
|||
|
#include "jazzvdeo.h"
|
|||
|
#include "jzvxl484.h"
|
|||
|
#include <jaginit.h>
|
|||
|
#include "cirrus.h"
|
|||
|
#include "modeset.h"
|
|||
|
#include "mode542x.h"
|
|||
|
#include "string.h"
|
|||
|
#include <tga.h>
|
|||
|
#include <glint.h> // S001
|
|||
|
#include <rgb525.h> // S001
|
|||
|
|
|||
|
#include "pci.h"
|
|||
|
|
|||
|
//
|
|||
|
// 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
|
|||
|
|
|||
|
// S001 vvv
|
|||
|
#define _GLINT60HZ_
|
|||
|
|
|||
|
#if defined(R96DBG)
|
|||
|
#define DispDbgPrint(STRING) \
|
|||
|
DbgPrint STRING;
|
|||
|
#else
|
|||
|
#define DispDbgPrint(STRING)
|
|||
|
#endif
|
|||
|
|
|||
|
//
|
|||
|
// for x86bios emulate
|
|||
|
//
|
|||
|
PCHAR K351UseBios=NULL;
|
|||
|
|
|||
|
PHAL_RESET_DISPLAY_PARAMETERS HalpResetDisplayParameters;
|
|||
|
|
|||
|
#define TAB_SIZE 4
|
|||
|
#define TEXT_ATTR 0x1F
|
|||
|
|
|||
|
//
|
|||
|
// Define forward referenced procedure prototypes.
|
|||
|
//
|
|||
|
|
|||
|
VOID
|
|||
|
HalpDisplayINT10Setup (
|
|||
|
VOID
|
|||
|
);
|
|||
|
|
|||
|
VOID HalpOutputCharacterINT10 (
|
|||
|
IN UCHAR Character
|
|||
|
);
|
|||
|
|
|||
|
VOID HalpScrollINT10 (
|
|||
|
IN UCHAR line
|
|||
|
);
|
|||
|
|
|||
|
VOID HalpDisplayCharacterVGA (
|
|||
|
IN UCHAR Character
|
|||
|
);
|
|||
|
|
|||
|
BOOLEAN
|
|||
|
HalpInitializeX86DisplayAdapter (
|
|||
|
VOID
|
|||
|
);
|
|||
|
|
|||
|
VOID
|
|||
|
HalpDisplayCharacterOld (
|
|||
|
IN UCHAR Character
|
|||
|
);
|
|||
|
|
|||
|
VOID
|
|||
|
HalpOutputCharacterOld (
|
|||
|
IN PUCHAR Glyph
|
|||
|
);
|
|||
|
// S001 ^^^
|
|||
|
|
|||
|
VOID
|
|||
|
HalpDisplayCirrusSetup (
|
|||
|
VOID
|
|||
|
);
|
|||
|
|
|||
|
BOOLEAN
|
|||
|
HalpCirrusInterpretCmdStream (
|
|||
|
PUSHORT pusCmdStream
|
|||
|
);
|
|||
|
|
|||
|
VOID
|
|||
|
HalpDisplayTgaSetup(
|
|||
|
VOID
|
|||
|
);
|
|||
|
|
|||
|
VOID
|
|||
|
Write_Dbg_Uchar(
|
|||
|
PUCHAR,
|
|||
|
UCHAR
|
|||
|
);
|
|||
|
|
|||
|
// S001 vvv
|
|||
|
#if 0
|
|||
|
VOID
|
|||
|
RGB525_WRITE(
|
|||
|
ULONG dac,
|
|||
|
ULONG offset,
|
|||
|
UCHAR data );
|
|||
|
|
|||
|
VOID
|
|||
|
RGB525_SET_REG(
|
|||
|
ULONG dac,
|
|||
|
ULONG index,
|
|||
|
UCHAR data );
|
|||
|
#endif
|
|||
|
|
|||
|
VOID
|
|||
|
HalpDisplayGlintSetup(
|
|||
|
VOID
|
|||
|
);
|
|||
|
// S001 ^^^
|
|||
|
|
|||
|
//
|
|||
|
// Define virtual address of the video memory and control registers.
|
|||
|
//
|
|||
|
|
|||
|
#define VIDEO_MEMORY_BASE 0x40000000
|
|||
|
|
|||
|
//
|
|||
|
// Define memory access constants for VXL
|
|||
|
//
|
|||
|
|
|||
|
#define CIRRUS_BASE ((PJAGUAR_REGISTERS)(0x1c403000 | KSEG1_BASE))
|
|||
|
#define CIRRUS_OFFSET ((PUSHORT)0x3b0)
|
|||
|
#define PCI_0_IO_BASE 0x1c000000 // S001
|
|||
|
#define PCI_1_IO_BASE 0x1c400000
|
|||
|
#define CIRRUS_CONTROL_BASE_OFFSET 0x3000
|
|||
|
#define CIRRUS_MEMORY_BASE_LOW 0xa0000000
|
|||
|
|
|||
|
#define KSEG1_BASE 0xa0000000
|
|||
|
|
|||
|
#define TGA_REGISTER_BASE ((ULONG)0x403ff000)
|
|||
|
#define PONCE_ADDR_REG ((PULONG)(0x1a000008 | KSEG1_BASE))
|
|||
|
#define PONCE_DATA_REG ((PULONG)(0x1a000010 | KSEG1_BASE))
|
|||
|
#define PONCE_PERRM ((PULONG)(0x1a000810 | KSEG1_BASE))
|
|||
|
#define PONCE_PAERR ((PULONG)(0x1a000800 | KSEG1_BASE))
|
|||
|
#define PONCE_PERST ((PULONG)(0x1a000820 | KSEG1_BASE))
|
|||
|
|
|||
|
// S001 vvv
|
|||
|
#define GLINT_CONTROL_REGISTER_BASE ((ULONG)0x403ff000)
|
|||
|
#define GLINT_VIDEO_REGISTER_BASE ((ULONG)0x403fe000)
|
|||
|
#define RGB525_REGISTER_BASE ((ULONG)0x403fd000)
|
|||
|
|
|||
|
//
|
|||
|
// Define controller setup routine type.
|
|||
|
//
|
|||
|
|
|||
|
typedef
|
|||
|
VOID
|
|||
|
(*PHALP_CONTROLLER_SETUP) (
|
|||
|
VOID
|
|||
|
);
|
|||
|
|
|||
|
typedef
|
|||
|
VOID
|
|||
|
(*PHALP_DISPLAY_CHARACTER) (
|
|||
|
UCHAR
|
|||
|
);
|
|||
|
|
|||
|
typedef
|
|||
|
VOID
|
|||
|
(*PHALP_SCROLL_SCREEN) (
|
|||
|
UCHAR
|
|||
|
);
|
|||
|
|
|||
|
PHALP_DISPLAY_CHARACTER HalpDisplayCharacter = NULL;
|
|||
|
// S001 ^^^
|
|||
|
|
|||
|
//
|
|||
|
// 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;
|
|||
|
|
|||
|
ULONG HalpGlintRevisionId; // S001
|
|||
|
|
|||
|
//
|
|||
|
// Define display variables.
|
|||
|
//
|
|||
|
|
|||
|
BOOLEAN HalpDisplayOwnedByHal;
|
|||
|
ENTRYLO HalpDisplayPte;
|
|||
|
ULONG HalpDisplayControlBase = 0;
|
|||
|
ULONG HalpDisplayMemoryBase = 0;
|
|||
|
ULONG HalpDisplayResetRegisterBase = 0;
|
|||
|
PHALP_CONTROLLER_SETUP HalpDisplayControllerSetup = NULL;
|
|||
|
MONITOR_CONFIGURATION_DATA HalpMonitorConfigurationData;
|
|||
|
BOOLEAN HalpDisplayTypeUnknown = FALSE;
|
|||
|
ULONG HalpDisplayPCIDevice = FALSE;
|
|||
|
|
|||
|
LARGE_INTEGER HalpCirrusPhigicalVideo = {0,0};
|
|||
|
LARGE_INTEGER HalpTgaPhigicalVideo = {0,0};
|
|||
|
LARGE_INTEGER HalpTgaPhigicalVideoCont = {0,0};
|
|||
|
// S001 vvv
|
|||
|
LARGE_INTEGER HalpGlintPhygicalVideo = {0,0};
|
|||
|
LARGE_INTEGER HalpGlintPhygicalVideoCont = {0,0};
|
|||
|
ULONG HalpDisplayType16BPP = FALSE;
|
|||
|
// S001 ^^^
|
|||
|
|
|||
|
|
|||
|
ULONG HalpCirrusAlive=FALSE;
|
|||
|
|
|||
|
typedef struct _R94A_PCI_CONFIGURATION_ADDRESS_REG{
|
|||
|
ULONG Reserved2: 2;
|
|||
|
ULONG RegisterNumber: 6;
|
|||
|
ULONG FunctionNumber: 3;
|
|||
|
ULONG DeviceNumber: 5;
|
|||
|
ULONG BusNumber: 8;
|
|||
|
ULONG Reserved1: 7;
|
|||
|
ULONG ConfigEnable: 1;
|
|||
|
} R94A_PCI_CONFIGURATION_ADDRESS_REG, *PR94A_PCI_CONFIGURATION_ADDRESS_REG;
|
|||
|
|
|||
|
BOOLEAN
|
|||
|
HalpCheckPCIDevice (
|
|||
|
IN PCI_SLOT_NUMBER Slot
|
|||
|
);
|
|||
|
|
|||
|
volatile PULONG HalpPonceConfigAddrReg = PONCE_ADDR_REG;
|
|||
|
volatile PULONG HalpPonceConfigDataReg = PONCE_DATA_REG;
|
|||
|
volatile PULONG HalpPoncePerrm = PONCE_PERRM;
|
|||
|
volatile PULONG HalpPoncePaerr = PONCE_PAERR;
|
|||
|
volatile PULONG HalpPoncePerst = PONCE_PERST;
|
|||
|
|
|||
|
// S001 vvv
|
|||
|
VOID
|
|||
|
HalpReadPCIConfigUlongByOffset (
|
|||
|
IN PCI_SLOT_NUMBER Slot,
|
|||
|
IN PULONG Buffer,
|
|||
|
IN ULONG Offset
|
|||
|
);
|
|||
|
|
|||
|
VOID
|
|||
|
HalpWritePCIConfigUlongByOffset (
|
|||
|
IN PCI_SLOT_NUMBER Slot,
|
|||
|
IN PULONG Buffer,
|
|||
|
IN ULONG Offset
|
|||
|
);
|
|||
|
|
|||
|
VOID
|
|||
|
HalpReadPCIConfigUshortByOffset (
|
|||
|
IN PCI_SLOT_NUMBER Slot,
|
|||
|
IN PUSHORT Buffer,
|
|||
|
IN ULONG Offset
|
|||
|
);
|
|||
|
|
|||
|
VOID
|
|||
|
HalpWritePCIConfigUshortByOffset (
|
|||
|
IN PCI_SLOT_NUMBER Slot,
|
|||
|
IN PUSHORT Buffer,
|
|||
|
IN ULONG Offset
|
|||
|
);
|
|||
|
|
|||
|
VOID
|
|||
|
HalpReadPCIConfigUcharByOffset (
|
|||
|
IN PCI_SLOT_NUMBER Slot,
|
|||
|
IN PUCHAR Buffer,
|
|||
|
IN ULONG Offset
|
|||
|
);
|
|||
|
|
|||
|
VOID
|
|||
|
HalpWritePCIConfigUcharByOffset (
|
|||
|
IN PCI_SLOT_NUMBER Slot,
|
|||
|
IN PUCHAR Buffer,
|
|||
|
IN ULONG Offset
|
|||
|
);
|
|||
|
// S001 ^^^
|
|||
|
|
|||
|
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;
|
|||
|
PUCHAR Srcend;
|
|||
|
|
|||
|
if ( (Source == Destination) || (Length == 0) ) {
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
if ((Source < Destination)&((Source + Length) > Destination)) {
|
|||
|
if((Destination - Source) > 4){
|
|||
|
Remainder = (UCHAR)(Length &0x03);
|
|||
|
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);
|
|||
|
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++;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
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;
|
|||
|
PCI_SLOT_NUMBER Slot;
|
|||
|
ULONG ReadValue;
|
|||
|
PCHAR Options;
|
|||
|
|
|||
|
HalpPonceConfigAddrReg = PONCE_ADDR_REG;
|
|||
|
HalpPonceConfigDataReg = PONCE_DATA_REG;
|
|||
|
HalpPoncePerrm = PONCE_PERRM;
|
|||
|
HalpPoncePaerr = PONCE_PAERR;
|
|||
|
HalpPoncePerst = PONCE_PERST;
|
|||
|
|
|||
|
//
|
|||
|
// 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.
|
|||
|
//
|
|||
|
|
|||
|
DispDbgPrint(("Hal: HalpInitializeDisplay0\n")); // S001
|
|||
|
|
|||
|
MatchKey = 0;
|
|||
|
ConfigurationEntry = KeFindConfigurationEntry(LoaderBlock->ConfigurationRoot,
|
|||
|
ControllerClass,
|
|||
|
DisplayController,
|
|||
|
&MatchKey);
|
|||
|
|
|||
|
DispDbgPrint(("Hal: ConfigurationEntry Found\n")); // S001
|
|||
|
|
|||
|
if (ConfigurationEntry == NULL) {
|
|||
|
MatchKey = 1;
|
|||
|
ConfigurationEntry = KeFindConfigurationEntry(LoaderBlock->ConfigurationRoot,
|
|||
|
ControllerClass,
|
|||
|
DisplayController,
|
|||
|
&MatchKey);
|
|||
|
if (ConfigurationEntry == NULL) {
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// 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.
|
|||
|
//
|
|||
|
|
|||
|
// S001 vvv
|
|||
|
if (LoaderBlock->LoadOptions != NULL) {
|
|||
|
Options = LoaderBlock->LoadOptions;
|
|||
|
//
|
|||
|
// Why link error occure?
|
|||
|
// So, I change.
|
|||
|
// v-masank@microsoft.com
|
|||
|
// 5/21/96
|
|||
|
//
|
|||
|
//strupr(Options);
|
|||
|
K351UseBios = strstr(Options, "USEBIOS");
|
|||
|
}
|
|||
|
if(K351UseBios!=NULL){
|
|||
|
DispDbgPrint(("HAL: Use X86BIOS emulation\n"));
|
|||
|
|
|||
|
HalpDisplayControllerSetup = HalpDisplayINT10Setup;
|
|||
|
HalpDisplayCharacter = HalpDisplayCharacterVGA;
|
|||
|
HalpDisplayControlBase = PCI_0_IO_BASE;
|
|||
|
}else
|
|||
|
// S001 ^^^
|
|||
|
if (!strcmp(ConfigurationEntry->ComponentEntry.Identifier,
|
|||
|
"necvdfrb")) {
|
|||
|
DispDbgPrint(("necvdfrb Config found\n"));
|
|||
|
|
|||
|
HalpDisplayControllerSetup = HalpDisplayCirrusSetup;
|
|||
|
HalpCirrusAlive =TRUE;
|
|||
|
HalpDisplayCharacter = HalpDisplayCharacterOld; // S001
|
|||
|
HalpDisplayControlBase = PCI_1_IO_BASE + CIRRUS_CONTROL_BASE_OFFSET;
|
|||
|
HalpDisplayMemoryBase = CIRRUS_MEMORY_BASE_LOW;
|
|||
|
HalpDisplayPCIDevice = TRUE;
|
|||
|
|
|||
|
} else if (!strcmp(ConfigurationEntry->ComponentEntry.Identifier,"10110004")) {
|
|||
|
//
|
|||
|
// for DEC21030 PCI
|
|||
|
//
|
|||
|
DispDbgPrint(("DEC G/A found\n"));
|
|||
|
|
|||
|
HalpDisplayControllerSetup = HalpDisplayTgaSetup;
|
|||
|
HalpDisplayCharacter = HalpDisplayCharacterOld; // S001
|
|||
|
HalpDisplayPCIDevice = TRUE;
|
|||
|
|
|||
|
Slot.u.bits.FunctionNumber = 0;
|
|||
|
|
|||
|
for (Slot.u.bits.DeviceNumber = 1; Slot.u.bits.DeviceNumber < 6; Slot.u.bits.DeviceNumber++){
|
|||
|
DispDbgPrint(("DEC G/A found 2vvvv\n"));
|
|||
|
|
|||
|
HalpReadPCIConfigUlongByOffset(Slot,&ReadValue,0);
|
|||
|
|
|||
|
#if defined (DBG7)
|
|||
|
DbgPrint("DEVICE-VENDER=0x%x\n",ReadValue);
|
|||
|
#endif
|
|||
|
DispDbgPrint(("DEC G/A found 200\n"));
|
|||
|
|
|||
|
if (ReadValue == 0x00041011){
|
|||
|
HalpReadPCIConfigUlongByOffset(Slot,&ReadValue,0x4);
|
|||
|
|
|||
|
#if defined (DBG7)
|
|||
|
DbgPrint("PCI-COMMAND=0x%x\n",ReadValue);
|
|||
|
#endif
|
|||
|
|
|||
|
if ((ReadValue & 0x00000002) == 0x2){
|
|||
|
HalpReadPCIConfigUlongByOffset(Slot,&ReadValue, 0x10);
|
|||
|
#if defined (DBG7)
|
|||
|
DbgPrint("DISPLAY-MEMORY-BASE=0x%x\n",ReadValue);
|
|||
|
#endif
|
|||
|
HalpDisplayControlBase =
|
|||
|
(ReadValue & 0xfffffff0) + TGA_REG_SPC_OFFSET;
|
|||
|
HalpDisplayControlBase |= 0x40000000;
|
|||
|
#if defined (DBG7)
|
|||
|
HalpReadPCIConfigUlongByOffset(Slot,&ReadValue, 0x14);
|
|||
|
DbgPrint("DISPLAY-IO-BASE=0x%x\n",ReadValue);
|
|||
|
DbgPrint("DEC G/A HalpDisplayControlBase=0x%x\n",HalpDisplayControlBase);
|
|||
|
#endif
|
|||
|
DispDbgPrint(("DEC G/A found 2\n"));
|
|||
|
|
|||
|
} else {
|
|||
|
|
|||
|
DispDbgPrint(("DEC G/A found 2-1\n"));
|
|||
|
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
DispDbgPrint(("DEC G/A found 3-0\n"));
|
|||
|
|
|||
|
if (HalpNumberOfPonce == 2){
|
|||
|
|
|||
|
DispDbgPrint(("DEC G/A found 3\n"));
|
|||
|
|
|||
|
HalpPonceConfigAddrReg += 0x400;
|
|||
|
HalpPonceConfigDataReg += 0x400;
|
|||
|
HalpPoncePerrm += 0x400;
|
|||
|
HalpPoncePaerr += 0x400;
|
|||
|
HalpPoncePerst += 0x400;
|
|||
|
|
|||
|
for (Slot.u.bits.DeviceNumber = 5; Slot.u.bits.DeviceNumber < 7; Slot.u.bits.DeviceNumber++){
|
|||
|
HalpReadPCIConfigUlongByOffset(Slot,&ReadValue,0);
|
|||
|
|
|||
|
#if defined (DBG7)
|
|||
|
DbgPrint("DEVICE-VENDER=0x%x\n",ReadValue);
|
|||
|
#endif
|
|||
|
|
|||
|
if (ReadValue == 0x00041011){
|
|||
|
HalpReadPCIConfigUlongByOffset(Slot,&ReadValue,0x4);
|
|||
|
|
|||
|
#if defined (DBG7)
|
|||
|
DbgPrint("PCI-COMMAND=0x%x\n",ReadValue);
|
|||
|
#endif
|
|||
|
|
|||
|
if ((ReadValue & 0x00000002) == 0x2){
|
|||
|
HalpReadPCIConfigUlongByOffset(Slot,&ReadValue, 0x10);
|
|||
|
#if defined (DBG7)
|
|||
|
DbgPrint("DISPLAY-MEMORY-BASE=0x%x\n",ReadValue);
|
|||
|
#endif
|
|||
|
HalpDisplayControlBase =
|
|||
|
(ReadValue & 0xfffffff0) + TGA_REG_SPC_OFFSET;
|
|||
|
HalpDisplayControlBase |= 0x80000000;
|
|||
|
|
|||
|
#if defined (DBG7)
|
|||
|
DbgPrint("DEC G/A HalpDisplayControlBase=0x%x\n",HalpDisplayControlBase);
|
|||
|
HalpReadPCIConfigUlongByOffset(Slot,&ReadValue, 0x14);
|
|||
|
DbgPrint("DISPLAY-IO-BASE=0x%x\n",ReadValue);
|
|||
|
#endif
|
|||
|
|
|||
|
DispDbgPrint(("DEC G/A found 4\n"));
|
|||
|
|
|||
|
} else {
|
|||
|
|
|||
|
DispDbgPrint(("DEC G/A found 4-1\n"));
|
|||
|
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
} else {
|
|||
|
|
|||
|
DispDbgPrint(("DEC G/A found 5\n"));
|
|||
|
|
|||
|
HalpPonceConfigAddrReg += 0x800;
|
|||
|
HalpPonceConfigDataReg += 0x800;
|
|||
|
HalpPoncePerrm += 0x800;
|
|||
|
HalpPoncePaerr += 0x800;
|
|||
|
HalpPoncePerst += 0x800;
|
|||
|
|
|||
|
for (Slot.u.bits.DeviceNumber = 1; Slot.u.bits.DeviceNumber < 5; Slot.u.bits.DeviceNumber++){
|
|||
|
HalpReadPCIConfigUlongByOffset(Slot,&ReadValue,0);
|
|||
|
|
|||
|
if (ReadValue == 0x00041011){
|
|||
|
HalpReadPCIConfigUlongByOffset(Slot,&ReadValue,0x4);
|
|||
|
|
|||
|
if ((ReadValue & 0x00000002) == 0x2){
|
|||
|
HalpReadPCIConfigUlongByOffset(Slot,&ReadValue, 0x10);
|
|||
|
HalpDisplayControlBase =
|
|||
|
(ReadValue & 0xfffffff0) + TGA_REG_SPC_OFFSET;
|
|||
|
HalpDisplayControlBase |= 0xC0000000;
|
|||
|
} else {
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
// S001 vvv
|
|||
|
} else if (!strcmp(ConfigurationEntry->ComponentEntry.Identifier,"3D3D0001")) {
|
|||
|
|
|||
|
ULONG ponceNumber;
|
|||
|
ULONG glintFound=FALSE;
|
|||
|
|
|||
|
//
|
|||
|
// for GLINT 300SX PCI
|
|||
|
//
|
|||
|
|
|||
|
DispDbgPrint(("Hal: GLiNT config entry found\n"));
|
|||
|
|
|||
|
HalpDisplayControllerSetup = HalpDisplayGlintSetup;
|
|||
|
HalpDisplayCharacter = HalpDisplayCharacterOld;
|
|||
|
HalpDisplayPCIDevice = TRUE;
|
|||
|
HalpDisplayType16BPP = TRUE;
|
|||
|
|
|||
|
//
|
|||
|
// FunctionNumber always zero
|
|||
|
//
|
|||
|
|
|||
|
Slot.u.bits.FunctionNumber = 0;
|
|||
|
|
|||
|
for (ponceNumber = 0; ponceNumber < R98B_MAX_PONCE ; ponceNumber++) {
|
|||
|
ULONG startDevNum;
|
|||
|
ULONG endDevNum;
|
|||
|
ULONG addressOffset;
|
|||
|
|
|||
|
HalpPonceConfigAddrReg = PONCE_ADDR_REG + (ponceNumber * 0x400);
|
|||
|
HalpPonceConfigDataReg = PONCE_DATA_REG + (ponceNumber * 0x400);
|
|||
|
HalpPoncePerrm = PONCE_PERRM + (ponceNumber * 0x400);
|
|||
|
HalpPoncePaerr = PONCE_PAERR + (ponceNumber * 0x400);
|
|||
|
HalpPoncePerst = PONCE_PERST + (ponceNumber * 0x400);
|
|||
|
|
|||
|
addressOffset = (ponceNumber+1) * 0x40000000;
|
|||
|
|
|||
|
DispDbgPrint(("Hal: search GLiNT board on PONCE#%d\n", ponceNumber));
|
|||
|
|
|||
|
switch(ponceNumber){
|
|||
|
case 0:
|
|||
|
startDevNum = 2;
|
|||
|
endDevNum = 5;
|
|||
|
break;
|
|||
|
|
|||
|
case 1:
|
|||
|
if (HalpNumberOfPonce == 3) {
|
|||
|
DispDbgPrint(("Hal: Skip PONCE#1\n"));
|
|||
|
continue;
|
|||
|
}
|
|||
|
startDevNum = 3;
|
|||
|
endDevNum = 6;
|
|||
|
break;
|
|||
|
|
|||
|
case 2:
|
|||
|
if (HalpNumberOfPonce == 2) {
|
|||
|
DispDbgPrint(("Hal: Skip PONCE#2\n"));
|
|||
|
continue;
|
|||
|
}
|
|||
|
startDevNum = 1;
|
|||
|
endDevNum = 4;
|
|||
|
break;
|
|||
|
|
|||
|
default:
|
|||
|
continue;
|
|||
|
}
|
|||
|
|
|||
|
for (Slot.u.bits.DeviceNumber = startDevNum;
|
|||
|
Slot.u.bits.DeviceNumber <= endDevNum;
|
|||
|
Slot.u.bits.DeviceNumber++){
|
|||
|
HalpReadPCIConfigUlongByOffset(Slot,&ReadValue,0);
|
|||
|
|
|||
|
if (ReadValue == 0x00013d3d){
|
|||
|
HalpReadPCIConfigUlongByOffset(Slot,&ReadValue,0x4);
|
|||
|
|
|||
|
DispDbgPrint(("Hal: GLiNT found on PONCE#%d, Device=%d\n", ponceNumber,Slot.u.bits.DeviceNumber));
|
|||
|
|
|||
|
//
|
|||
|
// GLINT 300SX has no I/O space regions
|
|||
|
//
|
|||
|
|
|||
|
if (ReadValue & 0x2){
|
|||
|
|
|||
|
//
|
|||
|
// Control Registers
|
|||
|
//
|
|||
|
|
|||
|
HalpReadPCIConfigUlongByOffset(Slot,&ReadValue, 0x10);
|
|||
|
HalpDisplayControlBase = (ReadValue & 0xfffffff0);
|
|||
|
HalpDisplayControlBase |= addressOffset;
|
|||
|
|
|||
|
DispDbgPrint(("Hal: GLiNT HalpDisplayControlBase=0x%08lx\n", HalpDisplayControlBase));
|
|||
|
//
|
|||
|
// Framebuffer
|
|||
|
//
|
|||
|
|
|||
|
HalpReadPCIConfigUlongByOffset(Slot,&ReadValue, 0x18);
|
|||
|
HalpDisplayMemoryBase = (ReadValue & 0xfffffff0);
|
|||
|
HalpDisplayMemoryBase |= addressOffset;
|
|||
|
|
|||
|
DispDbgPrint(("Hal: GLiNT HalpDisplayMemoryBase=0x%08lx\n", HalpDisplayMemoryBase));
|
|||
|
//
|
|||
|
// Revision ID
|
|||
|
//
|
|||
|
|
|||
|
HalpReadPCIConfigUlongByOffset(Slot,&ReadValue, 0x08);
|
|||
|
|
|||
|
HalpGlintRevisionId = (ReadValue & 0x000000ff);
|
|||
|
|
|||
|
DispDbgPrint(("Hal: GLiNT HalpGlintRevisionId=0x%08lx\n", HalpGlintRevisionId));
|
|||
|
|
|||
|
//
|
|||
|
// Enable ROM.
|
|||
|
//
|
|||
|
|
|||
|
HalpReadPCIConfigUlongByOffset(Slot,&ReadValue, 0x30);
|
|||
|
ReadValue |= 0x1;
|
|||
|
HalpWritePCIConfigUlongByOffset(Slot,&ReadValue, 0x30);
|
|||
|
|
|||
|
glintFound = TRUE;
|
|||
|
|
|||
|
break;
|
|||
|
|
|||
|
} else {
|
|||
|
DispDbgPrint(("Hal: GLiNT have not I/O space\n"));
|
|||
|
|
|||
|
return FALSE;
|
|||
|
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if(glintFound == TRUE) {
|
|||
|
DispDbgPrint(("Hal: GLiNT adapter already found\n"));
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
} else {
|
|||
|
DispDbgPrint(("DisplayTypeUnknown\n"));
|
|||
|
|
|||
|
HalpDisplayControllerSetup = HalpDisplayINT10Setup;
|
|||
|
HalpDisplayCharacter = HalpDisplayCharacterVGA;
|
|||
|
HalpDisplayControlBase = PCI_0_IO_BASE;
|
|||
|
HalpDisplayTypeUnknown = TRUE;
|
|||
|
// S001 ^^^
|
|||
|
}
|
|||
|
|
|||
|
Child = ConfigurationEntry->Child;
|
|||
|
|
|||
|
DispDbgPrint(("Hal: parameters read start\n"));
|
|||
|
|
|||
|
RtlMoveMemory((PVOID)&HalpMonitorConfigurationData,
|
|||
|
Child->ConfigurationData,
|
|||
|
Child->ComponentEntry.ConfigurationDataLength);
|
|||
|
|
|||
|
//
|
|||
|
// Compute character output display parameters.
|
|||
|
//
|
|||
|
|
|||
|
HalpDisplayText =
|
|||
|
HalpMonitorConfigurationData.VerticalResolution / HalpCharacterHeight;
|
|||
|
|
|||
|
if(HalpDisplayControllerSetup == HalpDisplayCirrusSetup){
|
|||
|
HalpScrollLine =
|
|||
|
1024 * HalpCharacterHeight;
|
|||
|
// S001 vvv
|
|||
|
} else if (HalpDisplayType16BPP) {
|
|||
|
HalpScrollLine =
|
|||
|
HalpMonitorConfigurationData.HorizontalResolution * HalpCharacterHeight * sizeof(USHORT);
|
|||
|
// S001 ^^^
|
|||
|
} else {
|
|||
|
HalpScrollLine =
|
|||
|
HalpMonitorConfigurationData.HorizontalResolution * HalpCharacterHeight;
|
|||
|
}
|
|||
|
|
|||
|
HalpScrollLength = HalpScrollLine * (HalpDisplayText - 1);
|
|||
|
|
|||
|
if(HalpDisplayControllerSetup == HalpDisplayCirrusSetup){
|
|||
|
HalpDisplayWidth =
|
|||
|
1024 / HalpCharacterWidth;
|
|||
|
|
|||
|
}else{
|
|||
|
|
|||
|
HalpDisplayWidth =
|
|||
|
HalpMonitorConfigurationData.HorizontalResolution / HalpCharacterWidth;
|
|||
|
}
|
|||
|
|
|||
|
DispDbgPrint(("Hal: HalpDisplayText = %d\n", HalpDisplayText));
|
|||
|
DispDbgPrint(("Hal: HalpDisplayWidth = %d\n", HalpDisplayWidth));
|
|||
|
DispDbgPrint(("Hal: HalpScrollLine = %d\n", HalpScrollLine));
|
|||
|
DispDbgPrint(("Hal: HalpScrollLength = %d\n", HalpScrollLength));
|
|||
|
|
|||
|
//
|
|||
|
// Scan the memory allocation descriptors and allocate a free page
|
|||
|
// to map the video memory and control registers, and initialize the
|
|||
|
// PDE entry.
|
|||
|
//
|
|||
|
|
|||
|
DispDbgPrint(("Hal: Mem get \n"));
|
|||
|
|
|||
|
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;
|
|||
|
|
|||
|
Pte.C = UNCACHED_POLICY;
|
|||
|
|
|||
|
//
|
|||
|
// 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)));
|
|||
|
|
|||
|
// S001 vvv
|
|||
|
if (HalpDisplayControllerSetup == HalpDisplayINT10Setup) {
|
|||
|
|
|||
|
HalpCirrusPhigicalVideo.HighPart = 1;
|
|||
|
HalpCirrusPhigicalVideo.LowPart = 0x40000000;
|
|||
|
|
|||
|
Pte.PFN = (HalpCirrusPhigicalVideo.LowPart >> PAGE_SHIFT) &
|
|||
|
(0x7fffffff >> PAGE_SHIFT-1) |
|
|||
|
HalpCirrusPhigicalVideo.HighPart << (32 - PAGE_SHIFT);
|
|||
|
}else
|
|||
|
// S001 ^^^
|
|||
|
if (HalpDisplayControllerSetup == HalpDisplayCirrusSetup) {
|
|||
|
|
|||
|
HalpCirrusPhigicalVideo.HighPart = 1;
|
|||
|
HalpCirrusPhigicalVideo.LowPart = CIRRUS_MEMORY_BASE_LOW;
|
|||
|
|
|||
|
Pte.PFN = (HalpCirrusPhigicalVideo.LowPart >> PAGE_SHIFT) &
|
|||
|
(0x7fffffff >> PAGE_SHIFT-1) |
|
|||
|
HalpCirrusPhigicalVideo.HighPart << (32 - PAGE_SHIFT);
|
|||
|
} else if (HalpDisplayControllerSetup == HalpDisplayTgaSetup) {
|
|||
|
|
|||
|
HalpTgaPhigicalVideo.HighPart = 1;
|
|||
|
HalpTgaPhigicalVideo.LowPart = HalpDisplayControlBase - TGA_REG_SPC_OFFSET + TGA_DSP_BUF_OFFSET;
|
|||
|
|
|||
|
#if defined (DBG7)
|
|||
|
DbgPrint("DEC G/A HalpTgaPhigicalVideo.HighPart=0x%x\n",HalpTgaPhigicalVideo.HighPart);
|
|||
|
DbgPrint("DEC G/A HalpTgaPhigicalVideo.LowPart=0x%x\n",HalpTgaPhigicalVideo.LowPart);
|
|||
|
#endif
|
|||
|
|
|||
|
Pte.PFN = (HalpTgaPhigicalVideo.LowPart >> PAGE_SHIFT) &
|
|||
|
(0x7fffffff >> PAGE_SHIFT-1) |
|
|||
|
HalpTgaPhigicalVideo.HighPart << (32 - PAGE_SHIFT);
|
|||
|
|
|||
|
}
|
|||
|
// S001 vvv
|
|||
|
else if (HalpDisplayControllerSetup == HalpDisplayGlintSetup) { // M021
|
|||
|
|
|||
|
HalpGlintPhygicalVideo.HighPart = 1;
|
|||
|
HalpGlintPhygicalVideo.LowPart = HalpDisplayMemoryBase;
|
|||
|
|
|||
|
Pte.PFN = (HalpGlintPhygicalVideo.LowPart >> PAGE_SHIFT) &
|
|||
|
(0x7fffffff >> PAGE_SHIFT-1) |
|
|||
|
HalpGlintPhygicalVideo.HighPart << (32 - PAGE_SHIFT);
|
|||
|
}
|
|||
|
// S001 ^^^
|
|||
|
|
|||
|
Pte.G = 0;
|
|||
|
Pte.V = 1;
|
|||
|
Pte.D = 1;
|
|||
|
Pte.C = UNCACHED_POLICY;
|
|||
|
|
|||
|
//
|
|||
|
// 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 == HalpDisplayTgaSetup) {
|
|||
|
HalpTgaPhigicalVideo.HighPart = 1;
|
|||
|
HalpTgaPhigicalVideo.LowPart = HalpDisplayControlBase;
|
|||
|
Pte.PFN = (HalpDisplayControlBase >> PAGE_SHIFT) &
|
|||
|
(0x7fffffff >> PAGE_SHIFT-1) |
|
|||
|
HalpTgaPhigicalVideo.HighPart << (32 - PAGE_SHIFT);
|
|||
|
*PageFrame = Pte;
|
|||
|
|
|||
|
// S001 vvv
|
|||
|
} else if (HalpDisplayControllerSetup == HalpDisplayGlintSetup) {
|
|||
|
|
|||
|
HalpGlintPhygicalVideoCont.HighPart = 1;
|
|||
|
HalpGlintPhygicalVideoCont.LowPart = HalpDisplayControlBase;
|
|||
|
|
|||
|
//
|
|||
|
// IBM RGB525
|
|||
|
//
|
|||
|
|
|||
|
Pte.PFN = ((HalpGlintPhygicalVideoCont.LowPart + 0x4000) >> PAGE_SHIFT) &
|
|||
|
(0x7fffffff >> PAGE_SHIFT-1) |
|
|||
|
HalpGlintPhygicalVideoCont.HighPart << (32 - PAGE_SHIFT);
|
|||
|
*(PageFrame - 2) = Pte;
|
|||
|
|
|||
|
//
|
|||
|
// GLINT 300SX Internal Video Registers
|
|||
|
//
|
|||
|
|
|||
|
Pte.PFN = ((HalpGlintPhygicalVideoCont.LowPart + 0x3000) >> PAGE_SHIFT) &
|
|||
|
(0x7fffffff >> PAGE_SHIFT-1) |
|
|||
|
HalpGlintPhygicalVideoCont.HighPart << (32 - PAGE_SHIFT);
|
|||
|
*(PageFrame - 1) = Pte;
|
|||
|
|
|||
|
//
|
|||
|
// GLINT 300SX Control Status Registers
|
|||
|
//
|
|||
|
|
|||
|
Pte.PFN = (HalpGlintPhygicalVideoCont.LowPart >> PAGE_SHIFT) &
|
|||
|
(0x7fffffff >> PAGE_SHIFT-1) |
|
|||
|
HalpGlintPhygicalVideoCont.HighPart << (32 - PAGE_SHIFT);
|
|||
|
*PageFrame = Pte;
|
|||
|
|
|||
|
} else if (HalpDisplayControllerSetup == HalpDisplayINT10Setup){
|
|||
|
DispDbgPrint(("HAL: Map x86 and cirrus control register\n"));
|
|||
|
|
|||
|
Pte.PFN = ((ULONG)HalpDisplayControlBase + 0xffff) >> PAGE_SHIFT;
|
|||
|
|
|||
|
for (Index = 0; Index < (0x10000 / PAGE_SIZE ); Index++) {
|
|||
|
*PageFrame-- = Pte;
|
|||
|
DispDbgPrint(("HAL: Map index %x pfn %x\n",Index,Pte.PFN));
|
|||
|
Pte.PFN -= 1;
|
|||
|
}
|
|||
|
// S001 ^^^
|
|||
|
} else {
|
|||
|
|
|||
|
//
|
|||
|
// Page table for the video registers.
|
|||
|
//
|
|||
|
|
|||
|
Pte.PFN = ((ULONG)HalpDisplayControlBase) >> PAGE_SHIFT;
|
|||
|
*PageFrame = Pte;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Initialize the display controller.
|
|||
|
//
|
|||
|
|
|||
|
// S001 vvv
|
|||
|
if(HalpDisplayControllerSetup == HalpDisplayINT10Setup){
|
|||
|
if (HalpInitializeX86DisplayAdapter()) {
|
|||
|
// HalpDisplayControllerSetup(); // initialize twice bugbug
|
|||
|
}else{
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
}
|
|||
|
// S001 ^^^
|
|||
|
HalpDisplayControllerSetup();
|
|||
|
|
|||
|
HalpInitDisplayStringIntoNvram();
|
|||
|
|
|||
|
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();
|
|||
|
|
|||
|
return TRUE;
|
|||
|
}
|
|||
|
|
|||
|
VOID
|
|||
|
HalAcquireDisplayOwnership (
|
|||
|
IN PHAL_RESET_DISPLAY_PARAMETERS ResetDisplayParameters
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
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();
|
|||
|
|
|||
|
//
|
|||
|
// Set HAL ownership of the display to false.
|
|||
|
//
|
|||
|
|
|||
|
HalpResetDisplayParameters=ResetDisplayParameters; // S001
|
|||
|
HalpMrcModeChange((UCHAR)MRC_OP_DUMP_ONLY_NMI);
|
|||
|
HalpDisplayOwnedByHal = FALSE;
|
|||
|
|
|||
|
DispDbgPrint(("HAL: DisplayOwnedByHal = FALSE, DispResetRoutine = 0x%x\n",
|
|||
|
(ULONG)HalpResetDisplayParameters));
|
|||
|
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
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, dac_dmyread;
|
|||
|
|
|||
|
#if defined(DBCS) && defined(_MIPS_)
|
|||
|
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 ) {
|
|||
|
DispDbgPrint(("HAL: 640x480 60Hz setup\n"));
|
|||
|
HalpCirrusInterpretCmdStream(CL542x_640x480_256_60);
|
|||
|
HalpCirrusInterpretCmdStream(HalpCirrus_MODESET_1K_WIDE);
|
|||
|
} else {
|
|||
|
DispDbgPrint(("HAL: 640x480 72Hz setup\n"));
|
|||
|
HalpCirrusInterpretCmdStream(CL542x_640x480_256_72);
|
|||
|
HalpCirrusInterpretCmdStream(HalpCirrus_MODESET_1K_WIDE);
|
|||
|
}
|
|||
|
break;
|
|||
|
|
|||
|
case 800:
|
|||
|
if( verticalFrequency < 58 ) {
|
|||
|
DispDbgPrint(("HAL: 800x600 56Hz setup\n"));
|
|||
|
HalpCirrusInterpretCmdStream(CL542x_800x600_256_56);
|
|||
|
HalpCirrusInterpretCmdStream(HalpCirrus_MODESET_1K_WIDE);
|
|||
|
} else if( verticalFrequency < 66 ) {
|
|||
|
DispDbgPrint(("HAL: 800x600 60Hz setup\n"));
|
|||
|
HalpCirrusInterpretCmdStream(CL542x_800x600_256_60);
|
|||
|
HalpCirrusInterpretCmdStream(HalpCirrus_MODESET_1K_WIDE);
|
|||
|
} else {
|
|||
|
DispDbgPrint(("HAL: 800x600 72Hz setup\n"));
|
|||
|
HalpCirrusInterpretCmdStream(CL542x_800x600_256_72);
|
|||
|
HalpCirrusInterpretCmdStream(HalpCirrus_MODESET_1K_WIDE);
|
|||
|
}
|
|||
|
break;
|
|||
|
|
|||
|
case 1024:
|
|||
|
if( verticalFrequency < 52 ) {
|
|||
|
DispDbgPrint(("HAL: 1024x768 87Hz setup\n"));
|
|||
|
HalpCirrusInterpretCmdStream(CL542x_1024x768_256_87);
|
|||
|
HalpCirrusInterpretCmdStream(HalpCirrus_MODESET_1K_WIDE);
|
|||
|
} else if( verticalFrequency < 65 ) {
|
|||
|
DispDbgPrint(("HAL: 1024x768 60Hz setup\n"));
|
|||
|
HalpCirrusInterpretCmdStream(CL542x_1024x768_256_60);
|
|||
|
HalpCirrusInterpretCmdStream(HalpCirrus_MODESET_1K_WIDE);
|
|||
|
} else if( verticalFrequency < 78 ) {
|
|||
|
DispDbgPrint(("HAL: 1024x768 70Hz setup\n"));
|
|||
|
HalpCirrusInterpretCmdStream(CL542x_1024x768_256_70);
|
|||
|
HalpCirrusInterpretCmdStream(HalpCirrus_MODESET_1K_WIDE);
|
|||
|
} else {
|
|||
|
DispDbgPrint(("HAL: 1024x768 87Hz setup\n"));
|
|||
|
HalpCirrusInterpretCmdStream(CL542x_1024x768_256_87);
|
|||
|
HalpCirrusInterpretCmdStream(HalpCirrus_MODESET_1K_WIDE);
|
|||
|
}
|
|||
|
break;
|
|||
|
default:
|
|||
|
DispDbgPrint(("HAL: 640x480 60Hz setup\n"));
|
|||
|
HalpCirrusInterpretCmdStream(CL542x_640x480_256_60);
|
|||
|
HalpCirrusInterpretCmdStream(HalpCirrus_MODESET_1K_WIDE);
|
|||
|
// return;
|
|||
|
}
|
|||
|
#else // defined(DBCS) && defined(_MIPS_)
|
|||
|
|
|||
|
switch (HalpMonitorConfigurationData.HorizontalResolution) {
|
|||
|
case 640:
|
|||
|
|
|||
|
DispDbgPrint(("640x480 setup\n"));
|
|||
|
|
|||
|
HalpCirrusInterpretCmdStream(HalpCirrus_640x480_256);
|
|||
|
HalpCirrusInterpretCmdStream(HalpCirrus_MODESET_1K_WIDE);
|
|||
|
break;
|
|||
|
case 800:
|
|||
|
|
|||
|
DispDbgPrint(("800x600 setup\n"));
|
|||
|
|
|||
|
HalpCirrusInterpretCmdStream(HalpCirrus_800x600_256);
|
|||
|
HalpCirrusInterpretCmdStream(HalpCirrus_MODESET_1K_WIDE);
|
|||
|
break;
|
|||
|
case 1024:
|
|||
|
|
|||
|
DispDbgPrint(("1024x768 setup\n"));
|
|||
|
|
|||
|
HalpCirrusInterpretCmdStream(HalpCirrus_1024x768_256);
|
|||
|
HalpCirrusInterpretCmdStream(HalpCirrus_MODESET_1K_WIDE);
|
|||
|
break;
|
|||
|
default:
|
|||
|
return;
|
|||
|
}
|
|||
|
#endif // defined(DBCS) && defined(_MIPS_)
|
|||
|
|
|||
|
DispDbgPrint(("color set\n"));
|
|||
|
|
|||
|
dac_address = (ULONG)CIRRUS_BASE + 0x3b0 + DAC_ADDRESS_WRITE_PORT;
|
|||
|
dac_dmyread = (ULONG)CIRRUS_BASE + 0x3b0 + DAC_STATE_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);
|
|||
|
READ_PORT_UCHAR((PUCHAR)dac_dmyread);
|
|||
|
|
|||
|
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));
|
|||
|
READ_PORT_UCHAR((PUCHAR)dac_dmyread);
|
|||
|
|
|||
|
//
|
|||
|
// Set the video memory to address color one.
|
|||
|
//
|
|||
|
Buffer = (PULONG)VIDEO_MEMORY_BASE;
|
|||
|
Limit = (1024 *
|
|||
|
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;
|
|||
|
}
|
|||
|
|
|||
|
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++;
|
|||
|
|
|||
|
Write_Dbg_Uchar((PUCHAR)(ulBase+ulPort),
|
|||
|
jValue);
|
|||
|
|
|||
|
} else {
|
|||
|
|
|||
|
//
|
|||
|
// Single word out
|
|||
|
//
|
|||
|
|
|||
|
ulPort = *pusCmdStream++;
|
|||
|
usValue = *pusCmdStream++;
|
|||
|
|
|||
|
Write_Dbg_Uchar((PUCHAR)(ulBase+ulPort), (UCHAR)(usValue & 0x00ff));
|
|||
|
|
|||
|
Write_Dbg_Uchar((PUCHAR)(ulBase+ulPort+1 ), (UCHAR)(usValue >> 8));
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
} 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++;
|
|||
|
|
|||
|
Write_Dbg_Uchar((PUCHAR)ulPort,
|
|||
|
jValue);
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
} else {
|
|||
|
|
|||
|
//
|
|||
|
// String word outs
|
|||
|
//
|
|||
|
|
|||
|
ulPort = *pusCmdStream++;
|
|||
|
culCount = *pusCmdStream++;
|
|||
|
//
|
|||
|
// Buffering out is not use on the Miniport Driver for R96 machine.
|
|||
|
//
|
|||
|
|
|||
|
while(culCount--)
|
|||
|
{
|
|||
|
usValue = *pusCmdStream++;
|
|||
|
|
|||
|
Write_Dbg_Uchar((PUCHAR)
|
|||
|
(ulBase + ulPort), (UCHAR) (usValue & 0x00ff));
|
|||
|
Write_Dbg_Uchar((PUCHAR)
|
|||
|
(ulBase + ulPort+1), (UCHAR) (usValue >> 8));
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
} 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));
|
|||
|
|
|||
|
Write_Dbg_Uchar((PUCHAR)ulPort, (UCHAR) (usValue & 0x00ff));
|
|||
|
|
|||
|
Write_Dbg_Uchar((PUCHAR)ulPort+1, (UCHAR) (usValue >> 8));
|
|||
|
|
|||
|
ulIndex++;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
break;
|
|||
|
|
|||
|
//
|
|||
|
// Masked out (read, AND, XOR, write)
|
|||
|
//
|
|||
|
|
|||
|
case MASKOUT:
|
|||
|
|
|||
|
ulPort = *pusCmdStream++;
|
|||
|
jValue = READ_REGISTER_UCHAR((PUCHAR)ulBase+ulPort);
|
|||
|
jValue &= *pusCmdStream++;
|
|||
|
jValue ^= *pusCmdStream++;
|
|||
|
|
|||
|
Write_Dbg_Uchar((PUCHAR)ulBase + ulPort,
|
|||
|
jValue);
|
|||
|
|
|||
|
break;
|
|||
|
|
|||
|
//
|
|||
|
// Attribute Controller out
|
|||
|
//
|
|||
|
|
|||
|
case ATCOUT:
|
|||
|
|
|||
|
ulPort = ulBase + *pusCmdStream++;
|
|||
|
culCount = *pusCmdStream++;
|
|||
|
ulIndex = *pusCmdStream++;
|
|||
|
|
|||
|
while (culCount--) {
|
|||
|
|
|||
|
// Write Attribute Controller index
|
|||
|
|
|||
|
Write_Dbg_Uchar((PUCHAR)ulPort,
|
|||
|
(UCHAR)ulIndex);
|
|||
|
|
|||
|
|
|||
|
// Write Attribute Controller data
|
|||
|
jValue = (UCHAR) *pusCmdStream++;
|
|||
|
|
|||
|
Write_Dbg_Uchar((PUCHAR)ulPort, jValue);
|
|||
|
|
|||
|
ulIndex++;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
break;
|
|||
|
|
|||
|
//
|
|||
|
// None of the above; error
|
|||
|
//
|
|||
|
default:
|
|||
|
|
|||
|
return FALSE;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
break;
|
|||
|
|
|||
|
//
|
|||
|
// NOP
|
|||
|
//
|
|||
|
|
|||
|
case NCMD:
|
|||
|
|
|||
|
break;
|
|||
|
|
|||
|
//
|
|||
|
// Unknown command; error
|
|||
|
//
|
|||
|
|
|||
|
default:
|
|||
|
|
|||
|
return FALSE;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
return TRUE;
|
|||
|
|
|||
|
} // end HalpCirrusInterpretCmdStream()
|
|||
|
|
|||
|
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;
|
|||
|
|
|||
|
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 };
|
|||
|
const UCHAR PLLbits800x600_60[7] = { 0x80, 0x04, 0x80, 0xa5, 0x78, 0x20, 0x08 };
|
|||
|
const UCHAR PLLbits1024x768_60[7] = { 0x80, 0x00, 0x80, 0x24, 0x48, 0x20, 0x98 };
|
|||
|
|
|||
|
const UCHAR Vga_Ini_ColorTable[48] =
|
|||
|
{ VGA_INI_PALETTE_HI_WHITE_R, VGA_INI_PALETTE_HI_WHITE_G, VGA_INI_PALETTE_HI_WHITE_B,
|
|||
|
VGA_INI_PALETTE_BLUE_R, VGA_INI_PALETTE_BLUE_G, VGA_INI_PALETTE_BLUE_B,
|
|||
|
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,
|
|||
|
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,
|
|||
|
VGA_INI_PALETTE_WHITE_R, VGA_INI_PALETTE_WHITE_G, VGA_INI_PALETTE_WHITE_B,
|
|||
|
VGA_INI_PALETTE_HI_BLUE_R, VGA_INI_PALETTE_HI_BLUE_G, VGA_INI_PALETTE_HI_BLUE_B,
|
|||
|
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,
|
|||
|
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
|
|||
|
};
|
|||
|
|
|||
|
DispDbgPrint(("TGA Set Up IN\n"));
|
|||
|
|
|||
|
//
|
|||
|
// 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;
|
|||
|
} else {
|
|||
|
PLLbits = (PVOID)PLLbits640x480_60;
|
|||
|
}
|
|||
|
} else if( HalpMonitorConfigurationData.HorizontalResolution == 800
|
|||
|
&& HalpMonitorConfigurationData.VerticalResolution == 600 ){
|
|||
|
if( VerticalFrequency > 66 ){
|
|||
|
PLLbits = (PVOID)PLLbits800x600_72;
|
|||
|
} else {
|
|||
|
PLLbits = (PVOID)PLLbits800x600_60;
|
|||
|
}
|
|||
|
} else if( HalpMonitorConfigurationData.HorizontalResolution == 1024
|
|||
|
&& HalpMonitorConfigurationData.VerticalResolution == 768 ){
|
|||
|
PLLbits = (PVOID)PLLbits1024x768_60;
|
|||
|
} else {
|
|||
|
PLLbits = (PVOID)PLLbits640x480_60;
|
|||
|
}
|
|||
|
|
|||
|
// 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);
|
|||
|
}
|
|||
|
}
|
|||
|
#if defined (DBG7)
|
|||
|
DbgPrint("TGA Set Up 1\n");
|
|||
|
|
|||
|
DbgPrint("TGA_REGISTER_BASE=0x%x\n",TGA_REGISTER_BASE);
|
|||
|
DbgPrint("COMMAND_STATUS=0x%x\n",COMMAND_STATUS);
|
|||
|
DbgPrint("TGA_REGISTER_BASE + COMMAND_STATUS=0x%x\n",(READ_REGISTER_ULONG( (PULONG)(TGA_REGISTER_BASE + COMMAND_STATUS) )));
|
|||
|
#endif
|
|||
|
|
|||
|
// Verify 21030 is idle ( check busy bit on Command Status Register )
|
|||
|
while( (READ_REGISTER_ULONG( (PULONG)(TGA_REGISTER_BASE + COMMAND_STATUS) ) & 1) == 1 ){
|
|||
|
}
|
|||
|
#if defined (DBG7)
|
|||
|
DbgPrint("TGA Set Up 2\n");
|
|||
|
#endif
|
|||
|
|
|||
|
// 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 ){
|
|||
|
}
|
|||
|
#if defined (DBG7)
|
|||
|
DbgPrint("TGA Set Up 3\n");
|
|||
|
#endif
|
|||
|
|
|||
|
// Set to Video Base Address Register
|
|||
|
WRITE_REGISTER_ULONG( (PULONG)(TGA_REGISTER_BASE + VIDEO_BASE), 0x00000000 );
|
|||
|
|
|||
|
// 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 );
|
|||
|
#if defined (DBG7)
|
|||
|
DbgPrint("TGA Set Up 4\n");
|
|||
|
#endif
|
|||
|
|
|||
|
KeStallExecutionProcessor(10000L);
|
|||
|
#if defined (DBG7)
|
|||
|
DbgPrint("TGA Set Up 5\n");
|
|||
|
#endif
|
|||
|
|
|||
|
// 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++ ){
|
|||
|
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;
|
|||
|
#if defined (DBG7)
|
|||
|
DbgPrint("TGA Set Up End\n");
|
|||
|
#endif
|
|||
|
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
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;
|
|||
|
ULONG NowDisplayControlBase;
|
|||
|
ULONG NowDisplayMemoryBase;
|
|||
|
PENTRYLO PageFrame;
|
|||
|
ENTRYLO Pte;
|
|||
|
LONG Index;
|
|||
|
PCI_SLOT_NUMBER Slot;
|
|||
|
ULONG ReadValue;
|
|||
|
ULONG cpu;
|
|||
|
|
|||
|
//
|
|||
|
// 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.
|
|||
|
//
|
|||
|
|
|||
|
// DispDbgPrint(("HalDisplayString\n"));
|
|||
|
|
|||
|
KeRaiseIrql(HIGH_LEVEL, &OldIrql);
|
|||
|
|
|||
|
KiAcquireSpinLock(&HalpDisplayAdapterLock);
|
|||
|
|
|||
|
// S001 vvv
|
|||
|
HalpPonceConfigAddrReg = PONCE_ADDR_REG;
|
|||
|
HalpPonceConfigDataReg = PONCE_DATA_REG;
|
|||
|
HalpPoncePerrm = PONCE_PERRM;
|
|||
|
HalpPoncePaerr = PONCE_PAERR;
|
|||
|
HalpPoncePerst = PONCE_PERST;
|
|||
|
// S001 ^^^
|
|||
|
|
|||
|
SavedPte = *((PENTRYLO)(PDE_BASE |
|
|||
|
((VIDEO_MEMORY_BASE >> (PDI_SHIFT - 2)) & 0xffc)));
|
|||
|
|
|||
|
KeFlushCurrentTb();
|
|||
|
*((PENTRYLO)(PDE_BASE |
|
|||
|
((VIDEO_MEMORY_BASE >> (PDI_SHIFT - 2)) & 0xffc))) = HalpDisplayPte;
|
|||
|
|
|||
|
if (HalpDisplayPCIDevice == TRUE){
|
|||
|
|
|||
|
//
|
|||
|
// the display type is PCI
|
|||
|
// check physical address and reinitialize PTE
|
|||
|
// we assume that the device has no function
|
|||
|
//
|
|||
|
|
|||
|
Slot.u.bits.FunctionNumber = 0;
|
|||
|
|
|||
|
if (HalpDisplayControllerSetup == HalpDisplayCirrusSetup){
|
|||
|
|
|||
|
HalpPonceConfigAddrReg += 0x400;
|
|||
|
HalpPonceConfigDataReg += 0x400;
|
|||
|
HalpPoncePerrm += 0x400;
|
|||
|
HalpPoncePaerr += 0x400;
|
|||
|
HalpPoncePerst += 0x400;
|
|||
|
|
|||
|
Slot.u.bits.DeviceNumber = 4;
|
|||
|
|
|||
|
HalpReadPCIConfigUlongByOffset( Slot,&ReadValue,0x14);
|
|||
|
|
|||
|
DispDbgPrint(("CirrusControlBase:=0x%x\n",ReadValue));
|
|||
|
|
|||
|
NowDisplayControlBase = (ReadValue & 0x0000fc00) + PCI_1_IO_BASE;
|
|||
|
HalpReadPCIConfigUlongByOffset( Slot,&ReadValue,0x10);
|
|||
|
|
|||
|
DispDbgPrint(("NowDisplayControlBase = 0x%x\n",NowDisplayControlBase));
|
|||
|
DispDbgPrint(("CirrusMemoryBase:=0x%x\n",ReadValue));
|
|||
|
|
|||
|
NowDisplayMemoryBase = (ReadValue & 0xff000000) + 0x80000000;
|
|||
|
|
|||
|
DispDbgPrint(("NowDisplayMemoryBase = 0x%x\n",NowDisplayMemoryBase));
|
|||
|
|
|||
|
} else {
|
|||
|
|
|||
|
for (Slot.u.bits.DeviceNumber = 1; Slot.u.bits.DeviceNumber < 6; Slot.u.bits.DeviceNumber++){
|
|||
|
HalpReadPCIConfigUlongByOffset(Slot,&ReadValue,0);
|
|||
|
|
|||
|
if (HalpDisplayControllerSetup == HalpDisplayTgaSetup && ReadValue == 0x00041011){
|
|||
|
//
|
|||
|
// DEC 21030
|
|||
|
//
|
|||
|
|
|||
|
HalpReadPCIConfigUlongByOffset(Slot,&ReadValue, 0x10);
|
|||
|
DispDbgPrint(("DECControlBase:=0x%x\n",ReadValue));
|
|||
|
NowDisplayControlBase = (ReadValue & 0xfffffff0) + TGA_REG_SPC_OFFSET;
|
|||
|
NowDisplayControlBase |= 0x40000000;
|
|||
|
NowDisplayMemoryBase = 0;
|
|||
|
|
|||
|
// S001 vvv
|
|||
|
} else if (HalpDisplayControllerSetup == HalpDisplayGlintSetup && ReadValue == 0x00013d3d){
|
|||
|
//
|
|||
|
// GLINT 300SX
|
|||
|
//
|
|||
|
|
|||
|
HalpReadPCIConfigUlongByOffset(Slot,&ReadValue, 0x10);
|
|||
|
NowDisplayControlBase = (ReadValue & 0xfffffff0);
|
|||
|
NowDisplayControlBase |= 0x40000000;
|
|||
|
DispDbgPrint(("HAL:GLiNTCtrlBase=0x%08lx,Now=0x%08lx\n",
|
|||
|
ReadValue, NowDisplayControlBase));
|
|||
|
HalpReadPCIConfigUlongByOffset(Slot,&ReadValue, 0x18);
|
|||
|
NowDisplayMemoryBase = (ReadValue & 0xfffffff0);
|
|||
|
NowDisplayMemoryBase |= 0x40000000;
|
|||
|
DispDbgPrint(("HAL:GLiNTMemBase =0x%08lx,Now=0x%08lx\n",
|
|||
|
ReadValue, NowDisplayMemoryBase));
|
|||
|
// S001 ^^^
|
|||
|
}
|
|||
|
}
|
|||
|
if (HalpNumberOfPonce == 2){
|
|||
|
|
|||
|
HalpPonceConfigAddrReg += 0x400;
|
|||
|
HalpPonceConfigDataReg += 0x400;
|
|||
|
HalpPoncePerrm += 0x400;
|
|||
|
HalpPoncePaerr += 0x400;
|
|||
|
HalpPoncePerst += 0x400;
|
|||
|
|
|||
|
for (Slot.u.bits.DeviceNumber = 5; Slot.u.bits.DeviceNumber < 7; Slot.u.bits.DeviceNumber++){
|
|||
|
HalpReadPCIConfigUlongByOffset(Slot,&ReadValue,0);
|
|||
|
|
|||
|
if (HalpDisplayControllerSetup == HalpDisplayTgaSetup && ReadValue == 0x00041011){
|
|||
|
//
|
|||
|
// DEC 21030
|
|||
|
//
|
|||
|
|
|||
|
HalpReadPCIConfigUlongByOffset(Slot,&ReadValue,0x10);
|
|||
|
NowDisplayControlBase = (ReadValue & 0xfffffff0) + TGA_REG_SPC_OFFSET;
|
|||
|
NowDisplayControlBase |= 0x80000000;
|
|||
|
NowDisplayMemoryBase = 0;
|
|||
|
// S001 vvv
|
|||
|
} else if (HalpDisplayControllerSetup == HalpDisplayGlintSetup && ReadValue == 0x00013d3d){
|
|||
|
//
|
|||
|
// GLINT 300SX
|
|||
|
//
|
|||
|
|
|||
|
HalpReadPCIConfigUlongByOffset(Slot,&ReadValue, 0x10);
|
|||
|
NowDisplayControlBase = (ReadValue & 0xfffffff0);
|
|||
|
NowDisplayControlBase |= 0x80000000;
|
|||
|
DispDbgPrint(("HAL:GLiNTCtrlBase=0x%08lx,Now=0x%08lx\n",
|
|||
|
ReadValue, NowDisplayControlBase));
|
|||
|
HalpReadPCIConfigUlongByOffset(Slot,&ReadValue, 0x18);
|
|||
|
NowDisplayMemoryBase = (ReadValue & 0xfffffff0);
|
|||
|
NowDisplayMemoryBase |= 0x80000000;
|
|||
|
DispDbgPrint(("HAL:GLiNTMemBase =0x%08lx,Now=0x%08lx\n",
|
|||
|
ReadValue, NowDisplayMemoryBase));
|
|||
|
// S001 ^^^
|
|||
|
}
|
|||
|
}
|
|||
|
} else {
|
|||
|
HalpPonceConfigAddrReg += 0x800;
|
|||
|
HalpPonceConfigDataReg += 0x800;
|
|||
|
HalpPoncePerrm += 0x800;
|
|||
|
HalpPoncePaerr += 0x800;
|
|||
|
HalpPoncePerst += 0x800;
|
|||
|
|
|||
|
for (Slot.u.bits.DeviceNumber = 1; Slot.u.bits.DeviceNumber < 5; Slot.u.bits.DeviceNumber++){
|
|||
|
HalpReadPCIConfigUlongByOffset(Slot,&ReadValue,0);
|
|||
|
|
|||
|
if (HalpDisplayControllerSetup == HalpDisplayTgaSetup && ReadValue == 0x00041011){
|
|||
|
|
|||
|
//
|
|||
|
// DEC 21030
|
|||
|
//
|
|||
|
|
|||
|
HalpReadPCIConfigUlongByOffset(Slot,&ReadValue,0x10);
|
|||
|
NowDisplayControlBase = (ReadValue & 0xfffffff0) + TGA_REG_SPC_OFFSET;
|
|||
|
NowDisplayControlBase |= 0xC0000000;
|
|||
|
NowDisplayMemoryBase = 0;
|
|||
|
|
|||
|
// S001 vvv
|
|||
|
} else if (HalpDisplayControllerSetup == HalpDisplayGlintSetup && ReadValue == 0x00013d3d){
|
|||
|
//
|
|||
|
// GLINT 300SX
|
|||
|
//
|
|||
|
|
|||
|
HalpReadPCIConfigUlongByOffset(Slot,&ReadValue, 0x10);
|
|||
|
NowDisplayControlBase = (ReadValue & 0xfffffff0);
|
|||
|
NowDisplayControlBase |= 0xc0000000;
|
|||
|
HalpReadPCIConfigUlongByOffset(Slot,&ReadValue, 0x18);
|
|||
|
NowDisplayMemoryBase = (ReadValue & 0xfffffff0);
|
|||
|
NowDisplayMemoryBase |= 0xc0000000;
|
|||
|
// S001 ^^^
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// check to see if address has been changed
|
|||
|
//
|
|||
|
|
|||
|
if (HalpDisplayControlBase != NowDisplayControlBase ||
|
|||
|
HalpDisplayMemoryBase != NowDisplayMemoryBase){
|
|||
|
|
|||
|
// Called by OS, so reinitialize PTE
|
|||
|
HalpDisplayControlBase = NowDisplayControlBase;
|
|||
|
HalpDisplayMemoryBase = NowDisplayMemoryBase;
|
|||
|
|
|||
|
Pte.G = 0;
|
|||
|
Pte.V = 1;
|
|||
|
Pte.D = 1;
|
|||
|
Pte.C = UNCACHED_POLICY;
|
|||
|
|
|||
|
PageFrame = (PENTRYLO)(PTE_BASE | (VIDEO_MEMORY_BASE >> (PDI_SHIFT - PTI_SHIFT)));
|
|||
|
|
|||
|
if (HalpDisplayControllerSetup == HalpDisplayCirrusSetup) {
|
|||
|
HalpCirrusPhigicalVideo.HighPart = 1;
|
|||
|
HalpCirrusPhigicalVideo.LowPart = HalpDisplayMemoryBase;
|
|||
|
Pte.PFN = (HalpCirrusPhigicalVideo.LowPart >> PAGE_SHIFT) &
|
|||
|
(0x7fffffff >> PAGE_SHIFT-1) |
|
|||
|
HalpCirrusPhigicalVideo.HighPart << (32 - PAGE_SHIFT);
|
|||
|
|
|||
|
} else if (HalpDisplayControllerSetup == HalpDisplayTgaSetup){
|
|||
|
HalpTgaPhigicalVideoCont.HighPart = 1;
|
|||
|
HalpTgaPhigicalVideoCont.LowPart = HalpDisplayControlBase - TGA_REG_SPC_OFFSET + TGA_DSP_BUF_OFFSET;
|
|||
|
Pte.PFN = (HalpTgaPhigicalVideoCont.LowPart >> PAGE_SHIFT) &
|
|||
|
(0x7fffffff >> PAGE_SHIFT-1) |
|
|||
|
HalpTgaPhigicalVideoCont.HighPart << (32 - PAGE_SHIFT);
|
|||
|
// S001 vvv
|
|||
|
} else if (HalpDisplayControllerSetup == HalpDisplayGlintSetup) {
|
|||
|
HalpGlintPhygicalVideo.HighPart = 1;
|
|||
|
HalpGlintPhygicalVideo.LowPart = HalpDisplayMemoryBase;
|
|||
|
Pte.PFN = (HalpGlintPhygicalVideo.LowPart >> PAGE_SHIFT) &
|
|||
|
(0x7fffffff >> PAGE_SHIFT-1) |
|
|||
|
HalpGlintPhygicalVideo.HighPart << (32 - PAGE_SHIFT);
|
|||
|
// S001 ^^^
|
|||
|
}
|
|||
|
|
|||
|
for (Index = 0; Index < ((PAGE_SIZE / sizeof(ENTRYLO)) - 1); Index += 1) {
|
|||
|
*PageFrame++ = Pte;
|
|||
|
Pte.PFN += 1;
|
|||
|
}
|
|||
|
|
|||
|
if (HalpDisplayControllerSetup == HalpDisplayCirrusSetup) {
|
|||
|
|
|||
|
//
|
|||
|
// Page table for the video registers.
|
|||
|
//
|
|||
|
|
|||
|
Pte.PFN = ((ULONG)HalpDisplayControlBase) >> PAGE_SHIFT;
|
|||
|
*PageFrame = Pte;
|
|||
|
|
|||
|
} else if (HalpDisplayControllerSetup == HalpDisplayTgaSetup){
|
|||
|
HalpTgaPhigicalVideoCont.HighPart = 1;
|
|||
|
HalpTgaPhigicalVideoCont.LowPart = HalpDisplayControlBase;
|
|||
|
Pte.PFN = (HalpTgaPhigicalVideoCont.LowPart >> PAGE_SHIFT) &
|
|||
|
(0x7fffffff >> PAGE_SHIFT-1) |
|
|||
|
HalpTgaPhigicalVideoCont.HighPart << (32 - PAGE_SHIFT);
|
|||
|
*PageFrame = Pte;
|
|||
|
// S001 vvv
|
|||
|
} else if (HalpDisplayControllerSetup == HalpDisplayGlintSetup) {
|
|||
|
HalpGlintPhygicalVideoCont.HighPart = 1;
|
|||
|
HalpGlintPhygicalVideoCont.LowPart = HalpDisplayControlBase;
|
|||
|
|
|||
|
//
|
|||
|
// IBM RGB525
|
|||
|
//
|
|||
|
|
|||
|
Pte.PFN = ((HalpGlintPhygicalVideoCont.LowPart + 0x4000) >> PAGE_SHIFT) &
|
|||
|
(0x7fffffff >> PAGE_SHIFT-1) |
|
|||
|
HalpGlintPhygicalVideoCont.HighPart << (32 - PAGE_SHIFT);
|
|||
|
*(PageFrame - 2) = Pte;
|
|||
|
|
|||
|
//
|
|||
|
// GLINT 300SX Internal Video Registers
|
|||
|
//
|
|||
|
|
|||
|
Pte.PFN = ((HalpGlintPhygicalVideoCont.LowPart + 0x3000) >> PAGE_SHIFT) &
|
|||
|
(0x7fffffff >> PAGE_SHIFT-1) |
|
|||
|
HalpGlintPhygicalVideoCont.HighPart << (32 - PAGE_SHIFT);
|
|||
|
*(PageFrame - 1) = Pte;
|
|||
|
|
|||
|
//
|
|||
|
// GLINT 300SX Control Status Registers
|
|||
|
//
|
|||
|
|
|||
|
Pte.PFN = (HalpGlintPhygicalVideoCont.LowPart >> PAGE_SHIFT) &
|
|||
|
(0x7fffffff >> PAGE_SHIFT-1) |
|
|||
|
HalpGlintPhygicalVideoCont.HighPart << (32 - PAGE_SHIFT);
|
|||
|
*PageFrame = Pte;
|
|||
|
// S001 ^^^
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// 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) {
|
|||
|
// S001 vvv
|
|||
|
|
|||
|
DispDbgPrint(("HAL: Re Initialize Controller\n"));
|
|||
|
DispDbgPrint(("HAL: Str = %s\n",String));
|
|||
|
|
|||
|
if (HalpResetDisplayParameters &&
|
|||
|
(HalpDisplayControllerSetup == HalpDisplayINT10Setup) ) {
|
|||
|
//
|
|||
|
// Video work-around. The video driver has a reset function,
|
|||
|
// call it before resetting the system in case the bios doesn't
|
|||
|
// know how to reset the displays video mode.
|
|||
|
//
|
|||
|
|
|||
|
DispDbgPrint(("HAL: Call x86 reset routine\n"));
|
|||
|
|
|||
|
if (HalpResetDisplayParameters(80, 50)) {
|
|||
|
}
|
|||
|
}
|
|||
|
// S001 ^^^
|
|||
|
|
|||
|
if(HalpNMIFlag == 0){
|
|||
|
//
|
|||
|
// Non NMI. It is Panic.
|
|||
|
//
|
|||
|
HalpMrcModeChange((UCHAR)MRC_OP_DUMP_AND_POWERSW_NMI);
|
|||
|
//
|
|||
|
// Do not make eif. retun only at dump key
|
|||
|
//
|
|||
|
for (cpu=0;cpu < R98B_MAX_CPU;cpu++)
|
|||
|
HalpNMIHappend[cpu] = 1;
|
|||
|
}
|
|||
|
|
|||
|
DispDbgPrint(("HAL: Call DisplayControllerSetup\n"));
|
|||
|
|
|||
|
HalpDisplayControllerSetup();
|
|||
|
HalpInitDisplayStringIntoNvram();
|
|||
|
// HalpResetX86DisplayAdapter(); /* for X86 */
|
|||
|
}
|
|||
|
|
|||
|
HalStringIntoBufferStart( HalpColumn, HalpRow );
|
|||
|
|
|||
|
//
|
|||
|
// Display characters until a null byte is encountered.
|
|||
|
//
|
|||
|
|
|||
|
while (*String != 0) {
|
|||
|
HalpDisplayCharacter(*String++);
|
|||
|
}
|
|||
|
|
|||
|
HalpStringBufferCopyToNvram();
|
|||
|
|
|||
|
//
|
|||
|
// 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;
|
|||
|
|
|||
|
KiReleaseSpinLock(&HalpDisplayAdapterLock);
|
|||
|
|
|||
|
KeLowerIrql(OldIrql);
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
VOID
|
|||
|
HalpDisplayCharacterOld (
|
|||
|
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;
|
|||
|
PUSHORT DestinationShort; // S001
|
|||
|
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 {
|
|||
|
#if 0
|
|||
|
RtlMoveMemory((PVOID)VIDEO_MEMORY_BASE,
|
|||
|
(PVOID)(VIDEO_MEMORY_BASE + HalpScrollLine),
|
|||
|
HalpScrollLength);
|
|||
|
#else
|
|||
|
HalpMoveMemory32((PUCHAR)VIDEO_MEMORY_BASE,
|
|||
|
(PUCHAR)(VIDEO_MEMORY_BASE + HalpScrollLine),
|
|||
|
HalpScrollLength);
|
|||
|
#endif
|
|||
|
|
|||
|
// S001 vvv
|
|||
|
if (HalpDisplayType16BPP) {
|
|||
|
DestinationShort = (PUSHORT)(VIDEO_MEMORY_BASE + HalpScrollLength); // M022
|
|||
|
} else {
|
|||
|
Destination = (PUCHAR)VIDEO_MEMORY_BASE + HalpScrollLength;
|
|||
|
}
|
|||
|
|
|||
|
if (HalpDisplayType16BPP) {
|
|||
|
for (Index = 0; Index < HalpScrollLine/2; Index += 1) {
|
|||
|
*DestinationShort++ = (USHORT)0x000f;
|
|||
|
}
|
|||
|
} else {
|
|||
|
for (Index = 0; Index < HalpScrollLine; Index += 1) {
|
|||
|
*Destination++ = 1;
|
|||
|
}
|
|||
|
}
|
|||
|
// S001 ^^^
|
|||
|
}
|
|||
|
|
|||
|
HalpStringBufferCopyToNvram();
|
|||
|
HalStringIntoBufferStart( HalpColumn, HalpRow );
|
|||
|
|
|||
|
} else if (Character == '\r') {
|
|||
|
HalpColumn = 0;
|
|||
|
|
|||
|
HalpStringBufferCopyToNvram();
|
|||
|
HalStringIntoBufferStart( HalpColumn, HalpRow );
|
|||
|
|
|||
|
} else {
|
|||
|
HalStringIntoBuffer( Character );
|
|||
|
|
|||
|
if ((Character < HalpFontHeader->FirstCharacter) ||
|
|||
|
(Character > HalpFontHeader->LastCharacter)) {
|
|||
|
Character = HalpFontHeader->DefaultCharacter;
|
|||
|
}
|
|||
|
|
|||
|
Character -= HalpFontHeader->FirstCharacter;
|
|||
|
HalpOutputCharacterOld((PUCHAR)HalpFontHeader + HalpFontHeader->Map[Character].Offset);
|
|||
|
}
|
|||
|
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
// S001 vvv
|
|||
|
VOID
|
|||
|
HalpDisplayCharacterVGA (
|
|||
|
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.
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
|
|||
|
//
|
|||
|
// 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 { // need to scroll up the screen
|
|||
|
HalpScrollINT10(1);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//=========================================================================
|
|||
|
//
|
|||
|
// IBMBJB added tab processing
|
|||
|
//
|
|||
|
|
|||
|
else if( Character == '\t' ) // tab?
|
|||
|
{
|
|||
|
HalpColumn += TAB_SIZE;
|
|||
|
HalpColumn = (HalpColumn / TAB_SIZE) * TAB_SIZE;
|
|||
|
|
|||
|
if( HalpColumn >= 80 ) // tab beyond end of screen?
|
|||
|
{
|
|||
|
HalpColumn = 0; // next tab stop is 1st column of next line
|
|||
|
|
|||
|
if( HalpRow >= (HalpDisplayText - 1) )
|
|||
|
HalpScrollINT10( 1 ); // scroll the screen up
|
|||
|
else
|
|||
|
++HalpRow;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//=========================================================================
|
|||
|
|
|||
|
else if (Character == '\r') {
|
|||
|
HalpColumn = 0;
|
|||
|
} else if (Character == 0x7f) { /* DEL character */
|
|||
|
if (HalpColumn != 0) {
|
|||
|
HalpColumn -= 1;
|
|||
|
HalpOutputCharacterINT10(0);
|
|||
|
HalpColumn -= 1;
|
|||
|
} else /* do nothing */
|
|||
|
;
|
|||
|
} else if (Character >= 0x20) {
|
|||
|
// Auto wrap for 80 columns per line
|
|||
|
if (HalpColumn >= 80) {
|
|||
|
HalpColumn = 0;
|
|||
|
if (HalpRow < (HalpDisplayText - 1)) {
|
|||
|
HalpRow += 1;
|
|||
|
} else { // need to scroll up the screen
|
|||
|
HalpScrollINT10(1);
|
|||
|
}
|
|||
|
}
|
|||
|
HalpOutputCharacterINT10(Character);
|
|||
|
} else /* skip the nonprintable character */
|
|||
|
;
|
|||
|
|
|||
|
return;
|
|||
|
|
|||
|
} /* end of HalpDisplayCharacterVGA() */
|
|||
|
// S001 ^^^
|
|||
|
|
|||
|
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
|
|||
|
HalpOutputCharacterOld(
|
|||
|
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;
|
|||
|
PUSHORT DestinationShort; // S001
|
|||
|
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.
|
|||
|
//
|
|||
|
|
|||
|
// S001 vvv
|
|||
|
if (HalpDisplayType16BPP) {
|
|||
|
DestinationShort = (PUSHORT)(VIDEO_MEMORY_BASE +
|
|||
|
(HalpRow * HalpScrollLine) + (HalpColumn * HalpCharacterWidth * sizeof(USHORT)));
|
|||
|
} else {
|
|||
|
Destination = (PUCHAR)(VIDEO_MEMORY_BASE +
|
|||
|
(HalpRow * HalpScrollLine) + (HalpColumn * HalpCharacterWidth));
|
|||
|
}
|
|||
|
// S001 ^^^
|
|||
|
|
|||
|
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) {
|
|||
|
// S001 vvv
|
|||
|
if (HalpDisplayType16BPP) {
|
|||
|
if (FontValue >> 31)
|
|||
|
*DestinationShort++ = (USHORT)0xffff;
|
|||
|
else
|
|||
|
*DestinationShort++ = (USHORT)0x000f;
|
|||
|
}else{
|
|||
|
*Destination++ = (UCHAR) (FontValue >> 31) ^ 1;
|
|||
|
}
|
|||
|
// S001 ^^^
|
|||
|
FontValue <<= 1;
|
|||
|
}
|
|||
|
|
|||
|
if(HalpDisplayControllerSetup == HalpDisplayCirrusSetup){
|
|||
|
Destination +=
|
|||
|
(1024 - HalpCharacterWidth);
|
|||
|
// S001 vvv
|
|||
|
} else if (HalpDisplayType16BPP){
|
|||
|
DestinationShort +=
|
|||
|
(HalpMonitorConfigurationData.HorizontalResolution - HalpCharacterWidth);
|
|||
|
// S001 ^^^
|
|||
|
} else {
|
|||
|
Destination +=
|
|||
|
(HalpMonitorConfigurationData.HorizontalResolution - HalpCharacterWidth);
|
|||
|
}
|
|||
|
}
|
|||
|
HalpColumn += 1;
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
VOID
|
|||
|
Write_Dbg_Uchar(
|
|||
|
PUCHAR Ioadress,
|
|||
|
UCHAR Moji
|
|||
|
)
|
|||
|
{
|
|||
|
// DispDbgPrint(("Disply I/O Adress %x Char %x \n",Ioadress,Moji));
|
|||
|
|
|||
|
WRITE_PORT_UCHAR(Ioadress,Moji);
|
|||
|
}
|
|||
|
|
|||
|
// S001 vvv
|
|||
|
VOID
|
|||
|
HalpOutputCharacterINT10 (
|
|||
|
IN UCHAR Character
|
|||
|
)
|
|||
|
{
|
|||
|
ULONG Eax,Ebx,Ecx,Edx,Esi,Edi,Ebp;
|
|||
|
|
|||
|
Eax = 2 << 8; // AH = 2
|
|||
|
Ebx = 0; // BH = page number
|
|||
|
Edx = (HalpRow << 8) + HalpColumn;
|
|||
|
HalCallBios(0x10, &Eax,&Ebx,&Ecx,&Edx,&Esi,&Edi,&Ebp);
|
|||
|
|
|||
|
Eax = (0x0A << 8) + Character; // AH = 0xA AL = character
|
|||
|
Ebx = 0;
|
|||
|
Ecx = 1;
|
|||
|
HalCallBios(0x10, &Eax,&Ebx,&Ecx,&Edx,&Esi,&Edi,&Ebp);
|
|||
|
|
|||
|
HalpColumn += 1;
|
|||
|
}
|
|||
|
|
|||
|
VOID
|
|||
|
HalpScrollINT10 (
|
|||
|
IN UCHAR LinesToScroll
|
|||
|
)
|
|||
|
{
|
|||
|
ULONG Eax,Ebx,Ecx,Edx,Esi,Edi,Ebp;
|
|||
|
|
|||
|
Eax = 6 << 8; // AH = 6 (scroll up)
|
|||
|
Eax |= LinesToScroll; // AL = lines to scroll
|
|||
|
Ebx = TEXT_ATTR << 8; // BH = attribute to fill blank line(s)
|
|||
|
Ecx = 0; // CH,CL = upper left
|
|||
|
Edx = ((HalpDisplayText - 1) << 8)
|
|||
|
+ (HalpDisplayWidth - 1); // DH,DL = lower right
|
|||
|
HalCallBios(0x10, &Eax,&Ebx,&Ecx,&Edx,&Esi,&Edi,&Ebp);
|
|||
|
}
|
|||
|
|
|||
|
VOID
|
|||
|
HalpDisplayINT10Setup (
|
|||
|
VOID
|
|||
|
)
|
|||
|
{
|
|||
|
ULONG Eax,Ebx,Ecx,Edx,Esi,Edi,Ebp;
|
|||
|
|
|||
|
HalpColumn = 0;
|
|||
|
HalpRow = 0;
|
|||
|
HalpDisplayWidth = 80;
|
|||
|
HalpDisplayText = 50;
|
|||
|
HalpScrollLine = 160;
|
|||
|
HalpScrollLength = HalpScrollLine * (HalpDisplayText - 1);
|
|||
|
|
|||
|
HalpDisplayOwnedByHal = TRUE;
|
|||
|
|
|||
|
HalpResetX86DisplayAdapter(); // for compaq q-vision reset
|
|||
|
|
|||
|
//
|
|||
|
// Load 8x8 font 80x50 on VGA
|
|||
|
//
|
|||
|
Eax = 0x1112; // AH = 11 AL=12
|
|||
|
Ebx = 0;
|
|||
|
HalCallBios(0x10, &Eax,&Ebx,&Ecx,&Edx,&Esi,&Edi,&Ebp);
|
|||
|
|
|||
|
//
|
|||
|
// Set cursor to (0,0)
|
|||
|
//
|
|||
|
Eax = 0x02 << 8; // AH = 2
|
|||
|
Ebx = 0; // BH = page Number
|
|||
|
Edx = 0; // DH = row DL = column
|
|||
|
HalCallBios(0x10, &Eax,&Ebx,&Ecx,&Edx,&Esi,&Edi,&Ebp);
|
|||
|
|
|||
|
//
|
|||
|
// Make screen white on blue by scrolling entire screen
|
|||
|
//
|
|||
|
Eax = 0x06 << 8; // AH = 6 AL = 0
|
|||
|
Ebx = TEXT_ATTR << 8; // BH = attribute
|
|||
|
Ecx = 0; // (x,y) upper left
|
|||
|
Edx = ((HalpDisplayText-1) << 8); // (x,y) lower right
|
|||
|
Edx += HalpScrollLine/2;
|
|||
|
HalCallBios(0x10, &Eax,&Ebx,&Ecx,&Edx,&Esi,&Edi,&Ebp);
|
|||
|
|
|||
|
}
|
|||
|
// S001 ^^^
|
|||
|
BOOLEAN
|
|||
|
HalpCheckPCIDevice (
|
|||
|
IN PCI_SLOT_NUMBER Slot
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This function checks if spcified PCI slot is valid.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
Slot - Supplies a PCI slot number and function number.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
TRUE - specified slot is valid
|
|||
|
FALSE - specified slot is invalid
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
R94A_PCI_CONFIGURATION_ADDRESS_REG ConfigAddressValue;
|
|||
|
BOOLEAN ReturnValue;
|
|||
|
ULONG OrigData;
|
|||
|
ULONG IdValue;
|
|||
|
|
|||
|
//
|
|||
|
// Disable PCI-MasterAbort interrupt during configration read.
|
|||
|
//
|
|||
|
|
|||
|
// DispDbgPrint(("Hal: Chk perrmAddr=0x%x, paerrAddr=0x%x\n",HalpPoncePerrm, HalpPoncePaerr));
|
|||
|
|
|||
|
OrigData = READ_REGISTER_ULONG(HalpPoncePerrm);
|
|||
|
|
|||
|
// DispDbgPrint(("Hal: origdata perrm data=0x%08lx\n",OrigData));
|
|||
|
|
|||
|
WRITE_REGISTER_ULONG(HalpPoncePerrm, OrigData | 0x00800000);
|
|||
|
|
|||
|
//
|
|||
|
// read VendorID and DeviceID of the specified slot
|
|||
|
//
|
|||
|
|
|||
|
*((PULONG) &ConfigAddressValue) = 0x0;
|
|||
|
|
|||
|
ConfigAddressValue.ConfigEnable = 1;
|
|||
|
ConfigAddressValue.DeviceNumber = Slot.u.bits.DeviceNumber;
|
|||
|
ConfigAddressValue.FunctionNumber = Slot.u.bits.FunctionNumber;
|
|||
|
|
|||
|
// DispDbgPrint(("Hal: deviceNum=%d, funcNum=%d\n",Slot.u.bits.DeviceNumber, Slot.u.bits.FunctionNumber));
|
|||
|
|
|||
|
//
|
|||
|
// Synchronize with PCI configuration
|
|||
|
//
|
|||
|
|
|||
|
WRITE_REGISTER_ULONG(HalpPonceConfigAddrReg, *((PULONG) &ConfigAddressValue));
|
|||
|
IdValue = READ_REGISTER_ULONG(HalpPonceConfigDataReg);
|
|||
|
|
|||
|
//
|
|||
|
// Release spinlock
|
|||
|
//
|
|||
|
|
|||
|
if ((USHORT)(IdValue & 0xffff) == 0xffff){
|
|||
|
|
|||
|
//
|
|||
|
// waiting until ReceivedMasterAbort bit is set
|
|||
|
//
|
|||
|
|
|||
|
// DispDbgPrint(("Hal: chk 0\n"));
|
|||
|
// DispDbgPrint(("Hal: PERRI = 0x%x\n",READ_REGISTER_ULONG((PULONG)0xba000818)));
|
|||
|
// DispDbgPrint(("Hal: paerr = 0x%x\n",READ_REGISTER_ULONG(HalpPoncePaerr)));
|
|||
|
|
|||
|
//
|
|||
|
// clear the ReceivedMasterAbort bit
|
|||
|
//
|
|||
|
|
|||
|
WRITE_REGISTER_ULONG(HalpPoncePerst, 0x00800000);
|
|||
|
|
|||
|
//
|
|||
|
// Clear memory address error registers.
|
|||
|
//
|
|||
|
|
|||
|
// {
|
|||
|
// LARGE_INTEGER registerLarge;
|
|||
|
// READ_REGISTER_DWORD((PVOID)&((PDMA_REGISTERS)DMA_VIRTUAL_BASE)->InvalidAddress, ®isterLarge);
|
|||
|
// }
|
|||
|
|
|||
|
// DispDbgPrint(("Hal: chk 1\n"));
|
|||
|
|
|||
|
ReturnValue = FALSE;
|
|||
|
|
|||
|
} else {
|
|||
|
|
|||
|
// DispDbgPrint(("Hal: chk 2\n"));
|
|||
|
|
|||
|
ReturnValue = TRUE;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Restore the PCIInterruptEnable register.
|
|||
|
//
|
|||
|
|
|||
|
WRITE_REGISTER_ULONG(HalpPoncePerrm, OrigData);
|
|||
|
|
|||
|
// DispDbgPrint(("Hal: chk 3\n"));
|
|||
|
|
|||
|
return ReturnValue;
|
|||
|
}
|
|||
|
// S001 vvv
|
|||
|
VOID
|
|||
|
HalpDisplayGlintSetup(
|
|||
|
VOID
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This routine initializes the GLINT 300SX Graphics accelerator.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
None
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
None
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
ULONG VerticalFrequency;
|
|||
|
ULONG horizontalTotal;
|
|||
|
ULONG verticalTotal;
|
|||
|
|
|||
|
__VIDEO __Video;
|
|||
|
VIDEO Video = &__Video;
|
|||
|
long ClockDivider;
|
|||
|
|
|||
|
// for initialize ramdac
|
|||
|
ULONG Dac = RGB525_REGISTER_BASE;
|
|||
|
UCHAR ByteVal;
|
|||
|
|
|||
|
// for initialize timing
|
|||
|
ULONG Glint = GLINT_VIDEO_REGISTER_BASE - 0x3000;
|
|||
|
|
|||
|
// for initialize control
|
|||
|
ULONG SerialClk;
|
|||
|
ULONG Temp;
|
|||
|
ULONG Data;
|
|||
|
ULONG Mask;
|
|||
|
|
|||
|
// for initialize RampLut
|
|||
|
ULONG Index;
|
|||
|
|
|||
|
// for clear the screen
|
|||
|
PULONG DestinationUlong;
|
|||
|
ULONG Length;
|
|||
|
|
|||
|
/* check revision id R01 or R02. assume 40MHz(R01) or 50MHz(R02) reference clock for now */
|
|||
|
DispDbgPrint(("Hal: GLiNT Display setup\n"));
|
|||
|
|
|||
|
if ( HalpGlintRevisionId == 0){
|
|||
|
Video->RefDivCount = RGB525_PLL_REFCLK_40_MHz;
|
|||
|
} else {
|
|||
|
Video->RefDivCount = RGB525_PLL_REFCLK_50_MHz;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Calculate vertical frequency.
|
|||
|
//
|
|||
|
|
|||
|
#if defined(_GLINT60HZ_)
|
|||
|
|
|||
|
VerticalFrequency = 60;
|
|||
|
|
|||
|
#else
|
|||
|
|
|||
|
horizontalTotal = ( HalpMonitorConfigurationData.HorizontalDisplayTime
|
|||
|
+HalpMonitorConfigurationData.HorizontalBackPorch
|
|||
|
+HalpMonitorConfigurationData.HorizontalFrontPorch
|
|||
|
+HalpMonitorConfigurationData.HorizontalSync );
|
|||
|
|
|||
|
verticalTotal = ( HalpMonitorConfigurationData.VerticalResolution
|
|||
|
+HalpMonitorConfigurationData.VerticalBackPorch
|
|||
|
+HalpMonitorConfigurationData.VerticalFrontPorch
|
|||
|
+HalpMonitorConfigurationData.VerticalSync );
|
|||
|
|
|||
|
VerticalFrequency = 1000000000 / ( horizontalTotal * verticalTotal);
|
|||
|
|
|||
|
#endif // _GLINT60HZ_
|
|||
|
|
|||
|
DispDbgPrint(("HAL: VerticalResolution=%d\n",HalpMonitorConfigurationData.VerticalResolution));
|
|||
|
DispDbgPrint(("HAL: horizontalTotal=%d\n",horizontalTotal));
|
|||
|
DispDbgPrint(("HAL: verticalTotal=%d\n",verticalTotal));
|
|||
|
|
|||
|
//
|
|||
|
// Initialize video data
|
|||
|
//
|
|||
|
|
|||
|
/* get timing values for named resolution */
|
|||
|
|
|||
|
if ( HalpMonitorConfigurationData.HorizontalResolution == 1280
|
|||
|
&& HalpMonitorConfigurationData.VerticalResolution == 1024
|
|||
|
&& VerticalFrequency == 75)
|
|||
|
{
|
|||
|
DispDbgPrint(("HAL: GLiNT 1280x1024 75Hz setup\n"));
|
|||
|
Video->ImageWidth = 1280;
|
|||
|
Video->ImageHeight = 1024;
|
|||
|
Video->HLimit = 8 * 211;
|
|||
|
Video->HSyncStart = 8 * 2;
|
|||
|
Video->HSyncEnd = 8 * 20;
|
|||
|
Video->HBlankEnd = 8 * 51;
|
|||
|
Video->HSyncPolarity = GLINT_HSYNC_ACTIVE_LOW;
|
|||
|
Video->VLimit = 1066;
|
|||
|
Video->VSyncStart = 2;
|
|||
|
Video->VSyncEnd = 5;
|
|||
|
Video->VBlankEnd = 42;
|
|||
|
Video->VSyncPolarity = GLINT_HSYNC_ACTIVE_LOW;
|
|||
|
/* 134 MHz */
|
|||
|
Video->PixelClock = RGB525_DF(3) | RGB525_VCO_DIV_COUNT(2);
|
|||
|
}
|
|||
|
else if ( HalpMonitorConfigurationData.HorizontalResolution == 1024
|
|||
|
&& HalpMonitorConfigurationData.VerticalResolution == 768
|
|||
|
&& VerticalFrequency == 75)
|
|||
|
{
|
|||
|
DispDbgPrint(("HAL: GLiNT 1024x768 75Hz setup\n"));
|
|||
|
Video->ImageWidth = 1024;
|
|||
|
Video->ImageHeight = 768;
|
|||
|
Video->HLimit = 8 * 164;
|
|||
|
Video->HSyncStart = 8 * 2;
|
|||
|
Video->HSyncEnd = 8 * 14;
|
|||
|
Video->HBlankEnd = 8 * 36;
|
|||
|
Video->HSyncPolarity = GLINT_HSYNC_ACTIVE_HIGH;
|
|||
|
Video->VLimit = 800;
|
|||
|
Video->VSyncStart = 2;
|
|||
|
Video->VSyncEnd = 5;
|
|||
|
Video->VBlankEnd = 32;
|
|||
|
Video->VSyncPolarity = GLINT_HSYNC_ACTIVE_HIGH;
|
|||
|
/* 79 MHz */
|
|||
|
Video->PixelClock = RGB525_DF(2) | RGB525_VCO_DIV_COUNT(14);
|
|||
|
}
|
|||
|
else if ( HalpMonitorConfigurationData.HorizontalResolution == 1024
|
|||
|
&& HalpMonitorConfigurationData.VerticalResolution == 768
|
|||
|
&& VerticalFrequency == 60)
|
|||
|
{
|
|||
|
DispDbgPrint(("HAL: GLiNT 1024x768 60Hz setup\n"));
|
|||
|
Video->ImageWidth = 1024;
|
|||
|
Video->ImageHeight = 768;
|
|||
|
Video->HLimit = 8 * 168;
|
|||
|
Video->HSyncStart = 8 * 3;
|
|||
|
Video->HSyncEnd = 8 * 20;
|
|||
|
Video->HBlankEnd = 8 * 40;
|
|||
|
Video->HSyncPolarity = GLINT_HSYNC_ACTIVE_LOW;
|
|||
|
Video->VLimit = 806;
|
|||
|
Video->VSyncStart = 4;
|
|||
|
Video->VSyncEnd = 10;
|
|||
|
Video->VBlankEnd = 38;
|
|||
|
Video->VSyncPolarity = GLINT_HSYNC_ACTIVE_LOW;
|
|||
|
/* 65 MHz */
|
|||
|
Video->PixelClock = RGB525_DF(2) | RGB525_VCO_DIV_COUNT(0);
|
|||
|
}
|
|||
|
else if ( HalpMonitorConfigurationData.HorizontalResolution == 800
|
|||
|
&& HalpMonitorConfigurationData.VerticalResolution == 600
|
|||
|
&& VerticalFrequency == 75)
|
|||
|
{
|
|||
|
DispDbgPrint(("HAL: GLiNT 800x600 75Hz setup\n"));
|
|||
|
Video->ImageWidth = 800;
|
|||
|
Video->ImageHeight = 600;
|
|||
|
Video->HLimit = 8 * 132;
|
|||
|
Video->HSyncStart = 8 * 2;
|
|||
|
Video->HSyncEnd = 8 * 12;
|
|||
|
Video->HBlankEnd = 8 * 32;
|
|||
|
Video->HSyncPolarity = GLINT_HSYNC_ACTIVE_HIGH;
|
|||
|
Video->VLimit = 625;
|
|||
|
Video->VSyncStart = 2;
|
|||
|
Video->VSyncEnd = 5;
|
|||
|
Video->VBlankEnd = 25;
|
|||
|
Video->VSyncPolarity = GLINT_VSYNC_ACTIVE_HIGH;
|
|||
|
/* 49.5 MHz */
|
|||
|
Video->PixelClock = RGB525_DF(1) | RGB525_VCO_DIV_COUNT(34);
|
|||
|
}
|
|||
|
else if ( HalpMonitorConfigurationData.HorizontalResolution == 800
|
|||
|
&& HalpMonitorConfigurationData.VerticalResolution == 600
|
|||
|
&& VerticalFrequency == 60)
|
|||
|
{
|
|||
|
DispDbgPrint(("HAL: GLiNT 800x600 60Hz setup\n"));
|
|||
|
Video->ImageWidth = 800;
|
|||
|
Video->ImageHeight = 600;
|
|||
|
Video->HLimit = 8 * 132;
|
|||
|
Video->HSyncStart = 8 * 5;
|
|||
|
Video->HSyncEnd = 8 * 21;
|
|||
|
Video->HBlankEnd = 8 * 32;
|
|||
|
Video->HSyncPolarity = GLINT_HSYNC_ACTIVE_HIGH;
|
|||
|
Video->VLimit = 628;
|
|||
|
Video->VSyncStart = 2;
|
|||
|
Video->VSyncEnd = 6;
|
|||
|
Video->VBlankEnd = 28;
|
|||
|
Video->VSyncPolarity = GLINT_VSYNC_ACTIVE_HIGH;
|
|||
|
/* 40 MHz */
|
|||
|
Video->PixelClock = RGB525_DF(1) | RGB525_VCO_DIV_COUNT(15);
|
|||
|
}
|
|||
|
else if ( HalpMonitorConfigurationData.HorizontalResolution == 640 // add 4/5/1995
|
|||
|
&& HalpMonitorConfigurationData.VerticalResolution == 480
|
|||
|
&& VerticalFrequency == 60)
|
|||
|
{
|
|||
|
DispDbgPrint(("HAL: GLiNT 640x480 60Hz setup\n"));
|
|||
|
Video->ImageWidth = 640;
|
|||
|
Video->ImageHeight = 480;
|
|||
|
Video->HLimit = 8 * 100;
|
|||
|
Video->HSyncStart = 8 * 2;
|
|||
|
Video->HSyncEnd = 8 * 14;
|
|||
|
Video->HBlankEnd = 8 * 20;
|
|||
|
Video->HSyncPolarity = GLINT_HSYNC_ACTIVE_LOW;
|
|||
|
Video->VLimit = 525;
|
|||
|
Video->VSyncStart = 12;
|
|||
|
Video->VSyncEnd = 13;
|
|||
|
Video->VBlankEnd = 45;
|
|||
|
Video->VSyncPolarity = GLINT_VSYNC_ACTIVE_LOW;
|
|||
|
/* 31.5 MHz */
|
|||
|
Video->PixelClock = RGB525_DF(0) | RGB525_VCO_DIV_COUNT(36);
|
|||
|
}
|
|||
|
else if ( HalpMonitorConfigurationData.HorizontalResolution == 640
|
|||
|
&& HalpMonitorConfigurationData.VerticalResolution == 480
|
|||
|
&& VerticalFrequency == 75)
|
|||
|
{
|
|||
|
DispDbgPrint(("HAL: GLiNT 640x480 75Hz setup\n"));
|
|||
|
Video->ImageWidth = 640;
|
|||
|
Video->ImageHeight = 480;
|
|||
|
Video->HLimit = 8 * 105;
|
|||
|
Video->HSyncStart = 8 * 2;
|
|||
|
Video->HSyncEnd = 8 * 10;
|
|||
|
Video->HBlankEnd = 8 * 25;
|
|||
|
Video->HSyncPolarity = GLINT_HSYNC_ACTIVE_LOW;
|
|||
|
Video->VLimit = 500;
|
|||
|
Video->VSyncStart = 2;
|
|||
|
Video->VSyncEnd = 5;
|
|||
|
Video->VBlankEnd = 20;
|
|||
|
Video->VSyncPolarity = GLINT_VSYNC_ACTIVE_LOW;
|
|||
|
/* 31.5 MHz */
|
|||
|
Video->PixelClock = RGB525_DF(0) | RGB525_VCO_DIV_COUNT(61);
|
|||
|
}
|
|||
|
else if ( HalpMonitorConfigurationData.HorizontalResolution == 1280
|
|||
|
&& HalpMonitorConfigurationData.VerticalResolution == 1024
|
|||
|
&& VerticalFrequency == 57)
|
|||
|
{
|
|||
|
DispDbgPrint(("HAL: GLiNT 1280x1024 57Hz setup\n"));
|
|||
|
Video->ImageWidth = 1280;
|
|||
|
Video->ImageHeight = 1024;
|
|||
|
Video->HLimit = 8 * 211;
|
|||
|
Video->HSyncStart = 8 * 2;
|
|||
|
Video->HSyncEnd = 8 * 20;
|
|||
|
Video->HBlankEnd = 8 * 51;
|
|||
|
Video->HSyncPolarity = GLINT_HSYNC_ACTIVE_LOW;
|
|||
|
Video->VLimit = 1066;
|
|||
|
Video->VSyncStart = 2;
|
|||
|
Video->VSyncEnd = 5;
|
|||
|
Video->VBlankEnd = 42;
|
|||
|
Video->VSyncPolarity = GLINT_HSYNC_ACTIVE_LOW;
|
|||
|
/* 103 MHz */
|
|||
|
Video->PixelClock = RGB525_DF(2) | RGB525_VCO_DIV_COUNT(38);
|
|||
|
}
|
|||
|
else {
|
|||
|
//
|
|||
|
// force to set the resolution. 1024x768(60MHz)
|
|||
|
//
|
|||
|
|
|||
|
DispDbgPrint(("HAL: GLiNT 1024x768 60Hz setup (default setting)\n"));
|
|||
|
Video->ImageWidth = 1024;
|
|||
|
Video->ImageHeight = 768;
|
|||
|
Video->HLimit = 8 * 168;
|
|||
|
Video->HSyncStart = 8 * 3;
|
|||
|
Video->HSyncEnd = 8 * 20;
|
|||
|
Video->HBlankEnd = 8 * 40;
|
|||
|
Video->HSyncPolarity = GLINT_HSYNC_ACTIVE_LOW;
|
|||
|
Video->VLimit = 806;
|
|||
|
Video->VSyncStart = 4;
|
|||
|
Video->VSyncEnd = 10;
|
|||
|
Video->VBlankEnd = 38;
|
|||
|
Video->VSyncPolarity = GLINT_HSYNC_ACTIVE_LOW;
|
|||
|
/* 65 MHz */
|
|||
|
Video->PixelClock = RGB525_DF(2) | RGB525_VCO_DIV_COUNT(0);
|
|||
|
#if DBG
|
|||
|
DbgBreakPoint();
|
|||
|
#endif
|
|||
|
}
|
|||
|
|
|||
|
/* record image depth */
|
|||
|
|
|||
|
Video->ImageDepth = 16;
|
|||
|
|
|||
|
/* determine video clock divider and pixel format */
|
|||
|
|
|||
|
ClockDivider = 4;
|
|||
|
Video->PixelFormat = RGB525_PIXEL_FORMAT_16_BPP;
|
|||
|
|
|||
|
/* adjust horizontal timings */
|
|||
|
|
|||
|
Video->HLimit /= ClockDivider;
|
|||
|
Video->HSyncStart /= ClockDivider;
|
|||
|
Video->HSyncEnd /= ClockDivider;
|
|||
|
Video->HBlankEnd /= ClockDivider;
|
|||
|
|
|||
|
//
|
|||
|
// Initialize ramdac data
|
|||
|
//
|
|||
|
|
|||
|
RGB525_WRITE(Dac, __RGB525_PixelMask, 0xff);
|
|||
|
|
|||
|
/* set MiscControlOne register */
|
|||
|
ByteVal = RGB525_MISR_CNTL_OFF
|
|||
|
| RGB525_VMSK_CNTL_OFF
|
|||
|
| RGB525_PADR_RFMT_READ_ADDR
|
|||
|
| RGB525_SENS_DSAB_DISABLE
|
|||
|
| RGB525_VRAM_SIZE_64;
|
|||
|
RGB525_SET_REG(Dac, __RGB525_MiscControlOne, ByteVal);
|
|||
|
|
|||
|
/* set MiscControlTwo register */
|
|||
|
ByteVal = RGB525_PCLK_SEL_PLL
|
|||
|
| RGB525_INTL_MODE_DISABLE
|
|||
|
| RGB525_BLANK_CNTL_NORMAL
|
|||
|
| RGB525_COL_RES_8_BIT
|
|||
|
| RGB525_PORT_SEL_VRAM;
|
|||
|
RGB525_SET_REG(Dac, __RGB525_MiscControlTwo, ByteVal);
|
|||
|
|
|||
|
/* set MiscControlThree register */
|
|||
|
ByteVal = RGB525_SWAP_RB_DISABLE
|
|||
|
| RGB525_SWAP_WORD_31_00_FIRST
|
|||
|
| RGB525_SWAP_NIB_07_04_FIRST;
|
|||
|
RGB525_SET_REG(Dac, __RGB525_MiscControlThree, ByteVal);
|
|||
|
|
|||
|
/* set MiscClockControl register */
|
|||
|
ByteVal = RGB525_DDOTCLK_DISABLE
|
|||
|
| RGB525_SCLK_ENABLE
|
|||
|
| RGB525_PLL_ENABLE;
|
|||
|
RGB525_SET_REG(Dac, __RGB525_MiscClockControl, ByteVal);
|
|||
|
|
|||
|
/* set SyncControl register */
|
|||
|
ByteVal = RGB525_DLY_CNTL_ADD
|
|||
|
| RGB525_VSYN_INVT_DISABLE
|
|||
|
| RGB525_HSYN_INVT_DISABLE
|
|||
|
| RGB525_VSYN_CNTL_NORMAL
|
|||
|
| RGB525_HSYN_CNTL_NORMAL;
|
|||
|
RGB525_SET_REG(Dac, __RGB525_SyncControl, ByteVal);
|
|||
|
|
|||
|
/* set HSyncControl register */
|
|||
|
RGB525_SET_REG(Dac, __RGB525_HSyncControl, RGB525_HSYN_POS(0));
|
|||
|
|
|||
|
/* set PowerManagement register */
|
|||
|
ByteVal = RGB525_SCLK_PWR_NORMAL
|
|||
|
| RGB525_DDOT_PWR_DISABLE
|
|||
|
| RGB525_SYNC_PWR_NORMAL
|
|||
|
| RGB525_ICLK_PWR_NORMAL
|
|||
|
| RGB525_DAC_PWR_NORMAL;
|
|||
|
RGB525_SET_REG(Dac, __RGB525_PowerManagement, ByteVal);
|
|||
|
|
|||
|
/* set DACOperation register */
|
|||
|
ByteVal = RGB525_SOG_DISABLE
|
|||
|
| RGB525_BRB_NORMAL
|
|||
|
| RGB525_DSR_FAST
|
|||
|
| RGB525_DPE_ENABLE; /* disable? */
|
|||
|
RGB525_SET_REG(Dac, __RGB525_DACOperation, ByteVal);
|
|||
|
|
|||
|
/* set PaletteControl register */
|
|||
|
ByteVal = RGB525_6BIT_LINEAR_ENABLE
|
|||
|
| RGB525_PALETTE_PARTITION(0);
|
|||
|
RGB525_SET_REG(Dac, __RGB525_PaletteControl, ByteVal);
|
|||
|
|
|||
|
/* set PixelFormat register */
|
|||
|
RGB525_SET_REG(Dac, __RGB525_PixelFormat, Video->PixelFormat);
|
|||
|
|
|||
|
/* set 8BitPixelControl register */
|
|||
|
RGB525_SET_REG(Dac, __RGB525_8BitPixelControl,
|
|||
|
RGB525_B8_DCOL_INDIRECT);
|
|||
|
|
|||
|
/* set 16BitPixelControl register */
|
|||
|
ByteVal = RGB525_B16_DCOL_INDIRECT
|
|||
|
| RGB525_B16_565
|
|||
|
| RGB525_B16_ZIB
|
|||
|
| RGB525_B16_SPARSE;
|
|||
|
|
|||
|
RGB525_SET_REG(Dac, __RGB525_16BitPixelControl, ByteVal);
|
|||
|
|
|||
|
/* set 32BitPixelControl register */
|
|||
|
RGB525_SET_REG(Dac, __RGB525_32BitPixelControl,
|
|||
|
RGB525_B32_DCOL_INDIRECT);
|
|||
|
|
|||
|
/* set PLLControlOne register */
|
|||
|
ByteVal = RGB525_REF_SRC_REFCLK
|
|||
|
| RGB525_PLL_INT_FS_DIRECT;
|
|||
|
RGB525_SET_REG(Dac, __RGB525_PLLControlOne, ByteVal);
|
|||
|
|
|||
|
/* set PLLControlTwo register */
|
|||
|
RGB525_SET_REG(Dac, __RGB525_PLLControlTwo, RGB525_PLL_INT_FS(0));
|
|||
|
|
|||
|
/* set PLLRefDivCount register */
|
|||
|
RGB525_SET_REG(Dac, __RGB525_PLLRefDivCount, Video->RefDivCount);
|
|||
|
|
|||
|
/* set F0 register */
|
|||
|
RGB525_SET_REG(Dac, __RGB525_F0, Video->PixelClock);
|
|||
|
|
|||
|
/* set CursorControl register */
|
|||
|
RGB525_SET_REG(Dac, __RGB525_CursorControl, RGB525_CURSOR_MODE_OFF);
|
|||
|
|
|||
|
//
|
|||
|
// Initialize timing
|
|||
|
//
|
|||
|
|
|||
|
/* horizontal video timing values */
|
|||
|
|
|||
|
GLINT_WRITE(Glint, __GLINT_VTGHLimit, Video->HLimit);
|
|||
|
GLINT_WRITE(Glint, __GLINT_VTGHSyncStart, Video->HSyncStart);
|
|||
|
GLINT_WRITE(Glint, __GLINT_VTGHSyncEnd, Video->HSyncEnd);
|
|||
|
GLINT_WRITE(Glint, __GLINT_VTGHBlankEnd, Video->HBlankEnd);
|
|||
|
|
|||
|
/* vertical video timing values */
|
|||
|
|
|||
|
GLINT_WRITE(Glint, __GLINT_VTGVLimit, Video->VLimit);
|
|||
|
GLINT_WRITE(Glint, __GLINT_VTGVSyncStart, Video->VSyncStart);
|
|||
|
GLINT_WRITE(Glint, __GLINT_VTGVSyncEnd, Video->VSyncEnd);
|
|||
|
GLINT_WRITE(Glint, __GLINT_VTGVBlankEnd, Video->VBlankEnd);
|
|||
|
|
|||
|
/* horizontal clock gate values */
|
|||
|
|
|||
|
GLINT_WRITE(Glint, __GLINT_VTGHGateStart, Video->HBlankEnd - 2);
|
|||
|
GLINT_WRITE(Glint, __GLINT_VTGHGateEnd, Video->HLimit - 2);
|
|||
|
|
|||
|
/* vertical clock gate values */
|
|||
|
|
|||
|
GLINT_WRITE(Glint, __GLINT_VTGVGateStart, Video->VBlankEnd - 1)
|
|||
|
GLINT_WRITE(Glint, __GLINT_VTGVGateEnd, Video->VBlankEnd);
|
|||
|
|
|||
|
//
|
|||
|
// Initialize control
|
|||
|
//
|
|||
|
|
|||
|
/* serial clock control */
|
|||
|
|
|||
|
SerialClk = GLINT_EXTERNAL_QSF
|
|||
|
| GLINT_SPLIT_SIZE_128_WORD
|
|||
|
| GLINT_SCLK_VCLK_DIV_2;
|
|||
|
|
|||
|
GLINT_WRITE(Glint, __GLINT_VTGSerialClk, SerialClk);
|
|||
|
|
|||
|
/* set sync polarities and unblank screen */
|
|||
|
|
|||
|
// UpdatePolarityRegister(Glint,
|
|||
|
// GLINT_CBLANK_ACTIVE_LOW
|
|||
|
// | Video->HSyncPolarity
|
|||
|
// | Video->VSyncPolarity,
|
|||
|
// GLINT_CBLANK_POLARITY_MASK
|
|||
|
// | GLINT_HSYNC_POLARITY_MASK
|
|||
|
// | GLINT_VSYNC_POLARITY_MASK);
|
|||
|
|
|||
|
Data = GLINT_CBLANK_ACTIVE_LOW
|
|||
|
| Video->HSyncPolarity
|
|||
|
| Video->VSyncPolarity;
|
|||
|
Mask = GLINT_CBLANK_POLARITY_MASK
|
|||
|
| GLINT_HSYNC_POLARITY_MASK
|
|||
|
| GLINT_VSYNC_POLARITY_MASK;
|
|||
|
|
|||
|
/* read video polarity control register */
|
|||
|
|
|||
|
GLINT_READ(Glint, __GLINT_VTGPolarity, Temp);
|
|||
|
|
|||
|
/* replace existing polarity field */
|
|||
|
|
|||
|
Temp = (Temp & ~Mask) | (Data & Mask);
|
|||
|
|
|||
|
/* write result back to polarity register */
|
|||
|
|
|||
|
GLINT_WRITE(Glint, __GLINT_VTGPolarity, Temp);
|
|||
|
|
|||
|
/* set FrameRowAddr */
|
|||
|
|
|||
|
GLINT_WRITE(Glint, __GLINT_VTGFrameRowAddr, 0);
|
|||
|
|
|||
|
//
|
|||
|
// Initialize RampLut
|
|||
|
//
|
|||
|
|
|||
|
/* initialise palette address */
|
|||
|
|
|||
|
RGB525_WRITE(Dac, __RGB525_PalAddrWrite, 0);
|
|||
|
|
|||
|
/* ramp colour components using auto-increment */
|
|||
|
|
|||
|
for (Index = 0; Index <= 0xff; Index++)
|
|||
|
{
|
|||
|
RGB525_WRITE(Dac, __RGB525_PaletteData, Index);
|
|||
|
RGB525_WRITE(Dac, __RGB525_PaletteData, Index);
|
|||
|
RGB525_WRITE(Dac, __RGB525_PaletteData, Index);
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Clear the screen.
|
|||
|
//
|
|||
|
|
|||
|
DestinationUlong = (PULONG)VIDEO_MEMORY_BASE;
|
|||
|
|
|||
|
Length = (HalpMonitorConfigurationData.VerticalResolution *
|
|||
|
HalpMonitorConfigurationData.HorizontalResolution) * sizeof(USHORT);
|
|||
|
|
|||
|
for (Index = 0; Index < (Length / sizeof(ULONG)); Index++)
|
|||
|
*(DestinationUlong++) = (ULONG)0x000f000f;
|
|||
|
|
|||
|
//
|
|||
|
// Initialize the current display column, row, and ownership values.
|
|||
|
//
|
|||
|
|
|||
|
HalpColumn = 0;
|
|||
|
HalpRow = 0;
|
|||
|
HalpDisplayOwnedByHal = TRUE;
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
VOID
|
|||
|
HalpReadPCIConfigUlongByOffset (
|
|||
|
IN PCI_SLOT_NUMBER Slot,
|
|||
|
IN PULONG Buffer,
|
|||
|
IN ULONG Offset
|
|||
|
)
|
|||
|
/*++
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This function returns PCI configuration data.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
Slot - Supplies a PCI slot number and function number.
|
|||
|
Buffer - Supplies a pointer to a configuration data is returned.
|
|||
|
Offset - Offset in the PCI configuration header.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
None.
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
R94A_PCI_CONFIGURATION_ADDRESS_REG ConfigAddressValue;
|
|||
|
USHORT StatusValue;
|
|||
|
KIRQL OldIrql;
|
|||
|
|
|||
|
//
|
|||
|
// check to see if specified slot is valid
|
|||
|
//
|
|||
|
|
|||
|
if (!HalpCheckPCIDevice(Slot)) {
|
|||
|
|
|||
|
//
|
|||
|
// Invalid SlotID return no data
|
|||
|
//
|
|||
|
|
|||
|
*Buffer = 0xffffffff;
|
|||
|
return ;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
*((PULONG) &ConfigAddressValue) = 0x0;
|
|||
|
|
|||
|
ConfigAddressValue.ConfigEnable = 1;
|
|||
|
ConfigAddressValue.DeviceNumber = Slot.u.bits.DeviceNumber;
|
|||
|
ConfigAddressValue.FunctionNumber = Slot.u.bits.FunctionNumber;
|
|||
|
ConfigAddressValue.RegisterNumber = Offset >> 2;
|
|||
|
|
|||
|
//
|
|||
|
// Synchronize with PCI configuration
|
|||
|
//
|
|||
|
|
|||
|
WRITE_REGISTER_ULONG(HalpPonceConfigAddrReg, *((PULONG) &ConfigAddressValue));
|
|||
|
|
|||
|
*Buffer = READ_REGISTER_ULONG(HalpPonceConfigDataReg);
|
|||
|
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
VOID
|
|||
|
HalpReadPCIConfigUshortByOffset (
|
|||
|
IN PCI_SLOT_NUMBER Slot,
|
|||
|
IN PUSHORT Buffer,
|
|||
|
IN ULONG Offset
|
|||
|
)
|
|||
|
{
|
|||
|
R94A_PCI_CONFIGURATION_ADDRESS_REG ConfigAddressValue;
|
|||
|
USHORT StatusValue;
|
|||
|
KIRQL OldIrql;
|
|||
|
|
|||
|
if (!HalpCheckPCIDevice(Slot)) {
|
|||
|
*Buffer = 0xffff;
|
|||
|
return ;
|
|||
|
}
|
|||
|
|
|||
|
*((PULONG) &ConfigAddressValue) = 0x0;
|
|||
|
|
|||
|
ConfigAddressValue.ConfigEnable = 1;
|
|||
|
ConfigAddressValue.DeviceNumber = Slot.u.bits.DeviceNumber;
|
|||
|
ConfigAddressValue.FunctionNumber = Slot.u.bits.FunctionNumber;
|
|||
|
ConfigAddressValue.RegisterNumber = Offset >> 2;
|
|||
|
|
|||
|
WRITE_REGISTER_ULONG(HalpPonceConfigAddrReg, *((PULONG) &ConfigAddressValue));
|
|||
|
|
|||
|
*Buffer = READ_REGISTER_USHORT((PUCHAR)HalpPonceConfigDataReg + (Offset % sizeof(ULONG)));
|
|||
|
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
VOID
|
|||
|
HalpReadPCIConfigUcharByOffset (
|
|||
|
IN PCI_SLOT_NUMBER Slot,
|
|||
|
IN PUCHAR Buffer,
|
|||
|
IN ULONG Offset
|
|||
|
)
|
|||
|
{
|
|||
|
R94A_PCI_CONFIGURATION_ADDRESS_REG ConfigAddressValue;
|
|||
|
USHORT StatusValue;
|
|||
|
KIRQL OldIrql;
|
|||
|
|
|||
|
if (!HalpCheckPCIDevice(Slot)) {
|
|||
|
*Buffer = 0xff;
|
|||
|
return ;
|
|||
|
}
|
|||
|
|
|||
|
*((PULONG) &ConfigAddressValue) = 0x0;
|
|||
|
|
|||
|
ConfigAddressValue.ConfigEnable = 1;
|
|||
|
ConfigAddressValue.DeviceNumber = Slot.u.bits.DeviceNumber;
|
|||
|
ConfigAddressValue.FunctionNumber = Slot.u.bits.FunctionNumber;
|
|||
|
ConfigAddressValue.RegisterNumber = Offset >> 2;
|
|||
|
|
|||
|
WRITE_REGISTER_ULONG(HalpPonceConfigAddrReg, *((PULONG) &ConfigAddressValue));
|
|||
|
|
|||
|
*Buffer = READ_REGISTER_UCHAR((PUCHAR)HalpPonceConfigDataReg + (Offset % sizeof(ULONG)));
|
|||
|
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
VOID
|
|||
|
HalpWritePCIConfigUlongByOffset (
|
|||
|
IN PCI_SLOT_NUMBER Slot,
|
|||
|
IN PULONG Buffer,
|
|||
|
IN ULONG Offset
|
|||
|
)
|
|||
|
{
|
|||
|
R94A_PCI_CONFIGURATION_ADDRESS_REG ConfigAddressValue;
|
|||
|
USHORT StatusValue;
|
|||
|
KIRQL OldIrql;
|
|||
|
|
|||
|
if (!HalpCheckPCIDevice(Slot)) {
|
|||
|
*Buffer = 0xffffffff;
|
|||
|
return ;
|
|||
|
}
|
|||
|
|
|||
|
*((PULONG) &ConfigAddressValue) = 0x0;
|
|||
|
|
|||
|
ConfigAddressValue.ConfigEnable = 1;
|
|||
|
ConfigAddressValue.DeviceNumber = Slot.u.bits.DeviceNumber;
|
|||
|
ConfigAddressValue.FunctionNumber = Slot.u.bits.FunctionNumber;
|
|||
|
ConfigAddressValue.RegisterNumber = Offset >> 2;
|
|||
|
|
|||
|
WRITE_REGISTER_ULONG(HalpPonceConfigAddrReg, *((PULONG) &ConfigAddressValue));
|
|||
|
|
|||
|
WRITE_REGISTER_ULONG(HalpPonceConfigDataReg, *Buffer);
|
|||
|
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
VOID
|
|||
|
HalpWritePCIConfigUshortByOffset (
|
|||
|
IN PCI_SLOT_NUMBER Slot,
|
|||
|
IN PUSHORT Buffer,
|
|||
|
IN ULONG Offset
|
|||
|
)
|
|||
|
{
|
|||
|
R94A_PCI_CONFIGURATION_ADDRESS_REG ConfigAddressValue;
|
|||
|
USHORT StatusValue;
|
|||
|
KIRQL OldIrql;
|
|||
|
|
|||
|
if (!HalpCheckPCIDevice(Slot)) {
|
|||
|
*Buffer = 0xffff;
|
|||
|
return ;
|
|||
|
}
|
|||
|
|
|||
|
*((PULONG) &ConfigAddressValue) = 0x0;
|
|||
|
|
|||
|
ConfigAddressValue.ConfigEnable = 1;
|
|||
|
ConfigAddressValue.DeviceNumber = Slot.u.bits.DeviceNumber;
|
|||
|
ConfigAddressValue.FunctionNumber = Slot.u.bits.FunctionNumber;
|
|||
|
ConfigAddressValue.RegisterNumber = Offset >> 2;
|
|||
|
|
|||
|
WRITE_REGISTER_ULONG(HalpPonceConfigAddrReg, *((PULONG) &ConfigAddressValue));
|
|||
|
|
|||
|
WRITE_REGISTER_USHORT((PUCHAR)HalpPonceConfigDataReg + (Offset % sizeof(ULONG)),*Buffer);
|
|||
|
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
VOID
|
|||
|
HalpWritePCIConfigUcharByOffset (
|
|||
|
IN PCI_SLOT_NUMBER Slot,
|
|||
|
IN PUCHAR Buffer,
|
|||
|
IN ULONG Offset
|
|||
|
)
|
|||
|
{
|
|||
|
R94A_PCI_CONFIGURATION_ADDRESS_REG ConfigAddressValue;
|
|||
|
USHORT StatusValue;
|
|||
|
KIRQL OldIrql;
|
|||
|
|
|||
|
if (!HalpCheckPCIDevice(Slot)) {
|
|||
|
*Buffer = 0xff;
|
|||
|
return ;
|
|||
|
}
|
|||
|
|
|||
|
*((PULONG) &ConfigAddressValue) = 0x0;
|
|||
|
|
|||
|
ConfigAddressValue.ConfigEnable = 1;
|
|||
|
ConfigAddressValue.DeviceNumber = Slot.u.bits.DeviceNumber;
|
|||
|
ConfigAddressValue.FunctionNumber = Slot.u.bits.FunctionNumber;
|
|||
|
ConfigAddressValue.RegisterNumber = Offset >> 2;
|
|||
|
|
|||
|
WRITE_REGISTER_ULONG(HalpPonceConfigAddrReg, *((PULONG) &ConfigAddressValue));
|
|||
|
|
|||
|
WRITE_REGISTER_UCHAR((PUCHAR)HalpPonceConfigDataReg + (Offset % sizeof(ULONG)), *Buffer);
|
|||
|
|
|||
|
return;
|
|||
|
}
|
|||
|
// S001 ^^^
|