From 377830b3a96dc86d23545b95c03fdf6309ab906f Mon Sep 17 00:00:00 2001 From: "Jake.Stine" Date: Fri, 27 Feb 2009 18:12:59 +0000 Subject: [PATCH] IOP Fixes/Optimizations: * Fixed the IOP's recExecute so that it correctly preserves X86 registers (EDI and EBX were not preserved!) * Optimized the recExecute procedure, seems like a nice speedup in FMVs and some games that are IOP intensive. * Renamed psxMemRead to iopMemRead, added new Virt/Phys functions, and fixed several instances of DMAs using translated addresses (DMAs are always physical maps). Our IOP doesn't really emulate the tlb so it won't fix anything, but it's more correct in cas stuff is better supported in the future. * Removed unneeded FreezeMMXRegs, since the IOPrec doesn't use any mmx/xmm regs anyway. git-svn-id: http://pcsx2.googlecode.com/svn/trunk@628 96395faa-99c1-11dd-bbfe-3dabce05a288 --- pcsx2/CDVD.cpp | 92 +++++++------ pcsx2/CdRom.cpp | 2 +- pcsx2/IopBios.cpp | 46 ++++--- pcsx2/IopDma.cpp | 12 +- pcsx2/IopMem.cpp | 43 ++---- pcsx2/IopMem.h | 64 +++++---- pcsx2/IopSio2.cpp | 4 +- pcsx2/Patch.cpp | 6 +- pcsx2/R3000AInterpreter.cpp | 23 ++-- pcsx2/R3000AOpcodeTables.cpp | 40 +++--- pcsx2/RDebug/deci2_dbgp.cpp | 8 +- pcsx2/RDebug/deci2_iloadp.cpp | 10 +- pcsx2/Sif.cpp | 8 +- pcsx2/windows/Debugger.cpp | 4 +- pcsx2/x86/aR3000A.S | 233 ++------------------------------ pcsx2/x86/iR3000A.cpp | 186 +++++++++++++------------ pcsx2/x86/iR3000Atables.cpp | 50 +++---- pcsx2/x86/ix86-32/iR5900-32.cpp | 8 +- 18 files changed, 308 insertions(+), 531 deletions(-) diff --git a/pcsx2/CDVD.cpp b/pcsx2/CDVD.cpp index 9d5f982ad2..7b171ba648 100644 --- a/pcsx2/CDVD.cpp +++ b/pcsx2/CDVD.cpp @@ -531,12 +531,10 @@ void cdvdReadKey(u8 arg0, u16 arg1, u32 arg2, u8* key) { // Now's a good time to reload the ELF info... if( ElfCRC == 0 ) { - FreezeMMXRegs(1); ElfCRC = loadElfCRC( str ); ElfApplyPatches(); LoadGameSpecificSettings(); GSsetGameCRC( ElfCRC, 0 ); - FreezeMMXRegs(0); } } @@ -840,7 +838,7 @@ void cdvdNewDiskCB() } } -void mechaDecryptBytes(unsigned char* buffer, int size) +void mechaDecryptBytes( u32 madr, int size ) { int i; @@ -848,10 +846,11 @@ void mechaDecryptBytes(unsigned char* buffer, int size) int doXor = (cdvd.decSet) & 1; int doShift = (cdvd.decSet) & 2; - for (i=0; i>shiftAmount) | (buffer[i]<<(8-shiftAmount)); + if( doXor ) *curval ^= cdvd.Key[4]; + if( doShift ) *curval = (*curval >> shiftAmount) | (*curval << (8-shiftAmount) ); } } @@ -870,10 +869,12 @@ int cdvdReadSector() { return -1; } - const u32 madr = HW_DMA3_MADR; + // DMAs use physical addresses (air) + u8* mdest = iopPhysMem( HW_DMA3_MADR ); // if raw dvd sector 'fill in the blanks' - if (cdvd.BlockSize == 2064) { + if (cdvd.BlockSize == 2064) + { // get info on dvd type and layer1 start u32 layer1Start; s32 dualType; @@ -882,57 +883,62 @@ int cdvdReadSector() { cdvdReadDvdDualInfo(&dualType, &layer1Start); - if((dualType == 1) && (lsn >= layer1Start)) { + if((dualType == 1) && (lsn >= layer1Start)) + { // dual layer ptp disc layerNum = 1; lsn = lsn-layer1Start + 0x30000; - } else if((dualType == 2) && (lsn >= layer1Start)) { + } else if((dualType == 2) && (lsn >= layer1Start)) + { // dual layer otp disc layerNum = 1; lsn = ~(layer1Start+0x30000 - 1); - } else { + } else + { // single layer disc // or on first layer of dual layer disc layerNum = 0; lsn += 0x30000; } // ENDLONGIF- Assumed the other dualType is 0. + + mdest[0] = 0x20 | layerNum; + mdest[1] = (u8)(lsn >> 16); + mdest[2] = (u8)(lsn >> 8); + mdest[3] = (u8)(lsn ); - PSXMu8(madr+0) = 0x20 | layerNum; - PSXMu8(madr+1) = (u8)(lsn >> 16); - PSXMu8(madr+2) = (u8)(lsn >> 8); - PSXMu8(madr+3) = (u8)(lsn ); - // sector IED (not calculated at present) - PSXMu8(madr+4) = 0; - PSXMu8(madr+5) = 0; - + mdest[4] = 0; + mdest[5] = 0; + // sector CPR_MAI (not calculated at present) - PSXMu8(madr+ 6) = 0; - PSXMu8(madr+ 7) = 0; - PSXMu8(madr+ 8) = 0; - PSXMu8(madr+ 9) = 0; - PSXMu8(madr+10) = 0; - PSXMu8(madr+11) = 0; - + mdest[6] = 0; + mdest[7] = 0; + mdest[8] = 0; + mdest[9] = 0; + mdest[10] = 0; + mdest[11] = 0; + // normal 2048 bytes of sector data - memcpy_fast(PSXM(madr+12), cdr.pTransfer, 2048); - + memcpy_fast( &mdest[12], cdr.pTransfer, 2048); + // 4 bytes of edc (not calculated at present) - PSXMu8(madr+2060) = 0; - PSXMu8(madr+2061) = 0; - PSXMu8(madr+2062) = 0; - PSXMu8(madr+2063) = 0; - } else { - // normal read - memcpy_fast((u8*)PSXM(madr), cdr.pTransfer, cdvd.BlockSize); + mdest[2060] = 0; + mdest[2061] = 0; + mdest[2062] = 0; + mdest[2063] = 0; } + else + { + memcpy_fast( mdest, cdr.pTransfer, cdvd.BlockSize); + } + // decrypt sector's bytes - if(cdvd.decSet) - mechaDecryptBytes((u8*)PSXM(madr), cdvd.BlockSize); + if( cdvd.decSet ) + mechaDecryptBytes( HW_DMA3_MADR, cdvd.BlockSize ); // Added a clear after memory write .. never seemed to be necessary before but *should* // be more correct. (air) - psxCpu->Clear( madr, cdvd.BlockSize/4); + psxCpu->Clear( HW_DMA3_MADR, cdvd.BlockSize/4 ); // SysPrintf("sector %x;%x;%x\n", PSXMu8(madr+0), PSXMu8(madr+1), PSXMu8(madr+2)); @@ -1329,7 +1335,7 @@ static uint cdvdStartSeek( uint newsector ) } else { - CDR_LOG( "CdSeek Begin > Contigious block without seek - delta=%d sectors\n", delta ); + CDR_LOG( "CdSeek Begin > Contiguous block without seek - delta=%d sectors\n", delta ); // seektime is the time it takes to read to the destination block: seektime = delta * cdvd.ReadTime; @@ -1419,7 +1425,7 @@ void cdvdWrite04(u8 rt) { // NCOMMAND cdvd.RErr = CDVDreadTrack( cdvd.SeekToSector, cdvd.ReadMode ); // Set the reading block flag. If a seek is pending then Readed will - // take priority in the handler anyway. If the read is contigeous then + // take priority in the handler anyway. If the read is contiguous then // this'll skip the seek delay. cdvd.Reading = 1; break; @@ -1460,7 +1466,7 @@ void cdvdWrite04(u8 rt) { // NCOMMAND cdvd.RErr = CDVDreadTrack( cdvd.SeekToSector, cdvd.ReadMode ); // Set the reading block flag. If a seek is pending then Readed will - // take priority in the handler anyway. If the read is contigeous then + // take priority in the handler anyway. If the read is contiguous then // this'll skip the seek delay. cdvd.Reading = 1; break; @@ -1491,7 +1497,7 @@ void cdvdWrite04(u8 rt) { // NCOMMAND cdvd.RErr = CDVDreadTrack( cdvd.SeekToSector, cdvd.ReadMode ); // Set the reading block flag. If a seek is pending then Readed will - // take priority in the handler anyway. If the read is contigeous then + // take priority in the handler anyway. If the read is contiguous then // this'll skip the seek delay. cdvd.Reading = 1; break; @@ -1503,7 +1509,7 @@ void cdvdWrite04(u8 rt) { // NCOMMAND //{ DevCon::WriteLn("CDGetToc Param[0]=%d, Param[1]=%d", params cdvd.Param[0],cdvd.Param[1]); //} - cdvdGetToc( PSXM( HW_DMA3_MADR ) ); + cdvdGetToc( iopPhysMem( HW_DMA3_MADR ) ); cdvdSetIrq( (1<Clear(madr, cdsize/4); cdr.pTransfer+=cdsize; diff --git a/pcsx2/IopBios.cpp b/pcsx2/IopBios.cpp index d7d21659f5..bb84b6dc85 100644 --- a/pcsx2/IopBios.cpp +++ b/pcsx2/IopBios.cpp @@ -164,18 +164,18 @@ const char *biosC0n[256] = { #define ra (psxRegs.GPR.n.ra) #define pc0 (psxRegs.pc) -#define Ra0 ((char*)PSXM(a0)) -#define Ra1 ((char*)PSXM(a1)) -#define Ra2 ((char*)PSXM(a2)) -#define Ra3 ((char*)PSXM(a3)) -#define Rv0 ((char*)PSXM(v0)) -#define Rsp ((char*)PSXM(sp)) +#define Ra0 (iopVirtMemR(a0)) +#define Ra1 (iopVirtMemR(a1)) +#define Ra2 (iopVirtMemR(a2)) +#define Ra3 (iopVirtMemR(a3)) +#define Rv0 (iopVirtMemR(v0)) +#define Rsp (iopVirtMemR(sp)) void bios_write() { // 0x35/0x03 if (a0 == 1) { // stdout - char *ptr = Ra1; + const char *ptr = Ra1; while (a2 > 0) { SysPrintf("%c", *ptr++); a2--; @@ -195,11 +195,19 @@ void bios_printf() { // 3f char *ptmp = tmp; int n=1, i=0, j; - memcpy(save, (char*)PSXM(sp), 4*4); - psxMu32(sp) = a0; - psxMu32(sp + 4) = a1; - psxMu32(sp + 8) = a2; - psxMu32(sp + 12) = a3; + memcpy(save, iopVirtMemR(sp), 4*4); + + iopMemWrite32(sp, a0); + iopMemWrite32(sp + 4, a1); + iopMemWrite32(sp + 8, a2); + iopMemWrite32(sp + 12, a3); + + + // old code used phys... is tlb more correct? + //psxMu32(sp) = a0; + //psxMu32(sp + 4) = a1; + //psxMu32(sp + 8) = a2; + //psxMu32(sp + 12) = a3; while (Ra0[i]) { switch (Ra0[i]) { @@ -223,21 +231,21 @@ _start: switch (Ra0[i]) { case 'f': case 'F': - ptmp+= sprintf(ptmp, tmp2, (float)psxMu32(sp + n * 4)); n++; break; + ptmp+= sprintf(ptmp, tmp2, (float)iopMemRead32(sp + n * 4)); n++; break; case 'a': case 'A': case 'e': case 'E': case 'g': case 'G': - ptmp+= sprintf(ptmp, tmp2, (double)psxMu32(sp + n * 4)); n++; break; + ptmp+= sprintf(ptmp, tmp2, (double)iopMemRead32(sp + n * 4)); n++; break; case 'p': case 'i': case 'd': case 'D': case 'o': case 'O': case 'x': case 'X': - ptmp+= sprintf(ptmp, tmp2, (unsigned int)psxMu32(sp + n * 4)); n++; break; + ptmp+= sprintf(ptmp, tmp2, (unsigned int)iopMemRead32(sp + n * 4)); n++; break; case 'c': - ptmp+= sprintf(ptmp, tmp2, (unsigned char)psxMu32(sp + n * 4)); n++; break; + ptmp+= sprintf(ptmp, tmp2, (unsigned char)iopMemRead32(sp + n * 4)); n++; break; case 's': - ptmp+= sprintf(ptmp, tmp2, (char*)PSXM(psxMu32(sp + n * 4))); n++; break; + ptmp+= sprintf(ptmp, tmp2, iopVirtMemR(iopMemRead32(sp + n * 4))); n++; break; case '%': *ptmp++ = Ra0[i]; break; } @@ -249,7 +257,9 @@ _start: } *ptmp = 0; - memcpy((char*)PSXM(sp), save, 4*4); + // Note: Use Read to obtain a write pointer here, since we're just writing back the + // temp buffer we saved earlier. + memcpy( (void*)iopVirtMemR(sp), save, 4*4); Console::Write( Color_Cyan, "%s", params tmp); diff --git a/pcsx2/IopDma.cpp b/pcsx2/IopDma.cpp index cc49441e89..53995dfb1d 100644 --- a/pcsx2/IopDma.cpp +++ b/pcsx2/IopDma.cpp @@ -43,9 +43,7 @@ static void __fastcall psxDmaGeneric(u32 madr, u32 bcr, u32 chcr, u32 spuCore, _ if(SPU2async) { - FreezeMMXRegs( 1 ); SPU2async(psxRegs.cycle - psxCounters[6].sCycleT); - FreezeMMXRegs( 0 ); //Console::Status("cycles sent to SPU2 %x\n", psxRegs.cycle - psxCounters[6].sCycleT); psxCounters[6].sCycleT = psxRegs.cycle; @@ -61,12 +59,12 @@ static void __fastcall psxDmaGeneric(u32 madr, u32 bcr, u32 chcr, u32 spuCore, _ { case 0x01000201: //cpu to spu2 transfer PSXDMA_LOG("*** DMA %c - mem2spu *** %x addr = %x size = %x\n", dmaNum, chcr, madr, bcr); - spu2WriteFunc((u16 *)PSXM(madr), size*2); + spu2WriteFunc((u16 *)iopPhysMem(madr), size*2); break; case 0x01000200: //spu2 to cpu transfer PSXDMA_LOG("*** DMA %c - spu2mem *** %x addr = %x size = %x\n", dmaNum, chcr, madr, bcr); - spu2ReadFunc((u16 *)PSXM(madr), size*2); + spu2ReadFunc((u16 *)iopPhysMem(madr), size*2); psxCpu->Clear(spuCore ? HW_DMA7_MADR : HW_DMA4_MADR, size); break; @@ -97,7 +95,7 @@ void psxDma2(u32 madr, u32 bcr, u32 chcr) // GPU void psxDma6(u32 madr, u32 bcr, u32 chcr) { - u32 *mem = (u32 *)PSXM(madr); + u32 *mem = (u32 *)iopPhysMem(madr); PSXDMA_LOG("*** DMA 6 - OT *** %lx addr = %lx size = %lx\n", chcr, madr, bcr); @@ -166,12 +164,12 @@ void psxDma8(u32 madr, u32 bcr, u32 chcr) { switch (chcr & 0x01000201) { case 0x01000201: //cpu to dev9 transfer PSXDMA_LOG("*** DMA 8 - DEV9 mem2dev9 *** %lx addr = %lx size = %lx\n", chcr, madr, bcr); - DEV9writeDMA8Mem((u32*)PSXM(madr), size); + DEV9writeDMA8Mem((u32*)iopPhysMem(madr), size); break; case 0x01000200: //dev9 to cpu transfer PSXDMA_LOG("*** DMA 8 - DEV9 dev9mem *** %lx addr = %lx size = %lx\n", chcr, madr, bcr); - DEV9readDMA8Mem((u32*)PSXM(madr), size); + DEV9readDMA8Mem((u32*)iopPhysMem(madr), size); break; default: diff --git a/pcsx2/IopMem.cpp b/pcsx2/IopMem.cpp index 421852ef01..136b862458 100644 --- a/pcsx2/IopMem.cpp +++ b/pcsx2/IopMem.cpp @@ -42,7 +42,7 @@ void psxMemShutdown() { } -u8 psxMemRead8(u32 mem) +u8 iopMemRead8(u32 mem) { u32 t = (mem >> 16) & 0x1fff; @@ -71,7 +71,7 @@ u8 psxMemRead8(u32 mem) } } -u16 psxMemRead16(u32 mem) +u16 iopMemRead16(u32 mem) { u32 t = (mem >> 16) & 0x1fff; @@ -105,7 +105,7 @@ u16 psxMemRead16(u32 mem) } } -u32 psxMemRead32(u32 mem) +u32 iopMemRead32(u32 mem) { u32 t = (mem >> 16) & 0x1fff; @@ -144,7 +144,7 @@ u32 psxMemRead32(u32 mem) } } -void psxMemWrite8(u32 mem, u8 value) +void iopMemWrite8(u32 mem, u8 value) { u32 t = (mem >> 16) & 0x1fff; @@ -179,7 +179,7 @@ void psxMemWrite8(u32 mem, u8 value) } } -void psxMemWrite16(u32 mem, u16 value) +void iopMemWrite16(u32 mem, u16 value) { u32 t = (mem >> 16) & 0x1fff; switch(t) { @@ -235,7 +235,7 @@ void psxMemWrite16(u32 mem, u16 value) } } -void psxMemWrite32(u32 mem, u32 value) +void iopMemWrite32(u32 mem, u32 value) { u32 t = (mem >> 16) & 0x1fff; switch(t) { @@ -326,22 +326,6 @@ void psxMemWrite32(u32 mem, u32 value) #else -// TLB functions - -#ifdef TLB_DEBUG_MEM -// fixme - there are a few places in the code where this is called that really shouldn't receive null. -// cdvdReadSector in CDVD.cpp, psxDma3 in CdRom.cpp, to name two. -void* PSXM(u32 mem) -{ - return (psxMemRLUT[(mem) >> 16] == 0 ? NULL : (void*)(psxMemRLUT[(mem) >> 16] + ((mem) & 0xffff))); -} - -void* _PSXM(u32 mem) -{ - return ((void*)(psxMemRLUT[(mem) >> 16] + ((mem) & 0xffff))); -} -#endif - u8 *psxM = NULL; u8 *psxP = NULL; u8 *psxH = NULL; @@ -442,7 +426,6 @@ void psxMemShutdown() { vtlb_free( m_psxAllMem, m_psxMemSize ); m_psxAllMem = NULL; - //safe_aligned_free( m_psxAllMem ); psxM = psxP = psxH = psxS = NULL; @@ -450,7 +433,7 @@ void psxMemShutdown() psxMemRLUT = NULL; } -u8 psxMemRead8(u32 mem) { +u8 iopMemRead8(u32 mem) { const u8* p; u32 t; @@ -477,7 +460,7 @@ u8 psxMemRead8(u32 mem) { } } -u16 psxMemRead16(u32 mem) { +u16 iopMemRead16(u32 mem) { const u8* p; u32 t; @@ -525,7 +508,7 @@ u16 psxMemRead16(u32 mem) { } } -u32 psxMemRead32(u32 mem) { +u32 iopMemRead32(u32 mem) { const u8* p; u32 t; t = (mem >> 16) & 0x1fff; @@ -573,9 +556,7 @@ u32 psxMemRead32(u32 mem) { if (t == 0x1000) return DEV9read32(mem & 0x1FFFFFFF); if (mem != 0xfffe0130) { -#ifdef PSXMEM_LOG if (g_psxWriteOk) PSXMEM_LOG("err lw %8.8lx\n", mem); -#endif } else { return writectrl; } @@ -584,7 +565,7 @@ u32 psxMemRead32(u32 mem) { } } -void psxMemWrite8(u32 mem, u8 value) { +void iopMemWrite8(u32 mem, u8 value) { char *p; u32 t; @@ -617,7 +598,7 @@ void psxMemWrite8(u32 mem, u8 value) { } } -void psxMemWrite16(u32 mem, u16 value) { +void iopMemWrite16(u32 mem, u16 value) { char *p; u32 t; @@ -674,7 +655,7 @@ void psxMemWrite16(u32 mem, u16 value) { } } -void psxMemWrite32(u32 mem, u32 value) { +void iopMemWrite32(u32 mem, u32 value) { char *p; u32 t; diff --git a/pcsx2/IopMem.h b/pcsx2/IopMem.h index 57d9dca6f2..3723c32b6c 100644 --- a/pcsx2/IopMem.h +++ b/pcsx2/IopMem.h @@ -26,13 +26,31 @@ extern u8 *psxS; extern uptr *psxMemWLUT; extern const uptr *psxMemRLUT; -#ifdef TLB_DEBUG_MEM -void* PSXM(u32 mem); -void* _PSXM(u32 mem); -#else -#define PSXM(mem) (psxMemRLUT[(mem) >> 16] == 0 ? NULL : (void*)(psxMemRLUT[(mem) >> 16] + ((mem) & 0xffff))) -#define _PSXM(mem) ((const void*)(psxMemRLUT[(mem) >> 16] + ((mem) & 0xffff))) -#endif + +// Obtains a write-safe pointer into the IOP's memory, with TLB address translation. +// Hacky! This should really never be used, since anything reading or writing through the +// TLB should be using iopMemRead/Write instead. +template +static __forceinline T* iopVirtMemW( u32 mem ) +{ + return (psxMemWLUT[(mem) >> 16] == 0) ? NULL : (T*)(psxMemRLUT[(mem) >> 16] + ((mem) & 0xffff)); +} + +// Obtains a read-safe pointer into the IOP's memory, with TLB address translation. +// Hacky! This should really never be used, since anything reading or writing through the +// TLB should be using iopMemRead/Write instead. +template +static __forceinline const T* iopVirtMemR( u32 mem ) +{ + return (psxMemRLUT[(mem) >> 16] == 0) ? NULL : (const T*)(psxMemRLUT[(mem) >> 16] + ((mem) & 0xffff)); + //return ((const T*)(psxMemRLUT[(mem) >> 16] + ((mem) & 0xffff))); +} + +// Obtains a pointer to the IOP's physical mapping (bypasses the TLB) +static __forceinline u8* iopPhysMem( u32 addr ) +{ + return &psxM[addr & 0x1fffff]; +} #define psxSs8(mem) psxS[(mem) & 0xffff] #define psxSs16(mem) (*(s16*)&psxS[(mem) & 0xffff]) @@ -41,14 +59,6 @@ void* _PSXM(u32 mem); #define psxSu16(mem) (*(u16*)&psxS[(mem) & 0xffff]) #define psxSu32(mem) (*(u32*)&psxS[(mem) & 0xffff]) -#define psxMs8(mem) psxM[(mem) & 0x1fffff] -#define psxMs16(mem) (*(s16*)&psxM[(mem) & 0x1fffff]) -#define psxMs32(mem) (*(s32*)&psxM[(mem) & 0x1fffff]) -#define psxMu8(mem) (*(u8*) &psxM[(mem) & 0x1fffff]) -#define psxMu16(mem) (*(u16*)&psxM[(mem) & 0x1fffff]) -#define psxMu32(mem) (*(u32*)&psxM[(mem) & 0x1fffff]) -#define psxMu64(mem) (*(u64*)&psxM[(mem) & 0x1fffff]) - #define psxPs8(mem) psxP[(mem) & 0xffff] #define psxPs16(mem) (*(s16*)&psxP[(mem) & 0xffff]) #define psxPs32(mem) (*(s32*)&psxP[(mem) & 0xffff]) @@ -63,23 +73,23 @@ void* _PSXM(u32 mem); #define psxHu16(mem) (*(u16*)&psxH[(mem) & 0xffff]) #define psxHu32(mem) (*(u32*)&psxH[(mem) & 0xffff]) -#define PSXMs8(mem) (*(s8 *)_PSXM(mem)) -#define PSXMs16(mem) (*(s16*)_PSXM(mem)) -#define PSXMs32(mem) (*(s32*)_PSXM(mem)) -#define PSXMu8(mem) (*(u8 *)_PSXM(mem)) -#define PSXMu16(mem) (*(u16*)_PSXM(mem)) -#define PSXMu32(mem) (*(u32*)_PSXM(mem)) +//#define PSXMs8(mem) (*(s8 *)_PSXM(mem)) +//#define PSXMs16(mem) (*(s16*)_PSXM(mem)) +//#define PSXMs32(mem) (*(s32*)_PSXM(mem)) +//#define PSXMu8(mem) (*(u8 *)_PSXM(mem)) +//#define PSXMu16(mem) (*(u16*)_PSXM(mem)) +//#define PSXMu32(mem) (*(u32*)_PSXM(mem)) void psxMemAlloc(); void psxMemReset(); void psxMemShutdown(); -u8 psxMemRead8 (u32 mem); -u16 psxMemRead16(u32 mem); -u32 psxMemRead32(u32 mem); -void psxMemWrite8 (u32 mem, u8 value); -void psxMemWrite16(u32 mem, u16 value); -void psxMemWrite32(u32 mem, u32 value); +u8 iopMemRead8 (u32 mem); +u16 iopMemRead16(u32 mem); +u32 iopMemRead32(u32 mem); +void iopMemWrite8 (u32 mem, u8 value); +void iopMemWrite16(u32 mem, u16 value); +void iopMemWrite32(u32 mem, u32 value); // x86reg and mmreg are always x86 regs void psxRecMemRead8(); diff --git a/pcsx2/IopSio2.cpp b/pcsx2/IopSio2.cpp index 0e2efb2a9f..ebece56760 100644 --- a/pcsx2/IopSio2.cpp +++ b/pcsx2/IopSio2.cpp @@ -222,7 +222,7 @@ void psxDma11(u32 madr, u32 bcr, u32 chcr) { sio.count = 1; for(j = 0; j < ((bcr & 0xFFFF) * 4); j++) { - sio2_fifoIn(PSXMu8(madr)); + sio2_fifoIn(iopMemRead8(madr)); madr++; if(sio2.packet.sendSize == BUFSIZE) goto finished; @@ -250,7 +250,7 @@ void psxDma12(u32 madr, u32 bcr, u32 chcr) { bcr = size; while (bcr > 0) { - PSXMu8(madr) = sio2_fifoOut(); + iopMemWrite8( madr, sio2_fifoOut() ); bcr--; madr++; if(sio2.recvIndex == sio2.packet.sendSize) break; } diff --git a/pcsx2/Patch.cpp b/pcsx2/Patch.cpp index e00f255338..bfbb2cbb63 100644 --- a/pcsx2/Patch.cpp +++ b/pcsx2/Patch.cpp @@ -381,13 +381,13 @@ void _applypatch(int place, IniPatch *p) switch (p->type) { case BYTE_T: - psxMemWrite8(p->addr, (u8)p->data); + iopMemWrite8(p->addr, (u8)p->data); break; case SHORT_T: - psxMemWrite16(p->addr, (u16)p->data); + iopMemWrite16(p->addr, (u16)p->data); break; case WORD_T: - psxMemWrite32(p->addr, (u32)p->data); + iopMemWrite32(p->addr, (u32)p->data); break; default: break; diff --git a/pcsx2/R3000AInterpreter.cpp b/pcsx2/R3000AInterpreter.cpp index 2a44912a72..3753aa0979 100644 --- a/pcsx2/R3000AInterpreter.cpp +++ b/pcsx2/R3000AInterpreter.cpp @@ -174,10 +174,10 @@ irxlib irxlibs[32] = { 26 } }; -#define Ra0 ((char*)PSXM(psxRegs.GPR.n.a0)) -#define Ra1 ((char*)PSXM(psxRegs.GPR.n.a1)) -#define Ra2 ((char*)PSXM(psxRegs.GPR.n.a2)) -#define Ra3 ((char*)PSXM(psxRegs.GPR.n.a3)) +#define Ra0 (iopVirtMemR(psxRegs.GPR.n.a0)) +#define Ra1 (iopVirtMemR(psxRegs.GPR.n.a1)) +#define Ra2 (iopVirtMemR(psxRegs.GPR.n.a2)) +#define Ra3 (iopVirtMemR(psxRegs.GPR.n.a3)) const char* intrname[]={ "INT_VBLANK", "INT_GM", "INT_CDROM", "INT_DMA", //00 @@ -204,17 +204,17 @@ void zeroEx() #ifdef PCSX2_DEVBUILD u32 pc; u32 code; - char *lib; + const char *lib; char *fname = NULL; int i; if (!Config.PsxOut) return; pc = psxRegs.pc; - while (PSXMu32(pc) != 0x41e00000) pc-=4; + while (iopMemRead32(pc) != 0x41e00000) pc-=4; - lib = (char*)PSXM(pc+12); - code = PSXMu32(psxRegs.pc - 4) & 0xffff; + lib = iopVirtMemR(pc+12); + code = iopMemRead32(psxRegs.pc - 4) & 0xffff; for (i=0; i(psxRegs.GPR.n.a0+12)); } if (!strncmp(lib, "intrman", 7) && code == 4) { @@ -377,8 +377,9 @@ void psxJALR() { if (_Rd_) { _SetLink(_Rd_); } doBranch(_u32(_rRs_)); } /////////////////////////////////////////// // These macros are used to assemble the repassembler functions -static __forceinline void execI() { - psxRegs.code = PSXMu32(psxRegs.pc); +static __forceinline void execI() +{ + psxRegs.code = iopMemRead32(psxRegs.pc); PSXCPU_LOG("%s\n", disR3000AF(psxRegs.code, psxRegs.pc)); diff --git a/pcsx2/R3000AOpcodeTables.cpp b/pcsx2/R3000AOpcodeTables.cpp index 95ce89b371..ccd5c3c00c 100644 --- a/pcsx2/R3000AOpcodeTables.cpp +++ b/pcsx2/R3000AOpcodeTables.cpp @@ -175,47 +175,47 @@ void psxRFE() { void psxLB() { if (_Rt_) { - _rRt_ = (s8 )psxMemRead8(_oB_); + _rRt_ = (s8 )iopMemRead8(_oB_); } else { - psxMemRead8(_oB_); + iopMemRead8(_oB_); } } void psxLBU() { if (_Rt_) { - _rRt_ = psxMemRead8(_oB_); + _rRt_ = iopMemRead8(_oB_); } else { - psxMemRead8(_oB_); + iopMemRead8(_oB_); } } void psxLH() { if (_Rt_) { - _rRt_ = (s16)psxMemRead16(_oB_); + _rRt_ = (s16)iopMemRead16(_oB_); } else { - psxMemRead16(_oB_); + iopMemRead16(_oB_); } } void psxLHU() { if (_Rt_) { - _rRt_ = psxMemRead16(_oB_); + _rRt_ = iopMemRead16(_oB_); } else { - psxMemRead16(_oB_); + iopMemRead16(_oB_); } } void psxLW() { if (_Rt_) { - _rRt_ = psxMemRead32(_oB_); + _rRt_ = iopMemRead32(_oB_); } else { - psxMemRead32(_oB_); + iopMemRead32(_oB_); } } void psxLWL() { u32 shift = (_oB_ & 3) << 3; - u32 mem = psxMemRead32(_oB_ & 0xfffffffc); + u32 mem = iopMemRead32(_oB_ & 0xfffffffc); if (!_Rt_) return; _rRt_ = ( _u32(_rRt_) & (0x00ffffff >> shift) ) | @@ -234,11 +234,11 @@ void psxLWL() { void psxLWR() { u32 shift = (_oB_ & 3) << 3; - u32 mem = psxMemRead32(_oB_ & 0xfffffffc); + u32 mem = iopMemRead32(_oB_ & 0xfffffffc); if (!_Rt_) return; _rRt_ = ( _u32(_rRt_) & (0xffffff00 << (24 - shift)) ) | - ( mem >> shift ); + ( mem >> shift ); /* Mem = 1234. Reg = abcd @@ -251,15 +251,15 @@ void psxLWR() { */ } -void psxSB() { psxMemWrite8 (_oB_, _u8 (_rRt_)); } -void psxSH() { psxMemWrite16(_oB_, _u16(_rRt_)); } -void psxSW() { psxMemWrite32(_oB_, _u32(_rRt_)); } +void psxSB() { iopMemWrite8 (_oB_, _u8 (_rRt_)); } +void psxSH() { iopMemWrite16(_oB_, _u16(_rRt_)); } +void psxSW() { iopMemWrite32(_oB_, _u32(_rRt_)); } void psxSWL() { u32 shift = (_oB_ & 3) << 3; - u32 mem = psxMemRead32(_oB_ & 0xfffffffc); + u32 mem = iopMemRead32(_oB_ & 0xfffffffc); - psxMemWrite32((_oB_ & 0xfffffffc), ( ( _u32(_rRt_) >> (24 - shift) ) ) | + iopMemWrite32((_oB_ & 0xfffffffc), ( ( _u32(_rRt_) >> (24 - shift) ) ) | ( mem & (0xffffff00 << shift) )); /* Mem = 1234. Reg = abcd @@ -274,9 +274,9 @@ void psxSWL() { void psxSWR() { u32 shift = (_oB_ & 3) << 3; - u32 mem = psxMemRead32(_oB_ & 0xfffffffc); + u32 mem = iopMemRead32(_oB_ & 0xfffffffc); - psxMemWrite32((_oB_ & 0xfffffffc), ( ( _u32(_rRt_) << shift ) | + iopMemWrite32((_oB_ & 0xfffffffc), ( ( _u32(_rRt_) << shift ) | (mem & (0x00ffffff >> (24 - shift)) ) ) ); /* Mem = 1234. Reg = abcd diff --git a/pcsx2/RDebug/deci2_dbgp.cpp b/pcsx2/RDebug/deci2_dbgp.cpp index 7f593474b2..0d5436fa53 100644 --- a/pcsx2/RDebug/deci2_dbgp.cpp +++ b/pcsx2/RDebug/deci2_dbgp.cpp @@ -244,8 +244,8 @@ void D2_DBGP(const u8 *inbuffer, u8 *outbuffer, char *message, char *eepc, char break; } if (in->h.destination=='I') - if (PSXM(mem->address & 0x1FFFFFFF)) - memcpy(data, PSXM(mem->address & 0x1FFFFFFF), mem->length); + if (iopVirtMemR(mem->address & 0x1FFFFFFF)) + memcpy(data, iopVirtMemR(mem->address & 0x1FFFFFFF), mem->length); else{ out->result=0x11; strcat(line, " ADDRESS ERROR"); @@ -298,8 +298,8 @@ void D2_DBGP(const u8 *inbuffer, u8 *outbuffer, char *message, char *eepc, char break; } if (in->h.destination=='I') - if (PSXM(mem->address & 0x1FFFFFFF)) - memcpy(PSXM(mem->address & 0x1FFFFFFF), data, mem->length); + if (iopVirtMemR(mem->address & 0x1FFFFFFF)) + memcpy( (void*)iopVirtMemR(mem->address & 0x1FFFFFFF), data, mem->length); else{ out->result=0x11; strcat(line, " ADDRESS ERROR"); diff --git a/pcsx2/RDebug/deci2_iloadp.cpp b/pcsx2/RDebug/deci2_iloadp.cpp index c7c1ad45e9..dcf733dc2a 100644 --- a/pcsx2/RDebug/deci2_iloadp.cpp +++ b/pcsx2/RDebug/deci2_iloadp.cpp @@ -58,7 +58,7 @@ void D2_ILOADP(const u8 *inbuffer, u8 *outbuffer, char *message){ DECI2_ILOADP_HEADER *in=(DECI2_ILOADP_HEADER*)inbuffer, *out=(DECI2_ILOADP_HEADER*)outbuffer; u8 *data=(u8*)in+sizeof(DECI2_ILOADP_HEADER); - irxImageInfo *iii; + const irxImageInfo *iii; static char line[1024]; memcpy(outbuffer, inbuffer, 128*1024);//BUFFERSIZE @@ -76,7 +76,7 @@ void D2_ILOADP(const u8 *inbuffer, u8 *outbuffer, char *message){ case 4: sprintf(line, "code=LIST action=%d stamp=%d moduleId=0x%X", in->action, in->stamp, in->moduleId); data=(u8*)out+sizeof(DECI2_ILOADP_HEADER); - for (iii=(irxImageInfo*)PSXM(0x800); iii; iii=iii->next?(irxImageInfo*)PSXM(iii->next):0, data+=4) + for (iii=iopVirtMemR(0x800); iii; iii=iii->next?iopVirtMemR(iii->next):0, data+=4) *(u32*)data=iii->index; out->h.length=data-(u8*)out; @@ -84,13 +84,13 @@ void D2_ILOADP(const u8 *inbuffer, u8 *outbuffer, char *message){ case 6: sprintf(line, "code=INFO action=%d stamp=%d moduleId=0x%X", in->action, in->stamp, in->moduleId); data=(u8*)out+sizeof(DECI2_ILOADP_HEADER); - for(iii=(irxImageInfo*)PSXM(0x800); iii; iii=iii->next?(irxImageInfo*)PSXM(iii->next):0) + for(iii=iopVirtMemR(0x800); iii; iii=iii->next?iopVirtMemR(iii->next):0) if (iii->index==in->moduleId){ writeInfo((DECI2_ILOADP_INFO*)data, iii->version, iii->flags, iii->vaddr, iii->text_size, iii->data_size, iii->bss_size); data+=sizeof(DECI2_ILOADP_INFO); - strcpy((char*)data, (char*)PSXM(iii->name)); - data+=strlen((char*)PSXM(iii->name))+4; + strcpy((char*)data, iopVirtMemR(iii->name)); + data+=strlen(iopVirtMemR(iii->name))+4; data=(u8*)((int)data & 0xFFFFFFFC); break; diff --git a/pcsx2/Sif.cpp b/pcsx2/Sif.cpp index 64c7bbb642..0b986ec392 100644 --- a/pcsx2/Sif.cpp +++ b/pcsx2/Sif.cpp @@ -204,11 +204,11 @@ __forceinline void SIF0Dma() else // Chain mode { // Process DMA tag at HW_DMA9_TADR - sif0.sifData = *(struct sifData *)PSXM(HW_DMA9_TADR); + sif0.sifData = *(sifData *)iopPhysMem( HW_DMA9_TADR ); sif0.sifData.words = (sif0.sifData.words + 3) & 0xfffffffc; // Round up to nearest 4. - SIF0write((u32*)PSXM(HW_DMA9_TADR+8), 4); + SIF0write((u32*)iopPhysMem(HW_DMA9_TADR+8), 4); //psxCycles += 2; @@ -231,7 +231,7 @@ __forceinline void SIF0Dma() SIF_LOG("+++++++++++ %lX of %lX\n", wTransfer, sif0.counter /*(HW_DMA9_BCR >> 16)*/ ); - SIF0write((u32*)PSXM(HW_DMA9_MADR), wTransfer); + SIF0write((u32*)iopPhysMem(HW_DMA9_MADR), wTransfer); HW_DMA9_MADR += wTransfer << 2; //HW_DMA9_BCR = (HW_DMA9_BCR & 0xFFFF) | (((HW_DMA9_BCR >> 16) - wTransfer)<<16); psxCycles += (wTransfer / 4) * BIAS; // fixme : should be / 16 @@ -453,7 +453,7 @@ __forceinline void SIF1Dma() SIF_LOG(" IOP SIF doing transfer %04X to %08X\n", readSize, HW_DMA10_MADR); - SIF1read((u32*)PSXM(HW_DMA10_MADR), readSize); + SIF1read((u32*)iopPhysMem(HW_DMA10_MADR), readSize); psxCpu->Clear(HW_DMA10_MADR, readSize); psxCycles += readSize / 4; // fixme: should be / 16 sif1.counter = size-readSize; diff --git a/pcsx2/windows/Debugger.cpp b/pcsx2/windows/Debugger.cpp index 5c713c61ac..b9f4655e61 100644 --- a/pcsx2/windows/Debugger.cpp +++ b/pcsx2/windows/Debugger.cpp @@ -57,7 +57,7 @@ void MakeDebugOpcode(void) void MakeIOPDebugOpcode(void) { - psxRegs.code = PSXMu32( opcode_addr); + psxRegs.code = iopMemRead32( opcode_addr ); } BOOL HasBreakpoint() @@ -671,7 +671,7 @@ void RefreshIOPDebugger(void) for (t = DebuggerIOPPC, cnt = 0; t < (DebuggerIOPPC + 0x00000029); t += 0x00000004, cnt++) { // Make the opcode. - u32 mem = PSXMu32(t); + u32 mem = iopMemRead32( t ); char *str = R3000A::disR3000Fasm(mem, t); SendMessage(hWnd_IOP_debugdisasm, LB_ADDSTRING, 0, (LPARAM)str); } diff --git a/pcsx2/x86/aR3000A.S b/pcsx2/x86/aR3000A.S index 4dfc408232..20b73843c8 100644 --- a/pcsx2/x86/aR3000A.S +++ b/pcsx2/x86/aR3000A.S @@ -8,221 +8,14 @@ .extern b440 .extern b440table -#define PS2MEM_BASE_ 0x18000000 // has to match Memory.h - + #define BLOCKTYPE_STARTPC 4 // startpc offset #define BLOCKTYPE_DELAYSLOT 1 // if bit set, delay slot #define BASEBLOCK_SIZE 2 // in dwords #define PCOFFSET 0x208 -#define PSX_MEMMASK 0x5fffffff - -#ifdef __x86_64__ - -#define REG_PC %edi -#define REG_BLOCK %r12 -#define REG_BLOCKd %r12d - -.globl R3000AExecute -R3000AExecute: - - push %rbx - push %rbp - push %r12 - push %r13 - push %r14 - push %r15 - - // calc PSX_GETBLOCK - // ((BASEBLOCK*)(recLUT[((u32)(x)) >> 16] + (sizeof(BASEBLOCK)/4)*((x) & 0xffff))) - mov %eax, dword ptr [psxRegs + PCOFFSET] - mov REG_PC, %eax - mov REG_BLOCKd, %eax - shl %rax, 32 - shr %rax, 48 - and REG_BLOCK, 0xfffc - shl %rax, 3 - add %rax, [psxRecLUT] - shl REG_BLOCK, 1 - add REG_BLOCK, [%rax] - - mov %r8d, [REG_BLOCK+4] - mov %r9d, REG_PC - and %r8d, 0x5fffffff - and %r9d, 0x5fffffff - cmp %r8d, %r9d - jne Execute_Recompile - mov %edx, [REG_BLOCK] - and %rdx, 0xfffffff // pFnptr - jnz Execute_Function - -Execute_Recompile: - call psxRecRecompile - mov %edx, [REG_BLOCK] - and %rdx, 0xfffffff // pFnptr - -Execute_Function: - call %rdx - - pop %r15 - pop %r14 - pop %r13 - pop %r12 - pop %rbp - pop %rbx - ret - - -// jumped to when invalid psxpc address -.globl psxDispatcher -psxDispatcher: - // EDX contains the current psxpc to jump to, stack contains the jump addr to modify - push %rdx - - // calc PSX_GETBLOCK - // ((BASEBLOCK*)(recLUT[((u32)(x)) >> 16] + (sizeof(BASEBLOCK)/4)*((x) & 0xffff))) - mov %eax, dword ptr [psxRegs + PCOFFSET] - mov REG_PC, %eax - mov REG_BLOCKd, %eax - shl %rax, 32 - shr %rax, 48 - and REG_BLOCK, 0xfffc - shl %rax, 3 - add %rax, [psxRecLUT] - shl REG_BLOCK, 1 - add REG_BLOCK, [%rax] - - // check if startpc&PSX_MEMMASK == psxRegs.pc&PSX_MEMMASK - mov %eax, REG_PC - mov %edx, [REG_BLOCK+BLOCKTYPE_STARTPC] - and %eax, PSX_MEMMASK // remove higher bits - and %edx, PSX_MEMMASK - cmp %eax, %edx - je psxDispatcher_CheckPtr - - // recompile - call psxRecRecompile -psxDispatcher_CheckPtr: - mov REG_BLOCKd, dword ptr [REG_BLOCK] - -#ifdef _DEBUG - test REG_BLOCKd, REG_BLOCKd - jnz psxDispatcher_CallFn - // throw an exception - int 10 - -psxDispatcher_CallFn: -#endif - - //and REG_BLOCK, 0x0fffffff - shl REG_BLOCK, 4 - mov %rdx, REG_BLOCK - pop %rcx // x86Ptr to mod - sub %rdx, %rcx - sub %rdx, 4 - mov [%rcx], %edx - - jmp REG_BLOCK - -.globl psxDispatcherClear -psxDispatcherClear: - // %EDX contains the current psxpc - mov dword ptr [psxRegs + PCOFFSET], %edx - mov %eax, %edx - - // calc PSX_GETBLOCK - // ((BASEBLOCK*)(recLUT[((u32)(x)) >> 16] + (sizeof(BASEBLOCK)/4)*((x) & 0xffff))) - mov REG_BLOCKd, %edx - shl %rax, 32 - shr %rax, 48 - and REG_BLOCK, 0xfffc - shl %rax, 3 - add %rax, [psxRecLUT] - shl REG_BLOCK, 1 - add REG_BLOCK, [%rax] - - // check if startpc&PSX_MEMMASK == psxRegs.pc&PSX_MEMMASK - mov REG_PC, %edx - mov %eax, REG_PC - mov %edx, [REG_BLOCK+BLOCKTYPE_STARTPC] - and %eax, PSX_MEMMASK // remove higher bits - and %edx, PSX_MEMMASK - cmp %eax, %edx - jne psxDispatcherClear_Recompile - - mov %eax, dword ptr [REG_BLOCK] - -#ifdef _DEBUG - test %eax, %eax - jnz psxDispatcherClear_CallFn - // throw an exception - int 10 - -psxDispatcherClear_CallFn: -#endif - - //and %rax, 0x0fffffff - shl %rax, 4 - jmp %rax - -psxDispatcherClear_Recompile: - call psxRecRecompile - mov %eax, dword ptr [REG_BLOCK] - - // r15 holds the prev x86 pointer - //and %rax, 0x0fffffff - shl %rax, 4 - mov byte ptr [%r15], 0xe9 // jmp32 - mov %rdx, %rax - sub %rdx, %r15 - sub %rdx, 5 - mov [%r15+1], %edx - - jmp %rax - -// called when jumping to variable psxpc address -.globl psxDispatcherReg -psxDispatcherReg: - - //s_pDispatchBlock = PSX_GETBLOCK(psxRegs.pc); - mov %eax, dword ptr [psxRegs + PCOFFSET] - mov REG_PC, %eax - mov REG_BLOCKd, %eax - shl %rax, 32 - shr %rax, 48 - and REG_BLOCK, 0xfffc - shl %rax, 3 - add %rax, [psxRecLUT] - shl REG_BLOCK, 1 - add REG_BLOCK, [%rax] - - // check if startpc == psxRegs.pc - cmp REG_PC, dword ptr [REG_BLOCK+BLOCKTYPE_STARTPC] - jne psxDispatcherReg_recomp - - mov REG_BLOCKd, dword ptr [REG_BLOCK] - -#ifdef _DEBUG - test %eax, %eax - jnz psxDispatcherReg_CallFn2 - // throw an exception - int 10 -psxDispatcherReg_CallFn2: -#endif - and REG_BLOCK, 0x0fffffff - jmp REG_BLOCK // fnptr - -psxDispatcherReg_recomp: - call psxRecRecompile - - mov %eax, dword ptr [REG_BLOCK] - //and %rax, 0x0fffffff - shl, REG_BLOCK, 4 - jmp %rax // fnprt - -#else // not x86-64 - + #define REG_PC %ecx #define REG_BLOCK %esi @@ -247,8 +40,8 @@ psxDispatcher: // check if startpc&PSX_MEMMASK == psxRegs.pc&PSX_MEMMASK mov %eax, REG_PC mov %edx, [REG_BLOCK+BLOCKTYPE_STARTPC] - and %eax, PSX_MEMMASK // remove higher bits - and %edx, PSX_MEMMASK + //and %eax, PSX_MEMMASK // remove higher bits + //and %edx, PSX_MEMMASK cmp %eax, %edx je psxDispatcher_CheckPtr @@ -300,8 +93,8 @@ psxDispatcherClear: mov %eax, %edx mov REG_PC, %edx mov %edx, [REG_BLOCK+BLOCKTYPE_STARTPC] - and %eax, PSX_MEMMASK // remove higher bits - and %edx, PSX_MEMMASK + //and %eax, PSX_MEMMASK // remove higher bits + //and %edx, PSX_MEMMASK cmp %eax, %edx jne psxDispatcherClear_Recompile @@ -379,16 +172,14 @@ psxDispatcherReg_CallFn2: jmp %eax // fnptr psxDispatcherReg_recomp: - sub %esp, 8 - mov dword ptr [%esp+4], %edx - mov dword ptr [%esp], %ecx + // changed this to use push/pop instead (faster on cores) - air + push edx + push ecx call psxRecRecompile - mov %edx, dword ptr [%esp+4] - add %esp, 8 - + pop ecx + pop edx + mov %eax, dword ptr [%edx] //and %eax, 0x0fffffff shl %eax, 4 jmp %eax // fnptr - -#endif diff --git a/pcsx2/x86/iR3000A.cpp b/pcsx2/x86/iR3000A.cpp index 3509de234d..9fce22bfe9 100644 --- a/pcsx2/x86/iR3000A.cpp +++ b/pcsx2/x86/iR3000A.cpp @@ -100,7 +100,6 @@ static void iPsxBranchTest(u32 newpc, u32 cpuBranch); void psxRecompileNextInstruction(int delayslot); extern void (*rpsxBSC[64])(); -extern void (*rpsxBSC_co[64])(); void rpsxpropBSC(EEINST* prev, EEINST* pinst); #ifdef _DEBUG @@ -157,7 +156,7 @@ static void iIopDumpBlock( int startpc, u8 * ptr ) f = fopen( filename, "w" ); assert( f != NULL ); for ( i = startpc; i < s_nEndBlock; i += 4 ) { - fprintf( f, "%s\n", disR3000Fasm( *(u32*)PSXM( i ), i ) ); + fprintf( f, "%s\n", disR3000Fasm( iopMemRead32( i ), i ) ); } // write the instruction info @@ -655,17 +654,9 @@ static void recShutdown() #pragma warning(disable:4731) // frame pointer register 'ebp' modified by inline assembly code -static u32 s_uSaveESP = 0; - +/* static __forceinline void R3000AExecute() { -#ifdef _DEBUG - u8* fnptr; - u32 oldesi; -/*#else - R3000AFNPTR pfn;*/ -#endif - BASEBLOCK* pblock; pblock = PSX_GETBLOCK(psxRegs.pc); @@ -709,40 +700,29 @@ static __forceinline void R3000AExecute() #else ((R3000AFNPTR)pblock->GetFnptr())(); #endif -} +}*/ u32 g_psxlastpc = 0; -#if defined(_MSC_VER) +#ifdef _MSC_VER static u32 g_temp; // jumped to when invalid psxpc address -__declspec(naked,noreturn) void psxDispatcher() +__declspec(naked) void psxDispatcher() { // EDX contains the current psxpc to jump to, stack contains the jump addr to modify __asm push edx - // calc PSX_GETBLOCK - s_pDispatchBlock = PSX_GETBLOCK(psxRegs.pc); - - __asm { - mov eax, s_pDispatchBlock + //jASSUME( psxRegs.pc <= PSX_MEMMASK ); + s_pDispatchBlock = PSX_GETBLOCK( psxRegs.pc ); - // check if startpc&PSX_MEMMASK == psxRegs.pc&PSX_MEMMASK - mov ecx, psxRegs.pc - mov edx, [eax+BLOCKTYPE_STARTPC]; - and ecx, PSX_MEMMASK // remove higher bits - and edx, PSX_MEMMASK - cmp ecx, edx - je CheckPtr + if( s_pDispatchBlock->startpc != psxRegs.pc ) + psxRecRecompile(psxRegs.pc); - // recompile - push psxRegs.pc // psxpc - call psxRecRecompile - add esp, 4 // pop old param + __asm + { mov eax, s_pDispatchBlock -CheckPtr: mov eax, dword ptr [eax] } @@ -751,11 +731,12 @@ CheckPtr: assert( g_temp ); #endif - __asm { - //and eax, 0x0fffffff + // Modify the prev block's jump address, and jump to the new block: + __asm + { shl eax,4 - mov edx, eax pop ecx // x86Ptr to mod + mov edx, eax sub edx, ecx sub edx, 4 mov dword ptr [ecx], edx @@ -764,20 +745,23 @@ CheckPtr: } } -__declspec(naked,noreturn) void psxDispatcherClear() +__declspec(naked) void psxDispatcherClear() { // EDX contains the current psxpc __asm mov psxRegs.pc, edx __asm push edx + //jASSUME( psxRegs.pc <= PSX_MEMMASK ); + // calc PSX_GETBLOCK s_pDispatchBlock = PSX_GETBLOCK(psxRegs.pc); - if( (s_pDispatchBlock->startpc&PSX_MEMMASK) == (psxRegs.pc&PSX_MEMMASK) ) { + if( s_pDispatchBlock->startpc == psxRegs.pc ) { assert( s_pDispatchBlock->GetFnptr() != 0 ); // already modded the code, jump to the new place - __asm { + __asm + { pop edx add esp, 4 // ignore stack mov eax, s_pDispatchBlock @@ -788,7 +772,8 @@ __declspec(naked,noreturn) void psxDispatcherClear() } } - __asm { + __asm + { call psxRecRecompile add esp, 4 // pop old param mov eax, s_pDispatchBlock @@ -809,32 +794,18 @@ __declspec(naked,noreturn) void psxDispatcherClear() } // called when jumping to variable psxpc address -__declspec(naked,noreturn) void psxDispatcherReg() +__declspec(naked) void psxDispatcherReg() { - __asm { - //s_pDispatchBlock = PSX_GETBLOCK(psxRegs.pc); - mov edx, psxRegs.pc - mov ecx, edx - } + //jASSUME( psxRegs.pc <= PSX_MEMMASK ); + s_pDispatchBlock = PSX_GETBLOCK( psxRegs.pc ); - __asm { - shr edx, 14 - and edx, 0xfffffffc - add edx, psxRecLUT - mov edx, dword ptr [edx] + if( s_pDispatchBlock->startpc != psxRegs.pc ) + psxRecRecompile(psxRegs.pc); - mov eax, ecx - and eax, 0xfffc - // edx += 2*eax - shl eax, 1 - add edx, eax - - // check if startpc == psxRegs.pc - mov eax, ecx - cmp eax, dword ptr [edx+BLOCKTYPE_STARTPC] - jne recomp - - mov eax, dword ptr [edx] + __asm + { + mov eax, s_pDispatchBlock + mov eax, dword ptr [eax] } #ifdef _DEBUG @@ -842,23 +813,10 @@ __declspec(naked,noreturn) void psxDispatcherReg() assert( g_temp ); #endif - __asm { - //and eax, 0x0fffffff - shl eax,4 - jmp eax // fnptr - -recomp: - sub esp, 8 - mov dword ptr [esp+4], edx - mov dword ptr [esp], ecx - call psxRecRecompile - mov edx, dword ptr [esp+4] - add esp, 8 - - mov eax, dword ptr [edx] - //and eax, 0x0fffffff - shl eax,4 - jmp eax // fnptr + __asm + { + shl eax, 4 + jmp eax } } @@ -876,6 +834,58 @@ void psxDispatcherReg(); #endif // _MSC_VER +static void recExecute() +{ + // note: this function is currently never used. + //for (;;) R3000AExecute(); +} + +static s32 recExecuteBlock( s32 eeCycles ) +{ + psxBreak = 0; + psxCycleEE = eeCycles; + + // Register freezing note: + // The IOP does not use mmx/xmm registers, so we don't modify the status + // of the g_EEFreezeRegs here. + +#ifdef _MSC_VER + __asm + { + push ebx + push esi + push edi + push ebp + + call psxDispatcherReg + + pop ebp + pop edi + pop esi + pop ebx + } +#else + __asm__ + ( + ".intel_syntax\n" + "push %ebx\n" + "push %esi\n" + "push %edi\n" + "push %ebp\n" + + "call psxDispatcherReg\n" + + "pop %ebp\n" + "pop %edi\n" + "pop %esi\n" + "pop %ebx\n" + ".att_syntax\n" + ); +#endif + + return psxBreak + psxCycleEE; +} + static void recClear(u32 Addr, u32 Size) { u32 i; @@ -1034,7 +1044,7 @@ static void iPsxBranchTest(u32 newpc, u32 cpuBranch) x86SetJ8( j8Ptr[0] ); } -static int *s_pCode; +static const int *s_pCode; #if !defined(_MSC_VER) static void checkcodefn() @@ -1148,7 +1158,7 @@ void psxRecompileNextInstruction(int delayslot) MOV32ItoR(EAX, psxpc); #endif - s_pCode = (int *)PSXM( psxpc ); + s_pCode = iopVirtMemR( psxpc ); assert(s_pCode); psxRegs.code = *(int *)s_pCode; @@ -1185,18 +1195,6 @@ void psxRecompileNextInstruction(int delayslot) _clearNeededX86regs(); } -static void recExecute() { - for (;;) R3000AExecute(); -} - -static s32 recExecuteBlock( s32 eeCycles ) -{ - psxBreak = 0; - psxCycleEE = eeCycles; - R3000AExecute(); - return psxBreak + psxCycleEE; -} - #include "IopHw.h" void iDumpPsxRegisters(u32 startpc, u32 temp) @@ -1354,7 +1352,7 @@ void psxRecRecompile(u32 startpc) } } - psxRegs.code = *(int *)PSXM(i); + psxRegs.code = iopMemRead32(i); switch(psxRegs.code >> 26) { case 0: // special @@ -1414,7 +1412,7 @@ StartRecomp: pcur->info = 0; for(i = s_nEndBlock; i > startpc; i -= 4 ) { - psxRegs.code = *(int *)PSXM(i-4); + psxRegs.code = iopMemRead32(i-4); pcur[-1] = pcur[0]; rpsxpropBSC(pcur-1, pcur); pcur--; diff --git a/pcsx2/x86/iR3000Atables.cpp b/pcsx2/x86/iR3000Atables.cpp index 60648dacee..d971bffe6a 100644 --- a/pcsx2/x86/iR3000Atables.cpp +++ b/pcsx2/x86/iR3000Atables.cpp @@ -895,7 +895,7 @@ REC_FUNC(SWR); #else -// TLB loadstore functions (slower +// TLB loadstore functions REC_FUNC(LWL); REC_FUNC(LWR); REC_FUNC(SWL); @@ -909,7 +909,7 @@ static void rpsxLB() MOV32MtoR(X86ARG1, (uptr)&psxRegs.GPR.r[_Rs_]); if (_Imm_) ADD32ItoR(X86ARG1, _Imm_); - _callFunctionArg1((uptr)psxMemRead8, X86ARG1|MEM_X86TAG, 0); + _callFunctionArg1((uptr)iopMemRead8, X86ARG1|MEM_X86TAG, 0); if (_Rt_) { MOVSX32R8toR(EAX, EAX); MOV32RtoM((uptr)&psxRegs.GPR.r[_Rt_], EAX); @@ -925,7 +925,7 @@ static void rpsxLBU() MOV32MtoR(X86ARG1, (uptr)&psxRegs.GPR.r[_Rs_]); if (_Imm_) ADD32ItoR(X86ARG1, _Imm_); - _callFunctionArg1((uptr)psxMemRead8, X86ARG1|MEM_X86TAG, 0); + _callFunctionArg1((uptr)iopMemRead8, X86ARG1|MEM_X86TAG, 0); if (_Rt_) { MOVZX32R8toR(EAX, EAX); MOV32RtoM((uptr)&psxRegs.GPR.r[_Rt_], EAX); @@ -941,7 +941,7 @@ static void rpsxLH() MOV32MtoR(X86ARG1, (uptr)&psxRegs.GPR.r[_Rs_]); if (_Imm_) ADD32ItoR(X86ARG1, _Imm_); - _callFunctionArg1((uptr)psxMemRead16, X86ARG1|MEM_X86TAG, 0); + _callFunctionArg1((uptr)iopMemRead16, X86ARG1|MEM_X86TAG, 0); if (_Rt_) { MOVSX32R16toR(EAX, EAX); MOV32RtoM((uptr)&psxRegs.GPR.r[_Rt_], EAX); @@ -957,7 +957,7 @@ static void rpsxLHU() MOV32MtoR(X86ARG1, (uptr)&psxRegs.GPR.r[_Rs_]); if (_Imm_) ADD32ItoR(X86ARG1, _Imm_); - _callFunctionArg1((uptr)psxMemRead16, X86ARG1|MEM_X86TAG, 0); + _callFunctionArg1((uptr)iopMemRead16, X86ARG1|MEM_X86TAG, 0); if (_Rt_) { MOVZX32R16toR(EAX, EAX); MOV32RtoM((uptr)&psxRegs.GPR.r[_Rt_], EAX); @@ -975,16 +975,13 @@ static void rpsxLW() MOV32MtoR(X86ARG1, (uptr)&psxRegs.GPR.r[_Rs_]); if (_Imm_) ADD32ItoR(X86ARG1, _Imm_); -#ifndef TLB_DEBUG_MEM TEST32ItoR(X86ARG1, 0x10000000); j8Ptr[0] = JZ8(0); -#endif - _callFunctionArg1((uptr)psxMemRead32, X86ARG1|MEM_X86TAG, 0); + _callFunctionArg1((uptr)iopMemRead32, X86ARG1|MEM_X86TAG, 0); if (_Rt_) { MOV32RtoM((uptr)&psxRegs.GPR.r[_Rt_], EAX); } -#ifndef TLB_DEBUG_MEM j8Ptr[1] = JMP8(0); x86SetJ8(j8Ptr[0]); @@ -996,7 +993,6 @@ static void rpsxLW() MOV32RtoM( (uptr)&psxRegs.GPR.r[_Rt_], X86ARG1); x86SetJ8(j8Ptr[1]); -#endif PSX_DEL_CONST(_Rt_); } @@ -1007,7 +1003,7 @@ static void rpsxSB() MOV32MtoR(X86ARG1, (uptr)&psxRegs.GPR.r[_Rs_]); if (_Imm_) ADD32ItoR(X86ARG1, _Imm_); - _callFunctionArg2((uptr)psxMemWrite8, X86ARG1|MEM_X86TAG, MEM_MEMORYTAG, 0, (uptr)&psxRegs.GPR.r[_Rt_]); + _callFunctionArg2((uptr)iopMemWrite8, X86ARG1|MEM_X86TAG, MEM_MEMORYTAG, 0, (uptr)&psxRegs.GPR.r[_Rt_]); } static void rpsxSH() @@ -1017,7 +1013,7 @@ static void rpsxSH() MOV32MtoR(X86ARG1, (uptr)&psxRegs.GPR.r[_Rs_]); if (_Imm_) ADD32ItoR(X86ARG1, _Imm_); - _callFunctionArg2((uptr)psxMemWrite16, X86ARG1|MEM_X86TAG, MEM_MEMORYTAG, 0, (uptr)&psxRegs.GPR.r[_Rt_]); + _callFunctionArg2((uptr)iopMemWrite16, X86ARG1|MEM_X86TAG, MEM_MEMORYTAG, 0, (uptr)&psxRegs.GPR.r[_Rt_]); } static void rpsxSW() @@ -1027,7 +1023,7 @@ static void rpsxSW() MOV32MtoR(X86ARG1, (uptr)&psxRegs.GPR.r[_Rs_]); if (_Imm_) ADD32ItoR(X86ARG1, _Imm_); - _callFunctionArg2((uptr)psxMemWrite32, X86ARG1|MEM_X86TAG, MEM_MEMORYTAG, 0, (uptr)&psxRegs.GPR.r[_Rt_]); + _callFunctionArg2((uptr)iopMemWrite32, X86ARG1|MEM_X86TAG, MEM_MEMORYTAG, 0, (uptr)&psxRegs.GPR.r[_Rt_]); } #endif // end load store @@ -1326,7 +1322,7 @@ void rpsxBEQ_process(int info, int process) x86Ptr = prevx86; s_do32 = 1; psxpc -= 4; - psxRegs.code = *(u32*)PSXM( psxpc - 4 ); + psxRegs.code = iopMemRead32( psxpc - 4 ); psxLoadBranchState(); rpsxSetBranchEQ(info, process); psxRecompileNextInstruction(1); @@ -1389,7 +1385,7 @@ void rpsxBNE_process(int info, int process) x86Ptr = prevx86; s_do32 = 1; psxpc -= 4; - psxRegs.code = *(u32*)PSXM( psxpc - 4 ); + psxRegs.code = iopMemRead32( psxpc - 4 ); psxLoadBranchState(); rpsxSetBranchEQ(info, process); psxRecompileNextInstruction(1); @@ -1442,7 +1438,7 @@ void rpsxBLTZ() else { x86Ptr = prevx86; psxpc -= 4; - psxRegs.code = *(u32*)PSXM( psxpc - 4 ); + psxRegs.code = iopMemRead32( psxpc - 4 ); psxLoadBranchState(); u32* pjmp32 = JL32(0); psxRecompileNextInstruction(1); @@ -1489,7 +1485,7 @@ void rpsxBGEZ() else { x86Ptr = prevx86; psxpc -= 4; - psxRegs.code = *(u32*)PSXM( psxpc - 4 ); + psxRegs.code = iopMemRead32( psxpc - 4 ); psxLoadBranchState(); u32* pjmp32 = JGE32(0); psxRecompileNextInstruction(1); @@ -1545,7 +1541,7 @@ void rpsxBLTZAL() else { x86Ptr = prevx86; psxpc -= 4; - psxRegs.code = *(u32*)PSXM( psxpc - 4 ); + psxRegs.code = iopMemRead32( psxpc - 4 ); psxLoadBranchState(); u32* pjmp32 = JL32(0); MOV32ItoM((uptr)&psxRegs.GPR.r[31], psxpc+4); @@ -1598,7 +1594,7 @@ void rpsxBGEZAL() else { x86Ptr = prevx86; psxpc -= 4; - psxRegs.code = *(u32*)PSXM( psxpc - 4 ); + psxRegs.code = iopMemRead32( psxpc - 4 ); psxLoadBranchState(); u32* pjmp32 = JGE32(0); MOV32ItoM((uptr)&psxRegs.GPR.r[31], psxpc+4); @@ -1649,7 +1645,7 @@ void rpsxBLEZ() else { x86Ptr = prevx86; psxpc -= 4; - psxRegs.code = *(u32*)PSXM( psxpc - 4 ); + psxRegs.code = iopMemRead32( psxpc - 4 ); psxLoadBranchState(); u32* pjmp32 = JLE32(0); psxRecompileNextInstruction(1); @@ -1697,7 +1693,7 @@ void rpsxBGTZ() else { x86Ptr = prevx86; psxpc -= 4; - psxRegs.code = *(u32*)PSXM( psxpc - 4 ); + psxRegs.code = iopMemRead32( psxpc - 4 ); psxLoadBranchState(); u32* pjmp32 = JG32(0); psxRecompileNextInstruction(1); @@ -1819,18 +1815,6 @@ void (*rpsxCP0[32])() = { rpsxNULL, rpsxNULL, rpsxNULL, rpsxNULL, rpsxNULL, rpsxNULL, rpsxNULL, rpsxNULL }; -// coissued insts -void (*rpsxBSC_co[64] )() = { - rpsxNULL, rpsxNULL, rpsxNULL, rpsxNULL, rpsxNULL, rpsxNULL, rpsxNULL, rpsxNULL, - rpsxNULL, rpsxNULL, rpsxNULL, rpsxNULL, rpsxNULL, rpsxNULL, rpsxNULL, rpsxNULL, - rpsxNULL, rpsxNULL, rpsxNULL, rpsxNULL, rpsxNULL, rpsxNULL, rpsxNULL, rpsxNULL, - rpsxNULL, rpsxNULL, rpsxNULL, rpsxNULL, rpsxNULL, rpsxNULL, rpsxNULL, rpsxNULL, - rpsxNULL, rpsxNULL, rpsxNULL, rpsxNULL, rpsxNULL, rpsxNULL, rpsxNULL, rpsxNULL, - rpsxNULL, rpsxNULL, rpsxNULL, rpsxNULL, rpsxNULL, rpsxNULL, rpsxNULL, rpsxNULL, - rpsxNULL, rpsxNULL, rpsxNULL, rpsxNULL, rpsxNULL, rpsxNULL, rpsxNULL, rpsxNULL, - rpsxNULL, rpsxNULL, rpsxNULL, rpsxNULL, rpsxNULL, rpsxNULL, rpsxNULL, rpsxNULL, -}; - //////////////////////////////////////////////// // Back-Prob Function Tables - Gathering Info // //////////////////////////////////////////////// diff --git a/pcsx2/x86/ix86-32/iR5900-32.cpp b/pcsx2/x86/ix86-32/iR5900-32.cpp index c99708a94f..65ad3635be 100644 --- a/pcsx2/x86/ix86-32/iR5900-32.cpp +++ b/pcsx2/x86/ix86-32/iR5900-32.cpp @@ -684,8 +684,8 @@ static __naked void Dispatcher() assert( g_EEDispatchTemp ); #endif + // Modify the prev block's jump address, and jump to the new block: __asm { - //and eax, 0x0fffffff shl eax, 4 pop ecx // x86Ptr to mod mov edx, eax @@ -718,7 +718,6 @@ static __naked void DispatcherClear() mov eax, s_pDispatchBlock add esp, 4 // ignore stack mov eax, dword ptr [eax] - //and eax, 0x0fffffff shl eax, 4 jmp eax } @@ -732,7 +731,6 @@ static __naked void DispatcherClear() pop ecx // old fnptr - //and eax, 0x0fffffff shl eax, 4 mov byte ptr [ecx], 0xe9 // jmp32 mov edx, eax @@ -764,7 +762,6 @@ static __naked void DispatcherReg() #endif __asm { - //and eax, 0x0fffffff shl eax, 4 jmp eax } @@ -774,7 +771,8 @@ __forceinline void recExecute() { // Optimization note : Compared pushad against manually pushing the regs one-by-one. // Manually pushing is faster, especially on Core2's and such. :) - do { + do + { g_EEFreezeRegs = true; __asm {