From 575e1ceb4652d377813411a9740b132b38b5a8b2 Mon Sep 17 00:00:00 2001 From: "Jake.Stine" Date: Mon, 19 Jul 2010 05:40:35 +0000 Subject: [PATCH] * 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 --- pcsx2/Dmac.h | 9 ++++---- pcsx2/Hw.cpp | 44 +++++++++++++++++-------------------- pcsx2/Hw.h | 2 -- pcsx2/Memory.h | 14 +++++------- pcsx2/SPR.cpp | 23 ++++++++++--------- pcsx2/ps2/GIFpath.cpp | 4 ++-- pcsx2/x86/microVU_Lower.inl | 1 - 7 files changed, 44 insertions(+), 53 deletions(-) diff --git a/pcsx2/Dmac.h b/pcsx2/Dmac.h index 5fa118a888..127fcea40e 100644 --- a/pcsx2/Dmac.h +++ b/pcsx2/Dmac.h @@ -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(); diff --git a/pcsx2/Hw.cpp b/pcsx2/Hw.cpp index 74f1ad4989..daf50a52ae 100644 --- a/pcsx2/Hw.cpp +++ b/pcsx2/Hw.cpp @@ -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 diff --git a/pcsx2/Hw.h b/pcsx2/Hw.h index 247a792e6d..f5cf400be9 100644 --- a/pcsx2/Hw.h +++ b/pcsx2/Hw.h @@ -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; diff --git a/pcsx2/Memory.h b/pcsx2/Memory.h index f164cb78fb..532faf6469 100644 --- a/pcsx2/Memory.h +++ b/pcsx2/Memory.h @@ -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(); diff --git a/pcsx2/SPR.cpp b/pcsx2/SPR.cpp index 3c19194dd2..0cb674c71f 100644 --- a/pcsx2/SPR.cpp +++ b/pcsx2/SPR.cpp @@ -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", diff --git a/pcsx2/ps2/GIFpath.cpp b/pcsx2/ps2/GIFpath.cpp index 1c9366ec21..501205c62e 100644 --- a/pcsx2/ps2/GIFpath.cpp +++ b/pcsx2/ps2/GIFpath.cpp @@ -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 ) diff --git a/pcsx2/x86/microVU_Lower.inl b/pcsx2/x86/microVU_Lower.inl index 41a38861fd..e48cfde205 100644 --- a/pcsx2/x86/microVU_Lower.inl +++ b/pcsx2/x86/microVU_Lower.inl @@ -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;