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);
|
||||
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();
|
||||
|
|
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'.
|
||||
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
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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 )
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue