Some work on the Voodoo Banshee emulation.

- Moved basic BitBlt stuff from the Cirrus code to a separate header file to
  make it usable for the Voodoo Banshee, too.
- Rewrite of the screen-to-screen BitBlt code for the new ROP code.
- Calculate redraw parameters based on the screen start.
- Set "Banshee busy" bit in the status register when 2D is busy.
- Added some error messages for unimplemented features.
This commit is contained in:
Volker Ruppert 2017-11-04 23:43:38 +00:00
parent b1aefb0b6c
commit ca9120655b
6 changed files with 238 additions and 163 deletions

View File

@ -0,0 +1,103 @@
/////////////////////////////////////////////////////////////////////////
// $Id$
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2017 The Bochs Project
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#ifndef BX_BITBLT_H
#define BX_BITBLT_H
typedef void (*bx_bitblt_rop_t)(
Bit8u *dst,const Bit8u *src,
int dstpitch,int srcpitch,
int bltwidth,int bltheight);
#define IMPLEMENT_FORWARD_BITBLT(name,opline) \
static void bitblt_rop_fwd_##name( \
Bit8u *dst,const Bit8u *src, \
int dstpitch,int srcpitch, \
int bltwidth,int bltheight) \
{ \
int x,y; \
dstpitch -= bltwidth; \
srcpitch -= bltwidth; \
for (y = 0; y < bltheight; y++) { \
for (x = 0; x < bltwidth; x++) { \
opline; \
dst++; \
src++; \
} \
dst += dstpitch; \
src += srcpitch; \
} \
}
#define IMPLEMENT_BACKWARD_BITBLT(name,opline) \
static void bitblt_rop_bkwd_##name( \
Bit8u *dst,const Bit8u *src, \
int dstpitch,int srcpitch, \
int bltwidth,int bltheight) \
{ \
int x,y; \
dstpitch += bltwidth; \
srcpitch += bltwidth; \
for (y = 0; y < bltheight; y++) { \
for (x = 0; x < bltwidth; x++) { \
opline; \
dst--; \
src--; \
} \
dst += dstpitch; \
src += srcpitch; \
} \
}
IMPLEMENT_FORWARD_BITBLT(0, *dst = 0)
IMPLEMENT_FORWARD_BITBLT(src_and_dst, *dst = (*src) & (*dst))
IMPLEMENT_FORWARD_BITBLT(nop, (void)0)
IMPLEMENT_FORWARD_BITBLT(src_and_notdst, *dst = (*src) & (~(*dst)))
IMPLEMENT_FORWARD_BITBLT(notdst, *dst = ~(*dst))
IMPLEMENT_FORWARD_BITBLT(src, *dst = *src)
IMPLEMENT_FORWARD_BITBLT(1, *dst = 0xff)
IMPLEMENT_FORWARD_BITBLT(notsrc_and_dst, *dst = (~(*src)) & (*dst))
IMPLEMENT_FORWARD_BITBLT(src_xor_dst, *dst = (*src) ^ (*dst))
IMPLEMENT_FORWARD_BITBLT(src_or_dst, *dst = (*src) | (*dst))
IMPLEMENT_FORWARD_BITBLT(notsrc_or_notdst, *dst = (~(*src)) | (~(*dst)))
IMPLEMENT_FORWARD_BITBLT(src_notxor_dst, *dst = ~((*src) ^ (*dst)))
IMPLEMENT_FORWARD_BITBLT(src_or_notdst, *dst = (*src) | (~(*dst)))
IMPLEMENT_FORWARD_BITBLT(notsrc, *dst = (~(*src)))
IMPLEMENT_FORWARD_BITBLT(notsrc_or_dst, *dst = (~(*src)) | (*dst))
IMPLEMENT_FORWARD_BITBLT(notsrc_and_notdst, *dst = (~(*src)) & (~(*dst)))
IMPLEMENT_BACKWARD_BITBLT(0, *dst = 0)
IMPLEMENT_BACKWARD_BITBLT(src_and_dst, *dst = (*src) & (*dst))
IMPLEMENT_BACKWARD_BITBLT(nop, (void)0)
IMPLEMENT_BACKWARD_BITBLT(src_and_notdst, *dst = (*src) & (~(*dst)))
IMPLEMENT_BACKWARD_BITBLT(notdst, *dst = ~(*dst))
IMPLEMENT_BACKWARD_BITBLT(src, *dst = *src)
IMPLEMENT_BACKWARD_BITBLT(1, *dst = 0xff)
IMPLEMENT_BACKWARD_BITBLT(notsrc_and_dst, *dst = (~(*src)) & (*dst))
IMPLEMENT_BACKWARD_BITBLT(src_xor_dst, *dst = (*src) ^ (*dst))
IMPLEMENT_BACKWARD_BITBLT(src_or_dst, *dst = (*src) | (*dst))
IMPLEMENT_BACKWARD_BITBLT(notsrc_or_notdst, *dst = (~(*src)) | (~(*dst)))
IMPLEMENT_BACKWARD_BITBLT(src_notxor_dst, *dst = ~((*src) ^ (*dst)))
IMPLEMENT_BACKWARD_BITBLT(src_or_notdst, *dst = (*src) | (~(*dst)))
IMPLEMENT_BACKWARD_BITBLT(notsrc, *dst = (~(*src)))
IMPLEMENT_BACKWARD_BITBLT(notsrc_or_dst, *dst = (~(*src)) | (*dst))
IMPLEMENT_BACKWARD_BITBLT(notsrc_and_notdst, *dst = (~(*src)) & (~(*dst)))
#endif

View File

@ -39,6 +39,7 @@
#include "iodev.h"
#include "vgacore.h"
#include "bitblt.h"
#include "svga_cirrus.h"
#include "virt_timer.h"
@ -3152,83 +3153,9 @@ cleanup:
//
/////////////////////////////////////////////////////////////////////////
#define IMPLEMENT_FORWARD_BITBLT(name,opline) \
static void bitblt_rop_fwd_##name( \
Bit8u *dst,const Bit8u *src, \
int dstpitch,int srcpitch, \
int bltwidth,int bltheight) \
{ \
int x,y; \
dstpitch -= bltwidth; \
srcpitch -= bltwidth; \
for (y = 0; y < bltheight; y++) { \
for (x = 0; x < bltwidth; x++) { \
opline; \
dst++; \
src++; \
} \
dst += dstpitch; \
src += srcpitch; \
} \
}
#define IMPLEMENT_BACKWARD_BITBLT(name,opline) \
static void bitblt_rop_bkwd_##name( \
Bit8u *dst,const Bit8u *src, \
int dstpitch,int srcpitch, \
int bltwidth,int bltheight) \
{ \
int x,y; \
dstpitch += bltwidth; \
srcpitch += bltwidth; \
for (y = 0; y < bltheight; y++) { \
for (x = 0; x < bltwidth; x++) { \
opline; \
dst--; \
src--; \
} \
dst += dstpitch; \
src += srcpitch; \
} \
}
IMPLEMENT_FORWARD_BITBLT(0, *dst = 0)
IMPLEMENT_FORWARD_BITBLT(src_and_dst, *dst = (*src) & (*dst))
IMPLEMENT_FORWARD_BITBLT(nop, (void)0)
IMPLEMENT_FORWARD_BITBLT(src_and_notdst, *dst = (*src) & (~(*dst)))
IMPLEMENT_FORWARD_BITBLT(notdst, *dst = ~(*dst))
IMPLEMENT_FORWARD_BITBLT(src, *dst = *src)
IMPLEMENT_FORWARD_BITBLT(1, *dst = 0xff)
IMPLEMENT_FORWARD_BITBLT(notsrc_and_dst, *dst = (~(*src)) & (*dst))
IMPLEMENT_FORWARD_BITBLT(src_xor_dst, *dst = (*src) ^ (*dst))
IMPLEMENT_FORWARD_BITBLT(src_or_dst, *dst = (*src) | (*dst))
IMPLEMENT_FORWARD_BITBLT(notsrc_or_notdst, *dst = (~(*src)) | (~(*dst)))
IMPLEMENT_FORWARD_BITBLT(src_notxor_dst, *dst = ~((*src) ^ (*dst)))
IMPLEMENT_FORWARD_BITBLT(src_or_notdst, *dst = (*src) | (~(*dst)))
IMPLEMENT_FORWARD_BITBLT(notsrc, *dst = (~(*src)))
IMPLEMENT_FORWARD_BITBLT(notsrc_or_dst, *dst = (~(*src)) | (*dst))
IMPLEMENT_FORWARD_BITBLT(notsrc_and_notdst, *dst = (~(*src)) & (~(*dst)))
IMPLEMENT_BACKWARD_BITBLT(0, *dst = 0)
IMPLEMENT_BACKWARD_BITBLT(src_and_dst, *dst = (*src) & (*dst))
IMPLEMENT_BACKWARD_BITBLT(nop, (void)0)
IMPLEMENT_BACKWARD_BITBLT(src_and_notdst, *dst = (*src) & (~(*dst)))
IMPLEMENT_BACKWARD_BITBLT(notdst, *dst = ~(*dst))
IMPLEMENT_BACKWARD_BITBLT(src, *dst = *src)
IMPLEMENT_BACKWARD_BITBLT(1, *dst = 0xff)
IMPLEMENT_BACKWARD_BITBLT(notsrc_and_dst, *dst = (~(*src)) & (*dst))
IMPLEMENT_BACKWARD_BITBLT(src_xor_dst, *dst = (*src) ^ (*dst))
IMPLEMENT_BACKWARD_BITBLT(src_or_dst, *dst = (*src) | (*dst))
IMPLEMENT_BACKWARD_BITBLT(notsrc_or_notdst, *dst = (~(*src)) | (~(*dst)))
IMPLEMENT_BACKWARD_BITBLT(src_notxor_dst, *dst = ~((*src) ^ (*dst)))
IMPLEMENT_BACKWARD_BITBLT(src_or_notdst, *dst = (*src) | (~(*dst)))
IMPLEMENT_BACKWARD_BITBLT(notsrc, *dst = (~(*src)))
IMPLEMENT_BACKWARD_BITBLT(notsrc_or_dst, *dst = (~(*src)) | (*dst))
IMPLEMENT_BACKWARD_BITBLT(notsrc_and_notdst, *dst = (~(*src)) & (~(*dst)))
bx_cirrus_bitblt_rop_t bx_svga_cirrus_c::svga_get_fwd_rop_handler(Bit8u rop)
bx_bitblt_rop_t bx_svga_cirrus_c::svga_get_fwd_rop_handler(Bit8u rop)
{
bx_cirrus_bitblt_rop_t rop_handler = bitblt_rop_fwd_nop;
bx_bitblt_rop_t rop_handler = bitblt_rop_fwd_nop;
switch (rop)
{
@ -3288,9 +3215,9 @@ bx_cirrus_bitblt_rop_t bx_svga_cirrus_c::svga_get_fwd_rop_handler(Bit8u rop)
return rop_handler;
}
bx_cirrus_bitblt_rop_t bx_svga_cirrus_c::svga_get_bkwd_rop_handler(Bit8u rop)
bx_bitblt_rop_t bx_svga_cirrus_c::svga_get_bkwd_rop_handler(Bit8u rop)
{
bx_cirrus_bitblt_rop_t rop_handler = bitblt_rop_bkwd_nop;
bx_bitblt_rop_t rop_handler = bitblt_rop_bkwd_nop;
switch (rop)
{

View File

@ -57,11 +57,6 @@
#define CIRRUS_VIDEO_MEMORY_KB (CIRRUS_VIDEO_MEMORY_MB * 1024)
#define CIRRUS_VIDEO_MEMORY_BYTES (CIRRUS_VIDEO_MEMORY_KB * 1024)
typedef void (*bx_cirrus_bitblt_rop_t)(
Bit8u *dst,const Bit8u *src,
int dstpitch,int srcpitch,
int bltwidth,int bltheight);
class bx_svga_cirrus_c : public bx_vgacore_c
{
public:
@ -172,8 +167,8 @@ private:
BX_CIRRUS_SMF void svga_colorexpand_transp_memsrc();
BX_CIRRUS_SMF bx_bool svga_asyncbitblt_next();
BX_CIRRUS_SMF bx_cirrus_bitblt_rop_t svga_get_fwd_rop_handler(Bit8u rop);
BX_CIRRUS_SMF bx_cirrus_bitblt_rop_t svga_get_bkwd_rop_handler(Bit8u rop);
BX_CIRRUS_SMF bx_bitblt_rop_t svga_get_fwd_rop_handler(Bit8u rop);
BX_CIRRUS_SMF bx_bitblt_rop_t svga_get_bkwd_rop_handler(Bit8u rop);
struct {
Bit8u index;
@ -212,7 +207,7 @@ private:
Bit8u *disp_ptr;
struct {
bx_cirrus_bitblt_rop_t rop_handler;
bx_bitblt_rop_t rop_handler;
int pixelwidth;
int bltwidth;
int bltheight;

View File

@ -71,6 +71,7 @@
#include "voodoo.h"
#include "virt_timer.h"
#include "bxthread.h"
#include "bitblt.h"
#define LOG_THIS theVoodooDevice->
@ -334,6 +335,9 @@ void bx_voodoo_c::init(void)
}
voodoo_init(BX_VOODOO_THIS s.model);
if (BX_VOODOO_THIS s.model >= VOODOO_BANSHEE) {
banshee_bitblt_init();
}
bx_create_event(&fifo_wakeup);
bx_create_event(&fifo_not_full);
@ -1190,6 +1194,12 @@ void bx_voodoo_c::banshee_write_handler(void *this_ptr, Bit32u address, Bit32u v
theVoodooVga->redraw_area(v->banshee.hwcursor.x - 63, v->banshee.hwcursor.y - 63,
v->banshee.hwcursor.x, v->banshee.hwcursor.y);
}
if (v->banshee.io[reg] & 0x0020) {
BX_ERROR(("vidProcCfg: chromaKey mode not supported yet"));
}
if (v->banshee.io[reg] & 0x1000) {
BX_ERROR(("vidProcCfg: CLUT high bank not supported yet"));
}
break;
case io_hwCurPatAddr:
@ -1535,6 +1545,11 @@ void bx_voodoo_c::banshee_blt_reg_write(Bit8u reg, Bit32u value)
v->banshee.blt.transp = (value >> 16) & 1;
v->banshee.blt.clip_sel = (value >> 23) & 1;
v->banshee.blt.rop0 = (value >> 24);
if (v->banshee.blt.x_dir) {
v->banshee.blt.rop_fn = v->banshee.blt.rop_handler[1][v->banshee.blt.rop0];
} else {
v->banshee.blt.rop_fn = v->banshee.blt.rop_handler[0][v->banshee.blt.rop0];
}
v->banshee.blt.dwcount = 0;
switch (v->banshee.blt.cmd) {
case 0: // NOP
@ -1547,7 +1562,6 @@ void bx_voodoo_c::banshee_blt_reg_write(Bit8u reg, Bit32u value)
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) {
@ -1622,6 +1636,7 @@ void bx_voodoo_c::banshee_blt_launch_area_write(Bit32u value)
if (--v->banshee.blt.dwcount == 0) {
switch (v->banshee.blt.cmd) {
case 3:
v->banshee.blt.busy = 1;
banshee_blt_host_to_screen();
break;
default:
@ -1643,11 +1658,23 @@ void bx_voodoo_c::banshee_blt_complete()
bx_bool xinc = (cmd >> 10) & 1;
bx_bool yinc = (cmd >> 11) & 1;
Bit32u offset0, offset1;
Bit16u x, y;
Bit16u x, y, w, h;
if (v->banshee.blt.x_dir) {
x = v->banshee.blt.dst_x - v->banshee.blt.dst_w + 1;
} else {
x = v->banshee.blt.dst_x;
}
if (v->banshee.blt.y_dir) {
y = v->banshee.blt.dst_y - v->banshee.blt.dst_h + 1;
} else {
y = v->banshee.blt.dst_y;
}
w = v->banshee.blt.dst_w;
h = v->banshee.blt.dst_h;
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);
offset0 = start1 + y * pitch1 + x * (v->banshee.bpp >> 3);
offset1 = offset0 + h * pitch1 + w * (v->banshee.bpp >> 3);
if (offset1 >= start0) {
if (offset0 >= start0) {
offset0 -= start0;
@ -1656,7 +1683,7 @@ void bx_voodoo_c::banshee_blt_complete()
}
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);
theVoodooVga->redraw_area(x, y, w, h);
}
} else {
BX_ERROR(("redraw: Blt start > Desktop start not handled yet"));
@ -1734,91 +1761,89 @@ void bx_voodoo_c::banshee_blt_rectangle_fill()
void bx_voodoo_c::banshee_blt_screen_to_screen()
{
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;
Bit32u sstart = v->banshee.blt.reg[blt_srcBaseAddr] & v->fbi.mask;
Bit32u dstart = v->banshee.blt.reg[blt_dstBaseAddr] & v->fbi.mask;
Bit32u spitch = v->banshee.blt.reg[blt_srcFormat] & 0x3fff;
Bit32u dpitch = v->banshee.blt.reg[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);
Bit8u *src_ptr1, *dst_ptr1;
Bit16u x, y, x0, x1, y0, y1, w, h, cx0, cx1, cy0, cy1;
Bit8u pxbytes = (v->banshee.bpp >> 3);
x0 = v->banshee.blt.dst_x;
y0 = v->banshee.blt.dst_y;
x0 = v->banshee.blt.src_x;
y0 = v->banshee.blt.src_y;
x1 = v->banshee.blt.dst_x;
y1 = 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;
BX_DEBUG(("Screen to screen blt: %d x %d ROP = 0x%02x", w, h, v->banshee.blt.rop0));
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_ptr += (y0 * spitch + x0 * pxbytes);
dst_ptr += (y1 * dpitch + x1 * pxbytes);
if (v->banshee.blt.y_dir) {
if (v->banshee.blt.x_dir) {
for (y = y1; y > (y1 - h); y--) {
src_ptr1 = src_ptr;
dst_ptr1 = dst_ptr;
for (x = x1; x > (x1 - w); x--) {
if ((x >= cx0) && (x < cx1) && (y >= cy0) && (y < cy1)) {
v->banshee.blt.rop_fn(dst_ptr1, src_ptr1, dpitch, spitch, pxbytes, 1);
}
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;
src_ptr1 -= pxbytes;
dst_ptr1 -= pxbytes;
}
src_ptr -= spitch;
dst_ptr -= dpitch;
}
} 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;
for (y = y1; y > (y1 - h); y--) {
src_ptr1 = src_ptr;
dst_ptr1 = dst_ptr;
for (x = x1; x < (x1 + w); x++) {
if ((x >= cx0) && (x < cx1) && (y >= cy0) && (y < cy1)) {
v->banshee.blt.rop_fn(dst_ptr1, src_ptr1, dpitch, spitch, pxbytes, 1);
}
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;
src_ptr1 += pxbytes;
dst_ptr1 += pxbytes;
}
src_ptr -= spitch;
dst_ptr -= dpitch;
}
}
} else {
BX_INFO(("Screen to screen blt: ROP 0x%02x not supported yet", rop0));
if (v->banshee.blt.x_dir) {
for (y = y1; y < (y1 + h); y++) {
src_ptr1 = src_ptr;
dst_ptr1 = dst_ptr;
for (x = x1; x > (x1 - w); x--) {
if ((x >= cx0) && (x < cx1) && (y >= cy0) && (y < cy1)) {
v->banshee.blt.rop_fn(dst_ptr1, src_ptr1, dpitch, spitch, pxbytes, 1);
}
src_ptr1 -= pxbytes;
dst_ptr1 -= pxbytes;
}
src_ptr += spitch;
dst_ptr += dpitch;
}
} else {
for (y = y1; y < (y1 + h); y++) {
src_ptr1 = src_ptr;
dst_ptr1 = dst_ptr;
for (x = x1; x < (x1 + w); x++) {
if ((x >= cx0) && (x < cx1) && (y >= cy0) && (y < cy1)) {
v->banshee.blt.rop_fn(dst_ptr1, src_ptr1, dpitch, spitch, pxbytes, 1);
}
src_ptr1 += pxbytes;
dst_ptr1 += pxbytes;
}
src_ptr += spitch;
dst_ptr += dpitch;
}
}
}
v->banshee.blt.busy = 0;
}

View File

@ -1740,6 +1740,8 @@ struct _banshee_info
bx_bool transp;
bx_bool clip_sel;
Bit8u rop0;
bx_bitblt_rop_t rop_fn;
bx_bitblt_rop_t rop_handler[2][0x100];
Bit16u src_x;
Bit16u src_y;
Bit16u src_w;

View File

@ -3019,7 +3019,7 @@ Bit32u register_r(Bit32u offset)
result |= 1 << 8;
/* bit 9 is overall busy */
if (v->pci.op_pending)
if ((v->pci.op_pending) || (v->banshee.blt.busy))
result |= 1 << 9;
if (v->type == VOODOO_2) {
@ -3304,6 +3304,29 @@ void init_tmu_shared(tmu_shared_state *s)
}
}
#define SETUP_BITBLT(num, name) \
do { \
v->banshee.blt.rop_handler[0][num] = bitblt_rop_fwd_##name; \
v->banshee.blt.rop_handler[1][num] = bitblt_rop_bkwd_nop; \
} while (0);
void banshee_bitblt_init()
{
for (int i = 0; i < 0x100; i++) {
v->banshee.blt.rop_handler[0][i] = bitblt_rop_fwd_nop;
v->banshee.blt.rop_handler[1][i] = bitblt_rop_bkwd_nop;
}
SETUP_BITBLT(0x00, 0);
SETUP_BITBLT(0x33, notsrc);
SETUP_BITBLT(0x55, notdst);
SETUP_BITBLT(0x66, src_xor_dst);
SETUP_BITBLT(0x88, src_and_dst);
SETUP_BITBLT(0xaa, nop);
SETUP_BITBLT(0xcc, src);
SETUP_BITBLT(0xee, src_or_dst);
SETUP_BITBLT(0xff, 1);
}
void voodoo_init(Bit8u _type)
{
int pen;