Rbor, rbsr, and other such things.

git-svn-id: http://pcsx2.googlecode.com/svn/trunk@1887 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
arcum42 2009-09-20 01:47:45 +00:00
parent 8234604dce
commit 8f4538ae0c
4 changed files with 54 additions and 44 deletions

View File

@ -86,7 +86,7 @@ __forceinline void gsInterrupt()
gif->chcr.STR = 0;
vif1Regs->stat &= ~VIF1_STAT_VGW;
psHu32(GIF_STAT) &= ~(GIF_STAT_APATH3 | GIF_STAT_OPH | GIF_STAT_P3Q | GIF_STAT_FQC);
gifRegs->stat._u32 &= ~(GIF_STAT_APATH3 | GIF_STAT_OPH | GIF_STAT_P3Q | GIF_STAT_FQC);
clearFIFOstuff(false);
hwDmacIrq(DMAC_GIF);
@ -188,7 +188,7 @@ void GIFdma()
{
Console::WriteLn("GS Stall Control Source = %x, Drain = %x\n MADR = %x, STADR = %x", (psHu32(0xe000) >> 4) & 0x3, (psHu32(0xe000) >> 6) & 0x3, gif->madr, psHu32(DMAC_STADR));
if ((gif->madr + (gif->qwc * 16)) > psHu32(DMAC_STADR))
if ((gif->madr + (gif->qwc * 16)) > dmacRegs->stadr.ADDR)
{
CPU_INT(2, gscycles);
gscycles = 0;
@ -201,12 +201,11 @@ void GIFdma()
clearFIFOstuff(true);
gifRegs->stat.FQC |= 0x10;// FQC=31, hack ;) (for values of 31 that equal 16) [ used to be 0xE00; // OPH=1 | APATH=3]
//psHu32(GIF_STAT) |= 0x10000000;
//Path2 gets priority in intermittent mode
if ((gifRegs->stat.P1Q || (vif1.cmd & 0x7f) == 0x50) && gifRegs->mode.IMT && (Path3progress == IMAGE_MODE))
{
GIF_LOG("Waiting VU %x, PATH2 %x, GIFMODE %x Progress %x", psHu32(GIF_STAT) & 0x100, (vif1.cmd & 0x7f), psHu32(GIF_MODE), Path3progress);
GIF_LOG("Waiting VU %x, PATH2 %x, GIFMODE %x Progress %x", gifRegs->stat.P1Q, (vif1.cmd & 0x7f), gifRegs->mode._u32, Path3progress);
CPU_INT(2, 16);
return;
}
@ -260,7 +259,7 @@ void GIFdma()
if (dmacRegs->ctrl.STD == STD_GIF)
{
// there are still bugs, need to also check if gif->madr +16*qwc >= stadr, if not, stall
if (!gspath3done && ((gif->madr + (gif->qwc * 16)) > psHu32(DMAC_STADR)) && (id == 4))
if (!gspath3done && ((gif->madr + (gif->qwc * 16)) > dmacRegs->stadr.ADDR) && (id == 4))
{
// stalled
Console::WriteLn("GS Stall Control Source = %x, Drain = %x\n MADR = %x, STADR = %x", (psHu32(0xe000) >> 4) & 0x3, (psHu32(0xe000) >> 6) & 0x3,gif->madr, psHu32(DMAC_STADR));
@ -307,10 +306,10 @@ void dmaGIF()
Path3progress = STOPPED_MODE;
gspath3done = 0; // For some reason this doesn't clear? So when the system starts the thread, we will clear it :)
psHu32(GIF_STAT) |= GIF_STAT_P3Q;
gifRegs->stat.P3Q = 1;
gifRegs->stat.FQC |= 0x10;// FQC=31, hack ;) ( 31? 16! arcum42) [used to be 0xE00; // OPH=1 | APATH=3]
//psHu32(GIF_STAT) |= 0x10000000;
clearFIFOstuff(true);
if (dmacRegs->ctrl.MFD == MFD_GIF) // GIF MFIFO
@ -345,9 +344,9 @@ static __forceinline int mfifoGIFrbTransfer()
u32 *src;
/* Check if the transfer should wrap around the ring buffer */
if ((gif->madr+mfifoqwc*16) > (psHu32(DMAC_RBOR) + psHu32(DMAC_RBSR)+16))
if ((gif->madr + mfifoqwc * 16) > (dmacRegs->rbor.ADDR + dmacRegs->rbsr.RMSK + 16))
{
int s1 = ((psHu32(DMAC_RBOR) + psHu32(DMAC_RBSR)+16) - gif->madr) >> 4;
int s1 = ((dmacRegs->rbor.ADDR + dmacRegs->rbsr.RMSK + 16) - gif->madr) >> 4;
int s2 = (mfifoqwc - s1);
// fixme - I don't think these should use WRITERING_DMA, since our source
// isn't the DmaGetAddr(gif->madr) address that WRITERING_DMA expects.
@ -360,7 +359,7 @@ static __forceinline int mfifoGIFrbTransfer()
if (s1 == (mfifoqwc - s2))
{
/* and second copy 's2' bytes from 'maddr' to '&data[s1]' */
src = (u32*)PSM(psHu32(DMAC_RBOR));
src = (u32*)PSM(dmacRegs->rbor.ADDR);
if (src == NULL) return -1;
s2 = WRITERING_DMA(src, s2);
}
@ -377,7 +376,7 @@ static __forceinline int mfifoGIFrbTransfer()
src = (u32*)PSM(gif->madr);
if (src == NULL) return -1;
mfifoqwc = WRITERING_DMA(src, mfifoqwc);
gif->madr = psHu32(DMAC_RBOR) + (gif->madr & psHu32(DMAC_RBSR));
gif->madr = dmacRegs->rbor.ADDR + (gif->madr & dmacRegs->rbsr.RMSK);
}
gifqwc -= mfifoqwc;
@ -391,8 +390,8 @@ static __forceinline int mfifoGIFchain()
/* Is QWC = 0? if so there is nothing to transfer */
if (gif->qwc == 0) return 0;
if (gif->madr >= psHu32(DMAC_RBOR) &&
gif->madr <= (psHu32(DMAC_RBOR) + psHu32(DMAC_RBSR)))
if (gif->madr >= dmacRegs->rbor.ADDR &&
gif->madr <= (dmacRegs->rbor.ADDR + dmacRegs->rbsr.RMSK))
{
if (mfifoGIFrbTransfer() == -1) return -1;
}
@ -408,6 +407,11 @@ static __forceinline int mfifoGIFchain()
return 0;
}
static u32 qwctag(u32 mask)
{
return (dmacRegs->rbor.ADDR + (mask & dmacRegs->rbsr.RMSK));
}
void mfifoGIFtransfer(int qwc)
{
u32 *ptag;
@ -436,7 +440,7 @@ void mfifoGIFtransfer(int qwc)
return;
}
gif->tadr = psHu32(DMAC_RBOR) + (gif->tadr & psHu32(DMAC_RBSR));
gif->tadr = qwctag(gif->tadr);
ptag = (u32*)dmaGetAddr(gif->tadr);
Tag::UnsafeTransfer(gif, ptag);
@ -449,35 +453,36 @@ void mfifoGIFtransfer(int qwc)
ptag[1], ptag[0], gif->qwc, id, gif->madr, gif->tadr, gifqwc, spr0->madr);
gifqwc--;
switch (id)
{
case TAG_REFE: // Refe - Transfer Packet According to ADDR field
gif->tadr = psHu32(DMAC_RBOR) + ((gif->tadr + 16) & psHu32(DMAC_RBSR));
gif->tadr = qwctag(gif->tadr + 16);
gifstate = GIF_STATE_DONE; //End Transfer
break;
case TAG_CNT: // 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
gif->madr = qwctag(gif->tadr + 16); //Set MADR to QW after Tag
gif->tadr = qwctag(gif->madr + (gif->qwc << 4)); //Set TADR to QW following the data
gifstate = GIF_STATE_READY;
break;
case TAG_NEXT: // 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->madr = qwctag(gif->tadr + 16); //Set MADR to QW following the tag
gif->tadr = temp; //Copy temporarily stored ADDR to Tag
gifstate = GIF_STATE_READY;
break;
case TAG_REF: // Ref - Transfer QWC from ADDR field
case TAG_REFS: // Refs - Transfer QWC from ADDR field (Stall Control)
gif->tadr = psHu32(DMAC_RBOR) + ((gif->tadr + 16) & psHu32(DMAC_RBSR)); //Set TADR to next tag
gif->tadr = qwctag(gif->tadr + 16); //Set TADR to next tag
gifstate = GIF_STATE_READY;
break;
case TAG_END: // 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
gif->madr = qwctag(gif->tadr + 16); //Set MADR to data following the tag
gif->tadr = qwctag(gif->madr + (gif->qwc << 4)); //Set TADR to QW following the data
gifstate = GIF_STATE_DONE; //End Transfer
break;
}
@ -556,7 +561,7 @@ void gifMFIFOInterrupt()
gspath3done = 0;
gscycles = 0;
psHu32(GIF_STAT) &= ~(GIF_STAT_APATH3 | GIF_STAT_OPH | GIF_STAT_P3Q | GIF_STAT_FQC); // OPH, APATH, P3Q, FQC = 0
gifRegs->stat._u32 &= ~(GIF_STAT_APATH3 | GIF_STAT_OPH | GIF_STAT_P3Q | GIF_STAT_FQC); // OPH, APATH, P3Q, FQC = 0
vif1Regs->stat &= ~VIF1_STAT_VGW;
gif->chcr.STR = 0;

View File

@ -62,14 +62,14 @@ int _SPR0chain()
{
case MFD_VIF1:
case MFD_GIF:
if ((spr0->madr & ~psHu32(DMAC_RBSR)) != psHu32(DMAC_RBOR))
if ((spr0->madr & ~dmacRegs->rbsr.RMSK) != dmacRegs->rbor.ADDR)
Console::WriteLn("SPR MFIFO Write outside MFIFO area");
else
mfifotransferred += spr0->qwc;
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));
spr0->madr = dmacRegs->rbor.ADDR + (spr0->madr & dmacRegs->rbsr.RMSK);
break;
case NO_MFD:
@ -139,7 +139,7 @@ static __forceinline void _dmaSPR0()
{
if (dmacRegs->ctrl.STS == STS_fromSPR)
{
Console::WriteLn("SPR0 stall %d", (psHu32(DMAC_CTRL) >> 6)&3);
Console::WriteLn("SPR0 stall %d", dmacRegs->ctrl.STS);
}
// Transfer Dn_QWC from SPR to Dn_MADR
@ -183,7 +183,7 @@ static __forceinline void _dmaSPR0()
switch (id)
{
case TAG_CNTS: // CNTS - Transfer QWC following the tag (Stall Control)
if (dmacRegs->ctrl.STS == STS_fromSPR) psHu32(DMAC_STADR) = spr0->madr + (spr0->qwc * 16); //Copy MADR to DMAC_STADR stall addr register
if (dmacRegs->ctrl.STS == STS_fromSPR) dmacRegs->stadr.ADDR = spr0->madr + (spr0->qwc * 16); //Copy MADR to DMAC_STADR stall addr register
break;
case TAG_CNT: // CNT - Transfer QWC following the tag.
@ -232,8 +232,8 @@ void SPRFROMinterrupt()
{
case MFD_GIF:
{
if ((spr0->madr & ~psHu32(DMAC_RBSR)) != psHu32(DMAC_RBOR)) Console::WriteLn("GIF MFIFO Write outside MFIFO area");
spr0->madr = psHu32(DMAC_RBOR) + (spr0->madr & psHu32(DMAC_RBSR));
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;
@ -243,7 +243,7 @@ void SPRFROMinterrupt()
case MFD_VIF1:
{
if ((spr0->madr & ~psHu32(DMAC_RBSR)) != psHu32(DMAC_RBOR)) Console::WriteLn("VIF MFIFO Write outside MFIFO area");
spr0->madr = psHu32(DMAC_RBOR) + (spr0->madr & psHu32(DMAC_RBSR));
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;

View File

@ -338,8 +338,8 @@ void __fastcall UNPACK_V4_8u(u32 *dest, u32 *data, int size)
static __forceinline int mfifoVIF1rbTransfer()
{
u32 maddr = psHu32(DMAC_RBOR);
u32 ret, msize = psHu32(DMAC_RBOR) + psHu32(DMAC_RBSR) + 16;
u32 maddr = dmacRegs->rbor.ADDR;
u32 ret, msize = dmacRegs->rbor.ADDR + dmacRegs->rbsr.RMSK + 16;
u16 mfifoqwc = std::min(vif1ch->qwc, vifqwc);
u32 *src;
@ -398,8 +398,8 @@ static __forceinline int mfifo_VIF1chain()
return 0;
}
if (vif1ch->madr >= psHu32(DMAC_RBOR) &&
vif1ch->madr <= (psHu32(DMAC_RBOR) + psHu32(DMAC_RBSR)))
if (vif1ch->madr >= dmacRegs->rbor.ADDR &&
vif1ch->madr <= (dmacRegs->rbor.ADDR + dmacRegs->rbsr.RMSK))
{
u16 startqwc = vif1ch->qwc;
ret = mfifoVIF1rbTransfer();
@ -420,6 +420,11 @@ static __forceinline int mfifo_VIF1chain()
return ret;
}
static u32 qwctag(u32 mask)
{
return (dmacRegs->rbor.ADDR + (mask & dmacRegs->rbsr.RMSK));
}
void mfifoVIF1transfer(int qwc)
{
u32 *ptag;
@ -434,7 +439,7 @@ void mfifoVIF1transfer(int qwc)
SPR_LOG("Added %x qw to mfifo, total now %x - Vif CHCR %x Stalled %x done %x", qwc, vifqwc, vif1ch->chcr._u32, vif1.vifstalled, vif1.done);
if (vif1.inprogress & 0x10)
{
if (vif1ch->madr >= psHu32(DMAC_RBOR) && vif1ch->madr <= (psHu32(DMAC_RBOR) + psHu32(DMAC_RBSR)))
if (vif1ch->madr >= dmacRegs->rbor.ADDR && vif1ch->madr <= (dmacRegs->rbor.ADDR + dmacRegs->rbsr.RMSK))
CPU_INT(10, 0);
else
CPU_INT(10, vif1ch->qwc * BIAS);
@ -477,35 +482,35 @@ void mfifoVIF1transfer(int qwc)
switch (id)
{
case TAG_REFE: // Refe - Transfer Packet According to ADDR field
vif1ch->tadr = psHu32(DMAC_RBOR) + ((vif1ch->tadr + 16) & psHu32(DMAC_RBSR));
vif1ch->tadr = qwctag(vif1ch->tadr + 16);
vif1.done = true; //End Transfer
break;
case TAG_CNT: // CNT - Transfer QWC following the tag.
vif1ch->madr = psHu32(DMAC_RBOR) + ((vif1ch->tadr + 16) & psHu32(DMAC_RBSR)); //Set MADR to QW after Tag
vif1ch->tadr = psHu32(DMAC_RBOR) + ((vif1ch->madr + (vif1ch->qwc << 4)) & psHu32(DMAC_RBSR)); //Set TADR to QW following the data
vif1ch->madr = qwctag(vif1ch->tadr + 16); //Set MADR to QW after Tag
vif1ch->tadr = qwctag(vif1ch->madr + (vif1ch->qwc << 4)); //Set TADR to QW following the data
vif1.done = false;
break;
case TAG_NEXT: // Next - Transfer QWC following tag. TADR = ADDR
{
int temp = vif1ch->madr; //Temporarily Store ADDR
vif1ch->madr = psHu32(DMAC_RBOR) + ((vif1ch->tadr + 16) & psHu32(DMAC_RBSR)); //Set MADR to QW following the tag
vif1ch->madr = qwctag(vif1ch->tadr + 16); //Set MADR to QW following the tag
vif1ch->tadr = temp; //Copy temporarily stored ADDR to Tag
if ((temp & psHu32(DMAC_RBSR)) != psHu32(DMAC_RBOR)) Console::WriteLn("Next tag = %x outside ring %x size %x", temp, psHu32(DMAC_RBOR), psHu32(DMAC_RBSR));
if ((temp & dmacRegs->rbsr.RMSK) != dmacRegs->rbor.ADDR) Console::WriteLn("Next tag = %x outside ring %x size %x", temp, psHu32(DMAC_RBOR), psHu32(DMAC_RBSR));
vif1.done = false;
break;
}
case TAG_REF: // Ref - Transfer QWC from ADDR field
case TAG_REFS: // Refs - Transfer QWC from ADDR field (Stall Control)
vif1ch->tadr = psHu32(DMAC_RBOR) + ((vif1ch->tadr + 16) & psHu32(DMAC_RBSR)); //Set TADR to next tag
vif1ch->tadr =qwctag(vif1ch->tadr + 16); //Set TADR to next tag
vif1.done = false;
break;
case TAG_END: // End - Transfer QWC following the tag
vif1ch->madr = psHu32(DMAC_RBOR) + ((vif1ch->tadr + 16) & psHu32(DMAC_RBSR)); //Set MADR to data following the tag
vif1ch->tadr = psHu32(DMAC_RBOR) + ((vif1ch->madr + (vif1ch->qwc << 4)) & psHu32(DMAC_RBSR)); //Set TADR to QW following the data
vif1ch->madr = qwctag(vif1ch->tadr + 16); //Set MADR to data following the tag
vif1ch->tadr = qwctag(vif1ch->madr + (vif1ch->qwc << 4)); //Set TADR to QW following the data
vif1.done = true; //End Transfer
break;
}
@ -579,7 +584,7 @@ void vifMFIFOInterrupt()
}
mfifoVIF1transfer(0);
if (vif1ch->madr >= psHu32(DMAC_RBOR) && vif1ch->madr <= (psHu32(DMAC_RBOR) + psHu32(DMAC_RBSR)))
if (vif1ch->madr >= dmacRegs->rbor.ADDR && vif1ch->madr <= (dmacRegs->rbor.ADDR + dmacRegs->rbsr.RMSK))
CPU_INT(10, 0);
else
CPU_INT(10, vif1ch->qwc * BIAS);

View File

@ -1917,7 +1917,7 @@ static int __fastcall Vif1TransDirectHL(u32 *data)
}
else
{
psHu32(GIF_STAT) &= ~(GIF_STAT_APATH2 | GIF_STAT_OPH);
gifRegs->stat._u32 &= ~(GIF_STAT_APATH2 | GIF_STAT_OPH);
ret = vif1.tag.size;
vif1.tag.size = 0;
vif1.cmd = 0;