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.
 
 
 
 
 
 

1546 lines
39 KiB

/*++
Copyright (c) 1995 International Business Machines Corporation
Module Name:
pxbbl.c
Abstract:
This module implements the HAL display initialization and output routines
for a PowerPC system using a GXT150P (Baby Blue) video adapter.
Author:
Jake Oshins
Environment:
Kernel mode
Revision History:
--*/
#include "halp.h"
#include "pci.h"
#include "pcip.h"
#include "string.h"
// Include GXT150P header file information
#include "bblrastz.h"
#include "bblrmdac.h"
#include "bbldef.h"
extern ULONG HalpInitPhase;
extern PUCHAR HalpVideoMemoryBase;
extern PUCHAR HalpVideoCoprocBase;
extern ULONG HalpColumn;
extern ULONG HalpRow;
extern ULONG HalpHorizontalResolution;
extern ULONG HalpVerticalResolution;
extern USHORT HalpBytesPerRow;
extern USHORT HalpCharacterHeight;
extern USHORT HalpCharacterWidth;
extern ULONG HalpDisplayText;
extern ULONG HalpDisplayWidth;
extern ULONG HalpScrollLength;
extern ULONG HalpScrollLine;
extern BOOLEAN HalpDisplayOwnedByHal;
extern POEM_FONT_FILE_HEADER HalpFontHeader;
extern ULONG HalpPciMaxSlots;
extern UCHAR TextPalette[];
#define TAB_SIZE 4
VOID
HalpDisplayPpcBBLSetup (
VOID
);
VOID
HalpDisplayCharacterBBL (
IN UCHAR Character
);
VOID
HalpOutputCharacterBBL(
IN PUCHAR Glyph
);
BOOLEAN
BBLGetConfigurationRegister (
IN ULONG dev_ven_id,
IN ULONG offset,
IN PULONG reg_value
);
BOOLEAN
BBLSetConfigurationRegister (
IN ULONG dev_ven_id,
IN ULONG offset,
IN ULONG reg_value
);
VOID
BBLScrollScreen(
VOID
);
BOOLEAN
BBLInitialize (
ULONG monID,
volatile PUCHAR HalpBBLRegisterBase
);
BOOLEAN
BBLGetMonitorID (
PULONG monID,
volatile PUCHAR HalpBBLRegisterBase
);
VOID
BBLWaitForVerticalSync (
volatile PUCHAR HalpBBLRegisterBase
);
VOID
HalpDisplayPpcBBLSetup (
VOID
)
/*++
Routine Description:
This routine initializes the GXT150P Graphics Adapter
Arguments:
None.
Return Value:
None.
--*/
{
ULONG rc, status, monID, count, value;
volatile PUCHAR HalpBBLRegisterBase = (PUCHAR)0;
ULONG buffer[(BBL_BELE_VAL + 2) >> 2];
PPCI_COMMON_CONFIG PciData;
PCI_SLOT_NUMBER PciSlot;
bbl_mon_data_t *bbl_mon_data_ptr;
BOOLEAN found, ok;
PHYSICAL_ADDRESS physaddr;
PHYSICAL_ADDRESS bbl_phys_address;
PciData = (PPCI_COMMON_CONFIG) buffer;
//
// There is no need to have both the register space and the
// DFA space mapped at the same time. This will save us from
// having multiple I/O spaces mapped at the same time. Thus
// saving DBATs which are in very very short supply...
//
//
// Strategy:
//
// 1. Map the PCI configuration register space
// 2. Update the PCI configuration registers
// 3. Unmap the PCI configuration register space
// 4. Map the register space
// 5. Reset the device
// 6. Read the monitor ID to figure what resolution and refresh mode to use
// 7. Perform device re-initialization (rasterizer, ramdac,
// and color palette)
// 8. Unmap the register space
// 9. Map the DFA space
// 10. Clear out VRAM to the default background color
// 11. Now can do character blits
//
/*******************************************************************/
/* S E T P C I C O N F I G U R A T I O N R E G I S T E R S */
/*******************************************************************/
bbl_phys_address.HighPart = 0x0; //PCI bus devices are in a 32-bit memory space
ok = BBLGetConfigurationRegister (BBL_DEV_VEND_ID,
FIELD_OFFSET(PCI_COMMON_CONFIG,u.type0.BaseAddresses[0]),
&bbl_phys_address.LowPart );
bbl_phys_address.LowPart += PCI_MEMORY_PHYSICAL_BASE; // translate bus-relative address
if(ok == TRUE){
value = BBL_BELE_VAL;
ok = BBLSetConfigurationRegister (BBL_DEV_VEND_ID, 0x70, value );
}
if(ok == FALSE){
return;
}
/**************************************************/
/* M A P T H E R E G I S T E R S P A C E */
/**************************************************/
//
// Map the the adapter register range into memory. Please note that this
// adapter will respond to all 256meg of addresses in the address range
// given even though we are only temporarily mapping a small region
//
if (HalpInitPhase == 0) {
BBL_DBG_PRINT("call KePhase0MapIo() to map the reg space. Phys=0x%x Len=0x%x %d\n",
bbl_phys_address.LowPart + BBL_REG_ADDR_OFFSET,
BBL_REG_ADDR_LENGTH,
BBL_REG_ADDR_LENGTH);
HalpBBLRegisterBase = (PUCHAR)KePhase0MapIo(bbl_phys_address.LowPart + BBL_REG_ADDR_OFFSET,
BBL_REG_ADDR_LENGTH); // 4 K
} else {
physaddr.HighPart = 0;
physaddr.LowPart = bbl_phys_address.LowPart + BBL_REG_ADDR_OFFSET;
HalpBBLRegisterBase = (PUCHAR)MmMapIoSpace(physaddr,
BBL_REG_ADDR_LENGTH,
FALSE);
}
BBL_DBG_PRINT("HalpBBLRegisterBase = 0x%x\n", HalpBBLRegisterBase);
/**************************************************/
/* F I N D F O N T T O U S E */
/**************************************************/
//IBMLAN Use font file from OS Loader
//
// Compute display variables using using HalpFontHeader which is
// initialized in HalpInitializeDisplay().
//
// 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.
//
HalpBytesPerRow = (HalpFontHeader->PixelWidth + 7) / 8;
HalpCharacterHeight = HalpFontHeader->PixelHeight;
HalpCharacterWidth = HalpFontHeader->PixelWidth;
BBL_DBG_PRINT("PixelWidth = %d PixelHeight = %d\n HalpFontHeader = 0x%x\n",
HalpFontHeader->PixelWidth, HalpFontHeader->PixelHeight, HalpFontHeader);
/*********************************************/
/* D I S A B L E V I D E O D I S P L A Y */
/*********************************************/
//
// Turn off display outputs from the ramdac so the screen will go
// blank while resetting the adapter and resetting it up
//
/*
* Disable Video
*/
BBL_DBG_PRINT ("disable video display\n");
/* Set the ramdac configuration to default values and disable */
/* display outputs so nothing is displayed on the screen during */
/* initialization */
/* Config low ... */
BBL_DBG_PRINT ("Write config register low = 0x%x\n", 0x00);
BBL_SET_RAMDAC_ADDRESS_REGS( BBL_REG_BASE, BBL_RAMDAC_CONFIG_LOW_REG );
BBL_SET_RAMDAC_DATA_NON_LUT( BBL_REG_BASE, 0x00 );
/* Config high ... */
BBL_DBG_PRINT ("Write config register high = 0x%x\n", 0x08);
BBL_SET_RAMDAC_ADDRESS_REGS( BBL_REG_BASE, BBL_RAMDAC_CONFIG_HIGH_REG );
BBL_SET_RAMDAC_DATA_NON_LUT( BBL_REG_BASE, 0x08 );
/*********************************************/
/* R E S E T C A R D */
/*********************************************/
//
// Attempt to reset the card. The only this can be done is to first
// read the status register, if the status register indicates that the
// FIFO is empty and the adapter is idle, then we're good-to-go. If
// the adapter is busy and the FIFO is empty, send a RESET_CURRENT_CMD
// down the FIFO and see if the adapter becomes idle. If the adapter
// does not become idle after a few milliseconds, send 0x0's down the
// command port checking status in between each time for adapter idle.
// If, after sending down many 0x0's, or if the adapter FIFO was originally
// not empty, we have a hung adapter, and there is absolutely nothing
// that we can do, which means we're dead, so return
//
status = BBL_GET_REG(BBL_REG_BASE, BBL_STATUS_REG);
if(status & BBL_CACHE_LINE_BUFFER_EMPTY){
BBL_DBG_PRINT("adapter FIFO is empty\n");
if(status & BBL_ADAPTER_BUSY){
BBL_DBG_PRINT("adapter is busy, attempting reset\n");
// Send down a RESET_CURRENT_COMMAND to the adapter
BBL_SET_REG(BBL_REG_BASE, BBL_RESET_CURRENT_CMD_REG, 0x0);
BBL_EIEIO;
// Wait to see if the adapter comes back
for(count=0;((count < 100000)&&(status & BBL_ADAPTER_BUSY));count++){
status = BBL_GET_REG(BBL_REG_BASE, BBL_STATUS_REG);
}
// If adapter still is busy, attempt sending 0x0's to the
// command port to force it to finish whatever it was doing last
if(status & BBL_ADAPTER_BUSY){
BBL_DBG_PRINT("adapter is still busy, attempting to send NULL command data\n");
for(count=0;((count < 10000)&&(status & BBL_ADAPTER_BUSY));count++){
BBL_SET_REG(BBL_REG_BASE, BBL_CMD_DATA_REG, 0x0);
status = BBL_GET_REG(BBL_REG_BASE, BBL_STATUS_REG);
}
// If we're still hung, we're dead, so just return
if(status & BBL_ADAPTER_BUSY){
BBL_DBG_PRINT("adapter hung, giving up\n");
#ifdef KDB
DbgBreakPoint();
#endif
return;
}else{
BBL_DBG_PRINT("adapter is NOT busy, sent NULL cmd/data down for %d loops\n", count);
}
}else{
BBL_DBG_PRINT("adapter is NOT busy, waited for %d loops\n", count);
}
}else{
BBL_DBG_PRINT("adapter is NOT busy\n");
}
}else{
// The adapter FIFO is not empty which indicates that it is hung, so return
BBL_DBG_PRINT("adapter FIFO is not empty\n");
BBL_DBG_PRINT("adapter hung, giving up\n");
#ifdef KDB
DbgBreakPoint();
#endif
return;
}
/*********************************************/
/* G E T M O N I T O R I D */
/*********************************************/
//
// Read the monitor ID from the card to determine what resolution
// to use
//
if(BBLGetMonitorID(&monID, HalpBBLRegisterBase) == FALSE){
BBL_DBG_PRINT("BBLGetMonitorID() failed\n");
#ifdef KDB
DbgBreakPoint();
#endif
return;
}
//
// Find the correct monitor ID information structure based on
// the monitor ID returned from the BBLGetMonitorID() function
//
// Find the monitor info structure from the monitor table
// Search for matching monitor ID */
bbl_mon_data_ptr = &bbl_mon_data[0];
do{
if(bbl_mon_data_ptr->monitor_id == monID)
break;
++bbl_mon_data_ptr;
}while(bbl_mon_data_ptr->monitor_id != BBL_MT_DEFAULT);
// If we did not find our ID in the table, use the default
// The last entry in the table is the default entry...
BBL_DBG_PRINT("&bbl_mon_data[0]=0x%x bbl_mon_data_ptr=0x%x\n",
&bbl_mon_data[0], bbl_mon_data_ptr);
/*********************************************/
/* S E T H A L V A R I A B L E S */
/*********************************************/
//
// set the correct horizontal and vertical resolutions for HAL
//
HalpHorizontalResolution = bbl_mon_data_ptr->x_res;
HalpVerticalResolution = bbl_mon_data_ptr->y_res;
BBL_DBG_PRINT("HalpHorizontalResolution = %d HalpVerticalResolution = %d\n",
HalpHorizontalResolution, HalpVerticalResolution);
//
// Compute character output display parameters.
//
HalpDisplayText =
HalpVerticalResolution / HalpCharacterHeight;
// GXT150P real scanline length is hardcoded at 2048 pixels independent
// of the resolution on the screen
HalpScrollLine =
BBL_SCANLINE_LENGTH * HalpCharacterHeight;
HalpScrollLength = HalpScrollLine * (HalpDisplayText - 1);
HalpDisplayWidth =
HalpHorizontalResolution / HalpCharacterWidth;
BBL_DBG_PRINT("DisplayText = %d ScrollLine = %d ScrollLength = %d DisplayWidth = %d\n",
HalpDisplayText, HalpScrollLine, HalpScrollLength, HalpDisplayWidth);
/**************************************************/
/* R E I N I T I A L I Z E T H E C A R D */
/**************************************************/
//
// Initialize the adapter card for the resolution found by looking
// at the monitor ID
//
if(BBLInitialize(monID, HalpBBLRegisterBase) == FALSE){
BBL_DBG_PRINT("BBLInitialize(monID=0x%x) failed\n", monID);
#ifdef KDB
DbgBreakPoint();
#endif
return;
}
/*********************************************/
/* U N M A P R E G I S T E R S P A C E */
/*********************************************/
//
// Unmap the the adapter register range from memory. Please note that this
// adapter will respond to all 256meg of addresses in the address range
// given even though we are only temporarily mapping a small region
//
if (HalpInitPhase == 0) {
if (HalpBBLRegisterBase) {
BBL_DBG_PRINT("call KePhase0DeleteIoMap() to unmap the reg space. Phys=0x%x Len=0x%x %d\n",
bbl_phys_address.LowPart + BBL_REG_ADDR_OFFSET, BBL_REG_ADDR_LENGTH, BBL_REG_ADDR_LENGTH);
KePhase0DeleteIoMap(bbl_phys_address.LowPart + BBL_REG_ADDR_OFFSET, BBL_REG_ADDR_LENGTH);
HalpBBLRegisterBase = 0x0;
}
}
/*************************************************/
/* M A P F R A M E B U F F E R S P A C E */
/*************************************************/
//
// Map in the frame buffer memory which is used to write characters to
// the screen. Please note that this adapter will respond to all 256meg
// of addresses in the address range
//
if (HalpInitPhase == 0) {
BBL_DBG_PRINT("call KePhase0MapIo() to map the FB_A space. Phys=0x%x Len=0x%x %d\n",
bbl_phys_address.LowPart + BBL_VIDEO_MEMORY_OFFSET,
BBL_VIDEO_MEMORY_LENGTH,
BBL_VIDEO_MEMORY_LENGTH);
HalpVideoMemoryBase = (PUCHAR)KePhase0MapIo(bbl_phys_address.LowPart + BBL_VIDEO_MEMORY_OFFSET,
BBL_VIDEO_MEMORY_LENGTH); // 2 MB
}
BBL_DBG_PRINT("HalpVideoMemoryBase = 0x%x\n", HalpVideoMemoryBase);
/*********************************************/
/* M I S C A N D R E T U R N */
/*********************************************/
//
// Initialize the current display column, row, and ownership values.
//
HalpColumn = 0;
HalpRow = 0;
HalpDisplayOwnedByHal = TRUE;
BBL_DBG_PRINT("leaving HalpDisplayPpcBBLSetup()\n");
return;
} //end of HalpDisplayPpcBBLSetup
BOOLEAN
BBLInitialize (
ULONG monID,
volatile PUCHAR HalpBBLRegisterBase
)
/*++
Routine Description:
Sets up the rasterizer and ramdac registers to the particular
resolution and refresh rate selected for the GXT150P card
Arguments:
monID -- indicates the resolution and refresh rate to use
Return Value:
The status of the operation (can only fail on a bad command); TRUE for
success, FALSE for failure.
--*/
{
bbl_mon_data_t *bbl_mon_data_ptr;
int i;
UCHAR bbl_clut[256*3];
BBL_DBG_PRINT("Entering BBLInitialize: monID = 0x%x\n", monID);
// Find the monitor info structure from the monitor table
// Search for matching monitor ID */
bbl_mon_data_ptr = &bbl_mon_data[0];
do{
if(bbl_mon_data_ptr->monitor_id == monID)
break;
++bbl_mon_data_ptr;
}while(bbl_mon_data_ptr->monitor_id != BBL_MT_DEFAULT);
// If we did not find our ID in the table, use the default
// The last entry in the table is the default entry...
BBL_DBG_PRINT("&bbl_mon_data[0]=0x%x bbl_mon_data_ptr=0x%x\n",
&bbl_mon_data[0], bbl_mon_data_ptr);
//
// Card has already been RESET and the display outputs been
// turned off
//
/*************************************************************/
/* B E G I N R A S T R E G I S T E R S E T U P */
/*************************************************************/
/*
* write Memory Configuration register
*
*/
BBL_DBG_PRINT ("Writing memory config register = 0x%x\n", 0x0c);
BBL_SET_REG( BBL_REG_BASE, BBL_CONFIG_REG, 0x0c );
/*
* set Interrupt Enable register
* disable all interrupts
*/
BBL_DBG_PRINT ("Disable all interrupts....\n");
BBL_SET_REG( BBL_REG_BASE, BBL_INTR_ENABLE_STATUS_REG, 0x70);
/*
* set Control register
*
*/
BBL_DBG_PRINT ("Writing control register = 0x%x\n", 0x01);
BBL_SET_REG( BBL_REG_BASE, BBL_CNTL_REG, 0x01 );
/****************************************/
/* B E G I N R A M D A C S E T U P */
/****************************************/
/*
* Turn off Hardware Cursor
*/
BBL_DBG_PRINT ("writing ICON Cursor control reg = DISABLE\n");
BBL_SET_ICON_CURSOR_CNTL( BBL_REG_BASE, 0x00);
/***********************/
/* S E T U P C R T C */
/***********************/
/*
* setup CRTC values
*/
BBL_DBG_PRINT ("\nSetup_CRTC:\n");
/*
* set PLL Reference register = 0x19
* set up PLL for reference frequency of 50Mhz.
*/
BBL_DBG_PRINT ("Set PLL Reference register at offset 0x%x = 0x%x\n",
BBL_RAMDAC_PLL_REF_REG, 0x19);
BBL_SET_PLL_REF_REG(BBL_REG_BASE, 50);
/*
* PLL VCO Divider Register -
*/
BBL_DBG_PRINT ("Set VCO_DIVIDER = 0x%x\n",
bbl_mon_data_ptr->pixel_freq);
BBL_SET_PLL_VCO_DIVIDER_REG( BBL_REG_BASE,
bbl_mon_data_ptr->pixel_freq );
/*
* CRT Control Register -
*/
BBL_DBG_PRINT ("Set DTG_CNTL=0x%x\n",
bbl_mon_data_ptr->crt_cntl);
BBL_SET_CRT_CNTL_REG( BBL_REG_BASE,
bbl_mon_data_ptr->crt_cntl);
/*
* Horizontal Total Register -
*/
BBL_DBG_PRINT ("Set HRZ_TOTAL=0x%x\n",
bbl_mon_data_ptr->hrz_total);
BBL_SET_HORIZONTAL_TOTAL_REG( BBL_REG_BASE,
bbl_mon_data_ptr->hrz_total);
/*
* Horizontal Display End Register -
*/
BBL_DBG_PRINT ("Set HRZ_DISP_END=0x%x\n",
(bbl_mon_data_ptr->x_res - 1));
BBL_SET_HORIZONTAL_DISPLAY_END_REG( BBL_REG_BASE,
(bbl_mon_data_ptr->x_res - 1));
/*
* Horizontal Sync Start Register -
*/
BBL_DBG_PRINT ("Set HRZ_SYNC_START=0x%x\n",
bbl_mon_data_ptr->hrz_sync_start);
BBL_SET_HORIZONTAL_SYNC_START_REG(BBL_REG_BASE,
bbl_mon_data_ptr->hrz_sync_start);
/*
* Horizontal Sync End1 Register -
*/
BBL_DBG_PRINT ("Set HRZ_SYNC_END1=0x%x\n",
bbl_mon_data_ptr->hrz_sync_end1);
BBL_SET_HORIZONTAL_SYNC_END1_REG(BBL_REG_BASE,
bbl_mon_data_ptr->hrz_sync_end1);
/*
* Horizontal Sync End2 Register -
*/
BBL_DBG_PRINT ("Set HRZ_SYNC_END2=0x%x\n",
bbl_mon_data_ptr->hrz_sync_end2);
BBL_SET_HORIZONTAL_SYNC_END2_REG(BBL_REG_BASE,
bbl_mon_data_ptr->hrz_sync_end2);
/*
* Vertical Total Register -
*/
BBL_DBG_PRINT ("Set VERT_TOTAL=0x%x\n",
bbl_mon_data_ptr->vrt_total);
BBL_SET_VERTICAL_TOTAL_REG(BBL_REG_BASE,
bbl_mon_data_ptr->vrt_total);
/*
* Vertical Display End Register -
*/
BBL_DBG_PRINT ("Set VRT_DISP_END=0x%x\n",
(bbl_mon_data_ptr->y_res - 1));
BBL_SET_VERTICAL_DISPLAY_END_REG( BBL_REG_BASE,
(bbl_mon_data_ptr->y_res - 1));
/*
* Vertical Sync Start Register -
*/
BBL_DBG_PRINT ("Set VERT_SYNC_STRT=0x%x\n",
bbl_mon_data_ptr->vrt_sync_start);
BBL_SET_VERTICAL_SYNC_START_REG(BBL_REG_BASE,
bbl_mon_data_ptr->vrt_sync_start);
/*
* Vertical Sync End Register -
*/
BBL_DBG_PRINT ("Set VERT_SYNC_END=0x%x\n",
bbl_mon_data_ptr->vrt_sync_end);
BBL_SET_VERTICAL_SYNC_END_REG(BBL_REG_BASE,
bbl_mon_data_ptr->vrt_sync_end);
/*******************************************/
/* F I N I S H R A M D A C S E T U P */
/*******************************************/
/*
* set configuration register low
*/
BBL_DBG_PRINT ("Setting up config low register=0x%x\n", 0x31);
BBL_SET_RAMDAC_ADDRESS_REGS( BBL_REG_BASE, BBL_RAMDAC_CONFIG_LOW_REG );
BBL_SET_RAMDAC_DATA_NON_LUT( BBL_REG_BASE, 0x31 );
/*
* set Configuration high register
*/
BBL_DBG_PRINT ("Writing RAMDAC config register high = 0x%x\n", 0x68);
BBL_SET_RAMDAC_ADDRESS_REGS( BBL_REG_BASE, BBL_RAMDAC_CONFIG_HIGH_REG );
BBL_SET_RAMDAC_DATA_NON_LUT( BBL_REG_BASE, 0x68 );
/* Set the RGB format register */
BBL_SET_RAMDAC_ADDRESS_REGS( BBL_REG_BASE, BBL_RAMDAC_RGB_FORMAT_REG );
BBL_SET_RAMDAC_DATA_NON_LUT( BBL_REG_BASE, 0x00 );
/*
* set WID/OVRLY Mask register = 0x0f
*/
BBL_DBG_PRINT ("WID/OVRLY mask register = 0x%x\n",
BBL_DEFAULT_WID_OL_PIXEL_MASK_VALUE);
BBL_SET_RAMDAC_ADDRESS_REGS( BBL_REG_BASE, BBL_RAMDAC_WID_OL_MASK_REG );
BBL_SET_RAMDAC_DATA_NON_LUT( BBL_REG_BASE,
BBL_DEFAULT_WID_OL_PIXEL_MASK_VALUE );
/*
* Set Pixel Mask
*/
BBL_DBG_PRINT ("Writing Pixel Mask register = 0x%x\n",
BBL_DEFAULT_WID_OL_PIXEL_MASK_VALUE);
BBL_SET_RAMDAC_FB_PIXEL_MASK_REG( BBL_REG_BASE,
BBL_DEFAULT_VRAM_PIXEL_MASK_VALUE );
/*******************/
/* S E T W A T S */
/*******************/
/*
* Load the default WAT
*/
BBL_DBG_PRINT ("update WAT\n");
BBL_SET_RAMDAC_ADDRESS_REGS ( BBL_REG_BASE,
BBL_RAMDAC_WAT_START_ADDR );
for(i=0;i<BBL_RAMDAC_WAT_LENGTH;i++){
BBL_SET_RAMDAC_DATA_NON_LUT ( BBL_REG_BASE, 0x10);
BBL_SET_RAMDAC_DATA_NON_LUT ( BBL_REG_BASE, 0x00);
}
/*************************************/
/* S E T C O L O R P A L E T T E */
/*************************************/
BBL_DBG_PRINT ("update colormap\n");
/*
* Set the colormap
*/
for(i=0; i<256; i++){
if((TextPalette[i] == 16)||
(TextPalette[i] == 32)||
(TextPalette[i] == 63)){
bbl_clut[i] = TextPalette[i] * 4;
}else{
bbl_clut[i] = TextPalette[i];
}
}
BBL_DBG_PRINT ("updating colormap\n");
BBL_LOAD_FB_COLOR_PALETTE(BBL_REG_BASE, 0,
BBL_RAMDAC_FB_LUT_LENGTH, &bbl_clut[0]);
/************************************************************/
/* F I N I S H R A S T R E G I S T E R S E T U P */
/************************************************************/
/*
* set PIXEL MASK register = 0xffffffff
*/
BBL_DBG_PRINT ("Writing Pixel Mask register = 0xFFFFFFFF\n");
BBL_SET_REG( BBL_REG_BASE, BBL_PIXEL_MASK_REG, 0xFFFFFFFF);
/*
* set Write Plane Mask register = 0xff
*/
BBL_DBG_PRINT ("Writing Plane Mask register = 0x%x\n", 0xFF);
BBL_SET_REG( BBL_REG_BASE, BBL_PLANE_MASK_REG, 0xFF);
/*
* Disable Line Style Dash 1234
*/
BBL_DBG_PRINT ("disable line style dash 1234 register\n");
BBL_SET_REG( BBL_REG_BASE, BBL_LINE_STYLE_DASH_1234_REG, 0x00);
/*
* Disable Line Style Dash 5678
*/
BBL_DBG_PRINT ("disable line style dash 5678 register\n");
BBL_SET_REG( BBL_REG_BASE, BBL_LINE_STYLE_DASH_5678_REG, 0x00);
/*
* Disable Scissors
*/
BBL_DBG_PRINT ("Disable scissors\n");
BBL_SET_REG( BBL_REG_BASE, BBL_SCISSOR_ENABLE_REG, 0x0);
/*
* set Window Origin Offset register ( x = 0, y = 0 )
*/
BBL_DBG_PRINT ("setting Window origin 0,0\n");
BBL_SET_REG( BBL_REG_BASE, BBL_WIN_ORIGIN_OFFSETS_REG, 0x0);
/*
* set Window ID and Clip Test register = DISABLE
*/
BBL_DBG_PRINT ("setting Window ID and Clip Test register = DISABLE\n");
BBL_SET_REG( BBL_REG_BASE, BBL_WID_CLIP_TEST_REG, 0x0);
/*******************************/
/* C L E A R O U T V R A M */
/*******************************/
/*
* set Foreground register
*/
BBL_DBG_PRINT ("Writing Foreground register = 0x%x\n", 0x0);
BBL_SET_REG( BBL_REG_BASE, BBL_FG_REG, 0x0);
/*
* set Background register
*/
BBL_DBG_PRINT ("Writing Background register = 0x%x\n", 0x0);
BBL_SET_REG( BBL_REG_BASE, BBL_BG_REG, 0x0);
/*
* set destination to WID planes
*/
BBL_SET_REG( BBL_REG_BASE, BBL_CNTL_REG, 0x201);
/*
* set Write Plane Mask register = 0x0f
*/
BBL_DBG_PRINT ("Writing Plane Mask register = 0x%x\n", 0x0F);
BBL_SET_REG( BBL_REG_BASE, BBL_PLANE_MASK_REG, 0x0F);
BBL_EIEIO;
/*
* clear out WID planes
*/
BBL_BUSY_POLL(BBL_REG_BASE);
BBL_FILL_RECT(BBL_REG_BASE, 0, 0, bbl_mon_data_ptr->x_res,
bbl_mon_data_ptr->y_res);
BBL_EIEIO;
/*
* set destination to FB_A
*/
BBL_SET_REG( BBL_REG_BASE, BBL_CNTL_REG, 0x01);
/*
* set Write Plane Mask register = 0xff
*/
BBL_DBG_PRINT ("Writing Plane Mask register = 0x%x\n", 0xFF);
BBL_SET_REG( BBL_REG_BASE, BBL_PLANE_MASK_REG, 0xFF);
BBL_EIEIO;
/*
* clear out FB_A (actually make it dark blue for HAL)
*/
BBL_BUSY_POLL(BBL_REG_BASE);
BBL_SET_REG( BBL_REG_BASE, BBL_FG_REG, 0x01); // dark blue
BBL_FILL_RECT(BBL_REG_BASE, 0, 0, bbl_mon_data_ptr->x_res,
bbl_mon_data_ptr->y_res);
BBL_EIEIO;
BBL_BUSY_POLL(BBL_REG_BASE);
/*******************************************/
/* E N A B L E V I D E O D I S P L A Y */
/*******************************************/
/*
* set Configuration high register
*/
BBL_DBG_PRINT ("Writing RAMDAC config register high = 0x%x\n", 0x69);
BBL_SET_RAMDAC_ADDRESS_REGS(BBL_REG_BASE, BBL_RAMDAC_CONFIG_HIGH_REG );
BBL_SET_RAMDAC_DATA_NON_LUT( BBL_REG_BASE, 0x69);
BBL_EIEIO;
BBL_DBG_PRINT ("Finished with BBLInitialize()\n");
return TRUE;
}
BOOLEAN
BBLGetMonitorID (
PULONG monID,
volatile PUCHAR HalpBBLRegisterBase
)
{
unsigned long switch_id, cable_id, cable_id_tmp;
unsigned long status_vert, status_horz, monitor_id;
unsigned char monitor_id_orig, monitor_id_tmp;
BBL_DBG_PRINT("Entering BBLGetMonitorID\n");
/*
* Disable the PLL and the DTG controllers
*/
BBL_SET_RAMDAC_ADDRESS_REGS(BBL_REG_BASE,
BBL_RAMDAC_CONFIG_LOW_REG);
BBL_SET_RAMDAC_DATA_NON_LUT(BBL_REG_BASE, 0x00);
BBL_EIEIO;
BBL_SET_RAMDAC_ADDRESS_REGS(BBL_REG_BASE,
BBL_RAMDAC_CONFIG_HIGH_REG);
BBL_SET_RAMDAC_DATA_NON_LUT(BBL_REG_BASE, 0x08);
BBL_EIEIO;
/*
* Setup the PLL registers
*/
BBL_SET_PLL_REF_REG(BBL_REG_BASE, 50);
BBL_SET_PLL_VCO_DIVIDER_REG(BBL_REG_BASE, 50 * 100);
BBL_EIEIO;
/*
* Enable the PLL
*/
BBL_SET_RAMDAC_ADDRESS_REGS(BBL_REG_BASE,
BBL_RAMDAC_CONFIG_HIGH_REG);
BBL_SET_RAMDAC_DATA_NON_LUT(BBL_REG_BASE, 0x48);
BBL_EIEIO;
/*
* Enable positive syncs
*/
BBL_SET_CRT_CNTL_REG(BBL_REG_BASE, 0x18);
/*
* Setup the horizontal DTG registers
*/
BBL_SET_HORIZONTAL_TOTAL_REG(BBL_REG_BASE, 0x00ff);
BBL_SET_HORIZONTAL_DISPLAY_END_REG(BBL_REG_BASE, 0x0080);
BBL_SET_HORIZONTAL_SYNC_START_REG(BBL_REG_BASE, 0x0103);
BBL_SET_HORIZONTAL_SYNC_END1_REG(BBL_REG_BASE, 0x008f);
BBL_SET_HORIZONTAL_SYNC_END2_REG(BBL_REG_BASE, 0x0000);
/*
* Setup the vertical DTG registers
*/
BBL_SET_VERTICAL_TOTAL_REG(BBL_REG_BASE, 0x00ff);
BBL_SET_VERTICAL_DISPLAY_END_REG(BBL_REG_BASE, 0x0080);
BBL_SET_VERTICAL_SYNC_START_REG(BBL_REG_BASE, 0x0100);
BBL_SET_VERTICAL_SYNC_END_REG(BBL_REG_BASE, 0x0088);
BBL_EIEIO;
/*
* Enable the DTG
*/
BBL_SET_RAMDAC_ADDRESS_REGS(BBL_REG_BASE,
BBL_RAMDAC_CONFIG_HIGH_REG);
BBL_SET_RAMDAC_DATA_NON_LUT(BBL_REG_BASE, 0x68);
/*
* Delay for 35 ms
*/
BBL_EIEIO;
BBLWaitForVerticalSync(BBL_REG_BASE);
BBLWaitForVerticalSync(BBL_REG_BASE);
BBLWaitForVerticalSync(BBL_REG_BASE);
/*
* Read the monitor ID with positive going syncs
*/
BBL_GET_MONITOR_ID(BBL_REG_BASE,monitor_id_orig);
/*
* Extract the raw monitor ID along with the DIP switch
* settings
*/
switch_id = (monitor_id_orig >> 4 ) & 0x0f ;
cable_id = (monitor_id_orig & 0x0f);
BBL_DBG_PRINT("monitor_id_orig=0x%x switch_id=0x%x cable_id=0x%x\n",
monitor_id_orig, switch_id, cable_id);
/*
* Set VSYNC to negative logic
*/
BBL_SET_CRT_CNTL_REG(BBL_REG_BASE, 0x08);
/*
* Delay for 35 ms
*/
BBL_EIEIO;
BBLWaitForVerticalSync(BBL_REG_BASE);
BBLWaitForVerticalSync(BBL_REG_BASE);
BBLWaitForVerticalSync(BBL_REG_BASE);
/*
* Read the monitor ID with negative VSYNC logic active
*/
BBL_GET_MONITOR_ID(BBL_REG_BASE,monitor_id_tmp);
/*
* Extract the negative VSYNC monitor ID and OR in
* the changed bits into the monitor ID
*/
status_vert = (monitor_id_tmp & 0x0f) ^ cable_id;
cable_id_tmp = monitor_id_tmp & 0x0f;
BBL_DBG_PRINT("monitor_id_tmp=0x%x status_vert=0x%x cable_id_tmp=0x%x\n",
monitor_id_tmp, status_vert, cable_id_tmp);
/*
* Set HSYNC to negative logic; VSYNC is still negative as well
*/
BBL_SET_CRT_CNTL_REG(BBL_REG_BASE, 0x00);
/*
* Delay for 35 ms
*/
BBL_EIEIO;
BBLWaitForVerticalSync(BBL_REG_BASE);
BBLWaitForVerticalSync(BBL_REG_BASE);
BBLWaitForVerticalSync(BBL_REG_BASE);
/*
* Read the monitor ID with negative HSYNC and VSYNC logic
*/
BBL_GET_MONITOR_ID(BBL_REG_BASE,monitor_id_tmp);
/*
* Extract the negative HSYNC and VSYNC value and OR in
* the changed bits into the monitor ID
*/
status_horz = (monitor_id_tmp & 0x0f) ^ cable_id_tmp;
monitor_id = switch_id << BBL_MON_ID_DIP_SWITCHES_SHIFT;
BBL_DBG_PRINT("monitor_id_tmp=0x%x status_horz=0x%x monitor_id=0x%x\n",
monitor_id_tmp, status_horz, monitor_id);
/*
* Turn PLL and DTG controllers back off
*/
BBL_SET_RAMDAC_ADDRESS_REGS(BBL_REG_BASE,
BBL_RAMDAC_CONFIG_HIGH_REG);
BBL_SET_RAMDAC_DATA_NON_LUT(BBL_REG_BASE, 0x08);
BBL_EIEIO;
/*
* Determine if we have a vert (V) or horz (H) value in the
* monitor ID based on what we read the three times above
*/
if(status_horz & 0x08)
monitor_id |= (BBL_MON_ID_CABLE_ID_H <<
BBL_MON_ID_CABLE_BIT_0_SHIFT);
else if(status_vert & 0x08)
monitor_id |= (BBL_MON_ID_CABLE_ID_V <<
BBL_MON_ID_CABLE_BIT_0_SHIFT);
else if(cable_id & 0x08)
monitor_id |= (BBL_MON_ID_CABLE_ID_1 <<
BBL_MON_ID_CABLE_BIT_0_SHIFT);
if(status_horz & 0x04)
monitor_id |= (BBL_MON_ID_CABLE_ID_H <<
BBL_MON_ID_CABLE_BIT_1_SHIFT);
else if(status_vert & 0x04)
monitor_id |= (BBL_MON_ID_CABLE_ID_V <<
BBL_MON_ID_CABLE_BIT_1_SHIFT);
else if(cable_id & 0x04)
monitor_id |= (BBL_MON_ID_CABLE_ID_1 <<
BBL_MON_ID_CABLE_BIT_1_SHIFT);
if(status_horz & 0x02)
monitor_id |= (BBL_MON_ID_CABLE_ID_H <<
BBL_MON_ID_CABLE_BIT_2_SHIFT);
else if(status_vert & 0x02)
monitor_id |= (BBL_MON_ID_CABLE_ID_V <<
BBL_MON_ID_CABLE_BIT_2_SHIFT);
else if(cable_id & 0x02)
monitor_id |= (BBL_MON_ID_CABLE_ID_1 <<
BBL_MON_ID_CABLE_BIT_2_SHIFT);
if(status_horz & 0x01)
monitor_id |= (BBL_MON_ID_CABLE_ID_H <<
BBL_MON_ID_CABLE_BIT_3_SHIFT);
else if(status_vert & 0x01)
monitor_id |= (BBL_MON_ID_CABLE_ID_V <<
BBL_MON_ID_CABLE_BIT_3_SHIFT);
else if(cable_id & 0x01)
monitor_id |= (BBL_MON_ID_CABLE_ID_1 <<
BBL_MON_ID_CABLE_BIT_3_SHIFT);
*monID = monitor_id;
BBL_DBG_PRINT ("Monitor id = 0x%x\n", monitor_id);
return TRUE;
}
VOID
BBLWaitForVerticalSync (
volatile PUCHAR HalpBBLRegisterBase
)
{
int counter = 0;
// Loop until out of Vertical Sync just in case we happened to
// catch the tail end of a vertical blank cycle
while((BBL_GET_REG(HalpBBLRegisterBase, BBL_STATUS_REG)
& BBL_VERTICAL_RETRACE) &&
(++counter < 1000000))
;
counter = 0;
// Wait until we hit the leading edge of the Vertical Sync
while((!(BBL_GET_REG(HalpBBLRegisterBase, BBL_STATUS_REG)
& BBL_VERTICAL_RETRACE)) &&
(++counter < 1000000))
;
#ifdef DBG
// If counter reaches 1000000, then there is something wrong with
// the setup of the ramdac
#ifdef KDB
if(counter == 1000000)
DbgBreakPoint();
#endif
#endif
}
VOID
HalpDisplayCharacterBBL (
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 encountered, the frame buffer is
scrolled. If characters extend below the end of line, they are not
displayed.
Arguments:
Character - Supplies a character to be displayed.
Return Value:
None.
--*/
{
//
// If the character is a newline:
//
if (Character == '\n') {
HalpColumn = 0;
if (HalpRow < (HalpDisplayText - 1)) {
HalpRow += 1;
} else { // need to scroll up the screen
BBLScrollScreen();
}
}
//
// If the character is a tab:
//
else if( Character == '\t' ) {
HalpColumn += TAB_SIZE;
HalpColumn = (HalpColumn / TAB_SIZE) * TAB_SIZE;
if( HalpColumn >= HalpDisplayWidth ) { // tab beyond end of screen?
HalpColumn = 0; // set to 1st column of next line
if( HalpRow >= (HalpDisplayText - 1) )
BBLScrollScreen();
else
++HalpRow;
}
}
//
// If the character is a return:
//
else if (Character == '\r') {
HalpColumn = 0;
}
//
// If the character is a DEL:
//
else if (Character == 0x7f) { /* DEL character */
if (HalpColumn != 0) {
HalpColumn -= 1;
Character = 0x20 - HalpFontHeader->FirstCharacter;
HalpOutputCharacterBBL((PUCHAR)HalpFontHeader +
HalpFontHeader->Map[Character].Offset);
HalpColumn -= 1;
} else /* do nothing */
;
}
//
// If not special character:
//
else {
if ((Character < HalpFontHeader->FirstCharacter) ||
(Character > HalpFontHeader->LastCharacter))
Character = HalpFontHeader->DefaultCharacter;
else
Character -= HalpFontHeader->FirstCharacter;
// Auto wrap for HalpDisplayWidth columns per line
if (HalpColumn >= HalpDisplayWidth) {
HalpColumn = 0;
if (HalpRow < (HalpDisplayText - 1)) {
HalpRow += 1;
} else { // need to scroll up the screen
BBLScrollScreen();
}
}
HalpOutputCharacterBBL((PUCHAR)HalpFontHeader +
HalpFontHeader->Map[Character].Offset);
}
return;
}
VOID
HalpOutputCharacterBBL(
IN PUCHAR Glyph
)
/*++
Routine Description:
This routine insert a set of pixels into the display at the current x
cursor position. If the current x cursor position is at the end of the
line, then a newline is displayed before the specified character.
Arguments:
Character - Supplies a character to be displayed.
Return Value:
None.
--*/
{
PUCHAR Destination;
ULONG FontValue;
ULONG I;
ULONG J;
//
// If the current x cursor position is at the end of the line, then
// output a line feed before displaying the character.
//
//if (HalpColumn == HalpDisplayWidth) {
// HalpDisplayCharacterBBL('\n');
//}
//
// Output the specified character and update the x cursor position.
//
Destination = (PUCHAR)(HalpVideoMemoryBase +
(HalpRow * HalpScrollLine) +
(HalpColumn * HalpCharacterWidth));
for (I = 0; I < HalpCharacterHeight; I += 1) {
FontValue = 0;
for (J = 0; J < HalpBytesPerRow; J += 1) {
FontValue |=
*(Glyph + (J * HalpCharacterHeight)) << (24 - (J * 8));
}
Glyph += 1;
for (J = 0; J < HalpCharacterWidth ; J += 1) {
*Destination = 0x01; // Clear out any pre-existing char
if (FontValue >> 31 != 0)
*Destination = 0x3F; // Make this pixel white (ARC color)
Destination++;
FontValue <<= 1;
}
Destination += (BBL_SCANLINE_LENGTH - HalpCharacterWidth);
}
HalpColumn += 1;
return;
}
VOID
BBLScrollScreen (
VOID
)
{
PULONG Destination, Source, End;
ULONG pix_col, Stride;
// Scroll up one line
Destination = (PULONG) HalpVideoMemoryBase;
Source = (PULONG) (HalpVideoMemoryBase + HalpScrollLine);
End = (PULONG) ((PUCHAR) Source + HalpScrollLength);
Stride = (ULONG) ((BBL_SCANLINE_LENGTH - HalpHorizontalResolution) >> 2);
while(Source < End){
pix_col = 0;
while(pix_col++ < (HalpHorizontalResolution >> 2)){
*Destination++ = *Source++;
}
Destination += Stride;
Source += Stride;
}
// Blue the bottom line
Destination = (PULONG) (HalpVideoMemoryBase + HalpScrollLength);
End = (PULONG) ((PUCHAR) Destination + HalpScrollLine);
while(Destination < End){
for (pix_col =0; pix_col < (HalpHorizontalResolution >> 2);
pix_col ++){
*Destination++ = 0x01010101;
}
Destination += Stride;
}
}
BOOLEAN
BBLSetConfigurationRegister (
IN ULONG dev_ven_id,
IN ULONG offset,
IN ULONG reg_value
)
{
ULONG slot = 0, bus = 0, value, i, j;
volatile PUCHAR HalpBBLRegisterBase;
BOOLEAN found;
if (HalpInitPhase == 0) {
if(HalpPhase0MapBusConfigSpace () == FALSE){
BBL_DBG_PRINT("HalpPhase0MapBusConfigSpace() failed\n");
#ifdef KDB
DbgBreakPoint();
#endif
return (FALSE);
}
}
found = FALSE;
for (j=0; j < HalpPciMaxBuses; j++) {
for (i=0; ((i<HalpPciMaxSlots)&&(found==FALSE)); i++){
if (HalpInitPhase == 0) {
HalpPhase0GetPciDataByOffset (j, i, &value, 0x0, 4);
} else {
HalGetBusDataByOffset(PCIConfiguration,
j,
i,
&value,
0x0,
4);
}
if(value == BBL_DEV_VEND_ID){
slot = i;
bus = j;
found = TRUE;
}
}
}
if(found == FALSE){
BBL_DBG_PRINT("Cannot find adapter!\n");
#ifdef KDB
DbgBreakPoint();
#endif
if (HalpInitPhase == 0) HalpPhase0UnMapBusConfigSpace ();
return (FALSE);
}
if (HalpInitPhase == 0) {
HalpPhase0SetPciDataByOffset (bus, slot, &reg_value, offset, 4);
HalpPhase0UnMapBusConfigSpace ();
} else {
HalSetBusDataByOffset(PCIConfiguration,
bus,
slot,
&reg_value,
offset,
4);
}
return (TRUE);
}
BOOLEAN
BBLGetConfigurationRegister (
IN ULONG dev_ven_id,
IN ULONG offset,
IN PULONG reg_value
)
{
ULONG slot = 0, bus = 0, value, i, j;
volatile PUCHAR HalpBBLRegisterBase;
BOOLEAN found;
if (HalpInitPhase == 0) {
if(HalpPhase0MapBusConfigSpace () == FALSE){
BBL_DBG_PRINT("HalpPhase0MapBusConfigSpace() failed\n");
#ifdef KDB
DbgBreakPoint();
#endif
return (FALSE);
}
}
found = FALSE;
for (j=0; j < HalpPciMaxBuses; j++) {
for (i=0; ((i<HalpPciMaxSlots)&&(found==FALSE)); i++){
if (HalpInitPhase == 0) {
HalpPhase0GetPciDataByOffset (j, i, &value, 0x0, 4);
} else {
HalGetBusDataByOffset(PCIConfiguration,
j,
i,
&value,
0x0,
4);
}
if(value == BBL_DEV_VEND_ID){
slot = i;
bus = j;
found = TRUE;
}
}
}
if(found == FALSE){
BBL_DBG_PRINT("Cannot find adapter!\n");
#ifdef KDB
DbgBreakPoint();
#endif
if (HalpInitPhase == 0) HalpPhase0UnMapBusConfigSpace ();
return (FALSE);
}
if (HalpInitPhase == 0) {
HalpPhase0GetPciDataByOffset (bus, slot, reg_value, offset, 4);
HalpPhase0UnMapBusConfigSpace ();
} else {
HalGetBusDataByOffset(PCIConfiguration,
bus,
slot,
reg_value,
offset,
4);
}
return (TRUE);
}