diff --git a/bochs/iodev/display/voodoo.cc b/bochs/iodev/display/voodoo.cc index 3921ce0cc..b4a55bc19 100644 --- a/bochs/iodev/display/voodoo.cc +++ b/bochs/iodev/display/voodoo.cc @@ -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; diff --git a/bochs/iodev/display/voodoo_data.h b/bochs/iodev/display/voodoo_data.h index 3b43aae3d..ab716e5c1 100644 --- a/bochs/iodev/display/voodoo_data.h +++ b/bochs/iodev/display/voodoo_data.h @@ -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 */ diff --git a/bochs/iodev/display/voodoo_func.h b/bochs/iodev/display/voodoo_func.h index 232266d95..1686ceae3 100644 --- a/bochs/iodev/display/voodoo_func.h +++ b/bochs/iodev/display/voodoo_func.h @@ -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; }