diff --git a/3rdparty/wxWidgets/src/common/string.cpp b/3rdparty/wxWidgets/src/common/string.cpp index 58d39955f..0a70bed06 100644 --- a/3rdparty/wxWidgets/src/common/string.cpp +++ b/3rdparty/wxWidgets/src/common/string.cpp @@ -1970,8 +1970,17 @@ int wxString::PrintfV(const wxChar* pszFormat, va_list argptr) } // we could have overshot - Shrink(); + // PCSX2: And we could have 4gb of ram and not really give a hoot if we overshoot + // the length of a temporary string by 0.5kb, which itself will likely be free'd a few + // instructions later. Also, this defeats the purpose of even using the 1kb "overshot" + // starting buffer size at the top of the function. Ideally if you are really concerned + // about memory, the 1024 should be a 512, and this should only shrink if the allocated + // length of the string is more than 128 bytes past the end of the actual string content. + // -- Jake Stine (air) + //if( capacity() - 128 >= length() ) // this line added by air, as proposed above. + // Shrink(); + return length(); } diff --git a/clean_msvc.cmd b/clean_msvc.cmd index 18876bdca..9bee5cab6 100644 --- a/clean_msvc.cmd +++ b/clean_msvc.cmd @@ -12,7 +12,7 @@ :: application debugging (however these files are by no means required by any software). del /s "%~dp0\*.ncb" -del /s "%~dp0\*.ilk" +del /s "%~dp0\bin\*.ilk" del /s "%~dp0\*.idb" del /s "%~dp0\*.bsc" del /s "%~dp0\*.sbr" diff --git a/common/build/Utilities/Utilities.cbp b/common/build/Utilities/Utilities.cbp index 960fa125a..78afe01da 100644 --- a/common/build/Utilities/Utilities.cbp +++ b/common/build/Utilities/Utilities.cbp @@ -58,7 +58,17 @@ - + + + + + + + + + + + diff --git a/common/build/x86emitter/x86emitter.cbp b/common/build/x86emitter/x86emitter.cbp index 5e4039a55..7ff25bc07 100644 --- a/common/build/x86emitter/x86emitter.cbp +++ b/common/build/x86emitter/x86emitter.cbp @@ -59,6 +59,7 @@ + @@ -67,6 +68,8 @@ + + diff --git a/common/include/Pcsx2Defs.h b/common/include/Pcsx2Defs.h index 5cd4e4686..818d1e3d4 100644 --- a/common/include/Pcsx2Defs.h +++ b/common/include/Pcsx2Defs.h @@ -189,7 +189,6 @@ # define PCSX2_ALIGNED16_EXTERN(x) extern __declspec(align(16)) x # define __naked __declspec(naked) -# define __unused /*unused*/ # define __noinline __declspec(noinline) # define __threadlocal __declspec(thread) @@ -244,7 +243,6 @@ This theoretically unoptimizes. Not having much luck so far. // happens *by design* like all the friggen time >_<) # define __fastcall __attribute__((fastcall)) -# define __unused __attribute__((unused)) # define _inline __inline__ __attribute__((unused)) # ifdef NDEBUG # define __forceinline __attribute__((always_inline,unused)) diff --git a/common/include/Utilities/Console.h b/common/include/Utilities/Console.h index 2d5386f32..f9d03e035 100644 --- a/common/include/Utilities/Console.h +++ b/common/include/Utilities/Console.h @@ -20,6 +20,8 @@ enum ConsoleColors { + Color_Current = -1, + Color_Black = 0, Color_Red, Color_Green, @@ -27,7 +29,7 @@ enum ConsoleColors Color_Blue, Color_Magenta, Color_Cyan, - Color_White + Color_White, }; // Use fastcall for the console; should be helpful in most cases diff --git a/common/include/Utilities/Threading.h b/common/include/Utilities/Threading.h index 07a7d5717..9c18e7f7f 100644 --- a/common/include/Utilities/Threading.h +++ b/common/include/Utilities/Threading.h @@ -73,6 +73,11 @@ namespace Threading // For use in spin/wait loops. extern void SpinWait(); + // Optional implementation to enable hires thread/process scheduler for the operating system. + // Needed by Windows, but might not be relevant to other platforms. + extern void EnableHiresScheduler(); + extern void DisableHiresScheduler(); + // sleeps the current thread for the given number of milliseconds. extern void Sleep( int ms ); @@ -314,7 +319,7 @@ namespace Threading // Section of methods for internal use only. void _DoSetThreadName( const wxString& name ); - void _DoSetThreadName( __unused const char* name ); + void _DoSetThreadName( const char* name ); void _internal_execute(); void _try_virtual_invoke( void (PersistentThread::*method)() ); void _ThreadCleanup(); diff --git a/common/include/x86emitter/implement/dwshift.h b/common/include/x86emitter/implement/dwshift.h index 427b7c551..1b582ba36 100644 --- a/common/include/x86emitter/implement/dwshift.h +++ b/common/include/x86emitter/implement/dwshift.h @@ -32,17 +32,17 @@ class DwordShiftImplAll public: // ---------- 32 Bit Interface ----------- - __forceinline void operator()( const xRegister32& to, const xRegister32& from, __unused const xRegisterCL& clreg ) const { xOpWrite0F( 0xa5 | m_shiftop, to, from ); } - __forceinline void operator()( void* dest, const xRegister32& from, __unused const xRegisterCL& clreg ) const { xOpWrite0F( 0xa5 | m_shiftop, from, dest ); } - __forceinline void operator()( const ModSibBase& dest, const xRegister32& from, __unused const xRegisterCL& clreg ) const { xOpWrite0F( 0xa5 | m_shiftop, from, dest ); } + __forceinline void operator()( const xRegister32& to, const xRegister32& from, const xRegisterCL& /* clreg */ ) const { xOpWrite0F( 0xa5 | m_shiftop, to, from ); } + __forceinline void operator()( void* dest, const xRegister32& from, const xRegisterCL& /* clreg */ ) const { xOpWrite0F( 0xa5 | m_shiftop, from, dest ); } + __forceinline void operator()( const ModSibBase& dest, const xRegister32& from, const xRegisterCL& /* clreg */ ) const { xOpWrite0F( 0xa5 | m_shiftop, from, dest ); } __forceinline void operator()( const xRegister32& to, const xRegister32& from, u8 shiftcnt ) const { if( shiftcnt != 0 ) xOpWrite0F( 0xa4 | m_shiftop, to, from ); } __forceinline void operator()( void* dest, const xRegister32& from, u8 shiftcnt ) const { if( shiftcnt != 0 ) xOpWrite0F( 0xa4 | m_shiftop, from, dest, shiftcnt ); } __forceinline void operator()( const ModSibBase& dest, const xRegister32& from, u8 shiftcnt ) const { if( shiftcnt != 0 ) xOpWrite0F( 0xa4 | m_shiftop, from, dest, shiftcnt ); } // ---------- 16 Bit Interface ----------- - __forceinline void operator()( const xRegister16& to, const xRegister16& from, __unused const xRegisterCL& clreg ) const { xOpWrite0F( 0x66, 0xa5 | m_shiftop, to, from ); } - __forceinline void operator()( void* dest, const xRegister16& from, __unused const xRegisterCL& clreg ) const { xOpWrite0F( 0x66, 0xa5 | m_shiftop, from, dest ); } - __forceinline void operator()( const ModSibBase& dest, const xRegister16& from, __unused const xRegisterCL& clreg ) const { xOpWrite0F( 0x66, 0xa5 | m_shiftop, from, dest ); } + __forceinline void operator()( const xRegister16& to, const xRegister16& from, const xRegisterCL& /* clreg */ ) const { xOpWrite0F( 0x66, 0xa5 | m_shiftop, to, from ); } + __forceinline void operator()( void* dest, const xRegister16& from, const xRegisterCL& /* clreg */ ) const { xOpWrite0F( 0x66, 0xa5 | m_shiftop, from, dest ); } + __forceinline void operator()( const ModSibBase& dest, const xRegister16& from, const xRegisterCL& /* clreg */ ) const { xOpWrite0F( 0x66, 0xa5 | m_shiftop, from, dest ); } __forceinline void operator()( const xRegister16& to, const xRegister16& from, u8 shiftcnt ) const { if( shiftcnt != 0 ) xOpWrite0F( 0x66, 0xa4 | m_shiftop, to, from ); } __forceinline void operator()( void* dest, const xRegister16& from, u8 shiftcnt ) const { if( shiftcnt != 0 ) xOpWrite0F( 0x66, 0xa4 | m_shiftop, from, dest, shiftcnt ); } __forceinline void operator()( const ModSibBase& dest, const xRegister16& from, u8 shiftcnt ) const { if( shiftcnt != 0 ) xOpWrite0F( 0x66, 0xa4 | m_shiftop, from, dest, shiftcnt ); } diff --git a/common/include/x86emitter/implement/group2.h b/common/include/x86emitter/implement/group2.h index 57506a232..b445bd2fb 100644 --- a/common/include/x86emitter/implement/group2.h +++ b/common/include/x86emitter/implement/group2.h @@ -39,14 +39,14 @@ template< G2Type InstType > class Group2ImplAll { public: - template< typename T > __forceinline void operator()( const xRegister& to, __unused const xRegisterCL& from ) const + template< typename T > __forceinline void operator()( const xRegister& to, const xRegisterCL& /* from */ ) const { prefix16(); xWrite8( Is8BitOp() ? 0xd2 : 0xd3 ); EmitSibMagic( InstType, to ); } - template< typename T > __noinline void operator()( const ModSibStrict& sibdest, __unused const xRegisterCL& from ) const + template< typename T > __noinline void operator()( const ModSibStrict& sibdest, const xRegisterCL& /* from */ ) const { prefix16(); xWrite8( Is8BitOp() ? 0xd2 : 0xd3 ); diff --git a/common/src/Utilities/Linux/LnxThreads.cpp b/common/src/Utilities/Linux/LnxThreads.cpp index 52a7af97f..4d6640f45 100644 --- a/common/src/Utilities/Linux/LnxThreads.cpp +++ b/common/src/Utilities/Linux/LnxThreads.cpp @@ -24,38 +24,44 @@ static bool isMultiCore = true; // assume more than one CPU (safer) -namespace Threading +// Note: Apparently this solution is Linux/Solaris only. +// FreeBSD/OsX need something far more complicated (apparently) +void Threading::CountLogicalCores( int LogicalCoresPerPhysicalCPU, int PhysicalCoresPerPhysicalCPU ) { - // Note: Apparently this solution is Linux/Solaris only. - // FreeBSD/OsX need something far more complicated (apparently) - void CountLogicalCores( int LogicalCoresPerPhysicalCPU, int PhysicalCoresPerPhysicalCPU ) + const uint numCPU = sysconf( _SC_NPROCESSORS_ONLN ); + if( numCPU > 0 ) { - const uint numCPU = sysconf( _SC_NPROCESSORS_ONLN ); - if( numCPU > 0 ) - { - isMultiCore = numCPU > 1; - x86caps.LogicalCores = numCPU; - x86caps.PhysicalCores = ( numCPU / LogicalCoresPerPhysicalCPU ) * PhysicalCoresPerPhysicalCPU; - } - else - { - // Indeterminate? - x86caps.LogicalCores = 1; - x86caps.PhysicalCores = 1; - } + isMultiCore = numCPU > 1; + x86caps.LogicalCores = numCPU; + x86caps.PhysicalCores = ( numCPU / LogicalCoresPerPhysicalCPU ) * PhysicalCoresPerPhysicalCPU; } - - __forceinline void Sleep( int ms ) + else { - usleep( 1000*ms ); - } - - // For use in spin/wait loops, Acts as a hint to Intel CPUs and should, in theory - // improve performance and reduce cpu power consumption. - __forceinline void SpinWait() - { - // If this doesn't compile you can just comment it out (it only serves as a - // performance hint and isn't required). - __asm__ ( "pause" ); + // Indeterminate? + x86caps.LogicalCores = 1; + x86caps.PhysicalCores = 1; } } + +__forceinline void Threading::Sleep( int ms ) +{ + usleep( 1000*ms ); +} + +// For use in spin/wait loops, Acts as a hint to Intel CPUs and should, in theory +// improve performance and reduce cpu power consumption. +__forceinline void Threading::SpinWait() +{ + // If this doesn't compile you can just comment it out (it only serves as a + // performance hint and isn't required). + __asm__ ( "pause" ); +} + +__forceinline void Threading::EnableHiresScheduler() +{ + // Don't know if linux has a customizable scheduler resolution like Windows (doubtful) +} + +__forceinline void Threading::DisableHiresScheduler() +{ +} diff --git a/common/src/Utilities/ThreadTools.cpp b/common/src/Utilities/ThreadTools.cpp index db4a9c246..8ace152ee 100644 --- a/common/src/Utilities/ThreadTools.cpp +++ b/common/src/Utilities/ThreadTools.cpp @@ -144,8 +144,6 @@ void Threading::PersistentThread::Start() if( pthread_create( &m_thread, NULL, _internal_callback, this ) != 0 ) throw Exception::ThreadCreationError(); - - m_detached = false; } // Returns: TRUE if the detachment was performed, or FALSE if the thread was @@ -384,7 +382,8 @@ wxString Threading::PersistentThread::GetName() const // private member, and provide a new Task executor by a different name). void Threading::PersistentThread::OnStartInThread() { - m_running = true; + m_running = true; + m_detached = false; } void Threading::PersistentThread::_internal_execute() @@ -426,7 +425,7 @@ void Threading::PersistentThread::_DoSetThreadName( const wxString& name ) _DoSetThreadName( name.ToUTF8() ); } -void Threading::PersistentThread::_DoSetThreadName( __unused const char* name ) +void Threading::PersistentThread::_DoSetThreadName( const char* name ) { pxAssertMsg( IsSelf(), "Thread affinity error." ); // only allowed from our own thread, thanks. @@ -435,7 +434,7 @@ void Threading::PersistentThread::_DoSetThreadName( __unused const char* name ) #if defined(_WINDOWS_) && defined (_MSC_VER) // This code sample was borrowed form some obscure MSDN article. - // In a rare bout of sanity, it's an actual Micrsoft-published hack + // In a rare bout of sanity, it's an actual Microsoft-published hack // that actually works! static const int MS_VC_EXCEPTION = 0x406D1388; @@ -443,10 +442,10 @@ void Threading::PersistentThread::_DoSetThreadName( __unused const char* name ) #pragma pack(push,8) struct THREADNAME_INFO { - DWORD dwType; // Must be 0x1000. - LPCSTR szName; // Pointer to name (in user addr space). - DWORD dwThreadID; // Thread ID (-1=caller thread). - DWORD dwFlags; // Reserved for future use, must be zero. + DWORD dwType; // Must be 0x1000. + LPCSTR szName; // Pointer to name (in user addr space). + DWORD dwThreadID; // Thread ID (-1=caller thread). + DWORD dwFlags; // Reserved for future use, must be zero. }; #pragma pack(pop) @@ -456,13 +455,9 @@ void Threading::PersistentThread::_DoSetThreadName( __unused const char* name ) info.dwThreadID = GetCurrentThreadId(); info.dwFlags = 0; - __try - { + __try { RaiseException( MS_VC_EXCEPTION, 0, sizeof(info)/sizeof(ULONG_PTR), (ULONG_PTR*)&info ); - } - __except(EXCEPTION_EXECUTE_HANDLER) - { - } + } __except(EXCEPTION_EXECUTE_HANDLER) { } #endif } diff --git a/common/src/Utilities/Windows/WinThreads.cpp b/common/src/Utilities/Windows/WinThreads.cpp index e4961999c..8f8603f74 100644 --- a/common/src/Utilities/Windows/WinThreads.cpp +++ b/common/src/Utilities/Windows/WinThreads.cpp @@ -22,45 +22,58 @@ #include "implement.h" // win32 pthreads implementations. #endif -namespace Threading +void Threading::CountLogicalCores( int LogicalCoresPerPhysicalCPU, int PhysicalCoresPerPhysicalCPU ) { - void CountLogicalCores( int LogicalCoresPerPhysicalCPU, int PhysicalCoresPerPhysicalCPU ) + DWORD vProcessCPUs; + DWORD vSystemCPUs; + + x86caps.LogicalCores = 1; + + if( !GetProcessAffinityMask (GetCurrentProcess (), + &vProcessCPUs, &vSystemCPUs) ) return; + + int CPUs = 0; + DWORD bit; + + for (bit = 1; bit != 0; bit <<= 1) { - DWORD vProcessCPUs; - DWORD vSystemCPUs; - - x86caps.LogicalCores = 1; - - if( !GetProcessAffinityMask (GetCurrentProcess (), - &vProcessCPUs, &vSystemCPUs) ) return; - - int CPUs = 0; - DWORD bit; - - for (bit = 1; bit != 0; bit <<= 1) - { - if (vSystemCPUs & bit) - CPUs++; - } - - x86caps.LogicalCores = CPUs; - if( LogicalCoresPerPhysicalCPU > CPUs) // for 1-socket HTT-disabled machines - LogicalCoresPerPhysicalCPU = CPUs; - - x86caps.PhysicalCores = ( CPUs / LogicalCoresPerPhysicalCPU ) * PhysicalCoresPerPhysicalCPU; - //ptw32_smp_system = ( x86caps.LogicalCores > 1 ) ? TRUE : FALSE; + if (vSystemCPUs & bit) + CPUs++; } - __forceinline void Sleep( int ms ) - { - ::Sleep( ms ); - } + x86caps.LogicalCores = CPUs; + if( LogicalCoresPerPhysicalCPU > CPUs) // for 1-socket HTT-disabled machines + LogicalCoresPerPhysicalCPU = CPUs; - // For use in spin/wait loops, Acts as a hint to Intel CPUs and should, in theory - // improve performance and reduce cpu power consumption. - __forceinline void SpinWait() - { - __asm { pause }; - } + x86caps.PhysicalCores = ( CPUs / LogicalCoresPerPhysicalCPU ) * PhysicalCoresPerPhysicalCPU; + //ptw32_smp_system = ( x86caps.LogicalCores > 1 ) ? TRUE : FALSE; +} + +__forceinline void Threading::Sleep( int ms ) +{ + ::Sleep( ms ); +} + +// For use in spin/wait loops, Acts as a hint to Intel CPUs and should, in theory +// improve performance and reduce cpu power consumption. +__forceinline void Threading::SpinWait() +{ + __asm pause; +} + +__forceinline void Threading::EnableHiresScheduler() +{ + // This improves accuracy of Sleep() by some amount, and only adds a negligable amount of + // overhead on modern CPUs. Typically desktops are already set pretty low, but laptops in + // particular may have a scheduler Period of 15 or 20ms to extend battery life. + + // (note: this same trick is used by most multimedia software and games) + + timeBeginPeriod( 1 ); +} + +__forceinline void Threading::DisableHiresScheduler() +{ + timeEndPeriod( 1 ); } diff --git a/pcsx2/CDVD/CDVD_internal.h b/pcsx2/CDVD/CDVD_internal.h index f77c4c6b0..207d4a25f 100644 --- a/pcsx2/CDVD/CDVD_internal.h +++ b/pcsx2/CDVD/CDVD_internal.h @@ -129,9 +129,9 @@ static const uint PSX_DVD_READSPEED = 1382400 + 256000; // normal is 1 Byte Time static const uint Cdvd_FullSeek_Cycles = (PSXCLK*100) / 1000; // average number of cycles per fullseek (100ms) static const uint Cdvd_FastSeek_Cycles = (PSXCLK*30) / 1000; // average number of cycles per fastseek (37ms) -static const __unused char *mg_zones[8] = {"Japan", "USA", "Europe", "Oceania", "Asia", "Russia", "China", "Mexico"}; +static const char *mg_zones[8] = {"Japan", "USA", "Europe", "Oceania", "Asia", "Russia", "China", "Mexico"}; -static const __unused char *nCmdName[0x100]= { +static const char *nCmdName[0x100]= { "CdSync", "CdNop", "CdStandby", @@ -168,7 +168,7 @@ enum nCmds N_CD_CHG_SPDL_CTRL = 0x0F, // CdChgSpdlCtrl }; -static const __unused char *sCmdName[0x100]= { +static const char *sCmdName[0x100]= { "", "sceCdGetDiscType", "sceCdReadSubQ", "subcommands",//sceCdGetMecaconVersion, read/write console id, read renewal date "", "sceCdTrayState", "sceCdTrayCtrl", "", "sceCdReadClock", "sceCdWriteClock", "sceCdReadNVM", "sceCdWriteNVM", @@ -232,4 +232,4 @@ static NVMLayout nvmlayouts[NVM_FORMAT_MAX] = {0x146, 0x270, 0x2B0, 0x200, 0x1C8, 0x1E0, 0x1B0, 0x180, 0x198}, // eeproms from bios v1.70 and up }; -#endif \ No newline at end of file +#endif diff --git a/pcsx2/CDVD/CDVDaccess.cpp b/pcsx2/CDVD/CDVDaccess.cpp index fc3756abf..e2e7bcd9e 100644 --- a/pcsx2/CDVD/CDVDaccess.cpp +++ b/pcsx2/CDVD/CDVDaccess.cpp @@ -497,7 +497,7 @@ s32 CALLBACK NODISCdummyS32() return 0; } -void CALLBACK NODISCnewDiskCB(__unused void (*callback)()) +void CALLBACK NODISCnewDiskCB(void (* /* callback */)()) { } diff --git a/pcsx2/CDVD/CDVDisoReader.cpp b/pcsx2/CDVD/CDVDisoReader.cpp index 6510015f9..beabdc1e1 100644 --- a/pcsx2/CDVD/CDVDisoReader.cpp +++ b/pcsx2/CDVD/CDVDisoReader.cpp @@ -396,7 +396,7 @@ s32 CALLBACK ISOdummyS32() return 0; } -void CALLBACK ISOnewDiskCB(__unused void(*callback)()) +void CALLBACK ISOnewDiskCB(void(* /* callback */)()) { } diff --git a/pcsx2/Counters.cpp b/pcsx2/Counters.cpp index 5d0db5fdb..c8042b2fc 100644 --- a/pcsx2/Counters.cpp +++ b/pcsx2/Counters.cpp @@ -322,12 +322,21 @@ static __forceinline void frameLimit() m_iStart = uExpectedEnd; - while( sDeltaTime < 0 ) - { - Timeslice(); - iEnd = GetCPUTicks(); - sDeltaTime = iEnd - uExpectedEnd; - } + // Shortcut for cases where no waiting is needed (they're running slow already, + // so don't bog 'em down with extra math...) + if( sDeltaTime >= 0 ) return; + + // If we're way ahead then we can afford to sleep the thread a bit. + // (note, sleep(1) thru sleep(2) tend to be the least accurate sleeps, and longer + // sleeps tend to be pretty reliable, so that's why the convoluted if/else below) + + s32 msec = (int)((sDeltaTime*-1000) / (s64)GetTickFrequency()); + if( msec > 4 ) Threading::Sleep( msec ); + else if( msec > 2 ) Threading::Sleep( 1 ); + + // Sleep is not picture-perfect accurate, but it's actually not necessary to + // maintain a "perfect" lock to uExpectedEnd anyway. if we're a little ahead + // starting this frame, it'll just sleep longer the next to make up for it. :) } static __forceinline void VSyncStart(u32 sCycle) diff --git a/pcsx2/Gif.cpp b/pcsx2/Gif.cpp index b6de30396..721a7c27a 100644 --- a/pcsx2/Gif.cpp +++ b/pcsx2/Gif.cpp @@ -30,15 +30,13 @@ using std::min; // A three-way toggle used to determine if the GIF is stalling (transferring) or done (finished). // Should be a gifstate_t rather then int, but I don't feel like possibly interfering with savestates right now. static int gifstate = GIF_STATE_READY; +static bool gifempty = false; -//static u64 s_gstag = 0; // used for querying the last tag - -// This should be a bool. Next time I feel like breaking the save state, it will be. --arcum42 static bool gspath3done = false; static u32 gscycles = 0, prevcycles = 0, mfifocycles = 0; static u32 gifqwc = 0; -bool gifmfifoirq = false; +static bool gifmfifoirq = false; static __forceinline void clearFIFOstuff(bool full) { @@ -60,8 +58,9 @@ __forceinline void gsInterrupt() return; } - if ((vif1.cmd & 0x7f) == 0x51) + if ((vif1.cmd & 0x7f) == 0x51) // DIRECTHL { + // Not waiting for the end of the Gif transfer. if (Path3progress != IMAGE_MODE) vif1Regs->stat.VGW = 0; } @@ -141,7 +140,7 @@ static __forceinline void GIFchain() static __forceinline bool checkTieBit(u32* &ptag) { - if (gif->chcr.TIE && (Tag::IRQ(ptag))) //Check TIE bit of CHCR and IRQ bit of tag + if (gif->chcr.TIE && (Tag::IRQ(ptag))) { GIF_LOG("dmaIrq Set"); gspath3done = true; @@ -151,28 +150,30 @@ static __forceinline bool checkTieBit(u32* &ptag) return false; } -static __forceinline bool ReadTag(u32* &ptag, u32 &id) +static __forceinline u32* ReadTag(u32 &id) { - ptag = (u32*)dmaGetAddr(gif->tadr); //Set memory pointer to TADR + u32* ptag = (u32*)dmaGetAddr(gif->tadr); //Set memory pointer to TADR + + if (!(Tag::Transfer("Gif", gif, ptag))) return NULL; - if (!(Tag::Transfer("Gif", gif, ptag))) return false; gif->madr = ptag[1]; //MADR = ADDR field - id = Tag::Id(ptag); //ID for DmaChain copied from bit 28 of the tag + id = Tag::Id(ptag); gscycles += 2; // Add 1 cycles from the QW read for the tag gspath3done = hwDmacSrcChainWithStack(gif, id); - return true; + return ptag; } -static __forceinline void ReadTag2(u32* &ptag) +static __forceinline u32* ReadTag2() { - ptag = (u32*)dmaGetAddr(gif->tadr); //Set memory pointer to TADR + u32* ptag = (u32*)dmaGetAddr(gif->tadr); //Set memory pointer to TADR Tag::UnsafeTransfer(gif, ptag); gif->madr = ptag[1]; gspath3done = hwDmacSrcChainWithStack(gif, Tag::Id(ptag)); + return ptag; } void GIFdma() @@ -209,6 +210,7 @@ void GIFdma() //Path2 gets priority in intermittent mode if ((gifRegs->stat.P1Q || (vif1.cmd & 0x7f) == 0x50) && gifRegs->mode.IMT && (Path3progress == IMAGE_MODE)) { + // We are in image mode doing DIRECTHL, Path 1 is in queue, and in intermittant mode. GIF_LOG("Waiting VU %x, PATH2 %x, GIFMODE %x Progress %x", gifRegs->stat.P1Q, (vif1.cmd & 0x7f), gifRegs->mode._u32, Path3progress); CPU_INT(2, 16); return; @@ -220,7 +222,8 @@ void GIFdma() { if ((gif->chcr.MOD == CHAIN_MODE) && gif->chcr.STR) { - if (!ReadTag(ptag, id)) return; + ptag = ReadTag(id); + if (ptag == NULL) return; GIF_LOG("PTH3 MASK gifdmaChain %8.8x_%8.8x size=%d, id=%d, addr=%lx", ptag[1], ptag[0], gif->qwc, id, gif->madr); //Check TIE bit of CHCR and IRQ bit of tag @@ -257,7 +260,8 @@ void GIFdma() if ((gif->chcr.MOD == CHAIN_MODE) && (!gspath3done)) // Chain Mode { - if (!ReadTag(ptag, id)) return; + ptag = ReadTag(id); + if (ptag == NULL) return; GIF_LOG("gifdmaChain %8.8x_%8.8x size=%d, id=%d, addr=%lx", ptag[1], ptag[0], gif->qwc, id, gif->madr); if (dmacRegs->ctrl.STD == STD_GIF) @@ -312,7 +316,7 @@ void dmaGIF() gspath3done = false; // For some reason this doesn't clear? So when the system starts the thread, we will clear it :) gifRegs->stat.P3Q = 1; - gifRegs->stat.FQC |= 0x10;// FQC=31, hack ;) ( 31? 16! arcum42) [used to be 0xE00; // OPH=1 | APATH=3] + gifRegs->stat.FQC |= 0x10; // hack ;) clearFIFOstuff(true); @@ -325,9 +329,7 @@ void dmaGIF() if ((gif->qwc == 0) && (gif->chcr.MOD != NORMAL_MODE)) { - u32 *ptag; - - ReadTag2(ptag); + u32* ptag = ReadTag2(); GIF_LOG("gifdmaChain %8.8x_%8.8x size=%d, id=%d, addr=%lx", ptag[1], ptag[0], gif->qwc, (ptag[0] >> 28), gif->madr); checkTieBit(ptag); @@ -401,10 +403,12 @@ static __forceinline int mfifoGIFchain() } else { - int mfifoqwc = gif->qwc; + int mfifoqwc; + u32 *pMem = (u32*)dmaGetAddr(gif->madr); if (pMem == NULL) return -1; - mfifoqwc = WRITERING_DMA(pMem, mfifoqwc); + + mfifoqwc = WRITERING_DMA(pMem, gif->qwc); mfifocycles += (mfifoqwc) * 2; /* guessing */ } @@ -420,7 +424,6 @@ void mfifoGIFtransfer(int qwc) { u32 *ptag; int id; - u32 temp = 0; mfifocycles = 0; gifmfifoirq = false; @@ -428,8 +431,11 @@ void mfifoGIFtransfer(int qwc) if(qwc > 0 ) { gifqwc += qwc; - if (gifstate != GIF_STATE_EMPTY) return; + + if (!(gifstate & GIF_STATE_EMPTY)) return; + // if (gifempty == false) return; gifstate &= ~GIF_STATE_EMPTY; + gifempty = false; } GIF_LOG("mfifoGIFtransfer %x madr %x, tadr %x", gif->chcr._u32, gif->madr, gif->tadr); @@ -440,13 +446,14 @@ void mfifoGIFtransfer(int qwc) { //if( gifqwc > 1 ) DevCon.WriteLn("gif mfifo tadr==madr but qwc = %d", gifqwc); hwDmacIrq(DMAC_MFIFO_EMPTY); - gifstate |= GIF_STATE_EMPTY; + gifstate |= GIF_STATE_EMPTY; + gifempty = true; return; } gif->tadr = qwctag(gif->tadr); + ptag = (u32*)dmaGetAddr(gif->tadr); - Tag::UnsafeTransfer(gif, ptag); gif->madr = ptag[1]; @@ -472,11 +479,13 @@ void mfifoGIFtransfer(int qwc) break; case TAG_NEXT: // Next - Transfer QWC following tag. TADR = ADDR - temp = gif->madr; //Temporarily Store ADDR + { + u32 temp = gif->madr; //Temporarily Store ADDR gif->madr = qwctag(gif->tadr + 16); //Set MADR to QW following the tag gif->tadr = temp; //Copy temporarily stored ADDR to Tag gifstate = GIF_STATE_READY; break; + } case TAG_REF: // Ref - Transfer QWC from ADDR field case TAG_REFS: // Refs - Transfer QWC from ADDR field (Stall Control) @@ -507,7 +516,7 @@ void mfifoGIFtransfer(int qwc) } FreezeRegs(0); - if ((gif->qwc == 0) && (gifstate == GIF_STATE_DONE)) gifstate = GIF_STATE_STALL; + if ((gif->qwc == 0) && (gifstate & GIF_STATE_DONE)) gifstate = GIF_STATE_STALL; CPU_INT(11,mfifocycles); SPR_LOG("mfifoGIFtransfer end %x madr %x, tadr %x", gif->chcr._u32, gif->madr, gif->tadr); @@ -515,6 +524,7 @@ void mfifoGIFtransfer(int qwc) void gifMFIFOInterrupt() { + Console.WriteLn("gifMFIFOInterrupt"); mfifocycles = 0; if (Path3progress == STOPPED_MODE) @@ -543,13 +553,15 @@ void gifMFIFOInterrupt() return; } - if (gifstate != GIF_STATE_STALL) + if (!(gifstate & GIF_STATE_STALL)) { if (gifqwc <= 0) { //Console.WriteLn("Empty"); hwDmacIrq(DMAC_MFIFO_EMPTY); gifstate |= GIF_STATE_EMPTY; + gifempty = true; + gifRegs->stat.IMT = 0; return; } @@ -558,7 +570,7 @@ void gifMFIFOInterrupt() } #ifdef PCSX2_DEVBUILD - if (gifstate == GIF_STATE_READY || gif->qwc > 0) + if ((gifstate & GIF_STATE_READY) || (gif->qwc > 0)) { Console.Error("gifMFIFO Panic > Shouldn't go here!"); return; @@ -587,6 +599,6 @@ void SaveStateBase::gifFreeze() Freeze( gifqwc ); Freeze( gspath3done ); Freeze( gscycles ); - + //Freeze(gifempty); // Note: mfifocycles is not a persistent var, so no need to save it here. } diff --git a/pcsx2/Gif.h b/pcsx2/Gif.h index aa6e47d11..3c7cfda38 100644 --- a/pcsx2/Gif.h +++ b/pcsx2/Gif.h @@ -45,9 +45,9 @@ enum gif_stat_flags GIF_STAT_P2Q = (1<<7), // PATH2 request Queued GIF_STAT_P1Q = (1<<8), // PATH1 request Queued GIF_STAT_OPH = (1<<9), // Output Path (Outputting Data) - GIF_STAT_APATH1 = (1<<10), // Data Transfer Path 1 (In progress) - GIF_STAT_APATH2 = (2<<10), // Data Transfer Path 2 (In progress) - GIF_STAT_APATH3 = (3<<10), // Data Transfer Path 3 (In progress) (Mask too) + GIF_STAT_APATH1 = (1<<10), // Data Transfer Path 1 (In progress) + GIF_STAT_APATH2 = (2<<10), // Data Transfer Path 2 (In progress) + GIF_STAT_APATH3 = (3<<10), // Data Transfer Path 3 (In progress) (Mask too) GIF_STAT_DIR = (1<<12), // Transfer Direction GIF_STAT_FQC = (31<<24) // QWC in GIF-FIFO }; @@ -239,10 +239,10 @@ struct GIFregisters extern Path3Modes Path3progress; extern void gsInterrupt(); -int _GIFchain(); -void GIFdma(); -void dmaGIF(); -void mfifoGIFtransfer(int qwc); -void gifMFIFOInterrupt(); +extern int _GIFchain(); +extern void GIFdma(); +extern void dmaGIF(); +extern void mfifoGIFtransfer(int qwc); +extern void gifMFIFOInterrupt(); #endif diff --git a/pcsx2/IopHw.h b/pcsx2/IopHw.h index 784e3d0e3..ef95fde6e 100644 --- a/pcsx2/IopHw.h +++ b/pcsx2/IopHw.h @@ -134,10 +134,21 @@ enum DMAChcrAddresses enum DMATadrAddresses { + HWx_DMA0_TADR = 0x1f80108c, + HWx_DMA1_TADR = 0x1f80109c, HWx_DMA2_TADR = 0x1f8010ac, + HWx_DMA3_TADR = 0x1f8010bc, HWx_DMA4_TADR = 0x1f8010cc, - HWx_DMA9_TADR = 0x1f80152c + HWx_DMA5_TADR = 0x1f8010dc, + HWx_DMA6_TADR = 0x1f8010ec, + HWx_DMA7_TADR = 0x1f80150c, + HWx_DMA8_TADR = 0x1f80151c, + HWx_DMA9_TADR = 0x1f80152c, + HWx_DMA10_TADR = 0x1f80153c, + HWx_DMA11_TADR = 0x1f80154c, + HWx_DMA12_TADR = 0x1f80155c }; + /* Registers for the IOP Counters */ enum IOPCountRegs { diff --git a/pcsx2/Linux/pcsx2.cbp b/pcsx2/Linux/pcsx2.cbp index 1888e8b58..9c461ca7b 100644 --- a/pcsx2/Linux/pcsx2.cbp +++ b/pcsx2/Linux/pcsx2.cbp @@ -16,6 +16,7 @@