- optimize IPC FIFO;
This commit is contained in:
mtabachenko 2009-07-29 22:59:46 +00:00
parent 309cb2418a
commit 66b71553d0
4 changed files with 41 additions and 27 deletions

View File

@ -34,6 +34,13 @@
IPC_FIFO ipc_fifo[2]; // 0 - ARM9
// 1 - ARM7
u8 FORCEINLINE IPC_FIFOgetSize(u8 proc)
{
if (ipc_fifo[proc].head < ipc_fifo[proc].tail) return (ipc_fifo[proc].tail - ipc_fifo[proc].head);
if (ipc_fifo[proc].head > ipc_fifo[proc].tail) return (17 - (ipc_fifo[proc].head - ipc_fifo[proc].tail));
return 0;
}
void IPC_FIFOinit(u8 proc)
{
memset(&ipc_fifo[proc], 0, sizeof(IPC_FIFO));
@ -46,7 +53,7 @@ void IPC_FIFOsend(u8 proc, u32 val)
if (!(cnt_l & 0x8000)) return; // FIFO disabled
u8 proc_remote = proc ^ 1;
if (ipc_fifo[proc].tail > 15)
if (ipc_fifo[proc].size > 15)
{
cnt_l |= 0x4000;
T1WriteWord(MMU.MMU_MEM[proc][0x40], 0x184, cnt_l);
@ -61,8 +68,10 @@ void IPC_FIFOsend(u8 proc, u32 val)
cnt_l &= 0xBFFC; // clear send empty bit & full
cnt_r &= 0xBCFF; // set recv empty bit & full
ipc_fifo[proc].buf[ipc_fifo[proc].tail++] = val;
ipc_fifo[proc].size = IPC_FIFOgetSize(proc);
if (ipc_fifo[proc].tail > 15) ipc_fifo[proc].tail = 0;
if (ipc_fifo[proc].tail > 15)
if (ipc_fifo[proc].size > 15)
{
cnt_l |= 0x0002; // set send full bit
cnt_r |= 0x0200; // set recv full bit
@ -82,7 +91,7 @@ u32 IPC_FIFOrecv(u8 proc)
u32 val = 0;
if ( ipc_fifo[proc_remote].tail == 0 ) // remote FIFO error
if ( ipc_fifo[proc_remote].size == 0 ) // remote FIFO error
{
cnt_l |= 0x4000;
T1WriteWord(MMU.MMU_MEM[proc][0x40], 0x184, cnt_l);
@ -94,16 +103,15 @@ u32 IPC_FIFOrecv(u8 proc)
cnt_l &= 0xBCFF; // clear send full bit & empty
cnt_r &= 0xBFFC; // set recv full bit & empty
val = ipc_fifo[proc_remote].buf[0];
val = ipc_fifo[proc_remote].buf[ipc_fifo[proc_remote].head++];
if (ipc_fifo[proc_remote].head > 15) ipc_fifo[proc_remote].head = 0;
//LOG("IPC%s recv FIFO 0x%08X (l 0x%X, tail %02i) (r 0x%X, tail %02i)\n",
// proc?"7":"9", val, cnt_l, ipc_fifo[proc].tail, cnt_r, ipc_fifo[proc^1].tail);
ipc_fifo[proc_remote].tail--;
for (int i = 0; i < ipc_fifo[proc_remote].tail; i++)
ipc_fifo[proc_remote].buf[i] = ipc_fifo[proc_remote].buf[i+1];;
ipc_fifo[proc_remote].size = IPC_FIFOgetSize(proc_remote);
if ( ipc_fifo[proc_remote].tail == 0 ) // FIFO empty
if ( ipc_fifo[proc_remote].size == 0 ) // FIFO empty
{
cnt_l |= 0x0100;
cnt_r |= 0x0001;
@ -142,15 +150,15 @@ 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));
if (gxPIPE.head < gxPIPE.tail) return (gxPIPE.tail - gxPIPE.head);
if (gxPIPE.head > gxPIPE.tail) return (5 - (gxPIPE.head - 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));
if (gxFIFO.head < gxFIFO.tail) return (gxFIFO.tail - gxFIFO.head);
if (gxFIFO.head > gxFIFO.tail) return (257 - (gxFIFO.head - gxFIFO.tail));
return 0;
}
@ -164,7 +172,7 @@ void GFX_FIFOclear()
u32 gxstat = T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x600);
gxstat &= 0x0000FFFF;
gxFIFO.pos = 0;
gxFIFO.head = 0;
gxFIFO.tail = 0;
gxFIFO.size = 0;
gxstat |= 0x06000000;
@ -252,11 +260,11 @@ BOOL FORCEINLINE GFX_FIFOrecv(u8 *cmd, u32 *param)
}
gxstat &= 0xF000FFFF;
*cmd = gxFIFO.cmd[gxFIFO.pos];
*param = gxFIFO.param[gxFIFO.pos];
gxFIFO.pos++;
*cmd = gxFIFO.cmd[gxFIFO.head];
*param = gxFIFO.param[gxFIFO.head];
gxFIFO.head++;
gxFIFO.size = GFX_FIFOgetSize();
if (gxFIFO.pos > 256) gxFIFO.pos = 0;
if (gxFIFO.head > 256) gxFIFO.head = 0;
gxstat |= ((gxFIFO.size & 0x1FF) << 16);
@ -268,7 +276,7 @@ BOOL FORCEINLINE GFX_FIFOrecv(u8 *cmd, u32 *param)
#endif
}
if (gxFIFO.tail == gxFIFO.pos) // empty
if (gxFIFO.tail == gxFIFO.head) // empty
gxstat |= 0x04000000;
else
gxstat |= 0x08000000; // set busy flag
@ -286,11 +294,11 @@ BOOL GFX_PIPErecv(u8 *cmd, u32 *param)
if (gxPIPE.size > 0)
{
*cmd = gxPIPE.cmd[gxPIPE.pos];
*param = gxPIPE.param[gxPIPE.pos];
gxPIPE.pos++;
*cmd = gxPIPE.cmd[gxPIPE.head];
*param = gxPIPE.param[gxPIPE.head];
gxPIPE.head++;
gxPIPE.size = GFX_PIPEgetSize();
if (gxPIPE.pos > 4) gxPIPE.pos = 0;
if (gxPIPE.head > 4) gxPIPE.head = 0;
if (gxPIPE.size < 2)
{
@ -337,6 +345,7 @@ 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;
}

View File

@ -35,7 +35,9 @@ typedef struct
{
u32 buf[16];
u8 head;
u8 tail;
u8 size;
} IPC_FIFO;
extern IPC_FIFO ipc_fifo[2];
@ -50,7 +52,7 @@ typedef struct
u8 cmd[257];
u32 param[257];
u16 pos; // start position
u16 head; // start position
u16 tail; // tail
u16 size; // size FIFO buffer
} GFX_FIFO;
@ -60,7 +62,7 @@ typedef struct
u8 cmd[5];
u32 param[5];
u8 pos;
u8 head;
u8 tail;
u8 size;
} GFX_PIPE;
@ -70,7 +72,6 @@ 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);

View File

@ -2387,12 +2387,12 @@ SFORMAT SF_GFX3D[]={
{ "GLBT", 4, 1, &BTind},
{ "GLPT", 4, 1, &PTind},
{ "GLPC", 4, 4, PTcoords},
{ "GFPO", 4, 1, &gxFIFO.pos},
{ "GFHD", 4, 1, &gxFIFO.head},
{ "GFTA", 4, 1, &gxFIFO.tail},
{ "GFSZ", 4, 1, &gxFIFO.size},
{ "GFCM", 1, 257, &gxFIFO.cmd[0]},
{ "GFPM", 4, 257, &gxFIFO.param[0]},
{ "GPPO", 1, 1, &gxPIPE.pos},
{ "GPHD", 1, 1, &gxPIPE.head},
{ "GPTA", 1, 1, &gxPIPE.tail},
{ "GPSZ", 1, 1, &gxPIPE.size},
{ "GPCM", 1, 5, &gxPIPE.cmd[0]},

View File

@ -240,9 +240,13 @@ SFORMAT SF_MMU[]={
{ "MCHD", 4, 1, &MMU.CheckDMAs},
//fifos
{ "F0TH", 1, 1, &ipc_fifo[0].head},
{ "F0TL", 1, 1, &ipc_fifo[0].tail},
{ "F0SZ", 1, 1, &ipc_fifo[0].size},
{ "F0BF", 4, 16, ipc_fifo[0].buf},
{ "F1TH", 1, 1, &ipc_fifo[1].head},
{ "F1TL", 1, 1, &ipc_fifo[1].tail},
{ "F1SZ", 1, 1, &ipc_fifo[1].size},
{ "F1BF", 4, 16, ipc_fifo[1].buf},
{ "FDHD", 4, 1, &disp_fifo.head},