mirror of https://github.com/PCSX2/pcsx2.git
* Converted SPR.cpp and hwMFIFOWrite to use memcpy_qwc in the place of memcpy_fast.
* Fix a bug in my merge of the new MTGS code that caused crashes on some games (PATH1 queue bug). * Added assertion checks to hwMFIFOWrite for qwc alignment and a SPR_LOG for null ringbuffer addresses (if a game specifies an invalid physical address). git-svn-id: http://pcsx2.googlecode.com/svn/trunk@3533 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
parent
856ffe4c65
commit
575e1ceb46
|
@ -693,11 +693,12 @@ static __forceinline tDMA_TAG *dmaGetAddr(u32 addr, bool write)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void hwIntcIrq(int n);
|
extern void hwIntcIrq(int n);
|
||||||
void hwDmacIrq(int n);
|
extern void hwDmacIrq(int n);
|
||||||
|
|
||||||
bool hwDmacSrcChainWithStack(DMACh *dma, int id);
|
extern bool hwMFIFOWrite(u32 addr, const u128* data, uint size_qwc);
|
||||||
bool hwDmacSrcChain(DMACh *dma, int id);
|
extern bool hwDmacSrcChainWithStack(DMACh *dma, int id);
|
||||||
|
extern bool hwDmacSrcChain(DMACh *dma, int id);
|
||||||
|
|
||||||
extern void intcInterrupt();
|
extern void intcInterrupt();
|
||||||
extern void dmacInterrupt();
|
extern void dmacInterrupt();
|
||||||
|
|
44
pcsx2/Hw.cpp
44
pcsx2/Hw.cpp
|
@ -127,39 +127,35 @@ void hwDmacIrq(int n)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write 'size' bytes to memory address 'addr' from 'data'.
|
// Write 'size' bytes to memory address 'addr' from 'data'.
|
||||||
bool hwMFIFOWrite(u32 addr, u8 *data, u32 size)
|
__releaseinline bool hwMFIFOWrite(u32 addr, const u128* data, uint qwc)
|
||||||
{
|
{
|
||||||
u32 msize = dmacRegs->rbor.ADDR + dmacRegs->rbsr.RMSK + 16;
|
// all FIFO addresses should always be QWC-aligned.
|
||||||
u8 *dst;
|
pxAssume((dmacRegs->rbor.ADDR & 15) == 0);
|
||||||
|
pxAssume((addr & 15) == 0);
|
||||||
|
|
||||||
addr = dmacRegs->rbor.ADDR + (addr & dmacRegs->rbsr.RMSK);
|
// DMAC Address resolution: FIFO can be placed anywhere in the *physical* memory map
|
||||||
|
// for the PS2. Its probably a serious error for a PS2 app to have the buffer cross
|
||||||
|
// valid/invalid page areas of ram, so realistically we only need to test the base address
|
||||||
|
// of the FIFO for address validity.
|
||||||
|
|
||||||
// Check if the transfer should wrap around the ring buffer
|
if (u128* dst = (u128*)PSM(dmacRegs->rbor.ADDR))
|
||||||
if ((addr+size) >= msize) {
|
{
|
||||||
int s1 = msize - addr;
|
const u32 ringsize = (dmacRegs->rbsr.RMSK / 16) + 1;
|
||||||
int s2 = size - s1;
|
pxAssertMsg( PSM(dmacRegs->rbor.ADDR+ringsize-1) != NULL, "Scratchpad/MFIFO ringbuffer spans into invalid (unmapped) physical memory!" );
|
||||||
|
uint startpos = (addr & dmacRegs->rbsr.RMSK)/16;
|
||||||
// it does, so first copy 's1' bytes from 'data' to 'addr'
|
MemCopy_WrappedDest( data, dst, startpos, ringsize, qwc );
|
||||||
dst = (u8*)PSM(addr);
|
|
||||||
if (dst == NULL) return false;
|
|
||||||
memcpy_fast(dst, data, s1);
|
|
||||||
|
|
||||||
// and second copy 's2' bytes from '&data[s1]' to 'maddr'
|
|
||||||
dst = (u8*)PSM(dmacRegs->rbor.ADDR);
|
|
||||||
if (dst == NULL) return false;
|
|
||||||
memcpy_fast(dst, &data[s1], s2);
|
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
// it doesn't, so just copy 'size' bytes from 'data' to 'addr'
|
{
|
||||||
dst = (u8*)PSM(addr);
|
SPR_LOG( "Scratchpad/MFIFO: invalid base physical address: 0x%08x", dmacRegs->rbor.ADDR );
|
||||||
if (dst == NULL) return false;
|
pxFailDev( wxsFormat( L"Scratchpad/MFIFO: Invalid base physical address: 0x%08x", dmacRegs->rbor.ADDR) );
|
||||||
memcpy_fast(dst, data, size);
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool hwDmacSrcChainWithStack(DMACh *dma, int id) {
|
__releaseinline bool hwDmacSrcChainWithStack(DMACh *dma, int id) {
|
||||||
switch (id) {
|
switch (id) {
|
||||||
case TAG_REFE: // Refe - Transfer Packet According to ADDR field
|
case TAG_REFE: // Refe - Transfer Packet According to ADDR field
|
||||||
//End Transfer
|
//End Transfer
|
||||||
|
|
|
@ -312,8 +312,6 @@ extern void __fastcall hwWrite64_generic( u32 mem, const mem64_t* srcval );
|
||||||
|
|
||||||
extern void __fastcall hwWrite128_generic(u32 mem, const mem128_t *srcval);
|
extern void __fastcall hwWrite128_generic(u32 mem, const mem128_t *srcval);
|
||||||
|
|
||||||
bool hwMFIFOWrite(u32 addr, u8 *data, u32 size);
|
|
||||||
|
|
||||||
extern const int rdram_devices;
|
extern const int rdram_devices;
|
||||||
extern int rdram_sdevid;
|
extern int rdram_sdevid;
|
||||||
|
|
||||||
|
|
|
@ -114,14 +114,12 @@ extern u8 *psMHW;
|
||||||
#define psERu32(mem) (*(u32*)&PS2MEM_EROM[(mem) & 0x3ffff])
|
#define psERu32(mem) (*(u32*)&PS2MEM_EROM[(mem) & 0x3ffff])
|
||||||
#define psERu64(mem) (*(u64*)&PS2MEM_EROM[(mem) & 0x3ffff])
|
#define psERu64(mem) (*(u64*)&PS2MEM_EROM[(mem) & 0x3ffff])
|
||||||
|
|
||||||
#define psSs8(mem) (*(s8 *)&PS2MEM_SCRATCH[(mem) & 0x3fff])
|
#define psSs32(mem) (*(s32 *)&PS2MEM_SCRATCH[(mem) & 0x3fff])
|
||||||
#define psSs16(mem) (*(s16*)&PS2MEM_SCRATCH[(mem) & 0x3fff])
|
#define psSs64(mem) (*(s64 *)&PS2MEM_SCRATCH[(mem) & 0x3fff])
|
||||||
#define psSs32(mem) (*(s32*)&PS2MEM_SCRATCH[(mem) & 0x3fff])
|
#define psSs128(mem) (*(s128*)&PS2MEM_SCRATCH[(mem) & 0x3fff])
|
||||||
#define psSs64(mem) (*(s64*)&PS2MEM_SCRATCH[(mem) & 0x3fff])
|
#define psSu32(mem) (*(u32 *)&PS2MEM_SCRATCH[(mem) & 0x3fff])
|
||||||
#define psSu8(mem) (*(u8 *)&PS2MEM_SCRATCH[(mem) & 0x3fff])
|
#define psSu64(mem) (*(u64 *)&PS2MEM_SCRATCH[(mem) & 0x3fff])
|
||||||
#define psSu16(mem) (*(u16*)&PS2MEM_SCRATCH[(mem) & 0x3fff])
|
#define psSu128(mem) (*(u128*)&PS2MEM_SCRATCH[(mem) & 0x3fff])
|
||||||
#define psSu32(mem) (*(u32*)&PS2MEM_SCRATCH[(mem) & 0x3fff])
|
|
||||||
#define psSu64(mem) (*(u64*)&PS2MEM_SCRATCH[(mem) & 0x3fff])
|
|
||||||
|
|
||||||
#define psH_DMACh(mem) (*(DMACh*)&PS2MEM_HW[(mem) & 0xffff])
|
#define psH_DMACh(mem) (*(DMACh*)&PS2MEM_HW[(mem) & 0xffff])
|
||||||
extern void memAlloc();
|
extern void memAlloc();
|
||||||
|
|
|
@ -64,14 +64,14 @@ int _SPR0chain()
|
||||||
else
|
else
|
||||||
mfifotransferred += spr0->qwc;
|
mfifotransferred += spr0->qwc;
|
||||||
|
|
||||||
hwMFIFOWrite(spr0->madr, &psSu8(spr0->sadr), spr0->qwc << 4);
|
hwMFIFOWrite(spr0->madr, &psSu128(spr0->sadr), spr0->qwc);
|
||||||
spr0->madr += spr0->qwc << 4;
|
spr0->madr += spr0->qwc << 4;
|
||||||
spr0->madr = dmacRegs->rbor.ADDR + (spr0->madr & dmacRegs->rbsr.RMSK);
|
spr0->madr = dmacRegs->rbor.ADDR + (spr0->madr & dmacRegs->rbsr.RMSK);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NO_MFD:
|
case NO_MFD:
|
||||||
case MFD_RESERVED:
|
case MFD_RESERVED:
|
||||||
memcpy_fast((u8*)pMem, &psSu8(spr0->sadr), spr0->qwc << 4);
|
memcpy_qwc(pMem, &psSu128(spr0->sadr), spr0->qwc);
|
||||||
|
|
||||||
// clear VU mem also!
|
// clear VU mem also!
|
||||||
TestClearVUs(spr0->madr, spr0->qwc << 2); // Wtf is going on here? AFAIK, only VIF should affect VU micromem (cottonvibes)
|
TestClearVUs(spr0->madr, spr0->qwc << 2); // Wtf is going on here? AFAIK, only VIF should affect VU micromem (cottonvibes)
|
||||||
|
@ -114,7 +114,7 @@ void _SPR0interleave()
|
||||||
{
|
{
|
||||||
case MFD_VIF1:
|
case MFD_VIF1:
|
||||||
case MFD_GIF:
|
case MFD_GIF:
|
||||||
hwMFIFOWrite(spr0->madr, &psSu8(spr0->sadr), spr0->qwc << 4);
|
hwMFIFOWrite(spr0->madr, &psSu128(spr0->sadr), spr0->qwc);
|
||||||
mfifotransferred += spr0->qwc;
|
mfifotransferred += spr0->qwc;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -122,7 +122,7 @@ void _SPR0interleave()
|
||||||
case MFD_RESERVED:
|
case MFD_RESERVED:
|
||||||
// clear VU mem also!
|
// clear VU mem also!
|
||||||
TestClearVUs(spr0->madr, spr0->qwc << 2);
|
TestClearVUs(spr0->madr, spr0->qwc << 2);
|
||||||
memcpy_fast((u8*)pMem, &psSu8(spr0->sadr), spr0->qwc << 4);
|
memcpy_qwc(pMem, &psSu128(spr0->sadr), spr0->qwc);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
spr0->sadr += spr0->qwc * 16;
|
spr0->sadr += spr0->qwc * 16;
|
||||||
|
@ -273,11 +273,10 @@ void dmaSPR0() // fromSPR
|
||||||
SPRFROMinterrupt();
|
SPRFROMinterrupt();
|
||||||
}
|
}
|
||||||
|
|
||||||
__forceinline static void SPR1transfer(u32 *data, int size)
|
__forceinline static void SPR1transfer(const void* data, int qwc)
|
||||||
{
|
{
|
||||||
memcpy_fast(&psSu8(spr1->sadr), (u8*)data, size << 2);
|
memcpy_qwc(&psSu128(spr1->sadr), data, qwc);
|
||||||
|
spr1->sadr += qwc * 16;
|
||||||
spr1->sadr += size << 2;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int _SPR1chain()
|
int _SPR1chain()
|
||||||
|
@ -289,8 +288,8 @@ int _SPR1chain()
|
||||||
pMem = SPRdmaGetAddr(spr1->madr, false);
|
pMem = SPRdmaGetAddr(spr1->madr, false);
|
||||||
if (pMem == NULL) return -1;
|
if (pMem == NULL) return -1;
|
||||||
|
|
||||||
SPR1transfer((u32*)pMem, spr1->qwc << 2);
|
SPR1transfer(pMem, spr1->qwc);
|
||||||
spr1->madr += spr1->qwc << 4;
|
spr1->madr += spr1->qwc * 16;
|
||||||
|
|
||||||
return (spr1->qwc);
|
return (spr1->qwc);
|
||||||
}
|
}
|
||||||
|
@ -317,7 +316,7 @@ void _SPR1interleave()
|
||||||
spr1->qwc = std::min(tqwc, qwc);
|
spr1->qwc = std::min(tqwc, qwc);
|
||||||
qwc -= spr1->qwc;
|
qwc -= spr1->qwc;
|
||||||
pMem = SPRdmaGetAddr(spr1->madr, false);
|
pMem = SPRdmaGetAddr(spr1->madr, false);
|
||||||
memcpy_fast(&psSu8(spr1->sadr), (u8*)pMem, spr1->qwc << 4);
|
memcpy_qwc(&psSu128(spr1->sadr), pMem, spr1->qwc);
|
||||||
spr1->sadr += spr1->qwc * 16;
|
spr1->sadr += spr1->qwc * 16;
|
||||||
spr1->madr += (sqwc + spr1->qwc) * 16;
|
spr1->madr += (sqwc + spr1->qwc) * 16;
|
||||||
}
|
}
|
||||||
|
@ -365,7 +364,7 @@ void _dmaSPR1() // toSPR work function
|
||||||
if (spr1->chcr.TTE)
|
if (spr1->chcr.TTE)
|
||||||
{
|
{
|
||||||
SPR_LOG("SPR TTE: %x_%x\n", ptag[3]._u32, ptag[2]._u32);
|
SPR_LOG("SPR TTE: %x_%x\n", ptag[3]._u32, ptag[2]._u32);
|
||||||
SPR1transfer((u32*)ptag, 4); //Transfer Tag
|
SPR1transfer(ptag, 1); //Transfer Tag
|
||||||
}
|
}
|
||||||
|
|
||||||
SPR_LOG("spr1 dmaChain %8.8x_%8.8x size=%d, id=%d, addr=%lx taddr=%lx saddr=%lx",
|
SPR_LOG("spr1 dmaChain %8.8x_%8.8x size=%d, id=%d, addr=%lx taddr=%lx saddr=%lx",
|
||||||
|
|
|
@ -529,7 +529,7 @@ __forceinline int GIFPath::ParseTagQuick(GIF_PATH pathidx, const u8* pMem, u32 s
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
__forceinline void MemCopy_WrappedDest( const u128* src, u128* destBase, uint& destStart, uint destSize, uint len )
|
__releaseinline void MemCopy_WrappedDest( const u128* src, u128* destBase, uint& destStart, uint destSize, uint len )
|
||||||
{
|
{
|
||||||
uint endpos = destStart + len;
|
uint endpos = destStart + len;
|
||||||
if( endpos < destSize )
|
if( endpos < destSize )
|
||||||
|
@ -547,7 +547,7 @@ __forceinline void MemCopy_WrappedDest( const u128* src, u128* destBase, uint& d
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
__forceinline void MemCopy_WrappedSrc( const u128* srcBase, uint& srcStart, uint srcSize, u128* dest, uint len )
|
__releaseinline void MemCopy_WrappedSrc( const u128* srcBase, uint& srcStart, uint srcSize, u128* dest, uint len )
|
||||||
{
|
{
|
||||||
uint endpos = srcStart + len;
|
uint endpos = srcStart + len;
|
||||||
if( endpos < srcSize )
|
if( endpos < srcSize )
|
||||||
|
|
|
@ -1134,7 +1134,6 @@ void __fastcall mVU_XGKICK_(u32 addr) {
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
memcpy_qwc(pDest, microVU1.regs->Mem + (addr*16), size);
|
memcpy_qwc(pDest, microVU1.regs->Mem + (addr*16), size);
|
||||||
Path1WritePos += size;
|
|
||||||
}
|
}
|
||||||
//if(!gifRegs->stat.P1Q) CPU_INT(28, 128);
|
//if(!gifRegs->stat.P1Q) CPU_INT(28, 128);
|
||||||
gifRegs->stat.P1Q = true;
|
gifRegs->stat.P1Q = true;
|
||||||
|
|
Loading…
Reference in New Issue