mirror of https://github.com/PCSX2/pcsx2.git
General cleanup in Gif.cpp && IPU.cpp. Did a bit of refactoring in Gif.cpp. Moved the path3hack to patches.
git-svn-id: http://pcsx2.googlecode.com/svn/trunk@850 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
parent
2a570c5f91
commit
0feb9de523
|
@ -0,0 +1,4 @@
|
|||
gametitle= Flinstones Bedrock Racing (SLES)
|
||||
comment=Path 3 Hack
|
||||
// Moved from Elfheader.cpp
|
||||
patch=path3hack
|
|
@ -0,0 +1,4 @@
|
|||
gametitle= Sprint Cars (SLUS)
|
||||
comment=Path 3 Hack
|
||||
// Moved from Elfheader.cpp
|
||||
patch=path3hack
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
301
pcsx2/Gif.cpp
301
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,19 +144,44 @@ 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()
|
||||
{
|
||||
|
@ -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);
|
||||
if(gif->tadr == spr0->madr) {
|
||||
//if( gifqwc > 1 ) DevCon::WriteLn("gif mfifo tadr==madr but qwc = %d", params gifqwc);
|
||||
//hwDmacIrq(14);
|
||||
|
||||
return;
|
||||
return;
|
||||
}
|
||||
gif->tadr = psHu32(DMAC_RBOR) + (gif->tadr & psHu32(DMAC_RBSR));
|
||||
ptag = (u32*)dmaGetAddr(gif->tadr);
|
||||
|
||||
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;
|
||||
|
||||
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 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;
|
||||
}
|
||||
gif->tadr = psHu32(DMAC_RBOR) + (gif->tadr & psHu32(DMAC_RBSR));
|
||||
ptag = (u32*)dmaGetAddr(gif->tadr);
|
||||
|
||||
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;
|
||||
|
||||
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 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;
|
||||
}
|
||||
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);
|
||||
|
|
|
@ -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.");
|
||||
|
||||
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("");
|
||||
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);
|
||||
}
|
||||
else
|
||||
{
|
||||
*(u32*)address = *(u32*)readpos;
|
||||
}
|
||||
|
||||
if (advance)
|
||||
g_BP.BP+=32;
|
||||
if (advance) g_BP.BP += 32;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
@ -1111,15 +1103,11 @@ __forceinline u8 __fastcall getBits16(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,16) < 16 )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if( FillInternalBuffer(&g_BP.BP,1,16) < 16 ) 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);
|
||||
|
@ -1127,10 +1115,11 @@ __forceinline u8 __fastcall getBits16(u8 *address, u32 advance)
|
|||
*(u16*)address = ((~mask&*(u16*)(readpos+1))>>(8-shift)) | (((mask)&*(u16*)readpos)<<shift);
|
||||
}
|
||||
else
|
||||
{
|
||||
*(u16*)address = *(u16*)readpos;
|
||||
}
|
||||
|
||||
if (advance)
|
||||
g_BP.BP+=16;
|
||||
if (advance) g_BP.BP+=16;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
@ -1147,17 +1136,17 @@ u8 __fastcall getBits8(u8 *address, u32 advance)
|
|||
readpos = readbits+(int)g_BP.BP/8;
|
||||
|
||||
if (g_BP.BP & 7) {
|
||||
|
||||
shift = g_BP.BP&7;
|
||||
mask = (0xff>>shift);
|
||||
|
||||
*(u8*)address = (((~mask)&readpos[1])>>(8-shift)) | (((mask)&*readpos)<<shift);
|
||||
}
|
||||
else
|
||||
{
|
||||
*(u8*)address = *(u8*)readpos;
|
||||
}
|
||||
|
||||
if (advance)
|
||||
g_BP.BP+=8;
|
||||
if (advance) g_BP.BP+=8;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
@ -1169,8 +1158,7 @@ int __fastcall getBits(u8 *address, u32 size, u32 advance)
|
|||
u32 pointer = 0;
|
||||
|
||||
// Check if the current BP has exceeded or reached the limit of 128
|
||||
if( FillInternalBuffer(&g_BP.BP,1,8) < 8 )
|
||||
return 0;
|
||||
if( FillInternalBuffer(&g_BP.BP,1,8) < 8 ) return 0;
|
||||
|
||||
oldbits = readbits;
|
||||
// Backup the current BP in case of VDEC/FDEC
|
||||
|
@ -1187,28 +1175,22 @@ int __fastcall getBits(u8 *address, u32 size, u32 advance)
|
|||
shift=8;
|
||||
}
|
||||
|
||||
howmuch = min(min(8-(pointer&7), 128-pointer),
|
||||
min(size, shift));
|
||||
howmuch = min(min(8-(pointer&7), 128-pointer), min(size, shift));
|
||||
|
||||
if( FillInternalBuffer(&pointer,advance,8) < 8 )
|
||||
{
|
||||
if(advance)
|
||||
{
|
||||
g_BP.BP = pointer;
|
||||
}
|
||||
if(advance) g_BP.BP = pointer;
|
||||
return address-oldaddr;
|
||||
}
|
||||
|
||||
mask = ((0xFF >> (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);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue