From 9912c99fd27df0ca4e854fa4420330377fd01aff Mon Sep 17 00:00:00 2001 From: Volker Ruppert Date: Tue, 16 May 2017 20:37:01 +0000 Subject: [PATCH] Continued work on Voodoo2 support (some demos now working). - Added capability to save/restore float type values in paramtree / siminterface. - Added Voodoo2 triangle generator data to save/restore list. - Implemented bitBLT function "SGRAM fill". - Minor other changes and cleanups. - TODO: remaining bitBLT functions, thread handling improvements. --- bochs/gui/paramtree.cc | 15 +++- bochs/gui/paramtree.h | 5 ++ bochs/gui/siminterface.cc | 21 +++-- bochs/iodev/display/voodoo.cc | 20 +++++ bochs/iodev/display/voodoo_func.h | 143 ++++++++++++++++++++---------- 5 files changed, 151 insertions(+), 53 deletions(-) diff --git a/bochs/gui/paramtree.cc b/bochs/gui/paramtree.cc index 756387635..efa01ebc4 100644 --- a/bochs/gui/paramtree.cc +++ b/bochs/gui/paramtree.cc @@ -2,7 +2,7 @@ // $Id$ ///////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2010-2015 The Bochs Project +// Copyright (C) 2010-2017 The Bochs Project // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -455,6 +455,19 @@ bx_shadow_num_c::bx_shadow_num_c(bx_param_c *parent, } } +// Float (floating point) +bx_shadow_num_c::bx_shadow_num_c(bx_param_c *parent, + const char *name, + float *ptr_to_real_val) +: bx_param_num_c(parent, name, NULL, NULL, BX_MIN_BIT64U, BX_MAX_BIT64U, 0, 1) +{ + this->varsize = 32; + this->lowbit = 0; + this->mask = BX_MAX_BIT32U; + val.pfloat = ptr_to_real_val; + this->base = BASE_FLOAT; +} + // Double (floating point) bx_shadow_num_c::bx_shadow_num_c(bx_param_c *parent, const char *name, diff --git a/bochs/gui/paramtree.h b/bochs/gui/paramtree.h index c01327074..b891585e0 100644 --- a/bochs/gui/paramtree.h +++ b/bochs/gui/paramtree.h @@ -89,6 +89,7 @@ public: #define BASE_DEC 10 #define BASE_HEX 16 +#define BASE_FLOAT 32 #define BASE_DOUBLE 64 class BOCHSAPI bx_param_c : public bx_object_c { @@ -190,6 +191,7 @@ protected: Bit32s *p32bit; // used by bx_shadow_num_c Bit16s *p16bit; // used by bx_shadow_num_c Bit8s *p8bit; // used by bx_shadow_num_c + float *pfloat; // used by bx_shadow_num_c double *pdouble; // used by bx_shadow_num_c bx_bool *pbool; // used by bx_shadow_bool_c } val; @@ -297,6 +299,9 @@ public: bx_shadow_num_c(bx_param_c *parent, const char *name, double *ptr_to_real_val); + bx_shadow_num_c(bx_param_c *parent, + const char *name, + float *ptr_to_real_val); virtual Bit64s get64(); virtual void set(Bit64s val); virtual void reset(); diff --git a/bochs/gui/siminterface.cc b/bochs/gui/siminterface.cc index 0de4c008d..848c3ceeb 100644 --- a/bochs/gui/siminterface.cc +++ b/bochs/gui/siminterface.cc @@ -1205,7 +1205,8 @@ bx_bool bx_real_sim_c::restore_bochs_param(bx_list_c *root, const char *sr_path, char *ptr; int i, j, p; unsigned n; - double fvalue; + float f1value; + double f2value; Bit64u value; bx_param_c *param = NULL; FILE *fp, *fp2; @@ -1247,8 +1248,12 @@ bx_bool bx_real_sim_c::restore_bochs_param(bx_list_c *root, const char *sr_path, switch (param->get_type()) { case BXT_PARAM_NUM: if (((bx_param_num_c*)param)->get_base() == BASE_DOUBLE) { - fvalue = strtod(ptr, NULL); - memcpy(&value, &fvalue, sizeof(double)); + f2value = strtod(ptr, NULL); + memcpy(&value, &f2value, sizeof(double)); + ((bx_param_num_c*)param)->set(value); + } else if (((bx_param_num_c*)param)->get_base() == BASE_FLOAT) { + f1value = (float)strtod(ptr, NULL); + memcpy(&value, &f1value, sizeof(float)); ((bx_param_num_c*)param)->set(value); } else if ((ptr[0] == '0') && (ptr[1] == 'x')) { ((bx_param_num_c*)param)->set(strtoull(ptr, NULL, 16)); @@ -1369,7 +1374,8 @@ bx_bool bx_real_sim_c::save_sr_param(FILE *fp, bx_param_c *node, const char *sr_ { int i, j; Bit64s value; - double fvalue; + float f1value; + double f2value; char pname[BX_PATHNAME_LEN], tmpstr[BX_PATHNAME_LEN]; FILE *fp2; @@ -1384,8 +1390,11 @@ bx_bool bx_real_sim_c::save_sr_param(FILE *fp, bx_param_c *node, const char *sr_ case BXT_PARAM_NUM: value = ((bx_param_num_c*)node)->get64(); if (((bx_param_num_c*)node)->get_base() == BASE_DOUBLE) { - memcpy(&fvalue, &value, sizeof(double)); - fprintf(fp, "%f\n", fvalue); + memcpy(&f2value, &value, sizeof(double)); + fprintf(fp, "%f\n", f2value); + } else if (((bx_param_num_c*)node)->get_base() == BASE_FLOAT) { + memcpy(&f1value, &value, sizeof(float)); + fprintf(fp, "%f\n", f1value); } else if (((bx_param_num_c*)node)->get_base() == BASE_DEC) { if (((bx_param_num_c*)node)->get_min() >= BX_MIN_BIT64U) { if ((Bit64u)((bx_param_num_c*)node)->get_max() > BX_MAX_BIT32U) { diff --git a/bochs/iodev/display/voodoo.cc b/bochs/iodev/display/voodoo.cc index 657cdc62a..5b1d5fdf2 100644 --- a/bochs/iodev/display/voodoo.cc +++ b/bochs/iodev/display/voodoo.cc @@ -359,6 +359,26 @@ void bx_voodoo_c::register_state(void) new bx_shadow_num_c(fbi, "dady", &v->fbi.dady); new bx_shadow_num_c(fbi, "dzdy", &v->fbi.dzdy); new bx_shadow_num_c(fbi, "dwdy", &v->fbi.dwdy); + new bx_shadow_num_c(fbi, "sverts", &v->fbi.sverts); + bx_list_c *svert = new bx_list_c(fbi, "svert", ""); + for (i = 0; i < 3; i++) { + sprintf(name, "%d", i); + bx_list_c *num = new bx_list_c(svert, name, ""); + new bx_shadow_num_c(num, "x", &v->fbi.svert[i].x); + new bx_shadow_num_c(num, "y", &v->fbi.svert[i].y); + new bx_shadow_num_c(num, "a", &v->fbi.svert[i].a); + new bx_shadow_num_c(num, "r", &v->fbi.svert[i].r); + new bx_shadow_num_c(num, "g", &v->fbi.svert[i].g); + new bx_shadow_num_c(num, "b", &v->fbi.svert[i].b); + new bx_shadow_num_c(num, "z", &v->fbi.svert[i].z); + new bx_shadow_num_c(num, "wb", &v->fbi.svert[i].wb); + new bx_shadow_num_c(num, "w0", &v->fbi.svert[i].w0); + new bx_shadow_num_c(num, "s0", &v->fbi.svert[i].s0); + new bx_shadow_num_c(num, "t0", &v->fbi.svert[i].t0); + new bx_shadow_num_c(num, "w1", &v->fbi.svert[i].w1); + new bx_shadow_num_c(num, "s1", &v->fbi.svert[i].s1); + new bx_shadow_num_c(num, "t1", &v->fbi.svert[i].t1); + } bx_list_c *cmdfifo = new bx_list_c(fbi, "cmdfifo", ""); for (i = 0; i < 2; i++) { sprintf(name, "%d", i); diff --git a/bochs/iodev/display/voodoo_func.h b/bochs/iodev/display/voodoo_func.h index 0945ded24..40e3d8c44 100644 --- a/bochs/iodev/display/voodoo_func.h +++ b/bochs/iodev/display/voodoo_func.h @@ -1423,6 +1423,53 @@ void recompute_video_memory(voodoo_state *v) } } + +void voodoo_bitblt(void) +{ + Bit8u command = (Bit8u)(v->reg[bltCommand].u & 0x07); + Bit16u c, cols, dst_x, dst_y, fgcolor, r, rows, size; + Bit32u offset, loffset; + + switch (command) { + case 0: + BX_ERROR(("Screen-to-Screen bitBLT not implemented yet")); + break; + case 1: + BX_ERROR(("CPU-to-Screen bitBLT not implemented yet")); + break; + case 2: + BX_ERROR(("bitBLT Rectangle fill not implemented yet")); + break; + case 3: + dst_x = (Bit16u)(v->reg[bltDstXY].u & 0x7ff); + dst_y = (Bit16u)((v->reg[bltDstXY].u >> 16) & 0x7ff); + cols = (Bit16u)(v->reg[bltSize].u & 0x1ff); + rows = (Bit16u)((v->reg[bltSize].u >> 16) & 0x1ff); + fgcolor = (Bit16u)(v->reg[bltColor].u & 0xffff); + loffset = (4 << v->fbi.lfb_stride); + for (r = 0; r <= rows; r++) { + offset = dst_y * loffset; + if (r == 0) { + offset += dst_x * 2; + size = loffset / 2 - dst_x; + } else if (r == rows) { + size = cols; + } else { + size = loffset / 2; + } + for (c = 0; c < size; c++) { + v->fbi.ram[offset + c * 2] = (Bit8u)(fgcolor & 0xff); + v->fbi.ram[offset + c * 2 + 1] = (Bit8u)(fgcolor >> 8); + } + dst_y++; + } + break; + default: + BX_ERROR(("Voodoo bitBLT: unknown command %d)", command)); + } +} + + void dacdata_w(dac_state *d, Bit8u regnum, Bit8u data) { d->reg[regnum] = data; @@ -1933,24 +1980,20 @@ void register_w(Bit32u offset, Bit32u data, bx_bool log) break; case userIntrCMD: - case bltSrcBaseAddr: - case bltDstBaseAddr: - case bltXYStrides: - case bltSrcChromaRange: - case bltDstChromaRange: - case bltClipX: - case bltClipY: - case bltSrcXY: - case bltDstXY: - case bltSize: - case bltRop: - case bltColor: - case bltCommand: case bltData: BX_ERROR(("Writing to register %s not supported yet", v->regnames[regnum])); v->reg[regnum].u = data; break; + case bltDstXY: + case bltSize: + case bltCommand: + v->reg[regnum].u = data; + if ((data >> 31) & 1) { + voodoo_bitblt(); + } + break; + /* these registers are referenced in the renderer; we must wait for pending work before changing */ case chromaRange: case chromaKey: @@ -2461,7 +2504,7 @@ nextpixel: return 0; } -void cmdfifo_put(Bit32u fbi_offset, Bit32u data) +void cmdfifo_w(Bit32u fbi_offset, Bit32u data) { BX_LOCK(cmdfifo_mutex); *(Bit32u*)(&v->fbi.ram[fbi_offset]) = data; @@ -2469,7 +2512,7 @@ void cmdfifo_put(Bit32u fbi_offset, Bit32u data) BX_UNLOCK(cmdfifo_mutex); } -Bit32u cmdfifo_get(void) +Bit32u cmdfifo_r(void) { Bit32u data; @@ -2493,7 +2536,7 @@ void cmdfifo_process(void) int i; setup_vertex svert = {0}; - command = cmdfifo_get(); + command = cmdfifo_r(); type = (Bit8u)(command & 0x07); switch (type) { case 0: @@ -2513,7 +2556,7 @@ void cmdfifo_process(void) regaddr = (command & 0x7ff8) >> 3; inc = (command >> 15) & 1; for (i = 0; i < (int)nwords; i++) { - data = cmdfifo_get(); + data = cmdfifo_r(); register_w(regaddr, data, 1); if (inc) regaddr++; } @@ -2524,7 +2567,7 @@ void cmdfifo_process(void) regaddr = bltSrcBaseAddr; while (mask) { if (mask & 1) { - data = cmdfifo_get(); + data = cmdfifo_r(); register_w(regaddr, data, 1); } regaddr++; @@ -2542,13 +2585,13 @@ void cmdfifo_process(void) v->reg[sSetupMode].u = ((smode << 16) | mask); /* loop over triangles */ for (i = 0; i < nvertex; i++) { - reg.u = cmdfifo_get(); + reg.u = cmdfifo_r(); svert.x = reg.f; - reg.u = cmdfifo_get(); + reg.u = cmdfifo_r(); svert.y = reg.f; if (pcolor) { if (mask & 0x03) { - data = cmdfifo_get(); + data = cmdfifo_r(); if (mask & 0x01) { svert.r = (float)RGB_RED(data); svert.g = (float)RGB_GREEN(data); @@ -2560,44 +2603,44 @@ void cmdfifo_process(void) } } else { if (mask & 0x01) { - reg.u = cmdfifo_get(); + reg.u = cmdfifo_r(); svert.r = reg.f; - reg.u = cmdfifo_get(); + reg.u = cmdfifo_r(); svert.g = reg.f; - reg.u = cmdfifo_get(); + reg.u = cmdfifo_r(); svert.b = reg.f; } if (mask & 0x02) { - reg.u = cmdfifo_get(); + reg.u = cmdfifo_r(); svert.a = reg.f; } } if (mask & 0x04) { - reg.u = cmdfifo_get(); + reg.u = cmdfifo_r(); svert.z = reg.f; } if (mask & 0x08) { - reg.u = cmdfifo_get(); + reg.u = cmdfifo_r(); svert.wb = reg.f; } if (mask & 0x10) { - reg.u = cmdfifo_get(); + reg.u = cmdfifo_r(); svert.w0 = reg.f; } if (mask & 0x20) { - reg.u = cmdfifo_get(); + reg.u = cmdfifo_r(); svert.s0 = reg.f; - reg.u = cmdfifo_get(); + reg.u = cmdfifo_r(); svert.t0 = reg.f; } if (mask & 0x40) { - reg.u = cmdfifo_get(); + reg.u = cmdfifo_r(); svert.w1 = reg.f; } if (mask & 0x80) { - reg.u = cmdfifo_get(); + reg.u = cmdfifo_r(); svert.s1 = reg.f; - reg.u = cmdfifo_get(); + reg.u = cmdfifo_r(); svert.t1 = reg.f; } /* if we're starting a new strip, or if this is the first of a set of verts */ @@ -2619,7 +2662,7 @@ void cmdfifo_process(void) setup_and_draw_triangle(v); } } - while (nwords--) cmdfifo_get(); + while (nwords--) cmdfifo_r(); break; case 4: nwords = (command >> 29); @@ -2627,32 +2670,32 @@ void cmdfifo_process(void) regaddr = (command & 0x7ff8) >> 3; while (mask) { if (mask & 1) { - data = cmdfifo_get(); + data = cmdfifo_r(); register_w(regaddr, data, 1); } regaddr++; mask >>= 1; } - while (nwords--) cmdfifo_get(); + while (nwords--) cmdfifo_r(); break; case 5: if ((command & 0x3fc00000) > 0) { BX_ERROR(("CMDFIFO packet type 5: byte disable not supported yet")); } nwords = (command >> 3) & 0x7ffff; - regaddr = (cmdfifo_get() & 0xffffff) >> 2; + regaddr = (cmdfifo_r() & 0xffffff) >> 2; code = (command >> 30); switch (code) { case 2: for (i = 0; i < (int)nwords; i++) { - data = cmdfifo_get(); + data = cmdfifo_r(); lfb_w(regaddr, data, 0xffffffff); regaddr++; } break; case 3: for (i = 0; i < (int)nwords; i++) { - data = cmdfifo_get(); + data = cmdfifo_r(); texture_w(regaddr, data); regaddr++; } @@ -2666,13 +2709,11 @@ void cmdfifo_process(void) } } -voodoo_reg reg; void register_w_common(Bit32u offset, Bit32u data) { Bit32u regnum = (offset) & 0xff; Bit32u chips = (offset>>8) & 0xf; - reg.u = data; /* Voodoo 2 CMDFIFO handling */ if (FBIINIT7_CMDFIFO_ENABLE(v->reg[fbiInit7].u)) { @@ -2682,7 +2723,7 @@ void register_w_common(Bit32u offset, Bit32u data) } else { Bit32u fbi_offset = (v->fbi.cmdfifo[0].base + ((offset & 0xffff) << 2)) & v->fbi.mask; if (LOG_CMDFIFO) BX_DEBUG(("CMDFIFO write: FBI offset=0x%08x, data=0x%08x", fbi_offset, data)); - cmdfifo_put(fbi_offset, data); + cmdfifo_w(fbi_offset, data); } return; } else { @@ -2798,14 +2839,10 @@ void register_w_common(Bit32u offset, Bit32u data) case fbiInit4: case fbiInit5: case fbiInit6: - case fbiInit7: poly_wait(v->poly, v->regnames[regnum]); if (v->type <= VOODOO_2 && (chips & 1) && INITEN_ENABLE_HW_INIT(v->pci.init_enable)) { - if ((v->type == VOODOO_2) && (regnum == fbiInit7)) { - v->fbi.cmdfifo[0].enable = FBIINIT7_CMDFIFO_ENABLE(data); - } v->reg[regnum].u = data; recompute_video_memory(v); v->fbi.video_changed = 1; @@ -2823,6 +2860,19 @@ void register_w_common(Bit32u offset, Bit32u data) } break; + case fbiInit7: + poly_wait(v->poly, v->regnames[regnum]); + + if (v->type == VOODOO_2 && (chips & 1) && INITEN_ENABLE_HW_INIT(v->pci.init_enable)) + { + if (v->fbi.cmdfifo[0].enable != FBIINIT7_CMDFIFO_ENABLE(data)) { + v->fbi.cmdfifo[0].enable = FBIINIT7_CMDFIFO_ENABLE(data); + BX_INFO(("CMDFIFO now %sabled", v->fbi.cmdfifo[0].enable ? "en" : "dis")); + } + v->reg[regnum].u = data; + } + break; + case cmdFifoBaseAddr: BX_LOCK(cmdfifo_mutex); v->fbi.cmdfifo[0].base = (data & 0x3ff) << 12; @@ -2859,6 +2909,7 @@ void register_w_common(Bit32u offset, Bit32u data) } } + Bit32u register_r(Bit32u offset) { Bit32u regnum = (offset) & 0xff;