From 9a98d3a5ba86e0b454dcfff583483b2dc086ddc7 Mon Sep 17 00:00:00 2001 From: Volker Ruppert Date: Fri, 1 Dec 2017 17:05:49 +0000 Subject: [PATCH] Some changes for the Voodoo Banshee emulation. - now also using update_timing() and vertical_timer_handler() for Banshee. - Changed CMDFIFO log message to BX_DEBUG. --- bochs/iodev/display/voodoo.cc | 101 +++++++++++++++++------------- bochs/iodev/display/voodoo_data.h | 3 +- bochs/iodev/display/voodoo_func.h | 6 +- 3 files changed, 61 insertions(+), 49 deletions(-) diff --git a/bochs/iodev/display/voodoo.cc b/bochs/iodev/display/voodoo.cc index 750573be6..86de4662e 100644 --- a/bochs/iodev/display/voodoo.cc +++ b/bochs/iodev/display/voodoo.cc @@ -427,7 +427,7 @@ void bx_voodoo_c::register_state(void) new bx_shadow_num_c(dac, name, &v->dac.reg[i], BASE_HEX); } new bx_shadow_num_c(dac, "read_result", &v->dac.read_result, BASE_HEX); - new bx_shadow_num_c(dac, "clk0_freq", &v->dac.clk0_freq); + new bx_shadow_num_c(dac, "vidclk", &v->vidclk); bx_list_c *fbi = new bx_list_c(vstate, "fbi", "framebuffer"); if ((BX_VOODOO_THIS s.model < VOODOO_BANSHEE) || (theVoodooVga == NULL)) { new bx_shadow_data_c(fbi, "ram", v->fbi.ram, v->fbi.mask + 1); @@ -649,6 +649,7 @@ void bx_voodoo_c::after_restore_state(void) BX_INFO(("new i/o base address: 0x%04x", BX_VOODOO_THIS pci_base_address[2])); } if ((v->banshee.io[io_vidProcCfg] & 0x01) && (theVoodooVga != NULL)) { + BX_VOODOO_THIS update_timing(); theVoodooVga->banshee_update_mode(); } // TODO @@ -716,40 +717,52 @@ void bx_voodoo_c::mode_change_timer_handler(void *this_ptr) bx_bool bx_voodoo_c::update_timing(void) { int htotal, vtotal, hsync, vsync; + float hfreq; + bx_crtc_params_t crtcp; - if (!BX_VOODOO_THIS s.vdraw.clock_enabled || !BX_VOODOO_THIS s.vdraw.output_on) - return 0; - if ((v->reg[hSync].u == 0) || (v->reg[vSync].u == 0)) - return 0; - if (BX_VOODOO_THIS s.model == VOODOO_2) { - htotal = ((v->reg[hSync].u >> 16) & 0x7ff) + 1 + (v->reg[hSync].u & 0x1ff) + 1; - vtotal = ((v->reg[vSync].u >> 16) & 0x1fff) + (v->reg[vSync].u & 0x1fff); - hsync = ((v->reg[hSync].u >> 16) & 0x7ff); - vsync = ((v->reg[vSync].u >> 16) & 0x1fff); + if (BX_VOODOO_THIS s.model < VOODOO_BANSHEE) { + if (!BX_VOODOO_THIS s.vdraw.clock_enabled || !BX_VOODOO_THIS s.vdraw.output_on) + return 0; + if ((v->reg[hSync].u == 0) || (v->reg[vSync].u == 0)) + return 0; + if (BX_VOODOO_THIS s.model == VOODOO_2) { + htotal = ((v->reg[hSync].u >> 16) & 0x7ff) + 1 + (v->reg[hSync].u & 0x1ff) + 1; + vtotal = ((v->reg[vSync].u >> 16) & 0x1fff) + (v->reg[vSync].u & 0x1fff); + hsync = ((v->reg[hSync].u >> 16) & 0x7ff); + vsync = ((v->reg[vSync].u >> 16) & 0x1fff); + } else { + htotal = ((v->reg[hSync].u >> 16) & 0x3ff) + 1 + (v->reg[hSync].u & 0xff) + 1; + vtotal = ((v->reg[vSync].u >> 16) & 0xfff) + (v->reg[vSync].u & 0xfff); + hsync = ((v->reg[hSync].u >> 16) & 0x3ff); + vsync = ((v->reg[vSync].u >> 16) & 0xfff); + } + hfreq = v->vidclk / (float)htotal; + if (((v->reg[fbiInit1].u >> 20) & 3) == 1) { // VCLK div 2 + hfreq /= 2; + } + v->vertfreq = hfreq / (float)vtotal; + BX_VOODOO_THIS s.vdraw.htotal_usec = (unsigned)(1000000.0 / hfreq); + BX_VOODOO_THIS s.vdraw.vtotal_usec = (unsigned)(1000000.0 / v->vertfreq); + BX_VOODOO_THIS s.vdraw.htime_to_pixel = (double)htotal / (1000000.0 / hfreq); + BX_VOODOO_THIS s.vdraw.hsync_usec = BX_VOODOO_THIS s.vdraw.htotal_usec * hsync / htotal; + BX_VOODOO_THIS s.vdraw.vsync_usec = vsync * BX_VOODOO_THIS s.vdraw.htotal_usec; + if ((BX_VOODOO_THIS s.vdraw.width != v->fbi.width) || + (BX_VOODOO_THIS s.vdraw.height != v->fbi.height)) { + BX_VOODOO_THIS s.vdraw.width = v->fbi.width; + BX_VOODOO_THIS s.vdraw.height = v->fbi.height; + bx_gui->dimension_update(v->fbi.width, v->fbi.height, 0, 0, 16); + vertical_timer_handler(NULL); + } + BX_INFO(("Voodoo output %dx%d@%uHz", v->fbi.width, v->fbi.height, (unsigned)v->vertfreq)); } else { - htotal = ((v->reg[hSync].u >> 16) & 0x3ff) + 1 + (v->reg[hSync].u & 0xff) + 1; - vtotal = ((v->reg[vSync].u >> 16) & 0xfff) + (v->reg[vSync].u & 0xfff); - hsync = ((v->reg[hSync].u >> 16) & 0x3ff); - vsync = ((v->reg[vSync].u >> 16) & 0xfff); - } - float hfreq = v->dac.clk0_freq / (float)htotal; - if (((v->reg[fbiInit1].u >> 20) & 3) == 1) { // VCLK div 2 - hfreq /= 2; - } - float vfreq = hfreq / (float)vtotal; - BX_VOODOO_THIS s.vdraw.htotal_usec = (unsigned)(1000000.0 / hfreq); - BX_VOODOO_THIS s.vdraw.vtotal_usec = (unsigned)(1000000.0 / vfreq); - BX_VOODOO_THIS s.vdraw.htime_to_pixel = (double)htotal / (1000000.0 / hfreq); - BX_VOODOO_THIS s.vdraw.hsync_usec = BX_VOODOO_THIS s.vdraw.htotal_usec * hsync / htotal; - BX_VOODOO_THIS s.vdraw.vsync_usec = vsync * BX_VOODOO_THIS s.vdraw.htotal_usec; - if ((BX_VOODOO_THIS s.vdraw.width != v->fbi.width) || - (BX_VOODOO_THIS s.vdraw.height != v->fbi.height)) { + BX_VVGA_THIS get_crtc_params(&crtcp); + hfreq = v->vidclk / (float)(crtcp.htotal * 8); + v->vertfreq = hfreq / (float)crtcp.vtotal; + BX_VOODOO_THIS s.vdraw.vtotal_usec = (unsigned)(1000000.0 / v->vertfreq); BX_VOODOO_THIS s.vdraw.width = v->fbi.width; BX_VOODOO_THIS s.vdraw.height = v->fbi.height; - bx_gui->dimension_update(v->fbi.width, v->fbi.height, 0, 0, 16); vertical_timer_handler(NULL); } - BX_INFO(("Voodoo output %dx%d@%uHz", v->fbi.width, v->fbi.height, (unsigned)vfreq)); bx_virt_timer.activate_timer(BX_VOODOO_THIS s.vertical_timer_id, (Bit32u)BX_VOODOO_THIS s.vdraw.vtotal_usec, 1); return 1; } @@ -783,11 +796,13 @@ 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; - BX_VOODOO_THIS s.vdraw.gui_update_pending = 1; + if (BX_VOODOO_THIS s.model < VOODOO_BANSHEE) { + // TODO: use tile-based update mechanism + BX_VOODOO_THIS s.vdraw.gui_update_pending = 1; + } } } @@ -930,26 +945,19 @@ void bx_voodoo_c::update(void) BX_UNLOCK(render_mutex); return; } - iWidth = BX_VOODOO_THIS s.vdraw.width; - iHeight = BX_VOODOO_THIS s.vdraw.height; bpp = 16; start = v->fbi.rgboffs[v->fbi.frontbuf]; pitch = v->fbi.rowpixels * 2; } else { - iWidth = v->fbi.width; - iHeight = v->fbi.height; 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; } - if (v->fbi.clut_dirty || v->fbi.video_changed) { - redraw_area(0, 0, iWidth, iHeight); - v->fbi.clut_dirty = 0; - v->fbi.video_changed = 0; - } } + iWidth = BX_VOODOO_THIS s.vdraw.width; + iHeight = BX_VOODOO_THIS s.vdraw.height; Bit8u *disp_ptr = &v->fbi.ram[start & v->fbi.mask]; if (bx_gui->graphics_tile_info_common(&info)) { @@ -1474,7 +1482,6 @@ void bx_voodoo_c::banshee_write_handler(void *this_ptr, Bit32u address, Bit32u v Bit8u offset = (Bit8u)(address & 0xff); Bit8u reg = (offset>>2), dac_idx, k, m, n; Bit32u old = v->banshee.io[reg]; - double vfreq; bx_bool prev_hwce = v->banshee.hwcursor.enabled; Bit16u prev_hwcx = v->banshee.hwcursor.x; Bit16u prev_hwcy = v->banshee.hwcursor.y; @@ -1517,10 +1524,10 @@ void bx_voodoo_c::banshee_write_handler(void *this_ptr, Bit32u address, Bit32u v k = (Bit8u)(value & 0x03); m = (Bit8u)((value >> 2) & 0x3f); n = (Bit8u)((value >> 8) & 0xff); - vfreq = 14318180.0f * ((double)n + 2.0f) / ((double)m + 2.0f) / (double)(1 << k); - BX_INFO(("Setting VCLK #3 (pllCtrl0) = %.3f MHz", vfreq / 1000000.0f)); + v->vidclk = 14318180.0f * ((double)n + 2.0f) / ((double)m + 2.0f) / (double)(1 << k); + BX_INFO(("Setting VCLK #3 (pllCtrl0) = %.3f MHz", v->vidclk / 1000000.0f)); if (theVoodooVga != NULL) { - theVoodooVga->banshee_set_vclk3((Bit32u)vfreq); + theVoodooVga->banshee_set_vclk3((Bit32u)v->vidclk); } } break; @@ -1543,9 +1550,12 @@ void bx_voodoo_c::banshee_write_handler(void *this_ptr, Bit32u address, Bit32u v if ((v->banshee.io[reg] ^ old) & 0x2800) v->fbi.clut_dirty = 1; if ((v->banshee.io[reg] & 0x01) && ((old & 0x01) == 0x00)) { + BX_VOODOO_THIS update_timing(); if (theVoodooVga != NULL) { theVoodooVga->banshee_update_mode(); } + } else if (!(v->banshee.io[reg] & 0x01) && ((old & 0x01) == 0x01)) { + bx_virt_timer.deactivate_timer(BX_VOODOO_THIS s.vertical_timer_id); } v->banshee.hwcursor.enabled = ((v->banshee.io[reg] >> 27) & 1); v->banshee.hwcursor.mode = ((v->banshee.io[reg] >> 1) & 1); @@ -2919,7 +2929,8 @@ void bx_voodoo_vga_c::banshee_update_mode(void) return; } v->banshee.half_mode = (v->banshee.io[io_vidProcCfg] >> 4) & 1; - BX_INFO(("switched to %d x %d x %d", v->fbi.width, v->fbi.height, v->banshee.disp_bpp)); + BX_INFO(("switched to %d x %d x %d @ %d Hz", v->fbi.width, v->fbi.height, + v->banshee.disp_bpp, (unsigned)v->vertfreq)); bx_gui->dimension_update(v->fbi.width, v->fbi.height, 0, 0, v->banshee.disp_bpp); // compatibilty settings for VGA core BX_VVGA_THIS s.last_xres = v->fbi.width; diff --git a/bochs/iodev/display/voodoo_data.h b/bochs/iodev/display/voodoo_data.h index b5a0cfd1a..5b10d15c6 100644 --- a/bochs/iodev/display/voodoo_data.h +++ b/bochs/iodev/display/voodoo_data.h @@ -1676,7 +1676,6 @@ struct _dac_state Bit8u clk0_m; Bit8u clk0_n; Bit8u clk0_p; - float clk0_freq; }; @@ -1796,6 +1795,8 @@ struct _voodoo_state pci_state pci; /* PCI state */ dac_state dac; /* DAC state */ + float vidclk; /* video clock */ + float vertfreq; /* vertical frequency */ fbi_state fbi; /* FBI states */ tmu_state tmu[MAX_TMU]; /* TMU states */ diff --git a/bochs/iodev/display/voodoo_func.h b/bochs/iodev/display/voodoo_func.h index fb72dc371..61fd5c1c7 100644 --- a/bochs/iodev/display/voodoo_func.h +++ b/bochs/iodev/display/voodoo_func.h @@ -1377,10 +1377,10 @@ void dacdata_w(dac_state *d, Bit8u regnum, Bit8u data) break; case 0x0e: if ((d->data_size == 1) && (data == 0xf8)) { - d->clk0_freq = 14318184.0f * ((float)(d->clk0_m + 2) / (float)(d->clk0_n + 2)) / (float)(1 << d->clk0_p); + v->vidclk = 14318184.0f * ((float)(d->clk0_m + 2) / (float)(d->clk0_n + 2)) / (float)(1 << d->clk0_p); Bit8u dacr6 = d->reg[6] & 0xf0; if ((dacr6 == 0x20) || (dacr6 == 0x60) || (dacr6 == 0x70)) { - d->clk0_freq /= 2.0f; + v->vidclk /= 2.0f; } Voodoo_update_timing(); } @@ -2517,7 +2517,7 @@ void cmdfifo_process(cmdfifo_info *f) case 3: // JMP f->rdptr = (command >> 4) & 0xfffffc; if (f->count_holes) { - BX_INFO(("cmdfifo_process(): JMP 0x%08x", f->rdptr)); + BX_DEBUG(("cmdfifo_process(): JMP 0x%08x", f->rdptr)); } break; default: