mirror of https://github.com/PCSX2/pcsx2.git
Modified the GIF and SPR in my wierd backward dma way :P should resolve problems with the Avatar games, 24 videos and hopefully anything else which has broken due to recent changes.
git-svn-id: http://pcsx2.googlecode.com/svn/trunk@604 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
parent
8d86297533
commit
441b70239a
|
@ -55,10 +55,10 @@ __forceinline void gsInterrupt() {
|
||||||
// re-reaise the IRQ as part of the mysterious Path3fix.
|
// re-reaise the IRQ as part of the mysterious Path3fix.
|
||||||
// fixme - this hack *should* have the gs_irq raised from the VIF, I think. It would be
|
// fixme - this hack *should* have the gs_irq raised from the VIF, I think. It would be
|
||||||
// more efficient and more correct. (air)
|
// more efficient and more correct. (air)
|
||||||
if (!(vif1Regs->mskpath3 && (vif1ch->chcr & 0x100)) || (psHu32(GIF_MODE) & 0x1))
|
/*if (!(vif1Regs->mskpath3 && (vif1ch->chcr & 0x100)) || (psHu32(GIF_MODE) & 0x1))
|
||||||
CPU_INT( 2, 64 );
|
CPU_INT( 2, 64 );*/
|
||||||
#endif
|
#endif
|
||||||
return;
|
if(gspath3done == 0) return;
|
||||||
}
|
}
|
||||||
|
|
||||||
gspath3done = 0;
|
gspath3done = 0;
|
||||||
|
@ -254,6 +254,7 @@ void GIFdma()
|
||||||
FreezeXMMRegs(0);
|
FreezeXMMRegs(0);
|
||||||
FreezeMMXRegs(0);
|
FreezeMMXRegs(0);
|
||||||
if(gif->qwc == 0 && (gif->chcr & 0xc) == 0) gspath3done = 1;
|
if(gif->qwc == 0 && (gif->chcr & 0xc) == 0) gspath3done = 1;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// Chain Mode
|
// Chain Mode
|
||||||
|
@ -311,9 +312,18 @@ void GIFdma()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
prevcycles = 0;
|
prevcycles = 0;
|
||||||
if (!(vif1Regs->mskpath3 || (psHu32(GIF_MODE) & 0x1))) {
|
if (!(vif1Regs->mskpath3 || (psHu32(GIF_MODE) & 0x1))) {
|
||||||
CPU_INT(2, gscycles);
|
if(gspath3done == 0){
|
||||||
|
ptag = (u32*)dmaGetAddr(gif->tadr); //Set memory pointer to 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
|
||||||
|
CPU_INT(2, gif->qwc * BIAS);
|
||||||
|
gif->qwc = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
//CPU_INT(2, gif->qwc * BIAS);
|
||||||
gscycles = 0;
|
gscycles = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -323,18 +333,46 @@ void dmaGIF() {
|
||||||
// CPU_INT(2, 48); //Wait time for the buffer to fill, fixes some timing problems in path 3 masking
|
// 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
|
//} //It takes the time of 24 QW for the BUS to become ready - The Punisher, And1 Streetball
|
||||||
//else
|
//else
|
||||||
gspath3done = 0; // For some reason this doesnt clear? So when the system starts the thread, we will clear it :)
|
|
||||||
|
|
||||||
if(gif->qwc > 0 && (gif->chcr & 0x4) == 0x4)
|
|
||||||
gspath3done = 1; //Halflife sets a QWC amount in chain mode, no tadr set.
|
|
||||||
|
|
||||||
if ((psHu32(DMAC_CTRL) & 0xC) == 0xC ) { // GIF MFIFO
|
if ((psHu32(DMAC_CTRL) & 0xC) == 0xC ) { // GIF MFIFO
|
||||||
//SysPrintf("GIF MFIFO\n");
|
SysPrintf("GIF MFIFO\n");
|
||||||
gifMFIFOInterrupt();
|
gifMFIFOInterrupt();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
GIFdma();
|
gspath3done = 0; // For some reason this doesnt clear? So when the system starts the thread, we will clear it :)
|
||||||
|
|
||||||
|
GSCSRr &= ~0xC000; //Clear FIFO stuff
|
||||||
|
GSCSRr |= 0x8000; //FIFO full
|
||||||
|
//psHu32(GIF_STAT)|= 0xE00; // OPH=1 | APATH=3
|
||||||
|
psHu32(GIF_STAT)|= 0x10000000; // FQC=31, hack ;)
|
||||||
|
|
||||||
|
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
|
||||||
|
CPU_INT(2, gif->qwc * BIAS);
|
||||||
|
gif->qwc = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(gif->qwc > 0 && (gif->chcr & 0x4) == 0x4) {
|
||||||
|
//SysPrintf("HL Hack\n");
|
||||||
|
gspath3done = 1; //Halflife sets a QWC amount in chain mode, no tadr set.
|
||||||
|
CPU_INT(2, gif->qwc * BIAS);
|
||||||
|
GIFdma();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//GIFdma();
|
||||||
|
CPU_INT(2, gif->qwc * BIAS);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define spr0 ((DMACh*)&PS2MEM_HW[0xD000])
|
#define spr0 ((DMACh*)&PS2MEM_HW[0xD000])
|
||||||
|
@ -417,7 +455,7 @@ static __forceinline int mfifoGIFchain() {
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
int gifmfifoirq = 0;
|
||||||
|
|
||||||
void mfifoGIFtransfer(int qwc) {
|
void mfifoGIFtransfer(int qwc) {
|
||||||
u32 *ptag;
|
u32 *ptag;
|
||||||
|
@ -425,6 +463,8 @@ void mfifoGIFtransfer(int qwc) {
|
||||||
u32 temp = 0;
|
u32 temp = 0;
|
||||||
mfifocycles = 0;
|
mfifocycles = 0;
|
||||||
|
|
||||||
|
gifmfifoirq = 0;
|
||||||
|
|
||||||
if(qwc > 0 ) {
|
if(qwc > 0 ) {
|
||||||
gifqwc += qwc;
|
gifqwc += qwc;
|
||||||
if(!(gif->chcr & 0x100))return;
|
if(!(gif->chcr & 0x100))return;
|
||||||
|
@ -432,6 +472,8 @@ void mfifoGIFtransfer(int qwc) {
|
||||||
}
|
}
|
||||||
SPR_LOG("mfifoGIFtransfer %x madr %x, tadr %x\n", gif->chcr, gif->madr, gif->tadr);
|
SPR_LOG("mfifoGIFtransfer %x madr %x, tadr %x\n", gif->chcr, gif->madr, gif->tadr);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if(gif->qwc == 0){
|
if(gif->qwc == 0){
|
||||||
if(gif->tadr == spr0->madr) {
|
if(gif->tadr == spr0->madr) {
|
||||||
#ifdef PCSX2_DEVBUILD
|
#ifdef PCSX2_DEVBUILD
|
||||||
|
@ -489,6 +531,7 @@ void mfifoGIFtransfer(int qwc) {
|
||||||
if ((gif->chcr & 0x80) && (ptag[0] >> 31)) {
|
if ((gif->chcr & 0x80) && (ptag[0] >> 31)) {
|
||||||
SPR_LOG("dmaIrq Set\n");
|
SPR_LOG("dmaIrq Set\n");
|
||||||
gifstate = GIF_STATE_DONE;
|
gifstate = GIF_STATE_DONE;
|
||||||
|
gifmfifoirq = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
FreezeXMMRegs(1);
|
FreezeXMMRegs(1);
|
||||||
|
@ -528,7 +571,7 @@ void gifMFIFOInterrupt()
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
//if(gifqwc > 0)SysPrintf("GIF MFIFO ending with stuff in it %x\n", gifqwc);
|
//if(gifqwc > 0)SysPrintf("GIF MFIFO ending with stuff in it %x\n", gifqwc);
|
||||||
gifqwc = 0;
|
if( gifmfifoirq == 0) gifqwc = 0;
|
||||||
gifstate = GIF_STATE_EMPTY;
|
gifstate = GIF_STATE_EMPTY;
|
||||||
gif->chcr &= ~0x100;
|
gif->chcr &= ~0x100;
|
||||||
hwDmacIrq(DMAC_GIF);
|
hwDmacIrq(DMAC_GIF);
|
||||||
|
|
|
@ -26,6 +26,9 @@
|
||||||
#define spr0 ((DMACh*)&PS2MEM_HW[0xD000])
|
#define spr0 ((DMACh*)&PS2MEM_HW[0xD000])
|
||||||
#define spr1 ((DMACh*)&PS2MEM_HW[0xD400])
|
#define spr1 ((DMACh*)&PS2MEM_HW[0xD400])
|
||||||
|
|
||||||
|
int spr0finished = 0;
|
||||||
|
int spr1finished = 0;
|
||||||
|
u32 mfifotransferred = 0;
|
||||||
void sprInit() {
|
void sprInit() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -74,6 +77,7 @@ int _SPR0chain() {
|
||||||
hwMFIFOWrite(spr0->madr, (u8*)&PS2MEM_SCRATCH[spr0->sadr & 0x3fff], spr0->qwc << 4);
|
hwMFIFOWrite(spr0->madr, (u8*)&PS2MEM_SCRATCH[spr0->sadr & 0x3fff], spr0->qwc << 4);
|
||||||
spr0->madr += spr0->qwc << 4;
|
spr0->madr += spr0->qwc << 4;
|
||||||
spr0->madr = psHu32(DMAC_RBOR) + (spr0->madr & psHu32(DMAC_RBSR));
|
spr0->madr = psHu32(DMAC_RBOR) + (spr0->madr & psHu32(DMAC_RBSR));
|
||||||
|
mfifotransferred += spr0->qwc;
|
||||||
} else {
|
} else {
|
||||||
memcpy_fast((u8*)pMem, &PS2MEM_SCRATCH[spr0->sadr & 0x3fff], spr0->qwc << 4);
|
memcpy_fast((u8*)pMem, &PS2MEM_SCRATCH[spr0->sadr & 0x3fff], spr0->qwc << 4);
|
||||||
Cpu->Clear(spr0->madr, spr0->qwc<<2);
|
Cpu->Clear(spr0->madr, spr0->qwc<<2);
|
||||||
|
@ -110,6 +114,7 @@ void _SPR0interleave() {
|
||||||
if ((psHu32(DMAC_CTRL) & 0xC) == 0xC || // GIF MFIFO
|
if ((psHu32(DMAC_CTRL) & 0xC) == 0xC || // GIF MFIFO
|
||||||
(psHu32(DMAC_CTRL) & 0xC) == 0x8) { // VIF1 MFIFO
|
(psHu32(DMAC_CTRL) & 0xC) == 0x8) { // VIF1 MFIFO
|
||||||
hwMFIFOWrite(spr0->madr, (u8*)&PS2MEM_SCRATCH[spr0->sadr & 0x3fff], spr0->qwc<<4);
|
hwMFIFOWrite(spr0->madr, (u8*)&PS2MEM_SCRATCH[spr0->sadr & 0x3fff], spr0->qwc<<4);
|
||||||
|
mfifotransferred += spr0->qwc;
|
||||||
} else {
|
} else {
|
||||||
Cpu->Clear(spr0->madr, spr0->qwc<<2);
|
Cpu->Clear(spr0->madr, spr0->qwc<<2);
|
||||||
// clear VU mem also!
|
// clear VU mem also!
|
||||||
|
@ -122,6 +127,7 @@ void _SPR0interleave() {
|
||||||
}
|
}
|
||||||
|
|
||||||
spr0->qwc = 0;
|
spr0->qwc = 0;
|
||||||
|
spr0finished = 1;
|
||||||
//CPU_INT(8, cycles);
|
//CPU_INT(8, cycles);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -142,6 +148,7 @@ static __forceinline void _dmaSPR0() {
|
||||||
int cycles = 0;
|
int cycles = 0;
|
||||||
SPR0chain();
|
SPR0chain();
|
||||||
//CPU_INT(8, cycles);
|
//CPU_INT(8, cycles);
|
||||||
|
spr0finished = 1;
|
||||||
|
|
||||||
return;
|
return;
|
||||||
} else if ((spr0->chcr & 0xc) == 0x4) {
|
} else if ((spr0->chcr & 0xc) == 0x4) {
|
||||||
|
@ -153,12 +160,12 @@ static __forceinline void _dmaSPR0() {
|
||||||
if(spr0->qwc > 0){
|
if(spr0->qwc > 0){
|
||||||
SPR0chain();
|
SPR0chain();
|
||||||
//CPU_INT(8, cycles);
|
//CPU_INT(8, cycles);
|
||||||
|
spr0finished = 1;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Destination Chain Mode
|
// Destination Chain Mode
|
||||||
|
|
||||||
while (done == 0) { // Loop while Dn_CHCR.STR is 1
|
//while (done == 0) { // Loop while Dn_CHCR.STR is 1
|
||||||
ptag = (u32*)&PS2MEM_SCRATCH[spr0->sadr & 0x3fff];
|
ptag = (u32*)&PS2MEM_SCRATCH[spr0->sadr & 0x3fff];
|
||||||
spr0->sadr+= 16;
|
spr0->sadr+= 16;
|
||||||
|
|
||||||
|
@ -171,7 +178,7 @@ static __forceinline void _dmaSPR0() {
|
||||||
spr0->qwc = (u16)ptag[0]; //QWC set to lower 16bits of the tag
|
spr0->qwc = (u16)ptag[0]; //QWC set to lower 16bits of the tag
|
||||||
spr0->madr = ptag[1]; //MADR = ADDR field
|
spr0->madr = ptag[1]; //MADR = ADDR field
|
||||||
|
|
||||||
SPR_LOG("dmaChain %8.8x_%8.8x size=%d, id=%d, addr=%lx\n",
|
SPR_LOG("spr0 dmaChain %8.8x_%8.8x size=%d, id=%d, addr=%lx spr=%lx\n",
|
||||||
ptag[1], ptag[0], spr0->qwc, id, spr0->madr);
|
ptag[1], ptag[0], spr0->qwc, id, spr0->madr);
|
||||||
|
|
||||||
if ((psHu32(DMAC_CTRL) & 0x30) == 0x20) { // STS == fromSPR
|
if ((psHu32(DMAC_CTRL) & 0x30) == 0x20) { // STS == fromSPR
|
||||||
|
@ -184,6 +191,7 @@ static __forceinline void _dmaSPR0() {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 1: // CNT - Transfer QWC following the tag.
|
case 1: // CNT - Transfer QWC following the tag.
|
||||||
|
done = 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 7: // End - Transfer QWC following the tag
|
case 7: // End - Transfer QWC following the tag
|
||||||
|
@ -195,7 +203,7 @@ static __forceinline void _dmaSPR0() {
|
||||||
//SysPrintf("SPR0 TIE\n");
|
//SysPrintf("SPR0 TIE\n");
|
||||||
done = 1;
|
done = 1;
|
||||||
spr0->qwc = 0;
|
spr0->qwc = 0;
|
||||||
break;
|
//break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -206,7 +214,17 @@ static __forceinline void _dmaSPR0() {
|
||||||
hwDmacIrq(8);
|
hwDmacIrq(8);
|
||||||
return;
|
return;
|
||||||
}*/
|
}*/
|
||||||
|
//}
|
||||||
|
spr0finished = done;
|
||||||
|
if(done == 0) {
|
||||||
|
ptag = (u32*)&PS2MEM_SCRATCH[spr0->sadr & 0x3fff]; //Set memory pointer to SADR
|
||||||
|
spr0->qwc = (u16)ptag[0]; //QWC set to lower 16bits of the tag
|
||||||
|
CPU_INT(8, spr0->qwc / BIAS);
|
||||||
|
spr0->qwc = 0;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
SPR_LOG("spr0 dmaChain complete %8.8x_%8.8x size=%d, id=%d, addr=%lx spr=%lx\n",
|
||||||
|
ptag[1], ptag[0], spr0->qwc, id, spr0->madr);
|
||||||
//CPU_INT(8, cycles);
|
//CPU_INT(8, cycles);
|
||||||
} else { // Interleave Mode
|
} else { // Interleave Mode
|
||||||
_SPR0interleave();
|
_SPR0interleave();
|
||||||
|
@ -221,7 +239,7 @@ extern void mfifoGIFtransfer(int);
|
||||||
|
|
||||||
void SPRFROMinterrupt()
|
void SPRFROMinterrupt()
|
||||||
{
|
{
|
||||||
int qwc = spr0->qwc;
|
//int qwc = spr0->qwc;
|
||||||
|
|
||||||
_dmaSPR0();
|
_dmaSPR0();
|
||||||
|
|
||||||
|
@ -229,15 +247,18 @@ void SPRFROMinterrupt()
|
||||||
if((spr0->madr & ~psHu32(DMAC_RBSR)) != psHu32(DMAC_RBOR)) SysPrintf("GIF MFIFO Write outside MFIFO area\n");
|
if((spr0->madr & ~psHu32(DMAC_RBSR)) != psHu32(DMAC_RBOR)) SysPrintf("GIF MFIFO Write outside MFIFO area\n");
|
||||||
spr0->madr = psHu32(DMAC_RBOR) + (spr0->madr & psHu32(DMAC_RBSR));
|
spr0->madr = psHu32(DMAC_RBOR) + (spr0->madr & psHu32(DMAC_RBSR));
|
||||||
//SysPrintf("mfifoGIFtransfer %x madr %x, tadr %x\n", gif->chcr, gif->madr, gif->tadr);
|
//SysPrintf("mfifoGIFtransfer %x madr %x, tadr %x\n", gif->chcr, gif->madr, gif->tadr);
|
||||||
mfifoGIFtransfer(qwc);
|
mfifoGIFtransfer(mfifotransferred);
|
||||||
|
mfifotransferred = 0;
|
||||||
} else
|
} else
|
||||||
if ((psHu32(DMAC_CTRL) & 0xC) == 0x8) { // VIF1 MFIFO
|
if ((psHu32(DMAC_CTRL) & 0xC) == 0x8) { // VIF1 MFIFO
|
||||||
if((spr0->madr & ~psHu32(DMAC_RBSR)) != psHu32(DMAC_RBOR)) SysPrintf("VIF MFIFO Write outside MFIFO area\n");
|
if((spr0->madr & ~psHu32(DMAC_RBSR)) != psHu32(DMAC_RBOR)) SysPrintf("VIF MFIFO Write outside MFIFO area\n");
|
||||||
spr0->madr = psHu32(DMAC_RBOR) + (spr0->madr & psHu32(DMAC_RBSR));
|
spr0->madr = psHu32(DMAC_RBOR) + (spr0->madr & psHu32(DMAC_RBSR));
|
||||||
//SysPrintf("mfifoVIF1transfer %x madr %x, tadr %x\n", vif1ch->chcr, vif1ch->madr, vif1ch->tadr);
|
//SysPrintf("mfifoVIF1transfer %x madr %x, tadr %x\n", vif1ch->chcr, vif1ch->madr, vif1ch->tadr);
|
||||||
//vifqwc+= qwc;
|
//vifqwc+= qwc;
|
||||||
mfifoVIF1transfer(qwc);
|
mfifoVIF1transfer(mfifotransferred);
|
||||||
|
mfifotransferred = 0;
|
||||||
}
|
}
|
||||||
|
if(spr0finished == 0) return;
|
||||||
spr0->chcr&= ~0x100;
|
spr0->chcr&= ~0x100;
|
||||||
hwDmacIrq(8);
|
hwDmacIrq(8);
|
||||||
}
|
}
|
||||||
|
@ -249,10 +270,18 @@ void dmaSPR0() { // fromSPR
|
||||||
SPR_LOG("dmaSPR0 chcr = %lx, madr = %lx, qwc = %lx, sadr = %lx\n",
|
SPR_LOG("dmaSPR0 chcr = %lx, madr = %lx, qwc = %lx, sadr = %lx\n",
|
||||||
spr0->chcr, spr0->madr, spr0->qwc, spr0->sadr);
|
spr0->chcr, spr0->madr, spr0->qwc, spr0->sadr);
|
||||||
|
|
||||||
|
if ((spr0->chcr & 0xc) == 0x4){
|
||||||
|
u32 *ptag;
|
||||||
|
ptag = (u32*)&PS2MEM_SCRATCH[spr0->sadr & 0x3fff]; //Set memory pointer to SADR
|
||||||
|
spr0->qwc = (u16)ptag[0]; //QWC set to lower 16bits of the tag
|
||||||
|
CPU_INT(8, spr0->qwc / BIAS);
|
||||||
|
spr0->qwc = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
// COMPLETE HACK!!! For now at least.. FFX Videos dont rely on interrupts or reading DMA values
|
// 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)
|
// 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)
|
// This "shouldn't" cause any problems as SPR is generally faster than the other DMAS anyway. (Refraction)
|
||||||
CPU_INT(8, spr0->qwc / 2);
|
CPU_INT(8, spr0->qwc / BIAS);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -310,6 +339,7 @@ void _SPR1interleave() {
|
||||||
}
|
}
|
||||||
|
|
||||||
spr1->qwc = 0;
|
spr1->qwc = 0;
|
||||||
|
spr1finished = 1;
|
||||||
//CPU_INT(9, cycles);
|
//CPU_INT(9, cycles);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -320,31 +350,35 @@ void _dmaSPR1() { // toSPR work function
|
||||||
//if(spr1->qwc == 0 && (spr1->chcr & 0xc) == 1) spr1->qwc = 0xffff;
|
//if(spr1->qwc == 0 && (spr1->chcr & 0xc) == 1) spr1->qwc = 0xffff;
|
||||||
// Transfer Dn_QWC from Dn_MADR to SPR1
|
// Transfer Dn_QWC from Dn_MADR to SPR1
|
||||||
SPR1chain();
|
SPR1chain();
|
||||||
|
spr1finished = 1;
|
||||||
//CPU_INT(9, cycles);
|
//CPU_INT(9, cycles);
|
||||||
return;
|
return;
|
||||||
} else if ((spr1->chcr & 0xc) == 0x4){
|
} else
|
||||||
|
if ((spr1->chcr & 0xc) == 0x4){
|
||||||
int cycles = 0;
|
int cycles = 0;
|
||||||
u32 *ptag;
|
u32 *ptag;
|
||||||
int id, done=0;
|
int id, done=0;
|
||||||
|
|
||||||
|
|
||||||
if(spr1->qwc > 0){
|
if(spr1->qwc > 0){
|
||||||
//if(spr1->qwc == 0 && (spr1->chcr & 0xc) == 1) spr1->qwc = 0xffff;
|
//if(spr1->qwc == 0 && (spr1->chcr & 0xc) == 1) spr1->qwc = 0xffff;
|
||||||
// Transfer Dn_QWC from Dn_MADR to SPR1
|
// Transfer Dn_QWC from Dn_MADR to SPR1
|
||||||
SPR1chain();
|
SPR1chain();
|
||||||
//CPU_INT(9, cycles);
|
spr1finished = 1;
|
||||||
return;
|
//CPU_INT(9, cycles);
|
||||||
}
|
return;
|
||||||
|
}
|
||||||
// Chain Mode
|
// Chain Mode
|
||||||
|
|
||||||
while (done == 0) { // Loop while Dn_CHCR.STR is 1
|
// while (done == 0) { // Loop while Dn_CHCR.STR is 1
|
||||||
ptag = (u32*)dmaGetAddr(spr1->tadr); //Set memory pointer to TADR
|
ptag = (u32*)dmaGetAddr(spr1->tadr); //Set memory pointer to TADR
|
||||||
if (ptag == NULL) { //Is ptag empty?
|
if (ptag == NULL) { //Is ptag empty?
|
||||||
SysPrintf("SPR1 Tag BUSERR\n");
|
SysPrintf("SPR1 Tag BUSERR\n");
|
||||||
spr1->chcr = ( spr1->chcr & 0xFFFF ) | ( (*ptag) & 0xFFFF0000 ); //Transfer upper part of tag to CHCR bits 31-15
|
spr1->chcr = ( spr1->chcr & 0xFFFF ) | ( (*ptag) & 0xFFFF0000 ); //Transfer upper part of tag to CHCR bits 31-15
|
||||||
psHu32(DMAC_STAT)|= 1<<15; //If yes, set BEIS (BUSERR) in DMAC_STAT register
|
psHu32(DMAC_STAT)|= 1<<15; //If yes, set BEIS (BUSERR) in DMAC_STAT register
|
||||||
done = 1;
|
done = 1;
|
||||||
break;
|
spr1finished = done;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
spr1->chcr = ( spr1->chcr & 0xFFFF ) | ( (*ptag) & 0xFFFF0000 ); //Transfer upper part of tag to CHCR bits 31-15
|
spr1->chcr = ( spr1->chcr & 0xFFFF ) | ( (*ptag) & 0xFFFF0000 ); //Transfer upper part of tag to CHCR bits 31-15
|
||||||
|
|
||||||
|
@ -358,7 +392,7 @@ void _dmaSPR1() { // toSPR work function
|
||||||
SPR1transfer(ptag, 4); //Transfer Tag
|
SPR1transfer(ptag, 4); //Transfer Tag
|
||||||
}
|
}
|
||||||
|
|
||||||
SPR_LOG("dmaChain %8.8x_%8.8x size=%d, id=%d, addr=%lx\n",
|
SPR_LOG("spr1 dmaChain %8.8x_%8.8x size=%d, id=%d, addr=%lx\n",
|
||||||
ptag[1], ptag[0], spr1->qwc, id, spr1->madr);
|
ptag[1], ptag[0], spr1->qwc, id, spr1->madr);
|
||||||
|
|
||||||
done = hwDmacSrcChain(spr1, id);
|
done = hwDmacSrcChain(spr1, id);
|
||||||
|
@ -369,9 +403,17 @@ void _dmaSPR1() { // toSPR work function
|
||||||
|
|
||||||
//SysPrintf("SPR1 TIE\n");
|
//SysPrintf("SPR1 TIE\n");
|
||||||
spr1->qwc = 0;
|
spr1->qwc = 0;
|
||||||
break;
|
done = 1;
|
||||||
|
// break;
|
||||||
|
}
|
||||||
|
//}
|
||||||
|
spr1finished = done;
|
||||||
|
if(done == 0) {
|
||||||
|
ptag = (u32*)dmaGetAddr(spr1->tadr); //Set memory pointer to TADR
|
||||||
|
spr1->qwc = (u16)ptag[0]; //QWC set to lower 16bits of the tag
|
||||||
|
CPU_INT(9, spr1->qwc / BIAS);
|
||||||
|
spr1->qwc = 0;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
} else { // Interleave Mode
|
} else { // Interleave Mode
|
||||||
_SPR1interleave();
|
_SPR1interleave();
|
||||||
}
|
}
|
||||||
|
@ -387,10 +429,18 @@ void dmaSPR1() { // toSPR
|
||||||
spr1->tadr, spr1->sadr);
|
spr1->tadr, spr1->sadr);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if ((spr1->chcr & 0xc) == 0x4){
|
||||||
|
u32 *ptag;
|
||||||
|
ptag = (u32*)dmaGetAddr(spr1->tadr); //Set memory pointer to TADR
|
||||||
|
spr1->qwc = (u16)ptag[0]; //QWC set to lower 16bits of the tag
|
||||||
|
CPU_INT(9, spr1->qwc / BIAS);
|
||||||
|
spr1->qwc = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
// COMPLETE HACK!!! For now at least.. FFX Videos dont rely on interrupts or reading DMA values
|
// 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)
|
// 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)
|
// This "shouldn't" cause any problems as SPR is generally faster than the other DMAS anyway. (Refraction)
|
||||||
CPU_INT(9, spr1->qwc / 2);
|
CPU_INT(9, spr1->qwc / BIAS);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -398,6 +448,7 @@ void dmaSPR1() { // toSPR
|
||||||
void SPRTOinterrupt()
|
void SPRTOinterrupt()
|
||||||
{
|
{
|
||||||
_dmaSPR1();
|
_dmaSPR1();
|
||||||
|
if( spr1finished == 0 ) return;
|
||||||
spr1->chcr &= ~0x100;
|
spr1->chcr &= ~0x100;
|
||||||
hwDmacIrq(9);
|
hwDmacIrq(9);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue