diff --git a/bochs/iodev/display/voodoo.cc b/bochs/iodev/display/voodoo.cc index af6488017..ebc89bbc7 100644 --- a/bochs/iodev/display/voodoo.cc +++ b/bochs/iodev/display/voodoo.cc @@ -798,13 +798,11 @@ void bx_voodoo_c::vertical_timer_handler(void *this_ptr) } if (v->fbi.video_changed || v->fbi.clut_dirty) { + // TODO: use tile-based update mechanism BX_VOODOO_THIS redraw_area(0, 0, BX_VOODOO_THIS s.vdraw.width, BX_VOODOO_THIS s.vdraw.height); v->fbi.clut_dirty = 0; v->fbi.video_changed = 0; - if (BX_VOODOO_THIS s.model < VOODOO_BANSHEE) { - // TODO: use tile-based update mechanism - BX_VOODOO_THIS s.vdraw.gui_update_pending = 1; - } + BX_VOODOO_THIS s.vdraw.gui_update_pending = 1; } } @@ -942,7 +940,15 @@ void bx_voodoo_c::update(void) bx_svga_tileinfo_t info; BX_LOCK(render_mutex); - if (BX_VOODOO_THIS s.model < VOODOO_BANSHEE) { + if ((BX_VOODOO_THIS s.model >= VOODOO_BANSHEE) && + ((v->banshee.io[io_vidProcCfg] & 0x181) == 0x81)) { + bpp = v->banshee.disp_bpp; + start = v->banshee.io[io_vidDesktopStartAddr]; + pitch = v->banshee.io[io_vidDesktopOverlayStride] & 0x7fff; + if (v->banshee.desktop_tiled) { + pitch *= 128; + } + } else { if (!BX_VOODOO_THIS s.vdraw.gui_update_pending) { BX_UNLOCK(render_mutex); return; @@ -950,20 +956,6 @@ void bx_voodoo_c::update(void) bpp = 16; start = v->fbi.rgboffs[v->fbi.frontbuf]; pitch = v->fbi.rowpixels * 2; - } else { - if ((v->banshee.io[io_vidProcCfg] & 0x181) == 0x81) { - bpp = v->banshee.disp_bpp; - start = v->banshee.io[io_vidDesktopStartAddr]; - pitch = v->banshee.io[io_vidDesktopOverlayStride] & 0x7fff; - if (v->banshee.desktop_tiled) { - pitch *= 128; - } - } else { - bpp = 16; - start = v->fbi.rgboffs[0]; - pitch = v->fbi.rowpixels * 2; - BX_VOODOO_THIS redraw_area(0, 0, BX_VOODOO_THIS s.vdraw.width, BX_VOODOO_THIS s.vdraw.height); - } } iWidth = BX_VOODOO_THIS s.vdraw.width; iHeight = BX_VOODOO_THIS s.vdraw.height; @@ -1686,7 +1678,7 @@ void bx_voodoo_c::banshee_mem_read(bx_phy_address addr, unsigned len, void *data } else { Bit8u temp = v->fbi.lfb_stride; v->fbi.lfb_stride = 11; - value = lfb_r((offset & 0xffffff) >> 2); + value = lfb_r((offset & v->fbi.mask) >> 2); v->fbi.lfb_stride = temp; } } else if ((addr & ~0x1ffffff) == BX_VOODOO_THIS pci_base_address[1]) { @@ -1714,10 +1706,6 @@ void bx_voodoo_c::banshee_mem_write(bx_phy_address addr, unsigned len, void *dat Bit32u offset = (addr & 0x1ffffff); Bit32u value = *(Bit32u*)data; Bit32u mask = 0xffffffff; - Bit8u value8; - Bit32u start = v->banshee.io[io_vidDesktopStartAddr]; - Bit32u pitch = v->banshee.io[io_vidDesktopOverlayStride] & 0x7fff; - unsigned i, x, y; if ((addr & ~0x1ffffff) == BX_VOODOO_THIS pci_base_address[0]) { if (offset < 0x80000) { @@ -1744,7 +1732,7 @@ void bx_voodoo_c::banshee_mem_write(bx_phy_address addr, unsigned len, void *dat mask = 0xffff0000; } } - lfb_w((offset & 0xffffff) >> 2, value, mask); + lfb_w((offset & v->fbi.mask) >> 2, value, mask); v->fbi.lfb_stride = temp; } } else if ((addr & ~0x1ffffff) == BX_VOODOO_THIS pci_base_address[1]) { @@ -1758,33 +1746,50 @@ void bx_voodoo_c::banshee_mem_write(bx_phy_address addr, unsigned len, void *dat BX_INFO(("CMDFIFO #1 write")); cmdfifo_w(&v->fbi.cmdfifo[1], offset, value); } else { - if (offset >= start) { - if (v->banshee.desktop_tiled) { - 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) & v->fbi.mask; - } - 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; - v->fbi.ram[offset + i] = value8; - } - } + banshee_mem_write_linear(offset, value, len); } } else { - lfb_w((offset - v->fbi.lfb_base) >> 2, value, 0xffffffff); + if (len == 2) { + if ((offset & 3) == 0) { + mask = 0x0000ffff; + } else { + mask = 0xffff0000; + } + } + lfb_w((offset - v->fbi.lfb_base) >> 2, value, mask); + } + } +} + +void bx_voodoo_c::banshee_mem_write_linear(Bit32u offset, Bit32u value, unsigned len) +{ + Bit8u value8; + Bit32u start = v->banshee.io[io_vidDesktopStartAddr]; + Bit32u pitch = v->banshee.io[io_vidDesktopOverlayStride] & 0x7fff; + unsigned i, x, y; + + if (offset >= start) { + if (v->banshee.desktop_tiled) { + 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) & v->fbi.mask; + } + 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; + v->fbi.ram[offset + i] = value8; } } } diff --git a/bochs/iodev/display/voodoo.h b/bochs/iodev/display/voodoo.h index c8b80dbfe..652845062 100644 --- a/bochs/iodev/display/voodoo.h +++ b/bochs/iodev/display/voodoo.h @@ -82,6 +82,8 @@ public: Bit32u banshee_blt_reg_read(Bit8u reg); void banshee_blt_reg_write(Bit8u reg, Bit32u value); + void banshee_mem_write_linear(Bit32u offset, Bit32u value, unsigned len); + private: bx_voodoo_t s; diff --git a/bochs/iodev/display/voodoo_func.h b/bochs/iodev/display/voodoo_func.h index 134a33d87..d0fe64e73 100644 --- a/bochs/iodev/display/voodoo_func.h +++ b/bochs/iodev/display/voodoo_func.h @@ -1909,7 +1909,7 @@ void register_w(Bit32u offset, Bit32u data, bx_bool log) else rowpixels = (data & 0x3fff) >> 1; if (v->fbi.rowpixels != rowpixels) - BX_PANIC(("aux buffer stride differs from color buffer stride")); + BX_ERROR(("aux buffer stride differs from color buffer stride")); } break; @@ -2534,10 +2534,10 @@ Bit32u cmdfifo_r(cmdfifo_info *f) void cmdfifo_process(cmdfifo_info *f) { Bit32u command, data, mask, nwords, regaddr; - Bit8u type, code, nvertex, smode, data8; + Bit8u type, code, nvertex, smode, disbytes; bx_bool blt, inc, pcolor; voodoo_reg reg; - int i, j; + int i, w0, wn; setup_vertex svert = {0}; command = cmdfifo_r(f); @@ -2715,18 +2715,33 @@ void cmdfifo_process(cmdfifo_info *f) nwords = (command >> 3) & 0x7ffff; regaddr = (cmdfifo_r(f) & 0xffffff) >> 2; code = (command >> 30); - if ((command & 0x3fc00000) > 0) { + disbytes = (command >> 22) & 0xff; + if ((disbytes > 0) && (code != 0)) { BX_ERROR(("CMDFIFO packet type 5: byte disable not supported yet (dest code = %d)", code)); } switch (code) { case 0: regaddr <<= 2; - for (i = 0; i < (int)nwords; i++) { + w0 = 0; + wn = nwords; + if ((disbytes > 0) && (disbytes != 0x0c) && (disbytes != 0xc0)) { + BX_ERROR(("CMDFIFO packet type 5: byte disable not complete yet (dest code = 0)")); + } + if ((disbytes & 0xf0) > 0) { data = cmdfifo_r(f); - for (j = 0; j < 4; j++) { - data8 = (data >> (j*8)) & 0xff; - v->fbi.ram[regaddr + j] = data8; + if ((disbytes & 0xf0) == 0x30) { + Voodoo_Banshee_LFB_write(regaddr + 2, data >> 16, 2); + } else if ((disbytes & 0xf0) == 0xc0) { + Voodoo_Banshee_LFB_write(regaddr, data, 2); } + w0++; + regaddr += 4; + } + for (i = w0; i < wn; i++) { + data = cmdfifo_r(f); + BX_UNLOCK(cmdfifo_mutex); + Voodoo_Banshee_LFB_write(regaddr, data, 4); + BX_LOCK(cmdfifo_mutex); regaddr += 4; } break; diff --git a/bochs/iodev/display/voodoo_main.h b/bochs/iodev/display/voodoo_main.h index 012bbd959..129b3396d 100644 --- a/bochs/iodev/display/voodoo_main.h +++ b/bochs/iodev/display/voodoo_main.h @@ -73,5 +73,6 @@ enum #define Voodoo_get_retrace(a) theVoodooDevice->get_retrace(a) #define Voodoo_update_timing() theVoodooDevice->update_timing() #define Voodoo_Banshee_2D_write(a,b) theVoodooDevice->banshee_blt_reg_write(a,b) +#define Voodoo_Banshee_LFB_write(a,b,c) theVoodooDevice->banshee_mem_write_linear(a,b,c) #endif