Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

938 lines
21 KiB

/*++
Copyright (c) 1995 International Business Machines Corporation
Module Name:
pxwd.c
Abstract:
This module implements the HAL display initialization and output routines
for a PowerPC system using a Western Digital video adapter.
Author:
Jim Wooldridge
Environment:
Kernel mode
Revision History:
--*/
#include "halp.h"
#include "pxwd.h"
#include "string.h"
//#include "txtpalet.h"
#include "pci.h"
//
// Data Types used only in this file
//
typedef enum _LCD_TYPE{
NOT_CHECKED = 0x00, // panel type has not been checked yet
NoLCD = 0x01, // CRT
IBM_F8515 = 0x02, // CRT + IBM F8515 10.4" TFT LCD
IBM_F8532 = 0x04, // CRT + IBM F8532 10.4" TFT SVGA LCD
TOSHIBA_DSTNC = 0x08, // CRT + Toshiba 10.4" Dual Scan STN Color LCD
UNKNOWN_LCD = 0x80 // panel not recognized
} LCD_TYPE;
typedef struct{
LCD_TYPE Type;
ULONG XResolution;
ULONG YResolution;
} PANEL_REC;
extern PUCHAR HalpVideoMemoryBase;
extern BOOLEAN HalpDisplayOwnedByHal;
extern ULONG HalpInitPhase;
//
// Define OEM font variables.
//
extern USHORT HalpBytesPerRow;
extern USHORT HalpCharacterHeight;
extern USHORT HalpCharacterWidth;
extern ULONG HalpDisplayText;
extern ULONG HalpDisplayWidth;
extern ULONG HalpScrollLength;
extern ULONG HalpScrollLine;
//
// Define display variables.
//
extern ULONG HalpColumn;
extern ULONG HalpRow;
extern ULONG HalpHorizontalResolution;
extern ULONG HalpVerticalResolution;
//
// Prototypes
//
VOID
GetPanelType(),
TurnOnLCD( BOOLEAN );
extern VOID WaitForVSync();
//
// Global variables
//
PANEL_REC
LCDPanel = {NOT_CHECKED, 0, 0};
//
// Western Digital internal functions
//
static VOID
LockPR (
USHORT PRnum,
PUCHAR pPRval
)
{
USHORT pIndex, pData;
UCHAR Index, Data;
switch (PRnum) {
case pr5:
pIndex = PORT_GCR_INDEX;
pData = PORT_GCR_DATA;
Index = pr5;
Data = pr5_lock;
break;
case pr10:
pIndex = WD_3D4_Index;
pData = WD_3D5_Data;
Index = pr10;
Data = pr10_lock;
break;
case pr11:
pIndex = WD_3D4_Index;
pData = WD_3D5_Data;
Index = pr11;
Data = pr11_lock;
break;
case pr1b:
// case pr1b_ual:
// case pr1b_ush:
// case pr1b_upr:
pIndex = WD_3D4_Index;
pData = WD_3D5_Data;
Index = pr1b;
Data = pr1b_lock;
break;
case pr20:
pIndex = PORT_SEQ_INDEX;
pData = PORT_SEQ_DATA;
Index = pr20;
Data = pr20_lock;
break;
case pr30:
pIndex = WD_3D4_Index;
pData = WD_3D5_Data;
Index = pr30;
Data = pr30_lock;
break;
case pr72_alt:
pIndex = PORT_SEQ_INDEX;
pData = PORT_SEQ_DATA;
Index = pr72;
Data = pr72_lock;
break;
default:
return;
} /* endswitch */
WRITE_WD_UCHAR( pIndex, Index );
if (pPRval!=NULL) {
*pPRval = READ_WD_UCHAR( pData );
} /* endif */
WRITE_WD_UCHAR( pData, Data );
}
static VOID
UnlockPR (
USHORT PRnum,
PUCHAR pPRval
)
{
USHORT pIndex, pData;
UCHAR Index, Data;
switch (PRnum) {
case pr5:
pIndex = PORT_GCR_INDEX;
pData = PORT_GCR_DATA;
Index = pr5;
Data = pr5_unlock;
break;
case pr10:
pIndex = WD_3D4_Index;
pData = WD_3D5_Data;
Index = pr10;
Data = pr10_unlock;
break;
case pr11:
pIndex = WD_3D4_Index;
pData = WD_3D5_Data;
Index = pr11;
Data = pr11_unlock;
break;
// case pr1b:
case pr1b_ual:
pIndex = WD_3D4_Index;
pData = WD_3D5_Data;
Index = pr1b;
Data = pr1b_unlock;
break;
case pr1b_ush:
pIndex = WD_3D4_Index;
pData = WD_3D5_Data;
Index = pr1b;
Data = pr1b_unlock_shadow;
break;
case pr1b_upr:
pIndex = WD_3D4_Index;
pData = WD_3D5_Data;
Index = pr1b;
Data = pr1b_unlock_pr;
break;
case pr20:
pIndex = PORT_SEQ_INDEX;
pData = PORT_SEQ_DATA;
Index = pr20;
Data = pr20_unlock;
break;
case pr30:
pIndex = WD_3D4_Index;
pData = WD_3D5_Data;
Index = pr30;
Data = pr30_unlock;
break;
case pr72_alt:
pIndex = PORT_SEQ_INDEX;
pData = PORT_SEQ_DATA;
Index = pr72;
Data = pr72_unlock;
break;
default:
return;
} /* endswitch */
WRITE_WD_UCHAR( pIndex, Index );
if (pPRval!=NULL) {
*pPRval = READ_WD_UCHAR( pData );
} /* endif */
WRITE_WD_UCHAR( pData, Data );
}
static VOID
RestorePR (
USHORT PRnum,
PUCHAR pPRval
)
{
USHORT pIndex, pData;
UCHAR Index, Data;
switch (PRnum) {
case pr5:
pIndex = PORT_GCR_INDEX;
pData = PORT_GCR_DATA;
Index = pr5;
break;
case pr10:
pIndex = WD_3D4_Index;
pData = WD_3D5_Data;
Index = pr10;
break;
case pr11:
pIndex = WD_3D4_Index;
pData = WD_3D5_Data;
Index = pr11;
break;
case pr1b:
// case pr1b_ual:
// case pr1b_ush:
// case pr1b_upr:
pIndex = WD_3D4_Index;
pData = WD_3D5_Data;
Index = pr1b;
break;
case pr20:
pIndex = PORT_SEQ_INDEX;
pData = PORT_SEQ_DATA;
Index = pr20;
break;
case pr30:
pIndex = WD_3D4_Index;
pData = WD_3D5_Data;
Index = pr30;
break;
case pr72_alt:
pIndex = PORT_SEQ_INDEX;
pData = PORT_SEQ_DATA;
Index = pr72;
break;
default:
return;
} /* endswitch */
Data = *pPRval;
WRITE_WD_UCHAR( pIndex, Index );
WRITE_WD_UCHAR( pData, Data );
}
static VOID
SetWDVGAConfig (
VOID
)
/*++
Routine Description:
Set WDVGA compatible configuration except DAC.
Arguments:
None.
Return Value:
None.
--*/
{
UCHAR SavePR5, SavePR10, SavePR11, SavePR20, SavePR72, Temp;
PUCHAR pPRtable;
LockPR( pr1b, NULL );
LockPR( pr30, NULL );
UnlockPR( pr20, NULL );
UnlockPR( pr10, &SavePR10 );
UnlockPR( pr11, &SavePR11 );
// non-ISO monitor setting clock
WRITE_WD_UCHAR( PORT_SEQ_INDEX, CLOCKING_MODE );
Temp = READ_WD_UCHAR( PORT_SEQ_DATA );
WRITE_WD_UCHAR( PORT_SEQ_DATA, (Temp | 0x01));
Temp = READ_WD_UCHAR( PORT_GEN_MISC_RD );
WRITE_WD_UCHAR( PORT_GEN_MISC_WR, (Temp & 0xf3));
// other clocking chip selects
UnlockPR( pr72_alt, &SavePR72 );
RestorePR( pr72_alt, &SavePR72 );
RestorePR( pr11, &SavePR11 );
RestorePR( pr10, &SavePR10 );
LockPR( pr20, NULL );
// start of WD90C24A2 both screen mode table
if( LCDPanel.Type == IBM_F8532 )
pPRtable = wd90c24a_both_800;
else
pPRtable = wd90c24a_both_640;
while (*pPRtable != END_PVGA) {
switch (*pPRtable++) {
case W_CRTC :
WRITE_WD_UCHAR( WD_3D4_Index, *pPRtable++ );
WRITE_WD_UCHAR( WD_3D5_Data, *pPRtable++ );
break;
case W_SEQ :
WRITE_WD_UCHAR( PORT_SEQ_INDEX, *pPRtable++ );
WRITE_WD_UCHAR( PORT_SEQ_DATA, *pPRtable++ );
break;
case W_GCR :
WRITE_WD_UCHAR( PORT_GCR_INDEX, *pPRtable++ );
WRITE_WD_UCHAR( PORT_GCR_DATA, *pPRtable++ );
break;
default :
break;
}
}
// unlock FLAT registers
UnlockPR( pr1b_ual, NULL );
WRITE_WD_UCHAR( PORT_SEQ_INDEX, pr68 );
Temp = READ_WD_UCHAR( PORT_SEQ_DATA );
if( LCDPanel.Type == IBM_F8532 )
WRITE_WD_UCHAR( PORT_SEQ_DATA, ((Temp & 0xe7) | 0x10) );
else
WRITE_WD_UCHAR( PORT_SEQ_DATA, ((Temp & 0xe7) | 0x08) );
WRITE_WD_UCHAR( WD_3D4_Index, pr19 );
if( LCDPanel.Type == IBM_F8532 )
WRITE_WD_UCHAR( WD_3D5_Data, (pr19_s32 & 0xf3));
else
WRITE_WD_UCHAR( WD_3D5_Data, (pr19_s32 & 0xf3));
// lock FLAT registers
LockPR( pr1b, NULL );
} /* SetWDVGAConfig */
VOID
HalpDisplayPpcWDSetup (
VOID
)
/*++
Routine Description:
This routine initializes the Western Digital display controller chip.
Arguments:
None.
Return Value:
None.
--*/
{
ULONG DataLong, stop;
USHORT i, j;
UCHAR DataByte;
UCHAR Index;
PVOID Index_3x4, Data_3x5;
ULONG MemBase;
PHYSICAL_ADDRESS physicalAddress;
if (HalpInitPhase == 0) {
HalpVideoMemoryBase = (PUCHAR)KePhase0MapIo(PCI_MEMORY_PHYSICAL_BASE,
0x400000); // 4 MB
} else {
//
// Map video memory space via pte's
//
physicalAddress.HighPart = 0;
physicalAddress.LowPart = PCI_MEMORY_PHYSICAL_BASE ;
HalpVideoMemoryBase = MmMapIoSpace(physicalAddress,
0x400000,
FALSE);
//
// IO control space has already been mapped in phase 1 via halpmapiospace
//
}
if( LCDPanel.Type == NOT_CHECKED )
GetPanelType();
// turn the panel off before configuring it (prevents blowing the fuse)
TurnOnLCD( FALSE );
// Enable Video Subsystem according to the WD90C24 reference book
WRITE_WD_UCHAR( SUBSYS_ENB, 0x16 );
WRITE_WD_UCHAR( Setup_OP, 0x01 );
WRITE_WD_UCHAR( SUBSYS_ENB, 0x0e );
WRITE_WD_UCHAR( PORT_SYS_VGA_ENABLE, VideoParam[0] );
SetWDVGAConfig();
// turn off the hardware cursor
WRITE_WD_USHORT( EPR_INDEX, 0x1002 );
WRITE_WD_USHORT( EPR_DATA, 0x0000 );
// Note: Synchronous reset must be done before MISC_OUT write operation
WRITE_WD_UCHAR( PORT_SEQ_INDEX, RESET ); // Synchronous Reset !
WRITE_WD_UCHAR( PORT_SEQ_DATA, 0x01 );
// For ATI card (0x63) we may want to change the frequence
if( LCDPanel.Type == IBM_F8532 )
WRITE_WD_UCHAR( PORT_GEN_MISC_WR, (VideoParam[1] & 0xf3) );
else
WRITE_WD_UCHAR( PORT_GEN_MISC_WR, VideoParam[1] );
// Note: Synchronous reset must be done before CLOCKING MODE register is
// modified
WRITE_WD_UCHAR( PORT_SEQ_INDEX, RESET ); // Synchronous Reset !
WRITE_WD_UCHAR( PORT_SEQ_DATA, 0x01 );
// Sequencer Register
for( Index = 1; Index < 5; Index++ )
{
WRITE_WD_UCHAR( PORT_SEQ_INDEX, Index );
WRITE_WD_UCHAR( PORT_SEQ_DATA, VideoParam[SEQ_OFFSET + Index] );
}
// Set CRT Controller
// out 3D4, 0x11, 00 (bit 7 must be 0 to unprotect CRT R0-R7)
// UnLockCR0_7();
WRITE_WD_UCHAR( WD_3D4_Index, VERTICAL_RETRACE_END );
DataByte = READ_WD_UCHAR( WD_3D5_Data );
DataByte = DataByte & 0x7f;
WRITE_WD_UCHAR( WD_3D5_Data, DataByte );
// CRTC controller CR0 - CR18
for( Index = 0; Index < 25; Index++ )
{
WRITE_WD_UCHAR( WD_3D4_Index, Index );
if( LCDPanel.Type == IBM_F8532 )
WRITE_WD_UCHAR( WD_3D5_Data, CRTC_800x600x60_Text[Index] );
else
WRITE_WD_UCHAR( WD_3D5_Data, CRTC_640x480x60_Text[Index] );
}
// attribute write
// program palettes and mode register
for( Index = 0; Index < 21; Index++ )
{
WaitForVSync();
DataByte = READ_WD_UCHAR( PORT_GEN_FEATURE_WR_C ); // Initialize Attr. F/F
WRITE_WD_UCHAR( PORT_ATTR_DATA_WR, Index );
// KeStallExecutionProcessor( 5 );
WRITE_WD_UCHAR( PORT_ATTR_INDEX, VideoParam[ATTR_OFFSET + Index] );
// KeStallExecutionProcessor( 5 );
WRITE_WD_UCHAR( PORT_ATTR_DATA_WR, 0x20 ); // Set into normal operation
}
WRITE_WD_UCHAR( PORT_SEQ_INDEX, RESET ); // reset to normal operation !
WRITE_WD_UCHAR( PORT_SEQ_DATA, 0x03 );
// graphics controller
for( Index = 0; Index < 9; Index++ )
{
WRITE_WD_UCHAR( PORT_GCR_INDEX, Index );
WRITE_WD_UCHAR( PORT_GCR_DATA, VideoParam[GRAPH_OFFSET + Index] );
}
// turn off the text mode cursor
WRITE_WD_UCHAR( WD_3D4_Index, CURSOR_START );
WRITE_WD_UCHAR( WD_3D5_Data, 0x2D );
// Load character fonts into plane 2 (A0000-AFFFF)
WRITE_WD_UCHAR( PORT_SEQ_INDEX, 0x02 ); // Enable Write Plane reg
WRITE_WD_UCHAR( PORT_SEQ_DATA, 0x04 ); // select plane 2
WRITE_WD_UCHAR( PORT_SEQ_INDEX, 0x04 ); // Memory Mode Control reg
WRITE_WD_UCHAR( PORT_SEQ_DATA, 0x06 ); // access to all planes,
WRITE_WD_UCHAR( PORT_GCR_INDEX, 0x05 ); // Graphic, Control Mode reg
WRITE_WD_UCHAR( PORT_GCR_DATA, 0x00 );
WRITE_WD_UCHAR( PORT_GCR_INDEX, 0x06 );
WRITE_WD_UCHAR( PORT_GCR_DATA, 0x04 );
WRITE_WD_UCHAR( PORT_GCR_INDEX, 0x04 );
WRITE_WD_UCHAR( PORT_GCR_DATA, 0x02 );
MemBase = 0xA0000; // Font Plane 2
for( i = 0; i < 256; i++ )
{
for( j = 0; j < 16; j++ )
{
WRITE_WD_VRAM( MemBase, VGAFont8x16[i * 16 + j] );
MemBase++;
}
// 32 bytes each character font
for( j = 16; j < 32; j++ )
{
WRITE_WD_VRAM( MemBase, 0 );
MemBase++;
}
}
// turn on screen
WRITE_WD_UCHAR( PORT_SEQ_INDEX, 0x01 );
DataByte = READ_WD_UCHAR( PORT_SEQ_DATA );
DataByte &= 0xdf;
DataByte ^= 0x0;
WRITE_WD_UCHAR( PORT_SEQ_DATA, DataByte );
WaitForVSync();
// Enable all the planes through the DAC
WRITE_WD_UCHAR( PORT_DAC_PIX_MASK, 0xff );
// start loading palette in register 0
WRITE_WD_UCHAR( PORT_DAC_WRITE_PIX_ADDR, 0 );
for( i = 0; i < 768; i++ )
{
WRITE_WD_UCHAR( PORT_DAC_DATA, TextPalette[i] );
}
//
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// select plane 0, 1
WRITE_WD_UCHAR( PORT_SEQ_INDEX, 0x02); // Enable Write Plane reg
WRITE_WD_UCHAR( PORT_SEQ_DATA, VideoParam[SEQ_OFFSET + 0x02] );
// access to planes 0, 1.
WRITE_WD_UCHAR( PORT_SEQ_INDEX, 0x04); // Memory Mode Control reg
WRITE_WD_UCHAR( PORT_SEQ_DATA, VideoParam[SEQ_OFFSET+0x04]);
WRITE_WD_UCHAR( PORT_GCR_INDEX, 0x05 ); // Graphic, Control Mode reg
WRITE_WD_UCHAR( PORT_GCR_DATA, VideoParam[GRAPH_OFFSET + 0x05] );
WRITE_WD_UCHAR( PORT_GCR_INDEX, 0x04);
WRITE_WD_UCHAR( PORT_GCR_DATA, VideoParam[GRAPH_OFFSET + 0x04] );
WRITE_WD_UCHAR( PORT_GCR_INDEX, 0x06);
WRITE_WD_UCHAR( PORT_GCR_DATA, VideoParam[GRAPH_OFFSET + 0x06] );
//
// Set screen into blue
//
if( LCDPanel.Type == IBM_F8532 )
stop = 0xb9db0;
else
stop = 0xb92c0;
for( DataLong = 0xB8000; DataLong < stop; DataLong += 2 )
{
WRITE_WD_VRAM( DataLong, 0x20 );
WRITE_WD_VRAM( DataLong + 1, 0x1F );
}
//
// turn the panel back on
//
TurnOnLCD( TRUE );
//
// Initialize the current display column, row, and ownership values.
//
HalpColumn = 0;
HalpRow = 0;
//IBMLAN===============================================================
// Added the following so that HalQueryDisplayParameters() and
// HalSetDisplayParameters() work with either S3 or P9.
if( LCDPanel.Type == IBM_F8532 )
{
HalpDisplayWidth = 100;
HalpDisplayText = 37;
HalpScrollLine = 200;
}
else
{
HalpDisplayWidth = 80;
HalpDisplayText = 25;
HalpScrollLine = 160;
}
HalpScrollLength =
HalpScrollLine * (HalpDisplayText - 1);
//end IBMLAN===========================================================
HalpDisplayOwnedByHal = TRUE;
return;
} /* end of InitializeWD() */
VOID
GetPanelType()
/*++
Routine Description:
This routine get the type of attached LCD display.
Arguments:
HwDeviceExtension - Pointer to the miniport driver's device extension.
Return Value:
None.
--*/
{
UCHAR data8;
//
// read the panel controller
//
WRITE_WD_UCHAR(0xd00, 0xff);
data8 = READ_WD_UCHAR(0xd01);
switch (data8 & 0x0f) {
case 0x0e:
LCDPanel.Type = IBM_F8515;
LCDPanel.XResolution = 640;
LCDPanel.YResolution = 480;
break;
case 0x0c:
LCDPanel.Type = IBM_F8532;
LCDPanel.XResolution = 800;
LCDPanel.YResolution = 600;
break;
case 0x0d:
LCDPanel.Type = TOSHIBA_DSTNC;
LCDPanel.XResolution = 640;
LCDPanel.YResolution = 480;
break;
default:
LCDPanel.Type = UNKNOWN_LCD;
LCDPanel.XResolution = 0;
LCDPanel.YResolution = 0;
break;
}
} // end GetPanelType()
BOOLEAN
HalpPhase0EnablePmController()
{
ULONG i, BaseAddress;
USHORT VendorID, DeviceID, Command;
//
// Locates the controller on the PCI bus, and configures it
//
if (HalpPhase0MapBusConfigSpace() == FALSE){
return( FALSE );
} else {
for (i = 0; i < PCI_MAX_DEVICES; i++) {
HalpPhase0GetPciDataByOffset(0,
i,
&VendorID,
FIELD_OFFSET(PCI_COMMON_CONFIG,VendorID),
sizeof(VendorID));
HalpPhase0GetPciDataByOffset(0,
i,
&DeviceID,
FIELD_OFFSET(PCI_COMMON_CONFIG,DeviceID),
sizeof(DeviceID));
if ((VendorID == 0x1014) && (DeviceID == 0x001C)) {
HalpPhase0GetPciDataByOffset(0,
i,
&Command,
FIELD_OFFSET(PCI_COMMON_CONFIG,Command),
sizeof(Command));
Command |= PCI_ENABLE_IO_SPACE;
BaseAddress = (ULONG)0x4100;
HalpPhase0SetPciDataByOffset(0,
i,
&Command,
FIELD_OFFSET(PCI_COMMON_CONFIG,Command),
sizeof(Command));
HalpPhase0SetPciDataByOffset(0,
i,
&BaseAddress,
FIELD_OFFSET(PCI_COMMON_CONFIG,u.type0.BaseAddresses[0]),
sizeof(BaseAddress));
break;
} /* endif */
} /* endfor */
} /* end if map config space succeeds */
HalpPhase0UnMapBusConfigSpace();
return( TRUE );
}
BOOLEAN
HalpPhase1EnablePmController()
{
ULONG i;
PCI_SLOT_NUMBER slot;
PCI_COMMON_CONFIG PCIDeviceConfig;
slot.u.AsULONG = (ULONG)0;
//
// Locates the controller on the PCI bus, and configures it
//
for (i = 0; i < PCI_MAX_DEVICES; i++) {
slot.u.bits.DeviceNumber = i;
HalGetBusData (
PCIConfiguration,
0,
slot.u.AsULONG,
&PCIDeviceConfig,
sizeof (PCIDeviceConfig)
);
if ((PCIDeviceConfig.VendorID == 0x1014) &&
(PCIDeviceConfig.DeviceID == 0x001C)) {
PCIDeviceConfig.Command |= PCI_ENABLE_IO_SPACE;
PCIDeviceConfig.u.type0.BaseAddresses[0] = (ULONG)0x4100;
HalSetBusData (
PCIConfiguration,
0,
slot.u.AsULONG,
&PCIDeviceConfig,
sizeof (PCIDeviceConfig)
);
break;
} /* endif */
} /* endfor */
return( TRUE );
}
# define PmIoBase 0x4100
VOID
TurnOnLCD( BOOLEAN PowerState )
/*++
Routine Description:
This routine turns on/off LCD.
Arguments:
HwDeviceExtension - Pointer to the miniport driver's adapter information.
Return Value:
None.
--*/
{
BOOLEAN found = FALSE;
if (HalpInitPhase == 0)
found = HalpPhase0EnablePmController();
else
found = HalpPhase1EnablePmController();
if (!found) {
return;
} /* endif */
//
// Turns on/off LCD
//
if (PowerState) {
KeStallExecutionProcessor(100 * 1000); // wait 100ms for panel protection
WRITE_WD_UCHAR(PmIoBase, 0x0C);
WRITE_WD_UCHAR(PmIoBase + 1,
READ_WD_UCHAR(PmIoBase + 1) | (UCHAR)0x02);
KeStallExecutionProcessor(5 * 1000); // wait 5ms for DC/DC converter
WRITE_WD_UCHAR(PmIoBase, 0x0C);
WRITE_WD_UCHAR(PmIoBase + 1,
READ_WD_UCHAR(PmIoBase + 1) | (UCHAR)0x0c);
KeStallExecutionProcessor(1);
WRITE_WD_UCHAR(PmIoBase, 0x00);
WRITE_WD_UCHAR(PmIoBase + 1,
READ_WD_UCHAR(PmIoBase + 1) & ~(UCHAR)0x80);
KeStallExecutionProcessor(1);
WRITE_WD_UCHAR(PmIoBase, 0x0C);
WRITE_WD_UCHAR(PmIoBase + 1,
READ_WD_UCHAR(PmIoBase + 1) | (UCHAR)0x01);
} else {
WRITE_WD_UCHAR(PmIoBase, 0x0C);
WRITE_WD_UCHAR(PmIoBase + 1,
READ_WD_UCHAR(PmIoBase + 1) & ~(UCHAR)0x01);
KeStallExecutionProcessor(1);
WRITE_WD_UCHAR(PmIoBase, 0x00);
WRITE_WD_UCHAR(PmIoBase + 1,
READ_WD_UCHAR(PmIoBase + 1) | (UCHAR)0x80);
KeStallExecutionProcessor(1);
WRITE_WD_UCHAR(PmIoBase, 0x0C);
WRITE_WD_UCHAR(PmIoBase + 1,
READ_WD_UCHAR(PmIoBase + 1) & ~(UCHAR)0x0C);
KeStallExecutionProcessor(1);
WRITE_WD_UCHAR(PmIoBase, 0x0C);
WRITE_WD_UCHAR(PmIoBase + 1,
READ_WD_UCHAR(PmIoBase + 1) & ~(UCHAR)0x02);
} /* endif */
} // end TurnOnLCD()