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 (madr < 0x11004000)
{
if(isWrite == true)
{ {
DbgCon.Warning("scratch pad clearing vu0"); DbgCon.Warning("scratch pad clearing vu0");
CpuVU0->Clear(madr&0xfff, qwc * 16); 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) else if (madr >= 0x11008000 && madr < 0x1100c000)
{
if(isWrite == true)
{ {
DbgCon.Warning("scratch pad clearing vu1"); DbgCon.Warning("scratch pad clearing vu1");
if (THREAD_VU1) { if (THREAD_VU1) {
DevCon.Error("MTVU Warning: SPR Accessing VU1 Memory!!!"); DevCon.Error("MTVU Warning: SPR Accessing VU1 Memory!!!");
vu1Thread.WaitVU(); vu1Thread.WaitVU();
} }
CpuVU1->Clear(madr&0x3fff, qwc * 16); 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() int _SPR0chain()
@ -87,7 +109,7 @@ int _SPR0chain()
memcpy_qwc(pMem, &psSu128(spr0ch.sadr), partialqwc); memcpy_qwc(pMem, &psSu128(spr0ch.sadr), partialqwc);
// clear VU mem also! // clear VU mem also!
TestClearVUs(spr0ch.madr, partialqwc); TestClearVUs(spr0ch.madr, partialqwc, true);
spr0ch.madr += partialqwc << 4; spr0ch.madr += partialqwc << 4;
spr0ch.sadr += partialqwc << 4; spr0ch.sadr += partialqwc << 4;
@ -138,7 +160,7 @@ void _SPR0interleave()
case NO_MFD: case NO_MFD:
case MFD_RESERVED: case MFD_RESERVED:
// clear VU mem also! // clear VU mem also!
TestClearVUs(spr0ch.madr, spr0ch.qwc); TestClearVUs(spr0ch.madr, spr0ch.qwc, true);
memcpy_qwc(pMem, &psSu128(spr0ch.sadr), spr0ch.qwc); memcpy_qwc(pMem, &psSu128(spr0ch.sadr), spr0ch.qwc);
break; break;
} }
@ -297,6 +319,11 @@ void dmaSPR0() // fromSPR
__fi static void SPR1transfer(const void* data, int qwc) __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); memcpy_qwc(&psSu128(spr1ch.sadr), data, qwc);
spr1ch.sadr += qwc * 16; spr1ch.sadr += qwc * 16;
} }

View File

@ -123,24 +123,30 @@ __fi tDMA_TAG* SPRdmaGetAddr(u32 addr, bool write)
if((addr >= 0x1100c000) && (addr < 0x11010000)) if((addr >= 0x1100c000) && (addr < 0x11010000))
{ {
DevCon.Warning("VU1 Mem %x", addr); //DevCon.Warning("VU1 Mem %x", addr);
return (tDMA_TAG*)VU1.Mem + (addr & 0x3ff0); 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. //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); //DevCon.Warning("VU0 Micro %x", addr);
return (tDMA_TAG*)VU1.Micro + (addr & 0x3ff0); 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 //DevCon.Warning("VU1 Micro %x", addr);
//Access it like above (it doesn't work lol) CSI 3 - Dimensions of Murder return (tDMA_TAG*)(VU1.Micro + (addr & 0x3ff0));
return (tDMA_TAG*)vtlb_GetPhyPtr(addr & 0x1FFFFFF0);
} }
// Unreachable // Unreachable
return NULL; return NULL;
} }