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:
parent
b1aefb0b6c
commit
ca9120655b
103
bochs/iodev/display/bitblt.h
Normal file
103
bochs/iodev/display/bitblt.h
Normal 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
|
@ -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)
|
||||
{
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user