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.
|
||||
// fixme - this hack *should* have the gs_irq raised from the VIF, I think. It would be
|
||||
// more efficient and more correct. (air)
|
||||
if (!(vif1Regs->mskpath3 && (vif1ch->chcr & 0x100)) || (psHu32(GIF_MODE) & 0x1))
|
||||
CPU_INT( 2, 64 );
|
||||
/*if (!(vif1Regs->mskpath3 && (vif1ch->chcr & 0x100)) || (psHu32(GIF_MODE) & 0x1))
|
||||
CPU_INT( 2, 64 );*/
|
||||
#endif
|
||||
return;
|
||||
if(gspath3done == 0) return;
|
||||
}
|
||||
|
||||
gspath3done = 0;
|
||||
|
@ -254,6 +254,7 @@ void GIFdma()
|
|||
FreezeXMMRegs(0);
|
||||
FreezeMMXRegs(0);
|
||||
if(gif->qwc == 0 && (gif->chcr & 0xc) == 0) gspath3done = 1;
|
||||
return;
|
||||
}
|
||||
else {
|
||||
// Chain Mode
|
||||
|
@ -311,9 +312,18 @@ void GIFdma()
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
prevcycles = 0;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
//} //It takes the time of 24 QW for the BUS to become ready - The Punisher, And1 Streetball
|
||||
//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
|
||||
//SysPrintf("GIF MFIFO\n");
|
||||
SysPrintf("GIF MFIFO\n");
|
||||
gifMFIFOInterrupt();
|
||||
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])
|
||||
|
@ -417,7 +455,7 @@ static __forceinline int mfifoGIFchain() {
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int gifmfifoirq = 0;
|
||||
|
||||
void mfifoGIFtransfer(int qwc) {
|
||||
u32 *ptag;
|
||||
|
@ -425,6 +463,8 @@ void mfifoGIFtransfer(int qwc) {
|
|||
u32 temp = 0;
|
||||
mfifocycles = 0;
|
||||
|
||||
gifmfifoirq = 0;
|
||||
|
||||
if(qwc > 0 ) {
|
||||
gifqwc += qwc;
|
||||
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);
|
||||
|
||||
|
||||
|
||||
if(gif->qwc == 0){
|
||||
if(gif->tadr == spr0->madr) {
|
||||
#ifdef PCSX2_DEVBUILD
|
||||
|
@ -489,6 +531,7 @@ void mfifoGIFtransfer(int qwc) {
|
|||
if ((gif->chcr & 0x80) && (ptag[0] >> 31)) {
|
||||
SPR_LOG("dmaIrq Set\n");
|
||||
gifstate = GIF_STATE_DONE;
|
||||
gifmfifoirq = 1;
|
||||
}
|
||||
}
|
||||
FreezeXMMRegs(1);
|
||||
|
@ -528,7 +571,7 @@ void gifMFIFOInterrupt()
|
|||
}
|
||||
#endif
|
||||
//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;
|
||||
gif->chcr &= ~0x100;
|
||||
hwDmacIrq(DMAC_GIF);
|
||||
|
|
|
@ -26,6 +26,9 @@
|
|||
#define spr0 ((DMACh*)&PS2MEM_HW[0xD000])
|
||||
#define spr1 ((DMACh*)&PS2MEM_HW[0xD400])
|
||||
|
||||
int spr0finished = 0;
|
||||
int spr1finished = 0;
|
||||
u32 mfifotransferred = 0;
|
||||
void sprInit() {
|
||||
}
|
||||
|
||||
|
@ -74,6 +77,7 @@ int _SPR0chain() {
|
|||
hwMFIFOWrite(spr0->madr, (u8*)&PS2MEM_SCRATCH[spr0->sadr & 0x3fff], spr0->qwc << 4);
|
||||
spr0->madr += spr0->qwc << 4;
|
||||
spr0->madr = psHu32(DMAC_RBOR) + (spr0->madr & psHu32(DMAC_RBSR));
|
||||
mfifotransferred += spr0->qwc;
|
||||
} else {
|
||||
memcpy_fast((u8*)pMem, &PS2MEM_SCRATCH[spr0->sadr & 0x3fff], spr0->qwc << 4);
|
||||
Cpu->Clear(spr0->madr, spr0->qwc<<2);
|
||||
|
@ -110,6 +114,7 @@ void _SPR0interleave() {
|
|||
if ((psHu32(DMAC_CTRL) & 0xC) == 0xC || // GIF MFIFO
|
||||
(psHu32(DMAC_CTRL) & 0xC) == 0x8) { // VIF1 MFIFO
|
||||
hwMFIFOWrite(spr0->madr, (u8*)&PS2MEM_SCRATCH[spr0->sadr & 0x3fff], spr0->qwc<<4);
|
||||
mfifotransferred += spr0->qwc;
|
||||
} else {
|
||||
Cpu->Clear(spr0->madr, spr0->qwc<<2);
|
||||
// clear VU mem also!
|
||||
|
@ -122,6 +127,7 @@ void _SPR0interleave() {
|
|||
}
|
||||
|
||||
spr0->qwc = 0;
|
||||
spr0finished = 1;
|
||||
//CPU_INT(8, cycles);
|
||||
}
|
||||
|
||||
|
@ -142,6 +148,7 @@ static __forceinline void _dmaSPR0() {
|
|||
int cycles = 0;
|
||||
SPR0chain();
|
||||
//CPU_INT(8, cycles);
|
||||
spr0finished = 1;
|
||||
|
||||
return;
|
||||
} else if ((spr0->chcr & 0xc) == 0x4) {
|
||||
|
@ -153,12 +160,12 @@ static __forceinline void _dmaSPR0() {
|
|||
if(spr0->qwc > 0){
|
||||
SPR0chain();
|
||||
//CPU_INT(8, cycles);
|
||||
|
||||
spr0finished = 1;
|
||||
return;
|
||||
}
|
||||
// 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];
|
||||
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->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);
|
||||
|
||||
if ((psHu32(DMAC_CTRL) & 0x30) == 0x20) { // STS == fromSPR
|
||||
|
@ -184,6 +191,7 @@ static __forceinline void _dmaSPR0() {
|
|||
break;
|
||||
|
||||
case 1: // CNT - Transfer QWC following the tag.
|
||||
done = 0;
|
||||
break;
|
||||
|
||||
case 7: // End - Transfer QWC following the tag
|
||||
|
@ -195,7 +203,7 @@ static __forceinline void _dmaSPR0() {
|
|||
//SysPrintf("SPR0 TIE\n");
|
||||
done = 1;
|
||||
spr0->qwc = 0;
|
||||
break;
|
||||
//break;
|
||||
}
|
||||
|
||||
|
||||
|
@ -206,7 +214,17 @@ static __forceinline void _dmaSPR0() {
|
|||
hwDmacIrq(8);
|
||||
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);
|
||||
} else { // Interleave Mode
|
||||
_SPR0interleave();
|
||||
|
@ -221,7 +239,7 @@ extern void mfifoGIFtransfer(int);
|
|||
|
||||
void SPRFROMinterrupt()
|
||||
{
|
||||
int qwc = spr0->qwc;
|
||||
//int qwc = spr0->qwc;
|
||||
|
||||
_dmaSPR0();
|
||||
|
||||
|
@ -229,15 +247,18 @@ void SPRFROMinterrupt()
|
|||
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));
|
||||
//SysPrintf("mfifoGIFtransfer %x madr %x, tadr %x\n", gif->chcr, gif->madr, gif->tadr);
|
||||
mfifoGIFtransfer(qwc);
|
||||
mfifoGIFtransfer(mfifotransferred);
|
||||
mfifotransferred = 0;
|
||||
} else
|
||||
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");
|
||||
spr0->madr = psHu32(DMAC_RBOR) + (spr0->madr & psHu32(DMAC_RBSR));
|
||||
//SysPrintf("mfifoVIF1transfer %x madr %x, tadr %x\n", vif1ch->chcr, vif1ch->madr, vif1ch->tadr);
|
||||
//vifqwc+= qwc;
|
||||
mfifoVIF1transfer(qwc);
|
||||
mfifoVIF1transfer(mfifotransferred);
|
||||
mfifotransferred = 0;
|
||||
}
|
||||
if(spr0finished == 0) return;
|
||||
spr0->chcr&= ~0x100;
|
||||
hwDmacIrq(8);
|
||||
}
|
||||
|
@ -249,10 +270,18 @@ void dmaSPR0() { // fromSPR
|
|||
SPR_LOG("dmaSPR0 chcr = %lx, madr = %lx, qwc = %lx, sadr = %lx\n",
|
||||
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
|
||||
// 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(8, spr0->qwc / 2);
|
||||
CPU_INT(8, spr0->qwc / BIAS);
|
||||
|
||||
|
||||
|
||||
|
@ -310,6 +339,7 @@ void _SPR1interleave() {
|
|||
}
|
||||
|
||||
spr1->qwc = 0;
|
||||
spr1finished = 1;
|
||||
//CPU_INT(9, cycles);
|
||||
|
||||
}
|
||||
|
@ -320,31 +350,35 @@ void _dmaSPR1() { // toSPR work function
|
|||
//if(spr1->qwc == 0 && (spr1->chcr & 0xc) == 1) spr1->qwc = 0xffff;
|
||||
// Transfer Dn_QWC from Dn_MADR to SPR1
|
||||
SPR1chain();
|
||||
spr1finished = 1;
|
||||
//CPU_INT(9, cycles);
|
||||
return;
|
||||
} else if ((spr1->chcr & 0xc) == 0x4){
|
||||
} else
|
||||
if ((spr1->chcr & 0xc) == 0x4){
|
||||
int cycles = 0;
|
||||
u32 *ptag;
|
||||
int id, done=0;
|
||||
|
||||
|
||||
if(spr1->qwc > 0){
|
||||
//if(spr1->qwc == 0 && (spr1->chcr & 0xc) == 1) spr1->qwc = 0xffff;
|
||||
// Transfer Dn_QWC from Dn_MADR to SPR1
|
||||
SPR1chain();
|
||||
//CPU_INT(9, cycles);
|
||||
return;
|
||||
}
|
||||
if(spr1->qwc > 0){
|
||||
//if(spr1->qwc == 0 && (spr1->chcr & 0xc) == 1) spr1->qwc = 0xffff;
|
||||
// Transfer Dn_QWC from Dn_MADR to SPR1
|
||||
SPR1chain();
|
||||
spr1finished = 1;
|
||||
//CPU_INT(9, cycles);
|
||||
return;
|
||||
}
|
||||
// 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
|
||||
if (ptag == NULL) { //Is ptag empty?
|
||||
SysPrintf("SPR1 Tag BUSERR\n");
|
||||
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
|
||||
done = 1;
|
||||
break;
|
||||
spr1finished = done;
|
||||
return;
|
||||
}
|
||||
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
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
done = hwDmacSrcChain(spr1, id);
|
||||
|
@ -369,9 +403,17 @@ void _dmaSPR1() { // toSPR work function
|
|||
|
||||
//SysPrintf("SPR1 TIE\n");
|
||||
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
|
||||
_SPR1interleave();
|
||||
}
|
||||
|
@ -387,10 +429,18 @@ void dmaSPR1() { // toSPR
|
|||
spr1->tadr, spr1->sadr);
|
||||
#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
|
||||
// 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(9, spr1->qwc / 2);
|
||||
CPU_INT(9, spr1->qwc / BIAS);
|
||||
|
||||
|
||||
}
|
||||
|
@ -398,6 +448,7 @@ void dmaSPR1() { // toSPR
|
|||
void SPRTOinterrupt()
|
||||
{
|
||||
_dmaSPR1();
|
||||
if( spr1finished == 0 ) return;
|
||||
spr1->chcr &= ~0x100;
|
||||
hwDmacIrq(9);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue