Some work for the Voodoo Banshee 16 bpp mode support.

- Started implementing the CMDFIFO "hole count" support. It does not yet count
  holes, but it handles the Amin and Amax values (except read pointer rollover
  and JMP command). This is enough to get a usable desktop after Win95 guest
  startup.
- Added read / write support for the desktop tile space.
- Fixed tiled desktop redraw after bitblt operation.
This commit is contained in:
Volker Ruppert 2017-11-22 17:07:39 +00:00
parent e136e25586
commit 3ad06c130e
3 changed files with 56 additions and 21 deletions

View File

@ -1630,6 +1630,9 @@ void bx_voodoo_c::banshee_mem_read(bx_phy_address addr, unsigned len, void *data
Bit32u *data_ptr = (Bit32u*)data;
Bit32u value = 0xffffffff;
Bit32u offset = (addr & 0x1ffffff);
Bit32u start = v->banshee.io[io_vidDesktopStartAddr];
Bit32u pitch = v->banshee.io[io_vidDesktopOverlayStride] & 0x7fff;
unsigned i, x, y;
if (BX_VOODOO_THIS pci_rom_size > 0) {
Bit32u mask = (BX_VOODOO_THIS pci_rom_size - 1);
@ -1666,11 +1669,16 @@ void bx_voodoo_c::banshee_mem_read(bx_phy_address addr, unsigned len, void *data
}
} else if ((addr & ~0x1ffffff) == BX_VOODOO_THIS pci_base_address[1]) {
if (offset < v->fbi.lfb_base) {
if (offset <= v->fbi.mask) {
value = 0;
for (unsigned i = 0; i < len; i++) {
value |= (v->fbi.ram[offset + i] << (i*8));
}
if (v->banshee.desktop_tiled && (offset >= start)) {
offset -= start;
pitch *= 128;
x = (offset << 0) & ((1 << v->fbi.lfb_stride) - 1);
y = (offset >> v->fbi.lfb_stride) & 0x7ff;
offset = start + y * pitch + x;
}
value = 0;
for (i = 0; i < len; i++) {
value |= (v->fbi.ram[offset + i] << (i*8));
}
} else {
value = lfb_r((offset - v->fbi.lfb_base) >> 2);
@ -1720,20 +1728,23 @@ void bx_voodoo_c::banshee_mem_write(bx_phy_address addr, unsigned len, void *dat
BX_INFO(("TODO: CMDFIFO #1 write"));
} else {
if (offset >= start) {
if (!v->banshee.desktop_tiled) {
BX_LOCK(render_mutex);
for (i = 0; i < len; i++) {
value8 = (value >> (i*8)) & 0xff;
v->fbi.ram[offset + i] = value8;
}
if (v->banshee.desktop_tiled) {
offset -= start;
x = (offset % pitch) / (v->banshee.disp_bpp >> 3);
y = offset / pitch;
theVoodooVga->redraw_area(x, y, len / (v->banshee.disp_bpp >> 3), 1);
BX_UNLOCK(render_mutex);
} else {
BX_ERROR(("write to desktop tile space not supported yet"));
pitch *= 128;
x = (offset << 0) & ((1 << v->fbi.lfb_stride) - 1);
y = (offset >> v->fbi.lfb_stride) & 0x7ff;
offset = start + y * pitch + x;
}
BX_LOCK(render_mutex);
for (i = 0; i < len; i++) {
value8 = (value >> (i*8)) & 0xff;
v->fbi.ram[offset + i] = value8;
}
offset -= start;
x = (offset % pitch) / (v->banshee.disp_bpp >> 3);
y = offset / pitch;
theVoodooVga->redraw_area(x, y, len / (v->banshee.disp_bpp >> 3), 1);
BX_UNLOCK(render_mutex);
} else {
for (i = 0; i < len; i++) {
value8 = (value >> (i*8)) & 0xff;
@ -1805,12 +1816,13 @@ void bx_voodoo_c::banshee_agp_reg_write(Bit8u reg, Bit32u value)
v->fbi.cmdfifo[1].end = v->fbi.cmdfifo[1].base + (((value & 0xff) + 1) << 12);
}
v->fbi.cmdfifo[fifo_idx].enabled = ((value >> 8) & 1);
v->fbi.cmdfifo[fifo_idx].count_holes = (((value >> 10) & 1) == 0);
BX_UNLOCK(cmdfifo_mutex);
break;
case cmdBump0:
case cmdBump1:
if (value > 0) {
BX_ERROR(("cmdBump0 not supported yet"));
BX_ERROR(("cmdBump%d not supported yet", fifo_idx));
}
break;
case cmdRdPtrL0:
@ -1827,11 +1839,15 @@ void bx_voodoo_c::banshee_agp_reg_write(Bit8u reg, Bit32u value)
break;
case cmdAMin0:
case cmdAMin1:
BX_LOCK(cmdfifo_mutex);
v->fbi.cmdfifo[fifo_idx].amin = value;
BX_UNLOCK(cmdfifo_mutex);
break;
case cmdAMax0:
case cmdAMax1:
BX_LOCK(cmdfifo_mutex);
v->fbi.cmdfifo[fifo_idx].amax = value;
BX_UNLOCK(cmdfifo_mutex);
break;
case cmdFifoDepth0:
case cmdFifoDepth1:
@ -2130,6 +2146,9 @@ void bx_voodoo_c::banshee_blt_complete()
bx_bool yinc = (cmd >> 11) & 1;
int x, y;
if (v->banshee.desktop_tiled) {
vpitch *= 128;
}
if ((dstart == vstart) && (dpitch == vpitch) && (dpxsize == vpxsize)) {
if (BLT.x_dir) {
x = BLT.dst_x + 1 - BLT.dst_w;

View File

@ -1496,7 +1496,7 @@ typedef struct _cmdfifo_info cmdfifo_info;
struct _cmdfifo_info
{
bx_bool enabled; /* enabled? */
Bit8u count_holes; /* count holes? */
bx_bool count_holes; /* count holes? */
Bit32u base; /* base address in framebuffer RAM */
Bit32u end; /* end address in framebuffer RAM */
Bit32u rdptr; /* current read pointer */

View File

@ -2444,7 +2444,15 @@ void cmdfifo_w(Bit32u fbi_offset, Bit32u data)
{
BX_LOCK(cmdfifo_mutex);
*(Bit32u*)(&v->fbi.ram[fbi_offset]) = data;
v->fbi.cmdfifo[0].depth++;
if (v->fbi.cmdfifo[0].count_holes) {
v->fbi.cmdfifo[0].amax = fbi_offset;
if (fbi_offset == (v->fbi.cmdfifo[0].amin + 4)) {
v->fbi.cmdfifo[0].amin = fbi_offset;
v->fbi.cmdfifo[0].depth = (v->fbi.cmdfifo[0].amin - v->fbi.cmdfifo[0].rdptr) / 4;
}
} else {
v->fbi.cmdfifo[0].depth++;
}
if (v->fbi.cmdfifo[0].depth_needed == BX_MAX_BIT32U) {
v->fbi.cmdfifo[0].depth_needed = cmdfifo_calc_depth_needed();
}
@ -2463,7 +2471,15 @@ Bit32u cmdfifo_r(void)
data = *(Bit32u*)(&v->fbi.ram[v->fbi.cmdfifo[0].rdptr & v->fbi.mask]);
v->fbi.cmdfifo[0].rdptr += 4;
v->fbi.cmdfifo[0].depth--;
if (v->fbi.cmdfifo[0].rdptr >= v->fbi.cmdfifo[0].end) {
BX_INFO(("CMDFIFO rollover"));
v->fbi.cmdfifo[0].rdptr = v->fbi.cmdfifo[0].base;
}
if (v->fbi.cmdfifo[0].count_holes) {
v->fbi.cmdfifo[0].depth = (v->fbi.cmdfifo[0].amin - v->fbi.cmdfifo[0].rdptr) / 4;
} else {
v->fbi.cmdfifo[0].depth--;
}
return data;
}