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:
parent
dd694757f4
commit
df6246601e
@ -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);
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user