📄 rndr_gu1.c
字号:
//
// For BLACKNESS (ROP = 0x00), set the color to 0x0000.
// For WHITENESS (ROP = 0xFF), set the color to 0xFFFF.
// For PATINVERT (ROP = 0x0F), invert the desired color.
//
// X screen X position (left)
// Y screen Y position (top)
// WIDTH width of rectangle, in pixels
// HEIGHT height of rectangle, in scanlines
// COLOR fill color
//
// THIS ROUTINE SHOULD NOT BE DIRECTLY CALLED FROM THE DRIVER. The driver
// should always use GFX_pattern_fill and let that routine call this one
// when approipriate. This is to hide quirks specific to MediaGX hardware.
//---------------------------------------------------------------------------
*/
void gu1_solid_fill(unsigned short x, unsigned short y,
unsigned short width, unsigned short height, unsigned long color)
{
unsigned short section;
/* POLL UNTIL ABLE TO WRITE TO THE REGISTERS */
/* Only one operation can be pending at a time. */
GFX_WAIT_PENDING;
/* SET REGISTERS TO DRAW RECTANGLE */
WRITE_REG16(GP_DST_XCOOR, x);
WRITE_REG16(GP_DST_YCOOR, y);
WRITE_REG16(GP_HEIGHT, height);
WRITE_REG16(GP_RASTER_MODE, 0x00F0); /* PATCOPY */
WRITE_REG16(GP_PAT_COLOR_0, (unsigned short) color);
/* CHECK WIDTH FOR GX BUG WORKAROUND */
if (width <= 16)
{
/* OK TO DRAW SMALL RECTANGLE IN ONE PASS */
WRITE_REG16(GP_WIDTH, width);
WRITE_REG16(GP_BLIT_MODE, 0);
}
else
{
/* DRAW FIRST PART OF RECTANGLE */
/* Get to a 16 pixel boundary. */
section = 0x10 - (x & 0x0F);
WRITE_REG16(GP_WIDTH, section);
WRITE_REG16(GP_BLIT_MODE, 0);
/* POLL UNTIL ABLE TO LOAD THE SECOND RECTANGLE */
GFX_WAIT_PENDING;
WRITE_REG16(GP_DST_XCOOR, x + section);
WRITE_REG16(GP_DST_YCOOR, y);
WRITE_REG16(GP_WIDTH, width - section);
WRITE_REG16(GP_BLIT_MODE, 0);
}
}
/*
//----------------------------------------------------------------------------
// GFX_PATTERN_FILL
//
// This routine is used to fill a rectangular region. The pattern must
// be previously loaded using one of GFX_load_*_pattern routines. Also, the
// raster operation must be previously specified using the
// "GFX_load_raster_operation" routine.
//
// X screen X position (left)
// Y screen Y position (top)
// WIDTH width of rectangle, in pixels
// HEIGHT height of rectangle, in scanlines
//----------------------------------------------------------------------------
*/
#if GFX_2DACCEL_DYNAMIC
void gu1_pattern_fill(unsigned short x, unsigned short y,
unsigned short width, unsigned short height)
#else
void gfx_pattern_fill(unsigned short x, unsigned short y,
unsigned short width, unsigned short height)
#endif
{
unsigned short section, buffer_width, blit_mode;
/* CHECK IF OPTIMIZED SOLID CASES */
/* Check all 16 bits of the ROP to include solid pattern flags. */
switch(GFXsavedRop)
{
/* CHECK FOR SPECIAL CASES WITHOUT DESTINATION DATA */
/* Need hardware workaround for fast "burst write" cases. */
case 0x00F0:
gu1_solid_fill(x, y, width, height, (unsigned short) GFXsavedColor);
break;
case 0x000F:
gu1_solid_fill(x, y, width, height,
(unsigned short) ~GFXsavedColor);
break;
case 0x0000:
gu1_solid_fill(x, y, width, height, 0x0000);
break;
case 0x00FF:
gu1_solid_fill(x, y, width, height, 0xFFFF);
break;
/* REMAINING CASES REQUIRE DESTINATION DATA OR NOT SOLID COLOR */
default:
/* DETERMINE BLT MODE VALUE */
/* Still here for non-solid patterns without destination data. */
blit_mode = GFXusesDstData ? BM_READ_DST_FB0 : 0;
/* SET SOURCE EXPANSION MODE */
/* If the ROP requires source data, then the source data is all 1's */
/* and then expanded into the desired color in GP_SRC_COLOR_1. */
blit_mode |= BM_SOURCE_EXPAND;
/* POLL UNTIL ABLE TO WRITE TO THE REGISTERS */
/* Write the registers that do not change for each section. */
GFX_WAIT_PENDING;
WRITE_REG16(GP_HEIGHT, height);
/* SINCE ONLY DESTINATION DATA, WE CAN USE BOTH BB0 AND BB1. */
/* Therefore, width available = BLT buffer width * 2. */
buffer_width = GFXbufferWidthPixels << 1;
/* REPEAT UNTIL FINISHED WITH RECTANGLE */
/* Perform BLT in vertical sections, as wide as the BLT buffer */
/* allows. Hardware does not split the operations, so */
/* software must do it to avoid large scanlines that would */
/* overflow the BLT buffers. */
while(width > 0)
{
/* DETERMINE WIDTH OF SECTION */
if (width > buffer_width) section = buffer_width;
else section = width;
/* POLL UNTIL ABLE TO WRITE TO THE REGISTERS */
GFX_WAIT_PENDING;
WRITE_REG16(GP_DST_XCOOR, x);
WRITE_REG16(GP_DST_YCOOR, y);
WRITE_REG16(GP_WIDTH, section);
WRITE_REG16(GP_BLIT_MODE, blit_mode);
/* ADJUST PARAMETERS FOR NEXT SECTION */
width -= section;
x += section;
}
break;
}
}
/*
//----------------------------------------------------------------------------
// SCREEN TO SCREEN BLT
//
// This routine should be used to perform a screen to screen BLT when the
// ROP does not require destination data.
//
// SRCX screen X position to copy from
// SRCY screen Y position to copy from
// DSTX screen X position to copy to
// DSTY screen Y position to copy to
// WIDTH width of rectangle, in pixels
// HEIGHT height of rectangle, in scanlines
//----------------------------------------------------------------------------
*/
#if GFX_2DACCEL_DYNAMIC
void gu1_screen_to_screen_blt(unsigned short srcx, unsigned short srcy,
unsigned short dstx, unsigned short dsty, unsigned short width,
unsigned short height)
#else
void gfx_screen_to_screen_blt(unsigned short srcx, unsigned short srcy,
unsigned short dstx, unsigned short dsty, unsigned short width,
unsigned short height)
#endif
{
unsigned short section, buffer_width;
unsigned short blit_mode;
/* CHECK IF RASTER OPERATION REQUIRES DESTINATION DATA */
blit_mode = GFXusesDstData ? BM_READ_DST_FB1 | BM_READ_SRC_FB :
BM_READ_SRC_FB;
/* CHECK Y DIRECTION */
/* Hardware has support for negative Y direction. */
if (dsty > srcy)
{
blit_mode |= BM_REVERSE_Y;
srcy += height - 1;
dsty += height - 1;
}
/* CHECK X DIRECTION */
/* Hardware does not support negative X direction since at the time */
/* of development all supported resolutions could fit a scanline of */
/* data at once into the BLT buffers (using both BB0 and BB1). This */
/* code is more generic to allow for any size BLT buffer. */
if (dstx > srcx)
{
srcx += width;
dstx += width;
}
/* POLL UNTIL ABLE TO WRITE TO THE REGISTERS */
/* Write the registers that do not change for each section. */
GFX_WAIT_PENDING;
WRITE_REG16(GP_HEIGHT, height);
/* CHECK AVAILABLE BLT BUFFER SIZE */
/* Can use both BLT buffers if no destination data is required. */
buffer_width = GFXusesDstData ? GFXbufferWidthPixels :
GFXbufferWidthPixels << 1;
/* REPEAT UNTIL FINISHED WITH RECTANGLE */
/* Perform BLT in vertical sections, as wide as the BLT buffer allows. */
/* Hardware does not split the operations, so software must do it to */
/* avoid large scanlines that would overflow the BLT buffers. */
while(width > 0)
{
/* CHECK WIDTH OF CURRENT SECTION */
if (width > buffer_width) section = buffer_width;
else section = width;
/* PROGRAM REGISTERS THAT ARE THE SAME FOR EITHER X DIRECTION */
GFX_WAIT_PENDING;
WRITE_REG16(GP_SRC_YCOOR, srcy);
WRITE_REG16(GP_DST_YCOOR, dsty);
WRITE_REG16(GP_WIDTH, section);
/* CHECK X DIRECTION */
if (dstx > srcx)
{
/* NEGATIVE X DIRECTION */
/* Still positive X direction within the section. */
srcx -= section;
dstx -= section;
WRITE_REG16(GP_SRC_XCOOR, srcx);
WRITE_REG16(GP_DST_XCOOR, dstx);
WRITE_REG16(GP_BLIT_MODE, blit_mode);
}
else
{
/* POSITIVE X DIRECTION */
WRITE_REG16(GP_SRC_XCOOR, srcx);
WRITE_REG16(GP_DST_XCOOR, dstx);
WRITE_REG16(GP_BLIT_MODE, blit_mode);
dstx += section;
srcx += section;
}
width -= section;
}
}
/*
//----------------------------------------------------------------------------
// SCREEN TO SCREEN TRANSPARENT BLT
//
// This routine should be used to perform a screen to screen BLT when a
// specified color should by transparent. The only supported ROP is SRCCOPY.
//
// SRCX screen X position to copy from
// SRCY screen Y position to copy from
// DSTX screen X position to copy to
// DSTY screen Y position to copy to
// WIDTH width of rectangle, in pixels
// HEIGHT height of rectangle, in scanlines
// COLOR transparent color
//----------------------------------------------------------------------------
*/
#if GFX_2DACCEL_DYNAMIC
void gu1_screen_to_screen_xblt(unsigned short srcx, unsigned short srcy,
unsigned short dstx, unsigned short dsty, unsigned short width,
unsigned short height, unsigned long color)
#else
void gfx_screen_to_screen_xblt(unsigned short srcx, unsigned short srcy,
unsigned short dstx, unsigned short dsty, unsigned short width,
unsigned short height, unsigned long color)
#endif
{
unsigned short section, buffer_width;
unsigned short blit_mode = BM_READ_SRC_FB;
/* CHECK Y DIRECTION */
/* Hardware has support for negative Y direction. */
if (dsty > srcy)
{
blit_mode |= BM_REVERSE_Y;
srcy += height - 1;
dsty += height - 1;
}
/* CHECK X DIRECTION */
/* Hardware does not support negative X direction since at the time */
/* of development all supported resolutions could fit a scanline of */
/* data at once into the BLT buffers (using both BB0 and BB1). This */
/* code is more generic to allow for any size BLT buffer. */
if (dstx > srcx)
{
srcx += width;
dstx += width;
}
/* CALCULATE BLT BUFFER SIZE */
/* Need to use BB1 to store the BLT buffer data. */
buffer_width = GFXbufferWidthPixels;
/* WRITE TRANSPARENCY COLOR TO BLT BUFFER 1 */
if (GFXbpp == 8)
{
color &= 0x00FF;
color |= (color << 8);
}
color = (color & 0x0000FFFF) | (color << 16);
/* WAIT UNTIL PIPELINE IS NOT BUSY BEFORE LOADING DATA INTO BB1 */
/* Need to make sure any previous BLT using BB1 is complete. */
/* Only need to load 32 bits of BB1 for the 1 pixel BLT that follows. */
GFX_WAIT_BUSY;
WRITE_REG32(GFXbb1Base, color);
/* DO BOGUS BLT TO LATCH DATA FROM BB1 */
/* Already know graphics pipeline is idle. */
/* Only need to latch data into the holding registers for the current */
/* data from BB1. A 1 pixel wide BLT will suffice. */
WRITE_REG32(GP_DST_XCOOR, 0);
WRITE_REG32(GP_SRC_XCOOR, 0);
WRITE_REG32(GP_WIDTH, 0x00010001);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -