diff --git a/desmume/src/FIFO.cpp b/desmume/src/FIFO.cpp index 632ae7068..acf58898e 100644 --- a/desmume/src/FIFO.cpp +++ b/desmume/src/FIFO.cpp @@ -140,6 +140,20 @@ void IPC_FIFOcnt(u8 proc, u16 val) GFX_PIPE gxPIPE; GFX_FIFO gxFIFO; +u8 FORCEINLINE GFX_PIPEgetSize() +{ + if (gxPIPE.pos < gxPIPE.tail) return (gxPIPE.tail - gxPIPE.pos); + if (gxPIPE.pos > gxPIPE.tail) return (5 - (gxPIPE.pos - gxPIPE.tail)); + return 0; +} + +u16 FORCEINLINE GFX_FIFOgetSize() +{ + if (gxFIFO.pos < gxFIFO.tail) return (gxFIFO.tail - gxFIFO.pos); + if (gxFIFO.pos > gxFIFO.tail) return (257 - (gxFIFO.pos - gxFIFO.tail)); + return 0; +} + void GFX_PIPEclear() { gxPIPE.tail = 0; @@ -150,7 +164,9 @@ void GFX_FIFOclear() u32 gxstat = T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x600); gxstat &= 0x0000FFFF; + gxFIFO.pos = 0; gxFIFO.tail = 0; + gxFIFO.size = 0; gxstat |= 0x06000000; T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x600, gxstat); } @@ -159,14 +175,15 @@ void GFX_FIFOsend(u8 cmd, u32 param) { u32 gxstat = T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x600); - if (gxFIFO.tail == 0) // FIFO empty + if (gxFIFO.size == 0) // FIFO empty { - - if (gxPIPE.tail < 4) // pipe not full + if (gxPIPE.size < 4) // pipe not full { gxPIPE.cmd[gxPIPE.tail] = cmd; gxPIPE.param[gxPIPE.tail] = param; gxPIPE.tail++; + gxPIPE.size = GFX_PIPEgetSize(); + if (gxPIPE.tail > 4) gxPIPE.tail = 0; #ifdef USE_GEOMETRY_FIFO_EMULATION gxstat |= 0x08000000; // set busy flag T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x600, gxstat); @@ -175,6 +192,7 @@ void GFX_FIFOsend(u8 cmd, u32 param) return; } } + //INFO("GFX FIFO: Send GFX 3D cmd 0x%02X to FIFO - 0x%08X (%03i/%02X)\n", cmd, param, gxFIFO.tail, gxFIFO.tail); if (gxstat & 0x01000000) { @@ -187,15 +205,20 @@ void GFX_FIFOsend(u8 cmd, u32 param) gxFIFO.cmd[gxFIFO.tail] = cmd; gxFIFO.param[gxFIFO.tail] = param; gxFIFO.tail++; + gxFIFO.size = GFX_FIFOgetSize(); + if (gxFIFO.tail > 256) gxFIFO.tail = 0; + #ifdef USE_GEOMETRY_FIFO_EMULATION gxstat |= 0x08000000; // set busy flag #endif - gxstat |= (gxFIFO.tail << 16); + gxstat |= ((gxFIFO.size & 0x1FF) << 16); - if (gxFIFO.tail < 128) + if (gxFIFO.size < 128) // less half + { gxstat |= 0x02000000; + } #ifndef USE_GEOMETRY_FIFO_EMULATION gxstat |= 0x02000000; // this is hack (must be removed later) @@ -211,7 +234,7 @@ BOOL FORCEINLINE GFX_FIFOrecv(u8 *cmd, u32 *param) { u32 gxstat = T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x600); - if (gxFIFO.tail == 0) // empty + if (gxFIFO.size == 0) // empty { gxstat &= 0xF000FFFF; gxstat |= 0x06000000; @@ -229,18 +252,15 @@ BOOL FORCEINLINE GFX_FIFOrecv(u8 *cmd, u32 *param) } gxstat &= 0xF000FFFF; - *cmd = gxFIFO.cmd[0]; - *param = gxFIFO.param[0]; - gxFIFO.tail--; - for (int i=0; i < gxFIFO.tail; i++) - { - gxFIFO.cmd[i] = gxFIFO.cmd[i+1]; - gxFIFO.param[i] = gxFIFO.param[i+1]; - } + *cmd = gxFIFO.cmd[gxFIFO.pos]; + *param = gxFIFO.param[gxFIFO.pos]; + gxFIFO.pos++; + gxFIFO.size = GFX_FIFOgetSize(); + if (gxFIFO.pos > 256) gxFIFO.pos = 0; - gxstat |= (gxFIFO.tail << 16); + gxstat |= ((gxFIFO.size & 0x1FF) << 16); - if (gxFIFO.tail < 128) + if (gxFIFO.size < 128) { gxstat |= 0x02000000; #ifdef USE_GEOMETRY_FIFO_EMULATION @@ -248,7 +268,7 @@ BOOL FORCEINLINE GFX_FIFOrecv(u8 *cmd, u32 *param) #endif } - if (gxFIFO.tail == 0) // empty + if (gxFIFO.tail == gxFIFO.pos) // empty gxstat |= 0x04000000; else gxstat |= 0x08000000; // set busy flag @@ -264,36 +284,36 @@ BOOL GFX_PIPErecv(u8 *cmd, u32 *param) u32 tmp_param = 0; u32 gxstat = 0; - if (gxPIPE.tail > 0) + if (gxPIPE.size > 0) { - *cmd = gxPIPE.cmd[0]; - *param = gxPIPE.param[0]; - gxPIPE.tail--; - for (int i=0; i < gxPIPE.tail; i++) - { - gxPIPE.cmd[i] = gxPIPE.cmd[i+1]; - gxPIPE.param[i] = gxPIPE.param[i+1]; - } + *cmd = gxPIPE.cmd[gxPIPE.pos]; + *param = gxPIPE.param[gxPIPE.pos]; + gxPIPE.pos++; + gxPIPE.size = GFX_PIPEgetSize(); + if (gxPIPE.pos > 4) gxPIPE.pos = 0; - if (gxPIPE.tail < 2) + if (gxPIPE.size < 2) { if (GFX_FIFOrecv(&tmp_cmd, &tmp_param)) { gxPIPE.cmd[gxPIPE.tail] = tmp_cmd; gxPIPE.param[gxPIPE.tail] = tmp_param; gxPIPE.tail++; - + gxPIPE.size = GFX_PIPEgetSize(); + if (gxPIPE.tail > 4) gxPIPE.tail = 0; if (GFX_FIFOrecv(&tmp_cmd, &tmp_param)) { gxPIPE.cmd[gxPIPE.tail] = tmp_cmd; gxPIPE.param[gxPIPE.tail] = tmp_param; gxPIPE.tail++; + gxPIPE.size = GFX_PIPEgetSize(); + if (gxPIPE.tail > 4) gxPIPE.tail = 0; } } } - if (gxPIPE.tail == 0) + if (gxPIPE.size == 0) { gxstat = T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x600); gxstat &= 0xF7FFFFFF; // clear busy flag @@ -317,7 +337,6 @@ void GFX_FIFOcnt(u32 val) //INFO("GFX FIFO: write context 0x%08X (prev 0x%08X) tail %i\n", val, gxstat, gxFIFO.tail); if (val & (1<<29)) // clear? (homebrew) { - GFX_PIPEclear(); GFX_FIFOclear(); return; } diff --git a/desmume/src/FIFO.h b/desmume/src/FIFO.h index b7d8aebf4..997725acf 100644 --- a/desmume/src/FIFO.h +++ b/desmume/src/FIFO.h @@ -50,7 +50,9 @@ typedef struct u8 cmd[257]; u32 param[257]; + u16 pos; // start position u16 tail; // tail + u16 size; // size FIFO buffer } GFX_FIFO; typedef struct @@ -58,7 +60,9 @@ typedef struct u8 cmd[5]; u32 param[5]; + u8 pos; u8 tail; + u8 size; } GFX_PIPE; extern GFX_PIPE gxPIPE; @@ -66,6 +70,7 @@ extern GFX_FIFO gxFIFO; extern void GFX_PIPEclear(); extern void GFX_FIFOclear(); extern void GFX_FIFOsend(u8 cmd, u32 param); +extern BOOL GFX_FIFOrecv(u8 *cmd, u32 *param); extern BOOL GFX_PIPErecv(u8 *cmd, u32 *param); extern void GFX_FIFOcnt(u32 val); diff --git a/desmume/src/MMU.cpp b/desmume/src/MMU.cpp index 041f02131..59b70f993 100644 --- a/desmume/src/MMU.cpp +++ b/desmume/src/MMU.cpp @@ -1262,7 +1262,7 @@ void FASTCALL MMU_doDMA(u32 num) #ifdef USE_GEOMETRY_FIFO_EMULATION if (MMU.DMAStartTime[PROCNUM][num]== EDMAMode_GXFifo) { - if (gxFIFO.tail > 127) return; + if (gxFIFO.size > 127) return; } #endif @@ -1344,7 +1344,7 @@ void FASTCALL MMU_doDMA(u32 num) #ifdef USE_GEOMETRY_FIFO_EMULATION if (MMU.DMAStartTime[PROCNUM][num] == EDMAMode_GXFifo) { - if ( gxFIFO.tail > 255) + if ( gxFIFO.size > 255 ) { if (i >= taille) break; diff --git a/desmume/src/gfx3d.cpp b/desmume/src/gfx3d.cpp index 04aed3f7c..942306957 100644 --- a/desmume/src/gfx3d.cpp +++ b/desmume/src/gfx3d.cpp @@ -2387,10 +2387,14 @@ SFORMAT SF_GFX3D[]={ { "GLBT", 4, 1, &BTind}, { "GLPT", 4, 1, &PTind}, { "GLPC", 4, 4, PTcoords}, + { "GFPO", 4, 1, &gxFIFO.pos}, { "GFTA", 4, 1, &gxFIFO.tail}, + { "GFSZ", 4, 1, &gxFIFO.size}, { "GFCM", 1, 257, &gxFIFO.cmd[0]}, { "GFPM", 4, 257, &gxFIFO.param[0]}, - { "GPTA", 4, 1, &gxPIPE.tail}, + { "GPPO", 1, 1, &gxPIPE.pos}, + { "GPTA", 1, 1, &gxPIPE.tail}, + { "GPSZ", 1, 1, &gxPIPE.size}, { "GPCM", 1, 5, &gxPIPE.cmd[0]}, { "GPPM", 4, 5, &gxPIPE.param[0]}, { "GCOL", 1, 4, colorRGB},