diff --git a/desmume/src/FIFO.cpp b/desmume/src/FIFO.cpp index 613bb1945..8fe54f5cd 100644 --- a/desmume/src/FIFO.cpp +++ b/desmume/src/FIFO.cpp @@ -23,77 +23,144 @@ #include "FIFO.h" #include +#include "armcpu.h" #include "debug.h" +#include "mem.h" +#include "MMU.h" // ========================================================= IPC FIFO -void IPC_FIFOclear(IPC_FIFO * fifo) -{ - memset(fifo, 0, sizeof(IPC_FIFO)); +IPC_FIFO ipc_fifo; - fifo->empty = TRUE; +void IPC_FIFOclear() +{ + memset(&ipc_fifo, 0, sizeof(IPC_FIFO)); //LOG("FIFO is cleared\n"); } -void IPC_FIFOadd(IPC_FIFO * fifo, u32 val) + +void IPC_FIFOsend(u8 proc, u32 val) { - if (fifo->full) + //LOG("IPC%s send FIFO 0x%08X\n", proc?"7":"9", val); + u16 cnt_l = T1ReadWord(MMU.MMU_MEM[proc][0x40], 0x184); + if (!(cnt_l & 0x8000)) return; // FIFO disabled + u16 cnt_r = T1ReadWord(MMU.MMU_MEM[proc^1][0x40], 0x184); + + if (ipc_fifo.sendTail[proc] < 16) // last full == error { - //LOG("FIFO send is full\n"); - fifo->error = true; - return; + ipc_fifo.sendBuf[proc][ipc_fifo.sendTail[proc]] = val; + ipc_fifo.sendTail[proc]++; + if (ipc_fifo.sendTail[proc] == 16) cnt_l |= 0x02; // full + cnt_l &= 0xFFFE; + + if (ipc_fifo.recvTail[proc^1] < 16) // last full == error + { + ipc_fifo.recvBuf[proc^1][ipc_fifo.recvTail[proc^1]] = val; + ipc_fifo.recvTail[proc^1]++; + if (ipc_fifo.recvTail[proc^1] == 16) cnt_r |= 0x0200; // full + cnt_r &= 0xFEFF; + } + else + cnt_r |= 0x4200; } + else + cnt_l |= 0x4002; - //LOG("IPC FIFO add value 0x%08X in pos %i\n", val, fifo->size); + // save in mem + T1WriteWord(MMU.MMU_MEM[proc][0x40], 0x184, cnt_l); + T1WriteWord(MMU.MMU_MEM[proc^1][0x40], 0x184, cnt_r); - fifo->buf[fifo->size] = val; - fifo->size++; - if (fifo->size == 16) - fifo->full = TRUE; - fifo->empty = FALSE; + if ((cnt_r & (1<<10))) + NDS_makeInt(proc^1, 18); } -u32 IPC_FIFOget(IPC_FIFO * fifo) +u32 IPC_FIFOrecv(u8 proc) { - if (fifo->empty) - { - fifo->error = true; - //LOG("FIFO get is empty\n"); - return(0); - } + //LOG("IPC%s recv FIFO:\n", proc?"7":"9"); + u32 val = 0; + u16 cnt_l = T1ReadWord(MMU.MMU_MEM[proc][0x40], 0x184); + u16 cnt_r = T1ReadWord(MMU.MMU_MEM[proc^1][0x40], 0x184); - u32 val = fifo->buf[0]; - //LOG("IPC FIFO get value 0x%08X in pos %i\n", val, fifo->size); - for (int i = 0; i < fifo->size; i++) - fifo->buf[i] = fifo->buf[i+1]; - fifo->size--; - if (fifo->size == 0) - fifo->empty = TRUE; - return val; + if (ipc_fifo.recvTail[proc] > 0) // not empty + { + val = ipc_fifo.recvBuf[proc][0]; + for (int i = 0; i < ipc_fifo.recvTail[proc]; i++) + ipc_fifo.recvBuf[proc][i] = ipc_fifo.recvBuf[proc][i+1]; + ipc_fifo.recvTail[proc]--; + if (ipc_fifo.recvTail[proc] == 0) // empty + cnt_l |= 0x0100; + + // remove from head + for (int i = 0; i < ipc_fifo.sendTail[proc^1]; i++) + ipc_fifo.sendBuf[proc^1][i] = ipc_fifo.sendBuf[proc^1][i+1]; + ipc_fifo.sendTail[proc^1]--; + if (ipc_fifo.sendTail[proc^1] == 0) // empty + cnt_r |= 0x0001; + } + else + cnt_l |= 0x4100; + + T1WriteWord(MMU.MMU_MEM[proc][0x40], 0x184, cnt_l); + T1WriteWord(MMU.MMU_MEM[proc^1][0x40], 0x184, cnt_r); + + if ((cnt_l & (1<<3))) + NDS_makeInt(proc, 19); + return (val); +} + +void IPC_FIFOcnt(u8 proc, u16 val) +{ + //LOG("IPC%s FIFO context 0x%X\n", proc?"7":"9", val); + + u16 cnt_l = T1ReadWord(MMU.MMU_MEM[proc][0x40], 0x184); + + cnt_l &= ~0x8404; + cnt_l |= (val & 0x8404); + cnt_l &= (~(val & 0x4000)); + if (val & 0x0008) + { + IPC_FIFOclear(); + cnt_l |= 0x0101; + } + T1WriteWord(MMU.MMU_MEM[proc][0x40], 0x184, cnt_l); + + if ((cnt_l & 0x0004)) + NDS_makeInt(proc, 18); } // ========================================================= GFX FIFO -void GFX_FIFOclear(GFX_FIFO * fifo) -{ - memset(fifo, 0, sizeof(GFX_FIFO)); +GFX_FIFO gxFIFO; - fifo->empty = TRUE; - fifo->half = TRUE; +void GFX_FIFOclear() +{ + u32 gxstat = T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x600); + + memset(&gxFIFO, 0, sizeof(GFX_FIFO)); + + // TODO: irq handle + gxstat &= 0x0000FF00; + gxstat |= 0x00000002; // this is hack + gxstat |= 0x86000000; + T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x600, gxstat); } -void GFX_FIFOadd(GFX_FIFO * fifo) +void GFX_FIFOsend(u32 cmd, u32 param) { - if (fifo->full) + u32 gxstat = T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x600); + gxstat &= 0x0000FF00; + gxstat |= 0x00000002; // this is hack + + if (gxFIFO.tail < 260) { - //INFO("GFX FIFO send is full\n"); - fifo->error = true; - return; + gxFIFO.cmd[gxFIFO.tail] = cmd & 0xFF; + gxFIFO.param[gxFIFO.tail] = param; + gxFIFO.tail++; + // TODO: irq handle + if (gxFIFO.tail < 130) + gxstat |= 0x72000000; + if (gxFIFO.tail == 16) + gxstat |= 0x01000000; } + else + gxstat |= 0x01000000; - fifo->size++; - if (fifo->size > 127) - fifo->half = FALSE; - - if (fifo->size == 256) - fifo->full = TRUE; - fifo->empty = FALSE; + T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x600, gxstat); } - diff --git a/desmume/src/FIFO.h b/desmume/src/FIFO.h index 05ad2e9cc..663b917c3 100644 --- a/desmume/src/FIFO.h +++ b/desmume/src/FIFO.h @@ -29,38 +29,31 @@ //=================================================== IPC FIFO typedef struct { - u32 buf[16]; // 64K - u8 size; // tail - - BOOL empty; - BOOL full; - BOOL error; + u32 sendBuf[2][16]; + u32 recvBuf[2][16]; + + u8 sendTail[2]; + u8 recvTail[2]; } IPC_FIFO; -extern void IPC_FIFOclear(IPC_FIFO * fifo); -extern void IPC_FIFOadd(IPC_FIFO * fifo, u32 val); -extern u32 IPC_FIFOget(IPC_FIFO * fifo); +extern IPC_FIFO ipc_fifo; +extern void IPC_FIFOclear(); +extern void IPC_FIFOsend(u8 proc, u32 val); +extern u32 IPC_FIFOrecv(u8 proc); +extern void IPC_FIFOcnt(u8 proc, u16 val); //=================================================== GFX FIFO typedef struct { - u32 size; // tail + u32 cmd[261]; + u32 param[261]; - BOOL empty; - BOOL half; - BOOL full; - BOOL error; - u8 irq; - - u32 pipe[4]; // additional 4 entries - u8 pipe_size; // pipe tail - - BOOL pipe_empty; - BOOL pipe_half; - BOOL pipe_full; + u32 tail; // tail } GFX_FIFO; -extern void GFX_FIFOclear(GFX_FIFO * fifo); -extern void GFX_FIFOadd(GFX_FIFO * fifo); + +extern GFX_FIFO gxFIFO; +extern void GFX_FIFOclear(); +extern void GFX_FIFOsend(u32 cmd, u32 param); //=================================================== Display memory FIFO #if 0 diff --git a/desmume/src/MMU.cpp b/desmume/src/MMU.cpp index a28ab6c63..8c60f62a4 100644 --- a/desmume/src/MMU.cpp +++ b/desmume/src/MMU.cpp @@ -311,9 +311,8 @@ void MMU_Init(void) { MMU.DTCMRegion = 0x027C0000; MMU.ITCMRegion = 0x00000000; - IPC_FIFOclear(&MMU.ipc_fifo[ARMCPU_ARM9]); - IPC_FIFOclear(&MMU.ipc_fifo[ARMCPU_ARM7]); - GFX_FIFOclear(&MMU.gfx_fifo); + IPC_FIFOclear(); + GFX_FIFOclear(); mc_init(&MMU.fw, MC_TYPE_FLASH); /* init fw device */ mc_alloc(&MMU.fw, NDS_FW_SIZE_V1); @@ -368,9 +367,8 @@ void MMU_clearMem() memset(MMU.ARM7_ERAM, 0, 0x010000); memset(MMU.ARM7_REG, 0, 0x010000); - IPC_FIFOclear(&MMU.ipc_fifo[ARMCPU_ARM9]); - IPC_FIFOclear(&MMU.ipc_fifo[ARMCPU_ARM7]); - GFX_FIFOclear(&MMU.gfx_fifo); + IPC_FIFOclear(); + GFX_FIFOclear(); MMU.DTCMRegion = 0x027C0000; MMU.ITCMRegion = 0x00000000; @@ -1586,6 +1584,22 @@ static void FASTCALL _MMU_ARM9_write08(u32 adr, u8 val) MMU.MMU_MEM[ARMCPU_ARM9][adr>>20][adr&MMU.MMU_MASK[ARMCPU_ARM9][adr>>20]]=val; } +static INLINE void MMU_IPCSync(u8 proc, u32 val) +{ + //INFO("IPC%s sync 0x%08X\n", proc?"7":"9", val); + u32 IPCSYNC_local = T1ReadLong(MMU.MMU_MEM[proc][0x40], 0x180) & 0xFFFF; + u32 IPCSYNC_remote = T1ReadLong(MMU.MMU_MEM[proc^1][0x40], 0x180); + + IPCSYNC_local = (IPCSYNC_local&0x6000)|(val&0xf00)|(IPCSYNC_local&0xf); + IPCSYNC_remote =(IPCSYNC_remote&0x6f00)|(val>>8)&0xf; + + T1WriteLong(MMU.MMU_MEM[proc][0x40], 0x180, IPCSYNC_local); + T1WriteLong(MMU.MMU_MEM[proc^1][0x40], 0x180, IPCSYNC_remote); + + if ((val & 0x2000) && (IPCSYNC_remote & 0x4000)) + NDS_makeInt(proc^1, 17); +} + //================================================= MMU ARM9 write 16 static void FASTCALL _MMU_ARM9_write16(u32 adr, u16 val) { @@ -1938,42 +1952,11 @@ static void FASTCALL _MMU_ARM9_write16(u32 adr, u16 val) return; case REG_IPCSYNC : - { - u16 IPCSYNC_remote = T1ReadWord(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0x180); - T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x180, (val&0xFFF0)|((IPCSYNC_remote>>8)&0x0F)); - T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0x180, (IPCSYNC_remote&0xFFF0)|((val>>8)&0x0F)); - MMU.reg_IF[ARMCPU_ARM9] |= ((IPCSYNC_remote & (1<<14))<<2); - MMU.reg_IF[ARMCPU_ARM7] |= ((val & (1<<13))<<3); - //MMU.reg_IF[ARMCPU_ARM7] |= ((IPCSYNC_remote & (1<<14))<<2) & ((val & (1<<13))<<3); - } + MMU_IPCSync(ARMCPU_ARM9, val); return; case REG_IPCFIFOCNT : - { - //LOG("IPC9 write16 context 0x%X\n", val); - u32 cnt_l = T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x184) & 0xFFFF; - u32 cnt_r = T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0x184) & 0xFFFF; - /* - if ((val & 0x8000) && !(cnt_l & 0x8000)) - { - // this is the first init, the other side didnt init yet - // so do a complete init - IPC_FIFOclear(&MMU.ipc_fifo); - T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x184,0x8101) ; - // and then handle it as usual - }*/ - - if (val & 0x4008) // clear FIFO - { - IPC_FIFOclear(&MMU.ipc_fifo[ARMCPU_ARM9]); - T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x184, (cnt_l & 0x0301) | (val & 0x8404) | 1); - T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0x184, (cnt_r & 0xC507) | 0x100); - MMU.reg_IF[ARMCPU_ARM9] |= ((val & 4)<<15); - //T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x184, val); - return; - } - T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x184, cnt_l | (val & 0xBFF4)); - } + IPC_FIFOcnt(ARMCPU_ARM9, val); return; case REG_TM0CNTL : case REG_TM1CNTL : @@ -2202,26 +2185,34 @@ static void FASTCALL _MMU_ARM9_write32(u32 adr, u32 val) if((adr>>24)==4) { - if(adr >= 0x04000380 && adr <= 0x040003BC) + if( (adr >= 0x04000330) && (adr < 0x04000340) ) //edge color table { - //toon table - ((u32 *)(MMU.MMU_MEM[ARMCPU_ARM9][0x40]))[(adr-0x04000000)>>2] = val; + ((u32 *)(MMU.MMU_MEM[ARMCPU_ARM9][0x40]))[(adr & 0xFFF) >> 2] = val; + return; + } + + if( (adr >= 0x04000360) && (adr < 0x04000380) ) //fog table + { + ((u32 *)(MMU.MMU_MEM[ARMCPU_ARM9][0x40]))[(adr & 0xFFF) >> 2] = val; + return; + } + + if( (adr >= 0x04000380) && (adr <= 0x40003BC) ) //toon table + { + ((u32 *)(MMU.MMU_MEM[ARMCPU_ARM9][0x40]))[(adr & 0xFFF) >> 2] = val; gfx3d_UpdateToonTable(&((MMU.MMU_MEM[ARMCPU_ARM9][0x40]))[(0x380)]); return; } - if (adr >= 0x04000400 && adr < 0x04000440) + if ( (adr >= 0x04000400) && (adr < 0x04000440) ) { - // Geometry commands (aka Dislay Lists) - Parameters:X - ((u32 *)(MMU.MMU_MEM[ARMCPU_ARM9][0x40]))[(adr-0x04000000)>>2] = val; - gfx3d_Add_Command(val); + gfx3d_sendCommandToFIFO(val); return; } - if (adr >= 0x04000440 && adr < 0x04000600) + if ( (adr >= 0x04000440) && (adr < 0x04000600) ) { - ((u32 *)(MMU.MMU_MEM[ARMCPU_ARM9][0x40]))[(adr-0x04000000)>>2] = val; - gfx3d_Add_Command_Direct((adr - 0x04000400) >> 2, val); + gfx3d_sendCommand(adr, val); return; } @@ -2262,12 +2253,6 @@ static void FASTCALL _MMU_ARM9_write32(u32 adr, u32 val) return; } - case 0x04000600: // Geometry Engine Status Register (R and R/W) - { - ((u32 *)(MMU.MMU_MEM[ARMCPU_ARM9][0x40]))[0x600>>2] = val; - return; - } - case REG_DISPA_WININ: { GPU_setWININ(MainScreen.gpu, val & 0xFFFF) ; @@ -2459,60 +2444,11 @@ static void FASTCALL _MMU_ARM9_write32(u32 adr, u32 val) return; } case REG_IPCSYNC : - { - LOG("MMU write 32 IPCSYNC\n"); - u32 IPCSYNC_remote = T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0x180); - T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x180, (val&0xFFF0)|((IPCSYNC_remote>>8)&0xF)); - T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0x180, (IPCSYNC_remote&0xFFF0)|((val>>8)&0xF)); - MMU.reg_IF[ARMCPU_ARM9] |= ((IPCSYNC_remote & (1<<14))<<2); - MMU.reg_IF[ARMCPU_ARM7] |= ((val & (1<<13))<<3); - //MMU.reg_IF[ARMCPU_ARM7] |= ((IPCSYNC_remote & (1<<14))<<2) & ((val & (1<<13))<<3); - } + MMU_IPCSync(ARMCPU_ARM9, val); return; - case REG_IPCFIFOCNT : - { - //LOG("IPC9 write32 context 0x%X\n", val); - u32 cnt_l = T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x184) & 0xFFFF; - u32 cnt_r = T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0x184) & 0xFFFF; - - /*if ((val & 0x8000) && !(cnt_l & 0x8000)) - { - // this is the first init, the other side didnt init yet - // so do a complete init - IPC_FIFOclear(&MMU.ipc_fifo); - T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x184,0x8101) ; - // and then handle it as usual - }*/ - if(val & 0x4008) - { - IPC_FIFOclear(&MMU.ipc_fifo[ARMCPU_ARM9]); - T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x184, (cnt_l & 0x0301) | (val & 0x8404) | 1); - T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0x184, (cnt_r & 0xC507) | 0x100); - MMU.reg_IF[ARMCPU_ARM9] |= ((val & 4)<<15);// & (MMU.reg_IME[ARMCPU_ARM9]<<17);// & (MMU.reg_IE[ARMCPU_ARM9]&0x20000);// - return; - } - T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x184, val & 0xBFF4); - return; - } case REG_IPCFIFOSEND : - { - //INFO("IPC9 write32\n"); - u32 cnt_l = T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x184) & 0xFFFF; - if (!(cnt_l & 0x8000)) return; //FIFO disabled - u32 cnt_r = T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0x184) & 0xFFFF; - IPC_FIFOadd(&MMU.ipc_fifo[ARMCPU_ARM7], val); - cnt_l = (cnt_l & 0xFFFC) | (MMU.ipc_fifo[ARMCPU_ARM9].full?0x0002:0); - cnt_r = (cnt_r & 0xFCFF) | (MMU.ipc_fifo[ARMCPU_ARM9].full?0x0200:0); - T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x184, cnt_l); - T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0x184, cnt_r); - //MMU.reg_IF[ARMCPU_ARM7] |= ((cnt_r & (1<<10))<<8); - if (cnt_r & 0x400) - { - MMU.reg_IF[ARMCPU_ARM7] |= ((cnt_r & (1<<10))<<8); // FIFO remote not empty - NDS_makeARM7Int(18); - } - } + IPC_FIFOsend(ARMCPU_ARM9, val); return; case REG_DMA0CNTL : //LOG("32 bit dma0 %04X\r\n", val); @@ -2738,7 +2674,6 @@ static u16 FASTCALL _MMU_ARM9_read16(u32 adr) case 0x04000606: return (gfx3d_GetNumVertex()&8191); // ============================================= 3D end - case REG_IME : return (u16)MMU.reg_IME[ARMCPU_ARM9]; @@ -2802,8 +2737,16 @@ static u32 FASTCALL _MMU_ARM9_read32(u32 adr) { switch(adr) { - case 0x04000600: // Geometry Engine Status Register (R and R/W) - return gfx3d_GetGXstatus(); + case 0x04000600: // Geometry Engine Status Register (R and R/W) + { + + u32 gxstat = T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM9][(adr >> 20)], + adr & MMU.MMU_MASK[ARMCPU_ARM9][(adr >> 20)]); + + // this is hack + gxstat |= 0x00000002; + return gxstat; + } case 0x04000640: case 0x04000644: @@ -2853,28 +2796,7 @@ static u32 FASTCALL _MMU_ARM9_read32(u32 adr) case REG_IF : return MMU.reg_IF[ARMCPU_ARM9]; case REG_IPCFIFORECV : - { - //INFO("IPC9 read32\n"); - u32 cnt_l = T1ReadWord(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x184) & 0xFFFF; - if (!(cnt_l & 0x8000)) return 0; // FIFO disabled - u32 cnt_r = T1ReadWord(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0x184) & 0xFFFF; - u32 val = IPC_FIFOget(&MMU.ipc_fifo[ARMCPU_ARM9]); - - cnt_l |= (MMU.ipc_fifo[ARMCPU_ARM9].empty?0x0100:0) | (MMU.ipc_fifo[ARMCPU_ARM9].full?0x0200:0) | (MMU.ipc_fifo[ARMCPU_ARM9].error?0x4000:0); - cnt_r |= (MMU.ipc_fifo[ARMCPU_ARM9].empty?0x0001:0) | (MMU.ipc_fifo[ARMCPU_ARM9].full?0x0002:0); - - T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x184, cnt_l); - T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0x184, cnt_r); - - if ((MMU.ipc_fifo[ARMCPU_ARM7].empty) && (cnt_l & BIT(2))) - { - MMU.reg_IF[ARMCPU_ARM7] |= ((cnt_r & (1<<8))<<7); // FIFO empty - NDS_makeARM7Int(17) ; // SEND FIFO EMPTY - } - - return val; - } - return 0; + return IPC_FIFOrecv(ARMCPU_ARM9); case REG_TM0CNTL : case REG_TM1CNTL : case REG_TM2CNTL : @@ -3207,41 +3129,11 @@ static void FASTCALL _MMU_ARM7_write16(u32 adr, u16 val) return; case REG_IPCSYNC : - { - u16 IPCSYNC_remote = T1ReadWord(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x180); - T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0x180, (val&0xFFF0)|((IPCSYNC_remote>>8)&0xF)); - T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x180, (IPCSYNC_remote&0xFFF0)|((val>>8)&0xF)); - MMU.reg_IF[ARMCPU_ARM9] |= ((IPCSYNC_remote & (1<<14))<<2) & ((val & (1<<13))<<3);// & (MMU.reg_IME[remote] << 16);// & (MMU.reg_IE[remote] & (1<<16));// - //execute = FALSE; - } + MMU_IPCSync(ARMCPU_ARM7, val); return; case REG_IPCFIFOCNT : - { - //LOG("IPC7 write16 context 0x%X\n", val); - u32 cnt_l = T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0x184) & 0xFFFF; - u32 cnt_r = T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x184) & 0xFFFF; - /* - if ((val & 0x8000) && !(cnt_l & 0x8000)) - { - // this is the first init, the other side didnt init yet - // so do a complete init - IPC_FIFOclear(&MMU.ipc_fifo); - T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0x184,0x8101) ; - // and then handle it as usual - }*/ - - if (val & 0x4008) // clear FIFO - { - IPC_FIFOclear(&MMU.ipc_fifo[ARMCPU_ARM7]); - T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0x184, (cnt_l & 0x0301) | (val & 0x8404) | 1); - T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x184, (cnt_r & 0xC507) | 0x100); - MMU.reg_IF[ARMCPU_ARM7] |= ((val & 4)<<15); - //T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0x184, val); - return; - } - T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0x184, cnt_l | (val & 0xBFF4)); - } + IPC_FIFOcnt(ARMCPU_ARM7, val); return; case REG_TM0CNTL : case REG_TM1CNTL : @@ -3496,61 +3388,11 @@ static void FASTCALL _MMU_ARM7_write32(u32 adr, u32 val) } case REG_IPCSYNC : - { - //execute=FALSE; - LOG("MMU write 32 IPCSYNC\n"); - u32 IPCSYNC_remote = T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x180); - T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0x180, (val&0xFFF0)|((IPCSYNC_remote>>8)&0xF)); - T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x180, (IPCSYNC_remote&0xFFF0)|((val>>8)&0xF)); - MMU.reg_IF[ARMCPU_ARM9] |= ((IPCSYNC_remote & (1<<14))<<2) & ((val & (1<<13))<<3);// & (MMU.reg_IME[remote] << 16);// & (MMU.reg_IE[remote] & (1<<16));// - } + MMU_IPCSync(ARMCPU_ARM7, val); return; - case REG_IPCFIFOCNT : - { - //LOG("IPC7 write32 context 0x%X\n", val); - u32 cnt_l = T1ReadWord(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0x184) & 0xFFFF ; - u32 cnt_r = T1ReadWord(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x184) & 0xFFFF ; - /* - if ((val & 0x8000) && !(cnt_l & 0x8000)) - { - // this is the first init, the other side didnt init yet - // so do a complete init - IPC_FIFOclear(&MMU.ipc_fifo); - T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0x184,0x8101) ; - // and then handle it as usual - } - */ - if(val & 0x4008) - { - IPC_FIFOclear(&MMU.ipc_fifo[ARMCPU_ARM7]); - T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0x184, (cnt_l & 0x0301) | (val & 0x8404) | 1); - T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x184, (cnt_r & 0xC507) | 0x100); - MMU.reg_IF[ARMCPU_ARM7] |= ((val & 4)<<15);// & (MMU.reg_IME[ARMCPU_ARM7]<<17);// & (MMU.reg_IE[ARMCPU_ARM7]&0x20000);// - return; - } - T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0x184, val & 0xBFF4); - //execute = FALSE; - return; - } case REG_IPCFIFOSEND : - { - //INFO("IPC7 write32\n"); - u32 cnt_l = T1ReadWord(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0x184) & 0xFFFF; - if (!(cnt_l & 0x8000)) return; //FIFO disabled - u32 cnt_r = T1ReadWord(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x184) & 0xFFFF; - IPC_FIFOadd(&MMU.ipc_fifo[ARMCPU_ARM9], val); - cnt_l = (cnt_l & 0xFFFC) | (MMU.ipc_fifo[ARMCPU_ARM7].full?0x0002:0); - cnt_r = (cnt_r & 0xFCFF) | (MMU.ipc_fifo[ARMCPU_ARM7].full?0x0200:0); - T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0x184, cnt_l); - T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x184, cnt_r); - //MMU.reg_IF[ARMCPU_ARM9] |= ((cnt_r & (1<<10))<<8); - if (cnt_r & 0x400) - { - MMU.reg_IF[ARMCPU_ARM9] |= ((cnt_r & (1<<10))<<8); // FIFO remote not empty - NDS_makeARM9Int(18); - } - } + IPC_FIFOsend(ARMCPU_ARM7, val); return; case REG_DMA0CNTL : //LOG("32 bit dma0 %04X\r\n", val); @@ -3740,7 +3582,7 @@ static u16 FASTCALL _MMU_ARM7_read16(u32 adr) return (u16)MMU.reg_IF[ARMCPU_ARM7]; case REG_IF + 2 : return (u16)(MMU.reg_IF[ARMCPU_ARM7]>>16); - + case REG_TM0CNTL : case REG_TM1CNTL : case REG_TM2CNTL : @@ -3780,31 +3622,7 @@ static u32 FASTCALL _MMU_ARM7_read32(u32 adr) case REG_IF : return MMU.reg_IF[ARMCPU_ARM7]; case REG_IPCFIFORECV : - { - //INFO("IPC7 read32\n"); - u32 cnt_l = T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0x184) & 0xFFFF; - if (!(cnt_l & 0x8000)) return 0; // FIFO disabled - u32 cnt_r = T1ReadWord(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x184) & 0xFFFF; - u32 val = IPC_FIFOget(&MMU.ipc_fifo[ARMCPU_ARM7]); - - cnt_l |= (MMU.ipc_fifo[ARMCPU_ARM7].empty?0x0100:0) | (MMU.ipc_fifo[ARMCPU_ARM7].full?0x0200:0) | (MMU.ipc_fifo[ARMCPU_ARM7].error?0x4000:0); - cnt_r |= (MMU.ipc_fifo[ARMCPU_ARM7].empty?0x0001:0) | (MMU.ipc_fifo[ARMCPU_ARM7].full?0x0002:0); - - T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0x184, cnt_l); - T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x184, cnt_r); - - if ((MMU.ipc_fifo[ARMCPU_ARM9].empty) && (cnt_l & BIT(2))) - { - MMU.reg_IF[ARMCPU_ARM9] |= ((cnt_r & (1<<8))<<7); // FIFO empty - NDS_makeARM9Int(17) ; // SEND FIFO EMPTY - } - - //if ((MMU.ipc_fifo.empty) && (cnt_l & BIT(2))) - // NDS_makeInt(ARMCPU_ARM9,17) ; // remote: SEND FIFO EMPTY - - return val; - } - return 0; + return IPC_FIFOrecv(ARMCPU_ARM7); case REG_TM0CNTL : case REG_TM1CNTL : case REG_TM2CNTL : diff --git a/desmume/src/MMU.h b/desmume/src/MMU.h index 922dd8fe1..b9f1a6d51 100644 --- a/desmume/src/MMU.h +++ b/desmume/src/MMU.h @@ -77,12 +77,6 @@ struct MMU_struct { u8 ARM9_RW_MODE; - // IPC FIFO - IPC_FIFO ipc_fifo[2]; // 0 - ARM9 FIFO - // 1 - ARM7 FIFO - // GFX FIFO - GFX_FIFO gfx_fifo; - static TWaitState MMU_WAIT16[2][16]; static TWaitState MMU_WAIT32[2][16]; diff --git a/desmume/src/NDSSystem.h b/desmume/src/NDSSystem.h index f12175f83..ac076213a 100644 --- a/desmume/src/NDSSystem.h +++ b/desmume/src/NDSSystem.h @@ -144,7 +144,8 @@ struct NDS_fw_touchscreen_cal { */ enum nds_fw_ds_type { NDS_FW_DS_TYPE_FAT, - NDS_FW_DS_TYPE_LITE + NDS_FW_DS_TYPE_LITE, + NDS_FW_DS_TYPE_iQue }; #define MAX_FW_NICKNAME_LENGTH 10 diff --git a/desmume/src/gfx3d.cpp b/desmume/src/gfx3d.cpp index 43b20ae02..59eb28666 100644 --- a/desmume/src/gfx3d.cpp +++ b/desmume/src/gfx3d.cpp @@ -31,6 +31,7 @@ #include "bits.h" #include "MMU.h" #include "render3D.h" +#include "mem.h" #include "types.h" #include "saves.h" #include "readwrite.h" @@ -245,6 +246,8 @@ void gfx3d_reset() _s=0; last_t = 0; last_s = 0; + + GFX_FIFOclear(); } void gfx3d_glViewPort(unsigned long v) @@ -1006,11 +1009,163 @@ void gfx3d_glGetVecRes(unsigned int index) //return 0; } +#if 0 +void gfx3d_execute(u8 cmd, u32 param) +{ + switch (cmd) + { + case 0x10: // MTX_MODE - Set Matrix Mode (W) + gfx3d_glMatrixMode(param); + break; + case 0x11: // MTX_PUSH - Push Current Matrix on Stack (W) + gfx3d_glPushMatrix(); + break; + case 0x12: // MTX_POP - Pop Current Matrix from Stack (W) + gfx3d_glPopMatrix(param); + break; + case 0x13: // MTX_STORE - Store Current Matrix on Stack (W) + gfx3d_glStoreMatrix(param); + break; + case 0x14: // MTX_RESTORE - Restore Current Matrix from Stack (W) + gfx3d_glRestoreMatrix(param); + break; + case 0x15: // MTX_IDENTITY - Load Unit Matrix to Current Matrix (W) + gfx3d_glLoadIdentity(); + break; + case 0x16: // MTX_LOAD_4x4 - Load 4x4 Matrix to Current Matrix (W) + gfx3d_glLoadMatrix4x4(param); + break; + case 0x17: // MTX_LOAD_4x3 - Load 4x3 Matrix to Current Matrix (W) + gfx3d_glLoadMatrix4x3(param); + break; + case 0x18: // MTX_MULT_4x4 - Multiply Current Matrix by 4x4 Matrix (W) + gfx3d_glMultMatrix4x4(param); + break; + case 0x19: // MTX_MULT_4x3 - Multiply Current Matrix by 4x3 Matrix (W) + gfx3d_glMultMatrix4x3(param); + break; + case 0x1A: // MTX_MULT_3x3 - Multiply Current Matrix by 3x3 Matrix (W) + gfx3d_glMultMatrix3x3(param); + break; + case 0x1B: // MTX_SCALE - Multiply Current Matrix by Scale Matrix (W) + gfx3d_glScale(param); + break; + case 0x1C: // MTX_TRANS - Mult. Curr. Matrix by Translation Matrix (W) + gfx3d_glTranslate(param); + break; + case 0x20: // COLOR - Directly Set Vertex Color (W) + gfx3d_glColor3b(param); + break; + case 0x21: // NORMAL - Set Normal Vector (W) + gfx3d_glNormal(param); + break; + case 0x22: // TEXCOORD - Set Texture Coordinates (W) + gfx3d_glTexCoord(param); + break; + case 0x23: // VTX_16 - Set Vertex XYZ Coordinates (W) + gfx3d_glVertex16b(param); + break; + case 0x24: // VTX_10 - Set Vertex XYZ Coordinates (W) + gfx3d_glVertex10b(param); + break; + case 0x25: // VTX_XY - Set Vertex XY Coordinates (W) + gfx3d_glVertex3_cord(0, 1, param); + break; + case 0x26: // VTX_XZ - Set Vertex XZ Coordinates (W) + gfx3d_glVertex3_cord(0, 2, param); + break; + case 0x27: // VTX_YZ - Set Vertex YZ Coordinates (W) + gfx3d_glVertex3_cord(1, 2, param); + break; + case 0x28: // VTX_DIFF - Set Relative Vertex Coordinates (W) + gfx3d_glVertex_rel(param); + break; + case 0x29: // POLYGON_ATTR - Set Polygon Attributes (W) + gfx3d_glPolygonAttrib(param); + break; + case 0x2A: // TEXIMAGE_PARAM - Set Texture Parameters (W) + gfx3d_glTexImage(param); + break; + case 0x2B: // PLTT_BASE - Set Texture Palette Base Address (W) + gfx3d_glTexPalette(param); + break; + case 0x30: // DIF_AMB - MaterialColor0 - Diffuse/Ambient Reflect. (W) + gfx3d_glMaterial0(param); + break; + case 0x31: // SPE_EMI - MaterialColor1 - Specular Ref. & Emission (W) + gfx3d_glMaterial1(param); + break; + case 0x32: // LIGHT_VECTOR - Set Light's Directional Vector (W) + gfx3d_glLightDirection(param); + break; + case 0x33: // LIGHT_COLOR - Set Light Color (W) + gfx3d_glLightColor(param); + break; + case 0x34: // SHININESS - Specular Reflection Shininess Table (W) + gfx3d_glShininess(param); + break; + case 0x40: // BEGIN_VTXS - Start of Vertex List (W) + gfx3d_glBegin(param); + break; + case 0x41: // END_VTXS - End of Vertex List (W) + gfx3d_glEnd(); + break; + case 0x50: // SWAP_BUFFERS - Swap Rendering Engine Buffer (W) + gfx3d_glFlush(param); + break; + case 0x60: // VIEWPORT - Set Viewport (W) + gfx3d_glViewPort(param); + break; + case 0x70: // BOX_TEST - Test if Cuboid Sits inside View Volume (W) + gfx3d_glBoxTest(param); + break; + case 0x71: // POS_TEST - Set Position Coordinates for Test (W) + gfx3d_glPosTest(param); + break; + case 0x72: // VEC_TEST - Set Directional Vector for Test (W) + gfx3d_glVecTest(param); + break; + default: + INFO("Unknown execute FIFO 3D command 0x%02X with param 0x%02X\n", cmd&0xFF, param); + break; + } +} +#endif + +void gfx3d_FlushFIFO() +{ + u32 cmd; + u32 param; + + GFX_FIFOclear(); + +#if 0 + //INFO("GX FIFO tail at %i, GXstat 0x%08X\n", gxFIFO.tail, gxstat); + if (gxFIFO.tail == 0) + { + GFX_FIFOclear(); + return; + } + for (int i=0; i< gxFIFO.tail; i++) + { + cmd = gxFIFO.cmd[i]; + param = gxFIFO.param[i]; + gfx3d_execute(cmd, param); + } + //gxstat = ((u32 *)(MMU.MMU_MEM[ARMCPU_ARM9][0x40]))[0x600>>2]; + //INFO("----------- GX FIFO tail at %i, GXstat 0x%08X\n\n", gxFIFO.tail, gxstat); + GFX_FIFOclear(); +#endif +} + void gfx3d_glFlush(unsigned long v) { //INFO("FIFO size=%i\n", MMU.gfx_fifo.size); GFX_busy = TRUE; + + gfx3d_FlushFIFO(); // GX FIFO commands execute + flushPending = TRUE; gfx3d.wbuffer = (v&1)!=0; gfx3d.sortmode = ((v>>1)&1)!=0; @@ -1018,7 +1173,6 @@ void gfx3d_glFlush(unsigned long v) // reset clInd = 0; clCmd = 0; - GFX_FIFOclear(&MMU.gfx_fifo); //the renderer wil lget the lists we just built gfx3d.polylist = polylist; @@ -1063,9 +1217,633 @@ void gfx3d_VBlankEndSignal() gpu3D->NDS_3D_Render(); } +#if 0 +void gfx3d_sendCommandToFIFO(u32 val) +{ + u32 gxstat = ((u32 *)(MMU.MMU_MEM[ARMCPU_ARM9][0x40]))[0x600>>2]; + //INFO("GX FIFO cmd 0x%08X, gxstat 0x%08X\n", val, gxstat); + //INFO("FIFO 3D command 0x%02X in 0x%08X (0x%08X)\n", clCmd&0xFF, clCmd, val); + if (!clInd) + { + clCmd = val; + clInd = 4; + return; + } +// INFO("FIFO 3D command 0x%02X in 0x%08X (0x%08X)\n", clCmd&0xFF, clCmd, val); + + for (;;) + { + switch (clCmd & 0xFF) + { + case 0x00: + { + if (clInd > 0) + { + clCmd >>= 8; + clInd--; + gfx3d_FlushFIFO(); + continue; + } + gfx3d_FlushFIFO(); + break; + } + case 0x11: // MTX_PUSH - Push Current Matrix on Stack (W) + case 0x15: // MTX_IDENTITY - Load Unit Matrix to Current Matrix (W) + case 0x41: // END_VTXS - End of Vertex List (W) + { + GFX_FIFOsend(clCmd & 0xFF, 0); + + clCmd >>= 8; + clInd--; + continue; + } + } + break; + } + + if (!clInd) + { + clCmd = val; + clInd = 4; + //INFO("GX FIFO cmd 0x%08X, gxstat 0x%08X (%i)\n", clCmd, gxstat, gxFIFO.tail); + return; + } + + switch (clCmd & 0xFF) + { + case 0x34: // SHININESS - Specular Reflection Shininess Table (W) + GFX_FIFOsend(clCmd & 0xFF, val); + + clInd2++; + if (clInd2 < 32) return; + clInd2 = 0; + clCmd >>= 8; + clInd--; + break; + + case 0x16: // MTX_LOAD_4x4 - Load 4x4 Matrix to Current Matrix (W) + case 0x18: // MTX_MULT_4x4 - Multiply Current Matrix by 4x4 Matrix (W) + GFX_FIFOsend(clCmd & 0xFF, val); + + clInd2++; + if (clInd2 < 16) return; + clInd2 = 0; + clCmd >>= 8; + clInd--; + break; + + case 0x17: // MTX_LOAD_4x3 - Load 4x3 Matrix to Current Matrix (W) + case 0x19: // MTX_MULT_4x3 - Multiply Current Matrix by 4x3 Matrix (W) + GFX_FIFOsend(clCmd & 0xFF, val); + + clInd2++; + if (clInd2 < 12) return; + clInd2 = 0; + clCmd >>= 8; + clInd--; + break; + + case 0x1A: // MTX_MULT_3x3 - Multiply Current Matrix by 3x3 Matrix (W) + GFX_FIFOsend(clCmd & 0xFF, val); + + clInd2++; + if (clInd2 < 9) return; + clInd2 = 0; + clCmd >>= 8; + clInd--; + break; + + case 0x1B: // MTX_SCALE - Multiply Current Matrix by Scale Matrix (W) + case 0x1C: // MTX_TRANS - Mult. Curr. Matrix by Translation Matrix (W) + case 0x70: // BOX_TEST - Test if Cuboid Sits inside View Volume (W) + GFX_FIFOsend(clCmd & 0xFF, val); + + clInd2++; + if (clInd2 < 3) return; + clInd2 = 0; + clCmd >>= 8; + clInd--; + break; + + case 0x23: // VTX_16 - Set Vertex XYZ Coordinates (W) + case 0x71: // POS_TEST - Set Position Coordinates for Test (W) + GFX_FIFOsend(clCmd & 0xFF, val); + + clInd2++; + if (clInd2 < 2) return; + clInd2 = 0; + clCmd >>= 8; + clInd--; + break; + + case 0x10: // MTX_MODE - Set Matrix Mode (W) + case 0x12: // MTX_POP - Pop Current Matrix from Stack (W) + case 0x13: // MTX_STORE - Store Current Matrix on Stack (W) + case 0x14: // MTX_RESTORE - Restore Current Matrix from Stack (W) + case 0x20: // COLOR - Directly Set Vertex Color (W) + case 0x21: // NORMAL - Set Normal Vector (W) + case 0x22: // TEXCOORD - Set Texture Coordinates (W) + case 0x24: // VTX_10 - Set Vertex XYZ Coordinates (W) + case 0x25: // VTX_XY - Set Vertex XY Coordinates (W) + case 0x26: // VTX_XZ - Set Vertex XZ Coordinates (W) + case 0x27: // VTX_YZ - Set Vertex YZ Coordinates (W) + case 0x28: // VTX_DIFF - Set Relative Vertex Coordinates (W) + case 0x29: // POLYGON_ATTR - Set Polygon Attributes (W) + case 0x2A: // TEXIMAGE_PARAM - Set Texture Parameters (W) + case 0x2B: // PLTT_BASE - Set Texture Palette Base Address (W) + case 0x30: // DIF_AMB - MaterialColor0 - Diffuse/Ambient Reflect. (W) + case 0x31: // SPE_EMI - MaterialColor1 - Specular Ref. & Emission (W) + case 0x32: // LIGHT_VECTOR - Set Light's Directional Vector (W) + case 0x33: // LIGHT_COLOR - Set Light Color (W) + case 0x40: // BEGIN_VTXS - Start of Vertex List (W) + case 0x60: // VIEWPORT - Set Viewport (W) + case 0x72: // VEC_TEST - Set Directional Vector for Test (W) + GFX_FIFOsend(clCmd & 0xFF, val); + + clCmd >>= 8; + clInd--; + break; + case 0x50: // SWAP_BUFFERS - Swap Rendering Engine Buffer (W) + + clCmd >>= 8; + clInd--; + break; + default: + INFO("Unknown FIFO 3D command 0x%02X in 0x%02X\n", clCmd&0xFF, val); + clCmd >>= 8; + clInd--; + return; + } + +} +#endif + +#if 1 +void NOPARAMS(u32 val) +{ + for (;;) + { + switch (clCmd & 0xFF) + { + case 0x00: + { + if (clInd > 0) + { + clCmd >>= 8; + clInd--; + gfx3d_FlushFIFO(); + continue; + } + gfx3d_FlushFIFO(); + clCmd = 0; + break; + } + case 0x11: + { + *(u32 *)(ARM9Mem.ARM9_REG + 0x444) = val; + gfx3d_glPushMatrix(); + GFX_FIFOsend(clCmd & 0xFF, val); + clCmd >>= 8; + clInd--; + continue; + } + case 0x15: + { + *(u32 *)(ARM9Mem.ARM9_REG + 0x454) = val; + gfx3d_glLoadIdentity(); + GFX_FIFOsend(clCmd & 0xFF, val); + clCmd >>= 8; + clInd--; + continue; + } + case 0x41: + { + *(u32 *)(ARM9Mem.ARM9_REG + 0x504) = val; + gfx3d_glEnd(); + GFX_FIFOsend(clCmd & 0xFF, val); + clCmd >>= 8; + clInd--; + continue; + } + } + break; + } +} + +void gfx3d_sendCommandToFIFO(u32 val) +{ + //INFO("3D command 0x%02X (full val = 0x%08X, val = 0x%08X, ind %i)\n", clCmd&0xFF, clCmd, val, clInd); + if (!clInd) + { + if (val == 0) + { + gfx3d_FlushFIFO(); + return; + } + clCmd = val; + clInd = 4; + NOPARAMS(val); + return; + } + + switch (clCmd & 0xFF) + { + case 0x10: // MTX_MODE - Set Matrix Mode (W) + *(u32 *)(ARM9Mem.ARM9_REG + 0x440) = val; + GFX_FIFOsend(clCmd & 0xFF, val); + gfx3d_glMatrixMode(val); + clCmd >>= 8; + clInd--; + break; + case 0x12: // MTX_POP - Pop Current Matrix from Stack (W) + *(u32 *)(ARM9Mem.ARM9_REG + 0x448) = val; + GFX_FIFOsend(clCmd & 0xFF, val); + gfx3d_glPopMatrix(val); + clCmd >>= 8; + clInd--; + break; + case 0x13: // MTX_STORE - Store Current Matrix on Stack (W) + *(u32 *)(ARM9Mem.ARM9_REG + 0x44C) = val; + GFX_FIFOsend(clCmd & 0xFF, val); + gfx3d_glStoreMatrix(val); + clCmd >>= 8; + clInd--; + break; + case 0x14: // MTX_RESTORE - Restore Current Matrix from Stack (W) + *(u32 *)(ARM9Mem.ARM9_REG + 0x450) = val; + GFX_FIFOsend(clCmd & 0xFF, val); + gfx3d_glRestoreMatrix(val); + clCmd >>= 8; + clInd--; + break; + case 0x16: // MTX_LOAD_4x4 - Load 4x4 Matrix to Current Matrix (W) + *(u32 *)(ARM9Mem.ARM9_REG + 0x458) = val; + GFX_FIFOsend(clCmd & 0xFF, val); + if (!gfx3d_glLoadMatrix4x4(val)) break; + clCmd >>= 8; + clInd--; + break; + case 0x17: // MTX_LOAD_4x3 - Load 4x3 Matrix to Current Matrix (W) + *(u32 *)(ARM9Mem.ARM9_REG + 0x45C) = val; + GFX_FIFOsend(clCmd & 0xFF, val); + if (!gfx3d_glLoadMatrix4x3(val)) break; + clCmd >>= 8; + clInd--; + break; + case 0x18: // MTX_MULT_4x4 - Multiply Current Matrix by 4x4 Matrix (W) + *(u32 *)(ARM9Mem.ARM9_REG + 0x460) = val; + GFX_FIFOsend(clCmd & 0xFF, val); + if (!gfx3d_glMultMatrix4x4(val)) break; + clCmd >>= 8; + clInd--; + break; + case 0x19: // MTX_MULT_4x3 - Multiply Current Matrix by 4x3 Matrix (W) + *(u32 *)(ARM9Mem.ARM9_REG + 0x464) = val; + GFX_FIFOsend(clCmd & 0xFF, val); + if (!gfx3d_glMultMatrix4x3(val)) break; + clCmd >>= 8; + clInd--; + break; + case 0x1A: // MTX_MULT_3x3 - Multiply Current Matrix by 3x3 Matrix (W) + *(u32 *)(ARM9Mem.ARM9_REG + 0x468) = val; + GFX_FIFOsend(clCmd & 0xFF, val); + if (!gfx3d_glMultMatrix3x3(val)) break; + clCmd >>= 8; + clInd--; + break; + case 0x1B: // MTX_SCALE - Multiply Current Matrix by Scale Matrix (W) + *(u32 *)(ARM9Mem.ARM9_REG + 0x46C) = val; + GFX_FIFOsend(clCmd & 0xFF, val); + if (!gfx3d_glScale(val)) break; + clCmd >>= 8; + clInd--; + break; + case 0x1C: // MTX_TRANS - Mult. Curr. Matrix by Translation Matrix (W) + *(u32 *)(ARM9Mem.ARM9_REG + 0x470) = val; + GFX_FIFOsend(clCmd & 0xFF, val); + if (!gfx3d_glTranslate(val)) break; + clCmd >>= 8; + clInd--; + break; + case 0x20: // COLOR - Directly Set Vertex Color (W) + *(u32 *)(ARM9Mem.ARM9_REG + 0x480) = val; + GFX_FIFOsend(clCmd & 0xFF, val); + gfx3d_glColor3b(val); + clCmd >>= 8; + clInd--; + break; + case 0x21: // NORMAL - Set Normal Vector (W) + *(u32 *)(ARM9Mem.ARM9_REG + 0x484) = val; + GFX_FIFOsend(clCmd & 0xFF, val); + gfx3d_glNormal(val); + clCmd >>= 8; + clInd--; + break; + case 0x22: // TEXCOORD - Set Texture Coordinates (W) + *(u32 *)(ARM9Mem.ARM9_REG + 0x488) = val; + GFX_FIFOsend(clCmd & 0xFF, val); + gfx3d_glTexCoord(val); + clCmd >>= 8; + clInd--; + break; + case 0x23: // VTX_16 - Set Vertex XYZ Coordinates (W) + *(u32 *)(ARM9Mem.ARM9_REG + 0x48C) = val; + GFX_FIFOsend(clCmd & 0xFF, val); + if (!gfx3d_glVertex16b(val)) break; + clCmd >>= 8; + clInd--; + break; + case 0x24: // VTX_10 - Set Vertex XYZ Coordinates (W) + *(u32 *)(ARM9Mem.ARM9_REG + 0x490) = val; + GFX_FIFOsend(clCmd & 0xFF, val); + gfx3d_glVertex10b(val); + clCmd >>= 8; + clInd--; + break; + case 0x25: // VTX_XY - Set Vertex XY Coordinates (W) + *(u32 *)(ARM9Mem.ARM9_REG + 0x494) = val; + GFX_FIFOsend(clCmd & 0xFF, val); + gfx3d_glVertex3_cord(0, 1, val); + clCmd >>= 8; + clInd--; + break; + case 0x26: // VTX_XZ - Set Vertex XZ Coordinates (W) + *(u32 *)(ARM9Mem.ARM9_REG + 0x498) = val; + GFX_FIFOsend(clCmd & 0xFF, val); + gfx3d_glVertex3_cord(0, 2, val); + clCmd >>= 8; + clInd--; + break; + case 0x27: // VTX_YZ - Set Vertex YZ Coordinates (W) + *(u32 *)(ARM9Mem.ARM9_REG + 0x49C) = val; + GFX_FIFOsend(clCmd & 0xFF, val); + gfx3d_glVertex3_cord(1, 2, val); + clCmd >>= 8; + clInd--; + break; + case 0x28: // VTX_DIFF - Set Relative Vertex Coordinates (W) + *(u32 *)(ARM9Mem.ARM9_REG + 0x4A0) = val; + GFX_FIFOsend(clCmd & 0xFF, val); + gfx3d_glVertex_rel(val); + clCmd >>= 8; + clInd--; + break; + case 0x29: // POLYGON_ATTR - Set Polygon Attributes (W) + *(u32 *)(ARM9Mem.ARM9_REG + 0x4A4) = val; + GFX_FIFOsend(clCmd & 0xFF, val); + gfx3d_glPolygonAttrib(val); + clCmd >>= 8; + clInd--; + break; + case 0x2A: // TEXIMAGE_PARAM - Set Texture Parameters (W) + *(u32 *)(ARM9Mem.ARM9_REG + 0x4A8) = val; + GFX_FIFOsend(clCmd & 0xFF, val); + gfx3d_glTexImage(val); + clCmd >>= 8; + clInd--; + break; + case 0x2B: // PLTT_BASE - Set Texture Palette Base Address (W) + *(u32 *)(ARM9Mem.ARM9_REG + 0x4AC) = val; + GFX_FIFOsend(clCmd & 0xFF, val); + gfx3d_glTexPalette(val); + clCmd >>= 8; + clInd--; + break; + case 0x30: // DIF_AMB - MaterialColor0 - Diffuse/Ambient Reflect. (W) + *(u32 *)(ARM9Mem.ARM9_REG + 0x4C0) = val; + GFX_FIFOsend(clCmd & 0xFF, val); + gfx3d_glMaterial0(val); + clCmd >>= 8; + clInd--; + break; + case 0x31: // SPE_EMI - MaterialColor1 - Specular Ref. & Emission (W) + *(u32 *)(ARM9Mem.ARM9_REG + 0x4C4) = val; + GFX_FIFOsend(clCmd & 0xFF, val); + gfx3d_glMaterial1(val); + clCmd >>= 8; + clInd--; + break; + case 0x32: // LIGHT_VECTOR - Set Light's Directional Vector (W) + *(u32 *)(ARM9Mem.ARM9_REG + 0x4C8) = val; + GFX_FIFOsend(clCmd & 0xFF, val); + gfx3d_glLightDirection(val); + clCmd >>= 8; + clInd--; + break; + case 0x33: // LIGHT_COLOR - Set Light Color (W) + *(u32 *)(ARM9Mem.ARM9_REG + 0x4CC) = val; + GFX_FIFOsend(clCmd & 0xFF, val); + gfx3d_glLightColor(val); + clCmd >>= 8; + clInd--; + break; + case 0x34: // SHININESS - Specular Reflection Shininess Table (W) + *(u32 *)(ARM9Mem.ARM9_REG + 0x4D0) = val; + GFX_FIFOsend(clCmd & 0xFF, val); + if (!gfx3d_glShininess(val)) break; + clCmd >>= 8; + clInd--; + break; + case 0x40: // BEGIN_VTXS - Start of Vertex List (W) + *(u32 *)(ARM9Mem.ARM9_REG + 0x500) = val; + GFX_FIFOsend(clCmd & 0xFF, val); + gfx3d_glBegin(val); + clCmd >>= 8; + clInd--; + break; + case 0x50: // SWAP_BUFFERS - Swap Rendering Engine Buffer (W) + *(u32 *)(ARM9Mem.ARM9_REG + 0x540) = val; + gfx3d_glFlush(val); + clCmd >>= 8; + clInd--; + break; + case 0x60: // VIEWPORT - Set Viewport (W) + *(u32 *)(ARM9Mem.ARM9_REG + 0x580) = val; + GFX_FIFOsend(clCmd & 0xFF, val); + gfx3d_glViewPort(val); + clCmd >>= 8; + clInd--; + break; + case 0x70: // BOX_TEST - Test if Cuboid Sits inside View Volume (W) + *(u32 *)(ARM9Mem.ARM9_REG + 0x5C0) = val; + GFX_FIFOsend(clCmd & 0xFF, val); + if (!gfx3d_glBoxTest(val)) break; + clCmd >>= 8; + clInd--; + break; + case 0x71: // POS_TEST - Set Position Coordinates for Test (W) + *(u32 *)(ARM9Mem.ARM9_REG + 0x5C4) = val; + GFX_FIFOsend(clCmd & 0xFF, val); + if (!gfx3d_glPosTest(val)) break; + clCmd >>= 8; + clInd--; + break; + case 0x72: // VEC_TEST - Set Directional Vector for Test (W) + *(u32 *)(ARM9Mem.ARM9_REG + 0x5C8) = val; + GFX_FIFOsend(clCmd & 0xFF, val); + gfx3d_glVecTest(val); + clCmd >>= 8; + clInd--; + break; + default: + INFO("Unknown 3D command 0x%02X in cmd=0x%02X\n", clCmd&0xFF, val); + clCmd >>= 8; + clInd--; + break; + } + NOPARAMS(val); +} +#endif + +void gfx3d_sendCommand(u32 cmd, u32 param) +{ + u32 gxstat = ((u32 *)(MMU.MMU_MEM[ARMCPU_ARM9][0x40]))[0x600>>2]; + if (gxstat & 0x08000000) // GX busy + return; + cmd &= 0x0FFF; + + switch (cmd) + { + case 0x340: // Alpha test reference value - Parameters:1 + gfx3d_glAlphaFunc(param); + break; + case 0x350: // Clear background color setup - Parameters:2 + gfx3d_glClearColor(param); + break; + case 0x354: // Clear background depth setup - Parameters:2 + gfx3d_glClearDepth(param); + break; + case 0x356: // Rear-plane Bitmap Scroll Offsets (W) + break; + case 0x358: // Fog Color - Parameters:4b + gfx3d_glFogColor(param); + break; + case 0x35C: + gfx3d_glFogOffset(param); + break; + case 0x440: // MTX_MODE - Set Matrix Mode (W) + gfx3d_glMatrixMode(param); + break; + case 0x444: // MTX_PUSH - Push Current Matrix on Stack (W) + gfx3d_glPushMatrix(); + break; + case 0x448: // MTX_POP - Pop Current Matrix from Stack (W) + gfx3d_glPopMatrix(param); + break; + case 0x44C: // MTX_STORE - Store Current Matrix on Stack (W) + gfx3d_glStoreMatrix(param); + break; + case 0x450: // MTX_RESTORE - Restore Current Matrix from Stack (W) + gfx3d_glRestoreMatrix(param); + break; + case 0x454: // MTX_IDENTITY - Load Unit Matrix to Current Matrix (W) + gfx3d_glLoadIdentity(); + break; + case 0x458: // MTX_LOAD_4x4 - Load 4x4 Matrix to Current Matrix (W) + gfx3d_glLoadMatrix4x4(param); + break; + case 0x45C: // MTX_LOAD_4x3 - Load 4x3 Matrix to Current Matrix (W) + gfx3d_glLoadMatrix4x3(param); + break; + case 0x460: // MTX_MULT_4x4 - Multiply Current Matrix by 4x4 Matrix (W) + gfx3d_glMultMatrix4x4(param); + break; + case 0x464: // MTX_MULT_4x3 - Multiply Current Matrix by 4x3 Matrix (W) + gfx3d_glMultMatrix4x3(param); + break; + case 0x468: // MTX_MULT_3x3 - Multiply Current Matrix by 3x3 Matrix (W) + gfx3d_glMultMatrix3x3(param); + break; + case 0x46C: // MTX_SCALE - Multiply Current Matrix by Scale Matrix (W) + gfx3d_glScale(param); + break; + case 0x470: // MTX_TRANS - Mult. Curr. Matrix by Translation Matrix (W) + gfx3d_glTranslate(param); + break; + case 0x480: // COLOR - Directly Set Vertex Color (W) + gfx3d_glColor3b(param); + break; + case 0x484: // NORMAL - Set Normal Vector (W) + gfx3d_glNormal(param); + break; + case 0x488: // TEXCOORD - Set Texture Coordinates (W) + gfx3d_glTexCoord(param); + break; + case 0x48C: // VTX_16 - Set Vertex XYZ Coordinates (W) + gfx3d_glVertex16b(param); + break; + case 0x490: // VTX_10 - Set Vertex XYZ Coordinates (W) + gfx3d_glVertex10b(param); + break; + case 0x494: // VTX_XY - Set Vertex XY Coordinates (W) + gfx3d_glVertex3_cord(0, 1, param); + break; + case 0x498: // VTX_XZ - Set Vertex XZ Coordinates (W) + gfx3d_glVertex3_cord(0, 2, param); + break; + case 0x49C: // VTX_YZ - Set Vertex YZ Coordinates (W) + gfx3d_glVertex3_cord(1, 2, param); + break; + case 0x4A0: // VTX_DIFF - Set Relative Vertex Coordinates (W) + gfx3d_glVertex_rel(param); + break; + case 0x4A4: // POLYGON_ATTR - Set Polygon Attributes (W) + gfx3d_glPolygonAttrib(param); + break; + case 0x4A8: // TEXIMAGE_PARAM - Set Texture Parameters (W) + gfx3d_glTexImage(param); + break; + case 0x4AC: // PLTT_BASE - Set Texture Palette Base Address (W) + gfx3d_glTexPalette(param); + break; + case 0x4C0: // DIF_AMB - MaterialColor0 - Diffuse/Ambient Reflect. (W) + gfx3d_glMaterial0(param); + break; + case 0x4C4: // SPE_EMI - MaterialColor1 - Specular Ref. & Emission (W) + gfx3d_glMaterial1(param); + break; + case 0x4C8: // LIGHT_VECTOR - Set Light's Directional Vector (W) + gfx3d_glLightDirection(param); + break; + case 0x4CC: // LIGHT_COLOR - Set Light Color (W) + gfx3d_glLightColor(param); + break; + case 0x4D0: // SHININESS - Specular Reflection Shininess Table (W) + gfx3d_glShininess(param); + break; + case 0x500: // BEGIN_VTXS - Start of Vertex List (W) + gfx3d_glBegin(param); + break; + case 0x504: // END_VTXS - End of Vertex List (W) + gfx3d_glEnd(); + break; + case 0x540: // SWAP_BUFFERS - Swap Rendering Engine Buffer (W) + gfx3d_glFlush(param); + break; + case 0x580: // VIEWPORT - Set Viewport (W) + gfx3d_glViewPort(param); + break; + case 0x5C0: // BOX_TEST - Test if Cuboid Sits inside View Volume (W) + gfx3d_glBoxTest(param); + break; + case 0x5C4: // POS_TEST - Set Position Coordinates for Test (W) + gfx3d_glPosTest(param); + break; + case 0x5C8: // VEC_TEST - Set Directional Vector for Test (W) + gfx3d_glVecTest(param); + break; + default: + INFO("Execute unknown 3D command %03X in param=0x%08X\n", cmd, param); + break; + } +} + +#if 0 u32 gfx3d_GetGXstatus() { u32 gxstat = ((u32 *)(MMU.MMU_MEM[ARMCPU_ARM9][0x40]))[0x600>>2]; + //INFO("GFX FIFO read size=%i value 0x%X\n", MMU.gfx_fifo.size, gxstat); + return (gxstat | 2); gxstat &= 0x0F00A000; // 0 BoxTest,PositionTest,VectorTest Busy (0=Ready, 1=Busy) @@ -1109,465 +1887,7 @@ u32 gfx3d_GetGXstatus() //INFO("GFX FIFO read size=%i value 0x%X\n", MMU.gfx_fifo.size, gxstat); return gxstat; } - -void NOPARAMS(u32 val) -{ - for (;;) - { - switch (clCmd & 0xFF) - { - case 0x00: - { - if (clInd > 0) - { - clCmd >>= 8; - clInd--; - continue; - } - clCmd = 0; - break; - } - case 0x11: - { - GFX_FIFOadd(&MMU.gfx_fifo); - *(u32 *)(ARM9Mem.ARM9_REG + 0x444) = val; - gfx3d_glPushMatrix(); - clCmd >>= 8; - clInd--; - continue; - } - case 0x15: - { - GFX_FIFOadd(&MMU.gfx_fifo); - *(u32 *)(ARM9Mem.ARM9_REG + 0x454) = val; - gfx3d_glLoadIdentity(); - clCmd >>= 8; - clInd--; - continue; - } - case 0x41: - { - GFX_FIFOadd(&MMU.gfx_fifo); - *(u32 *)(ARM9Mem.ARM9_REG + 0x504) = val; - gfx3d_glEnd(); - clCmd >>= 8; - clInd--; - continue; - } - } - break; - } -} - -void SETCOUNTCOMMANDS() -{ - if (!clCmd) clInd = 0; - else - { - u32 tmp_chk = 0xFF000000; - for (int t = 4; t > 0; t--) - { - if ((clCmd & tmp_chk)) - { - clInd = t; - break; - } - tmp_chk >>= 8; - } - } -} - -void gfx3d_Add_Command(u32 val) -{ - //INFO("3D command 0x%02X (full val = 0x%08X, val = 0x%08X, ind %i)\n", clCmd&0xFF, clCmd, val, clInd); - if (!clInd) - { - if (val == 0) return; - clCmd = val; - SETCOUNTCOMMANDS(); - NOPARAMS(val); - return; - } - - switch (clCmd & 0xFF) - { - case 0x10: // MTX_MODE - Set Matrix Mode (W) - *(u32 *)(ARM9Mem.ARM9_REG + 0x440) = val; - gfx3d_glMatrixMode(val); - clCmd >>= 8; - clInd--; - break; - case 0x12: // MTX_POP - Pop Current Matrix from Stack (W) - *(u32 *)(ARM9Mem.ARM9_REG + 0x448) = val; - gfx3d_glPopMatrix(val); - clCmd >>= 8; - clInd--; - break; - case 0x13: // MTX_STORE - Store Current Matrix on Stack (W) - *(u32 *)(ARM9Mem.ARM9_REG + 0x44C) = val; - gfx3d_glStoreMatrix(val); - clCmd >>= 8; - clInd--; - break; - case 0x14: // MTX_RESTORE - Restore Current Matrix from Stack (W) - *(u32 *)(ARM9Mem.ARM9_REG + 0x450) = val; - gfx3d_glRestoreMatrix(val); - clCmd >>= 8; - clInd--; - break; - case 0x16: // MTX_LOAD_4x4 - Load 4x4 Matrix to Current Matrix (W) - *(u32 *)(ARM9Mem.ARM9_REG + 0x458) = val; - if (!gfx3d_glLoadMatrix4x4(val)) break; - clCmd >>= 8; - clInd--; - break; - case 0x17: // MTX_LOAD_4x3 - Load 4x3 Matrix to Current Matrix (W) - *(u32 *)(ARM9Mem.ARM9_REG + 0x45C) = val; - if (!gfx3d_glLoadMatrix4x3(val)) break; - clCmd >>= 8; - clInd--; - break; - case 0x18: // MTX_MULT_4x4 - Multiply Current Matrix by 4x4 Matrix (W) - *(u32 *)(ARM9Mem.ARM9_REG + 0x460) = val; - if (!gfx3d_glMultMatrix4x4(val)) break; - clCmd >>= 8; - clInd--; - break; - case 0x19: // MTX_MULT_4x3 - Multiply Current Matrix by 4x3 Matrix (W) - *(u32 *)(ARM9Mem.ARM9_REG + 0x464) = val; - if (!gfx3d_glMultMatrix4x3(val)) break; - clCmd >>= 8; - clInd--; - break; - case 0x1A: // MTX_MULT_3x3 - Multiply Current Matrix by 3x3 Matrix (W) - *(u32 *)(ARM9Mem.ARM9_REG + 0x468) = val; - if (!gfx3d_glMultMatrix3x3(val)) break; - clCmd >>= 8; - clInd--; - break; - case 0x1B: // MTX_SCALE - Multiply Current Matrix by Scale Matrix (W) - *(u32 *)(ARM9Mem.ARM9_REG + 0x46C) = val; - if (!gfx3d_glScale(val)) break; - clCmd >>= 8; - clInd--; - break; - case 0x1C: // MTX_TRANS - Mult. Curr. Matrix by Translation Matrix (W) - *(u32 *)(ARM9Mem.ARM9_REG + 0x470) = val; - if (!gfx3d_glTranslate(val)) break; - clCmd >>= 8; - clInd--; - break; - case 0x20: // COLOR - Directly Set Vertex Color (W) - *(u32 *)(ARM9Mem.ARM9_REG + 0x480) = val; - gfx3d_glColor3b(val); - clCmd >>= 8; - clInd--; - break; - case 0x21: // NORMAL - Set Normal Vector (W) - *(u32 *)(ARM9Mem.ARM9_REG + 0x484) = val; - gfx3d_glNormal(val); - clCmd >>= 8; - clInd--; - break; - case 0x22: // TEXCOORD - Set Texture Coordinates (W) - *(u32 *)(ARM9Mem.ARM9_REG + 0x488) = val; - gfx3d_glTexCoord(val); - clCmd >>= 8; - clInd--; - break; - case 0x23: // VTX_16 - Set Vertex XYZ Coordinates (W) - *(u32 *)(ARM9Mem.ARM9_REG + 0x48C) = val; - if (!gfx3d_glVertex16b(val)) break; - clCmd >>= 8; - clInd--; - break; - case 0x24: // VTX_10 - Set Vertex XYZ Coordinates (W) - *(u32 *)(ARM9Mem.ARM9_REG + 0x490) = val; - gfx3d_glVertex10b(val); - clCmd >>= 8; - clInd--; - break; - case 0x25: // VTX_XY - Set Vertex XY Coordinates (W) - *(u32 *)(ARM9Mem.ARM9_REG + 0x494) = val; - gfx3d_glVertex3_cord(0, 1, val); - clCmd >>= 8; - clInd--; - break; - case 0x26: // VTX_XZ - Set Vertex XZ Coordinates (W) - *(u32 *)(ARM9Mem.ARM9_REG + 0x498) = val; - gfx3d_glVertex3_cord(0, 2, val); - clCmd >>= 8; - clInd--; - break; - case 0x27: // VTX_YZ - Set Vertex YZ Coordinates (W) - *(u32 *)(ARM9Mem.ARM9_REG + 0x49C) = val; - gfx3d_glVertex3_cord(1, 2, val); - clCmd >>= 8; - clInd--; - break; - case 0x28: // VTX_DIFF - Set Relative Vertex Coordinates (W) - *(u32 *)(ARM9Mem.ARM9_REG + 0x4A0) = val; - gfx3d_glVertex_rel(val); - clCmd >>= 8; - clInd--; - break; - case 0x29: // POLYGON_ATTR - Set Polygon Attributes (W) - *(u32 *)(ARM9Mem.ARM9_REG + 0x4A4) = val; - gfx3d_glPolygonAttrib(val); - clCmd >>= 8; - clInd--; - break; - case 0x2A: // TEXIMAGE_PARAM - Set Texture Parameters (W) - *(u32 *)(ARM9Mem.ARM9_REG + 0x4A8) = val; - gfx3d_glTexImage(val); - clCmd >>= 8; - clInd--; - break; - case 0x2B: // PLTT_BASE - Set Texture Palette Base Address (W) - *(u32 *)(ARM9Mem.ARM9_REG + 0x4AC) = val; - gfx3d_glTexPalette(val); - clCmd >>= 8; - clInd--; - break; - case 0x30: // DIF_AMB - MaterialColor0 - Diffuse/Ambient Reflect. (W) - *(u32 *)(ARM9Mem.ARM9_REG + 0x4C0) = val; - gfx3d_glMaterial0(val); - clCmd >>= 8; - clInd--; - break; - case 0x31: // SPE_EMI - MaterialColor1 - Specular Ref. & Emission (W) - *(u32 *)(ARM9Mem.ARM9_REG + 0x4C4) = val; - gfx3d_glMaterial1(val); - clCmd >>= 8; - clInd--; - break; - case 0x32: // LIGHT_VECTOR - Set Light's Directional Vector (W) - *(u32 *)(ARM9Mem.ARM9_REG + 0x4C8) = val; - gfx3d_glLightDirection(val); - clCmd >>= 8; - clInd--; - break; - case 0x33: // LIGHT_COLOR - Set Light Color (W) - *(u32 *)(ARM9Mem.ARM9_REG + 0x4CC) = val; - gfx3d_glLightColor(val); - clCmd >>= 8; - clInd--; - break; - case 0x34: // SHININESS - Specular Reflection Shininess Table (W) - *(u32 *)(ARM9Mem.ARM9_REG + 0x4D0) = val; - if (!gfx3d_glShininess(val)) break; - clCmd >>= 8; - clInd--; - break; - case 0x40: // BEGIN_VTXS - Start of Vertex List (W) - *(u32 *)(ARM9Mem.ARM9_REG + 0x500) = val; - gfx3d_glBegin(val); - clCmd >>= 8; - clInd--; - break; - case 0x50: // SWAP_BUFFERS - Swap Rendering Engine Buffer (W) - *(u32 *)(ARM9Mem.ARM9_REG + 0x540) = val; - gfx3d_glFlush(val); - clCmd >>= 8; - clInd--; - break; - case 0x60: // VIEWPORT - Set Viewport (W) - *(u32 *)(ARM9Mem.ARM9_REG + 0x580) = val; - gfx3d_glViewPort(val); - clCmd >>= 8; - clInd--; - break; - case 0x70: // BOX_TEST - Test if Cuboid Sits inside View Volume (W) - *(u32 *)(ARM9Mem.ARM9_REG + 0x5C0) = val; - if (!gfx3d_glBoxTest(val)) break; - clCmd >>= 8; - clInd--; - break; - case 0x71: // POS_TEST - Set Position Coordinates for Test (W) - *(u32 *)(ARM9Mem.ARM9_REG + 0x5C4) = val; - if (!gfx3d_glPosTest(val)) break; - clCmd >>= 8; - clInd--; - break; - case 0x72: // VEC_TEST - Set Directional Vector for Test (W) - *(u32 *)(ARM9Mem.ARM9_REG + 0x5C8) = val; - gfx3d_glVecTest(val); - clCmd >>= 8; - clInd--; - break; - default: - LOG("Unknown 3D command 0x%02X in cmd=0x%02X\n", clCmd&0xFF, val); - clCmd >>= 8; - clInd--; - return; - } - GFX_FIFOadd(&MMU.gfx_fifo); - NOPARAMS(val); -} - -void gfx3d_Add_Command_Direct(u32 cmd, u32 val) -{ - if (cmd == 0) return; - - switch (cmd) - { - // 3D commands without parameters - case 0x00: // NOP - No Operation (for padding packed GXFIFO commands) - break; - case 0x11: // MTX_PUSH - Push Current Matrix on Stack (W) - *(u32 *)(ARM9Mem.ARM9_REG + 0x444) = val; - gfx3d_glPushMatrix(); - break; - case 0x15: // MTX_IDENTITY - Load Unit Matrix to Current Matrix (W) - *(u32 *)(ARM9Mem.ARM9_REG + 0x454) = val; - gfx3d_glLoadIdentity(); - break; - case 0x41: // END_VTXS - End of Vertex List (W) - *(u32 *)(ARM9Mem.ARM9_REG + 0x504) = val; - gfx3d_glEnd(); - break; - case 0x10: // MTX_MODE - Set Matrix Mode (W) - *(u32 *)(ARM9Mem.ARM9_REG + 0x440) = val; - gfx3d_glMatrixMode(val); - break; - case 0x12: // MTX_POP - Pop Current Matrix from Stack (W) - *(u32 *)(ARM9Mem.ARM9_REG + 0x448) = val; - gfx3d_glPopMatrix(val); - break; - case 0x13: // MTX_STORE - Store Current Matrix on Stack (W) - *(u32 *)(ARM9Mem.ARM9_REG + 0x44C) = val; - gfx3d_glStoreMatrix(val); - break; - case 0x14: // MTX_RESTORE - Restore Current Matrix from Stack (W) - *(u32 *)(ARM9Mem.ARM9_REG + 0x450) = val; - gfx3d_glRestoreMatrix(val); - break; - case 0x16: // MTX_LOAD_4x4 - Load 4x4 Matrix to Current Matrix (W) - *(u32 *)(ARM9Mem.ARM9_REG + 0x458) = val; - if (!gfx3d_glLoadMatrix4x4(val)) break; - break; - case 0x17: // MTX_LOAD_4x3 - Load 4x3 Matrix to Current Matrix (W) - *(u32 *)(ARM9Mem.ARM9_REG + 0x45C) = val; - if (!gfx3d_glLoadMatrix4x3(val)) break; - break; - case 0x18: // MTX_MULT_4x4 - Multiply Current Matrix by 4x4 Matrix (W) - *(u32 *)(ARM9Mem.ARM9_REG + 0x460) = val; - if (!gfx3d_glMultMatrix4x4(val)) break; - break; - case 0x19: // MTX_MULT_4x3 - Multiply Current Matrix by 4x3 Matrix (W) - *(u32 *)(ARM9Mem.ARM9_REG + 0x464) = val; - if (!gfx3d_glMultMatrix4x3(val)) break; - break; - case 0x1A: // MTX_MULT_3x3 - Multiply Current Matrix by 3x3 Matrix (W) - *(u32 *)(ARM9Mem.ARM9_REG + 0x468) = val; - if (!gfx3d_glMultMatrix3x3(val)) break; - break; - case 0x1B: // MTX_SCALE - Multiply Current Matrix by Scale Matrix (W) - *(u32 *)(ARM9Mem.ARM9_REG + 0x46C) = val; - if (!gfx3d_glScale(val)) break; - break; - case 0x1C: // MTX_TRANS - Mult. Curr. Matrix by Translation Matrix (W) - *(u32 *)(ARM9Mem.ARM9_REG + 0x470) = val; - if (!gfx3d_glTranslate(val)) break; - break; - case 0x20: // COLOR - Directly Set Vertex Color (W) - *(u32 *)(ARM9Mem.ARM9_REG + 0x480) = val; - gfx3d_glColor3b(val); - break; - case 0x21: // NORMAL - Set Normal Vector (W) - *(u32 *)(ARM9Mem.ARM9_REG + 0x484) = val; - gfx3d_glNormal(val); - break; - case 0x22: // TEXCOORD - Set Texture Coordinates (W) - *(u32 *)(ARM9Mem.ARM9_REG + 0x488) = val; - gfx3d_glTexCoord(val); - break; - case 0x23: // VTX_16 - Set Vertex XYZ Coordinates (W) - *(u32 *)(ARM9Mem.ARM9_REG + 0x48C) = val; - if (!gfx3d_glVertex16b(val)) break; - break; - case 0x24: // VTX_10 - Set Vertex XYZ Coordinates (W) - *(u32 *)(ARM9Mem.ARM9_REG + 0x490) = val; - gfx3d_glVertex10b(val); - break; - case 0x25: // VTX_XY - Set Vertex XY Coordinates (W) - *(u32 *)(ARM9Mem.ARM9_REG + 0x494) = val; - gfx3d_glVertex3_cord(0, 1, val); - break; - case 0x26: // VTX_XZ - Set Vertex XZ Coordinates (W) - *(u32 *)(ARM9Mem.ARM9_REG + 0x498) = val; - gfx3d_glVertex3_cord(0, 2, val); - break; - case 0x27: // VTX_YZ - Set Vertex YZ Coordinates (W) - *(u32 *)(ARM9Mem.ARM9_REG + 0x49C) = val; - gfx3d_glVertex3_cord(1, 2, val); - break; - case 0x28: // VTX_DIFF - Set Relative Vertex Coordinates (W) - *(u32 *)(ARM9Mem.ARM9_REG + 0x4A0) = val; - gfx3d_glVertex_rel(val); - break; - case 0x29: // POLYGON_ATTR - Set Polygon Attributes (W) - *(u32 *)(ARM9Mem.ARM9_REG + 0x4A4) = val; - gfx3d_glPolygonAttrib(val); - break; - case 0x2A: // TEXIMAGE_PARAM - Set Texture Parameters (W) - *(u32 *)(ARM9Mem.ARM9_REG + 0x4A8) = val; - gfx3d_glTexImage(val); - break; - case 0x2B: // PLTT_BASE - Set Texture Palette Base Address (W) - *(u32 *)(ARM9Mem.ARM9_REG + 0x4AC) = val; - gfx3d_glTexPalette(val); - break; - case 0x30: // DIF_AMB - MaterialColor0 - Diffuse/Ambient Reflect. (W) - *(u32 *)(ARM9Mem.ARM9_REG + 0x4C0) = val; - gfx3d_glMaterial0(val); - break; - case 0x31: // SPE_EMI - MaterialColor1 - Specular Ref. & Emission (W) - *(u32 *)(ARM9Mem.ARM9_REG + 0x4C4) = val; - gfx3d_glMaterial1(val); - break; - case 0x32: // LIGHT_VECTOR - Set Light's Directional Vector (W) - *(u32 *)(ARM9Mem.ARM9_REG + 0x4C8) = val; - gfx3d_glLightDirection(val); - break; - case 0x33: // LIGHT_COLOR - Set Light Color (W) - *(u32 *)(ARM9Mem.ARM9_REG + 0x4CC) = val; - gfx3d_glLightColor(val); - break; - case 0x34: // SHININESS - Specular Reflection Shininess Table (W) - *(u32 *)(ARM9Mem.ARM9_REG + 0x4D0) = val; - if (!gfx3d_glShininess(val)) break; - break; - case 0x40: // BEGIN_VTXS - Start of Vertex List (W) - *(u32 *)(ARM9Mem.ARM9_REG + 0x500) = val; - gfx3d_glBegin(val); - break; - case 0x50: // SWAP_BUFFERS - Swap Rendering Engine Buffer (W) - *(u32 *)(ARM9Mem.ARM9_REG + 0x540) = val; - gfx3d_glFlush(val); - break; - case 0x60: // VIEWPORT - Set Viewport (W) - *(u32 *)(ARM9Mem.ARM9_REG + 0x580) = val; - gfx3d_glViewPort(val); - break; - case 0x70: // BOX_TEST - Test if Cuboid Sits inside View Volume (W) - *(u32 *)(ARM9Mem.ARM9_REG + 0x5C0) = val; - if (!gfx3d_glBoxTest(val)) break; - break; - case 0x71: // POS_TEST - Set Position Coordinates for Test (W) - *(u32 *)(ARM9Mem.ARM9_REG + 0x5C4) = val; - if (!gfx3d_glPosTest(val)) break; - break; - case 0x72: // VEC_TEST - Set Directional Vector for Test (W) - *(u32 *)(ARM9Mem.ARM9_REG + 0x5C8) = val; - gfx3d_glVecTest(val); - break; - default: - LOG("Execute unknown 3D command 0x%02X in val=0x%02X\n", cmd, val); - return; - } - GFX_FIFOadd(&MMU.gfx_fifo); -} +#endif static void gfx3d_Control_cache() { @@ -1670,11 +1990,9 @@ SFORMAT SF_GFX3D[]={ { "GLBT", 4, 1, &BTind}, { "GLPT", 4, 1, &PTind}, { "GLBS", 1, 1, &GFX_busy}, - { "GLF1", 1, 1, &MMU.gfx_fifo.empty}, - { "GLF1", 1, 1, &MMU.gfx_fifo.half}, - { "GLF1", 1, 1, &MMU.gfx_fifo.full}, - { "GLF1", 1, 1, &MMU.gfx_fifo.error}, - { "GLF1", 1, 1, &MMU.gfx_fifo.irq}, + { "GLF9", 4, 1, &gxFIFO.tail}, + { "GLF9", 4, 261, &gxFIFO.cmd}, + { "GLF9", 4, 261, &gxFIFO.param}, { "GCOL", 1, 4, colorRGB}, { "GLCO", 4, 4, lightColor}, { "GLDI", 4, 4, lightDirection}, diff --git a/desmume/src/gfx3d.h b/desmume/src/gfx3d.h index bca62dd9e..ab35226e1 100644 --- a/desmume/src/gfx3d.h +++ b/desmume/src/gfx3d.h @@ -197,8 +197,8 @@ void gfx3d_VBlankSignal(); void gfx3d_VBlankEndSignal(); void gfx3d_Control(unsigned long v); u32 gfx3d_GetGXstatus(); -void gfx3d_Add_Command_Direct(u32 cmd, u32 val); -void gfx3d_Add_Command(u32 val); +void gfx3d_sendCommandToFIFO(u32 val); +void gfx3d_sendCommand(u32 cmd, u32 param); //other misc stuff void gfx3d_glGetMatrix(unsigned int mode, int index, float* dest); diff --git a/desmume/src/saves.cpp b/desmume/src/saves.cpp index 46a03f22a..03ea09afe 100644 --- a/desmume/src/saves.cpp +++ b/desmume/src/saves.cpp @@ -220,16 +220,12 @@ SFORMAT SF_MMU[]={ { "MCHD", 4, 1, &MMU.CheckDMAs}, //fifos - { "F0ER", 4, 1, &MMU.ipc_fifo[0].error}, - { "F0EM", 4, 1, &MMU.ipc_fifo[0].empty}, - { "F0FU", 4, 1, &MMU.ipc_fifo[0].full}, - { "F0SZ", 1, 1, &MMU.ipc_fifo[0].size}, - { "F0BU", 4, 16, &MMU.ipc_fifo[0].buf}, - { "F1ER", 4, 1, &MMU.ipc_fifo[1].error}, - { "F1EM", 4, 1, &MMU.ipc_fifo[1].empty}, - { "F1FU", 4, 1, &MMU.ipc_fifo[1].full}, - { "F1SZ", 1, 1, &MMU.ipc_fifo[1].size}, - { "F1BU", 4, 16, &MMU.ipc_fifo[1].buf}, + { "F0ST", 1, 1, ipc_fifo.sendTail}, + { "F0RT", 1, 1, ipc_fifo.recvTail}, + { "FSB0", 4, 16, &ipc_fifo.sendBuf[0]}, + { "FRB0", 4, 16, &ipc_fifo.recvBuf[0]}, + { "FSB1", 4, 16, &ipc_fifo.sendBuf[1]}, + { "FRB1", 4, 16, &ipc_fifo.recvBuf[1]}, { 0 } };