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.
This commit is contained in:
Volker Ruppert 2017-05-16 20:37:01 +00:00
parent 9a705a3369
commit 9912c99fd2
5 changed files with 151 additions and 53 deletions

View File

@ -2,7 +2,7 @@
// $Id$ // $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 // This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public // 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) // Double (floating point)
bx_shadow_num_c::bx_shadow_num_c(bx_param_c *parent, bx_shadow_num_c::bx_shadow_num_c(bx_param_c *parent,
const char *name, const char *name,

View File

@ -89,6 +89,7 @@ public:
#define BASE_DEC 10 #define BASE_DEC 10
#define BASE_HEX 16 #define BASE_HEX 16
#define BASE_FLOAT 32
#define BASE_DOUBLE 64 #define BASE_DOUBLE 64
class BOCHSAPI bx_param_c : public bx_object_c { class BOCHSAPI bx_param_c : public bx_object_c {
@ -190,6 +191,7 @@ protected:
Bit32s *p32bit; // used by bx_shadow_num_c Bit32s *p32bit; // used by bx_shadow_num_c
Bit16s *p16bit; // used by bx_shadow_num_c Bit16s *p16bit; // used by bx_shadow_num_c
Bit8s *p8bit; // 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 double *pdouble; // used by bx_shadow_num_c
bx_bool *pbool; // used by bx_shadow_bool_c bx_bool *pbool; // used by bx_shadow_bool_c
} val; } val;
@ -297,6 +299,9 @@ public:
bx_shadow_num_c(bx_param_c *parent, bx_shadow_num_c(bx_param_c *parent,
const char *name, const char *name,
double *ptr_to_real_val); 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 Bit64s get64();
virtual void set(Bit64s val); virtual void set(Bit64s val);
virtual void reset(); virtual void reset();

View File

@ -1205,7 +1205,8 @@ bx_bool bx_real_sim_c::restore_bochs_param(bx_list_c *root, const char *sr_path,
char *ptr; char *ptr;
int i, j, p; int i, j, p;
unsigned n; unsigned n;
double fvalue; float f1value;
double f2value;
Bit64u value; Bit64u value;
bx_param_c *param = NULL; bx_param_c *param = NULL;
FILE *fp, *fp2; 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()) { switch (param->get_type()) {
case BXT_PARAM_NUM: case BXT_PARAM_NUM:
if (((bx_param_num_c*)param)->get_base() == BASE_DOUBLE) { if (((bx_param_num_c*)param)->get_base() == BASE_DOUBLE) {
fvalue = strtod(ptr, NULL); f2value = strtod(ptr, NULL);
memcpy(&value, &fvalue, sizeof(double)); 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); ((bx_param_num_c*)param)->set(value);
} else if ((ptr[0] == '0') && (ptr[1] == 'x')) { } else if ((ptr[0] == '0') && (ptr[1] == 'x')) {
((bx_param_num_c*)param)->set(strtoull(ptr, NULL, 16)); ((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; int i, j;
Bit64s value; Bit64s value;
double fvalue; float f1value;
double f2value;
char pname[BX_PATHNAME_LEN], tmpstr[BX_PATHNAME_LEN]; char pname[BX_PATHNAME_LEN], tmpstr[BX_PATHNAME_LEN];
FILE *fp2; 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: case BXT_PARAM_NUM:
value = ((bx_param_num_c*)node)->get64(); value = ((bx_param_num_c*)node)->get64();
if (((bx_param_num_c*)node)->get_base() == BASE_DOUBLE) { if (((bx_param_num_c*)node)->get_base() == BASE_DOUBLE) {
memcpy(&fvalue, &value, sizeof(double)); memcpy(&f2value, &value, sizeof(double));
fprintf(fp, "%f\n", fvalue); 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) { } else if (((bx_param_num_c*)node)->get_base() == BASE_DEC) {
if (((bx_param_num_c*)node)->get_min() >= BX_MIN_BIT64U) { if (((bx_param_num_c*)node)->get_min() >= BX_MIN_BIT64U) {
if ((Bit64u)((bx_param_num_c*)node)->get_max() > BX_MAX_BIT32U) { if ((Bit64u)((bx_param_num_c*)node)->get_max() > BX_MAX_BIT32U) {

View File

@ -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, "dady", &v->fbi.dady);
new bx_shadow_num_c(fbi, "dzdy", &v->fbi.dzdy); 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, "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", ""); bx_list_c *cmdfifo = new bx_list_c(fbi, "cmdfifo", "");
for (i = 0; i < 2; i++) { for (i = 0; i < 2; i++) {
sprintf(name, "%d", i); sprintf(name, "%d", i);

View File

@ -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) void dacdata_w(dac_state *d, Bit8u regnum, Bit8u data)
{ {
d->reg[regnum] = data; d->reg[regnum] = data;
@ -1933,24 +1980,20 @@ void register_w(Bit32u offset, Bit32u data, bx_bool log)
break; break;
case userIntrCMD: 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: case bltData:
BX_ERROR(("Writing to register %s not supported yet", v->regnames[regnum])); BX_ERROR(("Writing to register %s not supported yet", v->regnames[regnum]));
v->reg[regnum].u = data; v->reg[regnum].u = data;
break; 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 */ /* these registers are referenced in the renderer; we must wait for pending work before changing */
case chromaRange: case chromaRange:
case chromaKey: case chromaKey:
@ -2461,7 +2504,7 @@ nextpixel:
return 0; return 0;
} }
void cmdfifo_put(Bit32u fbi_offset, Bit32u data) void cmdfifo_w(Bit32u fbi_offset, Bit32u data)
{ {
BX_LOCK(cmdfifo_mutex); BX_LOCK(cmdfifo_mutex);
*(Bit32u*)(&v->fbi.ram[fbi_offset]) = data; *(Bit32u*)(&v->fbi.ram[fbi_offset]) = data;
@ -2469,7 +2512,7 @@ void cmdfifo_put(Bit32u fbi_offset, Bit32u data)
BX_UNLOCK(cmdfifo_mutex); BX_UNLOCK(cmdfifo_mutex);
} }
Bit32u cmdfifo_get(void) Bit32u cmdfifo_r(void)
{ {
Bit32u data; Bit32u data;
@ -2493,7 +2536,7 @@ void cmdfifo_process(void)
int i; int i;
setup_vertex svert = {0}; setup_vertex svert = {0};
command = cmdfifo_get(); command = cmdfifo_r();
type = (Bit8u)(command & 0x07); type = (Bit8u)(command & 0x07);
switch (type) { switch (type) {
case 0: case 0:
@ -2513,7 +2556,7 @@ void cmdfifo_process(void)
regaddr = (command & 0x7ff8) >> 3; regaddr = (command & 0x7ff8) >> 3;
inc = (command >> 15) & 1; inc = (command >> 15) & 1;
for (i = 0; i < (int)nwords; i++) { for (i = 0; i < (int)nwords; i++) {
data = cmdfifo_get(); data = cmdfifo_r();
register_w(regaddr, data, 1); register_w(regaddr, data, 1);
if (inc) regaddr++; if (inc) regaddr++;
} }
@ -2524,7 +2567,7 @@ void cmdfifo_process(void)
regaddr = bltSrcBaseAddr; regaddr = bltSrcBaseAddr;
while (mask) { while (mask) {
if (mask & 1) { if (mask & 1) {
data = cmdfifo_get(); data = cmdfifo_r();
register_w(regaddr, data, 1); register_w(regaddr, data, 1);
} }
regaddr++; regaddr++;
@ -2542,13 +2585,13 @@ void cmdfifo_process(void)
v->reg[sSetupMode].u = ((smode << 16) | mask); v->reg[sSetupMode].u = ((smode << 16) | mask);
/* loop over triangles */ /* loop over triangles */
for (i = 0; i < nvertex; i++) { for (i = 0; i < nvertex; i++) {
reg.u = cmdfifo_get(); reg.u = cmdfifo_r();
svert.x = reg.f; svert.x = reg.f;
reg.u = cmdfifo_get(); reg.u = cmdfifo_r();
svert.y = reg.f; svert.y = reg.f;
if (pcolor) { if (pcolor) {
if (mask & 0x03) { if (mask & 0x03) {
data = cmdfifo_get(); data = cmdfifo_r();
if (mask & 0x01) { if (mask & 0x01) {
svert.r = (float)RGB_RED(data); svert.r = (float)RGB_RED(data);
svert.g = (float)RGB_GREEN(data); svert.g = (float)RGB_GREEN(data);
@ -2560,44 +2603,44 @@ void cmdfifo_process(void)
} }
} else { } else {
if (mask & 0x01) { if (mask & 0x01) {
reg.u = cmdfifo_get(); reg.u = cmdfifo_r();
svert.r = reg.f; svert.r = reg.f;
reg.u = cmdfifo_get(); reg.u = cmdfifo_r();
svert.g = reg.f; svert.g = reg.f;
reg.u = cmdfifo_get(); reg.u = cmdfifo_r();
svert.b = reg.f; svert.b = reg.f;
} }
if (mask & 0x02) { if (mask & 0x02) {
reg.u = cmdfifo_get(); reg.u = cmdfifo_r();
svert.a = reg.f; svert.a = reg.f;
} }
} }
if (mask & 0x04) { if (mask & 0x04) {
reg.u = cmdfifo_get(); reg.u = cmdfifo_r();
svert.z = reg.f; svert.z = reg.f;
} }
if (mask & 0x08) { if (mask & 0x08) {
reg.u = cmdfifo_get(); reg.u = cmdfifo_r();
svert.wb = reg.f; svert.wb = reg.f;
} }
if (mask & 0x10) { if (mask & 0x10) {
reg.u = cmdfifo_get(); reg.u = cmdfifo_r();
svert.w0 = reg.f; svert.w0 = reg.f;
} }
if (mask & 0x20) { if (mask & 0x20) {
reg.u = cmdfifo_get(); reg.u = cmdfifo_r();
svert.s0 = reg.f; svert.s0 = reg.f;
reg.u = cmdfifo_get(); reg.u = cmdfifo_r();
svert.t0 = reg.f; svert.t0 = reg.f;
} }
if (mask & 0x40) { if (mask & 0x40) {
reg.u = cmdfifo_get(); reg.u = cmdfifo_r();
svert.w1 = reg.f; svert.w1 = reg.f;
} }
if (mask & 0x80) { if (mask & 0x80) {
reg.u = cmdfifo_get(); reg.u = cmdfifo_r();
svert.s1 = reg.f; svert.s1 = reg.f;
reg.u = cmdfifo_get(); reg.u = cmdfifo_r();
svert.t1 = reg.f; svert.t1 = reg.f;
} }
/* if we're starting a new strip, or if this is the first of a set of verts */ /* 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); setup_and_draw_triangle(v);
} }
} }
while (nwords--) cmdfifo_get(); while (nwords--) cmdfifo_r();
break; break;
case 4: case 4:
nwords = (command >> 29); nwords = (command >> 29);
@ -2627,32 +2670,32 @@ void cmdfifo_process(void)
regaddr = (command & 0x7ff8) >> 3; regaddr = (command & 0x7ff8) >> 3;
while (mask) { while (mask) {
if (mask & 1) { if (mask & 1) {
data = cmdfifo_get(); data = cmdfifo_r();
register_w(regaddr, data, 1); register_w(regaddr, data, 1);
} }
regaddr++; regaddr++;
mask >>= 1; mask >>= 1;
} }
while (nwords--) cmdfifo_get(); while (nwords--) cmdfifo_r();
break; break;
case 5: case 5:
if ((command & 0x3fc00000) > 0) { if ((command & 0x3fc00000) > 0) {
BX_ERROR(("CMDFIFO packet type 5: byte disable not supported yet")); BX_ERROR(("CMDFIFO packet type 5: byte disable not supported yet"));
} }
nwords = (command >> 3) & 0x7ffff; nwords = (command >> 3) & 0x7ffff;
regaddr = (cmdfifo_get() & 0xffffff) >> 2; regaddr = (cmdfifo_r() & 0xffffff) >> 2;
code = (command >> 30); code = (command >> 30);
switch (code) { switch (code) {
case 2: case 2:
for (i = 0; i < (int)nwords; i++) { for (i = 0; i < (int)nwords; i++) {
data = cmdfifo_get(); data = cmdfifo_r();
lfb_w(regaddr, data, 0xffffffff); lfb_w(regaddr, data, 0xffffffff);
regaddr++; regaddr++;
} }
break; break;
case 3: case 3:
for (i = 0; i < (int)nwords; i++) { for (i = 0; i < (int)nwords; i++) {
data = cmdfifo_get(); data = cmdfifo_r();
texture_w(regaddr, data); texture_w(regaddr, data);
regaddr++; regaddr++;
} }
@ -2666,13 +2709,11 @@ void cmdfifo_process(void)
} }
} }
voodoo_reg reg;
void register_w_common(Bit32u offset, Bit32u data) void register_w_common(Bit32u offset, Bit32u data)
{ {
Bit32u regnum = (offset) & 0xff; Bit32u regnum = (offset) & 0xff;
Bit32u chips = (offset>>8) & 0xf; Bit32u chips = (offset>>8) & 0xf;
reg.u = data;
/* Voodoo 2 CMDFIFO handling */ /* Voodoo 2 CMDFIFO handling */
if (FBIINIT7_CMDFIFO_ENABLE(v->reg[fbiInit7].u)) { if (FBIINIT7_CMDFIFO_ENABLE(v->reg[fbiInit7].u)) {
@ -2682,7 +2723,7 @@ void register_w_common(Bit32u offset, Bit32u data)
} else { } else {
Bit32u fbi_offset = (v->fbi.cmdfifo[0].base + ((offset & 0xffff) << 2)) & v->fbi.mask; 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)); 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; return;
} else { } else {
@ -2798,14 +2839,10 @@ void register_w_common(Bit32u offset, Bit32u data)
case fbiInit4: case fbiInit4:
case fbiInit5: case fbiInit5:
case fbiInit6: case fbiInit6:
case fbiInit7:
poly_wait(v->poly, v->regnames[regnum]); 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 && (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; v->reg[regnum].u = data;
recompute_video_memory(v); recompute_video_memory(v);
v->fbi.video_changed = 1; v->fbi.video_changed = 1;
@ -2823,6 +2860,19 @@ void register_w_common(Bit32u offset, Bit32u data)
} }
break; 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: case cmdFifoBaseAddr:
BX_LOCK(cmdfifo_mutex); BX_LOCK(cmdfifo_mutex);
v->fbi.cmdfifo[0].base = (data & 0x3ff) << 12; 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 register_r(Bit32u offset)
{ {
Bit32u regnum = (offset) & 0xff; Bit32u regnum = (offset) & 0xff;