Parent Directory
|
Revision Log
|
Patch
--- trunk/pcsx2/SPR.cpp 2010/09/07 03:24:11 31 +++ trunk/pcsx2/SPR.cpp 2010/09/07 11:08:22 62 @@ -51,95 +51,96 @@ { tDMA_TAG *pMem; - if (spr0->qwc == 0) return 0; - pMem = SPRdmaGetAddr(spr0->madr, true); + if (spr0ch.qwc == 0) return 0; + pMem = SPRdmaGetAddr(spr0ch.madr, true); if (pMem == NULL) return -1; - switch (dmacRegs->ctrl.MFD) + switch (dmacRegs.ctrl.MFD) { case MFD_VIF1: case MFD_GIF: - if ((spr0->madr & ~dmacRegs->rbsr.RMSK) != dmacRegs->rbor.ADDR) + if ((spr0ch.madr & ~dmacRegs.rbsr.RMSK) != dmacRegs.rbor.ADDR) Console.WriteLn("SPR MFIFO Write outside MFIFO area"); else - mfifotransferred += spr0->qwc; + mfifotransferred += spr0ch.qwc; - hwMFIFOWrite(spr0->madr, &psSu8(spr0->sadr), spr0->qwc << 4); - spr0->madr += spr0->qwc << 4; - spr0->madr = dmacRegs->rbor.ADDR + (spr0->madr & dmacRegs->rbsr.RMSK); + hwMFIFOWrite(spr0ch.madr, &psSu128(spr0ch.sadr), spr0ch.qwc); + spr0ch.madr += spr0ch.qwc << 4; + spr0ch.madr = dmacRegs.rbor.ADDR + (spr0ch.madr & dmacRegs.rbsr.RMSK); break; case NO_MFD: case MFD_RESERVED: - memcpy_fast((u8*)pMem, &psSu8(spr0->sadr), spr0->qwc << 4); + memcpy_qwc(pMem, &psSu128(spr0ch.sadr), spr0ch.qwc); // clear VU mem also! - TestClearVUs(spr0->madr, spr0->qwc << 2); // Wtf is going on here? AFAIK, only VIF should affect VU micromem (cottonvibes) - spr0->madr += spr0->qwc << 4; + TestClearVUs(spr0ch.madr, spr0ch.qwc << 2); // Wtf is going on here? AFAIK, only VIF should affect VU micromem (cottonvibes) + spr0ch.madr += spr0ch.qwc << 4; break; } - spr0->sadr += spr0->qwc << 4; + spr0ch.sadr += spr0ch.qwc << 4; - return (spr0->qwc) * BIAS; // bus is 1/2 the ee speed + return (spr0ch.qwc); // bus is 1/2 the ee speed } -__forceinline void SPR0chain() +__fi void SPR0chain() { - _SPR0chain(); - spr0->qwc = 0; + CPU_INT(DMAC_FROM_SPR, _SPR0chain() / BIAS); + spr0ch.qwc = 0; } void _SPR0interleave() { - int qwc = spr0->qwc; - int sqwc = dmacRegs->sqwc.SQWC; - int tqwc = dmacRegs->sqwc.TQWC; + int qwc = spr0ch.qwc; + int sqwc = dmacRegs.sqwc.SQWC; + int tqwc = dmacRegs.sqwc.TQWC; tDMA_TAG *pMem; if (tqwc == 0) tqwc = qwc; //Console.WriteLn("dmaSPR0 interleave"); SPR_LOG("SPR0 interleave size=%d, tqwc=%d, sqwc=%d, addr=%lx sadr=%lx", - spr0->qwc, tqwc, sqwc, spr0->madr, spr0->sadr); + spr0ch.qwc, tqwc, sqwc, spr0ch.madr, spr0ch.sadr); + + CPU_INT(DMAC_FROM_SPR, qwc / BIAS); while (qwc > 0) { - spr0->qwc = std::min(tqwc, qwc); - qwc -= spr0->qwc; - pMem = SPRdmaGetAddr(spr0->madr, true); + spr0ch.qwc = std::min(tqwc, qwc); + qwc -= spr0ch.qwc; + pMem = SPRdmaGetAddr(spr0ch.madr, true); - switch (dmacRegs->ctrl.MFD) + switch (dmacRegs.ctrl.MFD) { case MFD_VIF1: case MFD_GIF: - hwMFIFOWrite(spr0->madr, &psSu8(spr0->sadr), spr0->qwc << 4); - mfifotransferred += spr0->qwc; + hwMFIFOWrite(spr0ch.madr, &psSu128(spr0ch.sadr), spr0ch.qwc); + mfifotransferred += spr0ch.qwc; break; case NO_MFD: case MFD_RESERVED: // clear VU mem also! - TestClearVUs(spr0->madr, spr0->qwc << 2); - memcpy_fast((u8*)pMem, &psSu8(spr0->sadr), spr0->qwc << 4); + TestClearVUs(spr0ch.madr, spr0ch.qwc << 2); + memcpy_qwc(pMem, &psSu128(spr0ch.sadr), spr0ch.qwc); break; } - spr0->sadr += spr0->qwc * 16; - spr0->madr += (sqwc + spr0->qwc) * 16; + spr0ch.sadr += spr0ch.qwc * 16; + spr0ch.madr += (sqwc + spr0ch.qwc) * 16; } - spr0->qwc = 0; - spr0finished = true; + spr0ch.qwc = 0; } -static __forceinline void _dmaSPR0() +static __fi void _dmaSPR0() { - if (dmacRegs->ctrl.STS == STS_fromSPR) + if (dmacRegs.ctrl.STS == STS_fromSPR) { - Console.WriteLn("SPR0 stall %d", dmacRegs->ctrl.STS); + Console.WriteLn("SPR0 stall %d", dmacRegs.ctrl.STS); } // Transfer Dn_QWC from SPR to Dn_MADR - switch(spr0->chcr.MOD) + switch(spr0ch.chcr.MOD) { case NORMAL_MODE: { @@ -150,26 +151,25 @@ case CHAIN_MODE: { tDMA_TAG *ptag; - bool done = FALSE; + bool done = false; - if (spr0->qwc > 0) + if (spr0ch.qwc > 0) { SPR0chain(); - spr0finished = true; return; } // Destination Chain Mode - ptag = (tDMA_TAG*)&psSu32(spr0->sadr); - spr0->sadr += 16; + ptag = (tDMA_TAG*)&psSu32(spr0ch.sadr); + spr0ch.sadr += 16; - spr0->unsafeTransfer(ptag); + spr0ch.unsafeTransfer(ptag); - spr0->madr = ptag[1]._u32; //MADR = ADDR field + SPR + spr0ch.madr = ptag[1]._u32; //MADR = ADDR field + SPR SPR_LOG("spr0 dmaChain %8.8x_%8.8x size=%d, id=%d, addr=%lx spr=%lx", - ptag[1]._u32, ptag[0]._u32, spr0->qwc, ptag->ID, spr0->madr, spr0->sadr); + ptag[1]._u32, ptag[0]._u32, spr0ch.qwc, ptag->ID, spr0ch.madr, spr0ch.sadr); - if (dmacRegs->ctrl.STS == STS_fromSPR) // STS == fromSPR + if (dmacRegs.ctrl.STS == STS_fromSPR) // STS == fromSPR { Console.WriteLn("SPR stall control"); } @@ -177,7 +177,7 @@ switch (ptag->ID) { case TAG_CNTS: // CNTS - Transfer QWC following the tag (Stall Control) - if (dmacRegs->ctrl.STS == STS_fromSPR) dmacRegs->stadr.ADDR = spr0->madr + (spr0->qwc * 16); //Copy MADR to DMAC_STADR stall addr register + if (dmacRegs.ctrl.STS == STS_fromSPR) dmacRegs.stadr.ADDR = spr0ch.madr + (spr0ch.qwc * 16); //Copy MADR to DMAC_STADR stall addr register break; case TAG_CNT: // CNT - Transfer QWC following the tag. @@ -191,28 +191,22 @@ SPR0chain(); - if (spr0->chcr.TIE && ptag->IRQ) //Check TIE bit of CHCR and IRQ bit of tag + if (spr0ch.chcr.TIE && ptag->IRQ) //Check TIE bit of CHCR and IRQ bit of tag { //Console.WriteLn("SPR0 TIE"); done = true; } spr0finished = done; - - if (!done) - { - ptag = (tDMA_TAG*)&psSu32(spr0->sadr); //Set memory pointer to SADR - CPU_INT(DMAC_FROM_SPR, /*ptag[0].QWC / BIAS*/ 4 ); // the lower 16bits of the tag / BIAS); - return; - } SPR_LOG("spr0 dmaChain complete %8.8x_%8.8x size=%d, id=%d, addr=%lx spr=%lx", - ptag[1]._u32, ptag[0]._u32, spr0->qwc, ptag->ID, spr0->madr); + ptag[1]._u32, ptag[0]._u32, spr0ch.qwc, ptag->ID, spr0ch.madr); break; } //case INTERLEAVE_MODE: default: { _SPR0interleave(); + spr0finished = true; break; } } @@ -220,118 +214,119 @@ void SPRFROMinterrupt() { - _dmaSPR0(); - - if(mfifotransferred != 0) + + if (!spr0finished || spr0ch.qwc > 0) { - switch (dmacRegs->ctrl.MFD) + _dmaSPR0(); + + if(mfifotransferred != 0) { - case MFD_VIF1: // Most common case. - { - if ((spr0->madr & ~dmacRegs->rbsr.RMSK) != dmacRegs->rbor.ADDR) Console.WriteLn("VIF MFIFO Write outside MFIFO area"); - spr0->madr = dmacRegs->rbor.ADDR + (spr0->madr & dmacRegs->rbsr.RMSK); - //Console.WriteLn("mfifoVIF1transfer %x madr %x, tadr %x", vif1ch->chcr._u32, vif1ch->madr, vif1ch->tadr); - mfifoVIF1transfer(mfifotransferred); - mfifotransferred = 0; - if (vif1ch->chcr.STR) return; - break; - } - case MFD_GIF: + switch (dmacRegs.ctrl.MFD) { - if ((spr0->madr & ~dmacRegs->rbsr.RMSK) != dmacRegs->rbor.ADDR) Console.WriteLn("GIF MFIFO Write outside MFIFO area"); - spr0->madr = dmacRegs->rbor.ADDR + (spr0->madr & dmacRegs->rbsr.RMSK); - //Console.WriteLn("mfifoGIFtransfer %x madr %x, tadr %x", gif->chcr._u32, gif->madr, gif->tadr); - mfifoGIFtransfer(mfifotransferred); - mfifotransferred = 0; - if (gif->chcr.STR) return; - break; + case MFD_VIF1: // Most common case. + { + if ((spr0ch.madr & ~dmacRegs.rbsr.RMSK) != dmacRegs.rbor.ADDR) Console.WriteLn("VIF MFIFO Write outside MFIFO area"); + spr0ch.madr = dmacRegs.rbor.ADDR + (spr0ch.madr & dmacRegs.rbsr.RMSK); + //Console.WriteLn("mfifoVIF1transfer %x madr %x, tadr %x", vif1ch.chcr._u32, vif1ch.madr, vif1ch.tadr); + mfifoVIF1transfer(mfifotransferred); + mfifotransferred = 0; + break; + } + case MFD_GIF: + { + if ((spr0ch.madr & ~dmacRegs.rbsr.RMSK) != dmacRegs.rbor.ADDR) Console.WriteLn("GIF MFIFO Write outside MFIFO area"); + spr0ch.madr = dmacRegs.rbor.ADDR + (spr0ch.madr & dmacRegs.rbsr.RMSK); + //Console.WriteLn("mfifoGIFtransfer %x madr %x, tadr %x", gif->chcr._u32, gif->madr, gif->tadr); + mfifoGIFtransfer(mfifotransferred); + mfifotransferred = 0; + break; + } + default: + break; } - default: - break; } + return; } - if (!spr0finished) return; - spr0->chcr.STR = false; + spr0ch.chcr.STR = false; hwDmacIrq(DMAC_FROM_SPR); } void dmaSPR0() // fromSPR { SPR_LOG("dmaSPR0 chcr = %lx, madr = %lx, qwc = %lx, sadr = %lx", - spr0->chcr._u32, spr0->madr, spr0->qwc, spr0->sadr); + spr0ch.chcr._u32, spr0ch.madr, spr0ch.qwc, spr0ch.sadr); + + + spr0finished = false; //Init - if ((spr0->chcr.MOD == CHAIN_MODE) && spr0->qwc == 0) + if(spr0ch.chcr.MOD == CHAIN_MODE && spr0ch.qwc > 0) { - tDMA_TAG *ptag; - ptag = (tDMA_TAG*)&psSu32(spr0->sadr); //Set memory pointer to SADR - CPU_INT(DMAC_FROM_SPR, /*ptag[0].QWC / BIAS*/ 4 ); - return; + //DevCon.Warning(L"SPR0 QWC on Chain " + spr0ch.chcr.desc()); + if (spr0ch.chcr.tag().ID == TAG_END) // but not TAG_REFE? + { + spr0finished = true; + } } - if(spr0->chcr.MOD == CHAIN_MODE && spr0->qwc > 0) DevCon.Warning(L"SPR0 QWC on Chain " + spr0->chcr.desc()); - // COMPLETE HACK!!! For now at least.. FFX Videos dont rely on interrupts or reading DMA values - // It merely assumes that the last one has finished then starts another one (broke with the DMA fix) - // This "shouldn't" cause any problems as SPR is generally faster than the other DMAS anyway. (Refraction) - CPU_INT(DMAC_FROM_SPR, /*spr0->qwc / BIAS*/ 4 ); + + SPRFROMinterrupt(); } -__forceinline static void SPR1transfer(u32 *data, int size) +__fi static void SPR1transfer(const void* data, int qwc) { - memcpy_fast(&psSu8(spr1->sadr), (u8*)data, size << 2); - - spr1->sadr += size << 2; + memcpy_qwc(&psSu128(spr1ch.sadr), data, qwc); + spr1ch.sadr += qwc * 16; } int _SPR1chain() { tDMA_TAG *pMem; - if (spr1->qwc == 0) return 0; + if (spr1ch.qwc == 0) return 0; - pMem = SPRdmaGetAddr(spr1->madr, false); + pMem = SPRdmaGetAddr(spr1ch.madr, false); if (pMem == NULL) return -1; - SPR1transfer((u32*)pMem, spr1->qwc << 2); - spr1->madr += spr1->qwc << 4; + SPR1transfer(pMem, spr1ch.qwc); + spr1ch.madr += spr1ch.qwc * 16; - return (spr1->qwc) * BIAS; + return (spr1ch.qwc); } -__forceinline void SPR1chain() +__fi void SPR1chain() { - _SPR1chain(); - spr1->qwc = 0; + CPU_INT(DMAC_TO_SPR, _SPR1chain() / BIAS); + spr1ch.qwc = 0; } void _SPR1interleave() { - int qwc = spr1->qwc; - int sqwc = dmacRegs->sqwc.SQWC; - int tqwc = dmacRegs->sqwc.TQWC; + int qwc = spr1ch.qwc; + int sqwc = dmacRegs.sqwc.SQWC; + int tqwc = dmacRegs.sqwc.TQWC; tDMA_TAG *pMem; if (tqwc == 0) tqwc = qwc; SPR_LOG("SPR1 interleave size=%d, tqwc=%d, sqwc=%d, addr=%lx sadr=%lx", - spr1->qwc, tqwc, sqwc, spr1->madr, spr1->sadr); - + spr1ch.qwc, tqwc, sqwc, spr1ch.madr, spr1ch.sadr); + CPU_INT(DMAC_TO_SPR, qwc / BIAS); while (qwc > 0) { - spr1->qwc = std::min(tqwc, qwc); - qwc -= spr1->qwc; - pMem = SPRdmaGetAddr(spr1->madr, false); - memcpy_fast(&psSu8(spr1->sadr), (u8*)pMem, spr1->qwc << 4); - spr1->sadr += spr1->qwc * 16; - spr1->madr += (sqwc + spr1->qwc) * 16; + spr1ch.qwc = std::min(tqwc, qwc); + qwc -= spr1ch.qwc; + pMem = SPRdmaGetAddr(spr1ch.madr, false); + memcpy_qwc(&psSu128(spr1ch.sadr), pMem, spr1ch.qwc); + spr1ch.sadr += spr1ch.qwc * 16; + spr1ch.madr += (sqwc + spr1ch.qwc) * 16; } - spr1->qwc = 0; - spr1finished = true; + spr1ch.qwc = 0; } void _dmaSPR1() // toSPR work function { - switch(spr1->chcr.MOD) + switch(spr1ch.chcr.MOD) { case NORMAL_MODE: { @@ -346,39 +341,39 @@ tDMA_TAG *ptag; bool done = false; - if (spr1->qwc > 0) + if (spr1ch.qwc > 0) { + SPR_LOG("spr1 Normal or in Progress size=%d, addr=%lx taddr=%lx saddr=%lx", spr1ch.qwc, spr1ch.madr, spr1ch.tadr, spr1ch.sadr); // Transfer Dn_QWC from Dn_MADR to SPR1 SPR1chain(); - spr1finished = true; return; } // Chain Mode - ptag = SPRdmaGetAddr(spr1->tadr, false); //Set memory pointer to TADR + ptag = SPRdmaGetAddr(spr1ch.tadr, false); //Set memory pointer to TADR - if (!spr1->transfer("SPR1 Tag", ptag)) + if (!spr1ch.transfer("SPR1 Tag", ptag)) { done = true; spr1finished = done; } - spr1->madr = ptag[1]._u32; //MADR = ADDR field + SPR + spr1ch.madr = ptag[1]._u32; //MADR = ADDR field + SPR // Transfer dma tag if tte is set - if (spr1->chcr.TTE) + if (spr1ch.chcr.TTE) { SPR_LOG("SPR TTE: %x_%x\n", ptag[3]._u32, ptag[2]._u32); - SPR1transfer((u32*)ptag, 4); //Transfer Tag + SPR1transfer(ptag, 1); //Transfer Tag } - SPR_LOG("spr1 dmaChain %8.8x_%8.8x size=%d, id=%d, addr=%lx", - ptag[1]._u32, ptag[0]._u32, spr1->qwc, ptag->ID, spr1->madr); + SPR_LOG("spr1 dmaChain %8.8x_%8.8x size=%d, id=%d, addr=%lx taddr=%lx saddr=%lx", + ptag[1]._u32, ptag[0]._u32, spr1ch.qwc, ptag->ID, spr1ch.madr, spr1ch.tadr, spr1ch.sadr); - done = (hwDmacSrcChain(spr1, ptag->ID)); + done = (hwDmacSrcChain(spr1ch, ptag->ID)); SPR1chain(); //Transfers the data set by the switch - if (spr1->chcr.TIE && ptag->IRQ) //Check TIE bit of CHCR and IRQ bit of tag + if (spr1ch.chcr.TIE && ptag->IRQ) //Check TIE bit of CHCR and IRQ bit of tag { SPR_LOG("dmaIrq Set"); @@ -387,17 +382,13 @@ } spr1finished = done; - if (!done) - { - ptag = SPRdmaGetAddr(spr1->tadr, false); //Set memory pointer to TADR - CPU_INT(DMAC_TO_SPR, /*(ptag[0].QWC / BIAS)*/ 4 );// the lower 16 bits of the tag / BIAS); - } break; } //case INTERLEAVE_MODE: default: { _SPR1interleave(); + spr1finished = true; break; } } @@ -407,29 +398,34 @@ { SPR_LOG("dmaSPR1 chcr = 0x%x, madr = 0x%x, qwc = 0x%x\n" " tadr = 0x%x, sadr = 0x%x", - spr1->chcr._u32, spr1->madr, spr1->qwc, - spr1->tadr, spr1->sadr); - - if ((spr1->chcr.MOD == CHAIN_MODE) && (spr1->qwc == 0)) + spr1ch.chcr._u32, spr1ch.madr, spr1ch.qwc, + spr1ch.tadr, spr1ch.sadr); + + spr1finished = false; //Init + + if(spr1ch.chcr.MOD == CHAIN_MODE && spr1ch.qwc > 0) { - tDMA_TAG *ptag; - ptag = SPRdmaGetAddr(spr1->tadr, false); //Set memory pointer to TADR - CPU_INT(DMAC_TO_SPR, /*ptag[0].QWC / BIAS*/ 4 ); - return; + //DevCon.Warning(L"SPR1 QWC on Chain " + spr1ch.chcr.desc()); + if ((spr1ch.chcr.tag().ID == TAG_END) || (spr1ch.chcr.tag().ID == TAG_REFE)) + { + spr1finished = true; + } } - if(spr1->chcr.MOD == CHAIN_MODE && spr1->qwc > 0) DevCon.Warning(L"SPR1 QWC on Chain " + spr1->chcr.desc()); - // COMPLETE HACK!!! For now at least.. FFX Videos dont rely on interrupts or reading DMA values - // It merely assumes that the last one has finished then starts another one (broke with the DMA fix) - // This "shouldn't" cause any problems as SPR is generally faster than the other DMAS anyway. (Refraction) - CPU_INT(DMAC_TO_SPR, /*spr1->qwc / BIAS*/ 4 ); + + SPRTOinterrupt(); } void SPRTOinterrupt() { - _dmaSPR1(); - if (!spr1finished) return; + SPR_LOG("SPR1 Interrupt"); + if (!spr1finished || spr1ch.qwc > 0) + { + _dmaSPR1(); + return; + } - spr1->chcr.STR = false; + SPR_LOG("SPR1 End"); + spr1ch.chcr.STR = false; hwDmacIrq(DMAC_TO_SPR); }
ViewVC Help | |
Powered by ViewVC 1.1.22 |