181 lines
4 KiB
C
181 lines
4 KiB
C
|
/*++
|
|||
|
|
|||
|
Copyright (c) 1994-1995 International Buisness Machines Corporation
|
|||
|
Copyright (c) 1994-1995 Microsoft Corporation
|
|||
|
|
|||
|
Module Name:
|
|||
|
|
|||
|
sdac.c
|
|||
|
|
|||
|
Abstract:
|
|||
|
|
|||
|
This module contains the code that initializes the S3 SDAC.
|
|||
|
|
|||
|
Environment:
|
|||
|
|
|||
|
Kernel mode
|
|||
|
|
|||
|
Revision History:
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
#include "s3.h"
|
|||
|
|
|||
|
#if defined(ALLOC_PRAGMA)
|
|||
|
#pragma alloc_text(PAGE,InitializeSDAC)
|
|||
|
#pragma alloc_text(PAGE,FindSDAC)
|
|||
|
#endif
|
|||
|
|
|||
|
|
|||
|
BOOLEAN
|
|||
|
InitializeSDAC( PHW_DEVICE_EXTENSION HwDeviceExtension )
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Initializes the SDAC.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
HwDeviceExtension - Supplies a pointer to the miniport's device extension.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
Always TRUE
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
|
|||
|
SDAC_PLL_PARMS
|
|||
|
*SdacClk0;
|
|||
|
|
|||
|
ULONG
|
|||
|
tablebase;
|
|||
|
|
|||
|
UCHAR
|
|||
|
i,
|
|||
|
clk,
|
|||
|
dval,
|
|||
|
old55;
|
|||
|
|
|||
|
|
|||
|
tablebase = HwDeviceExtension->ActiveFrequencyEntry->Fixed.Clock;
|
|||
|
clk = (UCHAR) tablebase;
|
|||
|
|
|||
|
tablebase = (tablebase < 8) ? 0 : ((tablebase - 2) / 6) * 6;
|
|||
|
SdacClk0 = &SdacTable[tablebase];
|
|||
|
|
|||
|
clk -= (UCHAR) tablebase;
|
|||
|
clk |= 0x20;
|
|||
|
|
|||
|
// set RS[2] with CR55[0];
|
|||
|
VideoPortWritePortUchar(CRT_ADDRESS_REG, 0x55);
|
|||
|
dval = VideoPortReadPortUchar(CRT_DATA_REG);
|
|||
|
old55 = dval;
|
|||
|
dval &= 0xfc;
|
|||
|
dval |= 0x01;
|
|||
|
VideoPortWritePortUchar(CRT_DATA_REG, dval);
|
|||
|
VideoPortReadPortUchar(CRT_DATA_REG);
|
|||
|
|
|||
|
// Enhanced Command Register
|
|||
|
if( HwDeviceExtension->ActiveFrequencyEntry->BitsPerPel == 16 )
|
|||
|
VideoPortWritePortUchar(DAC_PIXEL_MASK_REG, 0x50);
|
|||
|
else
|
|||
|
VideoPortWritePortUchar(DAC_PIXEL_MASK_REG, 0x00);
|
|||
|
|
|||
|
// Program CLK0 registers
|
|||
|
for( i = 2; i < 8; ++i ) // write registers f2 - f7 only
|
|||
|
{
|
|||
|
// make sure we don't run off the end of the table
|
|||
|
if( (ULONG_PTR) &SdacClk0[i] >= (ULONG_PTR) &SdacTable[SDAC_TABLE_SIZE] )
|
|||
|
break;
|
|||
|
|
|||
|
if( SdacClk0[i].m || SdacClk0[i].n )
|
|||
|
{
|
|||
|
VideoPortWritePortUchar(DAC_ADDRESS_WRITE_PORT, i);
|
|||
|
VideoPortWritePortUchar(DAC_DATA_REG_PORT, SdacClk0[i].m);
|
|||
|
VideoPortWritePortUchar(DAC_DATA_REG_PORT, SdacClk0[i].n);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// Program CLK1
|
|||
|
VideoPortWritePortUchar(DAC_ADDRESS_WRITE_PORT, 0x0a);
|
|||
|
VideoPortWritePortUchar(DAC_DATA_REG_PORT, 0x41);
|
|||
|
VideoPortWritePortUchar(DAC_DATA_REG_PORT, 0x26);
|
|||
|
|
|||
|
// select CLK0 with the PLL control register
|
|||
|
VideoPortWritePortUchar(DAC_ADDRESS_WRITE_PORT, 0x0e);
|
|||
|
VideoPortWritePortUchar(DAC_DATA_REG_PORT, clk);
|
|||
|
|
|||
|
// restore CR55
|
|||
|
VideoPortWritePortUchar(CRT_ADDRESS_REG, 0x55);
|
|||
|
VideoPortWritePortUchar(CRT_DATA_REG, old55);
|
|||
|
|
|||
|
return( TRUE );
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
BOOLEAN
|
|||
|
FindSDAC( PHW_DEVICE_EXTENSION HwDeviceExtension )
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Detects and S3 SDAC.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
HwDeviceExtension - Supplies a pointer to the miniport's device extension.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
TRUE if SDAC detected; FALSE if not.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
|
|||
|
UCHAR
|
|||
|
regval,
|
|||
|
old55;
|
|||
|
|
|||
|
|
|||
|
// 4 consecutive reads of the SDAC's Pixel Mask Register cause
|
|||
|
// the next access to that register to be redirected to the
|
|||
|
// SDAC's Enhanced Command Register, additionally the 4th read
|
|||
|
// returns 0x70 to identify the SDAC
|
|||
|
|
|||
|
// set CR55[0] to access the Pixel Mask Register
|
|||
|
VideoPortWritePortUchar( CRT_ADDRESS_REG, 0x55 );
|
|||
|
old55 = VideoPortReadPortUchar( CRT_DATA_REG );
|
|||
|
VideoPortWritePortUchar( CRT_DATA_REG, (UCHAR) (old55 & 0xfc) );
|
|||
|
|
|||
|
// look for the SDAC's ID
|
|||
|
VideoPortWritePortUchar( DAC_PIXEL_MASK_REG, 0 );
|
|||
|
VideoPortWritePortUchar( DAC_PIXEL_MASK_REG, 0xff );
|
|||
|
VideoPortReadPortUchar( DAC_PIXEL_MASK_REG );
|
|||
|
VideoPortReadPortUchar( DAC_PIXEL_MASK_REG );
|
|||
|
VideoPortReadPortUchar( DAC_PIXEL_MASK_REG );
|
|||
|
|
|||
|
regval = VideoPortReadPortUchar( DAC_PIXEL_MASK_REG );
|
|||
|
|
|||
|
if( (regval & 0xf0) == 0x70 )
|
|||
|
{
|
|||
|
// clear the redirection
|
|||
|
VideoPortReadPortUchar( DAC_PIXEL_MASK_REG );
|
|||
|
return( TRUE );
|
|||
|
}
|
|||
|
|
|||
|
// restore the contents of register 55
|
|||
|
VideoPortWritePortUchar( CRT_ADDRESS_REG, 0x55 );
|
|||
|
VideoPortWritePortUchar( CRT_DATA_REG, old55 );
|
|||
|
|
|||
|
return( FALSE );
|
|||
|
|
|||
|
}
|