From 2212b9a47093cedda3d8986ec8e6036dddc9e0ad Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 15 Aug 2020 15:57:39 +0100 Subject: [PATCH] Implement out-of-order CMDFIFO handling on Banshee. --- src/vid_voodoo_banshee.c | 52 +++++++++++++++++++++++++++++++++++++--- src/vid_voodoo_common.h | 1 + 2 files changed, 50 insertions(+), 3 deletions(-) diff --git a/src/vid_voodoo_banshee.c b/src/vid_voodoo_banshee.c index ecdaa6b..796a42d 100644 --- a/src/vid_voodoo_banshee.c +++ b/src/vid_voodoo_banshee.c @@ -1403,10 +1403,56 @@ static void banshee_write_linear_l(uint32_t addr, uint32_t val, void *p) *(uint32_t *)&svga->vram[addr & svga->vram_mask] = val; if (addr >= voodoo->cmdfifo_base && addr < voodoo->cmdfifo_end) { -// pclog("CMDFIFO write %08x %08x %04x:%08x\n", addr, val, CS,cpu_state.pc); - voodoo->cmdfifo_depth_wr++; -// if ((voodoo->cmdfifo_depth_wr - voodoo->cmdfifo_depth_rd) < 20) +// pclog("CMDFIFO write %08x %08x old amin=%08x amax=%08x hlcnt=%i depth_wr=%i rp=%08x\n", addr, val, voodoo->cmdfifo_amin, voodoo->cmdfifo_amax, voodoo->cmdfifo_holecount, voodoo->cmdfifo_depth_wr, voodoo->cmdfifo_rp); + if (addr == voodoo->cmdfifo_base && !voodoo->cmdfifo_holecount) + { +// if (voodoo->cmdfifo_holecount) +// fatal("CMDFIFO reset pointers while outstanding holes\n"); + /*Reset pointers*/ + voodoo->cmdfifo_amin = voodoo->cmdfifo_base; + voodoo->cmdfifo_amax = voodoo->cmdfifo_base; + voodoo->cmdfifo_depth_wr++; voodoo_wake_fifo_thread(voodoo); + } + else if (voodoo->cmdfifo_holecount) + { +// if ((addr <= voodoo->cmdfifo_amin && voodoo->cmdfifo_amin != -4) || addr >= voodoo->cmdfifo_amax) +// fatal("CMDFIFO holecount write outside of amin/amax - amin=%08x amax=%08x holecount=%i\n", voodoo->cmdfifo_amin, voodoo->cmdfifo_amax, voodoo->cmdfifo_holecount); +// pclog("holecount %i\n", voodoo->cmdfifo_holecount); + voodoo->cmdfifo_holecount--; + if (!voodoo->cmdfifo_holecount) + { + int words_to_add = ((voodoo->cmdfifo_amax - voodoo->cmdfifo_amin) >> 2) + 1; + /*Filled in holes, resume normal operation*/ + voodoo->cmdfifo_depth_wr += ((voodoo->cmdfifo_amax - voodoo->cmdfifo_amin) >> 2); + voodoo->cmdfifo_amin = voodoo->cmdfifo_amax; + voodoo_wake_fifo_thread(voodoo); +// pclog("hole filled! amin=%08x amax=%08x added %i words\n", voodoo->cmdfifo_amin, voodoo->cmdfifo_amax, words_to_add); + } + } + else if (addr == voodoo->cmdfifo_amax+4) + { + /*In-order write*/ + voodoo->cmdfifo_amin = addr; + voodoo->cmdfifo_amax = addr; + voodoo->cmdfifo_depth_wr++; + voodoo_wake_fifo_thread(voodoo); + } + else + { + /*Out-of-order write*/ + if (addr < voodoo->cmdfifo_amin) + { + /*Reset back to start. Note that write is still out of order!*/ + voodoo->cmdfifo_amin = voodoo->cmdfifo_base-4; + + } +// else if (addr < voodoo->cmdfifo_amax) +// fatal("Out-of-order write really out of order\n"); + voodoo->cmdfifo_amax = addr; + voodoo->cmdfifo_holecount = ((voodoo->cmdfifo_amax - voodoo->cmdfifo_amin) >> 2) - 1; +// pclog("CMDFIFO out of order: amin=%08x amax=%08x holecount=%i\n", voodoo->cmdfifo_amin, voodoo->cmdfifo_amax, voodoo->cmdfifo_holecount); + } } } diff --git a/src/vid_voodoo_common.h b/src/vid_voodoo_common.h index 1c296c2..ee15c16 100644 --- a/src/vid_voodoo_common.h +++ b/src/vid_voodoo_common.h @@ -302,6 +302,7 @@ typedef struct voodoo_t int cmdfifo_rp; volatile int cmdfifo_depth_rd, cmdfifo_depth_wr; uint32_t cmdfifo_amin, cmdfifo_amax; + int cmdfifo_holecount; uint32_t sSetupMode; vert_t verts[4];