Some fixes for the Voodoo Banshee emulation.

- Always check if CMDFIFO is still enabled in the FIFO thread loop.
- Fixed offset for 3D register access (3D still not usable).
- Apply FBI mask when accessing memory in tiled desktop mode to avoid segfault.
- Added support for 16-bit writes to LFB.
- Don't access Voodoo2 CMDFIFO in Banshee mode.
- Set up the correct chipmask for Banshee (it has only one TMU).
- Fixed CMDFIFO enable message (using index #0 and #1).
This commit is contained in:
Volker Ruppert 2017-12-08 18:24:54 +00:00
parent dd694757f4
commit df6246601e
2 changed files with 22 additions and 13 deletions

View File

@ -230,11 +230,11 @@ BX_THREAD_FUNC(fifo_thread, indata)
BX_UNLOCK(fifo_mutex);
for (int i = 0; i < 2; i++) {
if (v->fbi.cmdfifo[i].enabled) {
BX_LOCK(cmdfifo_mutex);
while (v->fbi.cmdfifo[i].cmd_ready) {
while (v->fbi.cmdfifo[i].enabled && v->fbi.cmdfifo[i].cmd_ready) {
BX_LOCK(cmdfifo_mutex);
cmdfifo_process(&v->fbi.cmdfifo[i]);
BX_UNLOCK(cmdfifo_mutex);
}
BX_UNLOCK(cmdfifo_mutex);
}
}
}
@ -1671,7 +1671,7 @@ void bx_voodoo_c::banshee_mem_read(bx_phy_address addr, unsigned len, void *data
} else if (offset < 0x200000) {
value = banshee_blt_reg_read((offset >> 2) & 0x7f);
} else if (offset < 0x600000) {
value = register_r((offset & 0x1fffff) >> 2);
value = register_r((offset - 0x200000) >> 2);
} else if (offset < 0xc00000) {
BX_ERROR(("reserved read from offset 0x%08x", offset));
} else if (offset < 0x1000000) {
@ -1689,7 +1689,7 @@ void bx_voodoo_c::banshee_mem_read(bx_phy_address addr, unsigned len, void *data
pitch *= 128;
x = (offset << 0) & ((1 << v->fbi.lfb_stride) - 1);
y = (offset >> v->fbi.lfb_stride) & 0x7ff;
offset = start + y * pitch + x;
offset = (start + y * pitch + x) & v->fbi.mask;
}
value = 0;
for (i = 0; i < len; i++) {
@ -1706,6 +1706,7 @@ void bx_voodoo_c::banshee_mem_write(bx_phy_address addr, unsigned len, void *dat
{
Bit32u offset = (addr & 0x1ffffff);
Bit32u value = *(Bit32u*)data;
Bit32u mask = 0xffffffff;
Bit8u value8;
Bit32u start = v->banshee.io[io_vidDesktopStartAddr];
Bit32u pitch = v->banshee.io[io_vidDesktopOverlayStride] & 0x7fff;
@ -1719,7 +1720,7 @@ void bx_voodoo_c::banshee_mem_write(bx_phy_address addr, unsigned len, void *dat
} else if (offset < 0x200000) {
banshee_blt_reg_write((offset >> 2) & 0x7f, value);
} else if (offset < 0x600000) {
register_w_common((offset & 0x1fffff) >> 2, value);
register_w_common((offset - 0x200000) >> 2, value);
} else if (offset < 0x800000) {
texture_w((offset & 0x1fffff) >> 2, value);
} else if (offset < 0xc00000) {
@ -1729,7 +1730,14 @@ void bx_voodoo_c::banshee_mem_write(bx_phy_address addr, unsigned len, void *dat
} else {
Bit8u temp = v->fbi.lfb_stride;
v->fbi.lfb_stride = 11;
lfb_w((offset & 0xffffff) >> 2, value, 0xffffffff);
if (len == 2) {
if ((offset & 3) == 0) {
mask = 0x0000ffff;
} else {
mask = 0xffff0000;
}
}
lfb_w((offset & 0xffffff) >> 2, value, mask);
v->fbi.lfb_stride = temp;
}
} else if ((addr & ~0x1ffffff) == BX_VOODOO_THIS pci_base_address[1]) {
@ -1749,7 +1757,7 @@ void bx_voodoo_c::banshee_mem_write(bx_phy_address addr, unsigned len, void *dat
pitch *= 128;
x = (offset << 0) & ((1 << v->fbi.lfb_stride) - 1);
y = (offset >> v->fbi.lfb_stride) & 0x7ff;
offset = start + y * pitch + x;
offset = (start + y * pitch + x) & v->fbi.mask;
}
BX_LOCK(render_mutex);
for (i = 0; i < len; i++) {
@ -1838,7 +1846,7 @@ void bx_voodoo_c::banshee_agp_reg_write(Bit8u reg, Bit32u value)
v->fbi.cmdfifo[fifo_idx].count_holes = (((value >> 10) & 1) == 0);
if (v->fbi.cmdfifo[fifo_idx].enabled != ((value >> 8) & 1)) {
v->fbi.cmdfifo[fifo_idx].enabled = ((value >> 8) & 1);
BX_INFO(("CMDFIFO #%d now %sabled", fifo_idx + 1,
BX_INFO(("CMDFIFO #%d now %sabled", fifo_idx,
v->fbi.cmdfifo[fifo_idx].enabled ? "en" : "dis"));
}
BX_UNLOCK(cmdfifo_mutex);

View File

@ -2749,7 +2749,7 @@ void register_w_common(Bit32u offset, Bit32u data)
Bit32u chips = (offset>>8) & 0xf;
/* Voodoo 2 CMDFIFO handling */
if (v->fbi.cmdfifo[0].enabled) {
if ((v->type == VOODOO_2) && v->fbi.cmdfifo[0].enabled) {
if ((offset & 0x80000) > 0) {
if (!FBIINIT7_CMDFIFO_MEMORY_STORE(v->reg[fbiInit7].u)) {
BX_ERROR(("CMDFIFO-to-FIFO mode not supported yet"));
@ -3019,7 +3019,7 @@ Bit32u register_r(Bit32u offset)
BX_DEBUG(("Invalid attempt to read %s", v->regnames[regnum]));
return 0;
}
if (v->fbi.cmdfifo[0].enabled && ((offset & 0x80000) > 0)) {
if ((v->type == VOODOO_2) && v->fbi.cmdfifo[0].enabled && ((offset & 0x80000) > 0)) {
BX_DEBUG(("Invalid attempt to read from CMDFIFO"));
return 0;
}
@ -3061,7 +3061,7 @@ Bit32u register_r(Bit32u offset)
result |= 1 << 8;
/* bit 9 is overall busy */
if ((v->pci.op_pending) || (v->banshee.blt.busy))
if (v->pci.op_pending || v->banshee.blt.busy)
result |= 1 << 9;
if (v->type == VOODOO_2) {
@ -3401,6 +3401,7 @@ void voodoo_init(Bit8u _type)
v->reg[fbiInit3].u = (2 << 13) | (0xf << 17);
v->reg[fbiInit4].u = (1 << 0);
v->type = _type;
v->chipmask = 0x01 | 0x02 | 0x04 | 0x08;
switch (v->type) {
case VOODOO_1:
v->regaccess = voodoo_register_access;
@ -3421,9 +3422,9 @@ void voodoo_init(Bit8u _type)
v->regnames = banshee_reg_name;
v->alt_regmap = 1;
v->fbi.lfb_stride = 11;
v->chipmask = 0x01 | 0x02;
break;
}
v->chipmask = 0x01 | 0x02 | 0x04 | 0x08;
memset(v->dac.reg, 0, sizeof(v->dac.reg));
v->dac.read_result = 0;
v->dac.clk0_m = 0x37;