SPR VU Access (Again): Managed to get VU0 working the way we wanted it, thank to sudonim1 for pointing out where i was failing.

Also added a check for a possible scenario where SPR may try and read/write crossing VU0 memory boundaries in to mirrored space, could cause issues in games if it happens.

git-svn-id: http://pcsx2.googlecode.com/svn/trunk@5481 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
refraction@gmail.com 2012-12-19 20:20:14 +00:00
parent f3844f026a
commit c46d422887
2 changed files with 56 additions and 23 deletions

View File

@ -32,25 +32,47 @@ void sprInit()
{
}
static void TestClearVUs(u32 madr, u32 qwc)
static void TestClearVUs(u32 madr, u32 qwc, bool isWrite)
{
if (madr >= 0x11000000)
if (madr >= 0x11000000 && (madr < 0x11010000))
{
if (madr < 0x11004000)
{
if(isWrite == true)
{
DbgCon.Warning("scratch pad clearing vu0");
CpuVU0->Clear(madr&0xfff, qwc * 16);
}
if(((madr & 0xff0) + (qwc * 16)) > 0x1000 )
{
DevCon.Warning("Warning! SPR%d Crossing in to VU0 Micro Mirror address! Start MADR = %x, End MADR = %x", isWrite ? 0 : 1, madr, madr + (qwc * 16));
}
}
else if (madr >= 0x11008000 && madr < 0x1100c000)
{
if(isWrite == true)
{
DbgCon.Warning("scratch pad clearing vu1");
if (THREAD_VU1) {
DevCon.Error("MTVU Warning: SPR Accessing VU1 Memory!!!");
vu1Thread.WaitVU();
}
CpuVU1->Clear(madr&0x3fff, qwc * 16);
}
}
else if (madr >= 0x11004000 && madr < 0x11008000)
{
//SPR trying to write to to VU0 Mem mirror address.
if(((madr & 0xff0) + (qwc * 16)) > 0x1000)
{
DevCon.Warning("Warning! SPR%d Crossing in to VU0 Mem Mirror address! Start MADR = %x, End MADR = %x", isWrite ? 0 : 1, madr, madr + (qwc * 16));
}
}
}
}
int _SPR0chain()
@ -87,7 +109,7 @@ int _SPR0chain()
memcpy_qwc(pMem, &psSu128(spr0ch.sadr), partialqwc);
// clear VU mem also!
TestClearVUs(spr0ch.madr, partialqwc);
TestClearVUs(spr0ch.madr, partialqwc, true);
spr0ch.madr += partialqwc << 4;
spr0ch.sadr += partialqwc << 4;
@ -138,7 +160,7 @@ void _SPR0interleave()
case NO_MFD:
case MFD_RESERVED:
// clear VU mem also!
TestClearVUs(spr0ch.madr, spr0ch.qwc);
TestClearVUs(spr0ch.madr, spr0ch.qwc, true);
memcpy_qwc(pMem, &psSu128(spr0ch.sadr), spr0ch.qwc);
break;
}
@ -297,6 +319,11 @@ void dmaSPR0() // fromSPR
__fi static void SPR1transfer(const void* data, int qwc)
{
if ((spr1ch.madr >= 0x11000000) && (spr1ch.madr < 0x11010000))
{
TestClearVUs(spr1ch.madr, spr1ch.qwc, false);
}
memcpy_qwc(&psSu128(spr1ch.sadr), data, qwc);
spr1ch.sadr += qwc * 16;
}

View File

@ -123,24 +123,30 @@ __fi tDMA_TAG* SPRdmaGetAddr(u32 addr, bool write)
if((addr >= 0x1100c000) && (addr < 0x11010000))
{
DevCon.Warning("VU1 Mem %x", addr);
return (tDMA_TAG*)VU1.Mem + (addr & 0x3ff0);
//DevCon.Warning("VU1 Mem %x", addr);
return (tDMA_TAG*)(VU1.Mem + (addr & 0x3ff0));
}
if((addr >= 0x11004000) && (addr < 0x11008000))
{
//DevCon.Warning("VU0 Mem %x", addr);
return (tDMA_TAG*)(VU0.Mem + (addr & 0xff0));
}
//Possibly not needed but the manual doesn't say SPR cannot access it.
if((addr >= 0x11008000) && (addr < 0x1100c000))
if((addr >= 0x11000000) && (addr < 0x11004000))
{
DevCon.Warning("VU1 Micro %x", addr);
return (tDMA_TAG*)VU1.Micro + (addr & 0x3ff0);
//DevCon.Warning("VU0 Micro %x", addr);
return (tDMA_TAG*)(VU0.Micro + (addr & 0xff0));
}
if ((addr >= 0x11000000) && (addr < 0x11008000))
if((addr >= 0x11008000) && (addr < 0x1100c000))
{
//VU0 is still mapped directly to physical memory, you cant just
//Access it like above (it doesn't work lol) CSI 3 - Dimensions of Murder
return (tDMA_TAG*)vtlb_GetPhyPtr(addr & 0x1FFFFFF0);
//DevCon.Warning("VU1 Micro %x", addr);
return (tDMA_TAG*)(VU1.Micro + (addr & 0x3ff0));
}
// Unreachable
return NULL;
}