From 6265976a2c883905c33e2a3db41d581b2286f016 Mon Sep 17 00:00:00 2001 From: Volker Ruppert Date: Sun, 14 May 2017 15:53:29 +0000 Subject: [PATCH] Some work on the Voodoo2 CMDFIFO support. - Added CMDFIFO thread similar to the sound output thread. - split register write function in 2 functions: register_w_common() handles the CMDFIFO writes and valid registers in CMDFIFO mode. It forwards write accesses to other registers to register_w() (Voodoo1 and non-CMDFIFO mode). The CMDFIFO thread also calls register_w() when processing data. - The CMDFIFO thread processes all data, but it does not yet execute type 3 requests (extended triangle generator missing). - TODO #1: implement Voodoo2 specific triangle functions (for CMDFIFO). - TODO #2: implement 2D bitblt engine. --- bochs/iodev/display/voodoo.cc | 32 ++ bochs/iodev/display/voodoo_data.h | 2 +- bochs/iodev/display/voodoo_func.h | 566 +++++++++++++++++++++--------- 3 files changed, 426 insertions(+), 174 deletions(-) diff --git a/bochs/iodev/display/voodoo.cc b/bochs/iodev/display/voodoo.cc index d4d9fedc5..657cdc62a 100644 --- a/bochs/iodev/display/voodoo.cc +++ b/bochs/iodev/display/voodoo.cc @@ -75,6 +75,10 @@ bx_voodoo_c* theVoodooDevice = NULL; +#ifndef WIN32 +#include +#endif + #include "voodoo_types.h" #include "voodoo_data.h" #include "voodoo_main.h" @@ -154,6 +158,22 @@ void CDECL libvoodoo_LTX_plugin_fini(void) delete theVoodooDevice; } +// cmdfifo thread (Voodoo2) + +BX_THREAD_FUNC(cmdfifo_thread, indata) +{ + UNUSED(indata); + cmdfifo_control = 1; + while (cmdfifo_control > 0) { + while ((cmdfifo_control > 0) && (v->fbi.cmdfifo[0].depth == 0)) { + BX_MSLEEP(1); + } + cmdfifo_process(); + } + cmdfifo_control = -1; + BX_THREAD_EXIT; +} + // the device object bx_voodoo_c::bx_voodoo_c() @@ -166,6 +186,13 @@ bx_voodoo_c::bx_voodoo_c() bx_voodoo_c::~bx_voodoo_c() { + if (cmdfifo_control > 0) { + cmdfifo_control = 0; + while (cmdfifo_control >= 0) { + BX_MSLEEP(1); + } + BX_FINI_MUTEX(cmdfifo_mutex); + } if (v != NULL) { free(v->fbi.ram); free(v->tmu[0].ram); @@ -220,6 +247,11 @@ void bx_voodoo_c::init(void) voodoo_init(BX_VOODOO_THIS s.model); + if (BX_VOODOO_THIS s.model == VOODOO_2) { + BX_INIT_MUTEX(cmdfifo_mutex); + BX_THREAD_CREATE(cmdfifo_thread, this, cmdfifo_threadID); + } + BX_INFO(("3dfx Voodoo Graphics adapter (model=%s) initialized", SIM->get_param_enum("model", base)->get_selected())); } diff --git a/bochs/iodev/display/voodoo_data.h b/bochs/iodev/display/voodoo_data.h index ffd7430a0..faf894bf9 100644 --- a/bochs/iodev/display/voodoo_data.h +++ b/bochs/iodev/display/voodoo_data.h @@ -1610,7 +1610,7 @@ struct _fbi_state stats_block lfb_stats; /* LFB-access statistics */ Bit8u sverts; /* number of vertices ready */ - setup_vertex svert[3]; /* 3 setup vertices */ + setup_vertex svert[4]; /* 3 setup vertices + 1 for current data */ fifo_state fifo; /* framebuffer memory fifo */ cmdfifo_info cmdfifo[2]; /* command FIFOs */ diff --git a/bochs/iodev/display/voodoo_func.h b/bochs/iodev/display/voodoo_func.h index 95441d01f..c8ff7f646 100644 --- a/bochs/iodev/display/voodoo_func.h +++ b/bochs/iodev/display/voodoo_func.h @@ -60,6 +60,11 @@ Bit32u voodoo_last_msg = 255; #define MODIFY_PIXEL(VV) +/* cmdfifo thread (Voodoo2) */ +BX_THREAD_ID(cmdfifo_threadID); +int cmdfifo_control = 0; +BX_MUTEX(cmdfifo_mutex); + /* fast dither lookup */ static Bit8u dither4_lookup[256*16*2]; static Bit8u dither2_lookup[256*16*2]; @@ -1303,57 +1308,17 @@ void dacdata_r(dac_state *d, Bit8u regnum) d->read_result = result; } -void cmdfifo_put(Bit32u fbi_offset, Bit32u data) -{ - BX_ERROR(("Writing to CMDFIFO has no effect yet: FBI offset=0x%08x, data=0x%08x", - fbi_offset, data)); - *(Bit32u*)&v->fbi.ram[fbi_offset] = data; - v->fbi.cmdfifo[0].depth++; -} - -voodoo_reg reg; - -void register_w(Bit32u offset, Bit32u data) +void register_w(Bit32u offset, Bit32u data, bx_bool log) { Bit32u regnum = (offset) & 0xff; Bit32u chips = (offset>>8) & 0xf; - reg.u = data; - Bit64s data64; - BX_DEBUG(("write chip 0x%x reg 0x%x value 0x%08x(%s)", chips, regnum<<2, data, voodoo_reg_name[regnum])); - voodoo_last_msg=regnum; - if (chips == 0) chips = 0xf; - /* the first 64 registers can be aliased differently */ - if ((offset & 0x800c0) == 0x80000 && v->alt_regmap) - regnum = register_alias_map[offset & 0x3f]; - else - regnum = offset & 0xff; - - /* first make sure this register is writable */ - if (!(v->regaccess[regnum] & REGISTER_WRITE)) { - BX_DEBUG(("Invalid attempt to write %s", v->regnames[regnum])); - return; - } - if (FBIINIT7_CMDFIFO_ENABLE(v->reg[fbiInit7].u)) { - if (!FBIINIT7_CMDFIFO_MEMORY_STORE(v->reg[fbiInit7].u)) { - BX_ERROR(("CMDFIFO-to-FIFO mode not supported yet")); - } else if ((offset & 0x80000) > 0) { - Bit32u fbi_offset = (v->fbi.cmdfifo[0].base + ((offset & 0xffff) << 2)) & v->fbi.mask; - cmdfifo_put(fbi_offset, data); - return; - } else { - if (v->regaccess[regnum] & REGISTER_WRITETHRU) { - BX_DEBUG(("Writing to register %s in CMDFIFO mode", v->regnames[regnum])); - } else { - BX_DEBUG(("Invalid attempt to write %s in CMDFIFO mode", v->regnames[regnum])); - return; - } - } - } + if (log) + BX_DEBUG(("write chip 0x%x reg 0x%x value 0x%08x(%s)", chips, regnum<<2, data, voodoo_reg_name[regnum])); switch (regnum) { /* Vertex data is 12.4 formatted fixed point */ @@ -1663,113 +1628,6 @@ void register_w(Bit32u offset, Bit32u data) BX_DEBUG(("clutData ignored because video timing reset = 1")); } break; - /* external DAC access -- Voodoo/Voodoo2 only */ - case dacData: - if (v->type <= VOODOO_2 /*&& (chips & 1)*/) - { - poly_wait(v->poly, v->regnames[regnum]); - if (!(data & 0x800)) - dacdata_w(&v->dac, (data >> 8) & 7, data & 0xff); - else - dacdata_r(&v->dac, (data >> 8) & 7); - } - break; - - /* vertical sync rate -- Voodoo/Voodoo2 only */ - case hSync: - case vSync: - case backPorch: - case videoDimensions: - if (v->type <= VOODOO_2 && (chips & 1)) - { - poly_wait(v->poly, v->regnames[regnum]); - v->reg[regnum].u = data; - if (v->reg[hSync].u != 0 && v->reg[vSync].u != 0 && v->reg[videoDimensions].u != 0) - { - int htotal = ((v->reg[hSync].u >> 16) & 0x3ff) + 1 + (v->reg[hSync].u & 0xff) + 1; - int vtotal = ((v->reg[vSync].u >> 16) & 0xfff) + (v->reg[vSync].u & 0xfff); - int hvis = v->reg[videoDimensions].u & 0x3ff; - int vvis = (v->reg[videoDimensions].u >> 16) & 0x3ff; - int hbp = (v->reg[backPorch].u & 0xff) + 2; - int vbp = (v->reg[backPorch].u >> 16) & 0xff; - rectangle visarea; - - /* create a new visarea */ - visarea.min_x = hbp; - visarea.max_x = hbp + hvis - 1; - visarea.min_y = vbp; - visarea.max_y = vbp + vvis - 1; - - /* keep within bounds */ - visarea.max_x = MIN(visarea.max_x, htotal - 1); - visarea.max_y = MIN(visarea.max_y, vtotal - 1); - - BX_DEBUG(("hSync=%08X vSync=%08X backPorch=%08X videoDimensions=%08X", - v->reg[hSync].u, v->reg[vSync].u, v->reg[backPorch].u, v->reg[videoDimensions].u)); - BX_DEBUG(("Horiz: %d-%d (%d total) Vert: %d-%d (%d total) -- ", visarea.min_x, visarea.max_x, htotal, visarea.min_y, visarea.max_y, vtotal)); - - /* configure the new framebuffer info */ - v->fbi.width = hvis + 1; - v->fbi.height = vvis; - v->fbi.xoffs = hbp; - v->fbi.yoffs = vbp; - v->fbi.vsyncscan = (v->reg[vSync].u >> 16) & 0xfff; - - /* if changing dimensions, update video memory layout */ - if (regnum == videoDimensions) - recompute_video_memory(v); - - Voodoo_UpdateScreenStart(); - } - } - break; - - /* fbiInit0 can only be written if initEnable says we can -- Voodoo/Voodoo2 only */ - case fbiInit0: - poly_wait(v->poly, v->regnames[regnum]); - if (v->type <= VOODOO_2 && (chips & 1) && INITEN_ENABLE_HW_INIT(v->pci.init_enable)) { - Voodoo_Output_Enable(data & 1); - v->reg[fbiInit0].u = data; - if (FBIINIT0_GRAPHICS_RESET(data)) - soft_reset(v); - if (FBIINIT0_FIFO_RESET(data)) - fifo_reset(&v->pci.fifo); - recompute_video_memory(v); - } - break; - - /* fbiInitX can only be written if initEnable says we can -- Voodoo/Voodoo2 only */ - /* most of these affect memory layout, so always recompute that when done */ - case fbiInit1: - case fbiInit2: - 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; - } - break; - - case fbiInit3: - poly_wait(v->poly, v->regnames[regnum]); - if (v->type <= VOODOO_2 && (chips & 1) && INITEN_ENABLE_HW_INIT(v->pci.init_enable)) - { - v->reg[regnum].u = data; - v->alt_regmap = FBIINIT3_TRI_REGISTER_REMAP(data); - v->fbi.yorigin = FBIINIT3_YORIGIN_SUBTRACT(v->reg[fbiInit3].u); - recompute_video_memory(v); - } - break; - /* nccTable entries are processed and expanded immediately */ case nccTable+0: case nccTable+1: @@ -1876,32 +1734,23 @@ void register_w(Bit32u offset, Bit32u data) goto default_case; break; - case cmdFifoBaseAddr: - v->fbi.cmdfifo[0].base = (data & 0x3ff) << 12; - v->fbi.cmdfifo[0].end = ((data >> 16) & 0x3ff) << 12; - break; - - case cmdFifoRdPtr: - v->fbi.cmdfifo[0].rdptr = data; - break; - - case cmdFifoDepth: - v->fbi.cmdfifo[0].depth = data & 0xffff; - break; - - case cmdFifoAMin: - v->fbi.cmdfifo[0].amin = data; - break; - - case cmdFifoAMax: - v->fbi.cmdfifo[0].amax = data; - break; - - case intrCtrl: 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; /* these registers are referenced in the renderer; we must wait for pending work before changing */ @@ -2414,6 +2263,373 @@ nextpixel: return 0; } +void cmdfifo_put(Bit32u fbi_offset, Bit32u data) +{ + BX_LOCK(cmdfifo_mutex); + *(Bit32u*)(&v->fbi.ram[fbi_offset]) = data; + v->fbi.cmdfifo[0].depth++; + BX_UNLOCK(cmdfifo_mutex); +} + +Bit32u cmdfifo_get(void) +{ + Bit32u data; + + while ((cmdfifo_control > 0) && (v->fbi.cmdfifo[0].depth == 0)) { + BX_MSLEEP(1); + } + BX_LOCK(cmdfifo_mutex); + data = *(Bit32u*)(&v->fbi.ram[v->fbi.cmdfifo[0].rdptr & v->fbi.mask]); + v->fbi.cmdfifo[0].rdptr += 4; + v->fbi.cmdfifo[0].depth--; + BX_UNLOCK(cmdfifo_mutex); + return data; +} + +void cmdfifo_process(void) +{ + Bit32u data, mask, nwords, regaddr; + Bit8u type, code, nvertex, smode; + bx_bool inc, pcolor; + voodoo_reg reg; + + data = cmdfifo_get(); + type = (Bit8u)(data & 0x07); + switch (type) { + case 0: + code = (Bit8u)((data >> 3) & 0x07); + switch (code) { + case 0: // NOP + break; + case 3: // JMP + v->fbi.cmdfifo[0].rdptr = (data >> 4) & 0xfffffc; + break; + default: + BX_ERROR(("CMDFIFO packet type 0: unsupported code %d", code)); + } + break; + case 1: + nwords = (data >> 16); + regaddr = (data & 0x7ff8) >> 3; + inc = (data >> 15) & 1; + while (nwords--) { + data = cmdfifo_get(); + register_w(regaddr, data, 1); + if (inc) regaddr++; + } + break; + case 2: + BX_INFO(("CMDFIFO packet type 2: not tested yet")); + mask = (data >> 3); + regaddr = bltSrcBaseAddr; + while (mask) { + if (mask & 1) { + data = cmdfifo_get(); + register_w(regaddr, data, 1); + } + regaddr++; + mask >>= 1; + } + break; + case 3: + BX_ERROR(("CMDFIFO packet type 3: not implemented yet")); + nwords = (data >> 29); + pcolor = (data >> 28) & 1; + smode = (data >> 22) & 0x3f; + mask = (data >> 10) & 0xff; + nvertex = (data >> 6) & 0x0f; + code = (data >> 3) & 0x07; + register_w(sSetupMode, (smode << 16) | mask, 1); + // TODO + while (nvertex--) { + reg.u = cmdfifo_get(); + v->fbi.svert[3].x = reg.f; + reg.u = cmdfifo_get(); + v->fbi.svert[3].y = reg.f; + if (mask & 0x01) { + if (pcolor) { + data = cmdfifo_get(); + v->fbi.svert[3].b = (float)(data & 0xff); + v->fbi.svert[3].g = (float)((data >> 8) & 0xff); + v->fbi.svert[3].r = (float)((data >> 16) & 0xff); + v->fbi.svert[3].a = (float)((data >> 24) & 0xff); + } else { + reg.u = cmdfifo_get(); + v->fbi.svert[3].r = reg.f; + reg.u = cmdfifo_get(); + v->fbi.svert[3].g = reg.f; + reg.u = cmdfifo_get(); + v->fbi.svert[3].b = reg.f; + } + } + if ((mask & 0x02) && !pcolor) { + reg.u = cmdfifo_get(); + v->fbi.svert[3].a = reg.f; + } + if (mask & 0x04) { + reg.u = cmdfifo_get(); + v->fbi.svert[3].z = reg.f; + } + if (mask & 0x08) { + reg.u = cmdfifo_get(); + v->fbi.svert[3].wb = reg.f; + } + if (mask & 0x10) { + reg.u = cmdfifo_get(); + v->fbi.svert[3].w0 = reg.f; + } + if (mask & 0x20) { + reg.u = cmdfifo_get(); + v->fbi.svert[3].s0 = reg.f; + reg.u = cmdfifo_get(); + v->fbi.svert[3].t0 = reg.f; + } + if (mask & 0x40) { + reg.u = cmdfifo_get(); + v->fbi.svert[3].w1 = reg.f; + } + if (mask & 0x80) { + reg.u = cmdfifo_get(); + v->fbi.svert[3].s1 = reg.f; + reg.u = cmdfifo_get(); + v->fbi.svert[3].t1 = reg.f; + } + // TODO + } + while (nwords--) cmdfifo_get(); + break; + case 4: + nwords = (data >> 29); + mask = (data >> 15) & 0x3fff; + regaddr = (data & 0x7ff8) >> 3; + while (mask) { + if (mask & 1) { + data = cmdfifo_get(); + register_w(regaddr, data, 1); + } + regaddr++; + mask >>= 1; + } + while (nwords--) cmdfifo_get(); + break; + case 5: + if ((data & 0x3fc00000) > 0) { + BX_ERROR(("CMDFIFO packet type 5: byte disable not supported yet")); + } + nwords = (data >> 3) & 0x7ffff; + regaddr = (cmdfifo_get() & 0xffffff) >> 2; + code = (data >> 30); + switch (code) { + case 2: + while (nwords--) { + data = cmdfifo_get(); + lfb_w(regaddr, data, 0xffffffff); + regaddr++; + } + break; + case 3: + while (nwords--) { + data = cmdfifo_get(); + texture_w(regaddr, data); + regaddr++; + } + break; + default: + BX_ERROR(("CMDFIFO packet type 5: unsupported destination type %d", code)); + } + break; + default: + BX_ERROR(("CMDFIFO: unsupported packet type %d", type)); + } +} + +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)) { + if (!FBIINIT7_CMDFIFO_MEMORY_STORE(v->reg[fbiInit7].u)) { + BX_ERROR(("CMDFIFO-to-FIFO mode not supported yet")); + } else if ((offset & 0x80000) > 0) { + Bit32u fbi_offset = (v->fbi.cmdfifo[0].base + ((offset & 0xffff) << 2)) & v->fbi.mask; + BX_DEBUG(("CMDFIFO write: FBI offset=0x%08x, data=0x%08x", fbi_offset, data)); + cmdfifo_put(fbi_offset, data); + return; + } else { + if (v->regaccess[regnum] & REGISTER_WRITETHRU) { + BX_DEBUG(("Writing to register %s in CMDFIFO mode", v->regnames[regnum])); + } else { + BX_DEBUG(("Invalid attempt to write %s in CMDFIFO mode", v->regnames[regnum])); + return; + } + } + } + + if (chips == 0) + chips = 0xf; + + /* first make sure this register is writable */ + if (!(v->regaccess[regnum] & REGISTER_WRITE)) { + BX_DEBUG(("Invalid attempt to write %s", v->regnames[regnum])); + return; + } + /* the first 64 registers can be aliased differently */ + if ((offset & 0x800c0) == 0x80000 && v->alt_regmap) + regnum = register_alias_map[offset & 0x3f]; + else + regnum = offset & 0xff; + + BX_DEBUG(("write chip 0x%x reg 0x%x value 0x%08x(%s)", chips, regnum<<2, data, voodoo_reg_name[regnum])); + + switch (regnum) { + /* external DAC access -- Voodoo/Voodoo2 only */ + case dacData: + if (v->type <= VOODOO_2 /*&& (chips & 1)*/) + { + poly_wait(v->poly, v->regnames[regnum]); + if (!(data & 0x800)) + dacdata_w(&v->dac, (data >> 8) & 7, data & 0xff); + else + dacdata_r(&v->dac, (data >> 8) & 7); + } + break; + + /* vertical sync rate -- Voodoo/Voodoo2 only */ + case hSync: + case vSync: + case backPorch: + case videoDimensions: + if (v->type <= VOODOO_2 && (chips & 1)) + { + poly_wait(v->poly, v->regnames[regnum]); + v->reg[regnum].u = data; + if (v->reg[hSync].u != 0 && v->reg[vSync].u != 0 && v->reg[videoDimensions].u != 0) + { + int htotal = ((v->reg[hSync].u >> 16) & 0x3ff) + 1 + (v->reg[hSync].u & 0xff) + 1; + int vtotal = ((v->reg[vSync].u >> 16) & 0xfff) + (v->reg[vSync].u & 0xfff); + int hvis = v->reg[videoDimensions].u & 0x3ff; + int vvis = (v->reg[videoDimensions].u >> 16) & 0x3ff; + int hbp = (v->reg[backPorch].u & 0xff) + 2; + int vbp = (v->reg[backPorch].u >> 16) & 0xff; + rectangle visarea; + + /* create a new visarea */ + visarea.min_x = hbp; + visarea.max_x = hbp + hvis - 1; + visarea.min_y = vbp; + visarea.max_y = vbp + vvis - 1; + + /* keep within bounds */ + visarea.max_x = MIN(visarea.max_x, htotal - 1); + visarea.max_y = MIN(visarea.max_y, vtotal - 1); + + BX_DEBUG(("hSync=%08X vSync=%08X backPorch=%08X videoDimensions=%08X", + v->reg[hSync].u, v->reg[vSync].u, v->reg[backPorch].u, v->reg[videoDimensions].u)); + BX_DEBUG(("Horiz: %d-%d (%d total) Vert: %d-%d (%d total) -- ", visarea.min_x, visarea.max_x, htotal, visarea.min_y, visarea.max_y, vtotal)); + + /* configure the new framebuffer info */ + v->fbi.width = hvis + 1; + v->fbi.height = vvis; + v->fbi.xoffs = hbp; + v->fbi.yoffs = vbp; + v->fbi.vsyncscan = (v->reg[vSync].u >> 16) & 0xfff; + + /* if changing dimensions, update video memory layout */ + if (regnum == videoDimensions) + recompute_video_memory(v); + + Voodoo_UpdateScreenStart(); + } + } + break; + + /* fbiInit0 can only be written if initEnable says we can -- Voodoo/Voodoo2 only */ + case fbiInit0: + poly_wait(v->poly, v->regnames[regnum]); + if (v->type <= VOODOO_2 && (chips & 1) && INITEN_ENABLE_HW_INIT(v->pci.init_enable)) { + Voodoo_Output_Enable(data & 1); + v->reg[fbiInit0].u = data; + if (FBIINIT0_GRAPHICS_RESET(data)) + soft_reset(v); + if (FBIINIT0_FIFO_RESET(data)) + fifo_reset(&v->pci.fifo); + recompute_video_memory(v); + } + break; + + /* fbiInitX can only be written if initEnable says we can -- Voodoo/Voodoo2 only */ + /* most of these affect memory layout, so always recompute that when done */ + case fbiInit1: + case fbiInit2: + 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; + } + break; + + case fbiInit3: + poly_wait(v->poly, v->regnames[regnum]); + if (v->type <= VOODOO_2 && (chips & 1) && INITEN_ENABLE_HW_INIT(v->pci.init_enable)) + { + v->reg[regnum].u = data; + v->alt_regmap = FBIINIT3_TRI_REGISTER_REMAP(data); + v->fbi.yorigin = FBIINIT3_YORIGIN_SUBTRACT(v->reg[fbiInit3].u); + recompute_video_memory(v); + } + break; + + case cmdFifoBaseAddr: + BX_LOCK(cmdfifo_mutex); + v->fbi.cmdfifo[0].base = (data & 0x3ff) << 12; + v->fbi.cmdfifo[0].end = ((data >> 16) & 0x3ff) << 12; + BX_UNLOCK(cmdfifo_mutex); + break; + + case cmdFifoRdPtr: + BX_LOCK(cmdfifo_mutex); + v->fbi.cmdfifo[0].rdptr = data; + BX_UNLOCK(cmdfifo_mutex); + break; + + case cmdFifoDepth: + BX_LOCK(cmdfifo_mutex); + v->fbi.cmdfifo[0].depth = data & 0xffff; + BX_UNLOCK(cmdfifo_mutex); + break; + + case cmdFifoAMin: + v->fbi.cmdfifo[0].amin = data; + break; + + case cmdFifoAMax: + v->fbi.cmdfifo[0].amax = data; + break; + + case intrCtrl: + BX_ERROR(("Writing to register %s not supported yet", v->regnames[regnum])); + break; + + default: + register_w(offset, data, 0); + } +} + Bit32u register_r(Bit32u offset) { Bit32u regnum = (offset) & 0xff; @@ -2472,6 +2688,10 @@ Bit32u register_r(Bit32u offset) if (v->pci.op_pending) result |= 1 << 9; + if (v->type == VOODOO_2) { + if (v->fbi.cmdfifo[0].enable && v->fbi.cmdfifo[0].depth > 0) + result |= 7 << 7; + } /* Banshee is different starting here */ if (v->type < VOODOO_BANSHEE) { @@ -2627,7 +2847,7 @@ Bit32u lfb_r(Bit32u offset) void voodoo_w(Bit32u offset, Bit32u data, Bit32u mask) { if ((offset & (0xc00000/4)) == 0) - register_w(offset, data); + register_w_common(offset, data); else if (offset & (0x800000/4)) texture_w(offset, data); else