mirror of https://github.com/PCSX2/pcsx2.git
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:
parent
f3844f026a
commit
c46d422887
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue