📄 flash.cpp
字号:
// This allows the dot clock frequency that was just set to settle.
delay_milliseconds();
// SET THE "DCLK_MUL" FIELD OF DC_GENERAL_CFG
// The GX hardware divides the dot clock, so 2x really means that the
// internal dot clock equals the external dot clock.
gcfg |= pMode->gcfg & DC_GCFG_DCLK_MASK;
WRITE_REG32(GXregisters, DC_GENERAL_CFG, gcfg);
// DELAY: WAIT FOR THE ADL TO LOCK
// This allows the clock generatation within GX to settle. This is
// needed since some of the register writes that follow require that
// clock to be present.
delay_milliseconds();
// SET THE DISPLAY CONTROLLER PARAMETERS
WRITE_REG32(GXregisters, DC_FB_ST_OFFSET, pMode->fb_offset);
WRITE_REG32(GXregisters, DC_CB_ST_OFFSET, pMode->cb_offset);
WRITE_REG32(GXregisters, DC_CURS_ST_OFFSET, pMode->curs_offset);
WRITE_REG32(GXregisters, DC_LINE_DELTA, pMode->line_delta);
WRITE_REG32(GXregisters, DC_BUF_SIZE, pMode->buffer_size);
WRITE_REG32(GXregisters, DC_H_TIMING_1, pMode->htiming1);
WRITE_REG32(GXregisters, DC_H_TIMING_2, pMode->htiming2);
WRITE_REG32(GXregisters, DC_H_TIMING_3, pMode->htiming3);
WRITE_REG32(GXregisters, DC_FP_H_TIMING, pMode->fp_htiming);
WRITE_REG32(GXregisters, DC_V_TIMING_1, pMode->vtiming1);
WRITE_REG32(GXregisters, DC_V_TIMING_2, pMode->vtiming2);
WRITE_REG32(GXregisters, DC_V_TIMING_3, pMode->vtiming3);
WRITE_REG32(GXregisters, DC_FP_V_TIMING, pMode->fp_vtiming);
// COPY NEW GX CONFIGURATION VALUES
gcfg = pMode->gcfg;
tcfg = pMode->tcfg;
ocfg = pMode->ocfg;
// MODIFY GX CONFIGURATION FOR CX5530, IF NEEDED
// SET SYNC POLARITIES
// For CX5530 systems, the GX is always programmed so that it
// gemerates positive sync polarities (pulse from low to high).
// The CX5530 then reverses the polarities, if needed.
dcfg30 &= ~(unsigned long) CX5530_DCFG_CRT_HSYNC_POL;
dcfg30 &= ~(unsigned long) CX5530_DCFG_CRT_VSYNC_POL;
dcfg30 &= ~(unsigned long) CX5530_DCFG_FP_HSYNC_POL;
dcfg30 &= ~(unsigned long) CX5530_DCFG_FP_VSYNC_POL;
if (pMode->hsync_pol == 0) dcfg30 |= CX5530_DCFG_CRT_HSYNC_POL;
if (pMode->vsync_pol == 0) dcfg30 |= CX5530_DCFG_CRT_VSYNC_POL;
if (tcfg & DC_TCFG_FHSP) dcfg30 |= CX5530_DCFG_FP_HSYNC_POL;
if (tcfg & DC_TCFG_FVSP) dcfg30 |= CX5530_DCFG_FP_VSYNC_POL;
tcfg &= ~(unsigned long) (DC_TCFG_CHSP | DC_TCFG_CVSP);
tcfg &= ~(unsigned long) (DC_TCFG_FHSP | DC_TCFG_FVSP);
// PROGRAM THE CONFIGURATION REGISTERS (MUST BE IN THIS SEQUENCE)
WRITE_REG32(GXregisters, DC_OUTPUT_CFG, pMode->ocfg);
WRITE_REG32(GXregisters, DC_TIMING_CFG, pMode->tcfg);
value = pMode->gcfg; //store in temp variable
#if COMPRESSION_ENABLE
// Enable compression
// Compression (writes) and decompression (reads) have separate enable
// bits for hardware debug purposes. Always enable both.
value |= (DC_GCFG_CMPE | DC_GCFG_DECE);
#endif
WRITE_REG32(GXregisters, DC_GENERAL_CFG, value);
// ENABLE 5530 DISPLAY
// ENABLE DISPLAY
dcfg30 |= CX5530_DCFG_DIS_EN;
dcfg30 |= CX5530_DCFG_HSYNC_EN;
dcfg30 |= CX5530_DCFG_VSYNC_EN;
// ENABLE CRT OUTPUT
dcfg30 |= CX5530_DCFG_DAC_BL_EN;
dcfg30 |= CX5530_DCFG_DAC_PWDNX;
// ENABLE FLAT PANEL OUTPUT
dcfg30 |= CX5530_DCFG_FP_PWR_EN;
dcfg30 |= CX5530_DCFG_FP_DATA_EN;
// PICK WHICH DATA STREAM GOES THROUGH THE PALETTE
// For this file, this is always the video stream.
dcfg30 |= CX5530_DCFG_GV_PAL_BYP;
WRITE_REG32(CX5530registers, CX55xx_DISPLAY_CONFIG, dcfg30);
// Setting the BPP and stride in Graphics pipeline
value = (m_nScreenStride > 1024) ? 0x200 : 0;
value |= (m_pMode->Bpp > 8) ? 0x100 : 0;
WRITE_REG32(GXregisters, GP_BLIT_STATUS, value);
//Set the BPP
Display_BPP = m_pMode->Bpp;
if (Display_BPP == 8)
BB0_Size_Pixels = BB0_Size_Bytes;
else
BB0_Size_Pixels = BB0_Size_Bytes >> 1;
// RESTORE LOCK OF DC_UNLOCK
Lock();
return S_OK;
}
//Given the GPEMode get the appropriate index into the Display structure
unsigned long GxVideo::GetDpyMode(GPEMode pMode )
{
int i;
//Loop thru to find if the modeId really exists
for(i=0; i < NUMBEROFMODES; i++)
{
if((pMode.width == DisplayParams[i].gpeMode.width) &&
(pMode.height == DisplayParams[i].gpeMode.height) &&
(pMode.Bpp == DisplayParams[i].gpeMode.Bpp) &&
(pMode.frequency == DisplayParams[i].gpeMode.frequency))
{
DEBUGMSG( 1,(TEXT("DpyModeExists Found mode %d at %d\n"),
DisplayParams[i].gpeMode.modeId, i));
return(DisplayParams[i].gpeMode.modeId);
}
}
DEBUGMSG( 1,(TEXT("GetDpyMode mode not found for %dx%dx%d %d !!!\n"),
pMode.width, pMode.height, pMode.Bpp, pMode.frequency));
return 0;//default mode
}
//----------------------------------------------------------------------------
// DisplayTestScreen - Displays the bitmap at the given location for all
// resolutions visible in the area.
//----------------------------------------------------------------------------
void GxVideo::DisplayTestScreen(int width, int height, int depth, int freq)
{
int Freq;
int xoff, yoff;
DEBUGMSG(1,(TEXT("DisplayTestScreen\n")));
WAIT_PENDING(GXregisters);
WRITE_REG16(GXregisters, GP_DST_XCOOR, 0);
WRITE_REG16(GXregisters, GP_DST_YCOOR, 0);
WRITE_REG16(GXregisters, GP_WIDTH, width-1);
WRITE_REG16(GXregisters, GP_HEIGHT, height-1);
WRITE_REG16(GXregisters, GP_RASTER_MODE, 0xF0);
SelectSolidColor(0xFCFC); //BLUE
WRITE_REG16(GXregisters, GP_BLIT_MODE, 0);
switch(freq){
case 60:
Freq = 0;
break;
case 65:
Freq = 1;
break;
case 70:
Freq = 2;
break;
case 72:
Freq = 3;
break;
case 75:
Freq = 4;
break;
case 80:
Freq = 5;
break;
case 85:
Freq = 6;
break;
}
xoff = 121;
yoff = 16;
if(width >= 640){
DisplayBitmapData(0, Freq, (640 - xoff), (480 - yoff));
DrawBorder(639, 479);
}
if(width >= 800){
DisplayBitmapData(1, Freq, (800 - xoff), (600 - yoff));
DrawBorder(799, 599);
}
if(width >= 1024){
DisplayBitmapData(2, Freq, (1024 - xoff), (768 - yoff));
DrawBorder(1023, 767);
}
if(width >= 1280){
DisplayBitmapData(3, Freq, (1280 - xoff), (1024 - yoff));
DrawBorder(1279, 1023);
}
}
//----------------------------------------------------------------------------
// DisplayBitmapData - Displays the bitmap at the given location
//----------------------------------------------------------------------------
void GxVideo::DisplayBitmapData( int Resoffset,
int Freqoffset,
int xpos, int ypos )
{
unsigned long spadAddr, i, j, freqOffset,resOffset;
DEBUGMSG(0,(TEXT("AcceleratedBitmapScreenBlt\n")));
resOffset=(Resoffset * IMG_HEIGHT);
freqOffset=(Freqoffset * IMG_HEIGHT);
WAIT_PENDING(GXregisters);
WRITE_REG32(GXregisters, GP_DST_XCOOR, (ypos << 16) | xpos);
WRITE_REG32(GXregisters, GP_WIDTH, 0x10000 |
(IMG_RES_WIDTH + IMG_AT_WIDTH + IMG_FREQ_WIDTH));
WRITE_REG16(GXregisters, GP_RASTER_MODE, 0x00CC);
// REPEAT FOR EACH SCANLINE
for (i = 0; i < IMG_HEIGHT; i++)
{
// COPY CURRENT POINTER TO A DWORD POINTER
spadAddr = BB0_Base_Address;
WAIT_BUSY(GXregisters);
for (j = 0; j < IMG_RES_WIDTH; j++)
{
WRITE_REG8(GXregisters, spadAddr, ResImg[resOffset+i][j]);
spadAddr++;
}
//now put the @ symbol
for (j = 0; j < IMG_AT_WIDTH; j++)
{
WRITE_REG8(GXregisters, spadAddr, Imgat[i][j]);
spadAddr++;
}
//now put the Frequency symbol
for (j = 0; j < IMG_FREQ_WIDTH; j++)
{
WRITE_REG8(GXregisters, spadAddr, Imghz[freqOffset+i][j]);
spadAddr++;
}
WRITE_REG16(GXregisters, GP_BLIT_MODE, BM_READ_SRC_BB0);
}
}
//----------------------------------------------------------------------------
// DrawBorder
// Draw boder for a rectangle using stright lines
//----------------------------------------------------------------------------
void GxVideo::DrawBorder( int wid, int ht )
{
SelectSolidColor(0xFFFF);//White
DrawStraightLine( 0, 0, 1, ht-1 );
DrawStraightLine( wid-2, 0, wid-1, ht-1 );
DrawStraightLine( 0, 0, wid-1, 1 );
DrawStraightLine( 0, ht-2, wid-1, ht-1 );
}
//----------------------------------------------------------------------------
// DrawStraightLine
// Draw stright lines either vertical/horizontal only
//----------------------------------------------------------------------------
void GxVideo::DrawStraightLine( int x1, int y1, int x2, int y2 )
{
int start_width, width = x2 - x1;
WAIT_PENDING(GXregisters);
WRITE_REG32(GXregisters, GP_DST_XCOOR, (y1 << 16) | x1);
WRITE_REG16(GXregisters, GP_RASTER_MODE, 0x00F0);
WRITE_REG16(GXregisters, GP_HEIGHT, y2-y1);//height);
// CHECK IF GXm WORKAROUND IS NEEDED
if (width <= 16)
{
// DRAW SINGLE RECTANGLE
WRITE_REG16(GXregisters, GP_WIDTH, width);
WRITE_REG16(GXregisters, GP_BLIT_MODE, 0);
}
else
{
start_width = 16 - (width & 15);
// DRAW RECTANGLE <= 16 PIXELS
WRITE_REG16(GXregisters, GP_WIDTH, start_width);
WRITE_REG16(GXregisters, GP_BLIT_MODE, 0);
// DRAW REMAINING PART OF RECTANGLE
WAIT_PENDING(GXregisters);
WRITE_REG32(GXregisters, GP_DST_XCOOR, (y1 << 16) | (x1+start_width));
WRITE_REG16(GXregisters, GP_WIDTH, width - start_width);
WRITE_REG16(GXregisters, GP_BLIT_MODE, 0);
}
// For MXi, this function should call the ARC_PATTERN_FILL request.
}
//----------------------------------------------------------------------------
// ToggleCursor
// Toggle the cursor if to be shown/hidden
//----------------------------------------------------------------------------
void GxVideo::ToggleCursor( BOOL flag )
{
unsigned long cfg;
// UNLOCK THE DISPLAY CONTROLLER REGISTERS
Unlock();
// READ THE CURRENT GX VALUES
cfg = READ_REG32(GXregisters, DC_GENERAL_CFG);
// ENABLE/DISABLE CURSOR
if(flag) //enable
cfg |= DC_GCFG_CURE;
else
cfg &= ~(DC_GCFG_CURE);
WRITE_REG32(GXregisters, DC_GENERAL_CFG, cfg);
// RESTORE LOCK OF DC_UNLOCK
Lock();
}
// END OF FILE
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -