Some work on the Voodoo Banshee emulation.

- Host-to-screen and screen-to-screen copy operations implemented (ROP 0xcc).
- Rectangle fill command now handles clipping.
- Attempt to fix the redraw_area() location after bitblt operations.
- Update the host palette entries when writing to CLUT (fixes screenshot).
- Added 2D register names for debug messages.
This commit is contained in:
Volker Ruppert 2017-11-01 21:32:41 +00:00
parent 815b8238c7
commit b1aefb0b6c
2 changed files with 425 additions and 115 deletions

View File

@ -1110,7 +1110,7 @@ void bx_voodoo_c::banshee_write_handler(void *this_ptr, Bit32u address, Bit32u v
UNUSED(this_ptr);
Bit8u offset = (Bit8u)(address & 0xff);
Bit8u reg = (offset>>2), k, m, n;
Bit8u reg = (offset>>2), dac_idx, k, m, n;
Bit32u old = v->banshee.io[reg];
double vfreq;
bx_bool prev_hwce = v->banshee.hwcursor.enabled;
@ -1168,6 +1168,10 @@ void bx_voodoo_c::banshee_write_handler(void *this_ptr, Bit32u address, Bit32u v
if (v->banshee.io[reg] != v->fbi.clut[v->banshee.io[io_dacAddr] & 0x1ff]) {
v->fbi.clut[v->banshee.io[io_dacAddr] & 0x1ff] = v->banshee.io[reg];
v->fbi.clut_dirty = 1;
dac_idx = v->banshee.io[io_dacAddr] & 0xff;
bx_gui->palette_change_common(dac_idx, (v->fbi.clut[dac_idx] >> 16) & 0xff,
(v->fbi.clut[dac_idx] >> 8) & 0xff,
v->fbi.clut[dac_idx] & 0xff);
}
break;
@ -1464,109 +1468,206 @@ Bit32u bx_voodoo_c::banshee_blt_reg_read(Bit8u reg)
default:
result = v->banshee.blt.reg[reg];
}
BX_DEBUG(("2D read register 0x%03x result = 0x%08x", reg<<2, result));
if (reg < 0x20) {
BX_DEBUG(("2D read register 0x%03x (%s) result = 0x%08x", reg<<2,
banshee_blt_reg_name[reg], result));
}
return result;
}
void bx_voodoo_c::banshee_blt_reg_write(Bit8u reg, Bit32u value)
{
BX_DEBUG(("2D write register 0x%03x value = 0x%08x", reg<<2, value));
Bit32u pbytes;
Bit8u sfmt;
if (reg < 0x20) {
BX_DEBUG(("2D write register 0x%03x (%s) value = 0x%08x", reg<<2,
banshee_blt_reg_name[reg], value));
}
v->banshee.blt.reg[reg] = value;
if (reg == blt_intrCtrl) {
BX_ERROR(("intrCtrl register not supported yet"));
} else if (reg == blt_command) {
v->banshee.blt.cmd = (value & 0x0f);
v->banshee.blt.immed = (value >> 8) & 1;
v->banshee.blt.x_dir = (value >> 14) & 1;
v->banshee.blt.y_dir = (value >> 15) & 1;
v->banshee.blt.rop0 = (value >> 24);
v->banshee.blt.src_x = v->banshee.blt.reg[blt_srcXY] & 0x1fff;
v->banshee.blt.src_y= (v->banshee.blt.reg[blt_srcXY] >> 16) & 0x1fff;
v->banshee.blt.dst_x = v->banshee.blt.reg[blt_dstXY] & 0x1fff;
v->banshee.blt.dst_y= (v->banshee.blt.reg[blt_dstXY] >> 16) & 0x1fff;
v->banshee.blt.dst_w = v->banshee.blt.reg[blt_dstSize] & 0x1fff;
v->banshee.blt.dst_h = (v->banshee.blt.reg[blt_dstSize] >> 16) & 0x1fff;
v->banshee.blt.busy = 1;
switch (v->banshee.blt.cmd) {
case 0: // NOP
break;
case 1:
v->banshee.blt.busy = 1;
banshee_blt_screen_to_screen();
break;
case 2:
BX_INFO(("TODO: 2D Screen to screen stretch blt"));
break;
case 3:
v->banshee.blt.busy = 1;
banshee_blt_host_to_screen();
break;
case 4:
BX_INFO(("TODO: 2D Host to screen stretch blt"));
break;
case 5:
v->banshee.blt.busy = 1;
banshee_blt_rectangle_fill();
break;
case 6:
BX_INFO(("TODO: 2D Line"));
break;
case 7:
BX_INFO(("TODO: 2D Polyline"));
break;
case 8:
BX_INFO(("TODO: 2D Polygon fill"));
break;
case 13:
BX_INFO(("TODO: 2D Write Sgram Mode register"));
return;
case 14:
BX_INFO(("TODO: 2D Write Sgram Mask register"));
return;
case 15:
BX_INFO(("TODO: 2D Write Sgram Color register"));
return;
default:
BX_ERROR(("Unsupported 2D mode"));
}
if (v->banshee.blt.immed) {
banshee_blt_complete();
}
} else if ((reg >= 0x20) && (reg < 0x40)) {
banshee_blt_launch_area_write(value);
} else if ((reg >= 0x40) && (reg < 0x80)) {
BX_DEBUG(("colorPattern write"));
switch (reg) {
case blt_intrCtrl:
BX_ERROR(("intrCtrl register not supported yet"));
break;
case blt_clip0Min:
v->banshee.blt.clipx0[0] = v->banshee.blt.reg[reg] & 0xfff;
v->banshee.blt.clipy0[0] = (v->banshee.blt.reg[reg] >> 16) & 0x1fff;
break;
case blt_clip0Max:
v->banshee.blt.clipx1[0] = v->banshee.blt.reg[reg] & 0xfff;
v->banshee.blt.clipy1[0] = (v->banshee.blt.reg[reg] >> 16) & 0x1fff;
break;
case blt_pattern0Alias:
v->banshee.blt.reg[0x40] = value;
break;
case blt_pattern1Alias:
v->banshee.blt.reg[0x41] = value;
break;
case blt_clip1Min:
v->banshee.blt.clipx0[1] = v->banshee.blt.reg[reg] & 0xfff;
v->banshee.blt.clipy0[1] = (v->banshee.blt.reg[reg] >> 16) & 0x1fff;
break;
case blt_clip1Max:
v->banshee.blt.clipx1[1] = v->banshee.blt.reg[reg] & 0xfff;
v->banshee.blt.clipy1[1] = (v->banshee.blt.reg[reg] >> 16) & 0x1fff;
break;
case blt_srcSize:
v->banshee.blt.src_w = v->banshee.blt.reg[reg] & 0x1fff;
v->banshee.blt.src_h = (v->banshee.blt.reg[reg] >> 16) & 0x1fff;
break;
case blt_srcXY:
v->banshee.blt.src_x = v->banshee.blt.reg[reg] & 0x1fff;
v->banshee.blt.src_y = (v->banshee.blt.reg[reg] >> 16) & 0x1fff;
break;
case blt_dstSize:
v->banshee.blt.dst_w = v->banshee.blt.reg[reg] & 0x1fff;
v->banshee.blt.dst_h = (v->banshee.blt.reg[reg] >> 16) & 0x1fff;
break;
case blt_dstXY:
v->banshee.blt.dst_x = v->banshee.blt.reg[reg] & 0x1fff;
v->banshee.blt.dst_y = (v->banshee.blt.reg[reg] >> 16) & 0x1fff;
break;
case blt_command:
v->banshee.blt.cmd = (value & 0x0f);
v->banshee.blt.immed = (value >> 8) & 1;
v->banshee.blt.x_dir = (value >> 14) & 1;
v->banshee.blt.y_dir = (value >> 15) & 1;
v->banshee.blt.transp = (value >> 16) & 1;
v->banshee.blt.clip_sel = (value >> 23) & 1;
v->banshee.blt.rop0 = (value >> 24);
v->banshee.blt.dwcount = 0;
switch (v->banshee.blt.cmd) {
case 0: // NOP
break;
case 1:
v->banshee.blt.busy = 1;
banshee_blt_screen_to_screen();
break;
case 2:
BX_INFO(("TODO: 2D Screen to screen stretch blt"));
break;
case 3:
v->banshee.blt.busy = 1;
if (!v->banshee.blt.immed) {
sfmt = (v->banshee.blt.reg[blt_srcFormat] >> 16) & 0x0f;
if (sfmt == 0) {
pbytes = ((v->banshee.blt.dst_w + 7) >> 3) * v->banshee.blt.dst_h;
} else if (sfmt == 1) {
pbytes = v->banshee.blt.dst_w * v->banshee.blt.dst_h;
} else if ((sfmt >= 3) && (sfmt <= 3)) {
pbytes = v->banshee.blt.dst_w * v->banshee.blt.dst_h * (sfmt - 1);
} else {
pbytes = 0;
BX_INFO(("Source format %d not handled yet", sfmt));
}
v->banshee.blt.dwcount = (pbytes + 3) >> 2;
v->banshee.blt.lpidx = 0;
} else {
BX_ERROR(("Host to screen blt: immediate execution not supported"));
}
break;
case 4:
BX_INFO(("TODO: 2D Host to screen stretch blt"));
break;
case 5:
v->banshee.blt.busy = 1;
banshee_blt_rectangle_fill();
break;
case 6:
BX_INFO(("TODO: 2D Line"));
break;
case 7:
BX_INFO(("TODO: 2D Polyline"));
break;
case 8:
BX_INFO(("TODO: 2D Polygon fill"));
break;
case 13:
BX_INFO(("TODO: 2D Write Sgram Mode register"));
return;
case 14:
BX_INFO(("TODO: 2D Write Sgram Mask register"));
return;
case 15:
BX_INFO(("TODO: 2D Write Sgram Color register"));
return;
default:
BX_ERROR(("Unsupported 2D mode"));
}
if (v->banshee.blt.immed) {
banshee_blt_complete();
}
break;
default:
if ((reg >= 0x20) && (reg < 0x40)) {
banshee_blt_launch_area_write(value);
} else if ((reg >= 0x40) && (reg < 0x80)) {
BX_DEBUG(("colorPattern write"));
}
}
}
void bx_voodoo_c::banshee_blt_launch_area_write(Bit32u value)
{
BX_INFO(("launchArea write not handled yet"));
if (v->banshee.blt.dwcount > 0) {
BX_DEBUG(("launchArea write: value = 0x%08x", value));
if (v->banshee.blt.lpidx > 4095) {
BX_ERROR(("launchArea write: out of memory"));
return;
}
v->banshee.blt.lpmem[v->banshee.blt.lpidx++] = (value & 0xff);
v->banshee.blt.lpmem[v->banshee.blt.lpidx++] = ((value >> 8) & 0xff);
v->banshee.blt.lpmem[v->banshee.blt.lpidx++] = ((value >> 16) & 0xff);
v->banshee.blt.lpmem[v->banshee.blt.lpidx++] = ((value >> 24) & 0xff);
if (--v->banshee.blt.dwcount == 0) {
switch (v->banshee.blt.cmd) {
case 3:
banshee_blt_host_to_screen();
break;
default:
BX_ERROR(("launchArea write: command %d not handled yet",
v->banshee.blt.cmd));
}
banshee_blt_complete();
}
}
}
void bx_voodoo_c::banshee_blt_complete()
{
Bit32u start0 = v->banshee.io[io_vidDesktopStartAddr] & v->fbi.mask;
Bit32u start1 = v->banshee.blt.reg[blt_dstBaseAddr] & v->fbi.mask;
Bit16u pitch0 = v->banshee.io[io_vidDesktopOverlayStride] & 0x7fff;
Bit32u pitch1 = v->banshee.blt.reg[blt_dstFormat] & 0x3fff;
Bit32u cmd = v->banshee.blt.reg[blt_command];
bx_bool xinc = (cmd >> 10) & 1;
bx_bool yinc = (cmd >> 11) & 1;
Bit32u offset0, offset1;
Bit16u x, y;
theVoodooVga->redraw_area(v->banshee.blt.dst_x, v->banshee.blt.dst_y,
v->banshee.blt.dst_w, v->banshee.blt.dst_h);
if (xinc) {
if (v->banshee.blt.x_dir) {
v->banshee.blt.dst_x -= v->banshee.blt.dst_w;
} else {
v->banshee.blt.dst_x += v->banshee.blt.dst_w;
if (start1 <= start0) {
offset0 = start1 + v->banshee.blt.dst_y * pitch1 + v->banshee.blt.dst_x * (v->banshee.bpp >> 3);
offset1 = offset0 + v->banshee.blt.dst_h * pitch1 + v->banshee.blt.dst_w * (v->banshee.bpp >> 3);
if (offset1 >= start0) {
if (offset0 >= start0) {
offset0 -= start0;
} else {
offset0 = 0;
}
x = (offset0 % pitch0) / (v->banshee.bpp >> 3);
y = offset0 / pitch0;
theVoodooVga->redraw_area(x, y, v->banshee.blt.dst_w, v->banshee.blt.dst_h);
}
} else {
BX_ERROR(("redraw: Blt start > Desktop start not handled yet"));
}
if (xinc) {
v->banshee.blt.dst_x += v->banshee.blt.dst_w;
v->banshee.blt.reg[blt_dstXY] &= ~0xffff;
v->banshee.blt.reg[blt_dstXY] |= v->banshee.blt.dst_x;
}
if (yinc) {
if (v->banshee.blt.y_dir) {
v->banshee.blt.dst_y -= v->banshee.blt.dst_h;
} else {
v->banshee.blt.dst_y += v->banshee.blt.dst_h;
}
v->banshee.blt.dst_y += v->banshee.blt.dst_h;
v->banshee.blt.reg[blt_dstXY] &= 0xffff;
v->banshee.blt.reg[blt_dstXY] |= (v->banshee.blt.dst_y << 16);
}
@ -1574,58 +1675,233 @@ void bx_voodoo_c::banshee_blt_complete()
void bx_voodoo_c::banshee_blt_rectangle_fill()
{
Bit32u start = v->banshee.io[io_vidDesktopStartAddr] & v->fbi.mask;
Bit32u start = v->banshee.blt.reg[blt_dstBaseAddr] & v->fbi.mask;
Bit8u *disp_ptr = &v->fbi.ram[start];
Bit8u *vid_ptr, *vid_ptr2;
Bit32u pitch = v->banshee.io[io_vidDesktopOverlayStride] & 0x7fff;
Bit32u pitch = v->banshee.blt.reg[blt_dstFormat] & 0x3fff;
Bit32u color;
Bit16u x, y, x0, y0, w, h;
Bit16u x, y, x0, y0, w, h, cx0, cx1, cy0, cy1;
Bit8u rop0, pxbytes = v->banshee.bpp >> 3;
BX_DEBUG(("Rectangle fill"));
x0 = v->banshee.blt.dst_x;
y0 = v->banshee.blt.dst_y;
w = v->banshee.blt.dst_w;
h = v->banshee.blt.dst_h;
color = v->banshee.blt.reg[blt_colorFore];
vid_ptr = disp_ptr + y0 * pitch + x0 * (v->banshee.bpp >> 3);
for (y = y0; y < (y0 + h); y++) {
vid_ptr2 = vid_ptr;
for (x = x0; x < (x0 + w); x++) {
switch (v->banshee.bpp) {
case 8:
*(vid_ptr2++) = (color & 0xff);
break;
case 16:
*(vid_ptr2++) = (color & 0xff);
*(vid_ptr2++) = ((color >> 8) & 0xff);
break;
case 24:
*(vid_ptr2++) = (color & 0xff);
*(vid_ptr2++) = ((color >> 8) & 0xff);
*(vid_ptr2++) = ((color >> 16) & 0xff);
break;
case 32:
*(vid_ptr2++) = (color & 0xff);
*(vid_ptr2++) = ((color >> 8) & 0xff);
*(vid_ptr2++) = ((color >> 16) & 0xff);
*(vid_ptr2++) = ((color >> 24) & 0xff);
break;
rop0 = v->banshee.blt.rop0;
if (rop0 == 0xcc) {
BX_DEBUG(("Rectangle fill (copy %d x %d)", w, h));
cx0 = v->banshee.blt.clipx0[v->banshee.blt.clip_sel];
cy0 = v->banshee.blt.clipy0[v->banshee.blt.clip_sel];
cx1 = v->banshee.blt.clipx1[v->banshee.blt.clip_sel];
cy1 = v->banshee.blt.clipy1[v->banshee.blt.clip_sel];
color = v->banshee.blt.reg[blt_colorFore];
vid_ptr = disp_ptr + y0 * pitch + x0 * pxbytes;
for (y = y0; y < (y0 + h); y++) {
vid_ptr2 = vid_ptr;
for (x = x0; x < (x0 + w); x++) {
if ((x >= cx0) && (x < cx1) && (y >= cy0) && (y < cy1)) {
switch (v->banshee.bpp) {
case 8:
*(vid_ptr2++) = (color & 0xff);
break;
case 16:
*(vid_ptr2++) = (color & 0xff);
*(vid_ptr2++) = ((color >> 8) & 0xff);
break;
case 24:
*(vid_ptr2++) = (color & 0xff);
*(vid_ptr2++) = ((color >> 8) & 0xff);
*(vid_ptr2++) = ((color >> 16) & 0xff);
break;
case 32:
*(vid_ptr2++) = (color & 0xff);
*(vid_ptr2++) = ((color >> 8) & 0xff);
*(vid_ptr2++) = ((color >> 16) & 0xff);
*(vid_ptr2++) = ((color >> 24) & 0xff);
break;
}
} else {
vid_ptr2 += pxbytes;
}
}
vid_ptr += pitch;
}
vid_ptr += pitch;
} else {
BX_INFO(("Rectangle fill: ROP 0x%02x not supported yet", rop0));
}
v->banshee.blt.busy = 0;
}
void bx_voodoo_c::banshee_blt_screen_to_screen()
{
BX_INFO(("TODO: 2D Screen to screen blt (command=0x%08x)", v->banshee.blt.reg[blt_command]));
Bit32u sstart = v->banshee.io[blt_srcBaseAddr] & v->fbi.mask;
Bit32u dstart = v->banshee.io[blt_dstBaseAddr] & v->fbi.mask;
Bit32u pitch = v->banshee.io[blt_dstFormat] & 0x3fff;
Bit8u *src_ptr = &v->fbi.ram[sstart];
Bit8u *dst_ptr = &v->fbi.ram[dstart];
Bit8u *src_ptr1, *src_ptr2, *dst_ptr1, *dst_ptr2;
Bit16u x, y, x0, y0, w, h, cx0, cx1, cy0, cy1;
Bit8u rop0, pxbytes = (v->banshee.bpp >> 3);
x0 = v->banshee.blt.dst_x;
y0 = v->banshee.blt.dst_y;
w = v->banshee.blt.dst_w;
h = v->banshee.blt.dst_h;
rop0 = v->banshee.blt.rop0;
if (rop0 == 0xcc) {
BX_DEBUG(("Screen to screen blt (copy %d x %d)", w, h));
cx0 = v->banshee.blt.clipx0[v->banshee.blt.clip_sel];
cy0 = v->banshee.blt.clipy0[v->banshee.blt.clip_sel];
cx1 = v->banshee.blt.clipx1[v->banshee.blt.clip_sel];
cy1 = v->banshee.blt.clipy1[v->banshee.blt.clip_sel];
src_ptr1 = src_ptr + (y0 * pitch + x0);
dst_ptr1 = dst_ptr + (y0 * pitch + x0);
if (v->banshee.blt.y_dir) {
if (v->banshee.blt.x_dir) {
for (y = y0; y > (y0 - h); y--) {
src_ptr2 = src_ptr1;
dst_ptr2 = dst_ptr1;
for (x = x0; x > (x0 - w); x--) {
if ((x >= cx0) && (x < cx1) && (y >= cy0) && (y < cy1)) {
memcpy(dst_ptr2, src_ptr2, pxbytes);
}
src_ptr2 -= pxbytes;
dst_ptr2 -= pxbytes;
}
src_ptr1 -= pitch;
dst_ptr1 -= pitch;
}
} else {
for (y = y0; y > (y0 - h); y--) {
src_ptr2 = src_ptr1;
dst_ptr2 = dst_ptr1;
for (x = x0; x < (x0 + w); x++) {
if ((x >= cx0) && (x < cx1) && (y >= cy0) && (y < cy1)) {
memcpy(dst_ptr2, src_ptr2, pxbytes);
}
src_ptr2 += pxbytes;
dst_ptr2 += pxbytes;
}
src_ptr1 -= pitch;
dst_ptr1 -= pitch;
}
}
} else {
if (v->banshee.blt.x_dir) {
for (y = y0; y < (y0 + h); y++) {
src_ptr2 = src_ptr1;
dst_ptr2 = dst_ptr1;
for (x = x0; x > (x0 - w); x--) {
if ((x >= cx0) && (x < cx1) && (y >= cy0) && (y < cy1)) {
memcpy(dst_ptr2, src_ptr2, pxbytes);
}
src_ptr2 -= pxbytes;
dst_ptr2 -= pxbytes;
}
src_ptr1 += pitch;
dst_ptr1 += pitch;
}
} else {
for (y = y0; y < (y0 + h); y++) {
src_ptr2 = src_ptr1;
dst_ptr2 = dst_ptr1;
for (x = x0; x < (x0 + w); x++) {
if ((x >= cx0) && (x < cx1) && (y >= cy0) && (y < cy1)) {
memcpy(dst_ptr2, src_ptr2, pxbytes);
}
src_ptr2 += pxbytes;
dst_ptr2 += pxbytes;
}
src_ptr1 += pitch;
dst_ptr1 += pitch;
}
}
}
} else {
BX_INFO(("Screen to screen blt: ROP 0x%02x not supported yet", rop0));
}
v->banshee.blt.busy = 0;
}
void bx_voodoo_c::banshee_blt_host_to_screen()
{
BX_INFO(("TODO: 2D Host to screen blt (command=0x%08x)", v->banshee.blt.reg[blt_command]));
Bit32u start = v->banshee.blt.reg[blt_dstBaseAddr] & v->fbi.mask;
Bit8u *disp_ptr = &v->fbi.ram[start];
Bit8u *src_ptr = &v->banshee.blt.lpmem[0];
Bit8u *vid_ptr, *vid_ptr2;
Bit32u pitch = v->banshee.blt.reg[blt_dstFormat] & 0x3fff;
Bit8u pxbytes = v->banshee.bpp >> 3;
Bit32u color, fgcolor, bgcolor, scolor;
Bit16u i, x, y, x0, y0, w, h, cx0, cx1, cy0, cy1;
Bit8u mask, rop0;
x0 = v->banshee.blt.dst_x;
y0 = v->banshee.blt.dst_y;
w = v->banshee.blt.dst_w;
h = v->banshee.blt.dst_h;
rop0 = v->banshee.blt.rop0;
if (rop0 == 0xcc) {
BX_DEBUG(("Host to screen blt (copy %d x %d)", w, h));
cx0 = v->banshee.blt.clipx0[v->banshee.blt.clip_sel];
cy0 = v->banshee.blt.clipy0[v->banshee.blt.clip_sel];
cx1 = v->banshee.blt.clipx1[v->banshee.blt.clip_sel];
cy1 = v->banshee.blt.clipy1[v->banshee.blt.clip_sel];
fgcolor = v->banshee.blt.reg[blt_colorFore];
bgcolor = v->banshee.blt.reg[blt_colorBack];
vid_ptr = disp_ptr + y0 * pitch + x0 * pxbytes;
for (y = y0; y < (y0 + h); y++) {
vid_ptr2 = vid_ptr;
mask = 0x80;
for (x = x0; x < (x0 + w); x++) {
if ((x >= cx0) && (x < cx1) && (y >= cy0) && (y < cy1)) {
scolor = 0;
for (i = 0; i < pxbytes; i++) {
scolor |= (vid_ptr2[i] << (i * 8));
}
if (*src_ptr & mask) {
color = fgcolor;
} else if (!v->banshee.blt.transp) {
color = bgcolor;
} else {
color = scolor;
}
switch (v->banshee.bpp) {
case 8:
*(vid_ptr2++) = (color & 0xff);
break;
case 16:
*(vid_ptr2++) = (color & 0xff);
*(vid_ptr2++) = ((color >> 8) & 0xff);
break;
case 24:
*(vid_ptr2++) = (color & 0xff);
*(vid_ptr2++) = ((color >> 8) & 0xff);
*(vid_ptr2++) = ((color >> 16) & 0xff);
break;
case 32:
*(vid_ptr2++) = (color & 0xff);
*(vid_ptr2++) = ((color >> 8) & 0xff);
*(vid_ptr2++) = ((color >> 16) & 0xff);
*(vid_ptr2++) = ((color >> 24) & 0xff);
break;
}
} else {
vid_ptr2 += pxbytes;
}
mask >>= 1;
if (mask == 0) {
src_ptr++;
mask = 0x80;
}
}
if (mask != 0x80) {
src_ptr++;
}
vid_ptr += pitch;
}
} else {
BX_INFO(("Host to screen blt: ROP 0x%02x not supported yet", rop0));
}
v->banshee.blt.busy = 0;
}

View File

@ -1039,6 +1039,29 @@ static const char *const banshee_agp_reg_name[] =
/*************************************
*
* Register string table for debug
*
*************************************/
static const char *const banshee_blt_reg_name[] =
{
/* 0x000 */
"status", "intrCtrl", "clip0Min", "clip0Max",
"dstBaseAddr", "dstFormat", "srcColorkeyMin", "srcColorkeyMax",
"dstColorkeyMin", "dstColorkeyMax", "bresError0", "bresError1",
"rop", "srcBaseAddr", "commandExtra", "lineStipple",
/* 0x040 */
"lineStyle", "pattern0Alias", "pattern1Alias", "clip1Min",
"clip1Max", "srcFormat", "srcSize", "srcXY",
"colorBack", "colorFore", "dstSize", "dstXY",
"command", "RESERVED", "RESERVED", "RESERVED"
};
/*************************************
*
* Dithering tables
@ -1709,18 +1732,29 @@ struct _banshee_info
} hwcursor;
struct {
Bit32u reg[0x80]; /* 2D registers */
bx_bool busy;
Bit8u cmd;
bx_bool immed;
bx_bool busy;
bx_bool x_dir;
bx_bool y_dir;
bx_bool transp;
bx_bool clip_sel;
Bit8u rop0;
Bit16u src_x;
Bit16u src_y;
Bit16u src_w;
Bit16u src_h;
Bit16u dst_x;
Bit16u dst_y;
Bit16u dst_w;
Bit16u dst_h;
bx_bool x_dir;
bx_bool y_dir;
Bit8u rop0;
Bit16u clipx0[2];
Bit16u clipy0[2];
Bit16u clipx1[2];
Bit16u clipy1[2];
Bit32u dwcount;
Bit8u lpmem[4096];
Bit32u lpidx;
} blt;
};