diff --git a/bin/patches/8B0725D5.pnach b/bin/patches/8B0725D5.pnach new file mode 100644 index 0000000000..f4492a5864 --- /dev/null +++ b/bin/patches/8B0725D5.pnach @@ -0,0 +1,4 @@ +gametitle= Flinstones Bedrock Racing (SLES) +comment=Path 3 Hack +// Moved from Elfheader.cpp +patch=path3hack \ No newline at end of file diff --git a/bin/patches/A08C4057.pnach b/bin/patches/A08C4057.pnach new file mode 100644 index 0000000000..cb0c895995 --- /dev/null +++ b/bin/patches/A08C4057.pnach @@ -0,0 +1,4 @@ +gametitle= Sprint Cars (SLUS) +comment=Path 3 Hack +// Moved from Elfheader.cpp +patch=path3hack \ No newline at end of file diff --git a/common/include/Pcsx2Api.h b/common/include/Pcsx2Api.h index 63b5f16755..8ddf55d933 100644 --- a/common/include/Pcsx2Api.h +++ b/common/include/Pcsx2Api.h @@ -52,6 +52,10 @@ EXPORT_C(char*) PS2EgetLibName(void); // Intended for them to get the ini and plugin paths, but could allow for other things as well. EXPORT_C_(void) PS2EpassConfig(PcsxConfig Config); +// Alternately, this function serves the same purpose, but would work for emulators outside +// of pcsx2. +EXPORT_C_(void) PS2EpassIniPath(const char *path); + // PS2EgetLibType returns (may be OR'd) enum { PS2E_LT_GS = 0x01, diff --git a/common/include/PluginCallbacks.h b/common/include/PluginCallbacks.h index b6e65a131a..133bd4159a 100644 --- a/common/include/PluginCallbacks.h +++ b/common/include/PluginCallbacks.h @@ -27,6 +27,7 @@ typedef u32 (CALLBACK* _PS2EgetLibType)(void); typedef u32 (CALLBACK* _PS2EgetLibVersion2)(u32 type); typedef char*(CALLBACK* _PS2EgetLibName)(void); typedef void (CALLBACK* _PS2EpassConfig)(PcsxConfig *Config); +typedef void (CALLBACK* _PS2EpassIniPath)(const char *path); // GS // NOTE: GSreadFIFOX/GSwriteCSR functions CANNOT use XMM/MMX regs diff --git a/pcsx2/Elfheader.cpp b/pcsx2/Elfheader.cpp index 206ec773f1..24656e6264 100644 --- a/pcsx2/Elfheader.cpp +++ b/pcsx2/Elfheader.cpp @@ -584,9 +584,9 @@ void LoadGameSpecificSettings() case 0xb99379b7: // erementar gerad (discolored chars) g_VUGameFixes |= VUFIX_XGKICKDELAY2; // Tested - still needed - arcum42 break; - case 0xa08c4057: //Sprint Cars (SLUS) - case 0x8b0725d5: //Flinstones Bedrock Racing (SLES) - path3hack = 1; // We can move this to patch files right now - break; + //case 0xa08c4057: //Sprint Cars (SLUS) + //case 0x8b0725d5: //Flinstones Bedrock Racing (SLES) + //path3hack = 1; // We can move this to patch files right now + //break; } } diff --git a/pcsx2/GS.cpp b/pcsx2/GS.cpp index 843179f228..e241b0620a 100644 --- a/pcsx2/GS.cpp +++ b/pcsx2/GS.cpp @@ -32,13 +32,6 @@ using namespace std; using namespace R5900; -// This should be done properly with the other logs. -#ifdef DEBUG -#define MTGS_LOG SysPrintf -#else -#define MTGS_LOG 0&& -#endif - static bool m_gsOpened = false; #ifdef PCSX2_DEVBUILD diff --git a/pcsx2/Gif.cpp b/pcsx2/Gif.cpp index 4045521ece..5b67f962f8 100644 --- a/pcsx2/Gif.cpp +++ b/pcsx2/Gif.cpp @@ -28,12 +28,24 @@ using std::min; - #define gif ((DMACh*)&psH[0xA000]) +enum gifstate_t +{ + GIF_STATE_EMPTY = 0, + GIF_STATE_STALL, + GIF_STATE_DONE +}; + +// A three-way toggle used to determine if the GIF is stalling (transferring) or done (finished). +static gifstate_t gifstate = GIF_STATE_EMPTY; + +//int gscount = 0; static u64 s_gstag = 0; // used for querying the last tag -static int gspath3done=0; -static int gscycles = 0; +static int gspath3done = 0; +static u32 gscycles = 0, prevcycles = 0, mfifocycles = 0; +static u32 gifqwc = 0; + __forceinline void gsInterrupt() { GIF_LOG("gsInterrupt: %8.8x", cpuRegs.cycle); @@ -103,10 +115,10 @@ static void WRITERING_DMA(u32 *pMem, u32 qwc) else { GSGIFTRANSFER3(pMem, qwc); - if( GSgetLastTag != NULL ) + if (GSgetLastTag != NULL) { GSgetLastTag(&s_gstag); - if( s_gstag == 1 ) Path3transfer = 0; /* fixes SRS and others */ + if (s_gstag == 1) Path3transfer = 0; /* fixes SRS and others */ } } } @@ -119,12 +131,9 @@ int _GIFchain() { #endif u32 *pMem; - //if (gif->qwc == 0) return 0; - pMem = (u32*)dmaGetAddr(gif->madr); if (pMem == NULL) { // reset path3, fixes dark cloud 2 - gsGIFSoftReset(4); //must increment madr and clear qwc, else it loops @@ -135,25 +144,50 @@ int _GIFchain() { } WRITERING_DMA(pMem, qwc); - //if((psHu32(GIF_MODE) & 0x4)) amount -= qwc; gif->madr+= qwc*16; gif->qwc -= qwc; return (qwc)*2; } -#define GIFchain() \ - if (gif->qwc) { \ - gscycles+= _GIFchain(); /* guessing */ \ - } +__forceinline void GIFchain() +{ + FreezeRegs(1); + if (gif->qwc) gscycles+= _GIFchain(); /* guessing */ \ + FreezeRegs(0); +} -int gscount = 0; -static int prevcycles = 0; +static __forceinline void dmaGIFend() +{ + if ((psHu32(GIF_MODE) & 0x4) && gif->qwc != 0) + { + CPU_INT(2, min( 8, (int)gif->qwc ) /** BIAS*/); + } + else + { + CPU_INT(2, gif->qwc /** BIAS*/); + } +} + +// These could probably be consolidated into one function, +// but I wasn't absolutely sure if there was a good reason +// not to do the gif->qwc != 0 check. --arcum42 +static __forceinline void GIFdmaEnd() +{ + if (psHu32(GIF_MODE) & 0x4) + { + CPU_INT(2, min( 8, (int)gif->qwc ) /** BIAS*/); + } + else + { + CPU_INT(2, gif->qwc /** BIAS*/); + } +} void GIFdma() { u32 *ptag; u32 id; - + gscycles= prevcycles ? prevcycles: gscycles; if( (psHu32(GIF_CTRL) & 8) ) { // temporarily stop @@ -188,8 +222,7 @@ void GIFdma() GSCSRr &= ~0xC000; //Clear FIFO stuff GSCSRr |= 0x8000; //FIFO full - //psHu32(GIF_STAT)|= 0xE00; // OPH=1 | APATH=3 - psHu32(GIF_STAT)|= 0x10000000; // FQC=31, hack ;) + psHu32(GIF_STAT)|= 0x10000000; // FQC=31, hack ;) [ used to be 0xE00; // OPH=1 | APATH=3] #ifdef GSPATH3FIX if (vif1Regs->mskpath3 || psHu32(GIF_MODE) & 0x1) { @@ -203,7 +236,7 @@ void GIFdma() } gscycles += 2; gif->chcr = ( gif->chcr & 0xFFFF ) | ( (*ptag) & 0xFFFF0000 ); //Transfer upper part of tag to CHCR bits 31-15 - id = (ptag[0] >> 28) & 0x7; //ID for DmaChain copied from bit 28 of the tag + id = (ptag[0] >> 28) & 0x7; //ID for DmaChain copied from bit 28 of the tag gif->qwc = (u16)ptag[0]; //QWC set to lower 16bits of the tag gif->madr = ptag[1]; //MADR = ADDR field gspath3done = hwDmacSrcChainWithStack(gif, id); @@ -219,9 +252,8 @@ void GIFdma() // When MTGS is enabled, Gifchain calls WRITERING_DMA, which calls GSRINGBUF_DONECOPY, which freezes // the registers inside of the FreezeXMMRegs calls here and in the other two below.. // I'm not really sure that is intentional. --arcum42 - FreezeRegs(1); GIFchain(); - FreezeRegs(0); // Theres a comment below that says not to unfreeze the xmm regs, so not sure about this. + // Theres a comment below that says not to unfreeze the xmm regs, so not sure about freezing and unfreezing in GIFchain. if((gspath3done == 1 || (gif->chcr & 0xc) == 0) && gif->qwc == 0){ if(gif->qwc > 0) Console::WriteLn("Hurray!"); @@ -238,23 +270,19 @@ void GIFdma() return; } #endif - //gscycles = 0; // Transfer Dn_QWC from Dn_MADR to GIF if ((gif->chcr & 0xc) == 0 || gif->qwc > 0) { // Normal Mode - //gscount++; if ((psHu32(DMAC_CTRL) & 0xC0) == 0x80 && (gif->chcr & 0xc) == 0) { Console::WriteLn("DMA Stall Control on GIF normal"); } - FreezeRegs(1); GIFchain(); //Transfers the data set by the switch - FreezeRegs(0); - if(gif->qwc == 0 && (gif->chcr & 0xc) == 0) gspath3done = 1; + if (gif->qwc == 0 && (gif->chcr & 0xc) == 0) + { + gspath3done = 1; + } else { - if(psHu32(GIF_MODE) & 0x4) - CPU_INT(2, min( 8, (int)gif->qwc )/** BIAS*/); - else - CPU_INT(2, gif->qwc/* * BIAS*/); + GIFdmaEnd(); } return; } @@ -268,19 +296,11 @@ void GIFdma() } gscycles+=2; // Add 1 cycles from the QW read for the tag - // Transfer dma tag if tte is set - if (gif->chcr & 0x40) { - //u32 temptag[4] = {0}; - //Console::WriteLn("GIF TTE: %x_%x", params ptag[3], ptag[2]); - - //temptag[0] = ptag[2]; - //temptag[1] = ptag[3]; - //GSGIFTRANSFER3(ptag, 1); - } + // We used to transfer dma tags if tte is set here gif->chcr = ( gif->chcr & 0xFFFF ) | ( (*ptag) & 0xFFFF0000 ); //Transfer upper part of tag to CHCR bits 31-15 - id = (ptag[0] >> 28) & 0x7; //ID for DmaChain copied from bit 28 of the tag + id = (ptag[0] >> 28) & 0x7; //ID for DmaChain copied from bit 28 of the tag gif->qwc = (u16)ptag[0]; //QWC set to lower 16bits of the tag gif->madr = ptag[1]; //MADR = ADDR field @@ -300,14 +320,11 @@ void GIFdma() return; } } - FreezeRegs(1); GIFchain(); //Transfers the data set by the switch - FreezeRegs(0); if ((gif->chcr & 0x80) && ptag[0] >> 31) { //Check TIE bit of CHCR and IRQ bit of tag GIF_LOG("dmaIrq Set"); gspath3done = 1; - //gif->qwc = 0; } } } @@ -326,25 +343,19 @@ void GIFdma() gif->qwc = (u16)ptag[0]; //QWC set to lower 16bits of the tag gif->chcr = ( gif->chcr & 0xFFFF ) | ( (*ptag) & 0xFFFF0000 ); //Transfer upper part of tag to CHCR bits 31-15 - if(psHu32(GIF_MODE) & 0x4) - CPU_INT(2, min( 8, (int)gif->qwc )/** BIAS*/); - else - CPU_INT(2, gif->qwc /** BIAS*/); - + GIFdmaEnd(); gif->qwc = 0; return; } } - //CPU_INT(2, gif->qwc /** BIAS*/); gscycles = 0; } } void dmaGIF() { - //if(vif1Regs->mskpath3 || (psHu32(GIF_MODE) & 0x1)){ - // CPU_INT(2, 48); //Wait time for the buffer to fill, fixes some timing problems in path 3 masking - //} //It takes the time of 24 QW for the BUS to become ready - The Punisher, And1 Streetball - //else + //We used to addd wait time for the buffer to fill here, fixing some timing problems in path 3 masking + //It takes the time of 24 QW for the BUS to become ready - The Punisher, And1 Streetball + if ((psHu32(DMAC_CTRL) & 0xC) == 0xC ) { // GIF MFIFO Console::WriteLn("GIF MFIFO"); gifMFIFOInterrupt(); @@ -355,66 +366,33 @@ void dmaGIF() { GSCSRr &= ~0xC000; //Clear FIFO stuff GSCSRr |= 0x8000; //FIFO full - //psHu32(GIF_STAT)|= 0xE00; // OPH=1 | APATH=3 - psHu32(GIF_STAT)|= 0x10000000; // FQC=31, hack ;) + psHu32(GIF_STAT)|= 0x10000000; // FQC=31, hack ;) [used to be 0xE00; // OPH=1 | APATH=3] if ((gif->chcr & 0xc) != 0 && gif->qwc == 0){ u32 *ptag; ptag = (u32*)dmaGetAddr(gif->tadr); gif->qwc = (u16)ptag[0]; //QWC set to lower 16bits of the tag gif->chcr = ( gif->chcr & 0xFFFF ) | ( (*ptag) & 0xFFFF0000 ); //Transfer upper part of tag to CHCR bits 31-15 - if((psHu32(GIF_MODE) & 0x4) && gif->qwc != 0) - { - CPU_INT(2, min( 8, (int)gif->qwc ) /** BIAS*/); - } - else - { - CPU_INT(2, gif->qwc /** BIAS*/); - } + + dmaGIFend(); gif->qwc = 0; return; } if(gif->qwc > 0 && (gif->chcr & 0x4) == 0x4) { - //Console::WriteLn("HL Hack"); - gspath3done = 1; //Halflife sets a QWC amount in chain mode, no tadr set. - if((psHu32(GIF_MODE) & 0x4) && gif->qwc != 0) - { - CPU_INT(2, min( 8, (int)gif->qwc ) /** BIAS*/); - } - else - { - CPU_INT(2, gif->qwc /** BIAS*/); - } - return; + gspath3done = 1; //Halflife sets a QWC amount in chain mode, no tadr set. + + // Since this is all that's done after this if statement ends, anyways no need to have + // this code in here. + //dmaGIFend(); + //return; } - //GIFdma(); - if((psHu32(GIF_MODE) & 0x4) && gif->qwc != 0) - { - CPU_INT(2, min( 8, (int)gif->qwc ) /** BIAS*/); - } - else - { - CPU_INT(2, gif->qwc /** BIAS*/); - } + dmaGIFend(); } #define spr0 ((DMACh*)&PS2MEM_HW[0xD000]) -enum gifstate_t -{ - GIF_STATE_EMPTY = 0, - GIF_STATE_STALL, - GIF_STATE_DONE -}; - -static unsigned int mfifocycles; -static unsigned int gifqwc = 0; - -// A three-way toggle used to determine if the GIF is stalling (transferring) or done (finished). -static gifstate_t gifstate = GIF_STATE_EMPTY; - // called from only one location, so forceinline it: static __forceinline int mfifoGIFrbTransfer() { u32 qwc = (psHu32(GIF_MODE) & 0x4 && vif1Regs->mskpath3) ? min(8, (int)gif->qwc) : gif->qwc; @@ -485,7 +463,7 @@ static __forceinline int mfifoGIFchain() { return 0; } -int gifmfifoirq = 0; +bool gifmfifoirq = FALSE; void mfifoGIFtransfer(int qwc) { u32 *ptag; @@ -493,76 +471,73 @@ void mfifoGIFtransfer(int qwc) { u32 temp = 0; mfifocycles = 0; - gifmfifoirq = 0; + gifmfifoirq = FALSE; if(qwc > 0 ) { - gifqwc += qwc; - if(!(gif->chcr & 0x100))return; - if(gifstate == GIF_STATE_STALL) return; - } + gifqwc += qwc; + if(!(gif->chcr & 0x100))return; + if(gifstate == GIF_STATE_STALL) return; + } + SPR_LOG("mfifoGIFtransfer %x madr %x, tadr %x", gif->chcr, gif->madr, gif->tadr); - - if(gif->qwc == 0){ - if(gif->tadr == spr0->madr) { - #ifdef PCSX2_DEVBUILD - /*if( gifqwc > 1 ) - Console::WriteLn("gif mfifo tadr==madr but qwc = %d", params gifqwc);*/ - #endif - //hwDmacIrq(14); - - return; - } - gif->tadr = psHu32(DMAC_RBOR) + (gif->tadr & psHu32(DMAC_RBSR)); - ptag = (u32*)dmaGetAddr(gif->tadr); + if(gif->tadr == spr0->madr) { + //if( gifqwc > 1 ) DevCon::WriteLn("gif mfifo tadr==madr but qwc = %d", params gifqwc); + //hwDmacIrq(14); - id = (ptag[0] >> 28) & 0x7; - gif->qwc = (ptag[0] & 0xffff); - gif->madr = ptag[1]; - mfifocycles += 2; + return; + } + gif->tadr = psHu32(DMAC_RBOR) + (gif->tadr & psHu32(DMAC_RBSR)); + ptag = (u32*)dmaGetAddr(gif->tadr); - gif->chcr = ( gif->chcr & 0xFFFF ) | ( (*ptag) & 0xFFFF0000 ); - SPR_LOG("dmaChain %8.8x_%8.8x size=%d, id=%d, madr=%lx, tadr=%lx mfifo qwc = %x spr0 madr = %x", - ptag[1], ptag[0], gif->qwc, id, gif->madr, gif->tadr, gifqwc, spr0->madr); + id = (ptag[0] >> 28) & 0x7; + gif->qwc = (ptag[0] & 0xffff); + gif->madr = ptag[1]; + mfifocycles += 2; + + gif->chcr = ( gif->chcr & 0xFFFF ) | ( (*ptag) & 0xFFFF0000 ); + SPR_LOG("dmaChain %8.8x_%8.8x size=%d, id=%d, madr=%lx, tadr=%lx mfifo qwc = %x spr0 madr = %x", + ptag[1], ptag[0], gif->qwc, id, gif->madr, gif->tadr, gifqwc, spr0->madr); - gifqwc--; - switch (id) { - case 0: // Refe - Transfer Packet According to ADDR field - gif->tadr = psHu32(DMAC_RBOR) + ((gif->tadr + 16) & psHu32(DMAC_RBSR)); - gifstate = GIF_STATE_DONE; //End Transfer - break; + gifqwc--; + switch (id) { + case 0: // Refe - Transfer Packet According to ADDR field + gif->tadr = psHu32(DMAC_RBOR) + ((gif->tadr + 16) & psHu32(DMAC_RBSR)); + gifstate = GIF_STATE_DONE; //End Transfer + break; - case 1: // CNT - Transfer QWC following the tag. - gif->madr = psHu32(DMAC_RBOR) + ((gif->tadr + 16) & psHu32(DMAC_RBSR)); //Set MADR to QW after Tag - gif->tadr = psHu32(DMAC_RBOR) + ((gif->madr + (gif->qwc << 4)) & psHu32(DMAC_RBSR)); //Set TADR to QW following the data - gifstate = GIF_STATE_EMPTY; - break; + case 1: // CNT - Transfer QWC following the tag. + gif->madr = psHu32(DMAC_RBOR) + ((gif->tadr + 16) & psHu32(DMAC_RBSR)); //Set MADR to QW after Tag + gif->tadr = psHu32(DMAC_RBOR) + ((gif->madr + (gif->qwc << 4)) & psHu32(DMAC_RBSR)); //Set TADR to QW following the data + gifstate = GIF_STATE_EMPTY; + break; - case 2: // Next - Transfer QWC following tag. TADR = ADDR - temp = gif->madr; //Temporarily Store ADDR - gif->madr = psHu32(DMAC_RBOR) + ((gif->tadr + 16) & psHu32(DMAC_RBSR)); //Set MADR to QW following the tag - gif->tadr = temp; //Copy temporarily stored ADDR to Tag - gifstate = GIF_STATE_EMPTY; - break; + case 2: // Next - Transfer QWC following tag. TADR = ADDR + temp = gif->madr; //Temporarily Store ADDR + gif->madr = psHu32(DMAC_RBOR) + ((gif->tadr + 16) & psHu32(DMAC_RBSR)); //Set MADR to QW following the tag + gif->tadr = temp; //Copy temporarily stored ADDR to Tag + gifstate = GIF_STATE_EMPTY; + break; - case 3: // Ref - Transfer QWC from ADDR field - case 4: // Refs - Transfer QWC from ADDR field (Stall Control) - gif->tadr = psHu32(DMAC_RBOR) + ((gif->tadr + 16) & psHu32(DMAC_RBSR)); //Set TADR to next tag - gifstate = GIF_STATE_EMPTY; - break; + case 3: // Ref - Transfer QWC from ADDR field + case 4: // Refs - Transfer QWC from ADDR field (Stall Control) + gif->tadr = psHu32(DMAC_RBOR) + ((gif->tadr + 16) & psHu32(DMAC_RBSR)); //Set TADR to next tag + gifstate = GIF_STATE_EMPTY; + break; - case 7: // End - Transfer QWC following the tag - gif->madr = psHu32(DMAC_RBOR) + ((gif->tadr + 16) & psHu32(DMAC_RBSR)); //Set MADR to data following the tag - gif->tadr = psHu32(DMAC_RBOR) + ((gif->madr + (gif->qwc << 4)) & psHu32(DMAC_RBSR)); //Set TADR to QW following the data - gifstate = GIF_STATE_DONE; //End Transfer - break; - } - if ((gif->chcr & 0x80) && (ptag[0] >> 31)) { - SPR_LOG("dmaIrq Set"); - gifstate = GIF_STATE_DONE; - gifmfifoirq = 1; + case 7: // End - Transfer QWC following the tag + gif->madr = psHu32(DMAC_RBOR) + ((gif->tadr + 16) & psHu32(DMAC_RBSR)); //Set MADR to data following the tag + gif->tadr = psHu32(DMAC_RBOR) + ((gif->madr + (gif->qwc << 4)) & psHu32(DMAC_RBSR)); //Set TADR to QW following the data + gifstate = GIF_STATE_DONE; //End Transfer + break; } + + if ((gif->chcr & 0x80) && (ptag[0] >> 31)) { + SPR_LOG("dmaIrq Set"); + gifstate = GIF_STATE_DONE; + gifmfifoirq = TRUE; + } } FreezeRegs(1); if (mfifoGIFchain() == -1) { @@ -580,11 +555,15 @@ void mfifoGIFtransfer(int qwc) { void gifMFIFOInterrupt() { - if(!(gif->chcr & 0x100)) { Console::WriteLn("WTF GIFMFIFO");cpuRegs.interrupt &= ~(1 << 11); return ; } + if (!(gif->chcr & 0x100)) { + Console::WriteLn("WTF GIFMFIFO"); + cpuRegs.interrupt &= ~(1 << 11); + return ; + } if(gifstate != GIF_STATE_STALL) { if(gifqwc <= 0) { - //Console::WriteLn("Empty"); + //Console::WriteLn("Empty"); psHu32(GIF_STAT)&= ~0xE00; // OPH=0 | APATH=0 hwDmacIrq(14); return; @@ -599,7 +578,7 @@ void gifMFIFOInterrupt() } #endif //if(gifqwc > 0) Console::WriteLn("GIF MFIFO ending with stuff in it %x", params gifqwc); - if( gifmfifoirq == 0) gifqwc = 0; + if (!gifmfifoirq) gifqwc = 0; gifstate = GIF_STATE_EMPTY; gif->chcr &= ~0x100; hwDmacIrq(DMAC_GIF); diff --git a/pcsx2/IPU/IPU.cpp b/pcsx2/IPU/IPU.cpp index 785dc17887..9f8f6b9926 100644 --- a/pcsx2/IPU/IPU.cpp +++ b/pcsx2/IPU/IPU.cpp @@ -388,7 +388,7 @@ __forceinline void ipuWrite64(u32 mem, u64 value) switch( mem ) { case 0x10: - IPU_LOG("Ipu write64: IPU_CMD=0x%08X",value); + IPU_LOG("Ipu write64: IPU_CMD=0x%08X",value); IPUCMD_WRITE((u32)value); break; @@ -419,42 +419,51 @@ static __forceinline BOOL ipuIDEC(u32 val) { tIPU_CMD_IDEC idec( val ); - - IPU_LOG("IPU IDEC command."); - if (idec.FB){ IPU_LOG(" Skip %d bits.",idec.FB);} - IPU_LOG(" Quantizer step code=0x%X.",idec.QSC); - if (idec.DTD==0){ IPU_LOG(" Does not decode DT."); - }else{ IPU_LOG(" Decodes DT.");} - if (idec.SGN==0){ IPU_LOG(" No bias."); - }else{ IPU_LOG(" Bias=128.");} - if (idec.DTE==1){ IPU_LOG(" Dither Enabled.");} - if (idec.OFM==0){ IPU_LOG(" Output format is RGB32."); - }else{ IPU_LOG(" Output format is RGB16.");} - IPU_LOG(""); + IPU_LOG("IPU IDEC command."); + + if (idec.FB) IPU_LOG(" Skip %d bits.",idec.FB); + IPU_LOG(" Quantizer step code=0x%X.",idec.QSC); + + if (idec.DTD==0) + IPU_LOG(" Does not decode DT."); + else + IPU_LOG(" Decodes DT."); + + if (idec.SGN==0) + IPU_LOG(" No bias."); + else + IPU_LOG(" Bias=128."); + + if (idec.DTE==1) IPU_LOG(" Dither Enabled."); + if (idec.OFM==0) + IPU_LOG(" Output format is RGB32."); + else + IPU_LOG(" Output format is RGB16."); + + IPU_LOG(""); g_BP.BP+= idec.FB;//skip FB bits //from IPU_CTRL ipuRegs->ctrl.PCT = I_TYPE; //Intra DECoding;) - g_decoder.coding_type =ipuRegs->ctrl.PCT; - g_decoder.mpeg1 =ipuRegs->ctrl.MP1; - g_decoder.q_scale_type =ipuRegs->ctrl.QST; - g_decoder.intra_vlc_format=ipuRegs->ctrl.IVF; - g_decoder.scan =ipuRegs->ctrl.AS ? mpeg2_scan_alt: mpeg2_scan_norm; - g_decoder.intra_dc_precision=ipuRegs->ctrl.IDP; + g_decoder.coding_type = ipuRegs->ctrl.PCT; + g_decoder.mpeg1 = ipuRegs->ctrl.MP1; + g_decoder.q_scale_type = ipuRegs->ctrl.QST; + g_decoder.intra_vlc_format = ipuRegs->ctrl.IVF; + g_decoder.scan = ipuRegs->ctrl.AS ? mpeg2_scan_alt: mpeg2_scan_norm; + g_decoder.intra_dc_precision = ipuRegs->ctrl.IDP; //from IDEC value - g_decoder.quantizer_scale =idec.QSC; - g_decoder.frame_pred_frame_dct=!idec.DTD; - g_decoder.sgn =idec.SGN; - g_decoder.dte =idec.DTE; - g_decoder.ofm =idec.OFM; + g_decoder.quantizer_scale = idec.QSC; + g_decoder.frame_pred_frame_dct = !idec.DTD; + g_decoder.sgn = idec.SGN; + g_decoder.dte = idec.DTE; + g_decoder.ofm = idec.OFM; //other stuff - g_decoder.dcr =1;//resets DC prediction value + g_decoder.dcr = 1;//resets DC prediction value s_routine = so_create(mpeg2sliceIDEC, &s_RoutineDone, s_tempstack, sizeof(s_tempstack)); assert( s_routine != NULL ); so_call(s_routine); - if(s_RoutineDone) - s_routine = NULL; + if(s_RoutineDone) s_routine = NULL; return s_RoutineDone; } @@ -469,15 +478,26 @@ static __forceinline BOOL ipuBDEC(u32 val) { tIPU_CMD_BDEC bdec( val ); - IPU_LOG("IPU BDEC(macroblock decode) command %x, num: 0x%x",cpuRegs.pc, s_bdec); - if (bdec.FB){ IPU_LOG(" Skip 0x%X bits.", bdec.FB);} - if (bdec.MBI){ IPU_LOG(" Intra MB.");} - else{ IPU_LOG(" Non-intra MB.");} - if (bdec.DCR){ IPU_LOG(" Resets DC prediction value.");} - else{ IPU_LOG(" Doesn't reset DC prediction value.");} - if (bdec.DT){ IPU_LOG(" Use field DCT.");} - else{ IPU_LOG(" Use frame DCT.");} - IPU_LOG(" Quantizer step=0x%X",bdec.QSC); + IPU_LOG("IPU BDEC(macroblock decode) command %x, num: 0x%x",cpuRegs.pc, s_bdec); + if (bdec.FB) IPU_LOG(" Skip 0x%X bits.", bdec.FB); + + if (bdec.MBI) + IPU_LOG(" Intra MB."); + else + IPU_LOG(" Non-intra MB."); + + if (bdec.DCR) + IPU_LOG(" Resets DC prediction value."); + else + IPU_LOG(" Doesn't reset DC prediction value."); + + if (bdec.DT) + IPU_LOG(" Use field DCT."); + else + IPU_LOG(" Use frame DCT."); + + IPU_LOG(" Quantizer step=0x%X",bdec.QSC); + #ifdef _DEBUG s_bdec++; #endif @@ -502,8 +522,8 @@ static __forceinline BOOL ipuBDEC(u32 val) s_routine = so_create(mpeg2_slice, &s_RoutineDone, s_tempstack, sizeof(s_tempstack)); assert( s_routine != NULL ); so_call(s_routine); - if(s_RoutineDone) - s_routine = NULL; + + if(s_RoutineDone) s_routine = NULL; return s_RoutineDone; } @@ -512,32 +532,31 @@ static BOOL __fastcall ipuVDEC(u32 val) { switch( g_nCmdPos[0] ) { case 0: ipuRegs->cmd.DATA = 0; - if( !getBits32((u8*)&g_decoder.bitstream_buf, 0) ) - return FALSE; + if (!getBits32((u8*)&g_decoder.bitstream_buf, 0)) return FALSE; g_decoder.bitstream_bits = -16; BigEndian(g_decoder.bitstream_buf, g_decoder.bitstream_buf); switch((val >> 26) & 3){ case 0://Macroblock Address Increment - g_decoder.mpeg1 =ipuRegs->ctrl.MP1; + g_decoder.mpeg1 = ipuRegs->ctrl.MP1; ipuRegs->cmd.DATA = get_macroblock_address_increment(&g_decoder); break; case 1://Macroblock Type //known issues: no error detected - g_decoder.frame_pred_frame_dct=1;//prevent DCT_TYPE_INTERLACED - g_decoder.coding_type =ipuRegs->ctrl.PCT; - ipuRegs->cmd.DATA=get_macroblock_modes(&g_decoder); + g_decoder.frame_pred_frame_dct = 1;//prevent DCT_TYPE_INTERLACED + g_decoder.coding_type = ipuRegs->ctrl.PCT; + ipuRegs->cmd.DATA = get_macroblock_modes(&g_decoder); break; case 2://Motion Code //known issues: no error detected - ipuRegs->cmd.DATA=get_motion_delta(&g_decoder,0); + ipuRegs->cmd.DATA = get_motion_delta(&g_decoder,0); break; case 3://DMVector - ipuRegs->cmd.DATA=get_dmv(&g_decoder); + ipuRegs->cmd.DATA = get_dmv(&g_decoder); break; } g_BP.BP+=(g_decoder.bitstream_bits+16); - if((int)g_BP.BP < 0) { + if ((int)g_BP.BP < 0) { g_BP.BP += 128; ReorderBitstream(); } @@ -575,7 +594,7 @@ static BOOL ipuFDEC(u32 val) BigEndian(ipuRegs->cmd.DATA, ipuRegs->cmd.DATA); ipuRegs->top = ipuRegs->cmd.DATA; - IPU_LOG("FDEC read: 0x%8.8x", ipuRegs->top); + IPU_LOG("FDEC read: 0x%8.8x", ipuRegs->top); return TRUE; } @@ -584,7 +603,8 @@ static __forceinline BOOL ipuSETIQ(u32 val) { int i; - if ((val >> 27) & 1){ + if ((val >> 27) & 1) + { g_nCmdPos[0] += getBits((u8*)niq + g_nCmdPos[0], 512-8*g_nCmdPos[0], 1); // 8*8*8 IPU_LOG("Read non-intra quantization matrix from IPU FIFO."); @@ -593,8 +613,11 @@ static __forceinline BOOL ipuSETIQ(u32 val) niq[i*8+0], niq[i*8+1], niq[i*8+2], niq[i*8+3], niq[i*8+4], niq[i*8+5], niq[i*8+6], niq[i*8+7]); } - }else{ + } + else + { g_nCmdPos[0] += getBits((u8*)iq+8*g_nCmdPos[0], 512-8*g_nCmdPos[0], 1); + IPU_LOG("Read intra quantization matrix from IPU FIFO."); for (i=0; i<8; i++){ IPU_LOG("%02X %02X %02X %02X %02X %02X %02X %02X", @@ -658,13 +681,10 @@ static BOOL __fastcall ipuCSC(u32 val) if( g_nCmdPos[0] < 3072/8 ) { g_nCmdPos[0] += getBits((u8*)&mb8+g_nCmdPos[0], 3072-8*g_nCmdPos[0], 1); - if( g_nCmdPos[0] < 3072/8 ) - return FALSE; + if (g_nCmdPos[0] < 3072/8) return FALSE; ipu_csc(&mb8, &rgb32, 0); - if (csc.OFM){ - ipu_dither2(&rgb32, &rgb16, csc.DTE); - } + if (csc.OFM) ipu_dither2(&rgb32, &rgb16, csc.DTE); } if (csc.OFM){ @@ -672,8 +692,7 @@ static BOOL __fastcall ipuCSC(u32 val) { g_nCmdPos[1] += FIFOfrom_write(((u32*)&rgb16)+4*g_nCmdPos[1], 32-g_nCmdPos[1]); - if( g_nCmdPos[1] <= 0 ) - return FALSE; + if( g_nCmdPos[1] <= 0 ) return FALSE; } } else { @@ -681,8 +700,7 @@ static BOOL __fastcall ipuCSC(u32 val) { g_nCmdPos[1] += FIFOfrom_write(((u32*)&rgb32)+4*g_nCmdPos[1], 64-g_nCmdPos[1]); - if( g_nCmdPos[1] <= 0 ) - return FALSE; + if( g_nCmdPos[1] <= 0 ) return FALSE; } } @@ -699,9 +717,14 @@ static BOOL ipuPACK(u32 val) tIPU_CMD_CSC csc( val ); IPU_LOG("IPU PACK (Colorspace conversion from RGB32) command."); - if (csc.OFM){ IPU_LOG("Output format is RGB16. ");} - else{ IPU_LOG("Output format is INDX4. ");} - if (csc.DTE){ IPU_LOG("Dithering enabled."); } + + if (csc.OFM) + IPU_LOG("Output format is RGB16. "); + else + IPU_LOG("Output format is INDX4. "); + + if (csc.DTE) IPU_LOG("Dithering enabled."); + IPU_LOG("Number of macroblocks to be converted: %d", csc.MBC); for (;g_nCmdIndex<(int)csc.MBC; g_nCmdIndex++){ @@ -714,22 +737,18 @@ static BOOL ipuPACK(u32 val) ipu_csc(&mb8, &rgb32, 0); ipu_dither2(&rgb32, &rgb16, csc.DTE); - if (csc.OFM){ - ipu_vq(&rgb16, indx4); - } + if (csc.OFM) ipu_vq(&rgb16, indx4); } if (csc.OFM) { g_nCmdPos[1] += FIFOfrom_write(((u32*)&rgb16)+4*g_nCmdPos[1], 32-g_nCmdPos[1]); - if( g_nCmdPos[1] < 32 ) - return FALSE; + if( g_nCmdPos[1] < 32 ) return FALSE; } else { g_nCmdPos[1] += FIFOfrom_write(((u32*)indx4)+4*g_nCmdPos[1], 8-g_nCmdPos[1]); - if( g_nCmdPos[1] < 8 ) - return FALSE; + if( g_nCmdPos[1] < 8 ) return FALSE; } g_nCmdPos[0] = 0; @@ -791,9 +810,7 @@ void IPUCMD_WRITE(u32 val) { g_BP.BP+= val & 0x3F; - if( ipuFDEC(val) ) { - return; - } + if (ipuFDEC(val)) return; ipuRegs->cmd.BUSY = 0x80000000; ipuRegs->topbusy = 0x80000000; @@ -813,24 +830,19 @@ void IPUCMD_WRITE(u32 val) { g_BP.BP+= val & 0x3F; - if( ipuSETIQ(ipuRegs->cmd.DATA) ) { - return; - } + if (ipuSETIQ(ipuRegs->cmd.DATA)) return; break; case SCE_IPU_SETVQ: - if( ipuSETVQ(ipuRegs->cmd.DATA) ) { - return; - } + if (ipuSETVQ(ipuRegs->cmd.DATA)) return; break; case SCE_IPU_CSC: g_nCmdPos[1] = 0; g_nCmdIndex = 0; - if( ipuCSC(ipuRegs->cmd.DATA) ) { - if(ipu0dma->qwc > 0 && (ipu0dma->chcr & 0x100)) - IPU_INT0_FROM(); + if (ipuCSC(ipuRegs->cmd.DATA)) { + if(ipu0dma->qwc > 0 && (ipu0dma->chcr & 0x100)) IPU_INT0_FROM(); return; } @@ -840,17 +852,14 @@ void IPUCMD_WRITE(u32 val) { g_nCmdPos[1] = 0; g_nCmdIndex = 0; - if( ipuPACK(ipuRegs->cmd.DATA) ) { - return; - } + if (ipuPACK(ipuRegs->cmd.DATA)) return; break; case SCE_IPU_IDEC: - if( ipuIDEC(val) ) { + if (ipuIDEC(val)) { // idec done, ipu0 done too - if(ipu0dma->qwc > 0 && (ipu0dma->chcr & 0x100)) - IPU_INT0_FROM(); + if(ipu0dma->qwc > 0 && (ipu0dma->chcr & 0x100)) IPU_INT0_FROM(); return; } @@ -863,11 +872,8 @@ void IPUCMD_WRITE(u32 val) { case SCE_IPU_BDEC: if( ipuBDEC(val)) { - if(ipu0dma->qwc > 0 && (ipu0dma->chcr & 0x100)) - IPU_INT0_FROM(); - if (ipuRegs->ctrl.SCD || ipuRegs->ctrl.ECD) - hwIntcIrq(INTC_IPU); - + if(ipu0dma->qwc > 0 && (ipu0dma->chcr & 0x100)) IPU_INT0_FROM(); + if (ipuRegs->ctrl.SCD || ipuRegs->ctrl.ECD) hwIntcIrq(INTC_IPU); return; } @@ -890,7 +896,7 @@ void IPUWorker() switch (ipuCurCmd) { case SCE_IPU_VDEC: - if( !ipuVDEC(ipuRegs->cmd.DATA) ) + if (!ipuVDEC(ipuRegs->cmd.DATA)) { hwIntcIrq(INTC_IPU); return; @@ -902,7 +908,7 @@ void IPUWorker() break; case SCE_IPU_FDEC: - if( !ipuFDEC(ipuRegs->cmd.DATA) ) + if (!ipuFDEC(ipuRegs->cmd.DATA)) { hwIntcIrq(INTC_IPU); return; @@ -914,7 +920,7 @@ void IPUWorker() break; case SCE_IPU_SETIQ: - if( !ipuSETIQ(ipuRegs->cmd.DATA) ) + if (!ipuSETIQ(ipuRegs->cmd.DATA)) { hwIntcIrq(INTC_IPU); return; @@ -922,7 +928,7 @@ void IPUWorker() break; case SCE_IPU_SETVQ: - if( !ipuSETVQ(ipuRegs->cmd.DATA) ) + if (!ipuSETVQ(ipuRegs->cmd.DATA)) { hwIntcIrq(INTC_IPU); return; @@ -930,7 +936,7 @@ void IPUWorker() break; case SCE_IPU_CSC: - if( !ipuCSC(ipuRegs->cmd.DATA) ) + if (!ipuCSC(ipuRegs->cmd.DATA)) { hwIntcIrq(INTC_IPU); return; @@ -940,7 +946,7 @@ void IPUWorker() IPU_INT0_FROM(); break; case SCE_IPU_PACK: - if( !ipuPACK(ipuRegs->cmd.DATA) ) + if (!ipuPACK(ipuRegs->cmd.DATA)) { hwIntcIrq(INTC_IPU); return; @@ -950,7 +956,7 @@ void IPUWorker() case SCE_IPU_IDEC: so_call(s_routine); - if( !s_RoutineDone ) { + if (!s_RoutineDone) { hwIntcIrq(INTC_IPU); return; } @@ -961,13 +967,12 @@ void IPUWorker() ipuRegs->cmd.BUSY = 0; ipuCurCmd = 0xffffffff; // CHECK!: IPU0dma remains when IDEC is done, so we need to clear it - if(ipu0dma->qwc > 0 && (ipu0dma->chcr & 0x100)) - IPU_INT0_FROM(); + if(ipu0dma->qwc > 0 && (ipu0dma->chcr & 0x100)) IPU_INT0_FROM(); s_routine = NULL; break; case SCE_IPU_BDEC: - so_call(s_routine); + so_call(s_routine); if(!s_RoutineDone) { hwIntcIrq(INTC_IPU); @@ -978,11 +983,9 @@ void IPUWorker() ipuRegs->topbusy = 0; ipuRegs->cmd.BUSY = 0; ipuCurCmd = 0xffffffff; - if(ipu0dma->qwc > 0 && (ipu0dma->chcr & 0x100)) - IPU_INT0_FROM(); + if(ipu0dma->qwc > 0 && (ipu0dma->chcr & 0x100)) IPU_INT0_FROM(); s_routine = NULL; - if (ipuRegs->ctrl.SCD || ipuRegs->ctrl.ECD) - hwIntcIrq(INTC_IPU); + if (ipuRegs->ctrl.SCD || ipuRegs->ctrl.ECD) hwIntcIrq(INTC_IPU); return; default: @@ -1003,7 +1006,6 @@ __forceinline void inc_readbits() { readbits += 16; if( readbits >= _readbits+64 ) { - // move back *(u64*)(_readbits) = *(u64*)(_readbits+64); *(u64*)(_readbits+8) = *(u64*)(_readbits+72); @@ -1020,9 +1022,7 @@ __forceinline u8* next_readbits() // returns the pointer of readbits moved by 1 qword u8* prev_readbits() { - if( readbits < _readbits+16 ) { - return _readbits+48-(readbits-_readbits); - } + if( readbits < _readbits+16 ) return _readbits+48-(readbits-_readbits); return readbits-16; } @@ -1042,28 +1042,21 @@ u16 __fastcall FillInternalBuffer(u32 * pointer, u32 advance, u32 size) { if(g_BP.FP == 0) { - if( FIFOto_read(next_readbits()) == 0 ) - return 0; + if (FIFOto_read(next_readbits()) == 0) return 0; inc_readbits(); g_BP.FP = 1; } else if(g_BP.FP < 2 && (*(int*)pointer+size) >= 128) { - if( FIFOto_read(next_readbits()) ) - { - g_BP.FP += 1; - } + if (FIFOto_read(next_readbits())) g_BP.FP += 1; } if(*(int*)pointer >= 128) { assert( g_BP.FP >= 1); - if(g_BP.FP > 1) - { - inc_readbits(); - } + if(g_BP.FP > 1) inc_readbits(); if(advance) { @@ -1083,13 +1076,11 @@ u8 __fastcall getBits32(u8 *address, u32 advance) u8* readpos; // Check if the current BP has exceeded or reached the limit of 128 - if( FillInternalBuffer(&g_BP.BP,1,32) < 32 ) - return 0; + if (FillInternalBuffer(&g_BP.BP,1,32) < 32) return 0; readpos = readbits+(int)g_BP.BP/8; if (g_BP.BP & 7) { - shift = g_BP.BP&7; mask = (0xff>>shift); mask = mask|(mask<<8)|(mask<<16)|(mask<<24); @@ -1097,10 +1088,11 @@ u8 __fastcall getBits32(u8 *address, u32 advance) *(u32*)address = ((~mask&*(u32*)(readpos+1))>>(8-shift)) | (((mask)&*(u32*)readpos)<>shift); mask = mask|(mask<<8); @@ -1127,10 +1115,11 @@ __forceinline u8 __fastcall getBits16(u8 *address, u32 advance) *(u16*)address = ((~mask&*(u16*)(readpos+1))>>(8-shift)) | (((mask)&*(u16*)readpos)<>shift); *(u8*)address = (((~mask)&readpos[1])>>(8-shift)) | (((mask)&*readpos)<> (pointer&7)) << - (8-howmuch-(pointer&7))) & 0xFF; - mask &= readbits[((pointer)>>3)]; - mask >>= 8-howmuch-(pointer&7); - pointer += howmuch; - size -= howmuch; - shift -= howmuch; + mask= ((0xFF >> (pointer&7)) << (8-howmuch-(pointer&7))) & 0xFF; + mask &= readbits[((pointer)>>3)]; + mask >>= 8-howmuch-(pointer&7); + pointer += howmuch; + size -= howmuch; + shift -= howmuch; *address |= mask << shift; } - ++address; } else @@ -1218,15 +1200,12 @@ int __fastcall getBits(u8 *address, u32 size, u32 advance) { if( FillInternalBuffer(&pointer,advance,8) < 8 ) { - if(advance) - { - g_BP.BP = pointer; - } + if(advance) g_BP.BP = pointer; return address-oldaddr; } - howmuch = min(128-pointer, size); - size -= howmuch; + howmuch = min(128-pointer, size); + size -= howmuch; readmem = readbits + (pointer>>3); pointer += howmuch; @@ -1610,13 +1589,14 @@ int FIFOfrom_write(const u32 *value,int size) int transsize; int firsttrans; - if((int)ipuRegs->ctrl.OFC >= 8) - { - if(IPU0dma() == 0) - { + //if((int)ipuRegs->ctrl.OFC >= 8) + //{ + // if(IPU0dma() == 0) + // { // ipuRegs->ctrl.OFC = 0; - } - } + // } + //} + if ((int)ipuRegs->ctrl.OFC >= 8) IPU0dma(); transsize = min(size,8-(int)ipuRegs->ctrl.OFC); firsttrans = transsize; @@ -1722,8 +1702,7 @@ void dmaIPU1() // toIPU { //g_nDMATransfer &= ~(IPU_DMA_ACTV1|IPU_DMA_DOTIE1); IPU1dma(); - if( ipuRegs->ctrl.BUSY ) - IPUWorker(); + if (ipuRegs->ctrl.BUSY) IPUWorker(); } extern void GIFdma(); @@ -1767,8 +1746,10 @@ IPU_FORCEINLINE void ipu1Interrupt() { if( g_nDMATransfer & IPU_DMA_TIE1 ) { g_nDMATransfer &= ~IPU_DMA_TIE1; - }else + } + else { ipu1dma->chcr &= ~0x100; + } hwDmacIrq(DMAC_TO_IPU); }