* 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:
Jake.Stine 2010-07-19 05:40:35 +00:00
parent 856ffe4c65
commit 575e1ceb46
7 changed files with 44 additions and 53 deletions

View File

@ -693,11 +693,12 @@ static __forceinline tDMA_TAG *dmaGetAddr(u32 addr, bool write)
}
}
void hwIntcIrq(int n);
void hwDmacIrq(int n);
extern void hwIntcIrq(int n);
extern void hwDmacIrq(int n);
bool hwDmacSrcChainWithStack(DMACh *dma, int id);
bool hwDmacSrcChain(DMACh *dma, int id);
extern bool hwMFIFOWrite(u32 addr, const u128* data, uint size_qwc);
extern bool hwDmacSrcChainWithStack(DMACh *dma, int id);
extern bool hwDmacSrcChain(DMACh *dma, int id);
extern void intcInterrupt();
extern void dmacInterrupt();

View File

@ -127,39 +127,35 @@ void hwDmacIrq(int n)
}
// 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;
u8 *dst;
// all FIFO addresses should always be QWC-aligned.
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 ((addr+size) >= msize) {
int s1 = msize - addr;
int s2 = size - s1;
// it does, so first copy 's1' bytes from 'data' to 'addr'
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);
if (u128* dst = (u128*)PSM(dmacRegs->rbor.ADDR))
{
const u32 ringsize = (dmacRegs->rbsr.RMSK / 16) + 1;
pxAssertMsg( PSM(dmacRegs->rbor.ADDR+ringsize-1) != NULL, "Scratchpad/MFIFO ringbuffer spans into invalid (unmapped) physical memory!" );
uint startpos = (addr & dmacRegs->rbsr.RMSK)/16;
MemCopy_WrappedDest( data, dst, startpos, ringsize, qwc );
}
else {
// it doesn't, so just copy 'size' bytes from 'data' to 'addr'
dst = (u8*)PSM(addr);
if (dst == NULL) return false;
memcpy_fast(dst, data, size);
else
{
SPR_LOG( "Scratchpad/MFIFO: invalid base physical address: 0x%08x", dmacRegs->rbor.ADDR );
pxFailDev( wxsFormat( L"Scratchpad/MFIFO: Invalid base physical address: 0x%08x", dmacRegs->rbor.ADDR) );
return false;
}
return true;
}
bool hwDmacSrcChainWithStack(DMACh *dma, int id) {
__releaseinline bool hwDmacSrcChainWithStack(DMACh *dma, int id) {
switch (id) {
case TAG_REFE: // Refe - Transfer Packet According to ADDR field
//End Transfer

View File

@ -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);
bool hwMFIFOWrite(u32 addr, u8 *data, u32 size);
extern const int rdram_devices;
extern int rdram_sdevid;

View File

@ -114,14 +114,12 @@ extern u8 *psMHW;
#define psERu32(mem) (*(u32*)&PS2MEM_EROM[(mem) & 0x3ffff])
#define psERu64(mem) (*(u64*)&PS2MEM_EROM[(mem) & 0x3ffff])
#define psSs8(mem) (*(s8 *)&PS2MEM_SCRATCH[(mem) & 0x3fff])
#define psSs16(mem) (*(s16*)&PS2MEM_SCRATCH[(mem) & 0x3fff])
#define psSs32(mem) (*(s32*)&PS2MEM_SCRATCH[(mem) & 0x3fff])
#define psSs64(mem) (*(s64*)&PS2MEM_SCRATCH[(mem) & 0x3fff])
#define psSu8(mem) (*(u8 *)&PS2MEM_SCRATCH[(mem) & 0x3fff])
#define psSu16(mem) (*(u16*)&PS2MEM_SCRATCH[(mem) & 0x3fff])
#define psSu32(mem) (*(u32*)&PS2MEM_SCRATCH[(mem) & 0x3fff])
#define psSu64(mem) (*(u64*)&PS2MEM_SCRATCH[(mem) & 0x3fff])
#define psSs32(mem) (*(s32 *)&PS2MEM_SCRATCH[(mem) & 0x3fff])
#define psSs64(mem) (*(s64 *)&PS2MEM_SCRATCH[(mem) & 0x3fff])
#define psSs128(mem) (*(s128*)&PS2MEM_SCRATCH[(mem) & 0x3fff])
#define psSu32(mem) (*(u32 *)&PS2MEM_SCRATCH[(mem) & 0x3fff])
#define psSu64(mem) (*(u64 *)&PS2MEM_SCRATCH[(mem) & 0x3fff])
#define psSu128(mem) (*(u128*)&PS2MEM_SCRATCH[(mem) & 0x3fff])
#define psH_DMACh(mem) (*(DMACh*)&PS2MEM_HW[(mem) & 0xffff])
extern void memAlloc();

View File

@ -64,14 +64,14 @@ int _SPR0chain()
else
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 = dmacRegs->rbor.ADDR + (spr0->madr & dmacRegs->rbsr.RMSK);
break;
case NO_MFD:
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!
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_GIF:
hwMFIFOWrite(spr0->madr, &psSu8(spr0->sadr), spr0->qwc << 4);
hwMFIFOWrite(spr0->madr, &psSu128(spr0->sadr), spr0->qwc);
mfifotransferred += spr0->qwc;
break;
@ -122,7 +122,7 @@ void _SPR0interleave()
case MFD_RESERVED:
// clear VU mem also!
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;
}
spr0->sadr += spr0->qwc * 16;
@ -273,11 +273,10 @@ void dmaSPR0() // fromSPR
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);
spr1->sadr += size << 2;
memcpy_qwc(&psSu128(spr1->sadr), data, qwc);
spr1->sadr += qwc * 16;
}
int _SPR1chain()
@ -289,8 +288,8 @@ int _SPR1chain()
pMem = SPRdmaGetAddr(spr1->madr, false);
if (pMem == NULL) return -1;
SPR1transfer((u32*)pMem, spr1->qwc << 2);
spr1->madr += spr1->qwc << 4;
SPR1transfer(pMem, spr1->qwc);
spr1->madr += spr1->qwc * 16;
return (spr1->qwc);
}
@ -317,7 +316,7 @@ void _SPR1interleave()
spr1->qwc = std::min(tqwc, qwc);
qwc -= spr1->qwc;
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->madr += (sqwc + spr1->qwc) * 16;
}
@ -365,7 +364,7 @@ void _dmaSPR1() // toSPR work function
if (spr1->chcr.TTE)
{
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",

View File

@ -529,7 +529,7 @@ __forceinline int GIFPath::ParseTagQuick(GIF_PATH pathidx, const u8* pMem, u32 s
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;
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;
if( endpos < srcSize )

View File

@ -1134,7 +1134,6 @@ void __fastcall mVU_XGKICK_(u32 addr) {
}
else {
memcpy_qwc(pDest, microVU1.regs->Mem + (addr*16), size);
Path1WritePos += size;
}
//if(!gifRegs->stat.P1Q) CPU_INT(28, 128);
gifRegs->stat.P1Q = true;