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:
parent
9a705a3369
commit
9912c99fd2
@ -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,
|
||||
|
@ -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();
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user