Some work on the Voodoo2 bitblt functions.
- Implemented screen-to-screen blt function (untested). - Fixed and improved "Rectangle fill" function. - "SGRAM fill" function rewritten similar to the other functions. - TODO: cpu-to-screen function (handle data written to bltData register).
This commit is contained in:
parent
1a9e9be180
commit
f9eedc4a2c
@ -1355,50 +1355,34 @@ bx_bool clip_check(Bit16u x, Bit16u y)
|
||||
}
|
||||
|
||||
|
||||
Bit8u chroma_check(Bit8u *ptr, Bit32u min, Bit32u max, Bit8u pxsize, Bit8u shift)
|
||||
Bit8u chroma_check(Bit8u *ptr, Bit16u min, Bit16u max, bx_bool dst)
|
||||
{
|
||||
Bit8u pass = 0;
|
||||
Bit32u color;
|
||||
Bit8u r, g, b, rmin, rmax, gmin, gmax, bmin, bmax;
|
||||
|
||||
if (pxsize > 1) {
|
||||
if (pxsize == 2) {
|
||||
color = *ptr;
|
||||
color |= *(ptr + 1) << 8;
|
||||
r = (color >> 11);
|
||||
g = (color >> 5) & 0x3f;
|
||||
b = color & 0x1f;
|
||||
rmin = (min >> 11) & 0x1f;
|
||||
rmax = (max >> 11) & 0x1f;
|
||||
gmin = (min >> 5) & 0x3f;
|
||||
gmax = (max >> 5) & 0x3f;
|
||||
bmin = min & 0x1f;
|
||||
bmax = max & 0x1f;
|
||||
} else if (pxsize == 3) {
|
||||
color = *ptr;
|
||||
color |= *(ptr + 1) << 8;
|
||||
color |= *(ptr + 2) << 16;
|
||||
r = (color >> 16);
|
||||
g = (color >> 8) & 0xff;
|
||||
b = color & 0xff;
|
||||
rmin = (min >> 16) & 0xff;
|
||||
rmax = (max >> 16) & 0xff;
|
||||
gmin = (min >> 8) & 0xff;
|
||||
gmax = (max >> 8) & 0xff;
|
||||
bmin = min & 0xff;
|
||||
bmax = max & 0xff;
|
||||
}
|
||||
pass = ((r >= rmin) && (r <= rmax) && (g >= gmin) && (g <= gmax) &&
|
||||
(b >= bmin) && (b <= bmax));
|
||||
}
|
||||
return (pass << shift);
|
||||
color = *ptr;
|
||||
color |= *(ptr + 1) << 8;
|
||||
r = (color >> 11);
|
||||
g = (color >> 5) & 0x3f;
|
||||
b = color & 0x1f;
|
||||
rmin = (min >> 11) & 0x1f;
|
||||
rmax = (max >> 11) & 0x1f;
|
||||
gmin = (min >> 5) & 0x3f;
|
||||
gmax = (max >> 5) & 0x3f;
|
||||
bmin = min & 0x1f;
|
||||
bmax = max & 0x1f;
|
||||
pass = ((r >= rmin) && (r <= rmax) && (g >= gmin) && (g <= gmax) &&
|
||||
(b >= bmin) && (b <= bmax));
|
||||
if (!dst) pass <<= 1;
|
||||
return pass;
|
||||
}
|
||||
|
||||
void voodoo2_bitblt(void)
|
||||
{
|
||||
Bit8u rop = 0, *dst_ptr;
|
||||
Bit16u c, cols, dst_x, dst_y, r, rows, size, x;
|
||||
Bit32u offset, loffset, stride;
|
||||
Bit8u rop = 0, *dst_ptr, *src_ptr;
|
||||
Bit16u c, cols, dst_x, dst_y, src_x, src_y, r, rows, size, x;
|
||||
Bit32u doffset, soffset, dstride, sstride;
|
||||
|
||||
BLT.cmd = (Bit8u)(v->reg[bltCommand].u & 0x07);
|
||||
BLT.src_fmt = (Bit8u)((v->reg[bltCommand].u >> 3) & 0x1f);
|
||||
@ -1422,15 +1406,59 @@ void voodoo2_bitblt(void)
|
||||
}
|
||||
if (BLT.dst_tiled) {
|
||||
BLT.dst_base = (v->reg[bltDstBaseAddr].u & 0x3ff) << 12;
|
||||
BLT.src_pitch = (v->reg[bltXYStrides].u >> 10) & 0xfc0;
|
||||
BLT.dst_pitch = (v->reg[bltXYStrides].u >> 10) & 0xfc0;
|
||||
} else {
|
||||
BLT.dst_base = v->reg[bltDstBaseAddr].u & 0x3ffff8;
|
||||
BLT.dst_pitch = (v->reg[bltXYStrides].u >> 16) & 0xff8;
|
||||
}
|
||||
switch (BLT.cmd) {
|
||||
case 0:
|
||||
BX_ERROR(("TODO: Screen-to-Screen bitBLT: w = %d, h = %d, rop0 = %d",
|
||||
BX_DEBUG(("Screen-to-Screen bitBLT: w = %d, h = %d, rop0 = %d",
|
||||
BLT.dst_w, BLT.dst_h, BLT.rop[0]));
|
||||
src_x = (Bit16u)(v->reg[bltSrcXY].u & 0x7ff);
|
||||
src_y = (Bit16u)((v->reg[bltSrcXY].u >> 16) & 0x7ff);
|
||||
dst_x = (Bit16u)(v->reg[bltDstXY].u & 0x7ff);
|
||||
dst_y = (Bit16u)((v->reg[bltDstXY].u >> 16) & 0x7ff);
|
||||
cols = BLT.dst_w;
|
||||
rows = BLT.dst_h;
|
||||
dstride = BLT.dst_pitch;
|
||||
sstride = BLT.src_pitch;
|
||||
doffset = BLT.dst_base + dst_y * dstride;
|
||||
soffset = BLT.src_base + src_y * sstride;
|
||||
for (r = 0; r <= rows; r++) {
|
||||
dst_ptr = &v->fbi.ram[(doffset + dst_x * 2) & v->fbi.mask];
|
||||
src_ptr = &v->fbi.ram[(soffset + src_x * 2) & v->fbi.mask];
|
||||
x = dst_x;
|
||||
for (c = 0; c < cols; c++) {
|
||||
if (clip_check(x, dst_y)) {
|
||||
if (BLT.chroma_en & 1) {
|
||||
rop = chroma_check(src_ptr, BLT.src_col_min, BLT.src_col_max, 0);
|
||||
}
|
||||
if (BLT.chroma_en & 2) {
|
||||
rop |= chroma_check(dst_ptr, BLT.dst_col_min, BLT.dst_col_max, 1);
|
||||
}
|
||||
voodoo2_bitblt_mux(BLT.rop[rop], dst_ptr, src_ptr, 2);
|
||||
}
|
||||
if (BLT.x_dir) {
|
||||
dst_ptr -= 2;
|
||||
src_ptr -= 2;
|
||||
x--;
|
||||
} else {
|
||||
dst_ptr += 2;
|
||||
src_ptr += 2;
|
||||
x++;
|
||||
}
|
||||
}
|
||||
if (BLT.y_dir) {
|
||||
doffset -= dstride;
|
||||
soffset -= sstride;
|
||||
dst_y--;
|
||||
} else {
|
||||
doffset += dstride;
|
||||
soffset += sstride;
|
||||
dst_y++;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
BX_ERROR(("TODO: CPU-to-Screen bitBLT: w = %d, h = %d, rop0 = %d",
|
||||
@ -1443,23 +1471,33 @@ void voodoo2_bitblt(void)
|
||||
dst_y = (Bit16u)((v->reg[bltDstXY].u >> 16) & 0x7ff);
|
||||
cols = BLT.dst_w;
|
||||
rows = BLT.dst_h;
|
||||
stride = BLT.dst_pitch;
|
||||
loffset = BLT.dst_base + dst_y * stride;
|
||||
dstride = BLT.dst_pitch;
|
||||
doffset = BLT.dst_base + dst_y * dstride;
|
||||
for (r = 0; r <= rows; r++) {
|
||||
dst_ptr = &v->fbi.ram[(doffset + dst_x * 2) & v->fbi.mask];
|
||||
x = dst_x;
|
||||
dst_ptr = &v->fbi.ram[loffset & v->fbi.mask];
|
||||
for (c = 0; c < cols; c++) {
|
||||
if (clip_check(x, dst_y)) {
|
||||
if (BLT.chroma_en & 2) {
|
||||
rop = chroma_check(dst_ptr, BLT.dst_col_min, BLT.dst_col_max, 2, 0);
|
||||
rop = chroma_check(dst_ptr, BLT.dst_col_min, BLT.dst_col_max, 1);
|
||||
}
|
||||
voodoo2_bitblt_mux(BLT.rop[rop], dst_ptr, BLT.fgcolor, 2);
|
||||
}
|
||||
dst_ptr += 2;
|
||||
x++;
|
||||
if (BLT.x_dir) {
|
||||
dst_ptr -= 2;
|
||||
x--;
|
||||
} else {
|
||||
dst_ptr += 2;
|
||||
x++;
|
||||
}
|
||||
}
|
||||
if (BLT.y_dir) {
|
||||
doffset -= dstride;
|
||||
dst_y--;
|
||||
} else {
|
||||
doffset += dstride;
|
||||
dst_y++;
|
||||
}
|
||||
loffset += stride;
|
||||
dst_y++;
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
@ -1469,25 +1507,26 @@ void voodoo2_bitblt(void)
|
||||
rows = (Bit16u)((v->reg[bltSize].u >> 16) & 0x3ff);
|
||||
BX_DEBUG(("SGRAM fill: x = %d y = %d w = %d h = %d color = 0x%02x%02x",
|
||||
dst_x, dst_y, cols, rows, BLT.fgcolor[1], BLT.fgcolor[0]));
|
||||
stride = (1 << 12);
|
||||
loffset = dst_y * stride;
|
||||
dstride = (1 << 12);
|
||||
doffset = dst_y * dstride;
|
||||
for (r = 0; r <= rows; r++) {
|
||||
if (r == 0) {
|
||||
offset = (loffset + dst_x * 8) & v->fbi.mask;
|
||||
size = stride / 2 - (dst_x * 4) ;
|
||||
dst_ptr = &v->fbi.ram[(doffset + dst_x * 8) & v->fbi.mask];
|
||||
size = dstride / 2 - (dst_x * 4);
|
||||
} else {
|
||||
offset = (loffset & v->fbi.mask);
|
||||
dst_ptr = &v->fbi.ram[doffset & v->fbi.mask];
|
||||
if (r == rows) {
|
||||
size = cols * 4;
|
||||
} else {
|
||||
size = stride / 2;
|
||||
size = dstride / 2;
|
||||
}
|
||||
}
|
||||
for (c = 0; c < size; c++) {
|
||||
v->fbi.ram[offset++] = BLT.fgcolor[0];
|
||||
v->fbi.ram[offset++] = BLT.fgcolor[1];
|
||||
*dst_ptr = BLT.fgcolor[0];
|
||||
*(dst_ptr + 1) = BLT.fgcolor[1];
|
||||
dst_ptr += 2;
|
||||
}
|
||||
loffset += stride;
|
||||
doffset += dstride;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
Loading…
x
Reference in New Issue
Block a user