void gu2_set_bpp(unsigned short bpp);
void gu2_set_solid_pattern(unsigned long color);
void gu2_set_mono_pattern(unsigned long bgcolor, unsigned long fgcolor,
unsigned long data0, unsigned long data1,
unsigned char transparency);
void gu2_set_color_pattern(unsigned long bgcolor, unsigned long fgcolor,
unsigned long data0, unsigned long data1,
unsigned long data2, unsigned long data3,
unsigned char transparency);
void gu2_load_color_pattern_line(short y, unsigned long *pattern_8x8);
void gu2_set_solid_source(unsigned long color);
void gu2_set_mono_source(unsigned long bgcolor, unsigned long fgcolor,
unsigned short transparent);
void gu2_set_pattern_flags(unsigned short flags);
void gu2_set_raster_operation(unsigned char rop);
void gu2_pattern_fill(unsigned short x, unsigned short y,
unsigned short width, unsigned short height);
void gu2_color_pattern_fill(unsigned short x, unsigned short y,
unsigned short width, unsigned short height,
unsigned long *pattern);
void gu2_screen_to_screen_blt(unsigned short srcx, unsigned short srcy,
unsigned short dstx, unsigned short dsty,
unsigned short width, unsigned short height);
void gu2_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);
void gu2_color_bitmap_to_screen_blt(unsigned short srcx, unsigned short srcy,
unsigned short dstx, unsigned short dsty,
unsigned short width,
unsigned short height,
unsigned char *data, long pitch);
void gu2_color_bitmap_to_screen_xblt(unsigned short srcx, unsigned short srcy,
unsigned short dstx, unsigned short dsty,
unsigned short width,
unsigned short height,
unsigned char *data, long pitch,
unsigned long color);
void gu2_mono_bitmap_to_screen_blt(unsigned short srcx, unsigned short srcy,
unsigned short dstx, unsigned short dsty,
unsigned short width,
unsigned short height, unsigned char *data,
short pitch);
void gu2_text_blt(unsigned short dstx, unsigned short dsty,
unsigned short width, unsigned short height,
unsigned char *data);
void gu2_bresenham_line(unsigned short x, unsigned short y,
unsigned short length, unsigned short initerr,
unsigned short axialerr, unsigned short diagerr,
unsigned short flags);
void gu2_wait_until_idle(void);
int gu2_test_blt_pending(void);
void gu22_set_source_stride(unsigned short stride);
void gu22_set_destination_stride(unsigned short stride);
void gu22_set_pattern_origin(int x, int y);
void gu22_set_source_transparency(unsigned long color, unsigned long mask);
void gu22_set_alpha_mode(int mode);
void gu22_set_alpha_value(unsigned char value);
void gu22_pattern_fill(unsigned long dstoffset, unsigned short width,
unsigned short height);
void gu22_color_pattern_fill(unsigned long dstoffset, unsigned short width,
unsigned short height, unsigned long *pattern);
void gu22_screen_to_screen_blt(unsigned long srcoffset,
unsigned long dstoffset, unsigned short width,
unsigned short height, int flags);
void gu22_mono_expand_blt(unsigned long srcbase, unsigned short srcx,
unsigned short srcy, unsigned long dstoffset,
unsigned short width, unsigned short height,
int byte_packed);
void gu22_color_bitmap_to_screen_blt(unsigned short srcx, unsigned short srcy,
unsigned long dstoffset,
unsigned short width,
unsigned short height,
unsigned char *data, short pitch);
void gu22_mono_bitmap_to_screen_blt(unsigned short srcx, unsigned short srcy,
unsigned long dstoffset,
unsigned short width,
unsigned short height,
unsigned char *data, short pitch);
void gu22_text_blt(unsigned long dstoffset, unsigned short width,
unsigned short height, unsigned char *data);
void gu22_bresenham_line(unsigned long dstoffset, unsigned short length,
unsigned short initerr, unsigned short axialerr,
unsigned short diagerr, unsigned short flags);
void gu22_sync_to_vblank(void);
void gu2_reset_pitch(unsigned short pitch);
#define GU2_WAIT_PENDING while(READ_GP32(MGP_BLT_STATUS) & MGP_BS_BLT_PENDING)
#define GU2_WAIT_BUSY while(READ_GP32(MGP_BLT_STATUS) & MGP_BS_BLT_BUSY)
#define GU2_WAIT_HALF_EMPTY while(!(READ_GP32(MGP_BLT_STATUS) & MGP_BS_HALF_EMPTY))
#define WORD_SWIZZLE(x) (((x) << 16) | ((x) >> 16))
#define BYTE_SWIZZLE(x) (((x) << 24) | ((x) >> 24) | (((x) << 8) & 0x00FF0000) | (((x) >> 8) & 0x0000FF00))
unsigned long gu2_bpp;
unsigned long gu2_pitch = 1280;
unsigned long gu2_src_pitch = 1280;
unsigned long gu2_dst_pitch = 1280;
unsigned long gu2_xshift = 1;
unsigned long gu2_pattern_origin = 0;
unsigned long gu2_rop32;
unsigned long gu2_alpha32 = 0;
unsigned long gu2_alpha_value = 0;
unsigned long gu2_alpha_mode = 0;
unsigned long gu2_alpha_active = 0;
unsigned short gu2_alpha_blt_mode = 0;
unsigned short gu2_alpha_vec_mode = 0;
unsigned short gu2_blt_mode = 0;
unsigned short gu2_vector_mode = 0;
unsigned short gu2_bm_throttle = 0;
unsigned short gu2_vm_throttle = 0;
int gu2_current_line = 0;
#if GFX_2DACCEL_DYNAMIC
void
gu2_reset_pitch(unsigned short pitch)
#else
void
gfx_reset_pitch(unsigned short pitch)
#endif
{
gu2_pitch = pitch;
gu2_dst_pitch = pitch;
gu2_src_pitch = pitch;
}
#if GFX_2DACCEL_DYNAMIC
void
gu2_set_bpp(unsigned short bpp)
#else
void
gfx_set_bpp(unsigned short bpp)
#endif
{
GFXbpp = bpp;
switch (bpp) {
case 8:
gu2_bpp = MGP_RM_BPPFMT_332;
gu2_xshift = 0;
break;
case 12:
gu2_bpp = MGP_RM_BPPFMT_4444;
gu2_xshift = 1;
break;
case 15:
gu2_bpp = MGP_RM_BPPFMT_1555;
gu2_xshift = 1;
break;
case 16:
gu2_bpp = MGP_RM_BPPFMT_565;
gu2_xshift = 1;
break;
case 32:
gu2_bpp = MGP_RM_BPPFMT_8888;
gu2_xshift = 2;
break;
}
GU2_WAIT_BUSY;
WRITE_GP32(MGP_RASTER_MODE, gu2_bpp);
}
#if GFX_2DACCEL_DYNAMIC
void
gu2_set_solid_source(unsigned long color)
#else
void
gfx_set_solid_source(unsigned long color)
#endif
{
GFXsourceFlags = 0;
GU2_WAIT_PENDING;
WRITE_GP32(MGP_SRC_COLOR_FG, color);
}
#if GFX_2DACCEL_DYNAMIC
void
gu2_set_mono_source(unsigned long bgcolor, unsigned long fgcolor,
unsigned short transparent)
#else
void
gfx_set_mono_source(unsigned long bgcolor, unsigned long fgcolor,
unsigned short transparent)
#endif
{
GFXsourceFlags = transparent ? MGP_RM_SRC_TRANS : 0;
GU2_WAIT_PENDING;
WRITE_GP32(MGP_SRC_COLOR_FG, fgcolor);
WRITE_GP32(MGP_SRC_COLOR_BG, bgcolor);
}
#if GFX_2DACCEL_DYNAMIC
void
gu2_set_solid_pattern(unsigned long color)
#else
void
gfx_set_solid_pattern(unsigned long color)
#endif
{
GFXsourceFlags = 0;
GFXpatternFlags = 0;
GU2_WAIT_PENDING;
WRITE_GP32(MGP_RASTER_MODE, gu2_bpp);
WRITE_GP32(MGP_PAT_COLOR_0, color);
}
#if GFX_2DACCEL_DYNAMIC
void
gu2_set_mono_pattern(unsigned long bgcolor, unsigned long fgcolor,
unsigned long data0, unsigned long data1,
unsigned char transparent)
#else
void
gfx_set_mono_pattern(unsigned long bgcolor, unsigned long fgcolor,
unsigned long data0, unsigned long data1,
unsigned char transparent)
#endif
{
GFXsourceFlags = 0;
if (transparent)
GFXpatternFlags = MGP_RM_PAT_MONO | MGP_RM_PAT_TRANS;
else
GFXpatternFlags = MGP_RM_PAT_MONO;
GU2_WAIT_PENDING;
WRITE_GP32(MGP_RASTER_MODE, gu2_bpp | GFXpatternFlags);
WRITE_GP32(MGP_PAT_COLOR_0, bgcolor);
WRITE_GP32(MGP_PAT_COLOR_1, fgcolor);
WRITE_GP32(MGP_PAT_DATA_0, data0);
WRITE_GP32(MGP_PAT_DATA_1, data1);
}
#if GFX_2DACCEL_DYNAMIC
void
gu2_set_color_pattern(unsigned long bgcolor, unsigned long fgcolor,
unsigned long data0, unsigned long data1,
unsigned long data2, unsigned long data3,
unsigned char transparent)
#else
void
gfx_set_color_pattern(unsigned long bgcolor, unsigned long fgcolor,
unsigned long data0, unsigned long data1,
unsigned long data2, unsigned long data3,
unsigned char transparent)
#endif
{
}
#if GFX_2DACCEL_DYNAMIC
void
gu2_load_color_pattern_line(short y, unsigned long *pattern_8x8)
#else
void
gfx_load_color_pattern_line(short y, unsigned long *pattern_8x8)
#endif
{
unsigned long temp1, temp2, temp3, temp4;
GFXsourceFlags = 0;
GFXpatternFlags = MGP_RM_PAT_COLOR;
GU2_WAIT_PENDING;
WRITE_GP32(MGP_RASTER_MODE,
(gu2_rop32 & ~MGP_RM_PAT_FLAGS) | MGP_RM_PAT_COLOR);
if (gu2_xshift == 0) {
pattern_8x8 += (y & 7) << 1;
temp1 = BYTE_SWIZZLE(pattern_8x8[0]);
temp2 = BYTE_SWIZZLE(pattern_8x8[1]);
WRITE_GP32(MGP_PAT_DATA_1, temp1);
WRITE_GP32(MGP_PAT_DATA_0, temp2);
WRITE_GP32(MGP_PAT_COLOR_1, temp1);
WRITE_GP32(MGP_PAT_COLOR_0, temp2);
GU2_WAIT_BUSY;
WRITE_GP32(MGP_PAT_COLOR_3, temp1);
WRITE_GP32(MGP_PAT_COLOR_2, temp2);
WRITE_GP32(MGP_PAT_COLOR_5, temp1);
WRITE_GP32(MGP_PAT_COLOR_4, temp2);
} else if (gu2_xshift == 1) {
pattern_8x8 += (y & 7) << 2;
temp1 = WORD_SWIZZLE(pattern_8x8[0]);
temp2 = WORD_SWIZZLE(pattern_8x8[1]);
temp3 = WORD_SWIZZLE(pattern_8x8[2]);
temp4 = WORD_SWIZZLE(pattern_8x8[3]);
WRITE_GP32(MGP_PAT_COLOR_1, temp1);
WRITE_GP32(MGP_PAT_COLOR_0, temp2);
WRITE_GP32(MGP_PAT_DATA_1, temp3);
WRITE_GP32(MGP_PAT_DATA_0, temp4);
GU2_WAIT_BUSY;
WRITE_GP32(MGP_PAT_COLOR_5, temp1);
WRITE_GP32(MGP_PAT_COLOR_4, temp2);
WRITE_GP32(MGP_PAT_COLOR_3, temp3);
WRITE_GP32(MGP_PAT_COLOR_2, temp4);
} else {
pattern_8x8 += (y & 7) << 3;
WRITE_GP32(MGP_PAT_COLOR_1, pattern_8x8[4]);
WRITE_GP32(MGP_PAT_COLOR_0, pattern_8x8[5]);
WRITE_GP32(MGP_PAT_DATA_1, pattern_8x8[6]);
WRITE_GP32(MGP_PAT_DATA_0, pattern_8x8[7]);
GU2_WAIT_BUSY;
WRITE_GP32(MGP_PAT_COLOR_5, pattern_8x8[0]);
WRITE_GP32(MGP_PAT_COLOR_4, pattern_8x8[1]);
WRITE_GP32(MGP_PAT_COLOR_3, pattern_8x8[2]);
WRITE_GP32(MGP_PAT_COLOR_2, pattern_8x8[3]);
}
}
#if GFX_2DACCEL_DYNAMIC
void
gu2_set_raster_operation(unsigned char rop)
#else
void
gfx_set_raster_operation(unsigned char rop)
#endif
{
gu2_blt_mode = 0;
gu2_alpha_active = 0;
gu2_rop32 = (unsigned long)rop | GFXpatternFlags | gu2_bpp;
if ((rop & 0x33) ^ ((rop >> 2) & 0x33))
gu2_rop32 |= GFXsourceFlags;
else
gu2_blt_mode = 0x40;
if ((rop & 0x55) ^ ((rop >> 1) & 0x55)) {
gu2_blt_mode |= MGP_BM_DST_REQ;
gu2_vector_mode = MGP_VM_DST_REQ;
} else {
gu2_vector_mode = 0;
}
}
#if GFX_2DACCEL_DYNAMIC
void
gu2_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 long offset = 0, size;
size = (((unsigned long)width) << 16) | height;
offset = (unsigned long)y *gu2_pitch + (((unsigned long)x) << gu2_xshift);
if (GFXpatternFlags) {
offset |= ((unsigned long)(x & 7)) << 26;
offset |= ((unsigned long)(y & 7)) << 29;
}
GU2_WAIT_PENDING;
WRITE_GP32(MGP_RASTER_MODE, gu2_rop32);
WRITE_GP32(MGP_DST_OFFSET, offset);
WRITE_GP32(MGP_WID_HEIGHT, size);
WRITE_GP32(MGP_STRIDE, gu2_pitch);
WRITE_GP32(MGP_BLT_MODE, gu2_blt_mode);
}
#if GFX_2DACCEL_DYNAMIC
void
gu2_color_pattern_fill(unsigned short x, unsigned short y,
unsigned short width, unsigned short height,
unsigned long *pattern)
#else
void
gfx_color_pattern_fill(unsigned short x, unsigned short y,
unsigned short width, unsigned short height,
unsigned long *pattern)
#endif
{
unsigned long offset = (unsigned long)y * gu2_pitch +
(((unsigned long)x) << gu2_xshift);
unsigned long origin = gu2_pattern_origin;
unsigned long pitch = gu2_dst_pitch;
gfx2_set_pattern_origin(x, y);
gfx2_set_destination_stride((unsigned short)gu2_pitch);
gfx2_color_pattern_fill(offset, width, height, pattern);
gu2_pattern_origin = origin;
gu2_dst_pitch = pitch;
}
#if GFX_2DACCEL_DYNAMIC
void
gu2_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 long srcoffset, dstoffset, size;
unsigned short blt_mode;
size = (((unsigned long)width) << 16) | height;
blt_mode = gu2_blt_mode | MGP_BM_SRC_FB;
if (dstx > srcx) {
blt_mode |= MGP_BM_NEG_XDIR;
srcx += width - 1;
dstx += width - 1;
}
if (dsty > srcy) {
blt_mode |= MGP_BM_NEG_YDIR;
srcy += height - 1;
dsty += height - 1;
}
srcoffset = (unsigned long)srcy *gu2_pitch +
(((unsigned long)srcx) << gu2_xshift);
dstoffset = ((unsigned long)dsty * gu2_pitch +
(((unsigned long)dstx) << gu2_xshift)) & 0xFFFFFF;
if (GFXpatternFlags) {
dstoffset |= ((unsigned long)(dstx & 7)) << 26;
dstoffset |= ((unsigned long)(dsty & 7)) << 29;
}
if (blt_mode & MGP_BM_NEG_XDIR) {
srcoffset += (1 << gu2_xshift) - 1;
dstoffset += (1 << gu2_xshift) - 1;
}
GU2_WAIT_PENDING;
WRITE_GP32(MGP_RASTER_MODE, gu2_rop32);
WRITE_GP32(MGP_SRC_OFFSET, srcoffset);
WRITE_GP32(MGP_DST_OFFSET, dstoffset);
WRITE_GP32(MGP_WID_HEIGHT, size);
WRITE_GP32(MGP_STRIDE, gu2_pitch | (gu2_pitch << 16));
WRITE_GP16(MGP_BLT_MODE, blt_mode);
}
#if GFX_2DACCEL_DYNAMIC
void
gu2_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 long rop32;
rop32 = gu2_rop32;
GU2_WAIT_PENDING;
WRITE_GP32(MGP_SRC_COLOR_FG, color);
WRITE_GP32(MGP_SRC_COLOR_BG, 0xFFFFFFFF);
gu2_rop32 = gu2_bpp | MGP_RM_SRC_TRANS | 0xCC;
gfx_screen_to_screen_blt(srcx, srcy, dstx, dsty, width, height);
gu2_rop32 = rop32;
}
#if GFX_2DACCEL_DYNAMIC
void
gu2_color_bitmap_to_screen_blt(unsigned short srcx, unsigned short srcy,
unsigned short dstx, unsigned short dsty,
unsigned short width, unsigned short height,
unsigned char *data, long pitch)
#else
void
gfx_color_bitmap_to_screen_blt(unsigned short srcx, unsigned short srcy,
unsigned short dstx, unsigned short dsty,
unsigned short width, unsigned short height,
unsigned char *data, long pitch)
#endif
{
unsigned long dstoffset, srcoffset, size, bytes;
unsigned long offset, temp_offset;
unsigned long dword_bytes, bytes_extra;
unsigned short blt_mode;
blt_mode = gu2_blt_mode | MGP_BM_SRC_FB;
size = (((unsigned long)width) << 16) | 1;
offset = (unsigned long)srcy *pitch + ((unsigned long)srcx << gu2_xshift);
dstoffset = (unsigned long)dsty *gu2_pitch +
(((unsigned long)dstx) << gu2_xshift);
if (GFXpatternFlags) {
dstoffset |= ((unsigned long)(dstx & 7)) << 26;
dstoffset |= ((unsigned long)(dsty & 7)) << 29;
}
bytes = width << gu2_xshift;
dword_bytes = bytes & ~0x3L;
bytes_extra = bytes & 0x3L;
GU2_WAIT_BUSY;
WRITE_GP32(MGP_RASTER_MODE, gu2_rop32);
WRITE_GP32(MGP_WID_HEIGHT, size);
WRITE_GP32(MGP_STRIDE, gu2_pitch);
while (height--) {
temp_offset = offset;
srcoffset = gfx_gx2_scratch_base;
if (gu2_current_line)
srcoffset += 8192;
GU2_WAIT_PENDING;
WRITE_GP32(MGP_SRC_OFFSET, srcoffset);
WRITE_GP32(MGP_DST_OFFSET, dstoffset);
dstoffset += gu2_pitch;
dstoffset += 0x20000000;
WRITE_FRAME_BUFFER_STRING32(srcoffset, dword_bytes, data, temp_offset);
if (bytes_extra) {
temp_offset += dword_bytes;
srcoffset += dword_bytes;
WRITE_FRAME_BUFFER_STRING8(srcoffset, bytes_extra, data,
temp_offset);
}
WRITE_GP16(MGP_BLT_MODE, blt_mode);
offset += pitch;
gu2_current_line = 1 - gu2_current_line;
}
}
#if GFX_2DACCEL_DYNAMIC
void
gu2_color_bitmap_to_screen_xblt(unsigned short srcx, unsigned short srcy,
unsigned short dstx, unsigned short dsty,
unsigned short width, unsigned short height,
unsigned char *data, long pitch,
unsigned long color)
#else
void
gfx_color_bitmap_to_screen_xblt(unsigned short srcx, unsigned short srcy,
unsigned short dstx, unsigned short dsty,
unsigned short width, unsigned short height,
unsigned char *data, long pitch,
unsigned long color)
#endif
{
unsigned long rop32;
rop32 = gu2_rop32;
GU2_WAIT_PENDING;
WRITE_GP32(MGP_SRC_COLOR_FG, color);
WRITE_GP32(MGP_SRC_COLOR_BG, 0xFFFFFFFF);
gu2_rop32 = gu2_bpp | MGP_RM_SRC_TRANS | 0xCC;
gfx_color_bitmap_to_screen_blt(srcx, srcy, dstx, dsty, width, height,
data, pitch);
gu2_rop32 = rop32;
}
#if GFX_2DACCEL_DYNAMIC
void
gu2_mono_bitmap_to_screen_blt(unsigned short srcx, unsigned short srcy,
unsigned short dstx, unsigned short dsty,
unsigned short width, unsigned short height,
unsigned char *data, short pitch)
#else
void
gfx_mono_bitmap_to_screen_blt(unsigned short srcx, unsigned short srcy,
unsigned short dstx, unsigned short dsty,
unsigned short width, unsigned short height,
unsigned char *data, short pitch)
#endif
{
unsigned long dstoffset, size, bytes;
unsigned long offset, temp_offset, temp1 = 0, temp2 = 0;
unsigned long i, j = 0, fifo_lines, dwords_extra, bytes_extra;
unsigned long shift = 0;
size = (((unsigned long)width) << 16) | height;
offset = (unsigned long)srcy *pitch + ((unsigned long)srcx >> 3);
dstoffset = (unsigned long)dsty *gu2_pitch +
(((unsigned long)dstx) << gu2_xshift);
if (GFXpatternFlags) {
dstoffset |= ((unsigned long)(dstx & 7)) << 26;
dstoffset |= ((unsigned long)(dsty & 7)) << 29;
}
bytes = ((srcx & 7) + width + 7) >> 3;
fifo_lines = bytes >> 5;
dwords_extra = (bytes & 0x0000001Cl) >> 2;
bytes_extra = bytes & 0x00000003l;
GU2_WAIT_PENDING;
WRITE_GP32(MGP_RASTER_MODE, gu2_rop32);
WRITE_GP32(MGP_SRC_OFFSET, ((unsigned long)srcx & 7) << 26);
WRITE_GP32(MGP_DST_OFFSET, dstoffset);
WRITE_GP32(MGP_WID_HEIGHT, size);
WRITE_GP32(MGP_STRIDE, gu2_pitch);
WRITE_GP16(MGP_BLT_MODE, gu2_blt_mode | MGP_BM_SRC_HOST | MGP_BM_SRC_MONO);
GU2_WAIT_PENDING;
while (height--) {
temp_offset = offset;
for (i = 0; i < fifo_lines; i++) {
GU2_WAIT_HALF_EMPTY;
WRITE_GPREG_STRING32(MGP_HST_SOURCE, 8, j, data, temp_offset, temp1);
temp_offset += 32;
}
GU2_WAIT_HALF_EMPTY;
if (dwords_extra) {
WRITE_GPREG_STRING32(MGP_HST_SOURCE, dwords_extra, i, data,
temp_offset, temp1);
temp_offset += (dwords_extra << 2);
}
shift = 0;
if (bytes_extra)
WRITE_GPREG_STRING8(MGP_HST_SOURCE, bytes_extra, shift, i, data,
temp_offset, temp1, temp2);
offset += pitch;
}
}
#if GFX_2DACCEL_DYNAMIC
void
gu2_text_blt(unsigned short dstx, unsigned short dsty, unsigned short width,
unsigned short height, unsigned char *data)
#else
void
gfx_text_blt(unsigned short dstx, unsigned short dsty, unsigned short width,
unsigned short height, unsigned char *data)
#endif
{
unsigned long size, bytes;
unsigned long dstoffset, temp1 = 0, temp2 = 0, temp_offset = 0;
unsigned long i, j = 0, fifo_lines, dwords_extra, bytes_extra;
unsigned long shift;
size = (((unsigned long)width) << 16) | height;
dstoffset = (unsigned long)dsty *gu2_pitch +
(((unsigned long)dstx) << gu2_xshift);
if (GFXpatternFlags) {
dstoffset |= ((unsigned long)(dstx & 7)) << 26;
dstoffset |= ((unsigned long)(dsty & 7)) << 29;
}
bytes = ((width + 7) >> 3) * height;
fifo_lines = bytes >> 5;
dwords_extra = (bytes & 0x0000001Cl) >> 2;
bytes_extra = bytes & 0x00000003l;
GU2_WAIT_PENDING;
WRITE_GP32(MGP_RASTER_MODE, gu2_rop32);
WRITE_GP32(MGP_SRC_OFFSET, 0);
WRITE_GP32(MGP_DST_OFFSET, dstoffset);
WRITE_GP32(MGP_WID_HEIGHT, size);
WRITE_GP32(MGP_STRIDE, gu2_pitch);
WRITE_GP16(MGP_BLT_MODE, gu2_blt_mode | MGP_BM_SRC_HOST |
MGP_BM_SRC_BP_MONO);
GU2_WAIT_PENDING;
for (i = 0; i < fifo_lines; i++) {
GU2_WAIT_HALF_EMPTY;
WRITE_GPREG_STRING32(MGP_HST_SOURCE, 8, j, data, temp_offset, temp1);
temp_offset += 32;
}
if (dwords_extra || bytes_extra) {
GU2_WAIT_HALF_EMPTY;
if (dwords_extra) {
WRITE_GPREG_STRING32(MGP_HST_SOURCE, dwords_extra, i, data,
temp_offset, temp1);
temp_offset += (dwords_extra << 2);
}
if (bytes_extra) {
shift = 0;
WRITE_GPREG_STRING8(MGP_HST_SOURCE, bytes_extra, shift, i, data,
temp_offset, temp1, temp2);
}
}
}
#if GFX_2DACCEL_DYNAMIC
void
gu2_bresenham_line(unsigned short x, unsigned short y,
unsigned short length, unsigned short initerr,
unsigned short axialerr, unsigned short diagerr,
unsigned short flags)
#else
void
gfx_bresenham_line(unsigned short x, unsigned short y,
unsigned short length, unsigned short initerr,
unsigned short axialerr, unsigned short diagerr,
unsigned short flags)
#endif
{
unsigned long offset;
unsigned long data1 = (((unsigned long)axialerr) << 16) | diagerr;
unsigned long data2 = (((unsigned long)length) << 16) | initerr;
unsigned short vector_mode = gu2_vector_mode | flags;
offset = (unsigned long)y *gu2_pitch + (((unsigned long)x) << gu2_xshift);
if (!length)
return;
GU2_WAIT_PENDING;
WRITE_GP32(MGP_RASTER_MODE, gu2_rop32);
WRITE_GP32(MGP_DST_OFFSET, offset);
WRITE_GP32(MGP_VEC_ERR, data1);
WRITE_GP32(MGP_VEC_LEN, data2);
WRITE_GP32(MGP_STRIDE, gu2_pitch);
WRITE_GP32(MGP_VECTOR_MODE, vector_mode);
}
#if GFX_2DACCEL_DYNAMIC
void
gu2_wait_until_idle(void)
#else
void
gfx_wait_until_idle(void)
#endif
{
while (READ_GP32(MGP_BLT_STATUS) & MGP_BS_BLT_BUSY) ;
}
#if GFX_2DACCEL_DYNAMIC
int
gu2_test_blt_pending(void)
#else
int
gfx_test_blt_pending(void)
#endif
{
if (READ_GP32(MGP_BLT_STATUS) & MGP_BS_BLT_PENDING)
return (1);
return (0);
}
#if GFX_2DACCEL_DYNAMIC
void
gu22_set_source_stride(unsigned short stride)
#else
void
gfx2_set_source_stride(unsigned short stride)
#endif
{
gu2_src_pitch = (unsigned long)stride;
}
#if GFX_2DACCEL_DYNAMIC
void
gu22_set_destination_stride(unsigned short stride)
#else
void
gfx2_set_destination_stride(unsigned short stride)
#endif
{
gu2_dst_pitch = (unsigned long)stride;
}
#if GFX_2DACCEL_DYNAMIC
void
gu22_set_pattern_origin(int x, int y)
#else
void
gfx2_set_pattern_origin(int x, int y)
#endif
{
gu2_pattern_origin = (((unsigned long)(x & 7)) << 26) |
(((unsigned long)(y & 7)) << 29);
}
#if GFX_2DACCEL_DYNAMIC
void
gu22_set_source_transparency(unsigned long color, unsigned long mask)
#else
void
gfx2_set_source_transparency(unsigned long color, unsigned long mask)
#endif
{
GU2_WAIT_PENDING;
WRITE_GP32(MGP_SRC_COLOR_FG, color);
WRITE_GP32(MGP_SRC_COLOR_BG, mask);
GFXsourceFlags = (color || mask) ? MGP_RM_SRC_TRANS : 0;
}
#if GFX_2DACCEL_DYNAMIC
void
gu22_set_alpha_mode(int mode)
#else
void
gfx2_set_alpha_mode(int mode)
#endif
{
gu2_alpha_mode = mode;
}
#if GFX_2DACCEL_DYNAMIC
void
gu22_set_alpha_value(unsigned char value)
#else
void
gfx2_set_alpha_value(unsigned char value)
#endif
{
gu2_alpha_value = (unsigned long)value;
gu2_alpha_active = 1;
switch (gu2_alpha_mode) {
case ALPHA_MODE_BLEND:
gu2_alpha32 = gu2_alpha_value | gu2_bpp;
switch (gu2_alpha_value) {
case 0:
gu2_alpha32 |= MGP_RM_SELECT_ALPHA_1 |
MGP_RM_ALPHA_TIMES_A |
MGP_RM_ALPHA_TO_RGB | MGP_RM_DEST_FROM_CHAN_A;
break;
case 255:
gu2_alpha32 |= MGP_RM_SELECT_ALPHA_1 |
MGP_RM_ALPHA_TO_RGB | MGP_RM_ALPHA_TIMES_A;
break;
default:
gu2_alpha32 |= MGP_RM_SELECT_ALPHA_R |
MGP_RM_ALPHA_TO_RGB | MGP_RM_ALPHA_A_PLUS_BETA_B;
}
if (gu2_alpha_value != 0)
gu2_alpha32 |= GFXsourceFlags;
if (gu2_alpha_value != 255) {
gu2_alpha_blt_mode = MGP_BM_DST_REQ;
gu2_alpha_vec_mode = MGP_VM_DST_REQ;
}
break;
}
}
#if GFX_2DACCEL_DYNAMIC
void
gu22_pattern_fill(unsigned long dstoffset, unsigned short width,
unsigned short height)
#else
void
gfx2_pattern_fill(unsigned long dstoffset, unsigned short width,
unsigned short height)
#endif
{
unsigned long size;
size = (((unsigned long)width) << 16) | height;
GU2_WAIT_PENDING;
WRITE_GP32(MGP_RASTER_MODE, gu2_rop32);
WRITE_GP32(MGP_DST_OFFSET, dstoffset | gu2_pattern_origin);
WRITE_GP32(MGP_WID_HEIGHT, size);
WRITE_GP32(MGP_STRIDE, gu2_dst_pitch);
WRITE_GP32(MGP_BLT_MODE, gu2_blt_mode | gu2_bm_throttle);
gu2_bm_throttle = 0;
gu2_vm_throttle = 0;
}
#if GFX_2DACCEL_DYNAMIC
void
gu22_color_pattern_fill(unsigned long dstoffset, unsigned short width,
unsigned short height, unsigned long *pattern)
#else
void
gfx2_color_pattern_fill(unsigned long dstoffset, unsigned short width,
unsigned short height, unsigned long *pattern)
#endif
{
int pass;
unsigned long lines, size, patxorigin, patoffset;
patxorigin = (gu2_pattern_origin) & 0x1C000000;
GU2_WAIT_PENDING;
WRITE_GP32(MGP_RASTER_MODE,
(gu2_rop32 & ~MGP_RM_PAT_FLAGS) | MGP_RM_PAT_COLOR);
if ((gu2_dst_pitch << (gu2_xshift + 1)) <= 0xFFFF) {
switch (gu2_xshift) {
case 0:
patoffset = (gu2_pattern_origin >> 28) & 0x0E;
for (pass = 0; pass < 2; pass++) {
GU2_WAIT_PENDING;
WRITE_GP32(MGP_DST_OFFSET, dstoffset | patxorigin);
lines = (height + 1 - pass) >> 1;
if (!lines)
break;
size = (((unsigned long)width) << 16) | lines;
WRITE_GP32(MGP_WID_HEIGHT, size);
WRITE_GP32(MGP_STRIDE, gu2_dst_pitch << 1);
WRITE_GP32(MGP_PAT_DATA_1, BYTE_SWIZZLE(pattern[patoffset]));
WRITE_GP32(MGP_PAT_DATA_0, BYTE_SWIZZLE(pattern[patoffset + 1]));
patoffset = (patoffset + 4) & 0x0E;
WRITE_GP32(MGP_PAT_COLOR_1, BYTE_SWIZZLE(pattern[patoffset]));
WRITE_GP32(MGP_PAT_COLOR_0, BYTE_SWIZZLE(pattern[patoffset + 1]));
patoffset = (patoffset + 4) & 0x0E;
GU2_WAIT_BUSY;
WRITE_GP32(MGP_PAT_COLOR_3, BYTE_SWIZZLE(pattern[patoffset]));
WRITE_GP32(MGP_PAT_COLOR_2, BYTE_SWIZZLE(pattern[patoffset + 1]));
patoffset = (patoffset + 4) & 0x0E;
WRITE_GP32(MGP_PAT_COLOR_5, BYTE_SWIZZLE(pattern[patoffset]));
WRITE_GP32(MGP_PAT_COLOR_4, BYTE_SWIZZLE(pattern[patoffset + 1]));
WRITE_GP16(MGP_BLT_MODE, gu2_blt_mode | gu2_bm_throttle);
gu2_bm_throttle = 0;
gu2_vm_throttle = 0;
dstoffset += gu2_dst_pitch;
patoffset = (patoffset + 6) & 0x0E;
}
break;
case 1:
patoffset = (gu2_pattern_origin >> 27) & 0x1C;
for (pass = 0; pass < 4; pass++) {
GU2_WAIT_PENDING;
WRITE_GP32(MGP_DST_OFFSET, dstoffset | patxorigin);
lines = (height + 3 - pass) >> 2;
if (!lines)
break;
size = (((unsigned long)width) << 16) | lines;
WRITE_GP32(MGP_WID_HEIGHT, size);
WRITE_GP32(MGP_STRIDE, gu2_dst_pitch << 2);
WRITE_GP32(MGP_PAT_COLOR_1, WORD_SWIZZLE(pattern[patoffset]));
WRITE_GP32(MGP_PAT_COLOR_0, WORD_SWIZZLE(pattern[patoffset + 1]));
WRITE_GP32(MGP_PAT_DATA_1, WORD_SWIZZLE(pattern[patoffset + 2]));
WRITE_GP32(MGP_PAT_DATA_0, WORD_SWIZZLE(pattern[patoffset + 3]));
patoffset = (patoffset + 16) & 0x1C;
GU2_WAIT_BUSY;
WRITE_GP32(MGP_PAT_COLOR_5, WORD_SWIZZLE(pattern[patoffset]));
WRITE_GP32(MGP_PAT_COLOR_4, WORD_SWIZZLE(pattern[patoffset + 1]));
WRITE_GP32(MGP_PAT_COLOR_3, WORD_SWIZZLE(pattern[patoffset + 2]));
WRITE_GP32(MGP_PAT_COLOR_2, WORD_SWIZZLE(pattern[patoffset + 3]));
WRITE_GP16(MGP_BLT_MODE, gu2_blt_mode | gu2_bm_throttle);
gu2_bm_throttle = 0;
gu2_vm_throttle = 0;
dstoffset += gu2_dst_pitch;
patoffset = (patoffset + 20) & 0x1C;
}
break;
case 2:
patoffset = (gu2_pattern_origin >> 26) & 0x38;
for (pass = 0; pass < 8; pass++) {
GU2_WAIT_PENDING;
WRITE_GP32(MGP_DST_OFFSET, dstoffset | patxorigin);
lines = (height + 7 - pass) >> 3;
if (!lines)
break;
size = (((unsigned long)width) << 16) | lines;
WRITE_GP32(MGP_WID_HEIGHT, size);
WRITE_GP32(MGP_STRIDE, gu2_dst_pitch << 3);
WRITE_GP32(MGP_PAT_COLOR_1, pattern[patoffset + 4]);
WRITE_GP32(MGP_PAT_COLOR_0, pattern[patoffset + 5]);
WRITE_GP32(MGP_PAT_DATA_1, pattern[patoffset + 6]);
WRITE_GP32(MGP_PAT_DATA_0, pattern[patoffset + 7]);
GU2_WAIT_BUSY;
WRITE_GP32(MGP_PAT_COLOR_5, pattern[patoffset]);
WRITE_GP32(MGP_PAT_COLOR_4, pattern[patoffset + 1]);
WRITE_GP32(MGP_PAT_COLOR_3, pattern[patoffset + 2]);
WRITE_GP32(MGP_PAT_COLOR_2, pattern[patoffset + 3]);
WRITE_GP16(MGP_BLT_MODE, gu2_blt_mode | gu2_bm_throttle);
gu2_bm_throttle = 0;
gu2_vm_throttle = 0;
dstoffset += gu2_dst_pitch;
patoffset = (patoffset + 8) & 0x38;
}
break;
}
}
else {
WRITE_GP32(MGP_STRIDE, gu2_dst_pitch);
switch (gu2_xshift) {
case 0:
patoffset = (gu2_pattern_origin >> 28) & 0x0E;
while (height) {
lines = height > 4 ? 4 : height;
WRITE_GP32(MGP_DST_OFFSET, dstoffset | patxorigin);
WRITE_GP32(MGP_WID_HEIGHT,
(((unsigned long)width) << 16) | lines);
WRITE_GP32(MGP_PAT_DATA_1, BYTE_SWIZZLE(pattern[patoffset]));
WRITE_GP32(MGP_PAT_DATA_0, BYTE_SWIZZLE(pattern[patoffset + 1]));
patoffset = (patoffset + 2) & 0x0E;
WRITE_GP32(MGP_PAT_COLOR_1, BYTE_SWIZZLE(pattern[patoffset]));
WRITE_GP32(MGP_PAT_COLOR_0, BYTE_SWIZZLE(pattern[patoffset + 1]));
patoffset = (patoffset + 2) & 0x0E;
GU2_WAIT_BUSY;
WRITE_GP32(MGP_PAT_COLOR_3, BYTE_SWIZZLE(pattern[patoffset]));
WRITE_GP32(MGP_PAT_COLOR_2, BYTE_SWIZZLE(pattern[patoffset + 1]));
patoffset = (patoffset + 2) & 0x0E;
WRITE_GP32(MGP_PAT_COLOR_5, BYTE_SWIZZLE(pattern[patoffset]));
WRITE_GP32(MGP_PAT_COLOR_4, BYTE_SWIZZLE(pattern[patoffset + 1]));
patoffset = (patoffset + 2) & 0x0E;
WRITE_GP16(MGP_BLT_MODE, gu2_blt_mode | gu2_bm_throttle);
dstoffset += gu2_dst_pitch << 2;
height -= (unsigned short)lines;
}
break;
case 1:
patoffset = (gu2_pattern_origin >> 27) & 0x1C;
while (height) {
lines = height > 2 ? 2 : height;
WRITE_GP32(MGP_DST_OFFSET, dstoffset | patxorigin);
WRITE_GP32(MGP_WID_HEIGHT,
(((unsigned long)width) << 16) | lines);
WRITE_GP32(MGP_PAT_COLOR_1, WORD_SWIZZLE(pattern[patoffset]));
WRITE_GP32(MGP_PAT_COLOR_0, WORD_SWIZZLE(pattern[patoffset + 1]));
WRITE_GP32(MGP_PAT_DATA_1, WORD_SWIZZLE(pattern[patoffset + 2]));
WRITE_GP32(MGP_PAT_DATA_0, WORD_SWIZZLE(pattern[patoffset + 3]));
patoffset = (patoffset + 4) & 0x1C;
GU2_WAIT_BUSY;
WRITE_GP32(MGP_PAT_COLOR_5, WORD_SWIZZLE(pattern[patoffset]));
WRITE_GP32(MGP_PAT_COLOR_4, WORD_SWIZZLE(pattern[patoffset + 1]));
WRITE_GP32(MGP_PAT_COLOR_3, WORD_SWIZZLE(pattern[patoffset + 2]));
WRITE_GP32(MGP_PAT_COLOR_2, WORD_SWIZZLE(pattern[patoffset + 3]));
patoffset = (patoffset + 4) & 0x1C;
WRITE_GP16(MGP_BLT_MODE, gu2_blt_mode | gu2_bm_throttle);
dstoffset += gu2_dst_pitch << 1;
height -= (unsigned short)lines;
}
break;
case 2:
patoffset = (gu2_pattern_origin >> 26) & 0x38;
while (height) {
WRITE_GP32(MGP_DST_OFFSET, dstoffset | patxorigin);
WRITE_GP32(MGP_WID_HEIGHT, (((unsigned long)width) << 16) | 1l);
WRITE_GP32(MGP_PAT_COLOR_1, pattern[patoffset + 4]);
WRITE_GP32(MGP_PAT_COLOR_0, pattern[patoffset + 5]);
WRITE_GP32(MGP_PAT_DATA_1, pattern[patoffset + 6]);
WRITE_GP32(MGP_PAT_DATA_0, pattern[patoffset + 7]);
GU2_WAIT_BUSY;
WRITE_GP32(MGP_PAT_COLOR_5, pattern[patoffset]);
WRITE_GP32(MGP_PAT_COLOR_4, pattern[patoffset + 1]);
WRITE_GP32(MGP_PAT_COLOR_3, pattern[patoffset + 2]);
WRITE_GP32(MGP_PAT_COLOR_2, pattern[patoffset + 3]);
patoffset = (patoffset + 8) & 0x38;
WRITE_GP16(MGP_BLT_MODE, gu2_blt_mode | gu2_bm_throttle);
dstoffset += gu2_dst_pitch;
height--;
}
break;
}
}
}
#if GFX_2DACCEL_DYNAMIC
void
gu22_screen_to_screen_blt(unsigned long srcoffset, unsigned long dstoffset,
unsigned short width, unsigned short height,
int flags)
#else
void
gfx2_screen_to_screen_blt(unsigned long srcoffset, unsigned long dstoffset,
unsigned short width, unsigned short height,
int flags)
#endif
{
unsigned long size, xbytes;
unsigned short blt_mode;
size = (((unsigned long)width) << 16) | height;
if (gu2_alpha_active)
blt_mode = gu2_alpha_blt_mode | MGP_BM_SRC_FB;
else
blt_mode = gu2_blt_mode | MGP_BM_SRC_FB;
if (flags & 1) {
xbytes = (width - 1) << gu2_xshift;
srcoffset += xbytes;
dstoffset += xbytes;
blt_mode |= MGP_BM_NEG_XDIR;
}
if (flags & 2) {
srcoffset += (height - 1) * gu2_src_pitch;
dstoffset += (height - 1) * gu2_dst_pitch;
blt_mode |= MGP_BM_NEG_YDIR;
}
if (blt_mode & MGP_BM_NEG_XDIR) {
srcoffset += (1 << gu2_xshift) - 1;
dstoffset += (1 << gu2_xshift) - 1;
}
GU2_WAIT_PENDING;
if (gu2_alpha_active) {
WRITE_GP32(MGP_RASTER_MODE, gu2_alpha32);
} else {
WRITE_GP32(MGP_RASTER_MODE, gu2_rop32);
}
WRITE_GP32(MGP_SRC_OFFSET, srcoffset);
WRITE_GP32(MGP_DST_OFFSET, dstoffset | gu2_pattern_origin);
WRITE_GP32(MGP_WID_HEIGHT, size);
WRITE_GP32(MGP_STRIDE, gu2_dst_pitch | (gu2_src_pitch << 16));
WRITE_GP16(MGP_BLT_MODE, blt_mode | gu2_bm_throttle);
gu2_bm_throttle = 0;
gu2_vm_throttle = 0;
}
#if GFX_2DACCEL_DYNAMIC
void
gu22_mono_expand_blt(unsigned long srcbase, unsigned short srcx,
unsigned short srcy, unsigned long dstoffset,
unsigned short width, unsigned short height,
int byte_packed)
#else
void
gfx2_mono_expand_blt(unsigned long srcbase, unsigned short srcx,
unsigned short srcy, unsigned long dstoffset,
unsigned short width, unsigned short height,
int byte_packed)
#endif
{
unsigned long size, srcoffset;
unsigned short blt_mode;
size = (((unsigned long)width) << 16) | height;
srcoffset = srcbase + (unsigned long)srcy *gu2_src_pitch;
srcoffset += srcx >> 3;
srcoffset |= ((unsigned long)srcx & 7) << 26;
GU2_WAIT_PENDING;
if (gu2_alpha_active) {
blt_mode = gu2_alpha_blt_mode;
WRITE_GP32(MGP_RASTER_MODE, gu2_alpha32);
} else {
blt_mode = gu2_blt_mode;
WRITE_GP32(MGP_RASTER_MODE, gu2_rop32);
}
if (byte_packed)
blt_mode |= MGP_BM_SRC_FB | MGP_BM_SRC_BP_MONO | gu2_bm_throttle;
else
blt_mode |= MGP_BM_SRC_FB | MGP_BM_SRC_MONO | gu2_bm_throttle;
WRITE_GP32(MGP_SRC_OFFSET, srcoffset);
WRITE_GP32(MGP_DST_OFFSET, dstoffset | gu2_pattern_origin);
WRITE_GP32(MGP_WID_HEIGHT, size);
WRITE_GP32(MGP_STRIDE, gu2_dst_pitch | (gu2_src_pitch << 16));
WRITE_GP16(MGP_BLT_MODE, blt_mode);
gu2_bm_throttle = 0;
gu2_vm_throttle = 0;
}
#if GFX_2DACCEL_DYNAMIC
void
gu22_color_bitmap_to_screen_blt(unsigned short srcx, unsigned short srcy,
unsigned long dstoffset, unsigned short width,
unsigned short height, unsigned char *data,
short pitch)
#else
void
gfx2_color_bitmap_to_screen_blt(unsigned short srcx, unsigned short srcy,
unsigned long dstoffset, unsigned short width,
unsigned short height, unsigned char *data,
short pitch)
#endif
{
unsigned long size, bytes;
unsigned long offset, temp_offset;
unsigned long srcoffset, dword_bytes, bytes_extra;
unsigned short blt_mode;
size = (((unsigned long)width) << 16) | 1;
offset = (unsigned long)srcy *pitch + ((unsigned long)srcx << gu2_xshift);
dstoffset |= gu2_pattern_origin;
bytes = width << gu2_xshift;
dword_bytes = bytes & ~0x3L;
bytes_extra = bytes & 0x3L;
GU2_WAIT_BUSY;
if (gu2_alpha_active) {
blt_mode = gu2_alpha_blt_mode;
WRITE_GP32(MGP_RASTER_MODE, gu2_alpha32);
} else {
blt_mode = gu2_blt_mode;
WRITE_GP32(MGP_RASTER_MODE, gu2_rop32);
}
blt_mode |= MGP_BM_SRC_FB | gu2_bm_throttle;
gu2_bm_throttle = 0;
gu2_vm_throttle = 0;
WRITE_GP32(MGP_WID_HEIGHT, size);
while (height--) {
temp_offset = offset;
srcoffset = gfx_gx2_scratch_base;
if (gu2_current_line)
srcoffset += 8192;
GU2_WAIT_PENDING;
WRITE_GP32(MGP_SRC_OFFSET, srcoffset);
WRITE_GP32(MGP_DST_OFFSET, dstoffset);
dstoffset += gu2_dst_pitch;
dstoffset += 0x20000000;
WRITE_FRAME_BUFFER_STRING32(srcoffset, dword_bytes, data, temp_offset);
if (bytes_extra) {
temp_offset += dword_bytes;
srcoffset += dword_bytes;
WRITE_FRAME_BUFFER_STRING8(srcoffset, bytes_extra, data,
temp_offset);
}
WRITE_GP16(MGP_BLT_MODE, blt_mode);
offset += pitch;
gu2_current_line = 1 - gu2_current_line;
}
}
#if GFX_2DACCEL_DYNAMIC
void
gu22_text_blt(unsigned long dstoffset, unsigned short width,
unsigned short height, unsigned char *data)
#else
void
gfx2_text_blt(unsigned long dstoffset, unsigned short width,
unsigned short height, unsigned char *data)
#endif
{
unsigned long size, bytes;
unsigned long temp1 = 0, temp2 = 0, temp_offset = 0;
unsigned long i, j = 0, fifo_lines, dwords_extra, bytes_extra;
unsigned long shift;
unsigned short blt_mode;
size = (((unsigned long)width) << 16) | height;
bytes = ((width + 7) >> 3) * height;
fifo_lines = bytes >> 5;
dwords_extra = (bytes & 0x0000001Cl) >> 2;
bytes_extra = bytes & 0x00000003l;
GU2_WAIT_PENDING;
if (gu2_alpha_active) {
blt_mode = gu2_alpha_blt_mode;
WRITE_GP32(MGP_RASTER_MODE, gu2_alpha32);
} else {
blt_mode = gu2_blt_mode;
WRITE_GP32(MGP_RASTER_MODE, gu2_rop32);
}
WRITE_GP32(MGP_SRC_OFFSET, 0);
WRITE_GP32(MGP_DST_OFFSET, dstoffset | gu2_pattern_origin);
WRITE_GP32(MGP_WID_HEIGHT, size);
WRITE_GP32(MGP_STRIDE, gu2_dst_pitch);
WRITE_GP16(MGP_BLT_MODE, blt_mode | MGP_BM_SRC_HOST |
MGP_BM_SRC_BP_MONO | gu2_bm_throttle);
gu2_bm_throttle = 0;
gu2_vm_throttle = 0;
GU2_WAIT_PENDING;
for (i = 0; i < fifo_lines; i++) {
GU2_WAIT_HALF_EMPTY;
WRITE_GPREG_STRING32(MGP_HST_SOURCE, 8, j, data, temp_offset, temp1);
temp_offset += 32;
}
if (dwords_extra || bytes_extra) {
GU2_WAIT_HALF_EMPTY;
if (dwords_extra) {
WRITE_GPREG_STRING32(MGP_HST_SOURCE, dwords_extra, i, data,
temp_offset, temp1);
temp_offset += (dwords_extra << 2);
}
if (bytes_extra) {
shift = 0;
WRITE_GPREG_STRING8(MGP_HST_SOURCE, bytes_extra, shift, i, data,
temp_offset, temp1, temp2);
}
}
}
#if GFX_2DACCEL_DYNAMIC
void
gu22_mono_bitmap_to_screen_blt(unsigned short srcx, unsigned short srcy,
unsigned long dstoffset, unsigned short width,
unsigned short height, unsigned char *data,
short pitch)
#else
void
gfx2_mono_bitmap_to_screen_blt(unsigned short srcx, unsigned short srcy,
unsigned long dstoffset, unsigned short width,
unsigned short height, unsigned char *data,
short pitch)
#endif
{
unsigned long size, bytes;
unsigned long offset, temp_offset, temp1 = 0, temp2 = 0;
unsigned long i, j = 0, fifo_lines, dwords_extra, bytes_extra;
unsigned long shift = 0;
unsigned short blt_mode;
size = (((unsigned long)width) << 16) | height;
offset = (unsigned long)srcy *pitch + ((unsigned long)srcx >> 3);
bytes = ((srcx & 7) + width + 7) >> 3;
fifo_lines = bytes >> 5;
dwords_extra = (bytes & 0x0000001Cl) >> 2;
bytes_extra = bytes & 0x00000003l;
GU2_WAIT_PENDING;
if (gu2_alpha_active) {
blt_mode = gu2_alpha_blt_mode;
WRITE_GP32(MGP_RASTER_MODE, gu2_alpha32);
} else {
blt_mode = gu2_blt_mode;
WRITE_GP32(MGP_RASTER_MODE, gu2_rop32);
}
WRITE_GP32(MGP_SRC_OFFSET, ((unsigned long)srcx & 7) << 26);
WRITE_GP32(MGP_DST_OFFSET, dstoffset | gu2_pattern_origin);
WRITE_GP32(MGP_WID_HEIGHT, size);
WRITE_GP32(MGP_STRIDE, gu2_dst_pitch);
WRITE_GP16(MGP_BLT_MODE, blt_mode | MGP_BM_SRC_HOST |
MGP_BM_SRC_MONO | gu2_bm_throttle);
gu2_bm_throttle = 0;
gu2_vm_throttle = 0;
GU2_WAIT_PENDING;
while (height--) {
temp_offset = offset;
for (i = 0; i < fifo_lines; i++) {
GU2_WAIT_HALF_EMPTY;
WRITE_GPREG_STRING32(MGP_HST_SOURCE, 8, j, data, temp_offset, temp1);
temp_offset += 32;
}
GU2_WAIT_HALF_EMPTY;
if (dwords_extra)
WRITE_GPREG_STRING32(MGP_HST_SOURCE, dwords_extra, i, data,
temp_offset, temp1);
temp_offset += (dwords_extra << 2);
shift = 0;
if (bytes_extra)
WRITE_GPREG_STRING8(MGP_HST_SOURCE, bytes_extra, shift, i, data,
temp_offset, temp1, temp2);
offset += pitch;
}
}
#if GFX_2DACCEL_DYNAMIC
void
gu22_bresenham_line(unsigned long dstoffset,
unsigned short length, unsigned short initerr,
unsigned short axialerr, unsigned short diagerr,
unsigned short flags)
#else
void
gfx2_bresenham_line(unsigned long dstoffset,
unsigned short length, unsigned short initerr,
unsigned short axialerr, unsigned short diagerr,
unsigned short flags)
#endif
{
unsigned long vector_mode = gu2_vector_mode | flags;
unsigned long data1 = (((unsigned long)axialerr) << 16) | diagerr;
unsigned long data2 = (((unsigned long)length) << 16) | initerr;
if (!length)
return;
GU2_WAIT_PENDING;
if (gu2_alpha_active) {
vector_mode = gu2_alpha_vec_mode | flags;
WRITE_GP32(MGP_RASTER_MODE, gu2_alpha32);
} else
WRITE_GP32(MGP_RASTER_MODE, gu2_rop32);
WRITE_GP32(MGP_DST_OFFSET, dstoffset | gu2_pattern_origin);
WRITE_GP32(MGP_VEC_ERR, data1);
WRITE_GP32(MGP_VEC_LEN, data2);
WRITE_GP32(MGP_STRIDE, gu2_dst_pitch);
WRITE_GP32(MGP_VECTOR_MODE, vector_mode | gu2_vm_throttle);
gu2_bm_throttle = 0;
gu2_vm_throttle = 0;
}
#if GFX_2DACCEL_DYNAMIC
void
gu22_sync_to_vblank(void)
#else
void
gfx2_sync_to_vblank(void)
#endif
{
gu2_bm_throttle = MGP_BM_THROTTLE;
gu2_vm_throttle = MGP_VM_THROTTLE;
}