📄 disp_gu1.c
字号:
}
/*---------------------------------------------------------------------------
* gfx_set_display_offset
*
* This routine sets the start address of the frame buffer. It is
* typically used to pan across a virtual desktop (frame buffer larger than
* the displayed screen) or to flip the display between multiple buffers.
*---------------------------------------------------------------------------
*/
#if GFX_DISPLAY_DYNAMIC
void gu1_set_display_offset(unsigned long offset)
#else
void gfx_set_display_offset(unsigned long offset)
#endif
{
/* UPDATE FRAME BUFFER OFFSET */
unsigned long lock;
lock = READ_REG32(DC_UNLOCK);
WRITE_REG32(DC_UNLOCK, DC_UNLOCK_VALUE);
WRITE_REG32(DC_FB_ST_OFFSET, offset);
WRITE_REG32(DC_UNLOCK, lock);
/* START ADDRESS EFFECTS DISPLAY COMPRESSION */
/* Disable compression for non-zero start addresss values. */
/* Enable compression if offset is zero and comression is intended to */
/* be enabled from a previous call to "gfx_set_compression_enable". */
if ((offset == 0) && gfx_compression_enabled)
gu1_enable_compression();
else gu1_disable_compression();
return;
}
/*---------------------------------------------------------------------------
* gfx_set_display_palette
*
* This routine sets the entire palette in the display controller.
* A pointer is provided to a 256 entry table of 32-bit X:R:G:B values.
*---------------------------------------------------------------------------
*/
#if GFX_DISPLAY_DYNAMIC
int gu1_set_display_palette(unsigned long *palette)
#else
int gfx_set_display_palette(unsigned long *palette)
#endif
{
unsigned long data, i;
WRITE_REG32(DC_PAL_ADDRESS, 0);
if (palette)
{
for (i = 0; i < 256; i++)
{
/* CONVERT 24 BPP COLOR DATA TO 18 BPP COLOR DATA */
data = ((palette[i] >> 2) & 0x0003F) |
((palette[i] >> 4) & 0x00FC0) |
((palette[i] >> 6) & 0x3F000);
WRITE_REG32(DC_PAL_DATA, data);
}
}
return(0);
}
/*---------------------------------------------------------------------------
* gfx_set_cursor_enable
*
* This routine enables or disables the hardware cursor.
*
* WARNING: The cusrsor start offset must be set by setting the cursor
* position before calling this routine to assure that memory reads do not
* go past the end of graphics memory (this can hang GXm).
*---------------------------------------------------------------------------
*/
#if GFX_DISPLAY_DYNAMIC
void gu1_set_cursor_enable(int enable)
#else
void gfx_set_cursor_enable(int enable)
#endif
{
unsigned long unlock, gcfg;
/* SET OR CLEAR CURSOR ENABLE BIT */
unlock = READ_REG32(DC_UNLOCK);
gcfg = READ_REG32(DC_GENERAL_CFG);
if (enable) gcfg |= DC_GCFG_CURE;
else gcfg &= ~(DC_GCFG_CURE);
/* WRITE NEW REGISTER VALUE */
WRITE_REG32(DC_UNLOCK, DC_UNLOCK_VALUE);
WRITE_REG32(DC_GENERAL_CFG, gcfg);
WRITE_REG32(DC_UNLOCK, unlock);
}
/*---------------------------------------------------------------------------
* gfx_set_cursor_colors
*
* This routine sets the colors of the hardware cursor.
*---------------------------------------------------------------------------
*/
#if GFX_DISPLAY_DYNAMIC
void gu1_set_cursor_colors(unsigned long bkcolor, unsigned long fgcolor)
#else
void gfx_set_cursor_colors(unsigned long bkcolor, unsigned long fgcolor)
#endif
{
unsigned long value;
/* SET CURSOR COLORS */
WRITE_REG32(DC_PAL_ADDRESS, 0x100);
value = ((bkcolor & 0x000000FC) >> 2) |
((bkcolor & 0x0000FC00) >> (2+8-6)) |
((bkcolor & 0x00FC0000) >> (2+16-12));
WRITE_REG32(DC_PAL_DATA, value);
value = ((fgcolor & 0x000000FC) >> 2) |
((fgcolor & 0x0000FC00) >> (2+8-6)) |
((fgcolor & 0x00FC0000) >> (2+16-12));
WRITE_REG32(DC_PAL_DATA, value);
}
/*---------------------------------------------------------------------------
* gfx_set_cursor_position
*
* This routine sets the position of the hardware cusror. The starting
* offset of the cursor buffer must be specified so that the routine can
* properly clip scanlines if the cursor is off the top of the screen.
*---------------------------------------------------------------------------
*/
#if GFX_DISPLAY_DYNAMIC
void gu1_set_cursor_position(unsigned long memoffset,
unsigned short xpos, unsigned short ypos,
unsigned short xhotspot, unsigned short yhotspot)
#else
void gfx_set_cursor_position(unsigned long memoffset,
unsigned short xpos, unsigned short ypos,
unsigned short xhotspot, unsigned short yhotspot)
#endif
{
unsigned long unlock;
short x = (short) xpos - (short) xhotspot;
short y = (short) ypos - (short) yhotspot;
short xoffset = 0;
short yoffset = 0;
if (x < -31) return;
if (y < -31) return;
if (x < 0) { xoffset = -x; x = 0; }
if (y < 0) { yoffset = -y; y = 0; }
memoffset += (unsigned long) yoffset << 3;
/* SET CURSOR POSITION */
unlock = READ_REG32(DC_UNLOCK);
WRITE_REG32(DC_UNLOCK, DC_UNLOCK_VALUE);
WRITE_REG32(DC_CURS_ST_OFFSET, memoffset);
WRITE_REG32(DC_CURSOR_X, (unsigned long) x |
(((unsigned long) xoffset) << 11));
WRITE_REG32(DC_CURSOR_Y, (unsigned long) y |
(((unsigned long) yoffset) << 11));
WRITE_REG32(DC_UNLOCK, unlock);
}
/*---------------------------------------------------------------------------
* gfx_set_cursor_shape32
*
* This routine loads 32x32 cursor data into the specified location in
* graphics memory.
*---------------------------------------------------------------------------
*/
#if GFX_DISPLAY_DYNAMIC
void gu1_set_cursor_shape32(unsigned long memoffset,
unsigned long *andmask, unsigned long *xormask)
#else
void gfx_set_cursor_shape32(unsigned long memoffset,
unsigned long *andmask, unsigned long *xormask)
#endif
{
int i;
unsigned long value;
for (i = 0; i < 32; i++)
{
/* CONVERT TO 16 BITS AND MASK, 16 BITS XOR MASK PER DWORD */
value = (andmask[i] & 0xFFFF0000) | (xormask[i] >> 16);
WRITE_FB32(memoffset, value);
memoffset += 4;
value = (andmask[i] << 16) | (xormask[i] & 0x0000FFFF);
WRITE_FB32(memoffset, value);
memoffset += 4;
}
}
/*---------------------------------------------------------------------------
* gu1_enable_compression
*
* This is a private routine to this module (not exposed in the Durango API).
* It enables display compression.
*---------------------------------------------------------------------------
*/
void gu1_enable_compression(void)
{
int i;
unsigned long unlock, gcfg, offset;
/* DO NOT ENABLE IF START ADDRESS IS NOT ZERO */
offset = READ_REG32(DC_FB_ST_OFFSET) & 0x003FFFFF;
if (offset != 0) return;
/* CLEAR DIRTY/VALID BITS IN MEMORY CONTROLLER */
/* Software is required to do this before enabling compression. */
/* Don't want controller to think that old lines are still valid. */
for (i = 0; i < 1024; i++)
{
WRITE_REG32(MC_DR_ADD, i);
WRITE_REG32(MC_DR_ACC, 0);
}
/* TURN ON COMPRESSION CONTROL BITS */
unlock = READ_REG32(DC_UNLOCK);
gcfg = READ_REG32(DC_GENERAL_CFG);
gcfg |= DC_GCFG_CMPE | DC_GCFG_DECE;
WRITE_REG32(DC_UNLOCK, DC_UNLOCK_VALUE);
WRITE_REG32(DC_GENERAL_CFG, gcfg);
WRITE_REG32(DC_UNLOCK, unlock);
}
/*---------------------------------------------------------------------------
* gu1_disable_compression
*
* This is a private routine to this module (not exposed in the Durango API).
* It disables display compression.
*---------------------------------------------------------------------------
*/
void gu1_disable_compression(void)
{
unsigned long unlock, gcfg;
/* TURN OFF COMPRESSION CONTROL BITS */
unlock = READ_REG32(DC_UNLOCK);
gcfg = READ_REG32(DC_GENERAL_CFG);
gcfg &= ~(DC_GCFG_CMPE | DC_GCFG_DECE);
WRITE_REG32(DC_UNLOCK, DC_UNLOCK_VALUE);
WRITE_REG32(DC_GENERAL_CFG, gcfg);
WRITE_REG32(DC_UNLOCK, unlock);
}
/*---------------------------------------------------------------------------
* gfx_set_compression_enable
*
* This routine enables or disables display compression.
*---------------------------------------------------------------------------
*/
#if GFX_DISPLAY_DYNAMIC
int gu1_set_compression_enable(int enable)
#else
int gfx_set_compression_enable(int enable)
#endif
{
/* SET GLOBAL VARIABLE FOR INDENDED STATE */
/* Compression can only be enabled for non-zero start address values. */
/* Keep state to enable compression on start address changes. */
gfx_compression_enabled = enable;
if (enable) gu1_enable_compression();
else gu1_disable_compression();
return(0);
}
/*---------------------------------------------------------------------------
* gfx_set_compression_offset
*
* This routine sets the base offset for the compression buffer.
*---------------------------------------------------------------------------
*/
#if GFX_DISPLAY_DYNAMIC
int gu1_set_compression_offset(unsigned long offset)
#else
int gfx_set_compression_offset(unsigned long offset)
#endif
{
unsigned long lock;
/* MUST BE 16-BYTE ALIGNED FOR GXLV */
if (offset & 0x0F) return(1);
/* SET REGISTER VALUE */
lock = READ_REG32(DC_UNLOCK);
WRITE_REG32(DC_UNLOCK, DC_UNLOCK_VALUE);
WRITE_REG32(DC_CB_ST_OFFSET, offset);
WRITE_REG32(DC_UNLOCK, lock);
return(0);
}
/*---------------------------------------------------------------------------
* gfx_set_compression_pitch
*
* This routine sets the pitch, in bytes, of the compression buffer.
*---------------------------------------------------------------------------
*/
#if GFX_DISPLAY_DYNAMIC
int gu1_set_compression_pitch(unsigned short pitch)
#else
int gfx_set_compression_pitch(unsigned short pitch)
#endif
{
unsigned long lock, line_delta;
/* SET REGISTER VALUE */
lock = READ_REG32(DC_UNLOCK);
line_delta = READ_REG32(DC_LINE_DELTA) & 0xFF800FFF;
line_delta |= (pitch << 10) & 0x007FF000;
WRITE_REG32(DC_UNLOCK, DC_UNLOCK_VALUE);
WRITE_REG32(DC_LINE_DELTA, line_delta);
WRITE_REG32(DC_UNLOCK, lock);
return(0);
}
/*---------------------------------------------------------------------------
* gfx_set_compression_size
*
* This routine sets the line size of the compression buffer, which is the
* maximum number of bytes allowed to store a compressed line.
*---------------------------------------------------------------------------
*/
#if GFX_DISPLAY_DYNAMIC
int gu1_set_compression_size(unsigned short size)
#else
int gfx_set_compression_size(unsigned short size)
#endif
{
unsigned long lock, buf_size;
/* SET REGISTER VALUE */
size -= 16;
lock = READ_REG32(DC_UNLOCK);
buf_size = READ_REG32(DC_BUF_SIZE) & 0xFFFF01FF;
buf_size |= (((size >> 2) + 1) & 0x7F) << 9;
WRITE_REG32(DC_UNLOCK, DC_UNLOCK_VALUE);
WRITE_REG32(DC_BUF_SIZE, buf_size);
WRITE_REG32(DC_UNLOCK, lock);
return(0);
}
/*---------------------------------------------------------------------------
* gfx_set_display_video_enable (PRIVATE ROUTINE - NOT PART OF API)
*
* This routine is called by "gfx_set_video_enable". It abstracts the
* version of the display controller from the video overlay routines.
*---------------------------------------------------------------------------
*/
#if GFX_DISPLAY_DYNAMIC
void gu1_set_display_video_enable(int enable)
#else
void gfx_set_display_video_enable(int enable)
#endif
{
unsigned long lock, gcfg;
lock = READ_REG32(DC_UNLOCK);
gcfg = READ_REG32(DC_GENERAL_CFG);
WRITE_REG32(DC_UNLOCK, DC_UNLOCK_VALUE);
if (enable)
gcfg |= (DC_GCFG_VIDE | DC_GCFG_VRDY);
else gcfg &= ~(DC_GCFG_VIDE);
WRITE_REG32(DC_GENERAL_CFG, gcfg);
WRITE_REG32(DC_UNLOCK, lock);
return;
}
/*---------------------------------------------------------------------------
* gfx_set_display_video_size (PRIVATE ROUTINE - NOT PART OF API)
*
* This routine is called by "gfx_set_video_size". It abstracts the
* version of the display controller from the video overlay routines.
*---------------------------------------------------------------------------
*/
#if GFX_DISPLAY_DYNAMIC
void gu1_set_display_video_size(unsigned short width, unsigned short height)
#else
void gfx_set_display_video_size(unsigned short width, unsigned short height)
#endif
{
unsigned long lock, size, value;
size = (unsigned long) (width << 1) * (unsigned long) height;
lock = READ_REG32(DC_UNLOCK);
WRITE_REG32(DC_UNLOCK, DC_UNLOCK_VALUE);
value = READ_REG32(DC_BUF_SIZE) & 0x0000FFFF;
value |= (((size + 63) >> 6) << 16);
WRITE_REG32(DC_BUF_SIZE, value);
WRITE_REG32(DC_UNLOCK, lock);
}
/*---------------------------------------------------------------------------
* gfx_set_display_video_offset (PRIVATE ROUTINE - NOT PART OF API)
*
* This routine is called by "gfx_set_video_offset". It abstracts the
* version of the display controller from the video overlay routines.
*---------------------------------------------------------------------------
*/
#if GFX_DISPLAY_DYNAMIC
void gu1_set_display_video_offset(unsigned long offset)
#else
void gfx_set_display_video_offset(unsigned long offset)
#endif
{
unsigned long lock;
lock = READ_REG32(DC_UNLOCK);
WRITE_REG32(DC_UNLOCK, DC_UNLOCK_VALUE);
WRITE_REG32(DC_VID_ST_OFFSET, offset);
WRITE_REG32(DC_UNLOCK, lock);
}
/*---------------------------------------------------------------------------
* gfx_test_timing_active
*---------------------------------------------------------------------------
*/
#if GFX_DISPLAY_DYNAMIC
int gu1_test_timing_active(void)
#else
int gfx_test_timing_active(void)
#endif
{
if (READ_REG32(DC_TIMING_CFG) & DC_TCFG_TGEN)
return(1);
else return(0);
}
/*---------------------------------------------------------------------------
* gfx_test_vertical_active
*---------------------------------------------------------------------------
*/
#if GFX_DISPLAY_DYNAMIC
int gu1_test_vertical_active(void)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -