diff --git a/bin/GameIndex.dbf b/bin/GameIndex.dbf index f2ee1475c1..4cc2097de7 100644 --- a/bin/GameIndex.dbf +++ b/bin/GameIndex.dbf @@ -39013,12 +39013,12 @@ Compat = 5 Serial = SLPM-66676 Name = Kingdom Hearts Re: Chain of Memories Region = NTSC-J -Compat = 4 +Compat = 5 --------------------------------------------- Serial = SLUS-21799 Name = Kingdom Hearts Re: Chain of Memories Region = NTSC-U -Compat = 4 +Compat = 5 --------------------------------------------- Serial = SLUS-21820 Name = Legend Of Spyro - Dawn Of The Dragon diff --git a/common/include/Pcsx2Types.h b/common/include/Pcsx2Types.h index c30744d1c4..11c316ac51 100644 --- a/common/include/Pcsx2Types.h +++ b/common/include/Pcsx2Types.h @@ -16,16 +16,23 @@ #ifndef __PCSX2TYPES_H__ #define __PCSX2TYPES_H__ -/* - * Based on PS2E Definitions by - linuzappz@hotmail.com, - * shadowpcsx2@yahoo.gr, - * and florinsasu@hotmail.com - */ +// -------------------------------------------------------------------------------------- +// Forward declarations +// -------------------------------------------------------------------------------------- +// Forward declarations for wxWidgets-supporting features. +// If you aren't linking against wxWidgets libraries, then functions that +// depend on these types will not be usable (they will yield linker errors). + +#ifdef __cplusplus + class wxString; + class FastFormatAscii; + class FastFormatUnicode; +#endif -////////////////////////////////////////////////////////////////////////////////////////// -// Basic Atomic Types +// -------------------------------------------------------------------------------------- +// Basic Atomic Types +// -------------------------------------------------------------------------------------- #if defined(_MSC_VER) @@ -111,28 +118,41 @@ typedef s32 sptr; // performing explicit conversion from 64 and 32 bit values are provided instead. // #ifdef __cplusplus -struct u128 +union u128 { - u64 lo; - u64 hi; + struct + { + u64 lo; + u64 hi; + }; - // Explicit conversion from u64 + u64 _u64[2]; + u32 _u32[4]; + u16 _u16[8]; + u8 _u8[16]; + + // Explicit conversion from u64. Zero-extends the source through 128 bits. static u128 From64( u64 src ) { - u128 retval = { src, 0 }; + u128 retval; + retval.lo = src; + retval.hi = 0; return retval; } - // Explicit conversion from u32 + // Explicit conversion from u32. Zero-extends the source through 128 bits. static u128 From32( u32 src ) { - u128 retval = { src, 0 }; + u128 retval; + retval._u32[0] = src; + retval._u32[1] = 0; + retval.hi = 0; return retval; } - operator u32() const { return (u32)lo; } - operator u16() const { return (u16)lo; } - operator u8() const { return (u8)lo; } + operator u32() const { return _u32[0]; } + operator u16() const { return _u16[0]; } + operator u8() const { return _u8[0]; } bool operator==( const u128& right ) const { @@ -143,6 +163,17 @@ struct u128 { return (lo != right.lo) && (hi != right.hi); } + + // In order for the following ToString() and WriteTo methods to be available, you must + // be linking to both wxWidgets and the pxWidgets extension library. If you are not + // using them, then you will need to provide your own implementations of these methods. + wxString ToString() const; + wxString ToString64() const; + wxString ToString8() const; + + void WriteTo( FastFormatAscii& dest ) const; + void WriteTo8( FastFormatAscii& dest ) const; + void WriteTo64( FastFormatAscii& dest ) const; }; struct s128 @@ -183,13 +214,21 @@ struct s128 typedef union _u128_t { - u64 lo; - u64 hi; + struct + { + u64 lo; + u64 hi; + }; + + u64 _u64[2]; + u32 _u32[4]; + u16 _u16[8]; + u8 _u8[16]; } u128; typedef union _s128_t { - s64 lo; + u64 lo; s64 hi; } s128; diff --git a/common/include/Utilities/StringHelpers.h b/common/include/Utilities/StringHelpers.h index 453b8ffb86..00ca3be112 100644 --- a/common/include/Utilities/StringHelpers.h +++ b/common/include/Utilities/StringHelpers.h @@ -127,11 +127,13 @@ public: FastFormatAscii& Write( const char* fmt, ... ); FastFormatAscii& WriteV( const char* fmt, va_list argptr ); - const char* GetResult() const; - operator const char*() const; + bool IsEmpty() const; + + const char* c_str() const { return m_dest->GetPtr(); } + operator const char*() const { return m_dest->GetPtr(); } const wxString GetString() const; - operator wxString() const; + //operator wxString() const; }; class FastFormatUnicode @@ -149,18 +151,11 @@ public: FastFormatUnicode& WriteV( const char* fmt, va_list argptr ); FastFormatUnicode& WriteV( const wxChar* fmt, va_list argptr ); - const wxChar* GetResult() const; - const wxString GetString() const; + bool IsEmpty() const; - operator const wxChar*() const - { - return (const wxChar*)m_dest->GetPtr(); - } - - operator wxString() const - { - return (const wxChar*)m_dest->GetPtr(); - } + const wxChar* c_str() const { return (const wxChar*)m_dest->GetPtr(); } + operator const wxChar*() const { return (const wxChar*)m_dest->GetPtr(); } + operator wxString() const { return (const wxChar*)m_dest->GetPtr(); } }; extern bool pxParseAssignmentString( const wxString& src, wxString& ldest, wxString& rdest ); diff --git a/common/src/Utilities/AlignedMalloc.cpp b/common/src/Utilities/AlignedMalloc.cpp index 4f8264018a..c895c94972 100644 --- a/common/src/Utilities/AlignedMalloc.cpp +++ b/common/src/Utilities/AlignedMalloc.cpp @@ -37,7 +37,7 @@ void* __fastcall pcsx2_aligned_malloc(size_t size, size_t align) uptr aligned = (pasthead + align-1) & ~(align-1); AlignedMallocHeader* header = (AlignedMallocHeader*)(aligned-headsize); - jASSUME( (uptr)header >= (uptr)p ); + pxAssume( (uptr)header >= (uptr)p ); header->baseptr = p; header->size = size; diff --git a/common/src/Utilities/Console.cpp b/common/src/Utilities/Console.cpp index 11c3424b4d..bc75de447b 100644 --- a/common/src/Utilities/Console.cpp +++ b/common/src/Utilities/Console.cpp @@ -298,7 +298,7 @@ const IConsoleWriter ConsoleWriter_wxError = }; // ===================================================================================================== -// IConsoleWriter Implementations +// IConsoleWriter (implementations) // ===================================================================================================== // (all non-virtual members that do common work and then pass the result through DoWrite // or DoWriteLn) @@ -569,14 +569,14 @@ const NullConsoleWriter NullCon = {}; bool ConsoleLogSource::WriteV( ConsoleColors color, const char *fmt, va_list list ) const { ConsoleColorScope cs(color); - DoWrite( pxsFmtV(fmt,list).GetResult() ); + DoWrite( pxsFmtV(fmt,list).c_str() ); return false; } bool ConsoleLogSource::WriteV( ConsoleColors color, const wxChar *fmt, va_list list ) const { ConsoleColorScope cs(color); - DoWrite( pxsFmtV(fmt,list) ); + DoWrite( pxsFmtV(fmt,list).c_str() ); return false; } diff --git a/common/src/Utilities/Exceptions.cpp b/common/src/Utilities/Exceptions.cpp index 5c33bb3c7a..11b4ee1783 100644 --- a/common/src/Utilities/Exceptions.cpp +++ b/common/src/Utilities/Exceptions.cpp @@ -49,21 +49,20 @@ pxDoAssertFnType* pxDoAssert = pxAssertImpl_LogIt; // response times from the Output window... wxString DiagnosticOrigin::ToString( const wxChar* msg ) const { - wxString message; - message.reserve( 2048 ); + FastFormatUnicode message; - message.Printf( L"%s(%d) : assertion failed:\n", srcfile, line ); + message.Write( L"%s(%d) : assertion failed:\n", srcfile, line ); if( function != NULL ) - message += L" Function: " + fromUTF8(function) + L"\n"; + message.Write( " Function: %s\n", function ); - message += L" Thread: " + Threading::pxGetCurrentThreadName() + L"\n"; + message.Write(L" Thread: %s\n", Threading::pxGetCurrentThreadName().c_str() ); if( condition != NULL ) - message += L" Condition: " + wxString(condition) + L"\n"; + message.Write(L" Condition: %s\n", condition); if( msg != NULL ) - message += L" Message: " + wxString(msg) + L"\n"; + message.Write(L" Message: %s\n", msg); return message; } diff --git a/common/src/Utilities/FastFormatString.cpp b/common/src/Utilities/FastFormatString.cpp index 053711c629..7dad16217d 100644 --- a/common/src/Utilities/FastFormatString.cpp +++ b/common/src/Utilities/FastFormatString.cpp @@ -47,7 +47,7 @@ class FastFormatBuffers protected: typedef SafeAlignedArray BufferType; - static const uint BufferCount = 3; + static const uint BufferCount = 4; BufferType m_buffers[BufferCount]; uint m_curslot; @@ -64,7 +64,7 @@ public: m_buffers[i].Name = wxsFormat(L"%s Formatting Buffer (slot%d)", (sizeof(CharType)==1) ? L"Ascii" : L"Unicode", i); m_buffers[i].MakeRoomFor(1024); - m_buffers[i].ChunkSize = 4096; + m_buffers[i].ChunkSize = 2048; } m_curslot = 0; @@ -77,7 +77,7 @@ public: bool HasFreeBuffer() const { - return m_curslot < BufferCount; + return m_curslot < BufferCount-1; } BufferType& GrabBuffer() @@ -176,7 +176,7 @@ static __ri void format_that_unicode_mess( SafeArray& buffer, uint writepo while( true ) { int size = buffer.GetLength() / sizeof(wxChar); - int len = wxVsnprintf((wxChar*)buffer.GetPtr(writepos), size-writepos, fmt, argptr); + int len = wxVsnprintf((wxChar*)buffer.GetPtr(writepos*2), size-writepos, fmt, argptr); // some implementations of vsnprintf() don't NUL terminate @@ -267,12 +267,11 @@ FastFormatUnicode& FastFormatUnicode::Write( const wxChar* fmt, ... ) return *this; } -const wxChar* FastFormatUnicode::GetResult() const +bool FastFormatUnicode::IsEmpty() const { - return (wxChar*)m_dest->GetPtr(); + return ((wxChar&)(*m_dest)[0]) == 0; } - // -------------------------------------------------------------------------------------- // FastFormatAscii (implementations) // -------------------------------------------------------------------------------------- @@ -295,10 +294,10 @@ const wxString FastFormatAscii::GetString() const return fromAscii(m_dest->GetPtr()); } -FastFormatAscii::operator wxString() const +/*FastFormatAscii::operator wxString() const { return fromAscii(m_dest->GetPtr()); -} +}*/ FastFormatAscii& FastFormatAscii::WriteV( const char* fmt, va_list argptr ) { @@ -315,13 +314,8 @@ FastFormatAscii& FastFormatAscii::Write( const char* fmt, ... ) return *this; } -const char* FastFormatAscii::GetResult() const -{ - return m_dest->GetPtr(); -} -FastFormatAscii::operator const char*() const +bool FastFormatAscii::IsEmpty() const { - return m_dest->GetPtr(); + return (*m_dest)[0] == 0; } - diff --git a/common/src/Utilities/Mutex.cpp b/common/src/Utilities/Mutex.cpp index ac70bc5809..f680633e4d 100644 --- a/common/src/Utilities/Mutex.cpp +++ b/common/src/Utilities/Mutex.cpp @@ -253,11 +253,13 @@ Threading::ScopedLock::~ScopedLock() throw() Threading::ScopedLock::ScopedLock( const Mutex* locker ) { + m_IsLocked = false; AssignAndLock( locker ); } Threading::ScopedLock::ScopedLock( const Mutex& locker ) { + m_IsLocked = false; AssignAndLock( locker ); } @@ -268,6 +270,8 @@ void Threading::ScopedLock::AssignAndLock( const Mutex& locker ) void Threading::ScopedLock::AssignAndLock( const Mutex* locker ) { + pxAssume(!m_IsLocked); // if we're already locked, changing the lock is bad mojo. + m_lock = const_cast(locker); if( !m_lock ) return; diff --git a/common/src/Utilities/StringHelpers.cpp b/common/src/Utilities/StringHelpers.cpp index f17026be04..1b4785fa8a 100644 --- a/common/src/Utilities/StringHelpers.cpp +++ b/common/src/Utilities/StringHelpers.cpp @@ -35,6 +35,42 @@ __fi wxString fromAscii( const char* src ) return wxString::FromAscii( src ); } +wxString u128::ToString() const +{ + return pxsFmt( L"0x%08X.%08X.%08X.%08X", _u32[0], _u32[1], _u32[2], _u32[3] ); +} + +wxString u128::ToString64() const +{ + return pxsFmt( L"0x%08X%08X.%08X%08X", _u32[0], _u32[1], _u32[2], _u32[3] ); +} + +wxString u128::ToString8() const +{ + FastFormatUnicode result; + result.Write( L"0x%02X.%02X", _u8[0], _u8[1] ); + for (uint i=2; i<16; i+=2) + result.Write( L".%02X.%02X", _u8[i], _u8[i+1] ); + return result; +} + +void u128::WriteTo( FastFormatAscii& dest ) const +{ + dest.Write( "0x%08X.%08X.%08X.%08X", _u32[0], _u32[1], _u32[2], _u32[3] ); +} + +void u128::WriteTo64( FastFormatAscii& dest ) const +{ + dest.Write( "0x%08X%08X.%08X%08X", _u32[0], _u32[1], _u32[2], _u32[3] ); +} + +void u128::WriteTo8( FastFormatAscii& dest ) const +{ + dest.Write( "0x%02X.%02X", _u8[0], _u8[1] ); + for (uint i=2; i<16; i+=2) + dest.Write( ".%02X.%02X", _u8[i], _u8[i+1] ); +} + // Splits a string into parts and adds the parts into the given SafeList. // This list is not cleared, so concatenating many splits into a single large list is // the 'default' behavior, unless you manually clear the SafeList prior to subsequent calls. diff --git a/debian-unstable-upstream/README.Debian b/debian-unstable-upstream/README.Debian index d5851bd5d8..b996d0de2f 100644 --- a/debian-unstable-upstream/README.Debian +++ b/debian-unstable-upstream/README.Debian @@ -1,19 +1,19 @@ pcsx2 for debian ========================= -* This version have some majors modification against default upstream +* This version has some major modifications against the default upstream version. -> documents are stored in $XDG_CONFIG_HOME instead of $HOME/pcsx2 - -> some features was removed to compile against libsound 1.3. Pcsx2 - needs the version 1.5 + -> some features were removed so it could compile against libsound 1.3. + Pcsx2 needs at least soundtouch 1.5. * This package is highly experimental. -* Documentation needs some loves. Feel free to help. +* Documentation needs some love. Feel free to help. * -fPIC option was removed for multiple reason. - Code only support x86 architecture. - - Upstream code use ebx register so it is not compliant with PIC. - - Impact too much performance. - - only plugins so no others package link against us. + - Upstream code uses the ebx register so it's not compliant with PIC. + - Impacts the performance too much. + - Only plugins. No package will link to them. -- Gregory Hainaut Sat, 24 Apr 2010 23:11:10 +0200 diff --git a/debian-unstable-upstream/control b/debian-unstable-upstream/control index 40d446e7b2..d265f62770 100644 --- a/debian-unstable-upstream/control +++ b/debian-unstable-upstream/control @@ -2,6 +2,7 @@ Source: pcsx2.snapshot Section: games Priority: optional Maintainer: Gregory Hainaut +# WARNING we need dpkg-dev 1.15.7 to support dpkg-buildflags but ubunutu 10.04 have only 1.15.5.6... Build-Depends: debhelper (>= 7.0.50), dpkg-dev (>= 1.15.5.6), cmake (>=2.8), gcc-multilib [amd64], g++-multilib [amd64], zlib1g-dev (>= 1:1.2.3.3) | lib32z1-dev (>= 1.2.3.3) [amd64], @@ -28,22 +29,23 @@ Build-Depends: debhelper (>= 7.0.50), dpkg-dev (>= 1.15.5.6), cmake (>=2.8), # nvidia-cg-toolkit (>= 2.1.0017.deb1) | nvidia-cg-toolkit (>= 2.1.0017.deb1+nmu2) [amd64], nvidia-cg-toolkit-pcsx2 | nvidia-cg-toolkit (>= 2.1), ia32-nvidia-cg-toolkit-pcsx2 [amd64], ia32-libs (>= 20090808+nmu7) [amd64], ia32-libs-gtk (= 20100503+local1) [amd64] -Standards-Version: 3.9.0 +Standards-Version: 3.9.1 Homepage: http://pcsx2.net/ Package: pcsx2-unstable # Warning amd64 need additional ia32libs Architecture: i386 amd64 -Depends: ${shlibs:Depends}, ${misc:Depends}, pcsx2-data-unstable (>= ${binary:Version}), pcsx2-plugins-unstable (>= ${binary:Version}) -Conflicts: pcsx2 +Depends: ${shlibs:Depends}, ${misc:Depends}, + pcsx2-data-unstable (>= ${binary:Version}), + pcsx2-plugins-unstable (>= ${binary:Version}) + Conflicts: pcsx2 Description: Playstation 2 emulator - PCSX2 is a PlayStation 2 emulator for Windows and - Linux, started by the same team that brought you PCSX - (a Sony PlayStation 1 emulator). + PCSX2 is a PlayStation 2 emulator for Windows and Linux, started by the same + team that brought you PCSX (a Sony PlayStation 1 emulator). . - WARNING: it requieres a CPU with sse2 instructions. If your - CPU does not support this instruction set, it does not have - enough horse power to run this emulator anyway. + WARNING: It requires a CPU with SSE2 instructions. If your CPU does not support + this instruction set, it does not have enough horse power to run this emulator + anyway. . This package includes the main binary file. @@ -54,34 +56,33 @@ Depends: ${misc:Depends} Recommends: pcsx2-unstable (>= ${binary:Version}), pcsx2-plugins-unstable (>= ${binary:Version}) Conflicts: pcsx2-data Description: data for pcsx2 - PCSX2 is a PlayStation 2 emulator for Windows and - Linux, started by the same team that brought you PCSX - (a Sony PlayStation 1 emulator). + PCSX2 is a PlayStation 2 emulator for Windows and Linux, started by the same + team that brought you PCSX (a Sony PlayStation 1 emulator). . - WARNING: it requieres a CPU with sse2 instructions. If your - CPU does not support this instruction set, it does not have - enough horse power to run this emulator anyway. + WARNING: It requires a CPU with SSE2 instructions. If your CPU does not support + this instruction set, it does not have enough horse power to run this emulator + anyway. . This package includes data files. Package: pcsx2-plugins-unstable # Warning amd64 need additional ia32libs Architecture: i386 amd64 -Depends: ${shlibs:Depends}, ${misc:Depends} -Recommends: pcsx2-unstable (>= ${binary:Version}), pcsx2-data-unstable (>= ${binary:Version}), # manually add nvidia-cg-toolkit for zzogl. Do not why is not found by shlibs !!! +Depends: ${shlibs:Depends}, ${misc:Depends}, nvidia-cg-toolkit-pcsx2 | nvidia-cg-toolkit (>= 2.1), ia32-nvidia-cg-toolkit-pcsx2 [amd64] +Recommends: pcsx2-unstable (>= ${binary:Version}), + pcsx2-data-unstable (>= ${binary:Version}) Conflicts: pcsx2-plugins Description: Various plugins for pcsx2 - PCSX2 is a PlayStation 2 emulator for Windows and - Linux, started by the same team that brought you PCSX - (a Sony PlayStation 1 emulator). + PCSX2 is a PlayStation 2 emulator for Windows and Linux, started by the same + team that brought you PCSX (a Sony PlayStation 1 emulator). . - WARNING: it requieres a CPU with sse2 instructions. If your - CPU does not support this instruction set, it does not have - enough horse power to run this emulator anyway. + WARNING: It requires a CPU with SSE2 instructions. If your CPU does not support + this instruction set, it does not have enough horse power to run this emulator + anyway. . - This package includes the plugins of the emulator. + This package includes the plugins for PCSX2. Package: pcsx2-unstable-dbg Section: debug @@ -91,9 +92,12 @@ Architecture: i386 amd64 Depends: ${misc:Depends}, pcsx2-unstable (= ${binary:Version}) Conflicts: pcsx2-dbg Description: Debug symbols for pcsx2 - PCSX2 is a PlayStation 2 emulator for Windows and - Linux, started by the same team that brought you PCSX - (a Sony PlayStation 1 emulator). + PCSX2 is a PlayStation 2 emulator for Windows and Linux, started by the same + team that brought you PCSX (a Sony PlayStation 1 emulator). + . + WARNING: It requires a CPU with SSE2 instructions. If your CPU does not support + this instruction set, it does not have enough horse power to run this emulator + anyway. . This package contains the debug symbol of pcsx2. @@ -104,9 +108,12 @@ Priority: extra Architecture: i386 amd64 Depends: ${misc:Depends}, pcsx2-plugins-unstable (= ${binary:Version}) Conflicts: pcsx2-plugins-dbg -Description: Debug symbols for pcsx2-plugins - PCSX2 is a PlayStation 2 emulator for Windows and - Linux, started by the same team that brought you PCSX - (a Sony PlayStation 1 emulator). +Description: Debug symbols of the pcsx2-plugins + PCSX2 is a PlayStation 2 emulator for Windows and Linux, started by the same + team that brought you PCSX (a Sony PlayStation 1 emulator). . - This package contains the debug symbol of pcsx2 plugins. + WARNING: It requires a CPU with SSE2 instructions. If your CPU does not support + this instruction set, it does not have enough horse power to run this emulator + anyway. + . + This package contains the debug symbols of the pcsx2 plugins. diff --git a/debian-unstable-upstream/control_ppa b/debian-unstable-upstream/control_ppa index e820ff7a9a..109338502a 100644 --- a/debian-unstable-upstream/control_ppa +++ b/debian-unstable-upstream/control_ppa @@ -24,21 +24,22 @@ Build-Depends: debhelper (>= 7.0.50), dpkg-dev (>= 1.15.5.6), cmake (>=2.8), libgl1-mesa-dev, libglu1-mesa-dev, nvidia-cg-toolkit-pcsx2 -Standards-Version: 3.9.0 +Standards-Version: 3.9.1 Homepage: http://pcsx2.net/ Package: pcsx2-unstable Architecture: i386 -Depends: ${shlibs:Depends}, ${misc:Depends}, pcsx2-data-unstable (>= ${binary:Version}), pcsx2-plugins-unstable (>= ${binary:Version}) +Depends: ${shlibs:Depends}, ${misc:Depends}, + pcsx2-data-unstable (>= ${binary:Version}), + pcsx2-plugins-unstable (>= ${binary:Version}) Conflicts: pcsx2 Description: Playstation 2 emulator - PCSX2 is a PlayStation 2 emulator for Windows and - Linux, started by the same team that brought you PCSX - (a Sony PlayStation 1 emulator). + PCSX2 is a PlayStation 2 emulator for Windows and Linux, started by the same + team that brought you PCSX (a Sony PlayStation 1 emulator). . - WARNING: it requieres a CPU with sse2 instructions. If your - CPU does not support this instruction set, it does not have - enough horse power to run this emulator anyway. + WARNING: It requires a CPU with SSE2 instructions. If your CPU does not support + this instruction set, it does not have enough horse power to run this emulator + anyway. . This package includes the main binary file. @@ -49,33 +50,32 @@ Depends: ${misc:Depends} Recommends: pcsx2-unstable (>= ${binary:Version}), pcsx2-plugins-unstable (>= ${binary:Version}) Conflicts: pcsx2-data Description: data for pcsx2 - PCSX2 is a PlayStation 2 emulator for Windows and - Linux, started by the same team that brought you PCSX - (a Sony PlayStation 1 emulator). + PCSX2 is a PlayStation 2 emulator for Windows and Linux, started by the same + team that brought you PCSX (a Sony PlayStation 1 emulator). . - WARNING: it requieres a CPU with sse2 instructions. If your - CPU does not support this instruction set, it does not have - enough horse power to run this emulator anyway. + WARNING: It requires a CPU with SSE2 instructions. If your CPU does not support + this instruction set, it does not have enough horse power to run this emulator + anyway. . This package includes data files. Package: pcsx2-plugins-unstable Architecture: i386 -Depends: ${shlibs:Depends}, ${misc:Depends} -Recommends: pcsx2-unstable (>= ${binary:Version}), pcsx2-data-unstable (>= ${binary:Version}), # manually add nvidia-cg-toolkit for zzogl. Do not why is not found by shlibs !!! +Depends: ${shlibs:Depends}, ${misc:Depends}, nvidia-cg-toolkit-pcsx2 | nvidia-cg-toolkit (>= 2.1) +Recommends: pcsx2-unstable (>= ${binary:Version}), + pcsx2-data-unstable (>= ${binary:Version}) Conflicts: pcsx2-plugins Description: Various plugins for pcsx2 - PCSX2 is a PlayStation 2 emulator for Windows and - Linux, started by the same team that brought you PCSX - (a Sony PlayStation 1 emulator). + PCSX2 is a PlayStation 2 emulator for Windows and Linux, started by the same + team that brought you PCSX (a Sony PlayStation 1 emulator). . - WARNING: it requieres a CPU with sse2 instructions. If your - CPU does not support this instruction set, it does not have - enough horse power to run this emulator anyway. + WARNING: It requires a CPU with SSE2 instructions. If your CPU does not support + this instruction set, it does not have enough horse power to run this emulator + anyway. . - This package includes the plugins of the emulator. + This package includes the plugins for PCSX2. Package: pcsx2-unstable-dbg Section: debug @@ -84,9 +84,12 @@ Architecture: i386 Depends: ${misc:Depends}, pcsx2-unstable (= ${binary:Version}) Conflicts: pcsx2-dbg Description: Debug symbols for pcsx2 - PCSX2 is a PlayStation 2 emulator for Windows and - Linux, started by the same team that brought you PCSX - (a Sony PlayStation 1 emulator). + PCSX2 is a PlayStation 2 emulator for Windows and Linux, started by the same + team that brought you PCSX (a Sony PlayStation 1 emulator). + . + WARNING: It requires a CPU with SSE2 instructions. If your CPU does not support + this instruction set, it does not have enough horse power to run this emulator + anyway. . This package contains the debug symbol of pcsx2. @@ -96,9 +99,12 @@ Priority: extra Architecture: i386 Depends: ${misc:Depends}, pcsx2-plugins-unstable (= ${binary:Version}) Conflicts: pcsx2-plugins-dbg -Description: Debug symbols for pcsx2-plugins - PCSX2 is a PlayStation 2 emulator for Windows and - Linux, started by the same team that brought you PCSX - (a Sony PlayStation 1 emulator). +Description: Debug symbols of the pcsx2-plugins + PCSX2 is a PlayStation 2 emulator for Windows and Linux, started by the same + team that brought you PCSX (a Sony PlayStation 1 emulator). . - This package contains the debug symbol of pcsx2 plugins. + WARNING: It requires a CPU with SSE2 instructions. If your CPU does not support + this instruction set, it does not have enough horse power to run this emulator + anyway. + . + This package contains the debug symbols of the pcsx2 plugins. diff --git a/debian-unstable-upstream/copyright b/debian-unstable-upstream/copyright index 57d75fbf88..5d0e83d7de 100644 --- a/debian-unstable-upstream/copyright +++ b/debian-unstable-upstream/copyright @@ -155,6 +155,8 @@ License: BSD (3 clause) OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +Files: plugins/zzogl-pg/opengl/ZeroGSShaders/* plugins/zzogl-pg/opengl/zpipe* plugins/zzogl-pg/opengl/zerogsmath.h plugins/zzogl-pg/opengl/memcpy_amd.cpp +Copyright: Unknown The Debian packaging is: diff --git a/debian-unstable-upstream/create_pcsx2_tarball_from_svn_repository.sh b/debian-unstable-upstream/create_pcsx2_tarball_from_svn_repository.sh index 14ef3f2fbe..71977c9fd8 100755 --- a/debian-unstable-upstream/create_pcsx2_tarball_from_svn_repository.sh +++ b/debian-unstable-upstream/create_pcsx2_tarball_from_svn_repository.sh @@ -4,28 +4,34 @@ # it under the terms of the GNU Lesser General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. -# +# # This package is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Lesser General Public License for more details. -# +# # You should have received a copy of the GNU Lesser General Public License # along with this program. If not, see . ###################################################################### -# Global Parameter +# Global Parameters ###################################################################### # Svn parameter if [ -n "$1" ] ; then SVN_CO_VERSION=$1; else - echo "Please provide the subversion version as fisrt parameter" + echo "Please provide the subversion revision number as the first parameter" exit 1; fi -SVN_TRUNK="http://pcsx2.googlecode.com/svn/trunk" +if [ -n "$2" ] ; then + # Use branch argument + SVN_TRUNK="http://pcsx2.googlecode.com/svn/branches/$2" +else + # by default take the trunk + SVN_TRUNK="http://pcsx2.googlecode.com/svn/trunk" +fi # Debian name of package and tarball PKG_NAME="pcsx2.snapshot-${SVN_CO_VERSION}" @@ -38,7 +44,7 @@ NEW_DIR=${TMP_DIR}/$PKG_NAME ###################################################################### -# Basic function +# Basic functions ###################################################################### get_svn_dir() { @@ -58,8 +64,8 @@ get_svn_file() { for file in $* ; do if [ ! -e `basename ${file}` ] ; then - # Versionning information are not support for a single file - # so you can not use svn co + # Versioning information is not supported for a single file + # therefore you can't use svn co svn export --quiet ${SVN_TRUNK}/${file} -r $SVN_CO_VERSION; fi done @@ -69,8 +75,8 @@ get_svn_file() # Main script ###################################################################### -## Download the svn repository (only the usefull things) -echo "Download pcsx2 source rev ${SVN_CO_VERSION}" +## Download the svn repository (only the useful things) +echo "Downloading pcsx2 source revision ${SVN_CO_VERSION}" mkdir -p $ROOT_DIR; (cd $ROOT_DIR; get_svn_file CMakeLists.txt; @@ -78,7 +84,8 @@ mkdir -p $ROOT_DIR; get_svn_dir debian-unstable-upstream; echo "Done") -echo "Donwload Linux compatible plugins ${SVN_CO_VERSION}" +echo "Downloading Linux compatible plugins for revision ${SVN_CO_VERSION}" +# Note: Other plugins exist but they are not 100% copyright free. mkdir -p $ROOT_DIR/plugins (cd $ROOT_DIR/plugins; get_svn_file plugins/CMakeLists.txt; @@ -98,14 +105,14 @@ echo "Note: some plugins are more or less deprecated CDVDisoEFP, CDVDlinuz, Zero echo "Done") ## Installation -echo "Copy the subversion repository in a tmp directory" +echo "Copy the subversion repository to a temporary directory" # Copy the dir rm -fr $NEW_DIR cp -r $ROOT_DIR $NEW_DIR -echo "Remove .svn file" +echo "Remove .svn directories" find $NEW_DIR -name ".svn" -type d -exec rm -fr {} \; 2> /dev/null -echo "Remove old build system (script and autotools)" +echo "Remove old build system (scripts and autotools)" find $NEW_DIR -name "build.sh" -exec rm -f {} \; find $NEW_DIR -name "install-sh" -exec rm -f {} \; find $NEW_DIR -name "depcomp" -exec rm -f {} \; @@ -113,22 +120,25 @@ find $NEW_DIR -name "missing" -exec rm -f {} \; find $NEW_DIR -name "aclocal.m4" -exec rm -f {} \; find $NEW_DIR -name "configure.ac" -exec rm -f {} \; find $NEW_DIR -name "Makefile.am" -exec rm -f {} \; -echo "Remove 3rd party directory" +echo "Remove 3rd party directories" find $NEW_DIR -name "3rdparty" -exec rm -fr {} \; 2> /dev/null +# I really need to clean this mess one day +# echo "Remove plugins/zzogl-pg/opengl/ZeroGSShaders (some zlib source in the middle)" +# rm -fr $NEW_DIR/plugins/zzogl-pg/opengl/ZeroGSShaders echo "Remove windows file (useless & copyright issue)" -find $NEW_DIR -iname "windows" -exec rm -fr {} \; 2> /dev/null +find $NEW_DIR -iname "windows" -type d -exec rm -fr {} \; 2> /dev/null +find $NEW_DIR -name "Win32" -type d -exec rm -fr {} \; 2> /dev/null rm -fr "${NEW_DIR}/plugins/zzogl-pg/opengl/Win32" rm -fr "${NEW_DIR}/tools/GSDumpGUI" rm -fr "${NEW_DIR}/common/vsprops" -echo "Remove useless file (copyright issue)" +echo "Remove useless files (copyright issues)" rm -fr "${NEW_DIR}/plugins/zzogl-pg/opengl/ZeroGSShaders/zlib" rm -fr "${NEW_DIR}/common/src/Utilities/x86/MemcpyFast.cpp" -rm -fr "${NEW_DIR}/plugins/CDVDnull/Linux" - ## BUILD -echo "Build the tar gz file" -tar -C ${TMP_DIR} -czf ${TAR_NAME}.gz $PKG_NAME +echo "Build the tar.gz file" +tar -C $TMP_DIR -czf ${TAR_NAME}.gz $PKG_NAME ## Clean rm -fr $NEW_DIR +rm -fr $ROOT_DIR diff --git a/debian-unstable-upstream/patches/55_cmake_opt_clean.patch b/debian-unstable-upstream/patches/55_cmake_opt_clean.patch deleted file mode 100644 index 88bb08e898..0000000000 --- a/debian-unstable-upstream/patches/55_cmake_opt_clean.patch +++ /dev/null @@ -1,413 +0,0 @@ -Index: pcsx2.snapshot-3369/pcsx2/CMakeLists.txt -=================================================================== ---- pcsx2.snapshot-3369.orig/pcsx2/CMakeLists.txt -+++ pcsx2.snapshot-3369/pcsx2/CMakeLists.txt -@@ -17,12 +17,8 @@ - set(CMAKE_CXX_FLAGS_RELEASE "") - - # set common flags --set(CommonFlags -+set(CommonFlags - -pthread -- -fno-guess-branch-probability -- -fno-dse -- -fno-tree-dse -- -fno-strict-aliasing - -m32 - -march=i486 - -msse -@@ -38,55 +34,51 @@ - -W - -g) - -+# Remove optimization that can break the code. Must be retested -+set(BadFlags_O0 -+ -fno-guess-branch-probability -+ -fno-dse -+ -fno-tree-dse -+ ) -+ -+set(BadFlags_O1 -+ -fno-argument-alias -+ -fno-branch-count-reg -+ -fno-ipa-pure-const -+ -fno-ipa-reference -+ -fno-omit-frame-pointer -+ -fno-split-wide-types -+ -fno-tree-copy-prop -+ -fno-tree-dse -+ -fno-tree-sink -+ ) -+ -+set(BadFlags_O2 -+ -fno-expensive-optimizations -+ -fno-forward-propagate -+ -fno-inline-small-functions -+ -fno-ipa-cp -+ -fno-schedule-insns2 -+ -fno-strict-aliasing -+ -fno-tree-builtin-call-dce -+ ) -+ - # set optimization flags - set(OptimizationFlags -- -falign-functions -- -falign-jumps -- -falign-labels -- -falign-loops -- -fcaller-saves -- -fcprop-registers -- -fcrossjumping -- -fcse-follow-jumps - -fcse-skip-blocks -- -fdefer-pop -- -fdelete-null-pointer-checks -- -fgcse -- -fgcse-lm -- -fif-conversion -- -fif-conversion2 -- -fmerge-constants -- -foptimize-sibling-calls -- -fpeephole2 -- -fregmove -- -freorder-blocks -- -freorder-functions -- -frerun-cse-after-loop -- -fsched-interblock -- -fsched-spec - -fstrict-overflow -- -fthread-jumps -- -ftree-ccp -- -ftree-ch -- -ftree-copyrename -- -ftree-dce -- -ftree-dominator-opts -- -ftree-fre - -ftree-lrs -- -ftree-pre -- -ftree-sra -- -ftree-ter -- -ftree-vrp -- -funit-at-a-time) -+ -O2 -+ ) - - # Debug - Build - if(CMAKE_BUILD_TYPE STREQUAL Debug) -- -+ - # executable name - set(pcsx2Name pcsx2) -- -+ - # add defines -- add_definitions(${CommonFlags} ${DebugFlags} -DPCSX2_DEVBUILD -DPCSX2_DEBUG -DWX_PRECOMP) -+ add_definitions(${CommonFlags} ${DebugFlags} ${BadFlags_O0} -DPCSX2_DEVBUILD -DPCSX2_DEBUG -DWX_PRECOMP) - endif(CMAKE_BUILD_TYPE STREQUAL Debug) - - # Devel - Build -@@ -94,9 +86,9 @@ - - # executable name - set(pcsx2Name pcsx2) -- -+ - # add defines -- add_definitions(${CommonFlags} ${OptimizationFlags} -DPCSX2_DEVBUILD -DWX_PRECOMP -DNDEBUG) -+ add_definitions(${CommonFlags} ${OptimizationFlags} ${BadFlags_O0} ${BadFlags_O1} ${BadFlags_O2} -DPCSX2_DEVBUILD -DWX_PRECOMP -DNDEBUG) - endif(CMAKE_BUILD_TYPE STREQUAL Devel) - - # Release - Build -@@ -104,9 +96,9 @@ - - # executable name - set(pcsx2Name pcsx2) -- -+ - # add defines -- add_definitions(${CommonFlags} ${OptimizationFlags} -DWX_PRECOMP -DNDEBUG) -+ add_definitions(${CommonFlags} ${OptimizationFlags} ${BadFlags_O0} ${BadFlags_O1} ${BadFlags_O2} -DWX_PRECOMP -DNDEBUG) - endif(CMAKE_BUILD_TYPE STREQUAL Release) - - # you must have both svn client executable and a source that contains svn metadata -@@ -606,7 +598,7 @@ - set(Platform - ${pcsx2LinuxSources} - ${pcsx2LinuxHeaders}) --endif(Linux) -+endif(Linux) - - # Windows - if(Windows) -@@ -619,7 +611,7 @@ - if(MacOSX) - set(PlatformSources - ) --endif(MacOSX) -+endif(MacOSX) - - # additonal include directories - include_directories(. -@@ -640,7 +632,7 @@ - - # link target with project internal libraries - target_link_libraries(${pcsx2Name} Utilities x86emitter) -- -+ - # link target with wx - target_link_libraries(${pcsx2Name} ${wxWidgets_LIBRARIES}) - -Index: pcsx2.snapshot-3369/common/src/x86emitter/CMakeLists.txt -=================================================================== ---- pcsx2.snapshot-3369.orig/common/src/x86emitter/CMakeLists.txt -+++ pcsx2.snapshot-3369/common/src/x86emitter/CMakeLists.txt -@@ -22,10 +22,6 @@ - # set common flags - set(CommonFlags - -pthread -- -fno-guess-branch-probability -- -fno-dse -- -fno-tree-dse -- -fno-strict-aliasing - -m32 - -march=i486 - -msse -@@ -41,66 +37,63 @@ - -W - -g) - -+# Remove optimization that can break the code. Must be retested -+set(BadFlags_O0 -+ -fno-guess-branch-probability -+ -fno-dse -+ -fno-tree-dse -+ ) -+ -+set(BadFlags_O1 -+ -fno-argument-alias -+ -fno-branch-count-reg -+ -fno-ipa-pure-const -+ -fno-ipa-reference -+ -fno-omit-frame-pointer -+ -fno-split-wide-types -+ -fno-tree-copy-prop -+ -fno-tree-dse -+ -fno-tree-sink -+ ) -+ -+ -+set(BadFlags_O2 -+ -fno-expensive-optimizations -+ -fno-forward-propagate -+ -fno-inline-small-functions -+ -fno-ipa-cp -+ -fno-schedule-insns2 -+ -fno-strict-aliasing -+ -fno-tree-builtin-call-dce -+ ) -+ - # set optimization flags - set(OptimizationFlags -- -falign-functions -- -falign-jumps -- -falign-labels -- -falign-loops -- -fcaller-saves -- -fcprop-registers -- -fcrossjumping -- -fcse-follow-jumps - -fcse-skip-blocks -- -fdefer-pop -- -fdelete-null-pointer-checks -- -fgcse -- -fgcse-lm -- -fif-conversion -- -fif-conversion2 -- -fmerge-constants -- -foptimize-sibling-calls -- -fpeephole2 -- -fregmove -- -freorder-blocks -- -freorder-functions -- -frerun-cse-after-loop -- -fsched-interblock -- -fsched-spec - -fstrict-overflow -- -fthread-jumps -- -ftree-ccp -- -ftree-ch -- -ftree-copyrename -- -ftree-dce -- -ftree-dominator-opts -- -ftree-fre - -ftree-lrs -- -ftree-pre -- -ftree-sra -- -ftree-ter -- -ftree-vrp -- -funit-at-a-time) -+ -O2 -+ ) - - # Debug - Build - if(CMAKE_BUILD_TYPE STREQUAL Debug) - - # add defines -- add_definitions(${CommonFlags} ${DebugFlags} -DPCSX2_DEVBUILD -DPCSX2_DEBUG) -+ add_definitions(${CommonFlags} ${DebugFlags} ${BadFlags_O0} -DPCSX2_DEVBUILD -DPCSX2_DEBUG) - endif(CMAKE_BUILD_TYPE STREQUAL Debug) - - # Devel - Build - if(CMAKE_BUILD_TYPE STREQUAL Devel) - - # add defines -- add_definitions(${CommonFlags} ${OptimizationFlags} -DPCSX2_DEVBUILD) -+ add_definitions(${CommonFlags} ${OptimizationFlags} ${BadFlags_O0} ${BadFlags_O1} ${BadFlags_O2} -DPCSX2_DEVBUILD) - endif(CMAKE_BUILD_TYPE STREQUAL Devel) - - # Release - Build - if(CMAKE_BUILD_TYPE STREQUAL Release) - - # add defines -- add_definitions(${CommonFlags} ${OptimizationFlags}) -+ add_definitions(${CommonFlags} ${OptimizationFlags} ${BadFlags_O0} ${BadFlags_O1} ${BadFlags_O2}) - endif(CMAKE_BUILD_TYPE STREQUAL Release) - - # variable with all sources of this library -Index: pcsx2.snapshot-3369/common/src/Utilities/CMakeLists.txt -=================================================================== ---- pcsx2.snapshot-3369.orig/common/src/Utilities/CMakeLists.txt -+++ pcsx2.snapshot-3369/common/src/Utilities/CMakeLists.txt -@@ -20,16 +20,12 @@ - set(CMAKE_CXX_FLAGS_RELEASE "") - - # set common flags --set(CommonFlags -+set(CommonFlags - -pthread - -m32 - -march=i486 - -msse - -msse2 -- -fno-dse -- -fno-guess-branch-probability -- -fno-strict-aliasing -- -fno-tree-dse - -pipe - -Wno-format - -Wno-unused-parameter -@@ -41,66 +37,64 @@ - -g - -W) - -+# Remove optimization that can break the code. Must be retested -+set(BadFlags_O0 -+ -fno-guess-branch-probability -+ -fno-dse -+ -fno-tree-dse -+ ) -+ -+set(BadFlags_O1 -+ -fno-argument-alias -+ -fno-branch-count-reg -+ -fno-ipa-pure-const -+ -fno-ipa-reference -+ -fno-omit-frame-pointer -+ -fno-split-wide-types -+ -fno-tree-copy-prop -+ -fno-tree-dse -+ -fno-tree-sink -+ ) -+ -+ -+set(BadFlags_O2 -+ -fno-expensive-optimizations -+ -fno-forward-propagate -+ -fno-inline-small-functions -+ -fno-ipa-cp -+ -fno-schedule-insns2 -+ -fno-strict-aliasing -+ -fno-tree-builtin-call-dce -+ ) -+ -+ - # set optimization flags - set(OptimizationFlags -- -falign-functions -- -falign-jumps -- -falign-labels -- -falign-loops -- -fcaller-saves -- -fcprop-registers -- -fcrossjumping -- -fcse-follow-jumps - -fcse-skip-blocks -- -fdefer-pop -- -fdelete-null-pointer-checks -- -fgcse -- -fgcse-lm -- -fif-conversion -- -fif-conversion2 -- -fmerge-constants -- -foptimize-sibling-calls -- -fpeephole2 -- -fregmove -- -freorder-blocks -- -freorder-functions -- -frerun-cse-after-loop -- -fsched-interblock -- -fsched-spec - -fstrict-overflow -- -fthread-jumps -- -ftree-ccp -- -ftree-ch -- -ftree-copyrename -- -ftree-dce -- -ftree-dominator-opts -- -ftree-fre - -ftree-lrs -- -ftree-pre -- -ftree-sra -- -ftree-ter -- -ftree-vrp -- -funit-at-a-time) -+ -O2 -+ ) - - # Debug - Build - if(CMAKE_BUILD_TYPE STREQUAL Debug) -- -+ - # add defines -- add_definitions(${CommonFlags} ${DebugFlags} -DPCSX2_DEBUG -DPCSX2_DEVBUILD) -+ add_definitions(${CommonFlags} ${DebugFlags} ${BadFlags_O0} -DPCSX2_DEBUG -DPCSX2_DEVBUILD) - endif(CMAKE_BUILD_TYPE STREQUAL Debug) - - # Devel - Build - if(CMAKE_BUILD_TYPE STREQUAL Devel) -- -+ - # add defines -- add_definitions(${CommonFlags} ${OptimizationFlags} -DPCSX2_DEVBUILD) -+ add_definitions(${CommonFlags} ${OptimizationFlags} ${BadFlags_O0} ${BadFlags_O1} ${BadFlags_O2} -DPCSX2_DEVBUILD) - endif(CMAKE_BUILD_TYPE STREQUAL Devel) - - # Release - Build - if(CMAKE_BUILD_TYPE STREQUAL Release) -- -+ - # add defines -- add_definitions(${CommonFlags} ${OptimizationFlags}) -+ add_definitions(${CommonFlags} ${OptimizationFlags} ${BadFlags_O0} ${BadFlags_O1} ${BadFlags_O2}) - endif(CMAKE_BUILD_TYPE STREQUAL Release) - - # variable with all sources of this library -@@ -178,7 +172,7 @@ - - # link target with wx - target_link_libraries(${UtilitiesName} ${wxWidgets_LIBRARIES}) -- -+ - # Force the linker into 32 bits mode - target_link_libraries(${UtilitiesName} -m32) - diff --git a/debian-unstable-upstream/patches/56_cmake_enable_opt1.patch b/debian-unstable-upstream/patches/56_cmake_enable_opt1.patch deleted file mode 100644 index c3c6e6bc56..0000000000 --- a/debian-unstable-upstream/patches/56_cmake_enable_opt1.patch +++ /dev/null @@ -1,78 +0,0 @@ -Index: pcsx2.snapshot-3369/common/src/Utilities/CMakeLists.txt -=================================================================== ---- pcsx2.snapshot-3369.orig/common/src/Utilities/CMakeLists.txt -+++ pcsx2.snapshot-3369/common/src/Utilities/CMakeLists.txt -@@ -39,21 +39,9 @@ - - # Remove optimization that can break the code. Must be retested - set(BadFlags_O0 -- -fno-guess-branch-probability -- -fno-dse -- -fno-tree-dse - ) - - set(BadFlags_O1 -- -fno-argument-alias -- -fno-branch-count-reg -- -fno-ipa-pure-const -- -fno-ipa-reference -- -fno-omit-frame-pointer -- -fno-split-wide-types -- -fno-tree-copy-prop -- -fno-tree-dse -- -fno-tree-sink - ) - - -Index: pcsx2.snapshot-3369/common/src/x86emitter/CMakeLists.txt -=================================================================== ---- pcsx2.snapshot-3369.orig/common/src/x86emitter/CMakeLists.txt -+++ pcsx2.snapshot-3369/common/src/x86emitter/CMakeLists.txt -@@ -39,21 +39,9 @@ - - # Remove optimization that can break the code. Must be retested - set(BadFlags_O0 -- -fno-guess-branch-probability -- -fno-dse -- -fno-tree-dse - ) - - set(BadFlags_O1 -- -fno-argument-alias -- -fno-branch-count-reg -- -fno-ipa-pure-const -- -fno-ipa-reference -- -fno-omit-frame-pointer -- -fno-split-wide-types -- -fno-tree-copy-prop -- -fno-tree-dse -- -fno-tree-sink - ) - - -Index: pcsx2.snapshot-3369/pcsx2/CMakeLists.txt -=================================================================== ---- pcsx2.snapshot-3369.orig/pcsx2/CMakeLists.txt -+++ pcsx2.snapshot-3369/pcsx2/CMakeLists.txt -@@ -36,21 +36,9 @@ - - # Remove optimization that can break the code. Must be retested - set(BadFlags_O0 -- -fno-guess-branch-probability -- -fno-dse -- -fno-tree-dse - ) - - set(BadFlags_O1 -- -fno-argument-alias -- -fno-branch-count-reg -- -fno-ipa-pure-const -- -fno-ipa-reference -- -fno-omit-frame-pointer -- -fno-split-wide-types -- -fno-tree-copy-prop -- -fno-tree-dse -- -fno-tree-sink - ) - - set(BadFlags_O2 diff --git a/debian-unstable-upstream/patches/57_cmake_enable_opt2.patch b/debian-unstable-upstream/patches/57_cmake_enable_opt2.patch deleted file mode 100644 index 5bac1f073e..0000000000 --- a/debian-unstable-upstream/patches/57_cmake_enable_opt2.patch +++ /dev/null @@ -1,54 +0,0 @@ -Index: pcsx2.snapshot-3369/common/src/Utilities/CMakeLists.txt -=================================================================== ---- pcsx2.snapshot-3369.orig/common/src/Utilities/CMakeLists.txt -+++ pcsx2.snapshot-3369/common/src/Utilities/CMakeLists.txt -@@ -46,13 +46,6 @@ - - - set(BadFlags_O2 -- -fno-expensive-optimizations -- -fno-forward-propagate -- -fno-inline-small-functions -- -fno-ipa-cp -- -fno-schedule-insns2 -- -fno-strict-aliasing -- -fno-tree-builtin-call-dce - ) - - -Index: pcsx2.snapshot-3369/common/src/x86emitter/CMakeLists.txt -=================================================================== ---- pcsx2.snapshot-3369.orig/common/src/x86emitter/CMakeLists.txt -+++ pcsx2.snapshot-3369/common/src/x86emitter/CMakeLists.txt -@@ -46,13 +46,6 @@ - - - set(BadFlags_O2 -- -fno-expensive-optimizations -- -fno-forward-propagate -- -fno-inline-small-functions -- -fno-ipa-cp -- -fno-schedule-insns2 -- -fno-strict-aliasing -- -fno-tree-builtin-call-dce - ) - - # set optimization flags -Index: pcsx2.snapshot-3369/pcsx2/CMakeLists.txt -=================================================================== ---- pcsx2.snapshot-3369.orig/pcsx2/CMakeLists.txt -+++ pcsx2.snapshot-3369/pcsx2/CMakeLists.txt -@@ -42,13 +42,6 @@ - ) - - set(BadFlags_O2 -- -fno-expensive-optimizations -- -fno-forward-propagate -- -fno-inline-small-functions -- -fno-ipa-cp -- -fno-schedule-insns2 -- -fno-strict-aliasing -- -fno-tree-builtin-call-dce - ) - - # set optimization flags diff --git a/debian-unstable-upstream/patches/series b/debian-unstable-upstream/patches/series index 806163f7f6..a09286c9f4 100644 --- a/debian-unstable-upstream/patches/series +++ b/debian-unstable-upstream/patches/series @@ -2,7 +2,3 @@ 02_update_default_path.patch 05_move_data_to_config.patch 21_use_legacy_soundtouch_13.patch -# Personnal patch that need advance testing -#55_cmake_opt_clean.patch -#56_cmake_enable_opt1.patch -#57_cmake_enable_opt2.patch diff --git a/debian-unstable-upstream/pcsx2-plugins-unstable.lintian-overrides b/debian-unstable-upstream/pcsx2-plugins-unstable.lintian-overrides index 7f790a7dd6..5be0f61893 100644 --- a/debian-unstable-upstream/pcsx2-plugins-unstable.lintian-overrides +++ b/debian-unstable-upstream/pcsx2-plugins-unstable.lintian-overrides @@ -1,3 +1,6 @@ -# PIC code cause regression in the library and issue with the ebx register. -# Morever library are plugins and the code is only compatible with x86. +#* -fPIC option was removed for multiple reason. +# - Code only support x86 architecture. +# - Upstream code uses the ebx register so it's not compliant with PIC. +# - Impacts the performance too much. +# - Only plugins. No package will link to them. pcsx2-plugins-unstable: shlib-with-non-pic-code diff --git a/debian-unstable-upstream/pcsx2-unstable.install b/debian-unstable-upstream/pcsx2-unstable.install index ba3cebe852..dad979ffe7 100644 --- a/debian-unstable-upstream/pcsx2-unstable.install +++ b/debian-unstable-upstream/pcsx2-unstable.install @@ -1 +1,3 @@ bin/pcsx2 usr/games +debian/pcsx2.desktop usr/share/applications +debian/pcsx2.xpm usr/share/pixmaps diff --git a/debian-unstable-upstream/rules b/debian-unstable-upstream/rules index 40fde09ffb..788f6a4215 100755 --- a/debian-unstable-upstream/rules +++ b/debian-unstable-upstream/rules @@ -41,9 +41,9 @@ clean: dh_testroot rm -f build-stamp - # Backup some orig makefile if it not already done - # I hope some will be delete by upstream when cmake port is over - # Note in case we do not dl all plugins the test [ -f $${makefile} ] ensure the working + # Backup some orig makefile if it's not already done. + # I hope that some will be delete by upstream when the cmake port is over. + # Note: In case that we do not dl all the plugins, the test [ -f $${makefile} ] ensures it works for makefile in plugins/CDVDlinuz/Src/Linux/Makefile \ plugins/CDVDiso/src/Linux/Makefile \ plugins/CDVDiso/src/Windows/Makefile \ @@ -53,13 +53,13 @@ clean: plugins/CDVDisoEFP/src/Linux/Makefile ; do \ [ -f $${makefile}.orig ] || ( [ -f $${makefile} ] && mv $${makefile} $${makefile}.orig ) || true ; done - # Add here commands to clean up after the build process. + # Add here the commands to clean up after the build process. [ -f Makefile ] && $(MAKE) clean || true # Remove cmake stuff rm -fr $$(find . -type d -name CMakeFiles) rm -f $$(find . -type f -name CMakeCache.txt) $$(find . -type f -name cmake_install.cmake) rm -f $$(find . -type f -name Makefile) - # File generated by bin2cpp + # Files generated by bin2cpp cd pcsx2/gui/Resources/ && rm -f App*.h Config*.h BackgroundLogo.h ButtonIcon_Camera.h Dualshock.h # leftover of cmake rm -f bin/plugins/ps2hw.dat @@ -69,62 +69,15 @@ clean: dh_clean -install: -install: build - dh_testdir - dh_testroot - dh_prep - dh_installdirs +## Uncomment this, if fglrx driver is installed +#override_dh_shlibdeps: +# dh_shlibdeps -- --ignore-missing-info - ### the project build usefull thing in ./bin so directly install - ### from this directory to the debian pkg directory (skip debian/tmp) - # Ubuntu use debian/tmp as default sourcedir... - # copy bin into debian tmp - mkdir -p debian/tmp - cp -fr bin debian/tmp - dh_install --sourcedir=debian/tmp - - # install menu and icon - cp debian/pcsx2.desktop debian/pcsx2-unstable/usr/share/applications - cp debian/pcsx2.xpm debian/pcsx2-unstable/usr/share/pixmaps - - # lintian override - dh_lintian - -# Build architecture-independent files here. -binary-indep: build install - dh_testdir -i - dh_testroot -i - dh_installchangelogs -i - dh_installdocs -i - dh_installman -i - dh_link -i - dh_compress -i - dh_fixperms -i - dh_installdeb -i - dh_gencontrol -i - dh_md5sums -i - dh_builddeb -i - -# Build architecture-dependent files here. -binary-arch: build install - dh_testdir -a - dh_testroot -a - dh_installchangelogs -a - dh_installdocs -a - dh_installmenu -a - dh_installman -a +override_dh_strip: dh_strip --package=pcsx2-unstable --dbg-package=pcsx2-unstable-dbg dh_strip --package=pcsx2-plugins-unstable --dbg-package=pcsx2-plugins-unstable-dbg - dh_link -a - dh_compress -a - dh_fixperms -a - dh_makeshlibs -a - dh_installdeb -a - dh_shlibdeps -a - dh_gencontrol -a - dh_md5sums -a - dh_builddeb -a -binary: binary-indep binary-arch -.PHONY: build clean binary-indep binary-arch binary install +%: + dh $@ --parallel + +.PHONY: build clean install diff --git a/debian-unstable-upstream/rules_fglrx b/debian-unstable-upstream/rules_fglrx index 04fd2ef739..5e7540a5d5 100755 --- a/debian-unstable-upstream/rules_fglrx +++ b/debian-unstable-upstream/rules_fglrx @@ -41,9 +41,9 @@ clean: dh_testroot rm -f build-stamp - # Backup some orig makefile if it not already done - # I hope some will be delete by upstream when cmake port is over - # Note in case we do not dl all plugins the test [ -f $${makefile} ] ensure the working + # Backup some orig makefile if it's not already done. + # I hope that some will be delete by upstream when the cmake port is over. + # Note: In case that we do not dl all the plugins, the test [ -f $${makefile} ] ensures it works for makefile in plugins/CDVDlinuz/Src/Linux/Makefile \ plugins/CDVDiso/src/Linux/Makefile \ plugins/CDVDiso/src/Windows/Makefile \ @@ -53,13 +53,13 @@ clean: plugins/CDVDisoEFP/src/Linux/Makefile ; do \ [ -f $${makefile}.orig ] || ( [ -f $${makefile} ] && mv $${makefile} $${makefile}.orig ) || true ; done - # Add here commands to clean up after the build process. + # Add here the commands to clean up after the build process. [ -f Makefile ] && $(MAKE) clean || true # Remove cmake stuff rm -fr $$(find . -type d -name CMakeFiles) rm -f $$(find . -type f -name CMakeCache.txt) $$(find . -type f -name cmake_install.cmake) rm -f $$(find . -type f -name Makefile) - # File generated by bin2cpp + # Files generated by bin2cpp cd pcsx2/gui/Resources/ && rm -f App*.h Config*.h BackgroundLogo.h ButtonIcon_Camera.h Dualshock.h # leftover of cmake rm -f bin/plugins/ps2hw.dat @@ -69,65 +69,15 @@ clean: dh_clean -install: -install: build - dh_testdir - dh_testroot - dh_prep - dh_installdirs +# Allow compilation when fglrx is installed +override_dh_shlibdeps: + dh_shlibdeps -- --ignore-missing-info - ### the project build usefull thing in ./bin so directly install - ### from this directory to the debian pkg directory (skip debian/tmp) - # Ubuntu use debian/tmp as default sourcedir... - # copy bin into debian tmp - mkdir -p debian/tmp - cp -fr bin debian/tmp - dh_install --sourcedir=debian/tmp - - # install menu and icon - cp debian/pcsx2.desktop debian/pcsx2-unstable/usr/share/applications - cp debian/pcsx2.xpm debian/pcsx2-unstable/usr/share/pixmaps - - # lintian override - dh_lintian - -# Build architecture-independent files here. -binary-indep: build install - dh_testdir -i - dh_testroot -i - dh_installchangelogs -i - dh_installdocs -i - dh_installman -i - dh_link -i - dh_compress -i - dh_fixperms -i - dh_installdeb -i - dh_gencontrol -i - dh_md5sums -i - dh_builddeb -i - -# Build architecture-dependent files here. -binary-arch: build install - dh_testdir -a - dh_testroot -a - dh_installchangelogs -a - dh_installdocs -a - dh_installmenu -a - dh_installman -a +override_dh_strip: dh_strip --package=pcsx2-unstable --dbg-package=pcsx2-unstable-dbg dh_strip --package=pcsx2-plugins-unstable --dbg-package=pcsx2-plugins-unstable-dbg - dh_link -a - dh_compress -a - dh_fixperms -a - dh_makeshlibs -a - dh_installdeb -a - # XXX: WARNING to test the package on my system I must add the option (--exclude) - # due to fglrx drivers modify libGL. It must be re-enable for final packaging - # dh_shlibdeps -a - dh_shlibdeps -a --exclude=libzzogl - dh_gencontrol -a - dh_md5sums -a - dh_builddeb -a -binary: binary-indep binary-arch -.PHONY: build clean binary-indep binary-arch binary install +%: + dh $@ --parallel + +.PHONY: build clean install diff --git a/debian-unstable-upstream/watch b/debian-unstable-upstream/watch index a53911e452..ee7121df88 100644 --- a/debian-unstable-upstream/watch +++ b/debian-unstable-upstream/watch @@ -6,5 +6,6 @@ # Compulsory line, this is a version 3 file version=3 -# Note upstream do not release source files. It advices to pick them from subversion +# Note: Upstream does not release prepackaged source files. +# It's adviced to get them from their subversion repository. # http://pcsx2.googlecode.com/files/Pcsx2-linux-beta-(.*).tar.gz diff --git a/pcsx2/CDVD/CDVDisoReader.h b/pcsx2/CDVD/CDVDisoReader.h index 5d6dceb8f5..e03ef00689 100644 --- a/pcsx2/CDVD/CDVDisoReader.h +++ b/pcsx2/CDVD/CDVDisoReader.h @@ -16,10 +16,6 @@ #ifndef __CDVD_ISO_READER_H__ #define __CDVD_ISO_READER_H__ -#ifdef _MSC_VER -#pragma warning(disable:4018) -#endif - #include #include "IopCommon.h" diff --git a/pcsx2/CDVD/IsoFileFormats.cpp b/pcsx2/CDVD/IsoFileFormats.cpp index 092668660c..81daf56ad0 100644 --- a/pcsx2/CDVD/IsoFileFormats.cpp +++ b/pcsx2/CDVD/IsoFileFormats.cpp @@ -137,7 +137,8 @@ isoFile *isoOpen(const char *filename) iso->handle = _openfile( iso->filename, O_RDONLY); if (iso->handle == NULL) { - Console.Error("error loading %s", iso->filename); + Console.Error("ISO loader: Cannot access %s", iso->filename); + Console.Error(">> Make sure the iso file is not mounted in any disk emulation software! <<"); return NULL; } diff --git a/pcsx2/CDVD/IsoFileTools.h b/pcsx2/CDVD/IsoFileTools.h index 88e91109ac..5c4469469c 100644 --- a/pcsx2/CDVD/IsoFileTools.h +++ b/pcsx2/CDVD/IsoFileTools.h @@ -29,10 +29,6 @@ #define _FILE_OFFSET_BITS 64 -#ifdef _MSC_VER -# pragma warning(disable:4018) // disable signed/unsigned mismatch error -#endif - #include "IopCommon.h" #include diff --git a/pcsx2/CMakeLists.txt b/pcsx2/CMakeLists.txt index 866c07edd1..82155f8e83 100644 --- a/pcsx2/CMakeLists.txt +++ b/pcsx2/CMakeLists.txt @@ -165,7 +165,6 @@ set(pcsx2Sources Vif_Codes.cpp Vif_Transfer.cpp Vif_Unpack.cpp - Vif_Unpack.inl vtlb.cpp VU0.cpp VUmicro.cpp @@ -226,6 +225,7 @@ set(pcsx2Headers Vif_Dma.h Vif.h Vif_Unpack.h + Vif_Unpack.inl vtlb.h VUflags.h VUmicro.h @@ -295,7 +295,6 @@ set(pcsx2GuiSources gui/Panels/BaseApplicableConfigPanel.cpp gui/Panels/MemoryCardListView.cpp gui/Dialogs/BaseConfigurationDialog.cpp - gui/Dialogs/BaseConfigurationDialog.inl gui/Dialogs/BiosSelectorDialog.cpp gui/Dialogs/ConfirmationDialogs.cpp gui/Dialogs/CreateMemoryCardDialog.cpp @@ -353,6 +352,7 @@ set(pcsx2GuiHeaders gui/AppGameDatabase.h gui/ConsoleLogger.h gui/CpuUsageProvider.h + gui/Dialogs/BaseConfigurationDialog.inl gui/Dialogs/ConfigurationDialog.h gui/Dialogs/LogOptionsDialog.h gui/Dialogs/ModalPopups.h @@ -371,6 +371,7 @@ set(pcsx2GuiHeaders set(pcsx2IPUSources IPU/IPU.cpp IPU/IPU_Fifo.cpp + IPU/IPUdma.cpp IPU/mpeg2lib/Idct.cpp IPU/mpeg2lib/Mpeg.cpp IPU/yuv2rgb.cpp) @@ -379,6 +380,7 @@ set(pcsx2IPUSources set(pcsx2IPUHeaders IPU/IPU.h IPU/IPU_Fifo.h + IPU/IPUdma.h IPU/yuv2rgb.h) # Linux sources @@ -394,12 +396,15 @@ set(pcsx2LinuxHeaders set(pcsx2ps2Sources ps2/BiosTools.cpp ps2/GIFpath.cpp + ps2/LegacyDmac.cpp ps2/Iop/IopHwRead.cpp ps2/Iop/IopHwWrite.cpp) # ps2 headers set(pcsx2ps2Headers ps2/BiosTools.h + ps2/eeHwTraceLog.inl + ps2/HwInternal.h ps2/Iop/IopHw_Internal.h) # RDebug sources @@ -495,20 +500,6 @@ set(pcsx2x86Sources x86/ix86-32/iR5900Shift.cpp x86/ix86-32/iR5900Templates.cpp x86/ix86-32/recVTLB.cpp - x86/microVU_Alloc.inl - x86/microVU_Analyze.inl - x86/microVU_Branch.inl - x86/microVU_Clamp.inl - x86/microVU_Compile.inl - x86/microVU.cpp - x86/microVU_Execute.inl - x86/microVU_Flags.inl - x86/microVU_Log.inl - x86/microVU_Lower.inl - x86/microVU_Macro.inl - x86/microVU_Misc.inl - x86/microVU_Tables.inl - x86/microVU_Upper.inl x86/newVif_Dynarec.cpp x86/newVif_Unpack.cpp x86/newVif_UnpackSSE.cpp @@ -538,6 +529,20 @@ set(pcsx2x86Headers x86/microVU.h x86/microVU_IR.h x86/microVU_Misc.h + x86/microVU_Alloc.inl + x86/microVU_Analyze.inl + x86/microVU_Branch.inl + x86/microVU_Clamp.inl + x86/microVU_Compile.inl + x86/microVU.cpp + x86/microVU_Execute.inl + x86/microVU_Flags.inl + x86/microVU_Log.inl + x86/microVU_Lower.inl + x86/microVU_Macro.inl + x86/microVU_Misc.inl + x86/microVU_Tables.inl + x86/microVU_Upper.inl x86/newVif.h x86/newVif_BlockBuffer.h x86/newVif_HashBucket.h diff --git a/pcsx2/COP0.cpp b/pcsx2/COP0.cpp index b08efa5bdf..8ce8290f29 100644 --- a/pcsx2/COP0.cpp +++ b/pcsx2/COP0.cpp @@ -428,7 +428,7 @@ void MTC0() } int CPCOND0() { - return ((dmacRegs->stat.CIS | ~dmacRegs->pcr.CPC) == 0x3ff); + return ((dmacRegs.stat.CIS | ~dmacRegs.pcr.CPC) == 0x3ff); } //#define CPCOND0 1 diff --git a/pcsx2/Common.h b/pcsx2/Common.h index 22a99ddc01..34b895796e 100644 --- a/pcsx2/Common.h +++ b/pcsx2/Common.h @@ -17,12 +17,6 @@ #include "Pcsx2Defs.h" -static const s64 _1mb = 0x100000; -static const s64 _8mb = _1mb * 8; -static const s64 _16mb = _1mb * 16; -static const s64 _256mb = _1mb * 256; -static const s64 _1gb = _256mb * 4; - static const u32 BIAS = 2; // Bus is half of the actual ps2 speed static const u32 PS2CLK = 294912000; //hz /* 294.912 mhz */ diff --git a/pcsx2/Config.h b/pcsx2/Config.h index 203534d058..32d2188532 100644 --- a/pcsx2/Config.h +++ b/pcsx2/Config.h @@ -343,11 +343,11 @@ struct Pcsx2Config void LoadSave( IniInterface& conf ); void Set( const wxString& list, bool enabled=true ); - bool Clear( const wxString& list ) { Set( list, false ); } + void Clear( const wxString& list ) { Set( list, false ); } bool Get( GamefixId id ) const; void Set( GamefixId id, bool enabled=true ); - bool Clear( GamefixId id ) { Set( id, false ); } + void Clear( GamefixId id ) { Set( id, false ); } bool operator ==( const GamefixOptions& right ) const { diff --git a/pcsx2/Counters.cpp b/pcsx2/Counters.cpp index e6d1d88092..2979eb9219 100644 --- a/pcsx2/Counters.cpp +++ b/pcsx2/Counters.cpp @@ -15,11 +15,11 @@ #include "PrecompiledHeader.h" -#include "Common.h" #include #include +#include "Common.h" #include "R3000A.h" #include "Counters.h" #include "IopCounters.h" @@ -27,6 +27,8 @@ #include "GS.h" #include "VUmicro.h" +#include "ps2/HwInternal.h" + using namespace Threading; extern u8 psxhblankgate; @@ -45,6 +47,15 @@ SyncCounter vsyncCounter; u32 nextsCounter; // records the cpuRegs.cycle value of the last call to rcntUpdate() s32 nextCounter; // delta from nextsCounter, in cycles, until the next rcntUpdate() +// Forward declarations needed because C/C++ both are wimpy single-pass compilers. + +static void rcntStartGate(bool mode, u32 sCycle); +static void rcntEndGate(bool mode, u32 sCycle); +static void rcntWcount(int index, u32 value); +static void rcntWmode(int index, u32 value); +static void rcntWtarget(int index, u32 value); +static void rcntWhold(int index, u32 value); + void rcntReset(int index) { counters[index].count = 0; @@ -575,7 +586,7 @@ static __fi void _rcntSetGate( int index ) } // mode - 0 means hblank source, 8 means vblank source. -__fi void rcntStartGate(bool isVblank, u32 sCycle) +static __fi void rcntStartGate(bool isVblank, u32 sCycle) { int i; @@ -636,7 +647,7 @@ __fi void rcntStartGate(bool isVblank, u32 sCycle) } // mode - 0 means hblank signal, 8 means vblank signal. -__fi void rcntEndGate(bool isVblank , u32 sCycle) +static __fi void rcntEndGate(bool isVblank , u32 sCycle) { int i; @@ -677,7 +688,15 @@ __fi void rcntEndGate(bool isVblank , u32 sCycle) // rcntUpdate, since we're being called from there anyway. } -__fi void rcntWmode(int index, u32 value) +static __fi u32 rcntCycle(int index) +{ + if (counters[index].mode.IsCounting && (counters[index].mode.ClockSource != 0x3)) + return counters[index].count + ((cpuRegs.cycle - counters[index].sCycleT) / counters[index].rate); + else + return counters[index].count; +} + +static __fi void rcntWmode(int index, u32 value) { if(counters[index].mode.IsCounting) { if(counters[index].mode.ClockSource != 0x3) { @@ -711,7 +730,7 @@ __fi void rcntWmode(int index, u32 value) _rcntSet( index ); } -__fi void rcntWcount(int index, u32 value) +static __fi void rcntWcount(int index, u32 value) { EECNT_LOG("EE Counter[%d] writeCount = %x, oldcount=%x, target=%x", index, value, counters[index].count, counters[index].target ); @@ -737,7 +756,7 @@ __fi void rcntWcount(int index, u32 value) _rcntSet( index ); } -__fi void rcntWtarget(int index, u32 value) +static __fi void rcntWtarget(int index, u32 value) { EECNT_LOG("EE Counter[%d] writeTarget = %x", index, value); @@ -766,7 +785,7 @@ __fi void rcntWtarget(int index, u32 value) _rcntSet( index ); } -__fi void rcntWhold(int index, u32 value) +static __fi void rcntWhold(int index, u32 value) { EECNT_LOG("EE Counter[%d] Hold Write = %x", index, value); counters[index].hold = value; @@ -787,14 +806,76 @@ __fi u32 rcntRcount(int index) return ret; } -__fi u32 rcntCycle(int index) +template< uint page > +__fi u16 rcntRead32( u32 mem ) { - if (counters[index].mode.IsCounting && (counters[index].mode.ClockSource != 0x3)) - return counters[index].count + ((cpuRegs.cycle - counters[index].sCycleT) / counters[index].rate); - else - return counters[index].count; + // Important DevNote: + // Yes this uses a u16 return value on purpose! The upper bits 16 of the counter registers + // are all fixed to 0, so we always truncate everything in these two pages using a u16 + // return value! --air + + iswitch( mem ) { + icase(RCNT0_COUNT) return (u16)rcntRcount(0); + icase(RCNT0_MODE) return (u16)counters[0].modeval; + icase(RCNT0_TARGET) return (u16)counters[0].target; + icase(RCNT0_HOLD) return (u16)counters[0].hold; + + icase(RCNT1_COUNT) return (u16)rcntRcount(1); + icase(RCNT1_MODE) return (u16)counters[1].modeval; + icase(RCNT1_TARGET) return (u16)counters[1].target; + icase(RCNT1_HOLD) return (u16)counters[1].hold; + + icase(RCNT2_COUNT) return (u16)rcntRcount(2); + icase(RCNT2_MODE) return (u16)counters[2].modeval; + icase(RCNT2_TARGET) return (u16)counters[2].target; + + icase(RCNT3_COUNT) return (u16)rcntRcount(3); + icase(RCNT3_MODE) return (u16)counters[3].modeval; + icase(RCNT3_TARGET) return (u16)counters[3].target; + } + + return psHu16(mem); } +template< uint page > +__fi bool rcntWrite32( u32 mem, mem32_t& value ) +{ + pxAssume( mem >= RCNT0_COUNT && mem < 0x10002000 ); + + // [TODO] : counters should actually just use the EE's hw register space for storing + // count, mode, target, and hold. This will allow for a simplified handler for register + // reads. + + iswitch( mem ) { + icase(RCNT0_COUNT) return rcntWcount(0, value), false; + icase(RCNT0_MODE) return rcntWmode(0, value), false; + icase(RCNT0_TARGET) return rcntWtarget(0, value), false; + icase(RCNT0_HOLD) return rcntWhold(0, value), false; + + icase(RCNT1_COUNT) return rcntWcount(1, value), false; + icase(RCNT1_MODE) return rcntWmode(1, value), false; + icase(RCNT1_TARGET) return rcntWtarget(1, value), false; + icase(RCNT1_HOLD) return rcntWhold(1, value), false; + + icase(RCNT2_COUNT) return rcntWcount(2, value), false; + icase(RCNT2_MODE) return rcntWmode(2, value), false; + icase(RCNT2_TARGET) return rcntWtarget(2, value), false; + + icase(RCNT3_COUNT) return rcntWcount(3, value), false; + icase(RCNT3_MODE) return rcntWmode(3, value), false; + icase(RCNT3_TARGET) return rcntWtarget(3, value), false; + } + + // unhandled .. do memory writeback. + return true; +} + +template u16 rcntRead32<0x00>( u32 mem ); +template u16 rcntRead32<0x01>( u32 mem ); + +template bool rcntWrite32<0x00>( u32 mem, mem32_t& value ); +template bool rcntWrite32<0x01>( u32 mem, mem32_t& value ); + void SaveStateBase::rcntFreeze() { Freeze( counters ); diff --git a/pcsx2/Counters.h b/pcsx2/Counters.h index c6cb894ee0..bc19e92d4d 100644 --- a/pcsx2/Counters.h +++ b/pcsx2/Counters.h @@ -13,8 +13,7 @@ * If not, see . */ -#ifndef __COUNTERS_H__ -#define __COUNTERS_H__ +#pragma once struct EECNT_MODE { @@ -137,16 +136,10 @@ extern void rcntUpdate_vSync(); extern void rcntUpdate(); extern void rcntInit(); -extern void rcntStartGate(bool mode, u32 sCycle); -extern void rcntEndGate(bool mode, u32 sCycle); -extern void rcntWcount(int index, u32 value); -extern void rcntWmode(int index, u32 value); -extern void rcntWtarget(int index, u32 value); -extern void rcntWhold(int index, u32 value); extern u32 rcntRcount(int index); -extern u32 rcntCycle(int index); +template< uint page > extern bool rcntWrite32( u32 mem, mem32_t& value ); +template< uint page > extern u16 rcntRead32( u32 mem ); // returns u16 by design! (see implementation for details) extern u32 UpdateVSyncRate(); extern void frameLimitReset(); -#endif /* __COUNTERS_H__ */ diff --git a/pcsx2/DebugTools/Debug.h b/pcsx2/DebugTools/Debug.h index 75a7ca3d9b..737fb62f3d 100644 --- a/pcsx2/DebugTools/Debug.h +++ b/pcsx2/DebugTools/Debug.h @@ -342,17 +342,19 @@ struct SysConsoleLogPack extern SysTraceLogPack SysTrace; extern SysConsoleLogPack SysConsole; +extern void __Log( const char* fmt, ... ); // Helper macro for cut&paste. Note that we intentionally use a top-level *inline* bitcheck // against Trace.Enabled, to avoid extra overhead in Debug builds when logging is disabled. // (specifically this allows debug builds to skip havingto resolve all the parameters being // passed into the function) -#define macTrace(trace) SysTrace.trace.IsActive() && SysTrace.trace.Write - - #ifdef PCSX2_DEVBUILD - -extern void __Log( const char* fmt, ... ); +# define SysTraceActive(trace) SysTrace.trace.IsActive() +# define macTrace(trace) SysTraceActive(trace) && SysTrace.trace.Write +#else +# define SysTraceActive(trace) (false) +# define macTrace(trace) +#endif #define SIF_LOG macTrace(SIF) @@ -385,45 +387,9 @@ extern void __Log( const char* fmt, ... ); #define GPU_LOG macTrace(IOP.GPU) #define CDVD_LOG macTrace(IOP.CDVD) -#else // PCSX2_DEVBUILD -#define CPU_LOG 0&& -#define MEM_LOG 0&& -#define HW_LOG 0&& -#define DMA_LOG 0&& -#define BIOS_LOG 0&& -#define VU0_LOG 0&& -#define COP0_LOG 0&& -#define UnknownHW_LOG 0&& -#define VIF_LOG 0&& -#define SPR_LOG 0&& -#define GIF_LOG 0&& -#define SIF_LOG 0&& -#define IPU_LOG 0&& -#define VUM_LOG 0&& -#define VifCodeLog 0&& - -#define PSXCPU_LOG 0&& -#define PSXMEM_LOG 0&& -#define PSXHW_LOG 0&& -#define PSXUnkHW_LOG 0&& -#define PSXBIOS_LOG 0&& -#define PSXDMA_LOG 0&& - -#define PAD_LOG 0&& -#define CDR_LOG 0&& -#define CDVD_LOG 0&& -#define GPU_LOG 0&& -#define PSXCNT_LOG 0&& -#define EECNT_LOG 0&& - -#define EMU_LOG 0&& -#define CACHE_LOG 0&& -#define MEMCARDS_LOG 0&& -#endif - -#define ELF_LOG SysConsole.ELF.IsActive() && SysConsole.ELF.Write -#define eeRecPerfLog SysConsole.eeRecPerf.IsActive() && SysConsole.eeRecPerf -#define eeConLog SysConsole.eeConsole.IsActive() && SysConsole.eeConsole.Write -#define eeDeci2Log SysConsole.deci2.IsActive() && SysConsole.deci2.Write -#define iopConLog SysConsole.iopConsole.IsActive() && SysConsole.iopConsole.Write +#define ELF_LOG SysConsole.ELF.IsActive() && SysConsole.ELF.Write +#define eeRecPerfLog SysConsole.eeRecPerf.IsActive() && SysConsole.eeRecPerf +#define eeConLog SysConsole.eeConsole.IsActive() && SysConsole.eeConsole.Write +#define eeDeci2Log SysConsole.deci2.IsActive() && SysConsole.deci2.Write +#define iopConLog SysConsole.iopConsole.IsActive()&& SysConsole.iopConsole.Write diff --git a/pcsx2/Dmac.h b/pcsx2/Dmac.h index c9bbfbe4bd..b68737b79d 100644 --- a/pcsx2/Dmac.h +++ b/pcsx2/Dmac.h @@ -171,10 +171,6 @@ union tDMA_QWC { tDMA_TAG tag() const { return (tDMA_TAG)_u32; } }; -static void setDmacStat(u32 num); -static tDMA_TAG *dmaGetAddr(u32 addr, bool write); -static void throwBusError(const char *s); - struct DMACh { tDMA_CHCR chcr; u32 _null0[3]; @@ -200,63 +196,14 @@ struct DMACh { qwc = ptag[0].QWC; } - bool transfer(const char *s, tDMA_TAG* ptag) - { - if (ptag == NULL) // Is ptag empty? - { - throwBusError(s); - return false; - } - chcrTransfer(ptag); + bool transfer(const char *s, tDMA_TAG* ptag); + void unsafeTransfer(tDMA_TAG* ptag); + tDMA_TAG *getAddr(u32 addr, u32 num, bool write); + tDMA_TAG *DMAtransfer(u32 addr, u32 num); + tDMA_TAG dma_tag(); - qwcTransfer(ptag); - return true; - } - - void unsafeTransfer(tDMA_TAG* ptag) - { - chcrTransfer(ptag); - qwcTransfer(ptag); - } - - tDMA_TAG *getAddr(u32 addr, u32 num, bool write) - { - tDMA_TAG *ptr = dmaGetAddr(addr, write); - if (ptr == NULL) - { - throwBusError("dmaGetAddr"); - setDmacStat(num); - chcr.STR = false; - } - - return ptr; - } - - tDMA_TAG *DMAtransfer(u32 addr, u32 num) - { - tDMA_TAG *tag = getAddr(addr, num, false); - - if (tag == NULL) return NULL; - - chcrTransfer(tag); - qwcTransfer(tag); - return tag; - } - - tDMA_TAG dma_tag() - { - return chcr.tag(); - } - - wxString cmq_to_str() const - { - return wxsFormat(L"chcr = %lx, madr = %lx, qwc = %lx", chcr._u32, madr, qwc); - } - - wxString cmqt_to_str() const - { - return wxsFormat(L"chcr = %lx, madr = %lx, qwc = %lx, tadr = %1x", chcr._u32, madr, qwc, tadr); - } + wxString cmq_to_str() const; + wxString cmqt_to_str() const; }; enum INTCIrqs @@ -524,7 +471,7 @@ union tDMAC_ADDR wxCharBuffer ToUTF8(bool sprIsValid=true) const { - return FastFormatAscii().Write((sprIsValid && SPR) ? "0x%04X(SPR)" : "0x%08X", ADDR).GetResult(); + return FastFormatAscii().Write((sprIsValid && SPR) ? "0x%04X(SPR)" : "0x%08X", ADDR).c_str(); } }; @@ -588,88 +535,28 @@ struct INTCregisters u32 _padding2[3]; }; -#define dmacRegs ((DMACregisters*)(eeMem->HW+0xE000)) -#define intcRegs ((INTCregisters*)(eeMem->HW+0xF000)) +#define intcRegs ((INTCregisters*)(eeHw+0xF000)) -static __fi void throwBusError(const char *s) -{ - Console.Error("%s BUSERR", s); - dmacRegs->stat.BEIS = true; -} +static DMACregisters& dmacRegs = (DMACregisters&)eeHw[0xE000]; -static __fi void setDmacStat(u32 num) -{ - dmacRegs->stat.set_flags(1 << num); -} +// Various useful locations +static DMACh& vif0ch = (DMACh&)eeHw[0x8000]; +static DMACh& vif1ch = (DMACh&)eeHw[0x9000]; +static DMACh& gifch = (DMACh&)eeHw[0xA000]; +static DMACh& spr0ch = (DMACh&)eeHw[0xD000]; +static DMACh& spr1ch = (DMACh&)eeHw[0xD400]; -// Note: Dma addresses are guaranteed to be aligned to 16 bytes (128 bits) -static __fi tDMA_TAG *SPRdmaGetAddr(u32 addr, bool write) -{ - // if (addr & 0xf) { DMA_LOG("*PCSX2*: DMA address not 128bit aligned: %8.8x", addr); } - - //For some reason Getaway references SPR Memory from itself using SPR0, oh well, let it i guess... - if((addr & 0x70000000) == 0x70000000) - { - return (tDMA_TAG*)&eeMem->Scratch[addr & 0x3ff0]; - } - - // FIXME: Why??? DMA uses physical addresses - addr &= 0x1ffffff0; - - if (addr < Ps2MemSize::Base) - { - return (tDMA_TAG*)&eeMem->Main[addr]; - } - else if (addr < 0x10000000) - { - return (tDMA_TAG*)(write ? eeMem->ZeroWrite : eeMem->ZeroRead); - } - else if ((addr >= 0x11004000) && (addr < 0x11010000)) - { - //Access for VU Memory - return (tDMA_TAG*)vtlb_GetPhyPtr(addr & 0x1FFFFFF0); - } - else - { - Console.Error( "*PCSX2*: DMA error: %8.8x", addr); - return NULL; - } -} - -// Note: Dma addresses are guaranteed to be aligned to 16 bytes (128 bits) -static __ri tDMA_TAG *dmaGetAddr(u32 addr, bool write) -{ - // if (addr & 0xf) { DMA_LOG("*PCSX2*: DMA address not 128bit aligned: %8.8x", addr); } - if (DMA_TAG(addr).SPR) return (tDMA_TAG*)&eeMem->Scratch[addr & 0x3ff0]; - - // FIXME: Why??? DMA uses physical addresses - addr &= 0x1ffffff0; - - if (addr < Ps2MemSize::Base) - { - return (tDMA_TAG*)&eeMem->Main[addr]; - } - else if (addr < 0x10000000) - { - return (tDMA_TAG*)(write ? eeMem->ZeroWrite : eeMem->ZeroRead); - } - else if (addr < 0x10004000) - { - // Secret scratchpad address for DMA = end of maximum main memory? - //Console.Warning("Writing to the scratchpad without the SPR flag set!"); - return (tDMA_TAG*)&eeMem->Scratch[addr & 0x3ff0]; - } - else - { - Console.Error( "*PCSX2*: DMA error: %8.8x", addr); - return NULL; - } -} +extern void throwBusError(const char *s); +extern void setDmacStat(u32 num); +extern tDMA_TAG *SPRdmaGetAddr(u32 addr, bool write); +extern tDMA_TAG *dmaGetAddr(u32 addr, bool write); extern void hwIntcIrq(int n); extern void hwDmacIrq(int n); 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 bool hwDmacSrcChainWithStack(DMACh& dma, int id); +extern bool hwDmacSrcChain(DMACh& dma, int id); +template< uint page > u32 dmacRead32( u32 mem ); +template< uint page > extern bool dmacWrite32( u32 mem, mem32_t& value ); diff --git a/pcsx2/Dump.cpp b/pcsx2/Dump.cpp index b61ad4925a..5b08ba515d 100644 --- a/pcsx2/Dump.cpp +++ b/pcsx2/Dump.cpp @@ -129,10 +129,10 @@ void iDumpRegisters(u32 startpc, u32 temp) __Log("gif: %x %x %x", psHu32(0x3000), psHu32(0x3010), psHu32(0x3020)); for(i = 0; i < ArraySize(dmacs); ++i) { - DMACh* p = (DMACh*)(&eeMem->HW[dmacs[i]]); + DMACh* p = (DMACh*)(&eeHw[dmacs[i]]); __Log("dma%d c%x m%x q%x t%x s%x", i, p->chcr._u32, p->madr, p->qwc, p->tadr, p->sadr); } - __Log(L"dmac " + dmacRegs->ctrl.desc() + L" " + dmacRegs->stat.desc() + L" " + dmacRegs->rbsr.desc() + L" " + dmacRegs->rbor.desc()); + __Log(L"dmac " + dmacRegs.ctrl.desc() + L" " + dmacRegs.stat.desc() + L" " + dmacRegs.rbsr.desc() + L" " + dmacRegs.rbor.desc()); __Log(L"intc " + intcRegs->stat.desc() + L" " + intcRegs->mask.desc()); __Log("sif: %x %x %x %x %x", psHu32(SBUS_F200), psHu32(SBUS_F220), psHu32(SBUS_F230), psHu32(SBUS_F240), psHu32(SBUS_F260)); #endif diff --git a/pcsx2/FiFo.cpp b/pcsx2/FiFo.cpp index e2a9ff702e..fd5cc0fce8 100644 --- a/pcsx2/FiFo.cpp +++ b/pcsx2/FiFo.cpp @@ -28,8 +28,6 @@ /////////////////////////// Quick & dirty FIFO :D //////////////////////// ////////////////////////////////////////////////////////////////////////// -// ** NOTE: cannot use XMM/MMX regs ** - // Notes on FIFO implementation // // The FIFO consists of four separate pages of HW register memory, each mapped to a @@ -40,167 +38,108 @@ // 0x6000 - 0x7000 : GS (all registers map to 0x6000) // 0x7000 - 0x8000 : IPU (registers map to 0x7000 and 0x7010, respectively) -////////////////////////////////////////////////////////////////////////// -// ReadFIFO Pages - -void __fastcall ReadFIFO_page_4(u32 mem, mem128_t* out) +void __fastcall ReadFIFO_VIF1(mem128_t* out) { - pxAssert( (mem >= VIF0_FIFO) && (mem < VIF1_FIFO) ); - - VIF_LOG("ReadFIFO/VIF0 0x%08X", mem); - - CopyQWC( out, &psHu128(VIF0_FIFO) ); -} - -void __fastcall ReadFIFO_page_5(u32 mem, mem128_t* out) -{ - pxAssert( (mem >= VIF1_FIFO) && (mem < GIF_FIFO) ); - - VIF_LOG("ReadFIFO/VIF1, addr=0x%08X", mem); - - if (vif1Regs->stat.test(VIF1_STAT_INT | VIF1_STAT_VSS | VIF1_STAT_VIS | VIF1_STAT_VFS) ) + if (vif1Regs.stat.test(VIF1_STAT_INT | VIF1_STAT_VSS | VIF1_STAT_VIS | VIF1_STAT_VFS) ) DevCon.Warning( "Reading from vif1 fifo when stalled" ); - if(vif1Regs->stat.FQC == 0) Console.Warning("FQC = 0 on VIF FIFO READ!"); - if (vif1Regs->stat.FDR) + pxAssertRel(vif1Regs.stat.FQC != 0, "FQC = 0 on VIF FIFO READ!"); + if (vif1Regs.stat.FDR) { - if(vif1Regs->stat.FQC > vif1.GSLastDownloadSize) + if(vif1Regs.stat.FQC > vif1.GSLastDownloadSize) { DevCon.Warning("Warning! GS Download size < FIFO count!"); } - if (vif1Regs->stat.FQC > 0) + if (vif1Regs.stat.FQC > 0) { GetMTGS().WaitGS(); GSreadFIFO(&psHu64(VIF1_FIFO)); vif1.GSLastDownloadSize--; if (vif1.GSLastDownloadSize <= 16) - gifRegs->stat.OPH = false; - vif1Regs->stat.FQC = min((u32)16, vif1.GSLastDownloadSize); + gifRegs.stat.OPH = false; + vif1Regs.stat.FQC = min((u32)16, vif1.GSLastDownloadSize); } } CopyQWC( out, &psHu128(VIF1_FIFO) ); + VIF_LOG("ReadFIFO/VIF1 -> %ls", out->ToString().c_str()); } -void __fastcall ReadFIFO_page_6(u32 mem, mem128_t* out) -{ - pxAssert( (mem >= GIF_FIFO) && (mem < IPUout_FIFO) ); - - DevCon.Warning( "ReadFIFO/GIF, addr=0x%x", mem ); - - CopyQWC( out, &psHu128(GIF_FIFO) ); -} - -// ReadFIFO_page_7 is contained in IPU_Fifo.cpp - ////////////////////////////////////////////////////////////////////////// // WriteFIFO Pages - -void __fastcall WriteFIFO_page_4(u32 mem, const mem128_t *value) +// +void __fastcall WriteFIFO_VIF0(const mem128_t *value) { - pxAssert( (mem >= VIF0_FIFO) && (mem < VIF1_FIFO) ); - - VIF_LOG("WriteFIFO/VIF0, addr=0x%08X", mem); + VIF_LOG("WriteFIFO/VIF0 <- %ls", value->ToString().c_str()); CopyQWC(&psHu128(VIF0_FIFO), value); - vif0ch->qwc += 1; + vif0ch.qwc += 1; if(vif0.irqoffset != 0 && vif0.vifstalled == true) DevCon.Warning("Offset on VIF0 FIFO start!"); bool ret = VIF0transfer((u32*)value, 4); if (vif0.cmd) { - if(vif0.done == true && vif0ch->qwc == 0) vif0Regs->stat.VPS = VPS_WAITING; + if(vif0.done && vif0ch.qwc == 0) vif0Regs.stat.VPS = VPS_WAITING; } else { - vif0Regs->stat.VPS = VPS_IDLE; + vif0Regs.stat.VPS = VPS_IDLE; } pxAssertDev( ret, "vif stall code not implemented" ); } -void __fastcall WriteFIFO_page_5(u32 mem, const mem128_t *value) +void __fastcall WriteFIFO_VIF1(const mem128_t *value) { - pxAssert( (mem >= VIF1_FIFO) && (mem < GIF_FIFO) ); - - VIF_LOG("WriteFIFO/VIF1, addr=0x%08X", mem); + VIF_LOG("WriteFIFO/VIF1 <- %ls", value->ToString().c_str()); CopyQWC(&psHu128(VIF1_FIFO), value); - if (vif1Regs->stat.FDR) + if (vif1Regs.stat.FDR) DevCon.Warning("writing to fifo when fdr is set!"); - if (vif1Regs->stat.test(VIF1_STAT_INT | VIF1_STAT_VSS | VIF1_STAT_VIS | VIF1_STAT_VFS) ) + if (vif1Regs.stat.test(VIF1_STAT_INT | VIF1_STAT_VSS | VIF1_STAT_VIS | VIF1_STAT_VFS) ) DevCon.Warning("writing to vif1 fifo when stalled"); - vif1ch->qwc += 1; + vif1ch.qwc += 1; if(vif1.irqoffset != 0 && vif1.vifstalled == true) DevCon.Warning("Offset on VIF1 FIFO start!"); bool ret = VIF1transfer((u32*)value, 4); - if(GSTransferStatus.PTH2 == STOPPED_MODE && gifRegs->stat.APATH == GIF_APATH2) + if(GSTransferStatus.PTH2 == STOPPED_MODE && gifRegs.stat.APATH == GIF_APATH2) { - if(gifRegs->stat.DIR == 0)gifRegs->stat.OPH = false; - gifRegs->stat.APATH = GIF_APATH_IDLE; - if(gifRegs->stat.P1Q) gsPath1Interrupt(); + if(gifRegs.stat.DIR == 0)gifRegs.stat.OPH = false; + gifRegs.stat.APATH = GIF_APATH_IDLE; + if(gifRegs.stat.P1Q) gsPath1Interrupt(); } if (vif1.cmd) { - if(vif1.done == true && vif1ch->qwc == 0) vif1Regs->stat.VPS = VPS_WAITING; + if(vif1.done == true && vif1ch.qwc == 0) vif1Regs.stat.VPS = VPS_WAITING; } else { - vif1Regs->stat.VPS = VPS_IDLE; + vif1Regs.stat.VPS = VPS_IDLE; } pxAssertDev( ret, "vif stall code not implemented" ); } // Dummy GIF-TAG Packet to Guarantee Count = 1 -__aligned16 u32 nloop0_packet[4] = {0, 0, 0, 0}; +__aligned16 u128 nloop0_packet; -void __fastcall WriteFIFO_page_6(u32 mem, const mem128_t *value) +void __fastcall WriteFIFO_GIF(const mem128_t *value) { - pxAssert( (mem >= GIF_FIFO) && (mem < IPUout_FIFO) ); - GIF_LOG("WriteFIFO/GIF, addr=0x%08X", mem); + GIF_LOG("WriteFIFO/GIF <- %ls", value->ToString().c_str()); CopyQWC(&psHu128(GIF_FIFO), value); - CopyQWC(nloop0_packet, value); + CopyQWC(&nloop0_packet, value); GetMTGS().PrepDataPacket(GIF_PATH_3, 1); - GIFPath_CopyTag( GIF_PATH_3, (u128*)nloop0_packet, 1 ); + GIFPath_CopyTag( GIF_PATH_3, &nloop0_packet, 1 ); GetMTGS().SendDataPacket(); - if(GSTransferStatus.PTH3 == STOPPED_MODE && gifRegs->stat.APATH == GIF_APATH3 ) + if(GSTransferStatus.PTH3 == STOPPED_MODE && gifRegs.stat.APATH == GIF_APATH3 ) { - if(gifRegs->stat.DIR == 0)gifRegs->stat.OPH = false; - gifRegs->stat.APATH = GIF_APATH_IDLE; - if(gifRegs->stat.P1Q) gsPath1Interrupt(); - } -} - -void __fastcall WriteFIFO_page_7(u32 mem, const mem128_t *value) -{ - pxAssert( (mem >= IPUout_FIFO) && (mem < D0_CHCR) ); - - // All addresses in this page map to 0x7000 and 0x7010: - mem &= 0x10; - - IPU_LOG( "WriteFIFO, addr=0x%x", mem ); - - if( mem == 0 ) - { - // Should this raise a PS2 exception or just ignore silently? - Console.Warning( "WriteFIFO/IPUout (ignored)" ); - } - else - { - IPU_LOG("WriteFIFO in[%d] <- %8.8X_%8.8X_%8.8X_%8.8X", - mem/16, ((u32*)value)[3], ((u32*)value)[2], ((u32*)value)[1], ((u32*)value)[0]); - - //committing every 16 bytes - while( ipu_fifo.in.write((u32*)value, 1) == 0 ) - { - Console.WriteLn("IPU sleeping"); - Threading::Timeslice(); - } + if(gifRegs.stat.DIR == 0)gifRegs.stat.OPH = false; + gifRegs.stat.APATH = GIF_APATH_IDLE; + if(gifRegs.stat.P1Q) gsPath1Interrupt(); } } diff --git a/pcsx2/GS.cpp b/pcsx2/GS.cpp index 76fd624e98..cd38050cbc 100644 --- a/pcsx2/GS.cpp +++ b/pcsx2/GS.cpp @@ -56,9 +56,9 @@ extern u32 SIGNAL_Data_Pending[2]; void gsGIFReset() { - gifRegs->stat.reset(); - gifRegs->ctrl.reset(); - gifRegs->mode.reset(); + gifRegs.stat.reset(); + gifRegs.ctrl.reset(); + gifRegs.mode.reset(); } void gsReset() @@ -128,7 +128,7 @@ static __fi void gsCSRwrite( const tGS_CSR& csr ) SIGNAL_IMR_Pending = false; - if(gifRegs->stat.P1Q && gifRegs->stat.APATH <= GIF_APATH1) gsPath1Interrupt(); + if(gifRegs.stat.P1Q && gifRegs.stat.APATH <= GIF_APATH1) gsPath1Interrupt(); } if(csr.FINISH) CSRreg.FINISH = false; @@ -286,9 +286,9 @@ void __fastcall gsWrite64_page_01( u32 mem, const mem64_t* value ) //Only problem is it kills killzone :(. // (yes it *is* a complete hack; both lines here in fact --air) //========================================================================= - //gifRegs->stat.OPH = true; // Bleach wants it, Killzone hates it. + //gifRegs.stat.OPH = true; // Bleach wants it, Killzone hates it. - gifRegs->stat.DIR = (u32)value[0]; + gifRegs.stat.DIR = (u32)value[0]; //========================================================================= // BUSDIR INSANITY !! MTGS FLUSH NEEDED // @@ -459,9 +459,7 @@ void SaveStateBase::gsFreeze() { FreezeMem(PS2MEM_GS, 0x2000); Freeze(SIGNAL_IMR_Pending); - - if( GetVersion() > 0 ) - Freeze(gsRegionMode); + Freeze(gsRegionMode); gifPathFreeze(); } diff --git a/pcsx2/Gif.cpp b/pcsx2/Gif.cpp index 7329386dca..d3d2840451 100644 --- a/pcsx2/Gif.cpp +++ b/pcsx2/Gif.cpp @@ -54,9 +54,9 @@ void gsPath1Interrupt() - if((gifRegs->stat.APATH <= GIF_APATH1 || (gifRegs->stat.IP3 == true && gifRegs->stat.APATH == GIF_APATH3)) && Path1WritePos > 0 && !gifRegs->stat.PSE) + if((gifRegs.stat.APATH <= GIF_APATH1 || (gifRegs.stat.IP3 == true && gifRegs.stat.APATH == GIF_APATH3)) && Path1WritePos > 0 && !gifRegs.stat.PSE) { - gifRegs->stat.P1Q = false; + gifRegs.stat.P1Q = false; if (uint size = (Path1WritePos - Path1ReadPos)) { @@ -70,8 +70,8 @@ void gsPath1Interrupt() if(GSTransferStatus.PTH1 == STOPPED_MODE) { - gifRegs->stat.OPH = false; - gifRegs->stat.APATH = GIF_APATH_IDLE; + gifRegs.stat.OPH = false; + gifRegs.stat.APATH = GIF_APATH_IDLE; } } GetMTGS().SendDataPacket(); @@ -84,8 +84,8 @@ void gsPath1Interrupt() } else { - if(gifRegs->stat.PSE) DevCon.Warning("Path1 paused by GIF_CTRL"); - DevCon.Warning("Looping??? IP3 %x APATH %x OPH %x", gifRegs->stat.IP3, gifRegs->stat.APATH, gifRegs->stat.OPH); + if(gifRegs.stat.PSE) DevCon.Warning("Path1 paused by GIF_CTRL"); + DevCon.Warning("Looping??? IP3 %x APATH %x OPH %x", gifRegs.stat.IP3, gifRegs.stat.APATH, gifRegs.stat.OPH); //if(!(cpuRegs.interrupt & (1<<28)) && Path1WritePos > 0)CPU_INT(28, 128); } @@ -104,25 +104,25 @@ __fi void gsInterrupt() return; } - if(GSTransferStatus.PTH3 >= PENDINGSTOP_MODE && gifRegs->stat.APATH == GIF_APATH3 ) + if(GSTransferStatus.PTH3 >= PENDINGSTOP_MODE && gifRegs.stat.APATH == GIF_APATH3 ) { - gifRegs->stat.OPH = false; + gifRegs.stat.OPH = false; GSTransferStatus.PTH3 = STOPPED_MODE; - gifRegs->stat.APATH = GIF_APATH_IDLE; - if(gifRegs->stat.P1Q) gsPath1Interrupt(); + gifRegs.stat.APATH = GIF_APATH_IDLE; + if(gifRegs.stat.P1Q) gsPath1Interrupt(); } - if (!(gif->chcr.STR)) + if (!(gifch.chcr.STR)) { - //Console.WriteLn("Eh? why are you still interrupting! chcr %x, qwc %x, done = %x", gif->chcr._u32, gif->qwc, done); + //Console.WriteLn("Eh? why are you still interrupting! chcr %x, qwc %x, done = %x", gifch.chcr._u32, gifch.qwc, done); return; } - if ((gif->qwc > 0) || (!gspath3done)) + if ((gifch.qwc > 0) || (!gspath3done)) { - if (!dmacRegs->ctrl.DMAE) + if (!dmacRegs.ctrl.DMAE) { Console.Warning("gs dma masked, re-scheduling..."); // re-raise the int shortly in the future @@ -136,14 +136,14 @@ __fi void gsInterrupt() gspath3done = false; gscycles = 0; - gif->chcr.STR = false; + gifch.chcr.STR = false; //// - /*gifRegs->stat.OPH = false; + /*gifRegs.stat.OPH = false; GSTransferStatus.PTH3 = STOPPED_MODE; - gifRegs->stat.APATH = GIF_APATH_IDLE;*/ + gifRegs.stat.APATH = GIF_APATH_IDLE;*/ //// - gifRegs->stat.clear_flags(GIF_STAT_FQC); + gifRegs.stat.clear_flags(GIF_STAT_FQC); clearFIFOstuff(false); hwDmacIrq(DMAC_GIF); //DevCon.Warning("GIF DMA end"); @@ -166,20 +166,20 @@ int _GIFchain() { tDMA_TAG *pMem; - pMem = dmaGetAddr(gif->madr, false); + pMem = dmaGetAddr(gifch.madr, false); if (pMem == NULL) { // reset path3, fixes dark cloud 2 GIFPath_Clear( GIF_PATH_3 ); //must increment madr and clear qwc, else it loops - gif->madr += gif->qwc * 16; - gif->qwc = 0; + gifch.madr += gifch.qwc * 16; + gifch.qwc = 0; Console.Warning( "Hackfix - NULL GIFchain" ); return -1; } - return WRITERING_DMA(pMem, gif->qwc); + return WRITERING_DMA(pMem, gifch.qwc); } static __fi void GIFchain() @@ -187,12 +187,12 @@ static __fi void GIFchain() // qwc check now done outside this function // Voodoocycles // >> 2 so Drakan and Tekken 5 don't mess up in some PATH3 transfer. Cycles to interrupt were getting huge.. - /*if (gif->qwc)*/ gscycles+= ( _GIFchain() * BIAS); /* guessing */ + /*if (gifch.qwc)*/ gscycles+= ( _GIFchain() * BIAS); /* guessing */ } static __fi bool checkTieBit(tDMA_TAG* &ptag) { - if (gif->chcr.TIE && ptag->IRQ) + if (gifch.chcr.TIE && ptag->IRQ) { GIF_LOG("dmaIrq Set"); gspath3done = true; @@ -204,38 +204,38 @@ static __fi bool checkTieBit(tDMA_TAG* &ptag) static __fi tDMA_TAG* ReadTag() { - tDMA_TAG* ptag = dmaGetAddr(gif->tadr, false); //Set memory pointer to TADR + tDMA_TAG* ptag = dmaGetAddr(gifch.tadr, false); //Set memory pointer to TADR - if (!(gif->transfer("Gif", ptag))) return NULL; + if (!(gifch.transfer("Gif", ptag))) return NULL; - gif->madr = ptag[1]._u32; //MADR = ADDR field + SPR + gifch.madr = ptag[1]._u32; //MADR = ADDR field + SPR gscycles += 2; // Add 1 cycles from the QW read for the tag - gspath3done = hwDmacSrcChainWithStack(gif, ptag->ID); + gspath3done = hwDmacSrcChainWithStack(gifch, ptag->ID); return ptag; } static __fi tDMA_TAG* ReadTag2() { - tDMA_TAG* ptag = dmaGetAddr(gif->tadr, false); //Set memory pointer to TADR + tDMA_TAG* ptag = dmaGetAddr(gifch.tadr, false); //Set memory pointer to TADR - gif->unsafeTransfer(ptag); - gif->madr = ptag[1]._u32; + gifch.unsafeTransfer(ptag); + gifch.madr = ptag[1]._u32; - gspath3done = hwDmacSrcChainWithStack(gif, ptag->ID); + gspath3done = hwDmacSrcChainWithStack(gifch, ptag->ID); return ptag; } bool CheckPaths(int Channel) { - if(GSTransferStatus.PTH3 <= IMAGE_MODE && gifRegs->mode.IMT) + if(GSTransferStatus.PTH3 <= IMAGE_MODE && gifRegs.mode.IMT) { - if((gifRegs->stat.P1Q == true || gifRegs->stat.P2Q == true) || (gifRegs->stat.APATH > GIF_APATH_IDLE && gifRegs->stat.APATH < GIF_APATH3)) + if((gifRegs.stat.P1Q == true || gifRegs.stat.P2Q == true) || (gifRegs.stat.APATH > GIF_APATH_IDLE && gifRegs.stat.APATH < GIF_APATH3)) { - if((vif1.cmd & 0x7f) != 0x51 || gifRegs->stat.P1Q == true) + if((vif1.cmd & 0x7f) != 0x51 || gifRegs.stat.P1Q == true) { - gifRegs->stat.IP3 = true; - if(gifRegs->stat.P1Q) gsPath1Interrupt(); + gifRegs.stat.IP3 = true; + if(gifRegs.stat.P1Q) gsPath1Interrupt(); CPU_INT(DMAC_GIF, 16); return false; } @@ -244,15 +244,15 @@ bool CheckPaths(int Channel) else if((GSTransferStatus.PTH3 == IDLE_MODE)|| (GSTransferStatus.PTH3 == STOPPED_MODE)) { //This should cover both scenarios, as DIRECTHL doesn't gain priority when image mode is running (PENDINGIMAGE_MODE == fininshed). - if((gifRegs->stat.P1Q == true || gifRegs->stat.P2Q == true) || (gifRegs->stat.APATH > GIF_APATH_IDLE && gifRegs->stat.APATH < GIF_APATH3)) + if((gifRegs.stat.P1Q == true || gifRegs.stat.P2Q == true) || (gifRegs.stat.APATH > GIF_APATH_IDLE && gifRegs.stat.APATH < GIF_APATH3)) { - gifRegs->stat.IP3 = true; + gifRegs.stat.IP3 = true; CPU_INT(DMAC_GIF, 16); return false; } } - gifRegs->stat.IP3 = false; + gifRegs.stat.IP3 = false; return true; } @@ -262,18 +262,18 @@ void GIFdma() gscycles = prevcycles; - if (gifRegs->ctrl.PSE) // temporarily stop + if (gifRegs.ctrl.PSE) // temporarily stop { Console.WriteLn("Gif dma temp paused? (non MFIFO GIF)"); CPU_INT(DMAC_GIF, 16); return; } - if ((dmacRegs->ctrl.STD == STD_GIF) && (prevcycles != 0)) + if ((dmacRegs.ctrl.STD == STD_GIF) && (prevcycles != 0)) { - //Console.WriteLn("GS Stall Control Source = %x, Drain = %x\n MADR = %x, STADR = %x", (psHu32(0xe000) >> 4) & 0x3, (psHu32(0xe000) >> 6) & 0x3, gif->madr, psHu32(DMAC_STADR)); + //Console.WriteLn("GS Stall Control Source = %x, Drain = %x\n MADR = %x, STADR = %x", (psHu32(0xe000) >> 4) & 0x3, (psHu32(0xe000) >> 6) & 0x3, gifch.madr, psHu32(DMAC_STADR)); - if ((gif->madr + (gif->qwc * 16)) > dmacRegs->stadr.ADDR) + if ((gifch.madr + (gifch.qwc * 16)) > dmacRegs.stadr.ADDR) { CPU_INT(DMAC_GIF, 4); gscycles = 0; @@ -281,24 +281,24 @@ void GIFdma() } prevcycles = 0; - gif->qwc = 0; + gifch.qwc = 0; } clearFIFOstuff(true); - gifRegs->stat.FQC = min((u16)0x10, gif->qwc);// FQC=31, hack ;) (for values of 31 that equal 16) [ used to be 0xE00; // APATH=3] + gifRegs.stat.FQC = min((u16)0x10, gifch.qwc);// FQC=31, hack ;) (for values of 31 that equal 16) [ used to be 0xE00; // APATH=3] - if (vif1Regs->mskpath3 || gifRegs->mode.M3R) + if (vif1Regs.mskpath3 || gifRegs.mode.M3R) { - if (gif->qwc == 0) + if (gifch.qwc == 0) { - if ((gif->chcr.MOD == CHAIN_MODE) && gif->chcr.STR) + if ((gifch.chcr.MOD == CHAIN_MODE) && gifch.chcr.STR) { - //DevCon.Warning("GIF Reading Tag Masked MSK = %x", vif1Regs->mskpath3); + //DevCon.Warning("GIF Reading Tag Masked MSK = %x", vif1Regs.mskpath3); ptag = ReadTag(); - gifRegs->stat.FQC = min((u16)0x10, gif->qwc);// FQC=31, hack ;) (for values of 31 that equal 16) [ used to be 0xE00; // APATH=3] + gifRegs.stat.FQC = min((u16)0x10, gifch.qwc);// FQC=31, hack ;) (for values of 31 that equal 16) [ used to be 0xE00; // APATH=3] if (ptag == NULL) return; - GIF_LOG("PTH3 MASK gifdmaChain %8.8x_%8.8x size=%d, id=%d, addr=%lx tadr=%lx", ptag[1]._u32, ptag[0]._u32, gif->qwc, ptag->ID, gif->madr, gif->tadr); + GIF_LOG("PTH3 MASK gifdmaChain %8.8x_%8.8x size=%d, id=%d, addr=%lx tadr=%lx", ptag[1]._u32, ptag[0]._u32, gifch.qwc, ptag->ID, gifch.madr, gifch.tadr); //Check TIE bit of CHCR and IRQ bit of tag if (checkTieBit(ptag)) GIF_LOG("PATH3 MSK dmaIrq Set"); @@ -308,26 +308,26 @@ void GIFdma() if (GSTransferStatus.PTH3 == IDLE_MODE) { - GIF_LOG("PTH3 MASK Paused by VIF QWC %x", gif->qwc); + GIF_LOG("PTH3 MASK Paused by VIF QWC %x", gifch.qwc); - //DevCon.Warning("GIF Paused by Mask MSK = %x", vif1Regs->mskpath3); + //DevCon.Warning("GIF Paused by Mask MSK = %x", vif1Regs.mskpath3); - if(gif->qwc == 0) gsInterrupt(); - else gifRegs->stat.set_flags(GIF_STAT_P3Q); + if(gifch.qwc == 0) gsInterrupt(); + else gifRegs.stat.set_flags(GIF_STAT_P3Q); return; } - gifRegs->stat.FQC = min((u16)0x10, gif->qwc);// FQC=31, hack ;) (for values of 31 that equal 16) [ used to be 0xE00; // APATH=3] + gifRegs.stat.FQC = min((u16)0x10, gifch.qwc);// FQC=31, hack ;) (for values of 31 that equal 16) [ used to be 0xE00; // APATH=3] //Check with Path3 masking games - if (gif->qwc > 0) { - gifRegs->stat.set_flags(GIF_STAT_P3Q); + if (gifch.qwc > 0) { + gifRegs.stat.set_flags(GIF_STAT_P3Q); if(CheckPaths(DMAC_GIF) == false) return; - gifRegs->stat.clear_flags(GIF_STAT_P3Q); + gifRegs.stat.clear_flags(GIF_STAT_P3Q); GIF_LOG("PTH3 MASK Transferring"); GIFchain(); - /*if(GSTransferStatus.PTH3 == PENDINGSTOP_MODE && gifRegs->stat.APATH == GIF_APATH_IDLE) + /*if(GSTransferStatus.PTH3 == PENDINGSTOP_MODE && gifRegs.stat.APATH == GIF_APATH_IDLE) { GSTransferStatus.PTH3 = STOPPED_MODE; }*/ @@ -338,54 +338,54 @@ void GIFdma() } // Transfer Dn_QWC from Dn_MADR to GIF - if ((gif->chcr.MOD == NORMAL_MODE) || (gif->qwc > 0)) // Normal Mode + if ((gifch.chcr.MOD == NORMAL_MODE) || (gifch.qwc > 0)) // Normal Mode { - if ((dmacRegs->ctrl.STD == STD_GIF) && (gif->chcr.MOD == NORMAL_MODE)) + if ((dmacRegs.ctrl.STD == STD_GIF) && (gifch.chcr.MOD == NORMAL_MODE)) { //Console.WriteLn("DMA Stall Control on GIF normal"); } - gifRegs->stat.FQC = min((u16)0x10, gif->qwc);// FQC=31, hack ;) (for values of 31 that equal 16) [ used to be 0xE00; // APATH=3] + gifRegs.stat.FQC = min((u16)0x10, gifch.qwc);// FQC=31, hack ;) (for values of 31 that equal 16) [ used to be 0xE00; // APATH=3] //Check with Path3 masking games - //DevCon.Warning("GIF Transferring Normal/ChainQWC MSK = %x", vif1Regs->mskpath3); + //DevCon.Warning("GIF Transferring Normal/ChainQWC MSK = %x", vif1Regs.mskpath3); - if (gif->qwc > 0) { - gifRegs->stat.set_flags(GIF_STAT_P3Q); + if (gifch.qwc > 0) { + gifRegs.stat.set_flags(GIF_STAT_P3Q); if(CheckPaths(DMAC_GIF) == false) return; - gifRegs->stat.clear_flags(GIF_STAT_P3Q); + gifRegs.stat.clear_flags(GIF_STAT_P3Q); GIFchain(); //Transfers the data set by the switch CPU_INT(DMAC_GIF, gscycles); return; - } else DevCon.Warning("GIF Normalmode or QWC going to invalid case? CHCR %x", gif->chcr._u32); + } else DevCon.Warning("GIF Normalmode or QWC going to invalid case? CHCR %x", gifch.chcr._u32); //else DevCon.WriteLn("GIFdma() case 2, but qwc = 0!"); //Don't do 0 GIFchain and then return, fixes Dual Hearts } - if ((gif->chcr.MOD == CHAIN_MODE) && (!gspath3done)) // Chain Mode + if ((gifch.chcr.MOD == CHAIN_MODE) && (!gspath3done)) // Chain Mode { ptag = ReadTag(); if (ptag == NULL) return; - //DevCon.Warning("GIF Reading Tag MSK = %x", vif1Regs->mskpath3); - GIF_LOG("gifdmaChain %8.8x_%8.8x size=%d, id=%d, addr=%lx tadr=%lx", ptag[1]._u32, ptag[0]._u32, gif->qwc, ptag->ID, gif->madr, gif->tadr); - gifRegs->stat.FQC = min((u16)0x10, gif->qwc);// FQC=31, hack ;) (for values of 31 that equal 16) [ used to be 0xE00; // APATH=3] - if (dmacRegs->ctrl.STD == STD_GIF) + //DevCon.Warning("GIF Reading Tag MSK = %x", vif1Regs.mskpath3); + GIF_LOG("gifdmaChain %8.8x_%8.8x size=%d, id=%d, addr=%lx tadr=%lx", ptag[1]._u32, ptag[0]._u32, gifch.qwc, ptag->ID, gifch.madr, gifch.tadr); + gifRegs.stat.FQC = min((u16)0x10, gifch.qwc);// FQC=31, hack ;) (for values of 31 that equal 16) [ used to be 0xE00; // APATH=3] + if (dmacRegs.ctrl.STD == STD_GIF) { - // there are still bugs, need to also check if gif->madr +16*qwc >= stadr, if not, stall - if (!gspath3done && ((gif->madr + (gif->qwc * 16)) > dmacRegs->stadr.ADDR) && (ptag->ID == TAG_REFS)) + // there are still bugs, need to also check if gifch.madr +16*qwc >= stadr, if not, stall + if (!gspath3done && ((gifch.madr + (gifch.qwc * 16)) > dmacRegs.stadr.ADDR) && (ptag->ID == TAG_REFS)) { // stalled. // We really need to test this. Pay attention to prevcycles, as it used to trigger GIFchains in the code above. (rama) - //Console.WriteLn("GS Stall Control start Source = %x, Drain = %x\n MADR = %x, STADR = %x", (psHu32(0xe000) >> 4) & 0x3, (psHu32(0xe000) >> 6) & 0x3,gif->madr, psHu32(DMAC_STADR)); + //Console.WriteLn("GS Stall Control start Source = %x, Drain = %x\n MADR = %x, STADR = %x", (psHu32(0xe000) >> 4) & 0x3, (psHu32(0xe000) >> 6) & 0x3,gifch.madr, psHu32(DMAC_STADR)); prevcycles = gscycles; - //gif->tadr -= 16; + //gifch.tadr -= 16; // Quake III revolution wants to see tadr move. // Simple Media System (homebrew) as well. // -16 also seems right (it shifts the bg image right if anything else). - gif->tadr -= 16; + gifch.tadr -= 16; // Next line also needs to be here, according to ref - gif->qwc = 0; + gifch.qwc = 0; hwDmacIrq(DMAC_STALL_SIS); CPU_INT(DMAC_GIF, gscycles); gscycles = 0; @@ -394,7 +394,7 @@ void GIFdma() } checkTieBit(ptag); - /*if(gif->qwc == 0) + /*if(gifch.qwc == 0) { gsInterrupt(); return; @@ -403,34 +403,34 @@ void GIFdma() prevcycles = 0; CPU_INT(DMAC_GIF, gscycles); - gifRegs->stat.FQC = min((u16)0x10, gif->qwc);// FQC=31, hack ;) (for values of 31 that equal 16) [ used to be 0xE00; // OPH=1 | APATH=3] + gifRegs.stat.FQC = min((u16)0x10, gifch.qwc);// FQC=31, hack ;) (for values of 31 that equal 16) [ used to be 0xE00; // OPH=1 | APATH=3] } void dmaGIF() { //We used to add wait time for the buffer to fill here, fixing some timing problems in path 3 masking //It takes the time of 24 QW for the BUS to become ready - The Punisher And Streetball - //DevCon.Warning("dmaGIFstart chcr = %lx, madr = %lx, qwc = %lx\n tadr = %lx, asr0 = %lx, asr1 = %lx", gif->chcr._u32, gif->madr, gif->qwc, gif->tadr, gif->asr0, gif->asr1); + //DevCon.Warning("dmaGIFstart chcr = %lx, madr = %lx, qwc = %lx\n tadr = %lx, asr0 = %lx, asr1 = %lx", gifch.chcr._u32, gifch.madr, gifch.qwc, gifch.tadr, gifch.asr0, gifch.asr1); gspath3done = false; // For some reason this doesn't clear? So when the system starts the thread, we will clear it :) - gifRegs->stat.FQC |= 0x10; // hack ;) + gifRegs.stat.FQC |= 0x10; // hack ;) - if (gif->chcr.MOD == NORMAL_MODE) { //Else it really is a normal transfer and we want to quit, else it gets confused with chains + if (gifch.chcr.MOD == NORMAL_MODE) { //Else it really is a normal transfer and we want to quit, else it gets confused with chains gspath3done = true; } clearFIFOstuff(true); - if(gif->chcr.MOD == CHAIN_MODE && gif->qwc > 0) + if(gifch.chcr.MOD == CHAIN_MODE && gifch.qwc > 0) { - //DevCon.Warning(L"GIF QWC on Chain " + gif->chcr.desc()); - if ((gif->chcr.tag().ID == TAG_REFE) || (gif->chcr.tag().ID == TAG_END)) + //DevCon.Warning(L"GIF QWC on Chain " + gifch.chcr.desc()); + if ((gifch.chcr.tag().ID == TAG_REFE) || (gifch.chcr.tag().ID == TAG_END)) { gspath3done = true; } } - if (dmacRegs->ctrl.MFD == MFD_GIF) // GIF MFIFO + if (dmacRegs.ctrl.MFD == MFD_GIF) // GIF MFIFO { //Console.WriteLn("GIF MFIFO"); gifMFIFOInterrupt(); @@ -443,7 +443,7 @@ void dmaGIF() // called from only one location, so forceinline it: static __fi bool mfifoGIFrbTransfer() { - u32 mfifoqwc = min(gifqwc, (u32)gif->qwc); + u32 mfifoqwc = min(gifqwc, (u32)gifch.qwc); u32 *src; GetMTGS().PrepDataPacket(GIF_PATH_3, mfifoqwc); @@ -453,21 +453,21 @@ static __fi bool mfifoGIFrbTransfer() // memory similarly to how it wraps VU1 memory on PATH1. /* Check if the transfer should wrap around the ring buffer */ - if ((gif->madr + mfifoqwc * 16) > (dmacRegs->rbor.ADDR + dmacRegs->rbsr.RMSK + 16)) + if ((gifch.madr + mfifoqwc * 16) > (dmacRegs.rbor.ADDR + dmacRegs.rbsr.RMSK + 16)) { - uint s1 = ((dmacRegs->rbor.ADDR + dmacRegs->rbsr.RMSK + 16) - gif->madr) >> 4; + uint s1 = ((dmacRegs.rbor.ADDR + dmacRegs.rbsr.RMSK + 16) - gifch.madr) >> 4; uint s2 = (mfifoqwc - s1); /* it does (wrap around), so first copy 's1' bytes from 'addr' to 'data' */ /* and second copy 's2' bytes from 'maddr' to '&data[s1]' */ - src = (u32*)PSM(gif->madr); + src = (u32*)PSM(gifch.madr); if (src == NULL) return false; uint copied = GIFPath_CopyTag(GIF_PATH_3, (u128*)src, s1); if (copied == s1) // but only copy second if first didn't abort prematurely for some reason. { - src = (u32*)PSM(dmacRegs->rbor.ADDR); + src = (u32*)PSM(dmacRegs.rbor.ADDR); if (src == NULL) return false; copied += GIFPath_CopyTag(GIF_PATH_3, (u128*)src, s2); } @@ -476,11 +476,11 @@ static __fi bool mfifoGIFrbTransfer() } else { - /* it doesn't, so just transfer 'qwc*16' words from 'gif->madr' to GS */ - src = (u32*)PSM(gif->madr); + /* it doesn't, so just transfer 'qwc*16' words from 'gifch.madr' to GS */ + src = (u32*)PSM(gifch.madr); if (src == NULL) return false; mfifoqwc = GIFPath_CopyTag(GIF_PATH_3, (u128*)src, mfifoqwc); - gif->madr = dmacRegs->rbor.ADDR + (gif->madr & dmacRegs->rbsr.RMSK); + gifch.madr = dmacRegs.rbor.ADDR + (gifch.madr & dmacRegs.rbsr.RMSK); } GetMTGS().SendDataPacket(); @@ -493,10 +493,10 @@ static __fi bool mfifoGIFrbTransfer() static __fi bool mfifoGIFchain() { /* Is QWC = 0? if so there is nothing to transfer */ - if (gif->qwc == 0) return true; + if (gifch.qwc == 0) return true; - if (gif->madr >= dmacRegs->rbor.ADDR && - gif->madr <= (dmacRegs->rbor.ADDR + dmacRegs->rbsr.RMSK)) + if (gifch.madr >= dmacRegs.rbor.ADDR && + gifch.madr <= (dmacRegs.rbor.ADDR + dmacRegs.rbsr.RMSK)) { if (!mfifoGIFrbTransfer()) return false; } @@ -504,10 +504,10 @@ static __fi bool mfifoGIFchain() { int mfifoqwc; - tDMA_TAG *pMem = dmaGetAddr(gif->madr, false); + tDMA_TAG *pMem = dmaGetAddr(gifch.madr, false); if (pMem == NULL) return false; - mfifoqwc = WRITERING_DMA(pMem, gif->qwc); + mfifoqwc = WRITERING_DMA(pMem, gifch.qwc); mfifocycles += (mfifoqwc) * 2; /* guessing */ } @@ -516,7 +516,7 @@ static __fi bool mfifoGIFchain() static u32 qwctag(u32 mask) { - return (dmacRegs->rbor.ADDR + (mask & dmacRegs->rbsr.RMSK)); + return (dmacRegs.rbor.ADDR + (mask & dmacRegs.rbsr.RMSK)); } void mfifoGIFtransfer(int qwc) @@ -536,16 +536,16 @@ void mfifoGIFtransfer(int qwc) gifempty = false; } - if (gifRegs->ctrl.PSE) // temporarily stop + if (gifRegs.ctrl.PSE) // temporarily stop { Console.WriteLn("Gif dma temp paused?"); CPU_INT(DMAC_MFIFO_GIF, 16); return; } - if (gif->qwc == 0) + if (gifch.qwc == 0) { - if (gif->tadr == spr0->madr) + if (gifch.tadr == spr0ch.madr) { //if( gifqwc > 1 ) DevCon.WriteLn("gif mfifo tadr==madr but qwc = %d", gifqwc); hwDmacIrq(DMAC_MFIFO_EMPTY); @@ -554,55 +554,55 @@ void mfifoGIFtransfer(int qwc) return; } - gif->tadr = qwctag(gif->tadr); + gifch.tadr = qwctag(gifch.tadr); - ptag = dmaGetAddr(gif->tadr, false); - gif->unsafeTransfer(ptag); - gif->madr = ptag[1]._u32; + ptag = dmaGetAddr(gifch.tadr, false); + gifch.unsafeTransfer(ptag); + gifch.madr = ptag[1]._u32; mfifocycles += 2; GIF_LOG("dmaChain %8.8x_%8.8x size=%d, id=%d, madr=%lx, tadr=%lx mfifo qwc = %x spr0 madr = %x", - ptag[1]._u32, ptag[0]._u32, gif->qwc, ptag->ID, gif->madr, gif->tadr, gifqwc, spr0->madr); + ptag[1]._u32, ptag[0]._u32, gifch.qwc, ptag->ID, gifch.madr, gifch.tadr, gifqwc, spr0ch.madr); gifqwc--; switch (ptag->ID) { case TAG_REFE: // Refe - Transfer Packet According to ADDR field - gif->tadr = qwctag(gif->tadr + 16); + gifch.tadr = qwctag(gifch.tadr + 16); gifstate = GIF_STATE_DONE; //End Transfer break; case TAG_CNT: // CNT - Transfer QWC following the tag. - gif->madr = qwctag(gif->tadr + 16); //Set MADR to QW after Tag - gif->tadr = qwctag(gif->madr + (gif->qwc << 4)); //Set TADR to QW following the data + gifch.madr = qwctag(gifch.tadr + 16); //Set MADR to QW after Tag + gifch.tadr = qwctag(gifch.madr + (gifch.qwc << 4)); //Set TADR to QW following the data gifstate = GIF_STATE_READY; break; case TAG_NEXT: // Next - Transfer QWC following tag. TADR = 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 + u32 temp = gifch.madr; //Temporarily Store ADDR + gifch.madr = qwctag(gifch.tadr + 16); //Set MADR to QW following the tag + gifch.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) - gif->tadr = qwctag(gif->tadr + 16); //Set TADR to next tag + gifch.tadr = qwctag(gifch.tadr + 16); //Set TADR to next tag gifstate = GIF_STATE_READY; break; case TAG_END: // End - Transfer QWC following the tag - gif->madr = qwctag(gif->tadr + 16); //Set MADR to data following the tag - gif->tadr = qwctag(gif->madr + (gif->qwc << 4)); //Set TADR to QW following the data + gifch.madr = qwctag(gifch.tadr + 16); //Set MADR to data following the tag + gifch.tadr = qwctag(gifch.madr + (gifch.qwc << 4)); //Set TADR to QW following the data gifstate = GIF_STATE_DONE; //End Transfer break; } - if ((gif->chcr.TIE) && (ptag->IRQ)) + if ((gifch.chcr.TIE) && (ptag->IRQ)) { SPR_LOG("dmaIrq Set"); gifstate = GIF_STATE_DONE; @@ -612,14 +612,14 @@ void mfifoGIFtransfer(int qwc) if (!mfifoGIFchain()) { - Console.WriteLn("GIF dmaChain error size=%d, madr=%lx, tadr=%lx", gif->qwc, gif->madr, gif->tadr); + Console.WriteLn("GIF dmaChain error size=%d, madr=%lx, tadr=%lx", gifch.qwc, gifch.madr, gifch.tadr); gifstate = GIF_STATE_STALL; } - if ((gif->qwc == 0) && (gifstate & GIF_STATE_DONE)) gifstate = GIF_STATE_STALL; + if ((gifch.qwc == 0) && (gifstate & GIF_STATE_DONE)) gifstate = GIF_STATE_STALL; CPU_INT(DMAC_MFIFO_GIF,mfifocycles); - SPR_LOG("mfifoGIFtransfer end %x madr %x, tadr %x", gif->chcr._u32, gif->madr, gif->tadr); + SPR_LOG("mfifoGIFtransfer end %x madr %x, tadr %x", gifch.chcr._u32, gifch.madr, gifch.tadr); } void gifMFIFOInterrupt() @@ -634,16 +634,16 @@ void gifMFIFOInterrupt() return; } - if(GSTransferStatus.PTH3 == STOPPED_MODE && gifRegs->stat.APATH == GIF_APATH3 ) + if(GSTransferStatus.PTH3 == STOPPED_MODE && gifRegs.stat.APATH == GIF_APATH3 ) { - gifRegs->stat.OPH = false; - gifRegs->stat.APATH = GIF_APATH_IDLE; - if(gifRegs->stat.P1Q) gsPath1Interrupt(); + gifRegs.stat.OPH = false; + gifRegs.stat.APATH = GIF_APATH_IDLE; + if(gifRegs.stat.P1Q) gsPath1Interrupt(); } if(CheckPaths(11) == false) return; - if (!(gif->chcr.STR)) + if (!(gifch.chcr.STR)) { Console.WriteLn("WTF GIFMFIFO"); cpuRegs.interrupt &= ~(1 << 11); @@ -659,7 +659,7 @@ void gifMFIFOInterrupt() gifstate |= GIF_STATE_EMPTY; gifempty = true; - gifRegs->stat.IMT = false; + gifRegs.stat.IMT = false; return; } mfifoGIFtransfer(0); @@ -667,7 +667,7 @@ void gifMFIFOInterrupt() } #ifdef PCSX2_DEVBUILD - if ((gifstate & GIF_STATE_READY) || (gif->qwc > 0)) + if ((gifstate & GIF_STATE_READY) || (gifch.qwc > 0)) { Console.Error("gifMFIFO Panic > Shouldn't go here!"); return; @@ -679,10 +679,10 @@ void gifMFIFOInterrupt() gspath3done = false; gscycles = 0; - gifRegs->stat.clear_flags(GIF_STAT_APATH3 | GIF_STAT_P3Q | GIF_STAT_FQC); // APATH, P3Q, FQC = 0 + gifRegs.stat.clear_flags(GIF_STAT_APATH3 | GIF_STAT_P3Q | GIF_STAT_FQC); // APATH, P3Q, FQC = 0 - vif1Regs->stat.VGW = false; - gif->chcr.STR = false; + vif1Regs.stat.VGW = false; + gifch.chcr.STR = false; gifstate = GIF_STATE_READY; hwDmacIrq(DMAC_GIF); clearFIFOstuff(false); diff --git a/pcsx2/Gif.h b/pcsx2/Gif.h index dc4f0b7582..6a03820659 100644 --- a/pcsx2/Gif.h +++ b/pcsx2/Gif.h @@ -277,7 +277,7 @@ struct GIFregisters u32 padding9[3]; }; -#define gifRegs ((GIFregisters*)(eeMem->HW+0x3000)) +static GIFregisters& gifRegs = (GIFregisters&)eeHw[0x3000]; extern tGSTransferStatus GSTransferStatus; diff --git a/pcsx2/Hw.cpp b/pcsx2/Hw.cpp index f7720ae2e9..44a0003d6a 100644 --- a/pcsx2/Hw.cpp +++ b/pcsx2/Hw.cpp @@ -18,6 +18,7 @@ #include "Hardware.h" #include "newVif.h" +#include "IPU/IPUdma.h" using namespace R5900; @@ -45,17 +46,12 @@ void hwInit() hwInitialized = true; } -/*void hwShutdown() -{ - ipuShutdown(); -}*/ - void hwReset() { hwInit(); - memzero_ptr( eeMem->HW ); - //memset(eeMem->HW+0x2000, 0, 0x0000e000); + memzero_ptr( eeHw ); + //memset(eeHw+0x2000, 0, 0x0000e000); psHu32(SBUS_F260) = 0x1D000060; @@ -72,6 +68,9 @@ void hwReset() ipuReset(); vif0Reset(); vif1Reset(); + + // needed for legacy DMAC + ipuDmaReset(); } __fi void intcInterrupt() @@ -104,7 +103,7 @@ __fi void dmacInterrupt() return; } - if (!(dmacRegs->ctrl.DMAE) || psHu8(DMAC_ENABLER+2) == 1) + if (!(dmacRegs.ctrl.DMAE) || psHu8(DMAC_ENABLER+2) == 1) { //DevCon.Warning("DMAC Suspended or Disabled on interrupt"); return; @@ -131,7 +130,7 @@ void hwDmacIrq(int n) __ri bool hwMFIFOWrite(u32 addr, const u128* data, uint qwc) { // all FIFO addresses should always be QWC-aligned. - pxAssume((dmacRegs->rbor.ADDR & 15) == 0); + pxAssume((dmacRegs.rbor.ADDR & 15) == 0); pxAssume((addr & 15) == 0); // DMAC Address resolution: FIFO can be placed anywhere in the *physical* memory map @@ -139,24 +138,24 @@ __ri bool hwMFIFOWrite(u32 addr, const u128* data, uint qwc) // valid/invalid page areas of ram, so realistically we only need to test the base address // of the FIFO for address validity. - if (u128* dst = (u128*)PSM(dmacRegs->rbor.ADDR)) + 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; + 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 { - 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) ); + 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; } -__ri bool hwDmacSrcChainWithStack(DMACh *dma, int id) { +__ri bool hwDmacSrcChainWithStack(DMACh& dma, int id) { switch (id) { case TAG_REFE: // Refe - Transfer Packet According to ADDR field //End Transfer @@ -164,49 +163,49 @@ __ri bool hwDmacSrcChainWithStack(DMACh *dma, int id) { case TAG_CNT: // CNT - Transfer QWC following the tag. // Set MADR to QW afer tag, and set TADR to QW following the data. - dma->madr = dma->tadr + 16; - dma->tadr = dma->madr + (dma->qwc << 4); + dma.madr = dma.tadr + 16; + dma.tadr = dma.madr + (dma.qwc << 4); return false; case TAG_NEXT: // Next - Transfer QWC following tag. TADR = ADDR { // Set MADR to QW following the tag, and set TADR to the address formerly in MADR. - u32 temp = dma->madr; - dma->madr = dma->tadr + 16; - dma->tadr = temp; + u32 temp = dma.madr; + dma.madr = dma.tadr + 16; + dma.tadr = temp; return false; } case TAG_REF: // Ref - Transfer QWC from ADDR field case TAG_REFS: // Refs - Transfer QWC from ADDR field (Stall Control) //Set TADR to next tag - dma->tadr += 16; + dma.tadr += 16; return false; case TAG_CALL: // Call - Transfer QWC following the tag, save succeeding tag { // Store the address in MADR in temp, and set MADR to the data following the tag. - u32 temp = dma->madr; - dma->madr = dma->tadr + 16; + u32 temp = dma.madr; + dma.madr = dma.tadr + 16; if(temp == 0) { DevCon.Warning("DMA Chain CALL next tag error. Tag Addr = 0"); - dma->tadr = dma->madr + (dma->qwc << 4); + dma.tadr = dma.madr + (dma.qwc << 4); return false; } // Stash an address on the address stack pointer. - switch(dma->chcr.ASP) + switch(dma.chcr.ASP) { case 0: //Check if ASR0 is empty // Store the succeeding tag in asr0, and mark chcr as having 1 address. - dma->asr0 = dma->madr + (dma->qwc << 4); - dma->chcr.ASP++; + dma.asr0 = dma.madr + (dma.qwc << 4); + dma.chcr.ASP++; break; case 1: // Store the succeeding tag in asr1, and mark chcr as having 2 addresses. - dma->asr1 = dma->madr + (dma->qwc << 4); - dma->chcr.ASP++; + dma.asr1 = dma.madr + (dma.qwc << 4); + dma.chcr.ASP++; break; default: @@ -215,48 +214,48 @@ __ri bool hwDmacSrcChainWithStack(DMACh *dma, int id) { } // Set TADR to the address from MADR we stored in temp. - dma->tadr = temp; + dma.tadr = temp; return false; } case TAG_RET: // Ret - Transfer QWC following the tag, load next tag //Set MADR to data following the tag. - dma->madr = dma->tadr + 16; + dma.madr = dma.tadr + 16; // Snag an address from the address stack pointer. - switch(dma->chcr.ASP) + switch(dma.chcr.ASP) { case 2: // Pull asr1 from the stack, give it to TADR, and decrease the # of addresses. - dma->tadr = dma->asr1; - dma->asr1 = 0; - dma->chcr.ASP--; + dma.tadr = dma.asr1; + dma.asr1 = 0; + dma.chcr.ASP--; break; case 1: // Pull asr0 from the stack, give it to TADR, and decrease the # of addresses. - dma->tadr = dma->asr0; - dma->asr0 = 0; - dma->chcr.ASP--; + dma.tadr = dma.asr0; + dma.asr0 = 0; + dma.chcr.ASP--; break; case 0: // There aren't any addresses to pull, so end the transfer. - //dma->tadr += 16; //Clear tag address - Kills Klonoa 2 + //dma.tadr += 16; //Clear tag address - Kills Klonoa 2 return true; default: // If ASR1 and ASR0 are messed up, end the transfer. //Console.Error("TAG_RET: ASR 1 & 0 == 1. This shouldn't happen!"); - //dma->tadr += 16; //Clear tag address - Kills Klonoa 2 + //dma.tadr += 16; //Clear tag address - Kills Klonoa 2 return true; } return false; case TAG_END: // End - Transfer QWC following the tag //Set MADR to data following the tag, and end the transfer. - dma->madr = dma->tadr + 16; + dma.madr = dma.tadr + 16; //Don't Increment tadr; breaks Soul Calibur II and III return true; } @@ -264,7 +263,7 @@ __ri bool hwDmacSrcChainWithStack(DMACh *dma, int id) { return false; } -bool hwDmacSrcChain(DMACh *dma, int id) +bool hwDmacSrcChain(DMACh& dma, int id) { u32 temp; @@ -276,26 +275,26 @@ bool hwDmacSrcChain(DMACh *dma, int id) case TAG_CNT: // CNT - Transfer QWC following the tag. // Set MADR to QW after the tag, and TADR to QW following the data. - dma->madr = dma->tadr + 16; - dma->tadr = dma->madr + (dma->qwc << 4); + dma.madr = dma.tadr + 16; + dma.tadr = dma.madr + (dma.qwc << 4); return false; case TAG_NEXT: // Next - Transfer QWC following tag. TADR = ADDR // Set MADR to QW following the tag, and set TADR to the address formerly in MADR. - temp = dma->madr; - dma->madr = dma->tadr + 16; - dma->tadr = temp; + temp = dma.madr; + dma.madr = dma.tadr + 16; + dma.tadr = temp; return false; case TAG_REF: // Ref - Transfer QWC from ADDR field case TAG_REFS: // Refs - Transfer QWC from ADDR field (Stall Control) //Set TADR to next tag - dma->tadr += 16; + dma.tadr += 16; return false; case TAG_END: // End - Transfer QWC following the tag //Set MADR to data following the tag, and end the transfer. - dma->madr = dma->tadr + 16; + dma.madr = dma.tadr + 16; //Don't Increment tadr; breaks Soul Calibur II and III return true; } diff --git a/pcsx2/Hw.h b/pcsx2/Hw.h index 2af7c662d1..45511af670 100644 --- a/pcsx2/Hw.h +++ b/pcsx2/Hw.h @@ -13,28 +13,84 @@ * If not, see . */ +#pragma once -#ifndef __HW_H__ -#define __HW_H__ +namespace EEMemoryMap +{ + static const uint RCNT0_Start = 0x10000000; + static const uint RCNT0_End = 0x10000800; + static const uint RCNT1_Start = 0x10000800; + static const uint RCNT1_End = 0x10001000; + static const uint RCNT2_Start = 0x10001000; + static const uint RCNT2_End = 0x10001800; + static const uint RCNT3_Start = 0x10001800; + static const uint RCNT3_End = 0x10002000; -////////////////////////////////////////////////////////////////////////// -// Hardware FIFOs (128 bit access only!) -// -// VIF0 -- 0x10004000 -- eeMem->HW[0x4000] -// VIF1 -- 0x10005000 -- eeMem->HW[0x5000] -// GIF -- 0x10006000 -- eeMem->HW[0x6000] -// IPUout -- 0x10007000 -- eeMem->HW[0x7000] -// IPUin -- 0x10007010 -- eeMem->HW[0x7010] + static const uint IPU_Start = 0x10002000; + static const uint IPU_End = 0x10003000; -void __fastcall ReadFIFO_page_4(u32 mem, mem128_t *out); -void __fastcall ReadFIFO_page_5(u32 mem, mem128_t *out); -void __fastcall ReadFIFO_page_6(u32 mem, mem128_t *out); -void __fastcall ReadFIFO_page_7(u32 mem, mem128_t *out); + static const uint GIF_Start = 0x10003000; + static const uint GIF_End = 0x10003800; -void __fastcall WriteFIFO_page_4(u32 mem, const mem128_t *value); -void __fastcall WriteFIFO_page_5(u32 mem, const mem128_t *value); -void __fastcall WriteFIFO_page_6(u32 mem, const mem128_t *value); -void __fastcall WriteFIFO_page_7(u32 mem, const mem128_t *value); + static const uint VIF0_Start = 0x10003800; + static const uint VIF0_End = 0x10003C00; + static const uint VIF1_Start = 0x10003C00; + static const uint VIF1_End = 0x10004000; + + static const uint VIF0_FIFO_Start = 0x10004000; + static const uint VIF0_FIFO_End = 0x10005000; + static const uint VIF1_FIFO_Start = 0x10005000; + static const uint VIF1_FIFO_End = 0x10006000; + static const uint GIF_FIFO_Start = 0x10006000; + static const uint GIF_FIFO_End = 0x10007000; + static const uint IPU_FIFO_Start = 0x10007000; + static const uint IPU_FIFO_End = 0x10008000; + + static const uint VIF0dma_Start = 0x10008000; + static const uint VIF0dma_End = 0x10009000; + static const uint VIF1dma_Start = 0x10009000; + static const uint VIF1dma_End = 0x1000A000; + + static const uint GIFdma_Start = 0x1000A000; + static const uint GIFdma_End = 0x1000B000; + + static const uint fromIPU_Start = 0x1000B000; + static const uint fromIPU_End = 0x1000B400; + static const uint toIPU_Start = 0x1000B400; + static const uint toIPU_End = 0x1000C000; + + static const uint SIF0dma_Start = 0x1000C000; + static const uint SIF0dma_End = 0x1000C400; + static const uint SIF1dma_Start = 0x1000C400; + static const uint SIF1dma_End = 0x1000C800; + static const uint SIF2dma_Start = 0x1000C800; + static const uint SIF2dma_End = 0x1000D000; + + static const uint fromSPR_Start = 0x1000D000; + static const uint fromSPR_End = 0x1000D400; + static const uint toSPR_Start = 0x1000D400; + static const uint toSPR_End = 0x1000E000; + + static const uint DMAC_Start = 0x1000E000; + static const uint DMAC_End = 0x1000F000; + + static const uint INTC_Start = 0x1000F000; + static const uint INTC_End = 0x1000F100; + + static const uint SIO_Start = 0x1000F100; + static const uint SIO_End = 0x1000F200; + static const uint SBUS_Start = 0x1000F200; + static const uint SBUS_End = 0x1000F400; + + // MCH area -- Really not sure what this area is. Information is lacking. + static const uint MCH_Start = 0x1000F400; + static const uint MCH_End = 0x1000F500; + + // Extended master control register area for DMAC. + static const uint DMACext_Start = 0x1000F500; + static const uint DMACext_End = 0x1000F600; + +}; // HW defines enum EERegisterAddresses @@ -86,14 +142,14 @@ enum EERegisterAddresses VIF0_ITOPS = 0x10003890, VIF0_ITOP = 0x100038d0, VIF0_TOP = 0x100038e0, - VIF0_R0 = 0x10003900, - VIF0_R1 = 0x10003910, - VIF0_R2 = 0x10003920, - VIF0_R3 = 0x10003930, - VIF0_C0 = 0x10003940, - VIF0_C1 = 0x10003950, - VIF0_C2 = 0x10003960, - VIF0_C3 = 0x10003970, + VIF0_ROW0 = 0x10003900, + VIF0_ROW1 = 0x10003910, + VIF0_ROW2 = 0x10003920, + VIF0_ROW3 = 0x10003930, + VIF0_COL0 = 0x10003940, + VIF0_COL1 = 0x10003950, + VIF0_COL2 = 0x10003960, + VIF0_COL3 = 0x10003970, VIF1_STAT = 0x10003c00, VIF1_FBRST = 0x10003c10, @@ -110,14 +166,14 @@ enum EERegisterAddresses VIF1_TOPS = 0x10003cc0, VIF1_ITOP = 0x10003cd0, VIF1_TOP = 0x10003ce0, - VIF1_R0 = 0x10003d00, - VIF1_R1 = 0x10003d10, - VIF1_R2 = 0x10003d20, - VIF1_R3 = 0x10003d30, - VIF1_C0 = 0x10003d40, - VIF1_C1 = 0x10003d50, - VIF1_C2 = 0x10003d60, - VIF1_C3 = 0x10003d70, + VIF1_ROW0 = 0x10003d00, + VIF1_ROW1 = 0x10003d10, + VIF1_ROW2 = 0x10003d20, + VIF1_ROW3 = 0x10003d30, + VIF1_COL0 = 0x10003d40, + VIF1_COL1 = 0x10003d50, + VIF1_COL2 = 0x10003d60, + VIF1_COL3 = 0x10003d70, VIF0_FIFO = 0x10004000, VIF1_FIFO = 0x10005000, @@ -134,6 +190,13 @@ enum EERegisterAddresses D0_ASR0 = 0x10008040, D0_ASR1 = 0x10008050, + VIF0_CHCR = 0x10008000, + VIF0_MADR = 0x10008010, + VIF0_QWC = 0x10008020, + VIF0_TADR = 0x10008030, + VIF0_ASR0 = 0x10008040, + VIF0_ASR1 = 0x10008050, + //VIF1 D1_CHCR = 0x10009000, D1_MADR = 0x10009010, @@ -141,7 +204,13 @@ enum EERegisterAddresses D1_TADR = 0x10009030, D1_ASR0 = 0x10009040, D1_ASR1 = 0x10009050, - D1_SADR = 0x10009080, + + VIF1_CHCR = 0x10009000, + VIF1_MADR = 0x10009010, + VIF1_QWC = 0x10009020, + VIF1_TADR = 0x10009030, + VIF1_ASR0 = 0x10009040, + VIF1_ASR1 = 0x10009050, //GS D2_CHCR = 0x1000A000, @@ -150,44 +219,82 @@ enum EERegisterAddresses D2_TADR = 0x1000A030, D2_ASR0 = 0x1000A040, D2_ASR1 = 0x1000A050, - D2_SADR = 0x1000A080, + + GIF_CHCR = 0x1000A000, + GIF_MADR = 0x1000A010, + GIF_QWC = 0x1000A020, + GIF_TADR = 0x1000A030, + GIF_ASR0 = 0x1000A040, + GIF_ASR1 = 0x1000A050, //fromIPU D3_CHCR = 0x1000B000, D3_MADR = 0x1000B010, D3_QWC = 0x1000B020, D3_TADR = 0x1000B030, - D3_SADR = 0x1000B080, + + fromIPU_CHCR = 0x1000B000, + fromIPU_MADR = 0x1000B010, + fromIPU_QWC = 0x1000B020, + fromIPU_TADR = 0x1000B030, //toIPU D4_CHCR = 0x1000B400, D4_MADR = 0x1000B410, D4_QWC = 0x1000B420, D4_TADR = 0x1000B430, - D4_SADR = 0x1000B480, + + toIPU_CHCR = 0x1000B400, + toIPU_MADR = 0x1000B410, + toIPU_QWC = 0x1000B420, + toIPU_TADR = 0x1000B430, //SIF0 D5_CHCR = 0x1000C000, D5_MADR = 0x1000C010, D5_QWC = 0x1000C020, + SIF0_CHCR = 0x1000C000, + SIF0_MADR = 0x1000C010, + SIF0_QWC = 0x1000C020, + //SIF1 D6_CHCR = 0x1000C400, D6_MADR = 0x1000C410, D6_QWC = 0x1000C420, D6_TADR = 0x1000C430, + SIF1_CHCR = 0x1000C400, + SIF1_MADR = 0x1000C410, + SIF1_QWC = 0x1000C420, + SIF1_TADR = 0x1000C430, + //SIF2 D7_CHCR = 0x1000C800, D7_MADR = 0x1000C810, D7_QWC = 0x1000C820, + SIF2_CHCR = 0x1000C800, + SIF2_MADR = 0x1000C810, + SIF2_QWC = 0x1000C820, + //fromSPR D8_CHCR = 0x1000D000, D8_MADR = 0x1000D010, D8_QWC = 0x1000D020, - D8_SADR = 0x1000D080, - D9_CHCR = 0x1000D400, + + fromSPR_CHCR = 0x1000D000, + fromSPR_MADR = 0x1000D010, + fromSPR_QWC = 0x1000D020, + +//toSPR + D9_CHCR = 0x1000D400, + D9_MADR = 0x1000D010, + D9_QWC = 0x1000D020, + + toSPR_CHCR = 0x1000D400, + toSPR_MADR = 0x1000D410, + toSPR_QWC = 0x1000D420, DMAC_CTRL = 0x1000E000, DMAC_STAT = 0x1000E010, @@ -264,53 +371,7 @@ union tGS_SMODE2 bool IsInterlaced() const { return INT; } }; -void hwReset(); - -// hw read functions -extern mem8_t hwRead8 (u32 mem); -extern mem16_t hwRead16(u32 mem); - -extern mem32_t __fastcall hwRead32_page_00(u32 mem); -extern mem32_t __fastcall hwRead32_page_01(u32 mem); -extern mem32_t __fastcall hwRead32_page_02(u32 mem); -extern mem32_t __fastcall hwRead32_page_0F(u32 mem); -extern mem32_t __fastcall hwRead32_page_0F_INTC_HACK(u32 mem); -extern mem32_t __fastcall hwRead32_generic(u32 mem); - -extern void __fastcall hwRead64_page_00(u32 mem, mem64_t* result ); -extern void __fastcall hwRead64_page_01(u32 mem, mem64_t* result ); -extern void __fastcall hwRead64_page_02(u32 mem, mem64_t* result ); -extern void __fastcall hwRead64_generic_INTC_HACK(u32 mem, mem64_t *out); -extern void __fastcall hwRead64_generic(u32 mem, mem64_t* result ); - -extern void __fastcall hwRead128_page_00(u32 mem, mem128_t* result ); -extern void __fastcall hwRead128_page_01(u32 mem, mem128_t* result ); -extern void __fastcall hwRead128_page_02(u32 mem, mem128_t* result ); -extern void __fastcall hwRead128_generic(u32 mem, mem128_t *out); - -// hw write functions -extern void hwWrite8 (u32 mem, u8 value); -extern void hwWrite16(u32 mem, u16 value); - -extern void __fastcall hwWrite32_page_00( u32 mem, mem32_t value ); -extern void __fastcall hwWrite32_page_01( u32 mem, mem32_t value ); -extern void __fastcall hwWrite32_page_02( u32 mem, mem32_t value ); -extern void __fastcall hwWrite32_page_03( u32 mem, mem32_t value ); -extern void __fastcall hwWrite32_page_0B( u32 mem, mem32_t value ); -extern void __fastcall hwWrite32_page_0E( u32 mem, mem32_t value ); -extern void __fastcall hwWrite32_page_0F( u32 mem, mem32_t value ); -extern void __fastcall hwWrite32_generic( u32 mem, mem32_t value ); - -extern void __fastcall hwWrite64_page_00( u32 mem, const mem64_t* srcval ); -extern void __fastcall hwWrite64_page_01( u32 mem, const mem64_t* srcval ); -extern void __fastcall hwWrite64_page_02( u32 mem, const mem64_t* srcval ); -extern void __fastcall hwWrite64_page_03( u32 mem, const mem64_t* srcval ); -extern void __fastcall hwWrite64_page_0E( u32 mem, const mem64_t* srcval ); -extern void __fastcall hwWrite64_generic( u32 mem, const mem64_t* srcval ); - -extern void __fastcall hwWrite128_generic(u32 mem, const mem128_t *srcval); +extern void hwReset(); extern const int rdram_devices; extern int rdram_sdevid; - -#endif /* __HW_H__ */ diff --git a/pcsx2/HwRead.cpp b/pcsx2/HwRead.cpp index 0089c3c625..c20026cee2 100644 --- a/pcsx2/HwRead.cpp +++ b/pcsx2/HwRead.cpp @@ -16,9 +16,11 @@ #include "PrecompiledHeader.h" #include "Common.h" - #include "Hardware.h" +#include "ps2/HwInternal.h" +#include "ps2/eeHwTraceLog.inl" + using namespace R5900; static __fi void IntCHackCheck() @@ -29,470 +31,270 @@ static __fi void IntCHackCheck() if( diff > 0 ) cpuRegs.cycle = g_nextBranchCycle; } -///////////////////////////////////////////////////////////////////////// -// Hardware READ 8 bit +static const uint HwF_VerboseConLog = 1<<0; +static const uint HwF_IntcStatHack = 1<<1; // used for Reads only. -__fi mem8_t hwRead8(u32 mem) +template< uint page > void __fastcall _hwRead128(u32 mem, mem128_t* result ); + +template< uint page, bool intcstathack > +mem32_t __fastcall _hwRead32(u32 mem) { - u8 ret; + pxAssume( (mem & 0x03) == 0 ); - const u16 masked_mem = mem & 0xffff; - // TODO re-implement this warning along with a *complete* logging of all hw activity. - // (implementation should be modelled after thee iopHWRead/iopHwWrite files) - if( mem >= IPU_CMD && mem < D0_CHCR ) + switch( page ) { -#ifdef PCSX2_DEVBUILD - HW_LOG("8bit Hardware IPU Read at 0x%x, value=0x%x", mem, psHu8(mem) ); -#endif - return psHu8(mem); - } - // DevCon.Warning("Unexpected hwRead8 from 0x%x", mem); -#ifdef PCSX2_DEVBUILD - switch((mem >> 12) & 0xf) - { - case 0x03: - if(masked_mem >= 0x3800) HW_LOG("VIF%x Register Read8 at 0x%x, value=0x%x", (masked_mem < 0x3c00) ? 0 : 1, mem, psHu32(mem) ); - else HW_LOG("GIF Register Read8 at 0x%x, value=0x%x", mem, psHu32(mem) ); + case 0x00: return rcntRead32<0x00>( mem ); + case 0x01: return rcntRead32<0x01>( mem ); + + case 0x02: return ipuRead32( mem ); + + case 0x03: return dmacRead32<0x03>( mem ); + case 0x04: case 0x05: case 0x06: case 0x07: - case 0x08: - case 0x09: - case 0x0a: - case 0x0b: - case 0x0c: - case 0x0d: { - const char* regName = "Unknown"; + // [Ps2Confirm] Reading from FIFOs using non-128 bit reads is a complete mystery. + // No game is known to attempt such a thing (yay!), so probably nothing for us to + // worry about. Chances are, though, doing so is "legal" and yields some sort + // of reproducible behavior. Candidate for real hardware testing. + + // Current assumption: Reads 128 bits and discards the unused portion. - switch( mem & 0xf0) - { - case 0x00: regName = "CHCR"; break; - case 0x10: regName = "MADR"; break; - case 0x20: regName = "QWC"; break; - case 0x30: regName = "TADR"; break; - case 0x40: regName = "ASR0"; break; - case 0x50: regName = "ASR1"; break; - case 0x80: regName = "SADDR"; break; - } + DevCon.WriteLn( Color_Cyan, "Reading 32-bit FIFO data" ); - HW_LOG("Hardware Read 8 at 0x%x (%ls %s), value=0x%x", mem, ChcrName(mem & ~0xff), regName, psHu8(mem) ); - ret = psHu8(mem); - return ret; + u128 out128; + _hwRead128(mem, &out128); + return out128._u32[(mem >> 2) & 0x3]; } -} -#endif - - switch (mem) - { - case RCNT0_COUNT: ret = (u8)rcntRcount(0); break; - case RCNT0_MODE: ret = (u8)counters[0].modeval; break; - case RCNT0_TARGET: ret = (u8)counters[0].target; break; - case RCNT0_HOLD: ret = (u8)counters[0].hold; break; - case RCNT0_COUNT + 1: ret = (u8)(rcntRcount(0)>>8); break; - case RCNT0_MODE + 1: ret = (u8)(counters[0].modeval>>8); break; - case RCNT0_TARGET + 1: ret = (u8)(counters[0].target>>8); break; - case RCNT0_HOLD + 1: ret = (u8)(counters[0].hold>>8); break; - - case RCNT1_COUNT: ret = (u8)rcntRcount(1); break; - case RCNT1_MODE: ret = (u8)counters[1].modeval; break; - case RCNT1_TARGET: ret = (u8)counters[1].target; break; - case RCNT1_HOLD: ret = (u8)counters[1].hold; break; - case RCNT1_COUNT + 1: ret = (u8)(rcntRcount(1)>>8); break; - case RCNT1_MODE + 1: ret = (u8)(counters[1].modeval>>8); break; - case RCNT1_TARGET + 1: ret = (u8)(counters[1].target>>8); break; - case RCNT1_HOLD + 1: ret = (u8)(counters[1].hold>>8); break; - - case RCNT2_COUNT: ret = (u8)rcntRcount(2); break; - case RCNT2_MODE: ret = (u8)counters[2].modeval; break; - case RCNT2_TARGET: ret = (u8)counters[2].target; break; - case RCNT2_COUNT + 1: ret = (u8)(rcntRcount(2)>>8); break; - case RCNT2_MODE + 1: ret = (u8)(counters[2].modeval>>8); break; - case RCNT2_TARGET + 1: ret = (u8)(counters[2].target>>8); break; - - case RCNT3_COUNT: ret = (u8)rcntRcount(3); break; - case RCNT3_MODE: ret = (u8)counters[3].modeval; break; - case RCNT3_TARGET: ret = (u8)counters[3].target; break; - case RCNT3_COUNT + 1: ret = (u8)(rcntRcount(3)>>8); break; - case RCNT3_MODE + 1: ret = (u8)(counters[3].modeval>>8); break; - case RCNT3_TARGET + 1: ret = (u8)(counters[3].target>>8); break; - - default: - if ((mem & 0xffffff0f) == SBUS_F200) - { - switch (mem) - { - case SBUS_F240: - ret = psHu32(mem); - //psHu32(mem) &= ~0x4000; - break; - - case SBUS_F260: - ret = 0; - break; - - default: - ret = psHu32(mem); - break; - } - return (u8)ret; - } - - ret = psHu8(mem); - UnknownHW_LOG("Hardware Read 8 from 0x%x = 0x%x", mem, ret); - break; - } - - return ret; -} - -///////////////////////////////////////////////////////////////////////// -// Hardware READ 16 bit - -__fi mem16_t hwRead16(u32 mem) -{ - u16 ret; - const u16 masked_mem = mem & 0xffff; - - // TODO re-implement this warning along with a *complete* logging of all hw activity. - // (implementation should be modelled after the iopHWRead/iopHwWrite files) - if( mem >= IPU_CMD && mem < D0_CHCR ) - { -#ifdef PCSX2_DEVBUILD - HW_LOG("16 bit Hardware IPU Read at 0x%x, value=0x%x", mem, psHu16(mem) ); -#endif - return psHu16(mem); - } - // Console.Warning("Unexpected hwRead16 from 0x%x", mem); - -#ifdef PCSX2_DEVBUILD - switch((mem >> 12) & 0xf) - { - case 0x03: - if(masked_mem >= 0x3800) HW_LOG("VIF%x Register Read8 at 0x%x, value=0x%x", (masked_mem < 0x3c00) ? 0 : 1, mem, psHu32(mem) ); - else HW_LOG("GIF Register Read8 at 0x%x, value=0x%x", mem, psHu32(mem) ); - case 0x04: - case 0x05: - case 0x06: - case 0x07: - case 0x08: - case 0x09: - case 0x0a: - case 0x0b: - case 0x0c: - case 0x0d: - { - const char* regName = "Unknown"; - - switch( mem & 0xf0) - { - case 0x00: regName = "CHCR"; break; - case 0x10: regName = "MADR"; break; - case 0x20: regName = "QWC"; break; - case 0x30: regName = "TADR"; break; - case 0x40: regName = "ASR0"; break; - case 0x50: regName = "ASR1"; break; - case 0x80: regName = "SADDR"; break; - } - - HW_LOG("Hardware Read16 at 0x%x (%ls %s), value=0x%x", mem, ChcrName(mem & ~0xff), regName, psHu16(mem) ); - ret = psHu16(mem); - return ret; - } -} -#endif - - switch (mem) - { - case RCNT0_COUNT: ret = (u16)rcntRcount(0); break; - case RCNT0_MODE: ret = (u16)counters[0].modeval; break; - case RCNT0_TARGET: ret = (u16)counters[0].target; break; - case RCNT0_HOLD: ret = (u16)counters[0].hold; break; - - case RCNT1_COUNT: ret = (u16)rcntRcount(1); break; - case RCNT1_MODE: ret = (u16)counters[1].modeval; break; - case RCNT1_TARGET: ret = (u16)counters[1].target; break; - case RCNT1_HOLD: ret = (u16)counters[1].hold; break; - - case RCNT2_COUNT: ret = (u16)rcntRcount(2); break; - case RCNT2_MODE: ret = (u16)counters[2].modeval; break; - case RCNT2_TARGET: ret = (u16)counters[2].target; break; - - case RCNT3_COUNT: ret = (u16)rcntRcount(3); break; - case RCNT3_MODE: ret = (u16)counters[3].modeval; break; - case RCNT3_TARGET: ret = (u16)counters[3].target; break; - - default: - if ((mem & 0xffffff0f) == SBUS_F200) - { - switch (mem) - { - case SBUS_F240: - ret = psHu16(mem) | 0x0102; - psHu32(mem) &= ~0x4000; // not commented out like in bit mode? - break; - - case SBUS_F260: - ret = 0; - break; - - default: - ret = psHu32(mem); - break; - } - return (u16)ret; - } - ret = psHu16(mem); - UnknownHW_LOG("Hardware Read16 at 0x%x, value= 0x%x", ret, mem); - break; - } - return ret; -} - -///////////////////////////////////////////////////////////////////////// -// Hardware READ 32 bit - -// Reads hardware registers for page 0 (counters 0 and 1) -mem32_t __fastcall hwRead32_page_00(u32 mem) -{ - mem &= 0xffff; - switch( mem ) - { - case 0x00: return (u16)rcntRcount(0); - case 0x10: return (u16)counters[0].modeval; - case 0x20: return (u16)counters[0].target; - case 0x30: return (u16)counters[0].hold; - - case 0x800: return (u16)rcntRcount(1); - case 0x810: return (u16)counters[1].modeval; - case 0x820: return (u16)counters[1].target; - case 0x830: return (u16)counters[1].hold; - } - - return *((u32*)&eeMem->HW[mem]); -} - -// Reads hardware registers for page 1 (counters 2 and 3) -mem32_t __fastcall hwRead32_page_01(u32 mem) -{ - mem &= 0xffff; - switch( mem ) - { - case 0x1000: return (u16)rcntRcount(2); - case 0x1010: return (u16)counters[2].modeval; - case 0x1020: return (u16)counters[2].target; - - case 0x1800: return (u16)rcntRcount(3); - case 0x1810: return (u16)counters[3].modeval; - case 0x1820: return (u16)counters[3].target; - } - - return *((u32*)&eeMem->HW[mem]); -} - -// Reads hardware registers for page 15 (0x0F). -// This is used internally to produce two inline versions, one with INTC_HACK, and one without. -static __fi mem32_t __hwRead32_page_0F( u32 mem, bool intchack ) -{ - // *Performance Warning* This function is called -A-LOT. Be wary when making changes. It - // could impact FPS significantly. - - mem &= 0xffff; - - // INTC_STAT shortcut for heavy spinning. - // Performance Note: Visual Studio handles this best if we just manually check for it here, - // outside the context of the switch statement below. This is likely fixed by PGO also, - // but it's an easy enough conditional to account for anyways. - - static const uint ics = INTC_STAT & 0xffff; - if( mem == ics ) // INTC_STAT - { - if( intchack ) IntCHackCheck(); - return *((u32*)&eeMem->HW[ics]); - } - - switch( mem ) - { - case 0xf010: - HW_LOG("INTC_MASK Read32, value=0x%x", psHu32(INTC_MASK)); break; - case 0xf130: // SIO_ISR - case 0xf260: // SBUS_F260 - case 0xf410: // 0x1000f410 - case 0xf430: // MCH_RICM - return 0; + case 0x0f: + { + // INTC_STAT shortcut for heavy spinning. + // Performance Note: Visual Studio handles this best if we just manually check for it here, + // outside the context of the switch statement below. This is likely fixed by PGO also, + // but it's an easy enough conditional to account for anyways. - case 0xf240: // SBUS_F240 - return psHu32(0xf240) | 0xF0000102; - - case 0xf440: // MCH_DRD - if( !((psHu32(0xf430) >> 6) & 0xF) ) + if (mem == INTC_STAT) { - switch ((psHu32(0xf430)>>16) & 0xFFF) - { - //MCH_RICM: x:4|SA:12|x:5|SDEV:1|SOP:4|SBC:1|SDEV:5 + if (intcstathack) IntCHackCheck(); + return psHu32(INTC_STAT); + } - case 0x21://INIT - if(rdram_sdevid < rdram_devices) - { - rdram_sdevid++; - return 0x1F; - } + //if ((mem & 0x1000f200) == 0x1000f200) + // Console.Error("SBUS"); + + switch( mem ) + { + case SIO_ISR: + case SBUS_F260: + case 0x1000f410: + case MCH_RICM: return 0; - case 0x23://CNFGA - return 0x0D0D; //PVER=3 | MVER=16 | DBL=1 | REFBIT=5 + case SBUS_F240: + return psHu32(SBUS_F240) | 0xF0000102; - case 0x24://CNFGB - //0x0110 for PSX SVER=0 | CORG=8(5x9x7) | SPT=1 | DEVTYP=0 | BYTE=0 - return 0x0090; //SVER=0 | CORG=4(5x9x6) | SPT=1 | DEVTYP=0 | BYTE=0 + case MCH_DRD: + if( !((psHu32(MCH_RICM) >> 6) & 0xF) ) + { + switch ((psHu32(MCH_RICM)>>16) & 0xFFF) + { + //MCH_RICM: x:4|SA:12|x:5|SDEV:1|SOP:4|SBC:1|SDEV:5 - case 0x40://DEVID - return psHu32(0xf430) & 0x1F; // =SDEV - } + case 0x21://INIT + if(rdram_sdevid < rdram_devices) + { + rdram_sdevid++; + return 0x1F; + } + return 0; + + case 0x23://CNFGA + return 0x0D0D; //PVER=3 | MVER=16 | DBL=1 | REFBIT=5 + + case 0x24://CNFGB + //0x0110 for PSX SVER=0 | CORG=8(5x9x7) | SPT=1 | DEVTYP=0 | BYTE=0 + return 0x0090; //SVER=0 | CORG=4(5x9x6) | SPT=1 | DEVTYP=0 | BYTE=0 + + case 0x40://DEVID + return psHu32(MCH_RICM) & 0x1F; // =SDEV + } + } + return 0; } - return 0; + } + break; } - return *((u32*)&eeMem->HW[mem]); + + return psHu32(mem); } -mem32_t __fastcall hwRead32_page_0F(u32 mem) +template< uint page > +mem32_t __fastcall hwRead32(u32 mem) { - return __hwRead32_page_0F( mem, false ); + mem32_t retval = _hwRead32(mem); + eeHwTraceLog( mem, retval, true ); + return retval; } mem32_t __fastcall hwRead32_page_0F_INTC_HACK(u32 mem) { - return __hwRead32_page_0F( mem, true ); + mem32_t retval = _hwRead32<0x0f,true>(mem); + eeHwTraceLog( mem, retval, true ); + return retval; } -mem32_t __fastcall hwRead32_page_02(u32 mem) +// -------------------------------------------------------------------------------------- +// hwRead8 / hwRead16 / hwRead64 / hwRead128 +// -------------------------------------------------------------------------------------- + +template< uint page > +mem8_t __fastcall _hwRead8(u32 mem) { - return ipuRead32( mem ); + u32 ret32 = _hwRead32(mem & ~0x03); + return ((u8*)&ret32)[mem & 0x03]; } -// Used for all pages not explicitly specified above. -mem32_t __fastcall hwRead32_generic(u32 mem) +template< uint page > +mem8_t __fastcall hwRead8(u32 mem) { - const u16 masked_mem = mem & 0xffff; + mem8_t ret8 = _hwRead8<0x0f>(mem); + eeHwTraceLog( mem, ret8, true ); + return ret8; +} - switch( masked_mem>>12 ) // switch out as according to the 4k page of the access. +template< uint page > +mem16_t __fastcall _hwRead16(u32 mem) +{ + pxAssume( (mem & 0x01) == 0 ); + + u32 ret32 = _hwRead32(mem & ~0x03); + return ((u16*)&ret32)[(mem>>1) & 0x01]; +} + +template< uint page > +mem16_t __fastcall hwRead16(u32 mem) +{ + u16 ret16 = _hwRead16(mem); + eeHwTraceLog( mem, ret16, true ); + return ret16; +} + +mem16_t __fastcall hwRead16_page_0F_INTC_HACK(u32 mem) +{ + pxAssume( (mem & 0x01) == 0 ); + + u32 ret32 = _hwRead32<0x0f, true>(mem & ~0x03); + u16 ret16 = ((u16*)&ret32)[(mem>>1) & 0x01]; + + eeHwTraceLog( mem, ret16, "Read" ); + return ret16; +} + +template< uint page > +static void _hwRead64(u32 mem, mem64_t* result ) +{ + pxAssume( (mem & 0x07) == 0 ); + + switch (page) { - case 0x03: - if(masked_mem >= 0x3800) HW_LOG("VIF%x Register Read32 at 0x%x, value=0x%x", (masked_mem < 0x3c00) ? 0 : 1, mem, psHu32(mem) ); - else HW_LOG("GIF Register Read32 at 0x%x, value=0x%x", mem, psHu32(mem) ); - - // Fixme: OPH hack. Toggle the flag on each GIF_STAT access. (rama) - if (CHECK_OPHFLAGHACK) - { - if (masked_mem == 0x3020) - gifRegs->stat.OPH = !gifRegs->stat.OPH; - } - break; - /////////////////////////////////////////////////////// - // Most of the following case handlers are for developer builds only (logging). - // It'll all optimize to ziltch in public release builds. -#ifdef PCSX2_DEVBUILD + case 0x02: + *result = ipuRead64(mem); + return; + case 0x04: case 0x05: case 0x06: case 0x07: - case 0x08: - case 0x09: - case 0x0a: - case 0x0b: - case 0x0c: - case 0x0d: { - const char* regName = "Unknown"; + // [Ps2Confirm] Reading from FIFOs using non-128 bit reads is a complete mystery. + // No game is known to attempt such a thing (yay!), so probably nothing for us to + // worry about. Chances are, though, doing so is "legal" and yields some sort + // of reproducible behavior. Candidate for real hardware testing. + + // Current assumption: Reads 128 bits and discards the unused portion. - switch( mem & 0xf0) - { - case 0x00: regName = "CHCR"; break; - case 0x10: regName = "MADR"; break; - case 0x20: regName = "QWC"; break; - case 0x30: regName = "TADR"; break; - case 0x40: regName = "ASR0"; break; - case 0x50: regName = "ASR1"; break; - case 0x80: regName = "SADDR"; break; - } + uint wordpart = (mem >> 3) & 0x1; + DevCon.WriteLn( Color_Cyan, "Reading 64-bit FIFO data (%s 64 bits discarded)", wordpart ? "upper" : "lower" ); - HW_LOG("Hardware Read32 at 0x%x (%ls %s), value=0x%x", mem, ChcrName(mem & ~0xff), regName, psHu32(mem) ); + u128 out128; + _hwRead128(mem, &out128); + *result = out128._u64[wordpart]; } - break; -#endif - case 0x0e: -#ifdef PCSX2_DEVBUILD - HW_LOG("DMAC Control Regs addr=0x%x Read32, value=0x%x", mem, psHu32(mem)); -#else - if( mem == DMAC_STAT) - HW_LOG("DMAC_STAT Read32, value=0x%x", psHu32(DMAC_STAT)); -#endif - break; - - jNO_DEFAULT; + return; } - return *((u32*)&eeMem->HW[masked_mem]); + *result = _hwRead32( mem ); } -///////////////////////////////////////////////////////////////////////// -// Hardware READ 64 bit - -void __fastcall hwRead64_page_00(u32 mem, mem64_t* result ) +template< uint page > +void __fastcall hwRead64(u32 mem, mem64_t* result ) { - *result = hwRead32_page_00( mem ); + _hwRead64( mem, result ); + eeHwTraceLog( mem, *result, true ); } -void __fastcall hwRead64_page_01(u32 mem, mem64_t* result ) +template< uint page > +void __fastcall _hwRead128(u32 mem, mem128_t* result ) { - *result = hwRead32_page_01( mem ); + pxAssume( (mem & 0x0f) == 0 ); + + // FIFOs are the only "legal" 128 bit registers, so we Handle them first. + // All other registers fall back on the 64-bit handler (and from there + // all non-IPU reads fall back to the 32-bit handler). + + switch (page) + { + case 0x05: + ReadFIFO_VIF1( result ); + break; + + case 0x07: + if (mem & 0x10) + ZeroQWC( result ); // IPUin is write-only + else + ReadFIFO_IPUout( result ); + break; + + case 0x04: + case 0x06: + // VIF0 and GIF are write-only. + // [Ps2Confirm] Reads from these FIFOs (and IPUin) do one of the following: + // return zero, leave contents of the dest register unchanged, or in some + // indeterminate state. The actual behavior probably isn't important. + ZeroQWC( result ); + break; + + default: + _hwRead64( mem, &result->lo ); + result->hi = 0; + break; + } } -void __fastcall hwRead64_page_02(u32 mem, mem64_t* result ) +template< uint page > +void __fastcall hwRead128(u32 mem, mem128_t* result ) { - *result = ipuRead64(mem); + _hwRead128( mem, result ); + eeHwTraceLog( mem, *result, true ); } -void __fastcall hwRead64_generic_INTC_HACK(u32 mem, mem64_t* result ) -{ - if (mem == INTC_STAT) IntCHackCheck(); +#define InstantizeHwRead(pageidx) \ + template mem8_t __fastcall hwRead8(u32 mem); \ + template mem16_t __fastcall hwRead16(u32 mem); \ + template mem32_t __fastcall hwRead32(u32 mem); \ + template void __fastcall hwRead64(u32 mem, mem64_t* result ); \ + template void __fastcall hwRead128(u32 mem, mem128_t* result ); \ + template mem32_t __fastcall _hwRead32(u32 mem); - *result = psHu64(mem); - UnknownHW_LOG("Hardware Read 64 at %x",mem); -} - -void __fastcall hwRead64_generic(u32 mem, mem64_t* result ) -{ - *result = psHu64(mem); - UnknownHW_LOG("Hardware Read 64 at %x",mem); -} - -///////////////////////////////////////////////////////////////////////// -// Hardware READ 128 bit - -void __fastcall hwRead128_page_00(u32 mem, mem128_t* result ) -{ - result->lo = hwRead32_page_00( mem ); - result->hi = 0; -} - -void __fastcall hwRead128_page_01(u32 mem, mem128_t* result ) -{ - result->lo = hwRead32_page_01( mem ); - result->hi = 0; -} - -void __fastcall hwRead128_page_02(u32 mem, mem128_t* result ) -{ - // IPU is currently unhandled in 128 bit mode. - HW_LOG("Hardware Read 128 at %x (IPU)",mem); -} - -void __fastcall hwRead128_generic(u32 mem, mem128_t* out) -{ - CopyQWC(out, &psHu128(mem)); - UnknownHW_LOG("Hardware Read 128 at %x",mem); -} +InstantizeHwRead(0x00); InstantizeHwRead(0x08); +InstantizeHwRead(0x01); InstantizeHwRead(0x09); +InstantizeHwRead(0x02); InstantizeHwRead(0x0a); +InstantizeHwRead(0x03); InstantizeHwRead(0x0b); +InstantizeHwRead(0x04); InstantizeHwRead(0x0c); +InstantizeHwRead(0x05); InstantizeHwRead(0x0d); +InstantizeHwRead(0x06); InstantizeHwRead(0x0e); +InstantizeHwRead(0x07); InstantizeHwRead(0x0f); diff --git a/pcsx2/HwWrite.cpp b/pcsx2/HwWrite.cpp index c400ec4bf7..74a92020a2 100644 --- a/pcsx2/HwWrite.cpp +++ b/pcsx2/HwWrite.cpp @@ -16,1251 +16,377 @@ #include "PrecompiledHeader.h" #include "Common.h" - #include "Hardware.h" +#include "ps2/HwInternal.h" +#include "ps2/eeHwTraceLog.inl" + using namespace R5900; -///////////////////////////////////////////////////////////////////////// -// DMA Execution Interfaces - -// Returns true if the DMA is enabled and executed successfully. Returns false if execution -// was blocked (DMAE or master DMA enabler). -static bool QuickDmaExec( void (*func)(), u32 mem) -{ - bool ret = false; - DMACh *reg = &psH_DMACh(mem); - - if (reg->chcr.STR && dmacRegs->ctrl.DMAE && !psHu8(DMAC_ENABLER+2)) - { - func(); - ret = true; - } - - return ret; -} - - -tDMAC_QUEUE QueuedDMA(0); -u32 oldvalue = 0; - -static void StartQueuedDMA() -{ - if (QueuedDMA.VIF0) { DMA_LOG("Resuming DMA for VIF0"); QueuedDMA.VIF0 = !QuickDmaExec(dmaVIF0, D0_CHCR); } - if (QueuedDMA.VIF1) { DMA_LOG("Resuming DMA for VIF1"); QueuedDMA.VIF1 = !QuickDmaExec(dmaVIF1, D1_CHCR); } - if (QueuedDMA.GIF ) { DMA_LOG("Resuming DMA for GIF" ); QueuedDMA.GIF = !QuickDmaExec(dmaGIF , D2_CHCR); } - if (QueuedDMA.IPU0) { DMA_LOG("Resuming DMA for IPU0"); QueuedDMA.IPU0 = !QuickDmaExec(dmaIPU0, D3_CHCR); } - if (QueuedDMA.IPU1) { DMA_LOG("Resuming DMA for IPU1"); QueuedDMA.IPU1 = !QuickDmaExec(dmaIPU1, D4_CHCR); } - if (QueuedDMA.SIF0) { DMA_LOG("Resuming DMA for SIF0"); QueuedDMA.SIF0 = !QuickDmaExec(dmaSIF0, D5_CHCR); } - if (QueuedDMA.SIF1) { DMA_LOG("Resuming DMA for SIF1"); QueuedDMA.SIF1 = !QuickDmaExec(dmaSIF1, D6_CHCR); } - if (QueuedDMA.SIF2) { DMA_LOG("Resuming DMA for SIF2"); QueuedDMA.SIF2 = !QuickDmaExec(dmaSIF2, D7_CHCR); } - if (QueuedDMA.SPR0) { DMA_LOG("Resuming DMA for SPR0"); QueuedDMA.SPR0 = !QuickDmaExec(dmaSPR0, D8_CHCR); } - if (QueuedDMA.SPR1) { DMA_LOG("Resuming DMA for SPR1"); QueuedDMA.SPR1 = !QuickDmaExec(dmaSPR1, D9_CHCR); } -} - -static __ri void DmaExec( void (*func)(), u32 mem, u32 value ) -{ - DMACh *reg = &psH_DMACh(mem); - tDMA_CHCR chcr(value); - - //It's invalid for the hardware to write a DMA while it is active, not without Suspending the DMAC - if (reg->chcr.STR) - { - const uint channel = ChannelNumber(mem); - - if(psHu8(DMAC_ENABLER+2) == 1) //DMA is suspended so we can allow writes to anything - { - //If it stops the DMA, we need to clear any pending interrupts so the DMA doesnt continue. - if(chcr.STR == 0) - { - //DevCon.Warning(L"32bit %s DMA Stopped on Suspend", ChcrName(mem)); - if(channel == 1) - { - cpuClearInt( 10 ); - QueuedDMA._u16 &= ~(1 << 10); //Clear any queued DMA requests for this channel - } - else if(channel == 2) - { - cpuClearInt( 11 ); - QueuedDMA._u16 &= ~(1 << 11); //Clear any queued DMA requests for this channel - } - - cpuClearInt( channel ); - QueuedDMA._u16 &= ~(1 << channel); //Clear any queued DMA requests for this channel - } - //Sanity Check for possible future bug fix0rs ;p - //Spams on Persona 4 opening. - //if(reg->chcr.TAG != chcr.TAG) DevCon.Warning(L"32bit CHCR Tag on %s changed to %x from %x QWC = %x Channel Active", ChcrName(mem), chcr.TAG, reg->chcr.TAG, reg->qwc); - //Here we update the LOWER CHCR, if a chain is stopped half way through, it can be manipulated in to a different mode - //But we need to preserve the existing tag for now - reg->chcr.set((reg->chcr.TAG << 16) | chcr.lower()); - return; - } - else //Else the DMA is running (Not Suspended), so we cant touch it! - { - //As the manual states "Fields other than STR can only be written to when the DMA is stopped" - //Also "The DMA may not stop properly just by writing 0 to STR" - //So the presumption is that STR can be written to (ala force stop the DMA) but nothing else - - if(chcr.STR == 0) - { - //DevCon.Warning(L"32bit Force Stopping %s (Current CHCR %x) while DMA active", ChcrName(mem), reg->chcr._u32, chcr._u32); - reg->chcr.STR = 0; - //We need to clear any existing DMA loops that are in progress else they will continue! - - if(channel == 1) - { - cpuClearInt( 10 ); - QueuedDMA._u16 &= ~(1 << 10); //Clear any queued DMA requests for this channel - } - else if(channel == 2) - { - cpuClearInt( 11 ); - QueuedDMA._u16 &= ~(1 << 11); //Clear any queued DMA requests for this channel - } - - cpuClearInt( channel ); - QueuedDMA._u16 &= ~(1 << channel); //Clear any queued DMA requests for this channel - } - //else DevCon.Warning(L"32bit Attempted to change %s CHCR (Currently %x) with %x while DMA active, ignoring QWC = %x", ChcrName(mem), reg->chcr._u32, chcr._u32, reg->qwc); - return; - } - - } - - //if(reg->chcr.TAG != chcr.TAG && chcr.MOD == CHAIN_MODE) DevCon.Warning(L"32bit CHCR Tag on %s changed to %x from %x QWC = %x Channel Not Active", ChcrName(mem), chcr.TAG, reg->chcr.TAG, reg->qwc); - - reg->chcr.set(value); - - if (reg->chcr.STR && dmacRegs->ctrl.DMAE && !psHu8(DMAC_ENABLER+2)) - { - func(); - } - else if(reg->chcr.STR) - { - //DevCon.Warning(L"32bit %s DMA Start while DMAC Disabled\n", ChcrName(mem)); - QueuedDMA._u16 |= (1 << ChannelNumber(mem)); //Queue the DMA up to be started then the DMA's are Enabled and or the Suspend is lifted - } //else QueuedDMA._u16 &~= (1 << ChannelNumber(mem)); // -} - -// DmaExec8 should only be called for the second byte of CHCR. -// Testing Note: dark cloud 2 uses 8 bit DMAs register writes. -static __fi void DmaExec8( void (*func)(), u32 mem, u8 value ) -{ - pxAssumeMsg( (mem & 0xf) == 1, "DmaExec8 should only be called for the second byte of CHCR" ); - - // The calling function calls this when the second byte (bits 8->15) is written. Only bit 8 - // is effective, and it is the STR (start) bit. :) - DmaExec( func, mem & ~0xf, (u32)value<<8 ); -} - -static __fi void DmaExec16( void (*func)(), u32 mem, u16 value ) -{ - DmaExec( func, mem, (u32)value ); -} - - -///////////////////////////////////////////////////////////////////////// -// Hardware WRITE 8 bit - -void hwWrite8(u32 mem, u8 value) -{ - if ((mem >= VIF0_STAT) && (mem < VIF0_FIFO)) { - u32 bytemod = mem & 0x3; - u32 bitpos = 8 * bytemod; - u32 oldval = ~(0xff << bitpos) & psHu32(mem); - u32 newval = (value << bitpos) | oldval; - if (mem < VIF1_STAT) vif0Write32(mem & ~0x3, newval); - else vif1Write32(mem & ~0x3, newval); - return; - } - - if( mem >= IPU_CMD && mem < D0_CHCR ) - DevCon.Warning( "hwWrite8 to 0x%x = 0x%x", mem, value ); - - switch (mem) { - case RCNT0_COUNT: rcntWcount(0, value); break; - case RCNT0_MODE: rcntWmode(0, (counters[0].modeval & 0xff00) | value); break; - case RCNT0_MODE + 1: rcntWmode(0, (counters[0].modeval & 0xff) | value << 8); break; - case RCNT0_TARGET: rcntWtarget(0, value); break; - case RCNT0_HOLD: rcntWhold(0, value); break; - - case RCNT1_COUNT: rcntWcount(1, value); break; - case RCNT1_MODE: rcntWmode(1, (counters[1].modeval & 0xff00) | value); break; - case RCNT1_MODE + 1: rcntWmode(1, (counters[1].modeval & 0xff) | value << 8); break; - case RCNT1_TARGET: rcntWtarget(1, value); break; - case RCNT1_HOLD: rcntWhold(1, value); break; - - case RCNT2_COUNT: rcntWcount(2, value); break; - case RCNT2_MODE: rcntWmode(2, (counters[2].modeval & 0xff00) | value); break; - case RCNT2_MODE + 1: rcntWmode(2, (counters[2].modeval & 0xff) | value << 8); break; - case RCNT2_TARGET: rcntWtarget(2, value); break; - - case RCNT3_COUNT: rcntWcount(3, value); break; - case RCNT3_MODE: rcntWmode(3, (counters[3].modeval & 0xff00) | value); break; - case RCNT3_MODE + 1: rcntWmode(3, (counters[3].modeval & 0xff) | value << 8); break; - case RCNT3_TARGET: rcntWtarget(3, value); break; - - case GIF_CTRL: - psHu32(mem) = value & 0x8; - DevCon.Warning("GIFCTRL 8 = %x", value); - if (value & 0x1) - gsGIFReset(); - - if ( value & 8 ) - gifRegs->stat.PSE = true; - else - gifRegs->stat.PSE = false; - break; - - case GIF_MODE: - { - // need to set GIF_MODE (hamster ball) - gifRegs->mode.write(value); - - // set/clear bits 0 and 2 as per the GIF_MODE value. - const u32 bitmask = GIF_MODE_M3R | GIF_MODE_IMT; - psHu32(GIF_STAT) &= ~bitmask; - psHu32(GIF_STAT) |= (u32)value & bitmask; - if(value & GIF_MODE_M3R) DevCon.Warning("8bit GIFMODE M3R write %x", value); - //if(value & GIF_MODE_IMT) DevCon.Warning("8bit GIFMODE INT write %x", value); - } - break; - - case SIO_TXFIFO: - { - static bool iggy_newline = false; - static char sio_buffer[1024]; - static int sio_count; - - if (value == '\r') - { - iggy_newline = true; - sio_buffer[sio_count++] = '\n'; - } - else if (!iggy_newline || (value != '\n')) - { - iggy_newline = false; - sio_buffer[sio_count++] = value; - } - - if ((sio_count == ArraySize(sio_buffer)-1) || (sio_buffer[sio_count-1] == '\n')) - { - sio_buffer[sio_count] = 0; - eeConLog( ShiftJIS_ConvertString(sio_buffer) ); - sio_count = 0; - } - } - break; - - //case 0x10003c02: //Tony Hawks Project 8 uses this - // vif1Write32(mem & ~0x2, value << 16); - // break; - case D0_CHCR + 1: // dma0 - vif0 - DMA_LOG("VIF0dma EXECUTE, value=0x%x", value); - DmaExec8(dmaVIF0, mem, value); - break; - - case D1_CHCR + 1: // dma1 - vif1 - DMA_LOG("VIF1dma EXECUTE, value=0x%x", value); - DmaExec8(dmaVIF1, mem, value); - break; - - case D2_CHCR + 1: // dma2 - gif - DMA_LOG("GSdma EXECUTE, value=0x%x", value); - DmaExec8(dmaGIF, mem, value); - break; - - case D3_CHCR + 1: // dma3 - fromIPU - DMA_LOG("IPU0dma EXECUTE, value=0x%x", value); - DmaExec8(dmaIPU0, mem, value); - break; - - case D4_CHCR + 1: // dma4 - toIPU - DMA_LOG("IPU1dma EXECUTE, value=0x%x", value); - DmaExec8(dmaIPU1, mem, value); - break; - - case D5_CHCR + 1: // dma5 - sif0 - DMA_LOG("SIF0dma EXECUTE, value=0x%x", value); -// if (value == 0) psxSu32(0x30) = 0x40000; - DmaExec8(dmaSIF0, mem, value); - break; - - case D6_CHCR + 1: // dma6 - sif1 - DMA_LOG("SIF1dma EXECUTE, value=0x%x", value); - DmaExec8(dmaSIF1, mem, value); - break; - - case D7_CHCR + 1: // dma7 - sif2 - DMA_LOG("SIF2dma EXECUTE, value=0x%x", value); - DmaExec8(dmaSIF2, mem, value); - break; - - case D8_CHCR + 1: // dma8 - fromSPR - DMA_LOG("fromSPRdma8 EXECUTE, value=0x%x", value); - DmaExec8(dmaSPR0, mem, value); - break; - - case D9_CHCR + 1: // dma9 - toSPR - DMA_LOG("toSPRdma8 EXECUTE, value=0x%x", value); - DmaExec8(dmaSPR1, mem, value); - break; - case D0_CHCR: // dma0 - vif0 - case D1_CHCR: // dma1 - vif1 - case D2_CHCR: // dma2 - gif - case D3_CHCR: // dma3 - fromIPU - case D4_CHCR: // dma4 - toIPU - case D5_CHCR: // dma5 - sif0 - case D6_CHCR: // dma6 - sif1 - case D7_CHCR: // dma7 - sif2 - case D8_CHCR: // dma8 - fromSPR - case D9_CHCR: // dma9 - toSPR - //DevCon.Warning(L"8bit lower CHCR changed to %x from %x on %s DMA", value, psHu32(mem), ChcrName(mem)); - psHu8(mem) = value; - break; - - case D0_CHCR + 2: // dma0 - vif0 - case D0_CHCR + 3: // dma0 - vif0 - case D1_CHCR + 2: // dma1 - vif1 - case D1_CHCR + 3: // dma1 - vif1 - case D2_CHCR + 2: // dma2 - gif - case D2_CHCR + 3: // dma2 - gif - case D3_CHCR + 2: // dma3 - fromIPU - case D3_CHCR + 3: // dma3 - fromIPU - case D4_CHCR + 2: // dma4 - toIPU - case D4_CHCR + 3: // dma4 - toIPU - case D5_CHCR + 2: // dma5 - sif0 - case D5_CHCR + 3: // dma5 - sif0 - case D6_CHCR + 2: // dma6 - sif1 - case D6_CHCR + 3: // dma6 - sif1 - case D7_CHCR + 2: // dma7 - sif2 - case D7_CHCR + 3: // dma7 - sif2 - case D8_CHCR + 2: // dma8 - fromSPR - case D8_CHCR + 3: // dma8 - fromSPR - case D9_CHCR + 2: // dma9 - toSPR - case D9_CHCR + 3: // dma9 - toSPR - //DevCon.Warning(L"8bit CHCR TAG changed to %x from %x on %s DMA", value, psHu32(mem), ChcrName(mem & ~0xf)); - psHu8(mem) = value; - break; - - case DMAC_STAT: - case DMAC_STAT + 1: - case DMAC_STAT + 2: - case DMAC_STAT + 3: - DevCon.Warning("8bit dmac stat! %x", mem); - break; - - case DMAC_ENABLEW + 2: - oldvalue = psHu8(DMAC_ENABLEW + 2); - psHu8(DMAC_ENABLEW + 2) = value; - psHu8(DMAC_ENABLER + 2) = value; - if (((oldvalue & 0x1) == 1) && ((value & 0x1) == 0)) - { - if (!QueuedDMA.empty()) StartQueuedDMA(); - } - break; - case DMAC_CTRL+2: - oldvalue = psHu8(mem); - if ((oldvalue & 0x3) != (value & 0x3)) - { - DevCon.Warning("8bit Stall Source Changed to %x", (value & 0x30) >> 4); - } - if ((oldvalue & 0xC) != (value & 0xC)) - { - DevCon.Warning("8bit Stall Destination Changed to %x", (value & 0xC0) >> 4); - } - psHu8(mem) = value; - break; - - case SBUS_F200: // SIF(?) - psHu8(mem) = value; - break; - - case SBUS_F210: - psHu8(mem) = value; - break; - - case SBUS_F220: - psHu8(mem) = value; - break; - - case SBUS_F230: - psHu8(mem) = value; - break; - - case SBUS_F240: - if (!(value & 0x100)) psHu32(mem) &= ~0x100; - break; - - case SBUS_F250: - psHu8(mem) = value; - break; - - case SBUS_F260: - psHu8(mem) = value; - break; - - default: - pxAssert( (mem & 0xff0f) != 0xf200 ); - - switch(mem&~3) { - case SIO_ISR: - case 0x1000f410: - case MCH_RICM: - break; - - default: - psHu8(mem) = value; - } - HW_LOG("Unknown Hardware write 8 at %x with value %x", mem, value); - break; - } -} - -__ri void hwWrite16(u32 mem, u16 value) -{ - if( mem >= IPU_CMD && mem < D0_CHCR ) - Console.Warning( "hwWrite16 to %x", mem ); - - switch(mem) - { - case RCNT0_COUNT: rcntWcount(0, value); break; - case RCNT0_MODE: rcntWmode(0, value); break; - case RCNT0_TARGET: rcntWtarget(0, value); break; - case RCNT0_HOLD: rcntWhold(0, value); break; - - case RCNT1_COUNT: rcntWcount(1, value); break; - case RCNT1_MODE: rcntWmode(1, value); break; - case RCNT1_TARGET: rcntWtarget(1, value); break; - case RCNT1_HOLD: rcntWhold(1, value); break; - - case RCNT2_COUNT: rcntWcount(2, value); break; - case RCNT2_MODE: rcntWmode(2, value); break; - case RCNT2_TARGET: rcntWtarget(2, value); break; - - case RCNT3_COUNT: rcntWcount(3, value); break; - case RCNT3_MODE: rcntWmode(3, value); break; - case RCNT3_TARGET: rcntWtarget(3, value); break; - - case GIF_CTRL: - psHu32(mem) = value & 0x8; - DevCon.Warning("GIFCTRL 16 %x", value); - if (value & 0x1) - gsGIFReset(); - - if ( value & 8 ) - gifRegs->stat.PSE = true; - else - gifRegs->stat.PSE = false; - break; - - case GIF_MODE: - { - // need to set GIF_MODE (hamster ball) - gifRegs->mode.write(value); - - // set/clear bits 0 and 2 as per the GIF_MODE value. - const u32 bitmask = GIF_MODE_M3R | GIF_MODE_IMT; - psHu32(GIF_STAT) &= ~bitmask; - psHu32(GIF_STAT) |= (u32)value & bitmask; - if(value & GIF_MODE_M3R) DevCon.Warning("16bit GIFMODE M3R write %x", value); - //if(value & GIF_MODE_IMT) DevCon.Warning("16bit GIFMODE INT write %x", value); - - } - break; - case D0_CHCR: // dma0 - vif0 - DMA_LOG("VIF0dma %lx", value); - DmaExec16(dmaVIF0, mem, value); - break; - - case D1_CHCR: // dma1 - vif1 - chcr - DMA_LOG("VIF1dma CHCR %lx", value); - DmaExec16(dmaVIF1, mem, value); - break; - -#ifdef PCSX2_DEVBUILD - case D1_MADR: // dma1 - vif1 - madr - HW_LOG("VIF1dma Madr %lx", value); - psHu16(mem) = value;//dma1 madr - break; - - case D1_QWC: // dma1 - vif1 - qwc - HW_LOG("VIF1dma QWC %lx", value); - psHu16(mem) = value;//dma1 qwc - break; - - case D1_TADR: // dma1 - vif1 - tadr - HW_LOG("VIF1dma TADR %lx", value); - psHu16(mem) = value;//dma1 tadr - break; - - case D1_ASR0: // dma1 - vif1 - asr0 - HW_LOG("VIF1dma ASR0 %lx", value); - psHu16(mem) = value;//dma1 asr0 - break; - - case D1_ASR1: // dma1 - vif1 - asr1 - HW_LOG("VIF1dma ASR1 %lx", value); - psHu16(mem) = value;//dma1 asr1 - break; - - case D1_SADR: // dma1 - vif1 - sadr - HW_LOG("VIF1dma SADR %lx", value); - psHu16(mem) = value;//dma1 sadr - break; -#endif -// --------------------------------------------------- - - case D2_CHCR: // dma2 - gif - DMA_LOG("0x%8.8x hwWrite32: GSdma %lx", cpuRegs.cycle, value); - DmaExec16(dmaGIF, mem, value); - break; - -#ifdef PCSX2_DEVBUILD - case D2_MADR: - psHu16(mem) = value;//dma2 madr - HW_LOG("Hardware write DMA2_MADR 32bit at %x with value %x",mem,value); - break; - - case D2_QWC: - psHu16(mem) = value;//dma2 qwc - HW_LOG("Hardware write DMA2_QWC 32bit at %x with value %x",mem,value); - break; - - case D2_TADR: - psHu16(mem) = value;//dma2 taddr - HW_LOG("Hardware write DMA2_TADDR 32bit at %x with value %x",mem,value); - break; - - case D2_ASR0: - psHu16(mem) = value;//dma2 asr0 - HW_LOG("Hardware write DMA2_ASR0 32bit at %x with value %x",mem,value); - break; - - case D2_ASR1: - psHu16(mem) = value;//dma2 asr1 - HW_LOG("Hardware write DMA2_ASR1 32bit at %x with value %x",mem,value); - break; - - case D2_SADR: - psHu16(mem) = value;//dma2 saddr - HW_LOG("Hardware write DMA2_SADDR 32bit at %x with value %x",mem,value); - break; -#endif - - case D3_CHCR: // dma3 - fromIPU - DMA_LOG("IPU0dma %lx", value); - DmaExec16(dmaIPU0, mem, value); - break; - -#ifdef PCSX2_DEVBUILD - case D3_MADR: - psHu16(mem) = value;//dma2 madr - HW_LOG("Hardware write IPU0DMA_MADR 32bit at %x with value %x",mem,value); - break; - - case D3_QWC: - psHu16(mem) = value;//dma2 madr - HW_LOG("Hardware write IPU0DMA_QWC 32bit at %x with value %x",mem,value); - break; - - case D3_TADR: - psHu16(mem) = value;//dma2 tadr - HW_LOG("Hardware write IPU0DMA_TADR 32bit at %x with value %x",mem,value); - break; - - case D3_SADR: - psHu16(mem) = value;//dma2 saddr - HW_LOG("Hardware write IPU0DMA_SADDR 32bit at %x with value %x",mem,value); - break; -#endif - - case D4_CHCR: // dma4 - toIPU - DMA_LOG("IPU1dma %lx", value); - DmaExec16(dmaIPU1, mem, value); - break; - -#ifdef PCSX2_DEVBUILD - case D4_MADR: - psHu16(mem) = value;//dma2 madr - HW_LOG("Hardware write IPU1DMA_MADR 32bit at %x with value %x",mem,value); - break; - - case D4_QWC: - psHu16(mem) = value;//dma2 madr - HW_LOG("Hardware write IPU1DMA_QWC 32bit at %x with value %x",mem,value); - break; - - case D4_TADR: - psHu16(mem) = value;//dma2 tadr - HW_LOG("Hardware write IPU1DMA_TADR 32bit at %x with value %x",mem,value); - break; - - case D4_SADR: - psHu16(mem) = value;//dma2 saddr - HW_LOG("Hardware write IPU1DMA_SADDR 32bit at %x with value %x",mem,value); - break; -#endif - case D5_CHCR: // dma5 - sif0 - DMA_LOG("SIF0dma %lx", value); - DmaExec16(dmaSIF0, mem, value); - break; - - case D6_CHCR: // dma6 - sif1 - DMA_LOG("SIF1dma %lx", value); - DmaExec16(dmaSIF1, mem, value); - break; - - // Given the other values here, perhaps something like this is in order? - /*case 0x1000C402: // D6_CHCR + 2 - //? - break;*/ - -#ifdef PCSX2_DEVBUILD - case D6_MADR: // dma6 - sif1 - madr - HW_LOG("SIF1dma MADR = %lx", value); - psHu16(mem) = value; - break; - - case D6_QWC: // dma6 - sif1 - qwc - HW_LOG("SIF1dma QWC = %lx", value); - psHu16(mem) = value; - break; - - case D6_TADR: // dma6 - sif1 - tadr - HW_LOG("SIF1dma TADR = %lx", value); - psHu16(mem) = value; - break; -#endif - - case D7_CHCR: // dma7 - sif2 - DMA_LOG("SIF2dma %lx", value); - DmaExec16(dmaSIF2, mem, value); - break; - - case D8_CHCR: // dma8 - fromSPR - DMA_LOG("fromSPRdma %lx", value); - DmaExec16(dmaSPR0, mem, value); - break; - - case D9_CHCR: // dma9 - toSPR - DMA_LOG("toSPRdma %lx", value); - DmaExec16(dmaSPR1, mem, value); - break; - - case D0_CHCR + 2: // dma0 - vif0 - case D1_CHCR + 2: // dma1 - vif1 - case D2_CHCR + 2: // dma2 - gif - case D3_CHCR + 2: // dma3 - fromIPU - case D4_CHCR + 2: // dma4 - toIPU - case D5_CHCR + 2: // dma5 - sif0 - case D6_CHCR + 2: // dma6 - sif1 - case D7_CHCR + 2: // dma7 - sif2 - case D8_CHCR + 2: // dma8 - fromSPR - case D9_CHCR + 2: // dma9 - toSPR - //DevCon.Warning(L"16bit CHCR TAG changed to %x from %x on %s DMA", value, psHu32(mem), ChcrName(mem & ~0xf)); - psHu16(mem) = value; - break; - case DMAC_STAT: - case DMAC_STAT + 2: - DevCon.Warning("16bit dmac stat! %x", mem); - break; - - case DMAC_ENABLEW + 2: - oldvalue = psHu8(DMAC_ENABLEW + 2); - psHu16(DMAC_ENABLEW + 2) = value; - psHu16(DMAC_ENABLER + 2) = value; - if (((oldvalue & 0x1) == 1) && ((value & 0x1) == 0)) - { - if (!QueuedDMA.empty()) StartQueuedDMA(); - } - break; - case DMAC_CTRL: - oldvalue = psHu16(mem); - if ((oldvalue & 0x30) != (value & 0x30)) - { - DevCon.Warning("16bit Stall Source Changed to %x", (value & 0x30) >> 4); - } - if ((oldvalue & 0xC0) != (value & 0xC0)) - { - DevCon.Warning("16bit Stall Destination Changed to %x", (value & 0xC0) >> 4); - } - psHu16(mem) = value; - break; - case SIO_ISR: - case SIO_ISR + 2: - case 0x1000f410: - case 0x1000f410 + 2: - case MCH_RICM: - case MCH_RICM + 2: - break; - - case SBUS_F200: - psHu16(mem) = value; - break; - - case SBUS_F210: - psHu16(mem) = value; - break; - - case SBUS_F220: - psHu16(mem) |= value; - break; - - case SBUS_F230: - psHu16(mem) &= ~value; - break; - - case SBUS_F240: - if (!(value & 0x100)) - psHu16(mem) &= ~0x100; - else - psHu16(mem) |= 0x100; - break; - - case SBUS_F250: - psHu16(mem) = value; - break; - - case SBUS_F260: - psHu16(mem) = 0; - break; - - default: - psHu16(mem) = value; - UnknownHW_LOG("Unknown Hardware write 16 at %x with value %x",mem,value); - } -} - -// Page 0 of HW memory houses registers for Counters 0 and 1 -void __fastcall hwWrite32_page_00( u32 mem, u32 value ) -{ - mem &= 0xffff; - switch (mem) - { - case 0x000: rcntWcount(0, value); return; - case 0x010: rcntWmode(0, value); return; - case 0x020: rcntWtarget(0, value); return; - case 0x030: rcntWhold(0, value); return; - - case 0x800: rcntWcount(1, value); return; - case 0x810: rcntWmode(1, value); return; - case 0x820: rcntWtarget(1, value); return; - case 0x830: rcntWhold(1, value); return; - } - - *((u32*)&eeMem->HW[mem]) = value; -} - -// Page 1 of HW memory houses registers for Counters 2 and 3 -void __fastcall hwWrite32_page_01( u32 mem, u32 value ) -{ - mem &= 0xffff; - switch (mem) - { - case 0x1000: rcntWcount(2, value); return; - case 0x1010: rcntWmode(2, value); return; - case 0x1020: rcntWtarget(2, value); return; - - case 0x1800: rcntWcount(3, value); return; - case 0x1810: rcntWmode(3, value); return; - case 0x1820: rcntWtarget(3, value); return; - } - - *((u32*)&eeMem->HW[mem]) = value; -} - -// page 2 is the IPU register space! -void __fastcall hwWrite32_page_02( u32 mem, u32 value ) -{ - ipuWrite32(mem, value); -} - -// Page 3 contains writes to vif0 and vif1 registers, plus some GIF stuff! -void __fastcall hwWrite32_page_03( u32 mem, u32 value ) -{ - if (mem >= VIF0_STAT) - { - if(mem < VIF1_STAT) - vif0Write32(mem, value); - else - vif1Write32(mem, value); - return; - } - - switch (mem) - { - case GIF_CTRL: - psHu32(mem) = value & 0x8; - - if (value & 0x1) - gsGIFReset(); - - if ( value & 8 ) - gifRegs->stat.PSE = true; - else - gifRegs->stat.PSE = false; - break; - - case GIF_MODE: - { - // need to set GIF_MODE (hamster ball) - gifRegs->mode.write(value); - - // set/clear bits 0 and 2 as per the GIF_MODE value. - const u32 bitmask = GIF_MODE_M3R | GIF_MODE_IMT; - psHu32(GIF_STAT) &= ~bitmask; - psHu32(GIF_STAT) |= (u32)value & bitmask; - - } - break; - - case GIF_STAT: // stat is readonly - DevCon.Warning("*PCSX2* GIFSTAT write value = 0x%x (readonly, ignored)", value); - break; - - default: - psHu32(mem) = value; - } -} - -void __fastcall hwWrite32_page_0B( u32 mem, u32 value ) -{ - // Used for developer logging -- optimized away in Public Release. - const char* regName = "Unknown"; - - switch( mem ) - { - case D3_CHCR: // dma3 - fromIPU - DMA_LOG("IPU0dma EXECUTE, value=0x%x\n", value); - DmaExec(dmaIPU0, mem, value); - return; - - case D3_MADR: regName = "IPU0DMA_MADR"; break; - case D3_QWC: regName = "IPU0DMA_QWC"; break; - case D3_TADR: regName = "IPU0DMA_TADR"; break; - case D3_SADR: regName = "IPU0DMA_SADDR"; break; - - //------------------------------------------------------------------ - - case D4_CHCR: // dma4 - toIPU - DMA_LOG("IPU1dma EXECUTE, value=0x%x\n", value); - DmaExec(dmaIPU1, mem, value); - return; - - case D4_MADR: regName = "IPU1DMA_MADR"; break; - case D4_QWC: regName = "IPU1DMA_QWC"; break; - case D4_TADR: regName = "IPU1DMA_TADR"; break; - case D4_SADR: regName = "IPU1DMA_SADDR"; break; - } - - HW_LOG( "Hardware Write32 at 0x%x (%s), value=0x%x", mem, regName, value ); - psHu32(mem) = value; -} - - - -void __fastcall hwWrite32_page_0E( u32 mem, u32 value ) -{ - switch (mem) - { - case DMAC_CTRL: - { - u32 oldvalue = psHu32(mem); - - HW_LOG("DMAC_CTRL Write 32bit %x", value); - - psHu32(mem) = value; - //Check for DMAS that were started while the DMAC was disabled - if (((oldvalue & 0x1) == 0) && ((value & 0x1) == 1)) - { - if (!QueuedDMA.empty()) StartQueuedDMA(); - } - if ((oldvalue & 0x30) != (value & 0x30)) - { - DevCon.Warning("32bit Stall Source Changed to %x", (value & 0x30) >> 4); - } - if ((oldvalue & 0xC0) != (value & 0xC0)) - { - DevCon.Warning("32bit Stall Destination Changed to %x", (value & 0xC0) >> 4); - } - break; - } - - case DMAC_STAT: - HW_LOG("DMAC_STAT Write 32bit %x", value); - - // lower 16 bits: clear on 1 - // upper 16 bits: reverse on 1 - - psHu16(0xe010) &= ~(value & 0xffff); - psHu16(0xe012) ^= (u16)(value >> 16); - - cpuTestDMACInts(); - break; - - default: - psHu32(mem) = value; - break; - } -} - -void __fastcall hwWrite32_page_0F( u32 mem, u32 value ) -{ - // Shift the middle 8 bits (bits 4-12) into the lower 8 bits. - // This helps the compiler optimize the switch statement into a lookup table. :) +// Shift the middle 8 bits (bits 4-12) into the lower 8 bits. +// This helps the compiler optimize the switch statement into a lookup table. :) #define HELPSWITCH(m) (((m)>>4) & 0xff) +#define mcase(src) case HELPSWITCH(src) - switch( HELPSWITCH(mem) ) - { - case HELPSWITCH(INTC_STAT): - HW_LOG("INTC_STAT Write 32bit %x", value); - psHu32(INTC_STAT) &= ~value; - //cpuTestINTCInts(); - break; +template< uint page > void __fastcall _hwWrite8(u32 mem, u8 value); +template< uint page > void __fastcall _hwWrite16(u32 mem, u8 value); +template< uint page > void __fastcall _hwWrite128(u32 mem, u8 value); - case HELPSWITCH(INTC_MASK): - HW_LOG("INTC_MASK Write 32bit %x", value); - psHu32(INTC_MASK) ^= (u16)value; - cpuTestINTCInts(); - break; - //------------------------------------------------------------------ - case HELPSWITCH(MCH_RICM)://MCH_RICM: x:4|SA:12|x:5|SDEV:1|SOP:4|SBC:1|SDEV:5 - if ((((value >> 16) & 0xFFF) == 0x21) && (((value >> 6) & 0xF) == 1) && (((psHu32(0xf440) >> 7) & 1) == 0))//INIT & SRP=0 - rdram_sdevid = 0; // if SIO repeater is cleared, reset sdevid - psHu32(mem) = value & ~0x80000000; //kill the busy bit - break; - - case HELPSWITCH(SBUS_F200): - psHu32(mem) = value; - break; - - case HELPSWITCH(SBUS_F220): - psHu32(mem) |= value; - break; - - case HELPSWITCH(SBUS_F230): - psHu32(mem) &= ~value; - break; - - case HELPSWITCH(SBUS_F240): - if(!(value & 0x100)) - psHu32(mem) &= ~0x100; - else - psHu32(mem) |= 0x100; - break; - - case HELPSWITCH(SBUS_F260): - psHu32(mem) = 0; - break; - - case HELPSWITCH(MCH_DRD)://MCH_DRD: - psHu32(mem) = value; - break; - - case HELPSWITCH(DMAC_ENABLEW): - HW_LOG("DMAC_ENABLEW Write 32bit %lx", value); - oldvalue = psHu8(DMAC_ENABLEW + 2); - psHu32(DMAC_ENABLEW) = value; - psHu32(DMAC_ENABLER) = value; - if (((oldvalue & 0x1) == 1) && (((value >> 16) & 0x1) == 0)) - { - if (!QueuedDMA.empty()) StartQueuedDMA(); - } - break; - - //------------------------------------------------------------------ - case HELPSWITCH(SIO_ISR): - case HELPSWITCH(0x1000f410): - UnknownHW_LOG("Unknown Hardware write 32 at %x with value %x (%x)", mem, value, cpuRegs.CP0.n.Status.val); - break; - - default: - psHu32(mem) = value; - } -} - -void __fastcall hwWrite32_generic( u32 mem, u32 value ) +template +void __fastcall _hwWrite32( u32 mem, u32 value ) { - // Used for developer logging -- optimized away in Public Release. - const char* regName = "Unknown"; + pxAssume( (mem & 0x03) == 0 ); - switch (mem) + // Notes: + // All unknown registers on the EE are "reserved" as discarded writes and indeterminate + // reads. Bus error is only generated for registers outside the first 16k of mapped + // register space (which is handled by the VTLB mapping, so no need for checks here). + + switch (page) { - case D0_CHCR: // dma0 - vif0 - DMA_LOG("VIF0dma EXECUTE, value=0x%x", value); - DmaExec(dmaVIF0, mem, value); - return; + case 0x00: if (!rcntWrite32<0x00>(mem, value)) return; break; + case 0x01: if (!rcntWrite32<0x01>(mem, value)) return; break; -//------------------------------------------------------------------ - case D1_CHCR: // dma1 - vif1 - chcr - DMA_LOG("VIF1dma EXECUTE, value=0x%x", value); - DmaExec(dmaVIF1, mem, value); - return; + case 0x02: + if (!ipuWrite32(mem, value)) return; + break; - case D1_MADR: regName = "VIF1dma MADR"; break; - case D1_QWC: regName = "VIF1dma QWC"; break; - case D1_TADR: regName = "VIF1dma TADR"; break; - case D1_ASR0: regName = "VIF1dma ASR0"; break; - case D1_ASR1: regName = "VIF1dma ASR1"; break; - case D1_SADR: regName = "VIF1dma SADR"; break; + case 0x04: + case 0x05: + case 0x06: + case 0x07: + { + // [Ps2Confirm] Direct FIFO read/write behavior. We need to create a test that writes + // data to one of the FIFOs and determine the result. I'm not quite sure offhand a good + // way to do that --air + // Current assumption is that 32-bit and 64-bit writes likely do 128-bit zero-filled + // writes (upper 96 bits are 0, lower 32 bits are effective). -//------------------------------------------------------------------ - case D2_CHCR: // dma2 - gif - DMA_LOG("GIFdma EXECUTE, value=0x%x", value); - DmaExec(dmaGIF, mem, value); - return; + u128 zerofill = u128::From32(0); + zerofill._u32[(mem >> 2) & 0x03] = value; - case D2_MADR: regName = "GIFdma MADR"; break; - case D2_QWC: regName = "GIFdma QWC"; break; - case D2_TADR: regName = "GIFdma TADDR"; break; - case D2_ASR0: regName = "GIFdma ASR0"; break; - case D2_ASR1: regName = "GIFdma ASR1"; break; - case D2_SADR: regName = "GIFdma SADDR"; break; + DevCon.WriteLn( Color_Cyan, "Writing 32-bit FIFO data (zero-extended to 128 bits)" ); + _hwWrite128(mem, &zerofill); + } + return; -//------------------------------------------------------------------ - case D5_CHCR: // dma5 - sif0 - DMA_LOG("SIF0dma EXECUTE, value=0x%x", value); - DmaExec(dmaSIF0, mem, value); - return; -//------------------------------------------------------------------ - case D6_CHCR: // dma6 - sif1 - DMA_LOG("SIF1dma EXECUTE, value=0x%x", value); - DmaExec(dmaSIF1, mem, value); - return; + case 0x03: + if (mem >= EEMemoryMap::VIF0_Start) + { + if(mem >= EEMemoryMap::VIF1_Start) + { + if (!vifWrite32<1>(mem, value)) return; + } + else + { + if (!vifWrite32<0>(mem, value)) return; + } + } + else iswitch(mem) + { + icase(GIF_CTRL) + { + psHu32(mem) = value & 0x8; - case D6_MADR: regName = "SIF1dma MADR"; break; - case D6_QWC: regName = "SIF1dma QWC"; break; - case D6_TADR: regName = "SIF1dma TADR"; break; + if (value & 0x1) + gsGIFReset(); -//------------------------------------------------------------------ - case D7_CHCR: // dma7 - sif2 - DMA_LOG("SIF2dma EXECUTE, value=0x%x", value); - DmaExec(dmaSIF2, mem, value); - return; -//------------------------------------------------------------------ - case D8_CHCR: // dma8 - fromSPR - DMA_LOG("SPR0dma EXECUTE (fromSPR), value=0x%x", value); - DmaExec(dmaSPR0, mem, value); - return; -//------------------------------------------------------------------ - case D9_CHCR: // dma9 - toSPR - DMA_LOG("SPR1dma EXECUTE (toSPR), value=0x%x", value); - DmaExec(dmaSPR1, mem, value); - return; + if (value & 8) + gifRegs.stat.PSE = true; + else + gifRegs.stat.PSE = false; + + return; + } + + icase(GIF_MODE) + { + // need to set GIF_MODE (hamster ball) + gifRegs.mode.write(value); + + // set/clear bits 0 and 2 as per the GIF_MODE value. + const u32 bitmask = GIF_MODE_M3R | GIF_MODE_IMT; + psHu32(GIF_STAT) &= ~bitmask; + psHu32(GIF_STAT) |= (u32)value & bitmask; + + return; + } + } + break; + + case 0x08: + case 0x09: + case 0x0a: + case 0x0b: + case 0x0c: + case 0x0d: + case 0x0e: + if (!dmacWrite32(mem, value)) return; + break; + + case 0x0f: + { + switch( HELPSWITCH(mem) ) + { + mcase(INTC_STAT): + psHu32(INTC_STAT) &= ~value; + //cpuTestINTCInts(); + return; + + mcase(INTC_MASK): + psHu32(INTC_MASK) ^= (u16)value; + cpuTestINTCInts(); + return; + + mcase(SIO_TXFIFO): + { + u8* woot = (u8*)&value; + // [Ps2Confirm] What happens when we write 32 bit values to SIO_TXFIFO? + // If it works like the IOP, then all 32 bits are written to the FIFO in + // order. PCSX2 up to this point simply ignored non-8bit writes to this port. + _hwWrite8<0x0f>(SIO_TXFIFO, woot[0]); + _hwWrite8<0x0f>(SIO_TXFIFO, woot[1]); + _hwWrite8<0x0f>(SIO_TXFIFO, woot[2]); + _hwWrite8<0x0f>(SIO_TXFIFO, woot[3]); + } + return; + + mcase(SBUS_F200): + // Performs a standard psHu32 assignment (which is the default action anyway). + //psHu32(mem) = value; + break; + + mcase(SBUS_F220): + psHu32(mem) |= value; + return; + + mcase(SBUS_F230): + psHu32(mem) &= ~value; + return; + + mcase(SBUS_F240): + if(!(value & 0x100)) + psHu32(mem) &= ~0x100; + else + psHu32(mem) |= 0x100; + return; + + mcase(SBUS_F260): + psHu32(mem) = 0; + return; + + mcase(MCH_RICM)://MCH_RICM: x:4|SA:12|x:5|SDEV:1|SOP:4|SBC:1|SDEV:5 + if ((((value >> 16) & 0xFFF) == 0x21) && (((value >> 6) & 0xF) == 1) && (((psHu32(0xf440) >> 7) & 1) == 0))//INIT & SRP=0 + rdram_sdevid = 0; // if SIO repeater is cleared, reset sdevid + psHu32(mem) = value & ~0x80000000; //kill the busy bit + return; + + mcase(MCH_DRD): + // Performs a standard psHu32 assignment (which is the default action anyway). + //psHu32(mem) = value; + break; + + mcase(DMAC_ENABLEW): + if (!dmacWrite32<0x0f>(DMAC_ENABLEW, value)) return; + + //mcase(SIO_ISR): + //mcase(0x1000f410): + // Mystery Regs! No one knows!? + // (unhandled so fall through to default) + + } + } + break; } - HW_LOG( "Hardware Write32 at 0x%x (%s), value=0x%x", mem, regName, value ); + psHu32(mem) = value; } -///////////////////////////////////////////////////////////////////////// -// HW Write 64 bit - -// Page 0 of HW memory houses registers for Counters 0 and 1 -void __fastcall hwWrite64_page_00( u32 mem, const mem64_t* srcval ) +template +void __fastcall hwWrite32( u32 mem, u32 value ) { - hwWrite32_page_00( mem, (u32)*srcval ); // just ignore upper 32 bits. - psHu64(mem) = *srcval; + eeHwTraceLog( mem, value, false ); + _hwWrite32( mem, value ); } -// Page 1 of HW memory houses registers for Counters 2 and 3 -void __fastcall hwWrite64_page_01( u32 mem, const mem64_t* srcval ) -{ - hwWrite32_page_01( mem, (u32)*srcval ); // just ignore upper 32 bits. - psHu64(mem) = *srcval; -} +// -------------------------------------------------------------------------------------- +// hwWrite8 / hwWrite16 / hwWrite64 / hwWrite128 +// -------------------------------------------------------------------------------------- -void __fastcall hwWrite64_page_02( u32 mem, const mem64_t* srcval ) +template< uint page > +void __fastcall _hwWrite8(u32 mem, u8 value) { - //hwWrite64( mem, *srcval ); return; - ipuWrite64( mem, *srcval ); -} - -void __fastcall hwWrite64_page_03( u32 mem, const mem64_t* srcval ) -{ - //hwWrite64( mem, *srcval ); return; - const u64 value = *srcval; - - if (mem >= VIF0_STAT) + iswitch (mem) + icase(SIO_TXFIFO) { - if (mem < VIF1_STAT) - vif0Write32(mem, value); - else - vif1Write32(mem, value); + static bool iggy_newline = false; + static char sio_buffer[1024]; + static int sio_count; + + if (value == '\r') + { + iggy_newline = true; + sio_buffer[sio_count++] = '\n'; + } + else if (!iggy_newline || (value != '\n')) + { + iggy_newline = false; + sio_buffer[sio_count++] = value; + } + + if ((sio_count == ArraySize(sio_buffer)-1) || (sio_buffer[sio_count-1] == '\n')) + { + sio_buffer[sio_count] = 0; + eeConLog( ShiftJIS_ConvertString(sio_buffer) ); + sio_count = 0; + } return; } - switch (mem) + u32 merged = _hwRead32(mem & ~0x03); + ((u8*)&merged)[mem & 0x3] = value; + + _hwWrite32(mem & ~0x03, merged); +} + +template< uint page > +void __fastcall hwWrite8(u32 mem, u8 value) +{ + eeHwTraceLog( mem, value, false ); + _hwWrite8(mem, value); +} + +template< uint page > +void __fastcall _hwWrite16(u32 mem, u16 value) +{ + pxAssume( (mem & 0x01) == 0 ); + + u32 merged = _hwRead32(mem & ~0x03); + ((u16*)&merged)[(mem>>1) & 0x1] = value; + + hwWrite32(mem & ~0x03, merged); +} + +template< uint page > +void __fastcall hwWrite16(u32 mem, u16 value) +{ + eeHwTraceLog( mem, value, false ); + _hwWrite16(mem, value); +} + +template +void __fastcall _hwWrite64( u32 mem, const mem64_t* srcval ) +{ + pxAssume( (mem & 0x07) == 0 ); + + // * Only the IPU has true 64 bit registers. + // * FIFOs have 128 bit registers that are probably zero-fill. + // * All other registers likely disregard the upper 32-bits and simply act as normal + // 32-bit writes. + + switch (page) { - case GIF_CTRL: - DevCon.WriteLn("GIF_CTRL write 64", value); - psHu32(mem) = value & 0x8; - if(value & 0x1) - gsGIFReset(); + case 0x02: + if (!ipuWrite64(mem, *srcval)) return; + break; + + case 0x04: + case 0x05: + case 0x06: + case 0x07: + { + DevCon.WriteLn( Color_Cyan, "Writing 64-bit FIFO data (zero-extended to 128 bits)" ); + + u128 zerofill = u128::From32(0); + zerofill._u64[(mem >> 3) & 0x01] = *srcval; + hwWrite128(mem, &zerofill); + } + return; + + default: + // disregard everything except the lower 32 bits. + // ... and skip the 64 bit writeback since the 32-bit one will suffice. + hwWrite32( mem, ((u32*)srcval)[0] ); + return; + } + + psHu64(mem) = *srcval; +} + +template +void __fastcall hwWrite64( u32 mem, const mem64_t* srcval ) +{ + eeHwTraceLog( mem, *srcval, false ); + _hwWrite64(mem, srcval); +} + +template< uint page > +void __fastcall _hwWrite128(u32 mem, const mem128_t* srcval) +{ + pxAssume( (mem & 0x0f) == 0 ); + + // FIFOs are the only "legal" 128 bit registers. Handle them first. + // all other registers fall back on the 64-bit handler (and from there + // most of them fall back to the 32-bit handler). + + switch (page) + { + case 0x04: + WriteFIFO_VIF0(srcval); + return; + + case 0x05: + WriteFIFO_VIF1(srcval); + return; + + case 0x06: + WriteFIFO_GIF(srcval); + return; + + case 0x07: + if (mem & 0x10) + { + WriteFIFO_IPUin(srcval); + } else { - if( value & 8 ) - gifRegs->stat.PSE = true; - else - gifRegs->stat.PSE = false; + // [Ps2Confirm] Most likely writes to IPUout will be silently discarded. A test + // to confirm such would be easy -- just dump some data to FIFO_IPUout and see + // if the program causes BUSERR or something on the PS2. + + //WriteFIFO_IPUout(srcval); } - break; - - case GIF_MODE: - { - // set/clear bits 0 and 2 as per the GIF_MODE value. - const u32 bitmask = GIF_MODE_M3R | GIF_MODE_IMT; - - Console.WriteLn("GIFMODE64 %x", value); - - psHu64(GIF_MODE) = value; - psHu32(GIF_STAT) &= ~bitmask; - psHu32(GIF_STAT) |= (u32)value & bitmask; - break; - } - - case GIF_STAT: // stat is readonly - break; + + return; } + + // All upper bits of all non-FIFO 128-bit HW writes are almost certainly disregarded. --air + hwWrite64(mem, (mem64_t*)srcval); + + //CopyQWC(&psHu128(mem), srcval); } -void __fastcall hwWrite64_page_0E( u32 mem, const mem64_t* srcval ) +template< uint page > +void __fastcall hwWrite128(u32 mem, const mem128_t* srcval) { - //hwWrite64( mem, *srcval ); return; - - const u64 value = *srcval; - - switch (mem) - { - case DMAC_CTRL: - { - u32 oldvalue = psHu32(mem); - psHu64(mem) = value; - - HW_LOG("DMAC_CTRL Write 64bit %x", value); - - if (((oldvalue & 0x1) == 0) && ((value & 0x1) == 1)) - { - if (!QueuedDMA.empty()) StartQueuedDMA(); - } - if ((oldvalue & 0x30) != (value & 0x30)) - { - DevCon.Warning("64bit Stall Source Changed to %x", (value & 0x30) >> 4); - } - if ((oldvalue & 0xC0) != (value & 0xC0)) - { - DevCon.Warning("64bit Stall Destination Changed to %x", (value & 0xC0) >> 4); - } - break; - } - - case DMAC_STAT: - HW_LOG("DMAC_STAT Write 64bit %x", value); - - // lower 16 bits: clear on 1 - // upper 16 bits: reverse on 1 - - psHu16(0xe010) &= ~(value & 0xffff); - psHu16(0xe012) ^= (u16)(value >> 16); - - cpuTestDMACInts(); - break; - - default: - psHu64(mem) = value; - break; - } + eeHwTraceLog( mem, *srcval, false ); + _hwWrite128(mem, srcval); } -void __fastcall hwWrite64_generic( u32 mem, const mem64_t* srcval ) -{ - const u64 value = *srcval; +#define InstantizeHwWrite(pageidx) \ + template void __fastcall hwWrite8(u32 mem, mem8_t value); \ + template void __fastcall hwWrite16(u32 mem, mem16_t value); \ + template void __fastcall hwWrite32(u32 mem, mem32_t value); \ + template void __fastcall hwWrite64(u32 mem, const mem64_t* srcval); \ + template void __fastcall hwWrite128(u32 mem, const mem128_t* srcval); - switch (mem) - { - case D2_CHCR: // dma2 - gif - DMA_LOG("0x%8.8x hwWrite64: GSdma %x", cpuRegs.cycle, value); - DmaExec(dmaGIF, mem, value); - break; - - case INTC_STAT: - HW_LOG("INTC_STAT Write 64bit %x", (u32)value); - psHu32(INTC_STAT) &= ~value; - //cpuTestINTCInts(); - break; - - case INTC_MASK: - HW_LOG("INTC_MASK Write 64bit %x", (u32)value); - psHu32(INTC_MASK) ^= (u16)value; - cpuTestINTCInts(); - break; - - case SIO_ISR: - case 0x1000f410: - case MCH_RICM: - break; - - case DMAC_ENABLEW: // DMAC_ENABLEW - oldvalue = psHu8(DMAC_ENABLEW + 2); - psHu32(DMAC_ENABLEW) = value; - psHu32(DMAC_ENABLER) = value; - if (((oldvalue & 0x1) == 1) && (((value >> 16) & 0x1) == 0)) - { - if (!QueuedDMA.empty()) StartQueuedDMA(); - } - break; - - default: - psHu64(mem) = value; - UnknownHW_LOG("Unknown Hardware write 64 at %x with value %x (status=%x)",mem,value, cpuRegs.CP0.n.Status.val); - break; - } -} - -///////////////////////////////////////////////////////////////////////// -// HW Write 128 bit - -void __fastcall hwWrite128_generic(u32 mem, const mem128_t *srcval) -{ - //hwWrite128( mem, srcval ); return; - - const uint srcval32 = *srcval; - - switch (mem) - { - case INTC_STAT: - HW_LOG("INTC_STAT Write 128bit %x (lower 32bits effective)", srcval32); - psHu32(INTC_STAT) &= ~srcval32; - //cpuTestINTCInts(); - break; - - case INTC_MASK: - HW_LOG("INTC_MASK Write 128bit %x (lower 32bits effective)", srcval32); - psHu32(INTC_MASK) ^= (u16)srcval32; - cpuTestINTCInts(); - break; - - case DMAC_ENABLEW: // DMAC_ENABLEW - oldvalue = psHu8(DMAC_ENABLEW + 2); - psHu32(DMAC_ENABLEW) = srcval32; - psHu32(DMAC_ENABLER) = srcval32; - if (((oldvalue & 0x1) == 1) && (((srcval32 >> 16) & 0x1) == 0)) - { - if (!QueuedDMA.empty()) StartQueuedDMA(); - } - break; - - case SIO_ISR: - case 0x1000f410: - case MCH_RICM: - break; - - default: - CopyQWC(&psHu128(mem), srcval); - UnknownHW_LOG("Unknown Hardware write 128 at %x with value %x_%x (status=%x)", mem, srcval[1], srcval[0], cpuRegs.CP0.n.Status.val); - break; - } -} +InstantizeHwWrite(0x00); InstantizeHwWrite(0x08); +InstantizeHwWrite(0x01); InstantizeHwWrite(0x09); +InstantizeHwWrite(0x02); InstantizeHwWrite(0x0a); +InstantizeHwWrite(0x03); InstantizeHwWrite(0x0b); +InstantizeHwWrite(0x04); InstantizeHwWrite(0x0c); +InstantizeHwWrite(0x05); InstantizeHwWrite(0x0d); +InstantizeHwWrite(0x06); InstantizeHwWrite(0x0e); +InstantizeHwWrite(0x07); InstantizeHwWrite(0x0f); diff --git a/pcsx2/IPU/IPU.cpp b/pcsx2/IPU/IPU.cpp index 5798ac7418..165e2a0b40 100644 --- a/pcsx2/IPU/IPU.cpp +++ b/pcsx2/IPU/IPU.cpp @@ -13,16 +13,11 @@ * If not, see . */ -// ---------------------------------------------------------------------------- -// PCH Warning! This file, when compiled with PCH + Optimizations, fails in very curious -// and unexpected ways (most obvious is a freeze in the middle of the New Game video of -// Final Fantasy XII). So make sure to force-disable PCH for this file at ALL times. -// ---------------------------------------------------------------------------- - #include "PrecompiledHeader.h" #include "Common.h" #include "IPU.h" +#include "IPUdma.h" #include "yuv2rgb.h" #include "mpeg2lib/Mpeg.h" @@ -31,17 +26,12 @@ #include "Vif_Dma.h" #include -// Zero cycle IRQ schedules aren't really good, but the IPU uses them. -// Better to throw the IRQ inline: +static __fi void IPU_INT0_FROM() +{ + if (ipu0dma.qwc > 0 && ipu0dma.chcr.STR) ipu0Interrupt(); +} -#define IPU_INT0_FROM() ipu0Interrupt() -//#define IPU_INT0_FROM() CPU_INT( DMAC_FROM_IPU, 0 ) - -// IPU Inline'd IRQs : Calls the IPU interrupt handlers directly instead of -// feeding them through the EE's branch test. (see IPU.h for details) -tIPU_DMA g_nDMATransfer(0); tIPU_cmd ipu_cmd; -IPUStatus IPU1Status; void ReorderBitstream(); @@ -70,25 +60,22 @@ u8* readbits = _readbits; // always can decrement by one 1qw __fi void IPUProcessInterrupt() { - if (ipuRegs->ctrl.BUSY && g_BP.IFC) IPUWorker(); + if (ipuRegs.ctrl.BUSY && g_BP.IFC) IPUWorker(); } ///////////////////////////////////////////////////////// // Register accesses (run on EE thread) int ipuInit() { - memzero(*ipuRegs); + memzero(ipuRegs); memzero(g_BP); memzero(decoder); decoder.picture_structure = FRAME_PICTURE; //default: progressive...my guess:P - g_nDMATransfer.reset(); - IPU1Status.InProgress = false; - IPU1Status.DMAMode = DMA_MODE_NORMAL; - IPU1Status.DMAFinished = true; ipu_fifo.init(); ipu_cmd.clear(); + return 0; } @@ -97,13 +84,9 @@ void ipuReset() ipuInit(); } -void ipuShutdown() -{ -} - void ReportIPU() { - Console.WriteLn(g_nDMATransfer.desc()); + //Console.WriteLn(g_nDMATransfer.desc()); Console.WriteLn(ipu_fifo.in.desc()); Console.WriteLn(ipu_fifo.out.desc()); Console.WriteLn(g_BP.desc()); @@ -123,8 +106,6 @@ void SaveStateBase::ipuFreeze() // Get a report of the status of the ipu variables when saving and loading savestates. //ReportIPU(); FreezeTag("IPU"); - - Freeze(g_nDMATransfer); Freeze(ipu_fifo); Freeze(g_BP); @@ -232,27 +213,27 @@ __fi u32 ipuRead32(u32 mem) switch (mem) { ipucase(IPU_CTRL): // IPU_CTRL - ipuRegs->ctrl.IFC = g_BP.IFC; - ipuRegs->ctrl.CBP = coded_block_pattern; + ipuRegs.ctrl.IFC = g_BP.IFC; + ipuRegs.ctrl.CBP = coded_block_pattern; - if (!ipuRegs->ctrl.BUSY) - IPU_LOG("read32: IPU_CTRL=0x%08X %x", ipuRegs->ctrl._u32, cpuRegs.pc); + if (!ipuRegs.ctrl.BUSY) + IPU_LOG("read32: IPU_CTRL=0x%08X", ipuRegs.ctrl._u32); - return ipuRegs->ctrl._u32; + return ipuRegs.ctrl._u32; ipucase(IPU_BP): // IPU_BP - ipuRegs->ipubp = g_BP.BP & 0x7f; - ipuRegs->ipubp |= g_BP.IFC << 8; - ipuRegs->ipubp |= (g_BP.FP /*+ g_BP.bufferhasnew*/) << 16; + ipuRegs.ipubp = g_BP.BP & 0x7f; + ipuRegs.ipubp |= g_BP.IFC << 8; + ipuRegs.ipubp |= (g_BP.FP /*+ g_BP.bufferhasnew*/) << 16; - IPU_LOG("read32: IPU_BP=0x%08X", ipuRegs->ipubp); - return ipuRegs->ipubp; + IPU_LOG("read32: IPU_BP=0x%08X", ipuRegs.ipubp); + return ipuRegs.ipubp; default: - IPU_LOG("read32: Addr=0x%x Value = 0x%08X", mem, *(u32*)(((u8*)ipuRegs) + mem)); + IPU_LOG("read32: Addr=0x%08X Value = 0x%08X", mem, psHu32(IPU_CMD + mem)); } - return *(u32*)(((u8*)ipuRegs) + mem); + return psHu32(IPU_CMD + mem); } __fi u64 ipuRead64(u32 mem) @@ -268,8 +249,8 @@ __fi u64 ipuRead64(u32 mem) switch (mem) { ipucase(IPU_CMD): // IPU_CMD - if (ipuRegs->cmd.DATA & 0xffffff) - IPU_LOG("read64: IPU_CMD=BUSY=%x, DATA=%08X", ipuRegs->cmd.BUSY ? 1 : 0, ipuRegs->cmd.DATA); + if (ipuRegs.cmd.DATA & 0xffffff) + IPU_LOG("read64: IPU_CMD=BUSY=%x, DATA=%08X", ipuRegs.cmd.BUSY ? 1 : 0, ipuRegs.cmd.DATA); break; ipucase(IPU_CTRL): @@ -281,14 +262,14 @@ __fi u64 ipuRead64(u32 mem) break; ipucase(IPU_TOP): // IPU_TOP - IPU_LOG("read64: IPU_TOP=%x, bp = %d", ipuRegs->top, g_BP.BP); + IPU_LOG("read64: IPU_TOP=%x, bp = %d", ipuRegs.top, g_BP.BP); break; default: IPU_LOG("read64: Unknown=%x", mem); break; } - return *(u64*)(((u8*)ipuRegs) + mem); + return psHu64(IPU_CMD + mem); } void ipuSoftReset() @@ -297,17 +278,17 @@ void ipuSoftReset() coded_block_pattern = 0; - ipuRegs->ctrl.reset(); - ipuRegs->top = 0; + ipuRegs.ctrl.reset(); + ipuRegs.top = 0; ipu_cmd.clear(); - ipuRegs->cmd.BUSY = 0; + ipuRegs.cmd.BUSY = 0; g_BP.BP = 0; g_BP.FP = 0; //g_BP.bufferhasnew = 0; } -__fi void ipuWrite32(u32 mem, u32 value) +__fi bool ipuWrite32(u32 mem, u32 value) { // Note: It's assumed that mem's input value is always in the 0x10002000 page // of memory (if not, it's probably bad code). @@ -322,31 +303,29 @@ __fi void ipuWrite32(u32 mem, u32 value) ipucase(IPU_CMD): // IPU_CMD IPU_LOG("write32: IPU_CMD=0x%08X", value); IPUCMD_WRITE(value); - break; + return false; ipucase(IPU_CTRL): // IPU_CTRL // CTRL = the first 16 bits of ctrl [0x8000ffff], + value for the next 16 bits, // minus the reserved bits. (18-19; 27-29) [0x47f30000] - ipuRegs->ctrl.write(value); - if (ipuRegs->ctrl.IDP == 3) + ipuRegs.ctrl.write(value); + if (ipuRegs.ctrl.IDP == 3) { Console.WriteLn("IPU Invalid Intra DC Precision, switching to 9 bits"); - ipuRegs->ctrl.IDP = 1; + ipuRegs.ctrl.IDP = 1; } - if (ipuRegs->ctrl.RST) ipuSoftReset(); // RESET + if (ipuRegs.ctrl.RST) ipuSoftReset(); // RESET IPU_LOG("write32: IPU_CTRL=0x%08X", value); - break; - - default: - IPU_LOG("write32: Unknown=%x", mem); - *(u32*)((u8*)ipuRegs + mem) = value; - break; + return false; } + return true; } -__fi void ipuWrite64(u32 mem, u64 value) +// returns FALSE when the writeback is handled, TRUE if the caller should do the +// writeback itself. +__fi bool ipuWrite64(u32 mem, u64 value) { // Note: It's assumed that mem's input value is always in the 0x10002000 page // of memory (if not, it's probably bad code). @@ -361,13 +340,10 @@ __fi void ipuWrite64(u32 mem, u64 value) ipucase(IPU_CMD): IPU_LOG("write64: IPU_CMD=0x%08X", value); IPUCMD_WRITE((u32)value); - break; - - default: - IPU_LOG("write64: Unknown=%x", mem); - *(u64*)((u8*)ipuRegs + mem) = value; - break; + return false; } + + return true; } @@ -381,28 +357,30 @@ static void ipuBCLR(u32 val) g_BP.BP = val & 0x7F; g_BP.FP = 0; //g_BP.bufferhasnew = 0; - ipuRegs->ctrl.BUSY = 0; - ipuRegs->cmd.BUSY = 0; + ipuRegs.ctrl.BUSY = 0; + ipuRegs.cmd.BUSY = 0; memzero(_readbits); IPU_LOG("Clear IPU input FIFO. Set Bit offset=0x%X", g_BP.BP); } -static BOOL ipuIDEC(u32 val, bool resume) +static bool ipuIDEC(u32 val, bool resume) { tIPU_CMD_IDEC idec(val); if (!resume) { - idec.log(); - g_BP.BP += idec.FB;//skip FB bits + idec.log(); + g_BP.BP += idec.FB;//skip FB bits + //from IPU_CTRL - ipuRegs->ctrl.PCT = I_TYPE; //Intra DECoding;) - decoder.coding_type = ipuRegs->ctrl.PCT; - decoder.mpeg1 = ipuRegs->ctrl.MP1; - decoder.q_scale_type = ipuRegs->ctrl.QST; - decoder.intra_vlc_format = ipuRegs->ctrl.IVF; - decoder.scantype = ipuRegs->ctrl.AS; - decoder.intra_dc_precision = ipuRegs->ctrl.IDP; + ipuRegs.ctrl.PCT = I_TYPE; //Intra DECoding;) + + decoder.coding_type = ipuRegs.ctrl.PCT; + decoder.mpeg1 = ipuRegs.ctrl.MP1; + decoder.q_scale_type = ipuRegs.ctrl.QST; + decoder.intra_vlc_format = ipuRegs.ctrl.IVF; + decoder.scantype = ipuRegs.ctrl.AS; + decoder.intra_dc_precision = ipuRegs.ctrl.IDP; //from IDEC value decoder.quantizer_scale = idec.QSC; @@ -420,22 +398,22 @@ static BOOL ipuIDEC(u32 val, bool resume) static int s_bdec = 0; -static __fi BOOL ipuBDEC(u32 val, bool resume) +static __fi bool ipuBDEC(u32 val, bool resume) { tIPU_CMD_BDEC bdec(val); if (!resume) { - bdec.log(s_bdec); - if (IsDebugBuild) s_bdec++; + bdec.log(s_bdec); + if (IsDebugBuild) s_bdec++; g_BP.BP += bdec.FB;//skip FB bits decoder.coding_type = I_TYPE; - decoder.mpeg1 = ipuRegs->ctrl.MP1; - decoder.q_scale_type = ipuRegs->ctrl.QST; - decoder.intra_vlc_format = ipuRegs->ctrl.IVF; - decoder.scantype = ipuRegs->ctrl.AS; - decoder.intra_dc_precision = ipuRegs->ctrl.IDP; + decoder.mpeg1 = ipuRegs.ctrl.MP1; + decoder.q_scale_type = ipuRegs.ctrl.QST; + decoder.intra_vlc_format = ipuRegs.ctrl.IVF; + decoder.scantype = ipuRegs.ctrl.AS; + decoder.intra_dc_precision = ipuRegs.ctrl.IDP; //from BDEC value decoder.quantizer_scale = decoder.q_scale_type ? non_linear_quantizer_scale [bdec.QSC] : bdec.QSC << 1; @@ -450,13 +428,13 @@ static __fi BOOL ipuBDEC(u32 val, bool resume) return mpeg2_slice(); } -static BOOL __fastcall ipuVDEC(u32 val) +static bool __fastcall ipuVDEC(u32 val) { switch (ipu_cmd.pos[0]) { case 0: - ipuRegs->cmd.DATA = 0; - if (!getBits32((u8*)&decoder.bitstream_buf, 0)) return FALSE; + ipuRegs.cmd.DATA = 0; + if (!getBits32((u8*)&decoder.bitstream_buf, 0)) return false; decoder.bitstream_bits = -16; BigEndian(decoder.bitstream_buf, decoder.bitstream_buf); @@ -464,22 +442,22 @@ static BOOL __fastcall ipuVDEC(u32 val) switch ((val >> 26) & 3) { case 0://Macroblock Address Increment - decoder.mpeg1 = ipuRegs->ctrl.MP1; - ipuRegs->cmd.DATA = get_macroblock_address_increment(); + decoder.mpeg1 = ipuRegs.ctrl.MP1; + ipuRegs.cmd.DATA = get_macroblock_address_increment(); break; case 1://Macroblock Type decoder.frame_pred_frame_dct = 1; - decoder.coding_type = ipuRegs->ctrl.PCT; - ipuRegs->cmd.DATA = get_macroblock_modes(); + decoder.coding_type = ipuRegs.ctrl.PCT; + ipuRegs.cmd.DATA = get_macroblock_modes(); break; case 2://Motion Code - ipuRegs->cmd.DATA = get_motion_delta(0); + ipuRegs.cmd.DATA = get_motion_delta(0); break; case 3://DMVector - ipuRegs->cmd.DATA = get_dmv(); + ipuRegs.cmd.DATA = get_dmv(); break; } @@ -491,42 +469,42 @@ static BOOL __fastcall ipuVDEC(u32 val) ReorderBitstream(); } - ipuRegs->cmd.DATA = (ipuRegs->cmd.DATA & 0xFFFF) | ((decoder.bitstream_bits + 16) << 16); - ipuRegs->ctrl.ECD = (ipuRegs->cmd.DATA == 0); + ipuRegs.cmd.DATA = (ipuRegs.cmd.DATA & 0xFFFF) | ((decoder.bitstream_bits + 16) << 16); + ipuRegs.ctrl.ECD = (ipuRegs.cmd.DATA == 0); case 1: - if (!getBits32((u8*)&ipuRegs->top, 0)) + if (!getBits32((u8*)&ipuRegs.top, 0)) { ipu_cmd.pos[0] = 1; - return FALSE; + return false; } - BigEndian(ipuRegs->top, ipuRegs->top); + BigEndian(ipuRegs.top, ipuRegs.top); IPU_LOG("VDEC command data 0x%x(0x%x). Skip 0x%X bits/Table=%d (%s), pct %d", - ipuRegs->cmd.DATA, ipuRegs->cmd.DATA >> 16, val & 0x3f, (val >> 26) & 3, (val >> 26) & 1 ? - ((val >> 26) & 2 ? "DMV" : "MBT") : (((val >> 26) & 2 ? "MC" : "MBAI")), ipuRegs->ctrl.PCT); - return TRUE; + ipuRegs.cmd.DATA, ipuRegs.cmd.DATA >> 16, val & 0x3f, (val >> 26) & 3, (val >> 26) & 1 ? + ((val >> 26) & 2 ? "DMV" : "MBT") : (((val >> 26) & 2 ? "MC" : "MBAI")), ipuRegs.ctrl.PCT); + return true; jNO_DEFAULT } - return FALSE; + return false; } -static __fi BOOL ipuFDEC(u32 val) +static __fi bool ipuFDEC(u32 val) { - if (!getBits32((u8*)&ipuRegs->cmd.DATA, 0)) return FALSE; + if (!getBits32((u8*)&ipuRegs.cmd.DATA, 0)) return false; - BigEndian(ipuRegs->cmd.DATA, ipuRegs->cmd.DATA); - ipuRegs->top = ipuRegs->cmd.DATA; + BigEndian(ipuRegs.cmd.DATA, ipuRegs.cmd.DATA); + ipuRegs.top = ipuRegs.cmd.DATA; - IPU_LOG("FDEC read: 0x%8.8x", ipuRegs->top); + IPU_LOG("FDEC read: 0x%08x", ipuRegs.top); - return TRUE; + return true; } -static BOOL ipuSETIQ(u32 val) +static bool ipuSETIQ(u32 val) { int i; @@ -536,7 +514,7 @@ static BOOL ipuSETIQ(u32 val) for(;ipu_cmd.pos[0] < 8; ipu_cmd.pos[0]++) { - if (!getBits64((u8*)niq + 8 * ipu_cmd.pos[0], 1)) return FALSE; + if (!getBits64((u8*)niq + 8 * ipu_cmd.pos[0], 1)) return false; } IPU_LOG("Read non-intra quantization matrix from FIFO."); @@ -553,7 +531,7 @@ static BOOL ipuSETIQ(u32 val) for(;ipu_cmd.pos[0] < 8; ipu_cmd.pos[0]++) { - if (!getBits64((u8*)iq + 8 * ipu_cmd.pos[0], 1)) return FALSE; + if (!getBits64((u8*)iq + 8 * ipu_cmd.pos[0], 1)) return false; } IPU_LOG("Read intra quantization matrix from FIFO."); @@ -565,44 +543,44 @@ static BOOL ipuSETIQ(u32 val) } } - return TRUE; + return true; } -static BOOL ipuSETVQ(u32 val) +static bool ipuSETVQ(u32 val) { for(;ipu_cmd.pos[0] < 4; ipu_cmd.pos[0]++) { - if (!getBits64(((u8*)vqclut) + 8 * ipu_cmd.pos[0], 1)) return FALSE; + if (!getBits64(((u8*)vqclut) + 8 * ipu_cmd.pos[0], 1)) return false; } - IPU_LOG("SETVQ command.\nRead VQCLUT table from FIFO."); - IPU_LOG( - "%02d:%02d:%02d %02d:%02d:%02d %02d:%02d:%02d %02d:%02d:%02d " - "%02d:%02d:%02d %02d:%02d:%02d %02d:%02d:%02d %02d:%02d:%02d" - "%02d:%02d:%02d %02d:%02d:%02d %02d:%02d:%02d %02d:%02d:%02d " - "%02d:%02d:%02d %02d:%02d:%02d %02d:%02d:%02d %02d:%02d:%02d", - vqclut[0] >> 10, (vqclut[0] >> 5) & 0x1F, vqclut[0] & 0x1F, - vqclut[1] >> 10, (vqclut[1] >> 5) & 0x1F, vqclut[1] & 0x1F, - vqclut[2] >> 10, (vqclut[2] >> 5) & 0x1F, vqclut[2] & 0x1F, - vqclut[3] >> 10, (vqclut[3] >> 5) & 0x1F, vqclut[3] & 0x1F, - vqclut[4] >> 10, (vqclut[4] >> 5) & 0x1F, vqclut[4] & 0x1F, - vqclut[5] >> 10, (vqclut[5] >> 5) & 0x1F, vqclut[5] & 0x1F, - vqclut[6] >> 10, (vqclut[6] >> 5) & 0x1F, vqclut[6] & 0x1F, - vqclut[7] >> 10, (vqclut[7] >> 5) & 0x1F, vqclut[7] & 0x1F, - vqclut[8] >> 10, (vqclut[8] >> 5) & 0x1F, vqclut[8] & 0x1F, - vqclut[9] >> 10, (vqclut[9] >> 5) & 0x1F, vqclut[9] & 0x1F, - vqclut[10] >> 10, (vqclut[10] >> 5) & 0x1F, vqclut[10] & 0x1F, - vqclut[11] >> 10, (vqclut[11] >> 5) & 0x1F, vqclut[11] & 0x1F, - vqclut[12] >> 10, (vqclut[12] >> 5) & 0x1F, vqclut[12] & 0x1F, - vqclut[13] >> 10, (vqclut[13] >> 5) & 0x1F, vqclut[13] & 0x1F, - vqclut[14] >> 10, (vqclut[14] >> 5) & 0x1F, vqclut[14] & 0x1F, - vqclut[15] >> 10, (vqclut[15] >> 5) & 0x1F, vqclut[15] & 0x1F); + IPU_LOG("SETVQ command.\nRead VQCLUT table from FIFO."); + IPU_LOG( + "%02d:%02d:%02d %02d:%02d:%02d %02d:%02d:%02d %02d:%02d:%02d " + "%02d:%02d:%02d %02d:%02d:%02d %02d:%02d:%02d %02d:%02d:%02d" + "%02d:%02d:%02d %02d:%02d:%02d %02d:%02d:%02d %02d:%02d:%02d " + "%02d:%02d:%02d %02d:%02d:%02d %02d:%02d:%02d %02d:%02d:%02d", + vqclut[0] >> 10, (vqclut[0] >> 5) & 0x1F, vqclut[0] & 0x1F, + vqclut[1] >> 10, (vqclut[1] >> 5) & 0x1F, vqclut[1] & 0x1F, + vqclut[2] >> 10, (vqclut[2] >> 5) & 0x1F, vqclut[2] & 0x1F, + vqclut[3] >> 10, (vqclut[3] >> 5) & 0x1F, vqclut[3] & 0x1F, + vqclut[4] >> 10, (vqclut[4] >> 5) & 0x1F, vqclut[4] & 0x1F, + vqclut[5] >> 10, (vqclut[5] >> 5) & 0x1F, vqclut[5] & 0x1F, + vqclut[6] >> 10, (vqclut[6] >> 5) & 0x1F, vqclut[6] & 0x1F, + vqclut[7] >> 10, (vqclut[7] >> 5) & 0x1F, vqclut[7] & 0x1F, + vqclut[8] >> 10, (vqclut[8] >> 5) & 0x1F, vqclut[8] & 0x1F, + vqclut[9] >> 10, (vqclut[9] >> 5) & 0x1F, vqclut[9] & 0x1F, + vqclut[10] >> 10, (vqclut[10] >> 5) & 0x1F, vqclut[10] & 0x1F, + vqclut[11] >> 10, (vqclut[11] >> 5) & 0x1F, vqclut[11] & 0x1F, + vqclut[12] >> 10, (vqclut[12] >> 5) & 0x1F, vqclut[12] & 0x1F, + vqclut[13] >> 10, (vqclut[13] >> 5) & 0x1F, vqclut[13] & 0x1F, + vqclut[14] >> 10, (vqclut[14] >> 5) & 0x1F, vqclut[14] & 0x1F, + vqclut[15] >> 10, (vqclut[15] >> 5) & 0x1F, vqclut[15] & 0x1F); - return TRUE; + return true; } // IPU Transfers are split into 8Qwords so we need to send ALL the data -static BOOL __fastcall ipuCSC(u32 val) +static bool __fastcall ipuCSC(u32 val) { tIPU_CMD_CSC csc(val); csc.log_from_YCbCr(); @@ -611,7 +589,7 @@ static BOOL __fastcall ipuCSC(u32 val) { for(;ipu_cmd.pos[0] < 48; ipu_cmd.pos[0]++) { - if (!getBits64((u8*)&decoder.mb8 + 8 * ipu_cmd.pos[0], 1)) return FALSE; + if (!getBits64((u8*)&decoder.mb8 + 8 * ipu_cmd.pos[0], 1)) return false; } ipu_csc(decoder.mb8, decoder.rgb32, 0); @@ -623,7 +601,7 @@ static BOOL __fastcall ipuCSC(u32 val) { ipu_cmd.pos[1] += ipu_fifo.out.write(((u32*) & decoder.rgb16) + 4 * ipu_cmd.pos[1], 32 - ipu_cmd.pos[1]); - if (ipu_cmd.pos[1] <= 0) return FALSE; + if (ipu_cmd.pos[1] <= 0) return false; } } else @@ -632,7 +610,7 @@ static BOOL __fastcall ipuCSC(u32 val) { ipu_cmd.pos[1] += ipu_fifo.out.write(((u32*) & decoder.rgb32) + 4 * ipu_cmd.pos[1], 64 - ipu_cmd.pos[1]); - if (ipu_cmd.pos[1] <= 0) return FALSE; + if (ipu_cmd.pos[1] <= 0) return false; } } @@ -640,11 +618,11 @@ static BOOL __fastcall ipuCSC(u32 val) ipu_cmd.pos[1] = 0; } - return TRUE; + return true; } // Todo - Need to add the same stop and start code as CSC -static BOOL ipuPACK(u32 val) +static bool ipuPACK(u32 val) { tIPU_CMD_CSC csc(val); csc.log_from_RGB32(); @@ -653,7 +631,7 @@ static BOOL ipuPACK(u32 val) { for(;ipu_cmd.pos[0] < 8; ipu_cmd.pos[0]++) { - if (!getBits64((u8*)&decoder.mb8 + 8 * ipu_cmd.pos[0], 1)) return FALSE; + if (!getBits64((u8*)&decoder.mb8 + 8 * ipu_cmd.pos[0], 1)) return false; } ipu_csc(decoder.mb8, decoder.rgb32, 0); @@ -665,13 +643,13 @@ static BOOL ipuPACK(u32 val) { ipu_cmd.pos[1] += ipu_fifo.out.write(((u32*) & decoder.rgb16) + 4 * ipu_cmd.pos[1], 32 - ipu_cmd.pos[1]); - if (ipu_cmd.pos[1] < 32) return FALSE; + if (ipu_cmd.pos[1] < 32) return false; } else { ipu_cmd.pos[1] += ipu_fifo.out.write(((u32*)indx4) + 4 * ipu_cmd.pos[1], 8 - ipu_cmd.pos[1]); - if (ipu_cmd.pos[1] < 8) return FALSE; + if (ipu_cmd.pos[1] < 8) return false; } ipu_cmd.pos[0] = 0; @@ -688,217 +666,77 @@ static void ipuSETTH(u32 val) IPU_LOG("SETTH (Set threshold value)command %x.", val&0xff00ff); } -/////////////////////// -// IPU Worker Thread // -/////////////////////// -__fi void IPU_INTERRUPT() //dma +// -------------------------------------------------------------------------------------- +// CORE Functions (referenced from MPEG library) +// -------------------------------------------------------------------------------------- +__fi void ipu_csc(macroblock_8& mb8, macroblock_rgb32& rgb32, int sgn) { - hwIntcIrq(INTC_IPU); -} + int i; + u8* p = (u8*)&rgb32; -void IPUCMD_WRITE(u32 val) -{ - // don't process anything if currently busy - if (ipuRegs->ctrl.BUSY) Console.WriteLn("IPU BUSY!"); // wait for thread + yuv2rgb(); - ipuRegs->ctrl.ECD = 0; - ipuRegs->ctrl.SCD = 0; //clear ECD/SCD - ipu_cmd.clear(); - ipu_cmd.current = val; - - switch (val >> 28) + if (s_thresh[0] > 0) { - case SCE_IPU_BCLR: - ipuBCLR(val); - IPU_INTERRUPT(); //DMAC_TO_IPU - return; - - case SCE_IPU_VDEC: - - g_BP.BP += val & 0x3F; - - // check if enough data in queue - if (ipuVDEC(val)) return; - - ipuRegs->cmd.BUSY = 0x80000000; - ipuRegs->topbusy = 0x80000000; - break; - - case SCE_IPU_FDEC: - IPU_LOG("FDEC command. Skip 0x%X bits, FIFO 0x%X qwords, BP 0x%X, FP %d, CHCR 0x%x, %x", - val & 0x3f, g_BP.IFC, (int)g_BP.BP, g_BP.FP, ipu1dma->chcr._u32, cpuRegs.pc); - g_BP.BP += val & 0x3F; - if (ipuFDEC(val)) return; - ipuRegs->cmd.BUSY = 0x80000000; - ipuRegs->topbusy = 0x80000000; - break; - - case SCE_IPU_SETTH: - ipuSETTH(val); - hwIntcIrq(INTC_IPU); - return; - - case SCE_IPU_SETIQ: - IPU_LOG("SETIQ command."); - if (val & 0x3f) IPU_LOG("Skip %d bits.", val & 0x3f); - g_BP.BP += val & 0x3F; - if (ipuSETIQ(val)) return; - break; - - case SCE_IPU_SETVQ: - if (ipuSETVQ(val)) return; - break; - - case SCE_IPU_CSC: - ipu_cmd.pos[1] = 0; - ipu_cmd.index = 0; - - if (ipuCSC(val)) - { - if (ipu0dma->qwc > 0 && ipu0dma->chcr.STR) IPU_INT0_FROM(); - return; - } - break; - - case SCE_IPU_PACK: - ipu_cmd.pos[1] = 0; - ipu_cmd.index = 0; - if (ipuPACK(val)) return; - break; - - case SCE_IPU_IDEC: - if (ipuIDEC(val, false)) - { - // idec done, ipu0 done too - if (ipu0dma->qwc > 0 && ipu0dma->chcr.STR) IPU_INT0_FROM(); - return; - } - - ipuRegs->topbusy = 0x80000000; - break; - - case SCE_IPU_BDEC: - if (ipuBDEC(val, false)) - { - if (ipu0dma->qwc > 0 && ipu0dma->chcr.STR) IPU_INT0_FROM(); - if (ipuRegs->ctrl.SCD || ipuRegs->ctrl.ECD) hwIntcIrq(INTC_IPU); - return; - } - else - { - ipuRegs->topbusy = 0x80000000; + for (i = 0; i < 16*16; i++, p += 4) + { + if ((p[0] < s_thresh[0]) && (p[1] < s_thresh[0]) && (p[2] < s_thresh[0])) + *(u32*)p = 0; + else if ((p[0] < s_thresh[1]) && (p[1] < s_thresh[1]) && (p[2] < s_thresh[1])) + p[3] = 0x40; + } } - } - - // have to resort to the thread - ipuRegs->ctrl.BUSY = 1; - if(ipu1dma->chcr.STR == false) hwIntcIrq(INTC_IPU); -} - -void IPUWorker() -{ - pxAssert(ipuRegs->ctrl.BUSY); - - switch (ipu_cmd.CMD) + else if (s_thresh[1] > 0) { - case SCE_IPU_VDEC: - if (!ipuVDEC(ipu_cmd.current)) - { - if(ipu1dma->chcr.STR == false) hwIntcIrq(INTC_IPU); - return; - } - ipuRegs->cmd.BUSY = 0; - ipuRegs->topbusy = 0; - break; - - case SCE_IPU_FDEC: - if (!ipuFDEC(ipu_cmd.current)) - { - if(ipu1dma->chcr.STR == false) hwIntcIrq(INTC_IPU); - return; - } - ipuRegs->cmd.BUSY = 0; - ipuRegs->topbusy = 0; - break; - - case SCE_IPU_SETIQ: - if (!ipuSETIQ(ipu_cmd.current)) - { - if(ipu1dma->chcr.STR == false) hwIntcIrq(INTC_IPU); - return; - } - break; - - case SCE_IPU_SETVQ: - if (!ipuSETVQ(ipu_cmd.current)) - { - if(ipu1dma->chcr.STR == false) hwIntcIrq(INTC_IPU); - return; - } - break; - - case SCE_IPU_CSC: - if (!ipuCSC(ipu_cmd.current)) - { - if(ipu1dma->chcr.STR == false) hwIntcIrq(INTC_IPU); - return; - } - if (ipu0dma->qwc > 0 && ipu0dma->chcr.STR) IPU_INT0_FROM(); - break; - - case SCE_IPU_PACK: - if (!ipuPACK(ipu_cmd.current)) - { - if(ipu1dma->chcr.STR == false) hwIntcIrq(INTC_IPU); - return; - } - break; - - case SCE_IPU_IDEC: - if (!ipuIDEC(ipu_cmd.current, true)) - { - if(ipu1dma->chcr.STR == false) hwIntcIrq(INTC_IPU); - return; - } - - ipuRegs->ctrl.OFC = 0; - ipuRegs->ctrl.BUSY = 0; - ipuRegs->topbusy = 0; - ipuRegs->cmd.BUSY = 0; - ipu_cmd.current = 0xffffffff; - - // CHECK!: IPU0dma remains when IDEC is done, so we need to clear it - if (ipu0dma->qwc > 0 && ipu0dma->chcr.STR) IPU_INT0_FROM(); - break; - - case SCE_IPU_BDEC: - if (!ipuBDEC(ipu_cmd.current, true)) - { - if(ipu1dma->chcr.STR == false) hwIntcIrq(INTC_IPU); - return; - } - - ipuRegs->ctrl.BUSY = 0; - ipuRegs->topbusy = 0; - ipuRegs->cmd.BUSY = 0; - ipu_cmd.current = 0xffffffff; - - if (ipu0dma->qwc > 0 && ipu0dma->chcr.STR) IPU_INT0_FROM(); - if (ipuRegs->ctrl.SCD || ipuRegs->ctrl.ECD) hwIntcIrq(INTC_IPU); - return; - - default: - Console.WriteLn("Unknown IPU command: %08x", ipu_cmd.current); - break; + for (i = 0; i < 16*16; i++, p += 4) + { + if ((p[0] < s_thresh[1]) && (p[1] < s_thresh[1]) && (p[2] < s_thresh[1])) + p[3] = 0x40; + } + } + if (sgn) + { + for (i = 0; i < 16*16; i++, p += 4) + { + *(u32*)p ^= 0x808080; + } } - - // success - ipuRegs->ctrl.BUSY = 0; - ipu_cmd.current = 0xffffffff; } -///////////////// -// Buffer reader +__fi void ipu_dither(const macroblock_rgb32& rgb32, macroblock_rgb16& rgb16, int dte) +{ + int i, j; + for (i = 0; i < 16; ++i) + { + for (j = 0; j < 16; ++j) + { + rgb16.c[i][j].r = rgb32.c[i][j].r >> 3; + rgb16.c[i][j].g = rgb32.c[i][j].g >> 3; + rgb16.c[i][j].b = rgb32.c[i][j].b >> 3; + rgb16.c[i][j].a = rgb32.c[i][j].a == 0x40; + } + } +} + +__fi void ipu_vq(macroblock_rgb16& rgb16, u8* indx4) +{ + Console.Error("IPU: VQ not implemented"); +} + +__fi void ipu_copy(const macroblock_8& mb8, macroblock_16& mb16) +{ + const u8 *s = (const u8*)&mb8; + s16 *d = (s16*)&mb16; + int i; + for (i = 0; i < 256; i++) *d++ = *s++; //Y bias - 16 + for (i = 0; i < 64; i++) *d++ = *s++; //Cr bias - 128 + for (i = 0; i < 64; i++) *d++ = *s++; //Cb bias - 128 +} + + +// -------------------------------------------------------------------------------------- +// Buffer reader +// -------------------------------------------------------------------------------------- // move the readbits queue __fi void inc_readbits() @@ -1123,542 +961,207 @@ u8 __fastcall getBits8(u8 *address, u32 advance) return 1; } -///////////////////// CORE FUNCTIONS ///////////////// -void Skl_YUV_To_RGB32_MMX(u8 *RGB, const int Dst_BpS, const u8 *Y, const u8 *U, const u8 *V, - const int Src_BpS, const int Width, const int Height); - -__fi void ipu_csc(macroblock_8& mb8, macroblock_rgb32& rgb32, int sgn) +// -------------------------------------------------------------------------------------- +// IPU Worker / Dispatcher +// -------------------------------------------------------------------------------------- +void IPUCMD_WRITE(u32 val) { - int i; - u8* p = (u8*)&rgb32; + // don't process anything if currently busy + if (ipuRegs.ctrl.BUSY) Console.WriteLn("IPU BUSY!"); // wait for thread - yuv2rgb(); + ipuRegs.ctrl.ECD = 0; + ipuRegs.ctrl.SCD = 0; //clear ECD/SCD + ipu_cmd.clear(); + ipu_cmd.current = val; - if (s_thresh[0] > 0) + switch (val >> 28) { - for (i = 0; i < 16*16; i++, p += 4) - { - if ((p[0] < s_thresh[0]) && (p[1] < s_thresh[0]) && (p[2] < s_thresh[0])) - *(u32*)p = 0; - else if ((p[0] < s_thresh[1]) && (p[1] < s_thresh[1]) && (p[2] < s_thresh[1])) - p[3] = 0x40; - } - } - else if (s_thresh[1] > 0) - { - for (i = 0; i < 16*16; i++, p += 4) - { - if ((p[0] < s_thresh[1]) && (p[1] < s_thresh[1]) && (p[2] < s_thresh[1])) - p[3] = 0x40; - } - } - if (sgn) - { - for (i = 0; i < 16*16; i++, p += 4) - { - *(u32*)p ^= 0x808080; - } - } -} + case SCE_IPU_BCLR: + ipuBCLR(val); + hwIntcIrq(INTC_IPU); //DMAC_TO_IPU + return; -__fi void ipu_dither(const macroblock_rgb32& rgb32, macroblock_rgb16& rgb16, int dte) -{ - int i, j; - for (i = 0; i < 16; ++i) - { - for (j = 0; j < 16; ++j) - { - rgb16.c[i][j].r = rgb32.c[i][j].r >> 3; - rgb16.c[i][j].g = rgb32.c[i][j].g >> 3; - rgb16.c[i][j].b = rgb32.c[i][j].b >> 3; - rgb16.c[i][j].a = rgb32.c[i][j].a == 0x40; - } - } -} + case SCE_IPU_VDEC: -__fi void ipu_vq(macroblock_rgb16& rgb16, u8* indx4) -{ - Console.Error("IPU: VQ not implemented"); -} + g_BP.BP += val & 0x3F; -__fi void ipu_copy(const macroblock_8& mb8, macroblock_16& mb16) -{ - const u8 *s = (const u8*)&mb8; - s16 *d = (s16*)&mb16; - int i; - for (i = 0; i < 256; i++) *d++ = *s++; //Y bias - 16 - for (i = 0; i < 64; i++) *d++ = *s++; //Cr bias - 128 - for (i = 0; i < 64; i++) *d++ = *s++; //Cb bias - 128 -} + // check if enough data in queue + if (ipuVDEC(val)) return; + ipuRegs.cmd.BUSY = 0x80000000; + ipuRegs.topbusy = 0x80000000; + break; + case SCE_IPU_FDEC: + IPU_LOG("FDEC command. Skip 0x%X bits, FIFO 0x%X qwords, BP 0x%X, FP %d, CHCR 0x%x", + val & 0x3f, g_BP.IFC, (int)g_BP.BP, g_BP.FP, ipu1dma.chcr._u32); + g_BP.BP += val & 0x3F; + if (ipuFDEC(val)) return; + ipuRegs.cmd.BUSY = 0x80000000; + ipuRegs.topbusy = 0x80000000; + break; -static __fi bool ipuDmacPartialChain(tDMA_TAG tag) -{ - switch (tag.ID) - { - case TAG_REFE: // refe - ipu1dma->tadr += 16; - return true; + case SCE_IPU_SETTH: + ipuSETTH(val); + hwIntcIrq(INTC_IPU); + return; - case TAG_END: // end - ipu1dma->tadr = ipu1dma->madr; - return true; - } - return false; -} + case SCE_IPU_SETIQ: + IPU_LOG("SETIQ command."); + if (val & 0x3f) IPU_LOG("Skip %d bits.", val & 0x3f); + g_BP.BP += val & 0x3F; + if (ipuSETIQ(val)) return; + break; -extern void gsInterrupt(); -extern void vif1Interrupt(); + case SCE_IPU_SETVQ: + if (ipuSETVQ(val)) return; + break; -static __fi void ipuDmacSrcChain() -{ + case SCE_IPU_CSC: + ipu_cmd.pos[1] = 0; + ipu_cmd.index = 0; - switch (IPU1Status.ChainMode) - { - case TAG_REFE: // refe - //if(IPU1Status.InProgress == false) ipu1dma->tadr += 16; - IPU1Status.DMAFinished = true; - break; - case TAG_CNT: // cnt - // Set the taddr to the next tag - ipu1dma->tadr = ipu1dma->madr; - //if(IPU1Status.DMAFinished == false) IPU1Status.DMAFinished = false; - break; - - case TAG_NEXT: // next - ipu1dma->tadr = IPU1Status.NextMem; - //if(IPU1Status.DMAFinished == false) IPU1Status.DMAFinished = false; - break; - - case TAG_REF: // ref - //if(IPU1Status.InProgress == false)ipu1dma->tadr += 16; - //if(IPU1Status.DMAFinished == false) IPU1Status.DMAFinished = false; - break; - - case TAG_END: // end - ipu1dma->tadr = ipu1dma->madr; - IPU1Status.DMAFinished = true; - break; - } -} - -static __fi bool WaitGSPaths() -{ - if(CHECK_IPUWAITHACK) - { - if(GSTransferStatus.PTH3 < STOPPED_MODE && GSTransferStatus.PTH3 != IDLE_MODE) - { - //GIF_LOG("Flushing gif chcr %x tadr %x madr %x qwc %x", gif->chcr._u32, gif->tadr, gif->madr, gif->qwc); - //DevCon.WriteLn("Waiting for GIF"); - return false; - } - - if(GSTransferStatus.PTH2 != STOPPED_MODE) - { - //DevCon.WriteLn("Waiting for VIF"); - return false; - } - if(GSTransferStatus.PTH1 != STOPPED_MODE) - { - //DevCon.WriteLn("Waiting for VU"); - return false; - } - } - return true; -} - -static __fi int IPU1chain() { - - int totalqwc = 0; - - if (ipu1dma->qwc > 0 && IPU1Status.InProgress == true) - { - int qwc = ipu1dma->qwc; - u32 *pMem; - - pMem = (u32*)dmaGetAddr(ipu1dma->madr, false); - - if (pMem == NULL) - { - Console.Error("ipu1dma NULL!"); - return totalqwc; - } - - //Write our data to the fifo - qwc = ipu_fifo.in.write(pMem, qwc); - ipu1dma->madr += qwc << 4; - ipu1dma->qwc -= qwc; - totalqwc += qwc; - } - if( ipu1dma->qwc == 0) - { - //Update TADR etc - if(IPU1Status.DMAMode == DMA_MODE_CHAIN) ipuDmacSrcChain(); - //If the transfer has finished or we have room in the FIFO, schedule to the interrupt code. - - //No data left - IPU1Status.InProgress = false; - } //If we still have data the commands should pull this across when need be. - - return totalqwc; -} - -//static __fi bool WaitGSPaths() -//{ -// //Wait for all GS paths to be clear -// if (GSTransferStatus._u32 != 0x2a) -// { -// if(GSTransferStatus.PTH3 != STOPPED_MODE && vif1Regs->mskpath3) return true; -// IPU_LOG("Waiting for GS transfers to finish %x", GSTransferStatus._u32); -// IPU_INT_TO(4); -// return false; -// } -// return true; -//} - - - -int IPU1dma() -{ - int ipu1cycles = 0; - int totalqwc = 0; - - //We need to make sure GIF has flushed before sending IPU data, it seems to REALLY screw FFX videos - //if(!WaitGSPaths()) return totalqwc; - - if(ipu1dma->chcr.STR == false || IPU1Status.DMAMode == 2) - { - //We MUST stop the IPU from trying to fill the FIFO with more data if the DMA has been suspended - //if we don't, we risk causing the data to go out of sync with the fifo and we end up losing some! - //This is true for Dragons Quest 8 and probably others which suspend the DMA. - DevCon.Warning("IPU1 running when IPU1 DMA disabled! CHCR %x QWC %x", ipu1dma->chcr._u32, ipu1dma->qwc); - return 0; - } - - IPU_LOG("IPU1 DMA Called QWC %x Finished %d In Progress %d tadr %x", ipu1dma->qwc, IPU1Status.DMAFinished, IPU1Status.InProgress, ipu1dma->tadr); - - switch(IPU1Status.DMAMode) - { - case DMA_MODE_NORMAL: + if (ipuCSC(val)) { - if(!WaitGSPaths()) - { // legacy WaitGSPaths() for now - IPU_INT_TO(4); //Give it a short wait. - return totalqwc; - } - IPU_LOG("Processing Normal QWC left %x Finished %d In Progress %d", ipu1dma->qwc, IPU1Status.DMAFinished, IPU1Status.InProgress); - if(IPU1Status.InProgress == true) totalqwc += IPU1chain(); + IPU_INT0_FROM(); + return; } break; - case DMA_MODE_CHAIN: + case SCE_IPU_PACK: + ipu_cmd.pos[1] = 0; + ipu_cmd.index = 0; + if (ipuPACK(val)) return; + break; + + case SCE_IPU_IDEC: + if (ipuIDEC(val, false)) { - if(IPU1Status.InProgress == true) //No transfer is ready to go so we need to set one up - { - if(!WaitGSPaths()) - { // legacy WaitGSPaths() for now - IPU_INT_TO(4); //Give it a short wait. - return totalqwc; - } - IPU_LOG("Processing Chain QWC left %x Finished %d In Progress %d", ipu1dma->qwc, IPU1Status.DMAFinished, IPU1Status.InProgress); - totalqwc += IPU1chain(); - //Set the TADR forward - } + // idec done, ipu0 done too + IPU_INT0_FROM(); + return; + } + ipuRegs.topbusy = 0x80000000; + break; - if(IPU1Status.InProgress == false && IPU1Status.DMAFinished == false) //No transfer is ready to go so we need to set one up - { - tDMA_TAG* ptag = dmaGetAddr(ipu1dma->tadr, false); //Set memory pointer to TADR - - if (!ipu1dma->transfer("IPU1", ptag)) - { - return totalqwc; - } - - ipu1cycles += 1; // Add 1 cycles from the QW read for the tag - IPU1Status.ChainMode = ptag->ID; - - if(ipu1dma->chcr.TTE) DevCon.Warning("TTE?"); - - switch (IPU1Status.ChainMode) - { - case TAG_REFE: // refe - // do not change tadr - //ipu1dma->tadr += 16; - ipu1dma->tadr += 16; - ipu1dma->madr = ptag[1]._u32; - IPU_LOG("Tag should end on %x", ipu1dma->tadr); - - break; - - case TAG_CNT: // cnt - ipu1dma->madr = ipu1dma->tadr + 16; - IPU_LOG("Tag should end on %x", ipu1dma->madr + ipu1dma->qwc * 16); - //ipu1dma->tadr = ipu1dma->madr + (ipu1dma->qwc * 16); - // Set the taddr to the next tag - //IPU1Status.DMAFinished = false; - break; - - case TAG_NEXT: // next - ipu1dma->madr = ipu1dma->tadr + 16; - IPU1Status.NextMem = ptag[1]._u32; - IPU_LOG("Tag should end on %x", IPU1Status.NextMem); - //IPU1Status.DMAFinished = false; - break; - - case TAG_REF: // ref - ipu1dma->madr = ptag[1]._u32; - ipu1dma->tadr += 16; - IPU_LOG("Tag should end on %x", ipu1dma->tadr); - //IPU1Status.DMAFinished = false; - break; - - case TAG_END: // end - // do not change tadr - ipu1dma->madr = ipu1dma->tadr + 16; - ipu1dma->tadr += 16; - IPU_LOG("Tag should end on %x", ipu1dma->madr + ipu1dma->qwc * 16); - - break; - - default: - Console.Error("IPU ERROR: different transfer mode!, Please report to PCSX2 Team"); - break; - } - - //if(ipu1dma->qwc == 0) Console.Warning("Blank QWC!"); - if(ipu1dma->qwc > 0) IPU1Status.InProgress = true; - IPU_LOG("dmaIPU1 dmaChain %8.8x_%8.8x size=%d, addr=%lx, fifosize=%x", - ptag[1]._u32, ptag[0]._u32, ipu1dma->qwc, ipu1dma->madr, 8 - g_BP.IFC); - - if (ipu1dma->chcr.TIE && ptag->IRQ) //Tag Interrupt is set, so schedule the end/interrupt - IPU1Status.DMAFinished = true; - - - if(!WaitGSPaths() && ipu1dma->qwc > 0) - { // legacy WaitGSPaths() for now - IPU_INT_TO(4); //Give it a short wait. - return totalqwc; - } - IPU_LOG("Processing Start Chain QWC left %x Finished %d In Progress %d", ipu1dma->qwc, IPU1Status.DMAFinished, IPU1Status.InProgress); - totalqwc += IPU1chain(); - //Set the TADR forward - } - + case SCE_IPU_BDEC: + if (ipuBDEC(val, false)) + { + IPU_INT0_FROM(); + if (ipuRegs.ctrl.SCD || ipuRegs.ctrl.ECD) hwIntcIrq(INTC_IPU); + return; + } + else + { + ipuRegs.topbusy = 0x80000000; } break; } - //Do this here to prevent double settings on Chain DMA's - if(totalqwc > 0 || ipu1dma->qwc == 0) - { - IPU_INT_TO(totalqwc * BIAS); - if(ipuRegs->ctrl.BUSY && g_BP.IFC) IPUWorker(); - } - else - { - cpuRegs.eCycle[4] = 0x9999;//IPU_INT_TO(2048); - } - - IPU_LOG("Completed Call IPU1 DMA QWC Remaining %x Finished %d In Progress %d tadr %x", ipu1dma->qwc, IPU1Status.DMAFinished, IPU1Status.InProgress, ipu1dma->tadr); - return totalqwc; + // have to resort to the thread + ipuRegs.ctrl.BUSY = 1; + if(ipu1dma.chcr.STR == false) hwIntcIrq(INTC_IPU); } -int IPU0dma() +void IPUWorker() { - int readsize; - static int totalsize = 0; - tDMA_TAG* pMem; + pxAssert(ipuRegs.ctrl.BUSY); - if ((!(ipu0dma->chcr.STR) || (cpuRegs.interrupt & (1 << DMAC_FROM_IPU))) || (ipu0dma->qwc == 0)) - return 0; - - pxAssert(!(ipu0dma->chcr.TTE)); - - IPU_LOG("dmaIPU0 chcr = %lx, madr = %lx, qwc = %lx", - ipu0dma->chcr._u32, ipu0dma->madr, ipu0dma->qwc); - - pxAssert(ipu0dma->chcr.MOD == NORMAL_MODE); - - pMem = dmaGetAddr(ipu0dma->madr, true); - - readsize = min(ipu0dma->qwc, (u16)ipuRegs->ctrl.OFC); - totalsize+=readsize; - ipu_fifo.out.read(pMem, readsize); - - ipu0dma->madr += readsize << 4; - ipu0dma->qwc -= readsize; // note: qwc is u16 - - if (ipu0dma->qwc == 0) + switch (ipu_cmd.CMD) { - if (dmacRegs->ctrl.STS == STS_fromIPU) // STS == fromIPU - { - dmacRegs->stadr.ADDR = ipu0dma->madr; - switch (dmacRegs->ctrl.STD) + case SCE_IPU_VDEC: + if (!ipuVDEC(ipu_cmd.current)) { - case NO_STD: - break; - case STD_GIF: // GIF - Console.Warning("GIFSTALL"); - g_nDMATransfer.GIFSTALL = true; - break; - case STD_VIF1: // VIF - Console.Warning("VIFSTALL"); - g_nDMATransfer.VIFSTALL = true; - break; - case STD_SIF1: - Console.Warning("SIFSTALL"); - g_nDMATransfer.SIFSTALL = true; - break; + if(ipu1dma.chcr.STR == false) hwIntcIrq(INTC_IPU); + return; } - } - //Fixme ( voodoocycles ): - //This was IPU_INT_FROM(readsize*BIAS ); - //This broke vids in Digital Devil Saga - //Note that interrupting based on totalsize is just guessing.. - IPU_INT_FROM( readsize * BIAS ); - totalsize = 0; + ipuRegs.cmd.BUSY = 0; + ipuRegs.topbusy = 0; + break; + + case SCE_IPU_FDEC: + if (!ipuFDEC(ipu_cmd.current)) + { + if(ipu1dma.chcr.STR == false) hwIntcIrq(INTC_IPU); + return; + } + ipuRegs.cmd.BUSY = 0; + ipuRegs.topbusy = 0; + break; + + case SCE_IPU_SETIQ: + if (!ipuSETIQ(ipu_cmd.current)) + { + if(ipu1dma.chcr.STR == false) hwIntcIrq(INTC_IPU); + return; + } + break; + + case SCE_IPU_SETVQ: + if (!ipuSETVQ(ipu_cmd.current)) + { + if(ipu1dma.chcr.STR == false) hwIntcIrq(INTC_IPU); + return; + } + break; + + case SCE_IPU_CSC: + if (!ipuCSC(ipu_cmd.current)) + { + if(ipu1dma.chcr.STR == false) hwIntcIrq(INTC_IPU); + return; + } + IPU_INT0_FROM(); + break; + + case SCE_IPU_PACK: + if (!ipuPACK(ipu_cmd.current)) + { + if(ipu1dma.chcr.STR == false) hwIntcIrq(INTC_IPU); + return; + } + break; + + case SCE_IPU_IDEC: + if (!ipuIDEC(ipu_cmd.current, true)) + { + if(ipu1dma.chcr.STR == false) hwIntcIrq(INTC_IPU); + return; + } + + ipuRegs.ctrl.OFC = 0; + ipuRegs.ctrl.BUSY = 0; + ipuRegs.topbusy = 0; + ipuRegs.cmd.BUSY = 0; + ipu_cmd.current = 0xffffffff; + + // CHECK!: IPU0dma remains when IDEC is done, so we need to clear it + IPU_INT0_FROM(); + break; + + case SCE_IPU_BDEC: + if (!ipuBDEC(ipu_cmd.current, true)) + { + if(ipu1dma.chcr.STR == false) hwIntcIrq(INTC_IPU); + return; + } + + ipuRegs.ctrl.BUSY = 0; + ipuRegs.topbusy = 0; + ipuRegs.cmd.BUSY = 0; + ipu_cmd.current = 0xffffffff; + + IPU_INT0_FROM(); + if (ipuRegs.ctrl.SCD || ipuRegs.ctrl.ECD) hwIntcIrq(INTC_IPU); + return; + + default: + Console.WriteLn("Unknown IPU command: %08x", ipu_cmd.current); + break; } - return readsize; -} - -__fi void dmaIPU0() // fromIPU -{ - if (ipu0dma->pad != 0) - { - // Note: pad is the padding right above qwc, so we're testing whether qwc - // has overflowed into pad. - DevCon.Warning(L"IPU0dma's upper 16 bits set to %x\n", ipu0dma->pad); - ipu0dma->qwc = ipu0dma->pad = 0; - //If we are going to clear down IPU0, we should end it too. Going to test this scenario on the PS2 mind - Refraction - ipu0dma->chcr.STR = false; - hwDmacIrq(DMAC_FROM_IPU); - } - if (ipuRegs->ctrl.BUSY) IPUWorker(); -} - -__fi void dmaIPU1() // toIPU -{ - IPU_LOG("IPU1DMAStart QWC %x, MADR %x, CHCR %x, TADR %x", ipu1dma->qwc, ipu1dma->madr, ipu1dma->chcr._u32, ipu1dma->tadr); - - if (ipu1dma->pad != 0) - { - // Note: pad is the padding right above qwc, so we're testing whether qwc - // has overflowed into pad. - DevCon.Warning(L"IPU1dma's upper 16 bits set to %x\n", ipu1dma->pad); - ipu1dma->qwc = ipu1dma->pad = 0; - // If we are going to clear down IPU1, we should end it too. - // Going to test this scenario on the PS2 mind - Refraction - ipu1dma->chcr.STR = false; - hwDmacIrq(DMAC_TO_IPU); - } - - if (ipu1dma->chcr.MOD == CHAIN_MODE) //Chain Mode - { - IPU_LOG("Setting up IPU1 Chain mode"); - if(ipu1dma->qwc == 0) - { - IPU1Status.InProgress = false; - IPU1Status.DMAFinished = false; - } - else - { //Attempting to continue a previous chain - IPU_LOG("Resuming DMA TAG %x", (ipu1dma->chcr.TAG >> 12)); - //We MUST check the CHCR for the tag it last knew, it can be manipulated! - IPU1Status.ChainMode = (ipu1dma->chcr.TAG >> 12) & 0x7; - IPU1Status.InProgress = true; - IPU1Status.DMAFinished = ((ipu1dma->chcr.TAG >> 15) && ipu1dma->chcr.TIE) ? true : false; - } - - IPU1Status.DMAMode = DMA_MODE_CHAIN; - IPU1dma(); - } - else //Normal Mode - { - if(ipu1dma->qwc == 0) - { - ipu1dma->chcr.STR = false; - // Hack to force stop IPU - ipuRegs->cmd.BUSY = 0; - ipuRegs->ctrl.BUSY = 0; - ipuRegs->topbusy = 0; - // - hwDmacIrq(DMAC_TO_IPU); - Console.Warning("IPU1 Normal error!"); - } - else - { - IPU_LOG("Setting up IPU1 Normal mode"); - IPU1Status.InProgress = true; - IPU1Status.DMAFinished = true; - IPU1Status.DMAMode = DMA_MODE_NORMAL; - IPU1dma(); - } - } -} - -extern void GIFdma(); - -void ipu0Interrupt() -{ - IPU_LOG("ipu0Interrupt: %x", cpuRegs.cycle); - - if (g_nDMATransfer.FIREINT0) - { - g_nDMATransfer.FIREINT0 = false; - hwIntcIrq(INTC_IPU); - } - - if (g_nDMATransfer.GIFSTALL) - { - // gif - Console.Warning("IPU GIF Stall"); - g_nDMATransfer.GIFSTALL = false; - //if (gif->chcr.STR) GIFdma(); - } - - if (g_nDMATransfer.VIFSTALL) - { - // vif - Console.Warning("IPU VIF Stall"); - g_nDMATransfer.VIFSTALL = false; - //if (vif1ch->chcr.STR) dmaVIF1(); - } - - if (g_nDMATransfer.SIFSTALL) - { - // sif - Console.Warning("IPU SIF Stall"); - g_nDMATransfer.SIFSTALL = false; - - // Not totally sure whether this needs to be done or not, so I'm - // leaving it commented out for the moment. - //if (sif1dma->chcr.STR) SIF1Dma(); - } - - if (g_nDMATransfer.TIE0) - { - g_nDMATransfer.TIE0 = false; - } - - ipu0dma->chcr.STR = false; - hwDmacIrq(DMAC_FROM_IPU); -} - -IPU_FORCEINLINE void ipu1Interrupt() -{ - IPU_LOG("ipu1Interrupt %x:", cpuRegs.cycle); - - if(IPU1Status.DMAFinished == false || IPU1Status.InProgress == true) //Sanity Check - { - IPU1dma(); - return; - } - - IPU_LOG("ipu1 finish %x:", cpuRegs.cycle); - ipu1dma->chcr.STR = false; - IPU1Status.DMAMode = 2; - hwDmacIrq(DMAC_TO_IPU); + // success + ipuRegs.ctrl.BUSY = 0; + ipu_cmd.current = 0xffffffff; } diff --git a/pcsx2/IPU/IPU.h b/pcsx2/IPU/IPU.h index 6bfb1196fb..e33c211b3e 100644 --- a/pcsx2/IPU/IPU.h +++ b/pcsx2/IPU/IPU.h @@ -17,10 +17,6 @@ #include "IPU_Fifo.h" -#ifdef _MSC_VER -//#pragma pack(1) -#endif - #define ipumsk( src ) ( (src) & 0xff ) #define ipucase( src ) case ipumsk(src) @@ -29,26 +25,6 @@ #define IPU_FORCEINLINE __fi -struct IPUStatus { - bool InProgress; - u8 DMAMode; - bool DMAFinished; - bool IRQTriggered; - u8 TagFollow; - u32 TagAddr; - bool stalled; - u8 ChainMode; - u32 NextMem; -}; - -#define DMA_MODE_NORMAL 0 -#define DMA_MODE_CHAIN 1 - -#define IPU1_TAG_FOLLOW 0 -#define IPU1_TAG_QWC 1 -#define IPU1_TAG_ADDR 2 -#define IPU1_TAG_NONE 3 - // // Bitfield Structures // @@ -102,10 +78,6 @@ struct tIPU_BP { } }; -#ifdef _WIN32 -//#pragma pack() -#endif - union tIPU_CMD_IDEC { struct @@ -178,47 +150,6 @@ union tIPU_CMD_CSC void log_from_RGB32() const; }; -union tIPU_DMA -{ - struct - { - bool GIFSTALL : 1; - bool TIE0 :1; - bool TIE1 : 1; - bool ACTV1 : 1; - bool DOTIE1 : 1; - bool FIREINT0 : 1; - bool FIREINT1 : 1; - bool VIFSTALL : 1; - bool SIFSTALL : 1; - }; - u32 _u32; - - tIPU_DMA( u32 val ){ _u32 = val; } - - bool test(u32 flags) const { return !!(_u32 & flags); } - void set_flags(u32 flags) { _u32 |= flags; } - void clear_flags(u32 flags) { _u32 &= ~flags; } - void reset() { _u32 = 0; } - wxString desc() const - { - wxString temp(L"g_nDMATransfer["); - - if (GIFSTALL) temp += L" GIFSTALL "; - if (TIE0) temp += L" TIE0 "; - if (TIE1) temp += L" TIE1 "; - if (ACTV1) temp += L" ACTV1 "; - if (DOTIE1) temp += L" DOTIE1 "; - if (FIREINT0) temp += L" FIREINT0 "; - if (FIREINT1) temp += L" FIREINT1 "; - if (VIFSTALL) temp += L" VIFSTALL "; - if (SIFSTALL) temp += L" SIFSTALL "; - - temp += L"]"; - return temp; - } -}; - enum SCE_IPU { SCE_IPU_BCLR = 0x0 @@ -245,8 +176,6 @@ struct IPUregisters { u32 dummy3[2]; }; -#define ipuRegs ((IPUregisters*)(&eeMem->HW[0x2000])) - struct tIPU_cmd { int index; @@ -271,32 +200,22 @@ struct tIPU_cmd } }; +static IPUregisters& ipuRegs = (IPUregisters&)eeHw[0x2000]; + extern tIPU_cmd ipu_cmd; extern int coded_block_pattern; -extern IPUStatus IPU1Status; -extern tIPU_DMA g_nDMATransfer; extern int ipuInit(); extern void ipuReset(); -extern void ipuShutdown(); -extern int ipuFreeze(gzFile f, int Mode); -extern bool ipuCanFreeze(); extern u32 ipuRead32(u32 mem); extern u64 ipuRead64(u32 mem); -extern void ipuWrite32(u32 mem,u32 value); -extern void ipuWrite64(u32 mem,u64 value); +extern bool ipuWrite32(u32 mem,u32 value); +extern bool ipuWrite64(u32 mem,u64 value); extern void IPUCMD_WRITE(u32 val); extern void ipuSoftReset(); extern void IPUProcessInterrupt(); -extern void ipu0Interrupt(); -extern void ipu1Interrupt(); - -extern void dmaIPU0(); -extern void dmaIPU1(); -extern int IPU0dma(); -extern int IPU1dma(); extern u16 __fastcall FillInternalBuffer(u32 * pointer, u32 advance, u32 size); extern u8 __fastcall getBits128(u8 *address, u32 advance); diff --git a/pcsx2/IPU/IPU_Fifo.cpp b/pcsx2/IPU/IPU_Fifo.cpp index ed08d76a3f..2c2902cf6f 100644 --- a/pcsx2/IPU/IPU_Fifo.cpp +++ b/pcsx2/IPU/IPU_Fifo.cpp @@ -16,6 +16,7 @@ #include "PrecompiledHeader.h" #include "Common.h" #include "IPU.h" +#include "IPU/IPUdma.h" #include "mpeg2lib/Mpeg.h" @@ -35,7 +36,7 @@ void IPU_Fifo_Input::clear() { memzero(data); g_BP.IFC = 0; - ipuRegs->ctrl.IFC = 0; + ipuRegs.ctrl.IFC = 0; readpos = 0; writepos = 0; } @@ -43,7 +44,7 @@ void IPU_Fifo_Input::clear() void IPU_Fifo_Output::clear() { memzero(data); - ipuRegs->ctrl.OFC = 0; + ipuRegs.ctrl.OFC = 0; readpos = 0; writepos = 0; } @@ -89,9 +90,9 @@ int IPU_Fifo_Output::write(const u32 *value, int size) { int transsize, firsttrans; - if ((int)ipuRegs->ctrl.OFC >= 8) IPU0dma(); + if ((int)ipuRegs.ctrl.OFC >= 8) IPU0dma(); - transsize = min(size, 8 - (int)ipuRegs->ctrl.OFC); + transsize = min(size, 8 - (int)ipuRegs.ctrl.OFC); firsttrans = transsize; while (transsize-- > 0) @@ -104,7 +105,7 @@ int IPU_Fifo_Output::write(const u32 *value, int size) value += 4; } - ipuRegs->ctrl.OFC += firsttrans; + ipuRegs.ctrl.OFC += firsttrans; IPU0dma(); return firsttrans; @@ -150,7 +151,7 @@ void IPU_Fifo_Output::_readsingle(void *value) void IPU_Fifo_Output::read(void *value, int size) { - ipuRegs->ctrl.OFC -= size; + ipuRegs.ctrl.OFC -= size; while (size > 0) { _readsingle(value); @@ -161,38 +162,51 @@ void IPU_Fifo_Output::read(void *value, int size) void IPU_Fifo_Output::readsingle(void *value) { - if (ipuRegs->ctrl.OFC > 0) + if (ipuRegs.ctrl.OFC > 0) { - ipuRegs->ctrl.OFC--; + ipuRegs.ctrl.OFC--; _readsingle(value); } } __fi bool decoder_t::ReadIpuData(u128* out) { - if(decoder.ipu0_data == 0) return false; - _mm_store_ps((float*)out, _mm_load_ps((float*)GetIpuDataPtr())); + if(ipu0_data == 0) + { + IPU_LOG( "ReadFIFO/IPUout -> (fifo empty/no data available)" ); + return false; + } + + CopyQWC(out, GetIpuDataPtr()); --ipu0_data; ++ipu0_idx; + IPU_LOG( "ReadFIFO/IPUout -> %ls", out->ToString().c_str() ); + return true; } -void __fastcall ReadFIFO_page_7(u32 mem, mem128_t* out) +void __fastcall ReadFIFO_IPUout(mem128_t* out) { - pxAssert( (mem >= IPUout_FIFO) && (mem < D0_CHCR) ); + // FIXME! When ReadIpuData() doesn't succeed (returns false), the EE should probably stall + // until a value becomes available. This isn't exactly easy to do since the virtualized EE + // in PCSX2 *has* to be running in order for the IPU DMA to upload new input data to allow + // IPUout's FIFO to fill. Thus if we implement an EE stall, PCSX2 deadlocks. Grr. --air - // All addresses in this page map to 0x7000 and 0x7010: - mem &= 0x10; - - if (mem == 0) // IPUout_FIFO + if (decoder.ReadIpuData(out)) { - if (decoder.ReadIpuData(out)) - { - ipu_fifo.out.readpos = (ipu_fifo.out.readpos + 4) & 31; - } + ipu_fifo.out.readpos = (ipu_fifo.out.readpos + 4) & 31; + } +} + +void __fastcall WriteFIFO_IPUin(const mem128_t* value) +{ + IPU_LOG( "WriteFIFO/IPUin <- %ls", value->ToString().c_str() ); + + //committing every 16 bytes + if( ipu_fifo.in.write((u32*)value, 1) == 0 ) + { + IPUProcessInterrupt(); } - else // IPUin_FIFO - ipu_fifo.out.readsingle((void*)out); } diff --git a/pcsx2/IPU/IPUdma.cpp b/pcsx2/IPU/IPUdma.cpp new file mode 100644 index 0000000000..f44b1b09b8 --- /dev/null +++ b/pcsx2/IPU/IPUdma.cpp @@ -0,0 +1,509 @@ +/* PCSX2 - PS2 Emulator for PCs + * Copyright (C) 2002-2010 PCSX2 Dev Team + * + * PCSX2 is free software: you can redistribute it and/or modify it under the terms + * of the GNU Lesser General Public License as published by the Free Software Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with PCSX2. + * If not, see . + */ + +#include "PrecompiledHeader.h" +#include "Common.h" +#include "IPU.h" +#include "IPU/IPUdma.h" +#include "mpeg2lib/Mpeg.h" + +#include "Vif.h" +#include "Gif.h" +#include "Vif_Dma.h" + +static IPUStatus IPU1Status; +static tIPU_DMA g_nDMATransfer; + +void ipuDmaReset() +{ + IPU1Status.InProgress = false; + IPU1Status.DMAMode = DMA_MODE_NORMAL; + IPU1Status.DMAFinished = true; + + g_nDMATransfer.reset(); +} + +void SaveStateBase::ipuDmaFreeze() +{ + FreezeTag( "IPUdma" ); + Freeze(g_nDMATransfer); + Freeze(IPU1Status); +} + +static __fi bool ipuDmacPartialChain(tDMA_TAG tag) +{ + switch (tag.ID) + { + case TAG_REFE: // refe + ipu1dma.tadr += 16; + return true; + + case TAG_END: // end + ipu1dma.tadr = ipu1dma.madr; + return true; + } + return false; +} + +static __fi void ipuDmacSrcChain() +{ + switch (IPU1Status.ChainMode) + { + case TAG_REFE: // refe + //if(IPU1Status.InProgress == false) ipu1dma.tadr += 16; + IPU1Status.DMAFinished = true; + break; + case TAG_CNT: // cnt + // Set the taddr to the next tag + ipu1dma.tadr = ipu1dma.madr; + //if(IPU1Status.DMAFinished == false) IPU1Status.DMAFinished = false; + break; + + case TAG_NEXT: // next + ipu1dma.tadr = IPU1Status.NextMem; + //if(IPU1Status.DMAFinished == false) IPU1Status.DMAFinished = false; + break; + + case TAG_REF: // ref + //if(IPU1Status.InProgress == false)ipu1dma.tadr += 16; + //if(IPU1Status.DMAFinished == false) IPU1Status.DMAFinished = false; + break; + + case TAG_END: // end + ipu1dma.tadr = ipu1dma.madr; + IPU1Status.DMAFinished = true; + break; + } +} + +static __fi bool WaitGSPaths() +{ + if(CHECK_IPUWAITHACK) + { + if(GSTransferStatus.PTH3 < STOPPED_MODE && GSTransferStatus.PTH3 != IDLE_MODE) + { + //GIF_LOG("Flushing gif chcr %x tadr %x madr %x qwc %x", gif->chcr._u32, gif->tadr, gif->madr, gif->qwc); + //DevCon.WriteLn("Waiting for GIF"); + return false; + } + + if(GSTransferStatus.PTH2 != STOPPED_MODE) + { + //DevCon.WriteLn("Waiting for VIF"); + return false; + } + if(GSTransferStatus.PTH1 != STOPPED_MODE) + { + //DevCon.WriteLn("Waiting for VU"); + return false; + } + } + return true; +} + +static __fi int IPU1chain() { + + int totalqwc = 0; + + if (ipu1dma.qwc > 0 && IPU1Status.InProgress == true) + { + int qwc = ipu1dma.qwc; + u32 *pMem; + + pMem = (u32*)dmaGetAddr(ipu1dma.madr, false); + + if (pMem == NULL) + { + Console.Error("ipu1dma NULL!"); + return totalqwc; + } + + //Write our data to the fifo + qwc = ipu_fifo.in.write(pMem, qwc); + ipu1dma.madr += qwc << 4; + ipu1dma.qwc -= qwc; + totalqwc += qwc; + } + if( ipu1dma.qwc == 0) + { + //Update TADR etc + if(IPU1Status.DMAMode == DMA_MODE_CHAIN) ipuDmacSrcChain(); + //If the transfer has finished or we have room in the FIFO, schedule to the interrupt code. + + //No data left + IPU1Status.InProgress = false; + } //If we still have data the commands should pull this across when need be. + + return totalqwc; +} + +//static __fi bool WaitGSPaths() +//{ +// //Wait for all GS paths to be clear +// if (GSTransferStatus._u32 != 0x2a) +// { +// if(GSTransferStatus.PTH3 != STOPPED_MODE && vif1Regs.mskpath3) return true; +// IPU_LOG("Waiting for GS transfers to finish %x", GSTransferStatus._u32); +// IPU_INT_TO(4); +// return false; +// } +// return true; +//} + + + +int IPU1dma() +{ + int ipu1cycles = 0; + int totalqwc = 0; + + //We need to make sure GIF has flushed before sending IPU data, it seems to REALLY screw FFX videos + //if(!WaitGSPaths()) return totalqwc; + + if(ipu1dma.chcr.STR == false || IPU1Status.DMAMode == 2) + { + //We MUST stop the IPU from trying to fill the FIFO with more data if the DMA has been suspended + //if we don't, we risk causing the data to go out of sync with the fifo and we end up losing some! + //This is true for Dragons Quest 8 and probably others which suspend the DMA. + DevCon.Warning("IPU1 running when IPU1 DMA disabled! CHCR %x QWC %x", ipu1dma.chcr._u32, ipu1dma.qwc); + return 0; + } + + IPU_LOG("IPU1 DMA Called QWC %x Finished %d In Progress %d tadr %x", ipu1dma.qwc, IPU1Status.DMAFinished, IPU1Status.InProgress, ipu1dma.tadr); + + switch(IPU1Status.DMAMode) + { + case DMA_MODE_NORMAL: + { + if(!WaitGSPaths()) + { // legacy WaitGSPaths() for now + IPU_INT_TO(4); //Give it a short wait. + return totalqwc; + } + IPU_LOG("Processing Normal QWC left %x Finished %d In Progress %d", ipu1dma.qwc, IPU1Status.DMAFinished, IPU1Status.InProgress); + if(IPU1Status.InProgress == true) totalqwc += IPU1chain(); + } + break; + + case DMA_MODE_CHAIN: + { + if(IPU1Status.InProgress == true) //No transfer is ready to go so we need to set one up + { + if(!WaitGSPaths()) + { // legacy WaitGSPaths() for now + IPU_INT_TO(4); //Give it a short wait. + return totalqwc; + } + IPU_LOG("Processing Chain QWC left %x Finished %d In Progress %d", ipu1dma.qwc, IPU1Status.DMAFinished, IPU1Status.InProgress); + totalqwc += IPU1chain(); + //Set the TADR forward + } + + + if(IPU1Status.InProgress == false && IPU1Status.DMAFinished == false) //No transfer is ready to go so we need to set one up + { + tDMA_TAG* ptag = dmaGetAddr(ipu1dma.tadr, false); //Set memory pointer to TADR + + if (!ipu1dma.transfer("IPU1", ptag)) + { + return totalqwc; + } + + ipu1cycles += 1; // Add 1 cycles from the QW read for the tag + IPU1Status.ChainMode = ptag->ID; + + if(ipu1dma.chcr.TTE) DevCon.Warning("TTE?"); + + switch (IPU1Status.ChainMode) + { + case TAG_REFE: // refe + // do not change tadr + //ipu1dma.tadr += 16; + ipu1dma.tadr += 16; + ipu1dma.madr = ptag[1]._u32; + IPU_LOG("Tag should end on %x", ipu1dma.tadr); + + break; + + case TAG_CNT: // cnt + ipu1dma.madr = ipu1dma.tadr + 16; + IPU_LOG("Tag should end on %x", ipu1dma.madr + ipu1dma.qwc * 16); + //ipu1dma.tadr = ipu1dma.madr + (ipu1dma.qwc * 16); + // Set the taddr to the next tag + //IPU1Status.DMAFinished = false; + break; + + case TAG_NEXT: // next + ipu1dma.madr = ipu1dma.tadr + 16; + IPU1Status.NextMem = ptag[1]._u32; + IPU_LOG("Tag should end on %x", IPU1Status.NextMem); + //IPU1Status.DMAFinished = false; + break; + + case TAG_REF: // ref + ipu1dma.madr = ptag[1]._u32; + ipu1dma.tadr += 16; + IPU_LOG("Tag should end on %x", ipu1dma.tadr); + //IPU1Status.DMAFinished = false; + break; + + case TAG_END: // end + // do not change tadr + ipu1dma.madr = ipu1dma.tadr + 16; + ipu1dma.tadr += 16; + IPU_LOG("Tag should end on %x", ipu1dma.madr + ipu1dma.qwc * 16); + + break; + + default: + Console.Error("IPU ERROR: different transfer mode!, Please report to PCSX2 Team"); + break; + } + + //if(ipu1dma.qwc == 0) Console.Warning("Blank QWC!"); + if(ipu1dma.qwc > 0) IPU1Status.InProgress = true; + IPU_LOG("dmaIPU1 dmaChain %8.8x_%8.8x size=%d, addr=%lx, fifosize=%x", + ptag[1]._u32, ptag[0]._u32, ipu1dma.qwc, ipu1dma.madr, 8 - g_BP.IFC); + + if (ipu1dma.chcr.TIE && ptag->IRQ) //Tag Interrupt is set, so schedule the end/interrupt + IPU1Status.DMAFinished = true; + + + if(!WaitGSPaths() && ipu1dma.qwc > 0) + { // legacy WaitGSPaths() for now + IPU_INT_TO(4); //Give it a short wait. + return totalqwc; + } + IPU_LOG("Processing Start Chain QWC left %x Finished %d In Progress %d", ipu1dma.qwc, IPU1Status.DMAFinished, IPU1Status.InProgress); + totalqwc += IPU1chain(); + //Set the TADR forward + } + + } + break; + } + + //Do this here to prevent double settings on Chain DMA's + if(totalqwc > 0 || ipu1dma.qwc == 0) + { + IPU_INT_TO(totalqwc * BIAS); + IPUProcessInterrupt(); + } + else + { + cpuRegs.eCycle[4] = 0x9999;//IPU_INT_TO(2048); + } + + IPU_LOG("Completed Call IPU1 DMA QWC Remaining %x Finished %d In Progress %d tadr %x", ipu1dma.qwc, IPU1Status.DMAFinished, IPU1Status.InProgress, ipu1dma.tadr); + return totalqwc; +} + +int IPU0dma() +{ + int readsize; + static int totalsize = 0; + tDMA_TAG* pMem; + + if ((!(ipu0dma.chcr.STR) || (cpuRegs.interrupt & (1 << DMAC_FROM_IPU))) || (ipu0dma.qwc == 0)) + return 0; + + pxAssert(!(ipu0dma.chcr.TTE)); + + IPU_LOG("dmaIPU0 chcr = %lx, madr = %lx, qwc = %lx", + ipu0dma.chcr._u32, ipu0dma.madr, ipu0dma.qwc); + + pxAssert(ipu0dma.chcr.MOD == NORMAL_MODE); + + pMem = dmaGetAddr(ipu0dma.madr, true); + + readsize = min(ipu0dma.qwc, (u16)ipuRegs.ctrl.OFC); + totalsize+=readsize; + ipu_fifo.out.read(pMem, readsize); + + ipu0dma.madr += readsize << 4; + ipu0dma.qwc -= readsize; // note: qwc is u16 + + if (ipu0dma.qwc == 0) + { + if (dmacRegs.ctrl.STS == STS_fromIPU) // STS == fromIPU + { + dmacRegs.stadr.ADDR = ipu0dma.madr; + switch (dmacRegs.ctrl.STD) + { + case NO_STD: + break; + case STD_GIF: // GIF + Console.Warning("GIFSTALL"); + g_nDMATransfer.GIFSTALL = true; + break; + case STD_VIF1: // VIF + Console.Warning("VIFSTALL"); + g_nDMATransfer.VIFSTALL = true; + break; + case STD_SIF1: + Console.Warning("SIFSTALL"); + g_nDMATransfer.SIFSTALL = true; + break; + } + } + //Fixme ( voodoocycles ): + //This was IPU_INT_FROM(readsize*BIAS ); + //This broke vids in Digital Devil Saga + //Note that interrupting based on totalsize is just guessing.. + IPU_INT_FROM( readsize * BIAS ); + totalsize = 0; + } + + return readsize; +} + +__fi void dmaIPU0() // fromIPU +{ + if (ipu0dma.pad != 0) + { + // Note: pad is the padding right above qwc, so we're testing whether qwc + // has overflowed into pad. + DevCon.Warning(L"IPU0dma's upper 16 bits set to %x", ipu0dma.pad); + ipu0dma.qwc = ipu0dma.pad = 0; + //If we are going to clear down IPU0, we should end it too. Going to test this scenario on the PS2 mind - Refraction + ipu0dma.chcr.STR = false; + hwDmacIrq(DMAC_FROM_IPU); + } + IPUProcessInterrupt(); +} + +__fi void dmaIPU1() // toIPU +{ + IPU_LOG("IPU1DMAStart QWC %x, MADR %x, CHCR %x, TADR %x", ipu1dma.qwc, ipu1dma.madr, ipu1dma.chcr._u32, ipu1dma.tadr); + + if (ipu1dma.pad != 0) + { + // Note: pad is the padding right above qwc, so we're testing whether qwc + // has overflowed into pad. + DevCon.Warning(L"IPU1dma's upper 16 bits set to %x\n", ipu1dma.pad); + ipu1dma.qwc = ipu1dma.pad = 0; + // If we are going to clear down IPU1, we should end it too. + // Going to test this scenario on the PS2 mind - Refraction + ipu1dma.chcr.STR = false; + hwDmacIrq(DMAC_TO_IPU); + } + + if (ipu1dma.chcr.MOD == CHAIN_MODE) //Chain Mode + { + IPU_LOG("Setting up IPU1 Chain mode"); + if(ipu1dma.qwc == 0) + { + IPU1Status.InProgress = false; + IPU1Status.DMAFinished = false; + } + else + { //Attempting to continue a previous chain + IPU_LOG("Resuming DMA TAG %x", (ipu1dma.chcr.TAG >> 12)); + //We MUST check the CHCR for the tag it last knew, it can be manipulated! + IPU1Status.ChainMode = (ipu1dma.chcr.TAG >> 12) & 0x7; + IPU1Status.InProgress = true; + IPU1Status.DMAFinished = ((ipu1dma.chcr.TAG >> 15) && ipu1dma.chcr.TIE) ? true : false; + } + + IPU1Status.DMAMode = DMA_MODE_CHAIN; + IPU1dma(); + } + else //Normal Mode + { + if(ipu1dma.qwc == 0) + { + ipu1dma.chcr.STR = false; + // Hack to force stop IPU + ipuRegs.cmd.BUSY = 0; + ipuRegs.ctrl.BUSY = 0; + ipuRegs.topbusy = 0; + // + hwDmacIrq(DMAC_TO_IPU); + Console.Warning("IPU1 Normal error!"); + } + else + { + IPU_LOG("Setting up IPU1 Normal mode"); + IPU1Status.InProgress = true; + IPU1Status.DMAFinished = true; + IPU1Status.DMAMode = DMA_MODE_NORMAL; + IPU1dma(); + } + } +} + +extern void GIFdma(); + +void ipu0Interrupt() +{ + IPU_LOG("ipu0Interrupt: %x", cpuRegs.cycle); + + if (g_nDMATransfer.FIREINT0) + { + g_nDMATransfer.FIREINT0 = false; + hwIntcIrq(INTC_IPU); + } + + if (g_nDMATransfer.GIFSTALL) + { + // gif + Console.Warning("IPU GIF Stall"); + g_nDMATransfer.GIFSTALL = false; + //if (gif->chcr.STR) GIFdma(); + } + + if (g_nDMATransfer.VIFSTALL) + { + // vif + Console.Warning("IPU VIF Stall"); + g_nDMATransfer.VIFSTALL = false; + //if (vif1ch.chcr.STR) dmaVIF1(); + } + + if (g_nDMATransfer.SIFSTALL) + { + // sif + Console.Warning("IPU SIF Stall"); + g_nDMATransfer.SIFSTALL = false; + + // Not totally sure whether this needs to be done or not, so I'm + // leaving it commented out for the moment. + //if (sif1dma.chcr.STR) SIF1Dma(); + } + + if (g_nDMATransfer.TIE0) + { + g_nDMATransfer.TIE0 = false; + } + + ipu0dma.chcr.STR = false; + hwDmacIrq(DMAC_FROM_IPU); +} + +IPU_FORCEINLINE void ipu1Interrupt() +{ + IPU_LOG("ipu1Interrupt %x:", cpuRegs.cycle); + + if(IPU1Status.DMAFinished == false || IPU1Status.InProgress == true) //Sanity Check + { + IPU1dma(); + return; + } + + IPU_LOG("ipu1 finish %x:", cpuRegs.cycle); + ipu1dma.chcr.STR = false; + IPU1Status.DMAMode = 2; + hwDmacIrq(DMAC_TO_IPU); +} diff --git a/pcsx2/IPU/IPUdma.h b/pcsx2/IPU/IPUdma.h new file mode 100644 index 0000000000..9c62820d13 --- /dev/null +++ b/pcsx2/IPU/IPUdma.h @@ -0,0 +1,93 @@ +/* PCSX2 - PS2 Emulator for PCs + * Copyright (C) 2002-2010 PCSX2 Dev Team + * + * PCSX2 is free software: you can redistribute it and/or modify it under the terms + * of the GNU Lesser General Public License as published by the Free Software Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with PCSX2. + * If not, see . + */ + +#pragma once + +#include "IPU.h" + +static DMACh& ipu0dma = (DMACh&)eeHw[0xb000]; +static DMACh& ipu1dma = (DMACh&)eeHw[0xb400]; + +struct IPUStatus { + bool InProgress; + u8 DMAMode; + bool DMAFinished; + bool IRQTriggered; + u8 TagFollow; + u32 TagAddr; + bool stalled; + u8 ChainMode; + u32 NextMem; +}; + +#define DMA_MODE_NORMAL 0 +#define DMA_MODE_CHAIN 1 + +#define IPU1_TAG_FOLLOW 0 +#define IPU1_TAG_QWC 1 +#define IPU1_TAG_ADDR 2 +#define IPU1_TAG_NONE 3 + +union tIPU_DMA +{ + struct + { + bool GIFSTALL : 1; + bool TIE0 :1; + bool TIE1 : 1; + bool ACTV1 : 1; + bool DOTIE1 : 1; + bool FIREINT0 : 1; + bool FIREINT1 : 1; + bool VIFSTALL : 1; + bool SIFSTALL : 1; + }; + u32 _u32; + + tIPU_DMA( u32 val ){ _u32 = val; } + tIPU_DMA() { } + + bool test(u32 flags) const { return !!(_u32 & flags); } + void set_flags(u32 flags) { _u32 |= flags; } + void clear_flags(u32 flags) { _u32 &= ~flags; } + void reset() { _u32 = 0; } + wxString desc() const + { + wxString temp(L"g_nDMATransfer["); + + if (GIFSTALL) temp += L" GIFSTALL "; + if (TIE0) temp += L" TIE0 "; + if (TIE1) temp += L" TIE1 "; + if (ACTV1) temp += L" ACTV1 "; + if (DOTIE1) temp += L" DOTIE1 "; + if (FIREINT0) temp += L" FIREINT0 "; + if (FIREINT1) temp += L" FIREINT1 "; + if (VIFSTALL) temp += L" VIFSTALL "; + if (SIFSTALL) temp += L" SIFSTALL "; + + temp += L"]"; + return temp; + } +}; + +extern void ipu0Interrupt(); +extern void ipu1Interrupt(); + +extern void dmaIPU0(); +extern void dmaIPU1(); +extern int IPU0dma(); +extern int IPU1dma(); + +extern void ipuDmaReset(); diff --git a/pcsx2/IPU/mpeg2lib/Mpeg.cpp b/pcsx2/IPU/mpeg2lib/Mpeg.cpp index dddb64cfad..27edd38f89 100644 --- a/pcsx2/IPU/mpeg2lib/Mpeg.cpp +++ b/pcsx2/IPU/mpeg2lib/Mpeg.cpp @@ -680,7 +680,7 @@ static __fi bool slice_non_intra_DCT(s16 * const dest, const int stride, const b void __fi finishmpeg2sliceIDEC() { - ipuRegs->ctrl.SCD = 0; + ipuRegs.ctrl.SCD = 0; coded_block_pattern = decoder.coded_block_pattern; g_BP.BP += decoder.bitstream_bits - 16; @@ -710,8 +710,8 @@ bool mpeg2sliceIDEC() decoder.dc_dct_pred[2] = 128 << decoder.intra_dc_precision; decoder.mbc = 0; - ipuRegs->top = 0; - ipuRegs->ctrl.ECD = 0; + ipuRegs.top = 0; + ipuRegs.ctrl.ECD = 0; case 1: ipu_cmd.pos[0] = 1; @@ -907,17 +907,17 @@ finish_idec: { if (g_BP.BP & 7) g_BP.BP += 8 - (g_BP.BP & 7); - ipuRegs->ctrl.SCD = 1; + ipuRegs.ctrl.SCD = 1; } case 4: - if (!getBits32((u8*)&ipuRegs->top, 0)) + if (!getBits32((u8*)&ipuRegs.top, 0)) { ipu_cmd.pos[0] = 4; return false; } - BigEndian(ipuRegs->top, ipuRegs->top); + BigEndian(ipuRegs.top, ipuRegs.top); break; } @@ -942,8 +942,8 @@ bool mpeg2_slice() decoder.dc_dct_pred[2] = 128 << decoder.intra_dc_precision; } - ipuRegs->ctrl.ECD = 0; - ipuRegs->top = 0; + ipuRegs.ctrl.ECD = 0; + ipuRegs.top = 0; memzero_sse_a(mb8); memzero_sse_a(mb16); case 1: @@ -1082,7 +1082,7 @@ bool mpeg2_slice() } // Send The MacroBlock via DmaIpuFrom - ipuRegs->ctrl.SCD = 0; + ipuRegs.ctrl.SCD = 0; coded_block_pattern = decoder.coded_block_pattern; g_BP.BP += (int)decoder.bitstream_bits - 16; @@ -1128,17 +1128,17 @@ bool mpeg2_slice() { if (g_BP.BP & 7) g_BP.BP += 8 - (g_BP.BP & 7); - ipuRegs->ctrl.SCD = 1; + ipuRegs.ctrl.SCD = 1; } case 5: - if (!getBits32((u8*)&ipuRegs->top, 0)) + if (!getBits32((u8*)&ipuRegs.top, 0)) { ipu_cmd.pos[0] = 5; return false; } - BigEndian(ipuRegs->top, ipuRegs->top); + BigEndian(ipuRegs.top, ipuRegs.top); decoder.bitstream_bits = 0; break; } diff --git a/pcsx2/IopMem.cpp b/pcsx2/IopMem.cpp index c929542afb..9168b639d4 100644 --- a/pcsx2/IopMem.cpp +++ b/pcsx2/IopMem.cpp @@ -468,7 +468,7 @@ void __fastcall iopMemWrite32(u32 mem, u32 value) // wtf? why were we writing to the EE's sif space? Commenting this out doesn't // break any of my games, and should be more correct, but I guess we'll see. --air - //*(u32*)(eeMem->HW+0xf200+(mem&0xf0)) = value; + //*(u32*)(eeHw+0xf200+(mem&0xf0)) = value; return; } else if (t == 0x1000) diff --git a/pcsx2/Linux/pcsx2.cbp b/pcsx2/Linux/pcsx2.cbp index 71be9c287d..1a723591f9 100644 --- a/pcsx2/Linux/pcsx2.cbp +++ b/pcsx2/Linux/pcsx2.cbp @@ -137,6 +137,60 @@ + + @@ -240,6 +294,8 @@ + + @@ -522,9 +578,11 @@ + + diff --git a/pcsx2/MMI.cpp b/pcsx2/MMI.cpp index 53b9f3d6ba..a09a64fb2b 100644 --- a/pcsx2/MMI.cpp +++ b/pcsx2/MMI.cpp @@ -171,14 +171,11 @@ void PLZCW() { _PLZCW (1); } -__fi void PMFHL_CLAMP(u16 dst, u16 src) +__fi void PMFHL_CLAMP(u16& dst, s32 src) { - if ((int)src > (int)0x00007fff) - dst = 0x7fff; - else if ((int)src < (int)0xffff8000) // Ints only go up to 0x7FFFFFFF. Something's not right here. --arcum42 - dst = 0x8000; - else - dst = (u16)src; + if (src > 0x7fff) dst = 0x7fff; + else if (src < -0x8000) dst = 0x8000; + else dst = (u16)src; } void PMFHL() { diff --git a/pcsx2/Memory.cpp b/pcsx2/Memory.cpp index 12de95d7a9..7b0c4aa166 100644 --- a/pcsx2/Memory.cpp +++ b/pcsx2/Memory.cpp @@ -35,15 +35,14 @@ BIOS */ #include "PrecompiledHeader.h" -#include "IopCommon.h" - -#pragma warning(disable:4799) // No EMMS at end of function - #include +#include "IopCommon.h" #include "VUmicro.h" #include "GS.h" #include "System/PageFaultSource.h" + +#include "ps2/HwInternal.h" #include "ps2/BiosTools.h" #ifdef ENABLECACHE @@ -154,7 +153,6 @@ void memMapPhy() vtlb_MapBlock(psxM,0x1c000000,0x00800000); // Generic Handlers; These fallback to mem* stuff... - vtlb_MapHandler(tlb_fallback_1,0x10000000,0x10000); vtlb_MapHandler(tlb_fallback_7,0x14000000,0x10000); vtlb_MapHandler(tlb_fallback_4,0x18000000,0x10000); vtlb_MapHandler(tlb_fallback_5,0x1a000000,0x10000); @@ -166,17 +164,9 @@ void memMapPhy() // Hardware Register Handlers : specialized/optimized per-page handling of HW register accesses // (note that hw_by_page handles are assigned in memReset prior to calling this function) - vtlb_MapHandler(hw_by_page[0x0], 0x10000000, 0x01000); - vtlb_MapHandler(hw_by_page[0x1], 0x10001000, 0x01000); - vtlb_MapHandler(hw_by_page[0x2], 0x10002000, 0x01000); - vtlb_MapHandler(hw_by_page[0x3], 0x10003000, 0x01000); - vtlb_MapHandler(hw_by_page[0x4], 0x10004000, 0x01000); - vtlb_MapHandler(hw_by_page[0x5], 0x10005000, 0x01000); - vtlb_MapHandler(hw_by_page[0x6], 0x10006000, 0x01000); - vtlb_MapHandler(hw_by_page[0x7], 0x10007000, 0x01000); - vtlb_MapHandler(hw_by_page[0xb], 0x1000b000, 0x01000); - vtlb_MapHandler(hw_by_page[0xe], 0x1000e000, 0x01000); - vtlb_MapHandler(hw_by_page[0xf], 0x1000f000, 0x01000); + + for( uint i=0; i<16; ++i) + vtlb_MapHandler(hw_by_page[i], 0x10000000 + (0x01000 * i), 0x01000); vtlb_MapHandler(gs_page_0, 0x12000000, 0x01000); vtlb_MapHandler(gs_page_1, 0x12001000, 0x01000); @@ -256,8 +246,6 @@ static mem8_t __fastcall _ext_memRead8 (u32 mem) { switch (p) { - case 1: // hwm - return hwRead8(mem); case 3: // psh4 return psxHw4Read8(mem); case 6: // gsm @@ -280,8 +268,6 @@ static mem16_t __fastcall _ext_memRead16(u32 mem) { switch (p) { - case 1: // hwm - return hwRead16(mem); case 4: // b80 MEM_LOG("b800000 Memory read16 address %x", mem); return 0; @@ -358,9 +344,6 @@ template static void __fastcall _ext_memWrite8 (u32 mem, mem8_t value) { switch (p) { - case 1: // hwm - hwWrite8(mem, value); - return; case 3: // psh4 psxHw4Write8(mem, value); return; case 6: // gsm @@ -379,9 +362,6 @@ template static void __fastcall _ext_memWrite16(u32 mem, mem16_t value) { switch (p) { - case 1: // hwm - hwWrite16(mem, value); - return; case 5: // ba0 MEM_LOG("ba00000 Memory write16 to address %x with data %x", mem, value); return; @@ -602,10 +582,12 @@ protected: void OnPageFaultEvent( const PageFaultInfo& info, bool& handled ); }; -mmap_PageFaultHandler mmap_faultHandler; +static mmap_PageFaultHandler mmap_faultHandler; EEVM_MemoryAllocMess* eeMem = NULL; +__pagealigned u8 eeHw[Ps2MemSize::Hardware]; + void memAlloc() { if( eeMem == NULL ) @@ -630,13 +612,28 @@ void memBindConditionalHandlers() { if( hw_by_page[0xf] == -1 ) return; - vtlbMemR32FP* page0F32( EmuConfig.Speedhacks.IntcStat ? hwRead32_page_0F_INTC_HACK : hwRead32_page_0F ); - vtlbMemR64FP* page0F64( EmuConfig.Speedhacks.IntcStat ? hwRead64_generic_INTC_HACK : hwRead64_generic ); + if (EmuConfig.Speedhacks.IntcStat) + { + vtlbMemR16FP* page0F16(hwRead16_page_0F_INTC_HACK); + vtlbMemR32FP* page0F32(hwRead32_page_0F_INTC_HACK); + //vtlbMemR64FP* page0F64(hwRead64_generic_INTC_HACK); - vtlb_ReassignHandler( hw_by_page[0xf], - _ext_memRead8<1>, _ext_memRead16<1>, page0F32, page0F64, hwRead128_generic, - _ext_memWrite8<1>, _ext_memWrite16<1>, hwWrite32_page_0F, hwWrite64_generic, hwWrite128_generic - ); + vtlb_ReassignHandler( hw_by_page[0xf], + hwRead8<0x0f>, page0F16, page0F32, hwRead64<0x0f>, hwRead128<0x0f>, + hwWrite8<0x0f>, hwWrite16<0x0f>, hwWrite32<0x0f>, hwWrite64<0x0f>, hwWrite128<0x0f> + ); + } + else + { + vtlbMemR16FP* page0F16(hwRead16<0x0f>); + vtlbMemR32FP* page0F32(hwRead32<0x0f>); + //vtlbMemR64FP* page0F64(hwRead64<0x0f>); + + vtlb_ReassignHandler( hw_by_page[0xf], + hwRead8<0x0f>, page0F16, page0F32, hwRead64<0x0f>, hwRead128<0x0f>, + hwWrite8<0x0f>, hwWrite16<0x0f>, hwWrite32<0x0f>, hwWrite64<0x0f>, hwWrite128<0x0f> + ); + } } // Resets memory mappings, unmaps TLBs, reloads bios roms, etc. @@ -664,7 +661,6 @@ void memReset() tlb_fallback_3 = vtlb_RegisterHandlerTempl1(_ext_mem,3); tlb_fallback_4 = vtlb_RegisterHandlerTempl1(_ext_mem,4); tlb_fallback_5 = vtlb_RegisterHandlerTempl1(_ext_mem,5); - //tlb_fallback_6 = vtlb_RegisterHandlerTempl1(_ext_mem,6); tlb_fallback_7 = vtlb_RegisterHandlerTempl1(_ext_mem,7); tlb_fallback_8 = vtlb_RegisterHandlerTempl1(_ext_mem,8); @@ -701,68 +697,29 @@ void memReset() ); - ////////////////////////////////////////////////////////////////////////////////////////// // psHw Optimized Mappings // The HW Registers have been split into pages to improve optimization. - // Anything not explicitly mapped into one of the hw_by_page handlers will be handled - // by the default/generic tlb_fallback_1 handler. + +#define hwHandlerTmpl(page) \ + hwRead8, hwRead16, hwRead32, hwRead64, hwRead128, \ + hwWrite8, hwWrite16,hwWrite32,hwWrite64,hwWrite128 - tlb_fallback_1 = vtlb_RegisterHandler( - _ext_memRead8<1>, _ext_memRead16<1>, hwRead32_generic, hwRead64_generic, hwRead128_generic, - _ext_memWrite8<1>, _ext_memWrite16<1>, hwWrite32_generic, hwWrite64_generic, hwWrite128_generic - ); - - hw_by_page[0x0] = vtlb_RegisterHandler( - _ext_memRead8<1>, _ext_memRead16<1>, hwRead32_page_00, hwRead64_page_00, hwRead128_page_00, - _ext_memWrite8<1>, _ext_memWrite16<1>, hwWrite32_page_00, hwWrite64_page_00, hwWrite128_generic - ); - - hw_by_page[0x1] = vtlb_RegisterHandler( - _ext_memRead8<1>, _ext_memRead16<1>, hwRead32_page_01, hwRead64_page_01, hwRead128_page_01, - _ext_memWrite8<1>, _ext_memWrite16<1>, hwWrite32_page_01, hwWrite64_page_01, hwWrite128_generic - ); - - hw_by_page[0x2] = vtlb_RegisterHandler( - _ext_memRead8<1>, _ext_memRead16<1>, hwRead32_page_02, hwRead64_page_02, hwRead128_page_02, - _ext_memWrite8<1>, _ext_memWrite16<1>, hwWrite32_page_02, hwWrite64_page_02, hwWrite128_generic - ); - - hw_by_page[0x3] = vtlb_RegisterHandler( - _ext_memRead8<1>, _ext_memRead16<1>, hwRead32_generic, hwRead64_generic, hwRead128_generic, - _ext_memWrite8<1>, _ext_memWrite16<1>, hwWrite32_page_03, hwWrite64_page_03, hwWrite128_generic - ); - - hw_by_page[0x4] = vtlb_RegisterHandler( - _ext_memRead8<1>, _ext_memRead16<1>, hwRead32_generic, hwRead64_generic, ReadFIFO_page_4, - _ext_memWrite8<1>, _ext_memWrite16<1>, hwWrite32_generic, hwWrite64_generic, WriteFIFO_page_4 - ); - - hw_by_page[0x5] = vtlb_RegisterHandler( - _ext_memRead8<1>, _ext_memRead16<1>, hwRead32_generic, hwRead64_generic, ReadFIFO_page_5, - _ext_memWrite8<1>, _ext_memWrite16<1>, hwWrite32_generic, hwWrite64_generic, WriteFIFO_page_5 - ); - - hw_by_page[0x6] = vtlb_RegisterHandler( - _ext_memRead8<1>, _ext_memRead16<1>, hwRead32_generic, hwRead64_generic, ReadFIFO_page_6, - _ext_memWrite8<1>, _ext_memWrite16<1>, hwWrite32_generic, hwWrite64_generic, WriteFIFO_page_6 - ); - - hw_by_page[0x7] = vtlb_RegisterHandler( - _ext_memRead8<1>, _ext_memRead16<1>, hwRead32_generic, hwRead64_generic, ReadFIFO_page_7, - _ext_memWrite8<1>, _ext_memWrite16<1>, hwWrite32_generic, hwWrite64_generic, WriteFIFO_page_7 - ); - - hw_by_page[0xb] = vtlb_RegisterHandler( - _ext_memRead8<1>, _ext_memRead16<1>, hwRead32_generic, hwRead64_generic, hwRead128_generic, - _ext_memWrite8<1>, _ext_memWrite16<1>, hwWrite32_page_0B, hwWrite64_generic, hwWrite128_generic - ); - - hw_by_page[0xe] = vtlb_RegisterHandler( - _ext_memRead8<1>, _ext_memRead16<1>, hwRead32_generic, hwRead64_generic, hwRead128_generic, - _ext_memWrite8<1>, _ext_memWrite16<1>, hwWrite32_page_0E, hwWrite64_page_0E, hwWrite128_generic - ); - - hw_by_page[0xf] = vtlb_NewHandler(); + hw_by_page[0x0] = vtlb_RegisterHandler( hwHandlerTmpl(0x00) ); + hw_by_page[0x1] = vtlb_RegisterHandler( hwHandlerTmpl(0x01) ); + hw_by_page[0x2] = vtlb_RegisterHandler( hwHandlerTmpl(0x02) ); + hw_by_page[0x3] = vtlb_RegisterHandler( hwHandlerTmpl(0x03) ); + hw_by_page[0x4] = vtlb_RegisterHandler( hwHandlerTmpl(0x04) ); + hw_by_page[0x5] = vtlb_RegisterHandler( hwHandlerTmpl(0x05) ); + hw_by_page[0x6] = vtlb_RegisterHandler( hwHandlerTmpl(0x06) ); + hw_by_page[0x7] = vtlb_RegisterHandler( hwHandlerTmpl(0x07) ); + hw_by_page[0x8] = vtlb_RegisterHandler( hwHandlerTmpl(0x08) ); + hw_by_page[0x9] = vtlb_RegisterHandler( hwHandlerTmpl(0x09) ); + hw_by_page[0xa] = vtlb_RegisterHandler( hwHandlerTmpl(0x0a) ); + hw_by_page[0xb] = vtlb_RegisterHandler( hwHandlerTmpl(0x0b) ); + hw_by_page[0xc] = vtlb_RegisterHandler( hwHandlerTmpl(0x0c) ); + hw_by_page[0xd] = vtlb_RegisterHandler( hwHandlerTmpl(0x0d) ); + hw_by_page[0xe] = vtlb_RegisterHandler( hwHandlerTmpl(0x0e) ); + hw_by_page[0xf] = vtlb_NewHandler(); // redefined later based on speedhacking prefs memBindConditionalHandlers(); ////////////////////////////////////////////////////////////////////// diff --git a/pcsx2/Memory.h b/pcsx2/Memory.h index f9c3fbd269..7a325e1aec 100644 --- a/pcsx2/Memory.h +++ b/pcsx2/Memory.h @@ -34,33 +34,22 @@ static __fi void ZeroQWC( void* dest ) _mm_store_ps( (float*)dest, _mm_setzero_ps() ); } -// Various useful locations -#define spr0 ((DMACh*)&eeMem->HW[0xD000]) -#define spr1 ((DMACh*)&eeMem->HW[0xD400]) - -#define gif ((DMACh*)&eeMem->HW[0xA000]) - -#define vif0ch ((DMACh*)&eeMem->HW[0x8000]) -#define vif1ch ((DMACh*)&eeMem->HW[0x9000]) - -#define sif0dma ((DMACh*)&eeMem->HW[0xc000]) -#define sif1dma ((DMACh*)&eeMem->HW[0xc400]) -#define sif2dma ((DMACh*)&eeMem->HW[0xc800]) - -#define ipu0dma ((DMACh *)&eeMem->HW[0xb000]) -#define ipu1dma ((DMACh *)&eeMem->HW[0xb400]) +static __fi void ZeroQWC( u128& dest ) +{ + _mm_store_ps( (float*)&dest, _mm_setzero_ps() ); +} #define PSM(mem) (vtlb_GetPhyPtr((mem)&0x1fffffff)) //pcsx2 is a competition.The one with most hacks wins :D -#define psHs8(mem) (*(s8 *)&eeMem->HW[(mem) & 0xffff]) -#define psHs16(mem) (*(s16*)&eeMem->HW[(mem) & 0xffff]) -#define psHs32(mem) (*(s32*)&eeMem->HW[(mem) & 0xffff]) -#define psHs64(mem) (*(s64*)&eeMem->HW[(mem) & 0xffff]) -#define psHu8(mem) (*(u8 *)&eeMem->HW[(mem) & 0xffff]) -#define psHu16(mem) (*(u16*)&eeMem->HW[(mem) & 0xffff]) -#define psHu32(mem) (*(u32*)&eeMem->HW[(mem) & 0xffff]) -#define psHu64(mem) (*(u64*)&eeMem->HW[(mem) & 0xffff]) -#define psHu128(mem)(*(u128*)&eeMem->HW[(mem) & 0xffff]) +#define psHs8(mem) (*(s8 *)&eeHw[(mem) & 0xffff]) +#define psHs16(mem) (*(s16*)&eeHw[(mem) & 0xffff]) +#define psHs32(mem) (*(s32*)&eeHw[(mem) & 0xffff]) +#define psHs64(mem) (*(s64*)&eeHw[(mem) & 0xffff]) +#define psHu8(mem) (*(u8 *)&eeHw[(mem) & 0xffff]) +#define psHu16(mem) (*(u16*)&eeHw[(mem) & 0xffff]) +#define psHu32(mem) (*(u32*)&eeHw[(mem) & 0xffff]) +#define psHu64(mem) (*(u64*)&eeHw[(mem) & 0xffff]) +#define psHu128(mem)(*(u128*)&eeHw[(mem) & 0xffff]) #define psMs8(mem) (*(s8 *)&eeMem->Main[(mem) & 0x1ffffff]) #define psMs16(mem) (*(s16*)&eeMem->Main[(mem) & 0x1ffffff]) @@ -114,8 +103,6 @@ static __fi void ZeroQWC( void* dest ) #define psSu64(mem) (*(u64 *)&eeMem->Scratch[(mem) & 0x3fff]) #define psSu128(mem) (*(u128*)&eeMem->Scratch[(mem) & 0x3fff]) -#define psH_DMACh(mem) (*(DMACh*)&eeMem->HW[(mem) & 0xffff]) - extern void memAlloc(); extern void memReset(); // clears PS2 ram and loads the bios. Throws Exception::FileNotFound on error. extern void memShutdown(); @@ -135,13 +122,21 @@ extern void mmap_ResetBlockTracking(); #define memRead8 vtlb_memRead #define memRead16 vtlb_memRead #define memRead32 vtlb_memRead -#define memRead64 vtlb_memRead64 -#define memRead128 vtlb_memRead128 #define memWrite8 vtlb_memWrite #define memWrite16 vtlb_memWrite #define memWrite32 vtlb_memWrite -#define memWrite64 vtlb_memWrite64 -#define memWrite128 vtlb_memWrite128 + +static __fi void memRead64(u32 mem, mem64_t* out) { vtlb_memRead64(mem, out); } +static __fi void memRead64(u32 mem, mem64_t& out) { vtlb_memRead64(mem, &out); } + +static __fi void memRead128(u32 mem, mem128_t* out) { vtlb_memRead128(mem, out); } +static __fi void memRead128(u32 mem, mem128_t& out) { vtlb_memRead128(mem, &out); } + +static __fi void memWrite64(u32 mem, const mem64_t* val) { vtlb_memWrite64(mem, val); } +static __fi void memWrite64(u32 mem, const mem64_t& val) { vtlb_memWrite64(mem, &val); } +static __fi void memWrite128(u32 mem, const mem128_t* val) { vtlb_memWrite128(mem, val); } +static __fi void memWrite128(u32 mem, const mem128_t& val) { vtlb_memWrite128(mem, &val); } + extern u16 ba0R16(u32 mem); diff --git a/pcsx2/MemoryTypes.h b/pcsx2/MemoryTypes.h index 8feba6746a..a591469b1c 100644 --- a/pcsx2/MemoryTypes.h +++ b/pcsx2/MemoryTypes.h @@ -37,15 +37,55 @@ typedef u32 mem32_t; typedef u64 mem64_t; typedef u128 mem128_t; + +// -------------------------------------------------------------------------------------- +// Future-Planned VTLB pagefault scheme! +// -------------------------------------------------------------------------------------- +// When enabled, the VTLB will use a large-area reserved memory range of 512megs for EE +// physical ram/rom access. The base ram will be committed at 0x00000000, and ROMs will be +// at 0x1fc00000, etc. All memory ranges in between will be uncommitted memory -- which +// means that the memory will *not* count against the operating system's physical memory +// pool. +// +// When the VTLB generates memory operations (loads/stores), it will assume that the op +// is addressing either RAM or ROM, and by assuming that it can generate a completely efficient +// direct memory access (one AND and one MOV instruction). If the access is to another area of +// memory, such as hardware registers or scratchpad, the access will generate a page fault, the +// compiled block will be cleared and re-compiled using "full" VTLB translation logic. +// +#define VTLB_UsePageFaulting 0 + +#if VTLB_UsePageFaulting + +// The order of the components in this struct *matter* -- it has been laid out so that the +// full breadth of PS2 RAM and ROM mappings are directly supported. +struct EEVM_MemoryAllocMess +{ + u8 (&Main)[Ps2MemSize::Base]; // Main memory (hard-wired to 32MB) + + u8 _padding1[0x1e000000-Ps2MemSize::Base] + u8 (&ROM1)[Ps2MemSize::Rom1]; // DVD player + + u8 _padding2[0x1e040000-(0x1e000000+Ps2MemSize::Rom1)] + u8 (&EROM)[Ps2MemSize::ERom]; // DVD player extensions + + u8 _padding3[0x1e400000-(0x1e040000+Ps2MemSize::EROM)] + u8 (&ROM2)[Ps2MemSize::Rom2]; // Chinese extensions + + u8 _padding4[0x1fc00000-(0x1e040000+Ps2MemSize::Rom2)]; + u8 (&ROM)[Ps2MemSize::Rom]; // Boot rom (4MB) +}; + +#else + struct EEVM_MemoryAllocMess { u8 Scratch[Ps2MemSize::Scratch]; // Scratchpad! u8 Main[Ps2MemSize::Base]; // Main memory (hard-wired to 32MB) - u8 HW[Ps2MemSize::Hardware]; // Hardware registers u8 ROM[Ps2MemSize::Rom]; // Boot rom (4MB) u8 ROM1[Ps2MemSize::Rom1]; // DVD player - u8 ROM2[Ps2MemSize::Rom2]; // Chinese extensions (?) - u8 EROM[Ps2MemSize::ERom]; // DVD player extensions (?) + u8 ROM2[Ps2MemSize::Rom2]; // Chinese extensions + u8 EROM[Ps2MemSize::ERom]; // DVD player extensions // Two 1 megabyte (max DMA) buffers for reading and writing to high memory (>32MB). // Such accesses are not documented as causing bus errors but as the memory does @@ -56,4 +96,13 @@ struct EEVM_MemoryAllocMess u8 ZeroWrite[_1mb]; }; +#endif + +// EE Hardware registers. +// DevNote: These are done as a static array instead of a pointer in order to allow for simpler +// macros and reference handles to be defined (we can safely use compile-time references to +// registers instead of having to use instance variables). +extern __pagealigned u8 eeHw[Ps2MemSize::Hardware]; + + extern EEVM_MemoryAllocMess* eeMem; diff --git a/pcsx2/PrecompiledHeader.h b/pcsx2/PrecompiledHeader.h index 1684e381ef..600039b406 100644 --- a/pcsx2/PrecompiledHeader.h +++ b/pcsx2/PrecompiledHeader.h @@ -78,6 +78,7 @@ typedef int BOOL; #define TRUE 1 #define FALSE 0 + ////////////////////////////////////////////////////////////////////////////////////////// // Begin Pcsx2 Includes: Add items here that are local to Pcsx2 but stay relatively // unchanged for long periods of time, or happen to be used by almost everything, so they @@ -100,15 +101,24 @@ typedef int BOOL; #include "Config.h" +typedef void FnType_Void(); +typedef FnType_Void* Fnptr_Void; + +static const s64 _1mb = 0x100000; +static const s64 _8mb = _1mb * 8; +static const s64 _16mb = _1mb * 16; +static const s64 _256mb = _1mb * 256; +static const s64 _1gb = _256mb * 4; + +////////////////////////////////////////////////////////////////////////////////////////// +// Compiler/OS specific macros and defines -- Begin Section + // Linux isn't set up for svn version numbers yet. #ifdef __LINUX__ # define SVN_REV 0 # define SVN_MODS 0 #endif -////////////////////////////////////////////////////////////////////////////////////////// -// Compiler/OS specific macros and defines -- Begin Section - #if defined(_MSC_VER) # define strnicmp _strnicmp diff --git a/pcsx2/R5900.cpp b/pcsx2/R5900.cpp index 1f6e5da542..30c7ab6989 100644 --- a/pcsx2/R5900.cpp +++ b/pcsx2/R5900.cpp @@ -26,6 +26,7 @@ #include "R5900Exceptions.h" #include "Hardware.h" +#include "IPU/IPUdma.h" #include "Elfheader.h" #include "CDVD/CDVD.h" @@ -287,9 +288,11 @@ static __fi void TESTINT( u8 n, void (*callback)() ) cpuSetNextBranch( cpuRegs.sCycle[n], cpuRegs.eCycle[n] ); } +// [TODO] move this function to LegacyDmac.cpp, and remove most of the DMAC-related headers from +// being included into R5900.cpp. static __fi void _cpuTestInterrupts() { - if (!dmacRegs->ctrl.DMAE || psHu8(DMAC_ENABLER+2) == 1) + if (!dmacRegs.ctrl.DMAE || (psHu8(DMAC_ENABLER+2) & 1)) { //Console.Write("DMAC Disabled or suspended"); return; @@ -415,7 +418,7 @@ __fi void _cpuBranchTest_Shared() //if( EEsCycle < -450 ) // Console.WriteLn( " IOP ahead by: %d cycles", -EEsCycle ); - // Experimental and Probably Unnecessry Logic --> + // Experimental and Probably Unnecessary Logic --> // Check if the EE already has an exception pending, and if so we shouldn't // waste too much time updating the IOP. Theory being that the EE and IOP should // run closely in sync during raised exception events. But in practice it didn't @@ -502,11 +505,8 @@ __ri void cpuTestINTCInts() cpuRegs.sCycle[30] = cpuRegs.cycle; cpuRegs.eCycle[30] = 4; //Needs to be 4 to account for bus delays/pipelines etc - // only set the next branch delta if the exception won't be handled for - // the current branch... - if( !eeEventTestIsActive ) - cpuSetNextBranchDelta( 4 ); - else if(psxCycleEE > 0) + cpuSetNextBranchDelta( 4 ); + if(eeEventTestIsActive && (psxCycleEE > 0)) { psxBreak += psxCycleEE; // record the number of cycles the IOP didn't run. psxCycleEE = 0; @@ -529,11 +529,8 @@ __fi void cpuTestDMACInts() cpuRegs.sCycle[31] = cpuRegs.cycle; cpuRegs.eCycle[31] = 4; //Needs to be 4 to account for bus delays/pipelines etc - // only set the next branch delta if the exception won't be handled for - // the current branch... - if( !eeEventTestIsActive ) - cpuSetNextBranchDelta( 4 ); - else if(psxCycleEE > 0) + cpuSetNextBranchDelta( 4 ); + if(eeEventTestIsActive && (psxCycleEE > 0)) { psxBreak += psxCycleEE; // record the number of cycles the IOP didn't run. psxCycleEE = 0; diff --git a/pcsx2/R5900OpcodeImpl.cpp b/pcsx2/R5900OpcodeImpl.cpp index a990677278..10b1180698 100644 --- a/pcsx2/R5900OpcodeImpl.cpp +++ b/pcsx2/R5900OpcodeImpl.cpp @@ -816,7 +816,7 @@ void SQ() // an address error due to unaligned access isn't possible like it is on other loads/stores. u32 addr = cpuRegs.GPR.r[_Rs_].UL[0] + _Imm_; - memWrite128(addr & ~0xf, cpuRegs.GPR.r[_Rt_].UD); + memWrite128(addr & ~0xf, cpuRegs.GPR.r[_Rt_].UQ); } /********************************************************* @@ -868,8 +868,7 @@ void SYSCALL() } // The only thing this code is used for is the one log message, so don't execute it if we aren't logging bios messages. -#ifdef PCSX2_DEVBUILD - if (SysTrace.EE.Bios.IsActive() && (call == 0x77)) + if (SysTraceActive(EE.Bios) && (call == 0x77)) { t_sif_dma_transfer *dmat; //struct t_sif_cmd_header *hdr; @@ -891,7 +890,6 @@ void SYSCALL() dmat->dest, dmat->src); } } -#endif cpuRegs.pc -= 4; cpuException(0x20, cpuRegs.branch); diff --git a/pcsx2/SPR.cpp b/pcsx2/SPR.cpp index 7eeef1a0f9..5ea0243ae9 100644 --- a/pcsx2/SPR.cpp +++ b/pcsx2/SPR.cpp @@ -51,96 +51,96 @@ int _SPR0chain() { tDMA_TAG *pMem; - if (spr0->qwc == 0) return 0; - pMem = SPRdmaGetAddr(spr0->madr, true); + if (spr0ch.qwc == 0) return 0; + pMem = SPRdmaGetAddr(spr0ch.madr, true); if (pMem == NULL) return -1; - switch (dmacRegs->ctrl.MFD) + switch (dmacRegs.ctrl.MFD) { case MFD_VIF1: case MFD_GIF: - if ((spr0->madr & ~dmacRegs->rbsr.RMSK) != dmacRegs->rbor.ADDR) + if ((spr0ch.madr & ~dmacRegs.rbsr.RMSK) != dmacRegs.rbor.ADDR) Console.WriteLn("SPR MFIFO Write outside MFIFO area"); else - mfifotransferred += spr0->qwc; + mfifotransferred += spr0ch.qwc; - hwMFIFOWrite(spr0->madr, &psSu128(spr0->sadr), spr0->qwc); - spr0->madr += spr0->qwc << 4; - spr0->madr = dmacRegs->rbor.ADDR + (spr0->madr & dmacRegs->rbsr.RMSK); + hwMFIFOWrite(spr0ch.madr, &psSu128(spr0ch.sadr), spr0ch.qwc); + spr0ch.madr += spr0ch.qwc << 4; + spr0ch.madr = dmacRegs.rbor.ADDR + (spr0ch.madr & dmacRegs.rbsr.RMSK); break; case NO_MFD: case MFD_RESERVED: - memcpy_qwc(pMem, &psSu128(spr0->sadr), spr0->qwc); + memcpy_qwc(pMem, &psSu128(spr0ch.sadr), spr0ch.qwc); // clear VU mem also! - TestClearVUs(spr0->madr, spr0->qwc << 2); // Wtf is going on here? AFAIK, only VIF should affect VU micromem (cottonvibes) - spr0->madr += spr0->qwc << 4; + TestClearVUs(spr0ch.madr, spr0ch.qwc << 2); // Wtf is going on here? AFAIK, only VIF should affect VU micromem (cottonvibes) + spr0ch.madr += spr0ch.qwc << 4; break; } - spr0->sadr += spr0->qwc << 4; + spr0ch.sadr += spr0ch.qwc << 4; - return (spr0->qwc); // bus is 1/2 the ee speed + return (spr0ch.qwc); // bus is 1/2 the ee speed } __fi void SPR0chain() { CPU_INT(DMAC_FROM_SPR, _SPR0chain() / BIAS); - spr0->qwc = 0; + spr0ch.qwc = 0; } void _SPR0interleave() { - int qwc = spr0->qwc; - int sqwc = dmacRegs->sqwc.SQWC; - int tqwc = dmacRegs->sqwc.TQWC; + int qwc = spr0ch.qwc; + int sqwc = dmacRegs.sqwc.SQWC; + int tqwc = dmacRegs.sqwc.TQWC; tDMA_TAG *pMem; if (tqwc == 0) tqwc = qwc; //Console.WriteLn("dmaSPR0 interleave"); SPR_LOG("SPR0 interleave size=%d, tqwc=%d, sqwc=%d, addr=%lx sadr=%lx", - spr0->qwc, tqwc, sqwc, spr0->madr, spr0->sadr); + spr0ch.qwc, tqwc, sqwc, spr0ch.madr, spr0ch.sadr); CPU_INT(DMAC_FROM_SPR, qwc / BIAS); while (qwc > 0) { - spr0->qwc = std::min(tqwc, qwc); - qwc -= spr0->qwc; - pMem = SPRdmaGetAddr(spr0->madr, true); + spr0ch.qwc = std::min(tqwc, qwc); + qwc -= spr0ch.qwc; + pMem = SPRdmaGetAddr(spr0ch.madr, true); - switch (dmacRegs->ctrl.MFD) + switch (dmacRegs.ctrl.MFD) { case MFD_VIF1: case MFD_GIF: - hwMFIFOWrite(spr0->madr, &psSu128(spr0->sadr), spr0->qwc); - mfifotransferred += spr0->qwc; + hwMFIFOWrite(spr0ch.madr, &psSu128(spr0ch.sadr), spr0ch.qwc); + mfifotransferred += spr0ch.qwc; break; case NO_MFD: case MFD_RESERVED: // clear VU mem also! - TestClearVUs(spr0->madr, spr0->qwc << 2); - memcpy_qwc(pMem, &psSu128(spr0->sadr), spr0->qwc); + TestClearVUs(spr0ch.madr, spr0ch.qwc << 2); + memcpy_qwc(pMem, &psSu128(spr0ch.sadr), spr0ch.qwc); break; } - spr0->sadr += spr0->qwc * 16; - spr0->madr += (sqwc + spr0->qwc) * 16; + spr0ch.sadr += spr0ch.qwc * 16; + spr0ch.madr += (sqwc + spr0ch.qwc) * 16; } - spr0->qwc = 0; + spr0ch.qwc = 0; } static __fi void _dmaSPR0() { - if (dmacRegs->ctrl.STS == STS_fromSPR) + if (dmacRegs.ctrl.STS == STS_fromSPR) { - Console.WriteLn("SPR0 stall %d", dmacRegs->ctrl.STS); + Console.WriteLn("SPR0 stall %d", dmacRegs.ctrl.STS); } // Transfer Dn_QWC from SPR to Dn_MADR - switch(spr0->chcr.MOD) + switch(spr0ch.chcr.MOD) { case NORMAL_MODE: { @@ -153,23 +153,23 @@ static __fi void _dmaSPR0() tDMA_TAG *ptag; bool done = false; - if (spr0->qwc > 0) + if (spr0ch.qwc > 0) { SPR0chain(); return; } // Destination Chain Mode - ptag = (tDMA_TAG*)&psSu32(spr0->sadr); - spr0->sadr += 16; + ptag = (tDMA_TAG*)&psSu32(spr0ch.sadr); + spr0ch.sadr += 16; - spr0->unsafeTransfer(ptag); + spr0ch.unsafeTransfer(ptag); - spr0->madr = ptag[1]._u32; //MADR = ADDR field + SPR + spr0ch.madr = ptag[1]._u32; //MADR = ADDR field + SPR SPR_LOG("spr0 dmaChain %8.8x_%8.8x size=%d, id=%d, addr=%lx spr=%lx", - ptag[1]._u32, ptag[0]._u32, spr0->qwc, ptag->ID, spr0->madr, spr0->sadr); + ptag[1]._u32, ptag[0]._u32, spr0ch.qwc, ptag->ID, spr0ch.madr, spr0ch.sadr); - if (dmacRegs->ctrl.STS == STS_fromSPR) // STS == fromSPR + if (dmacRegs.ctrl.STS == STS_fromSPR) // STS == fromSPR { Console.WriteLn("SPR stall control"); } @@ -177,7 +177,7 @@ static __fi void _dmaSPR0() switch (ptag->ID) { case TAG_CNTS: // CNTS - Transfer QWC following the tag (Stall Control) - if (dmacRegs->ctrl.STS == STS_fromSPR) dmacRegs->stadr.ADDR = spr0->madr + (spr0->qwc * 16); //Copy MADR to DMAC_STADR stall addr register + if (dmacRegs.ctrl.STS == STS_fromSPR) dmacRegs.stadr.ADDR = spr0ch.madr + (spr0ch.qwc * 16); //Copy MADR to DMAC_STADR stall addr register break; case TAG_CNT: // CNT - Transfer QWC following the tag. @@ -191,7 +191,7 @@ static __fi void _dmaSPR0() SPR0chain(); - if (spr0->chcr.TIE && ptag->IRQ) //Check TIE bit of CHCR and IRQ bit of tag + if (spr0ch.chcr.TIE && ptag->IRQ) //Check TIE bit of CHCR and IRQ bit of tag { //Console.WriteLn("SPR0 TIE"); done = true; @@ -199,7 +199,7 @@ static __fi void _dmaSPR0() spr0finished = done; SPR_LOG("spr0 dmaChain complete %8.8x_%8.8x size=%d, id=%d, addr=%lx spr=%lx", - ptag[1]._u32, ptag[0]._u32, spr0->qwc, ptag->ID, spr0->madr); + ptag[1]._u32, ptag[0]._u32, spr0ch.qwc, ptag->ID, spr0ch.madr); break; } //case INTERLEAVE_MODE: @@ -215,27 +215,27 @@ static __fi void _dmaSPR0() void SPRFROMinterrupt() { - if (!spr0finished || spr0->qwc > 0) + if (!spr0finished || spr0ch.qwc > 0) { _dmaSPR0(); if(mfifotransferred != 0) { - switch (dmacRegs->ctrl.MFD) + switch (dmacRegs.ctrl.MFD) { case MFD_VIF1: // Most common case. { - if ((spr0->madr & ~dmacRegs->rbsr.RMSK) != dmacRegs->rbor.ADDR) Console.WriteLn("VIF MFIFO Write outside MFIFO area"); - spr0->madr = dmacRegs->rbor.ADDR + (spr0->madr & dmacRegs->rbsr.RMSK); - //Console.WriteLn("mfifoVIF1transfer %x madr %x, tadr %x", vif1ch->chcr._u32, vif1ch->madr, vif1ch->tadr); + if ((spr0ch.madr & ~dmacRegs.rbsr.RMSK) != dmacRegs.rbor.ADDR) Console.WriteLn("VIF MFIFO Write outside MFIFO area"); + spr0ch.madr = dmacRegs.rbor.ADDR + (spr0ch.madr & dmacRegs.rbsr.RMSK); + //Console.WriteLn("mfifoVIF1transfer %x madr %x, tadr %x", vif1ch.chcr._u32, vif1ch.madr, vif1ch.tadr); mfifoVIF1transfer(mfifotransferred); mfifotransferred = 0; break; } case MFD_GIF: { - if ((spr0->madr & ~dmacRegs->rbsr.RMSK) != dmacRegs->rbor.ADDR) Console.WriteLn("GIF MFIFO Write outside MFIFO area"); - spr0->madr = dmacRegs->rbor.ADDR + (spr0->madr & dmacRegs->rbsr.RMSK); + if ((spr0ch.madr & ~dmacRegs.rbsr.RMSK) != dmacRegs.rbor.ADDR) Console.WriteLn("GIF MFIFO Write outside MFIFO area"); + spr0ch.madr = dmacRegs.rbor.ADDR + (spr0ch.madr & dmacRegs.rbsr.RMSK); //Console.WriteLn("mfifoGIFtransfer %x madr %x, tadr %x", gif->chcr._u32, gif->madr, gif->tadr); mfifoGIFtransfer(mfifotransferred); mfifotransferred = 0; @@ -249,22 +249,22 @@ void SPRFROMinterrupt() } - spr0->chcr.STR = false; + spr0ch.chcr.STR = false; hwDmacIrq(DMAC_FROM_SPR); } void dmaSPR0() // fromSPR { SPR_LOG("dmaSPR0 chcr = %lx, madr = %lx, qwc = %lx, sadr = %lx", - spr0->chcr._u32, spr0->madr, spr0->qwc, spr0->sadr); + spr0ch.chcr._u32, spr0ch.madr, spr0ch.qwc, spr0ch.sadr); spr0finished = false; //Init - if(spr0->chcr.MOD == CHAIN_MODE && spr0->qwc > 0) + if(spr0ch.chcr.MOD == CHAIN_MODE && spr0ch.qwc > 0) { - //DevCon.Warning(L"SPR0 QWC on Chain " + spr0->chcr.desc()); - if (spr0->chcr.tag().ID == TAG_END) // but not TAG_REFE? + //DevCon.Warning(L"SPR0 QWC on Chain " + spr0ch.chcr.desc()); + if (spr0ch.chcr.tag().ID == TAG_END) // but not TAG_REFE? { spr0finished = true; } @@ -275,58 +275,58 @@ void dmaSPR0() // fromSPR __fi static void SPR1transfer(const void* data, int qwc) { - memcpy_qwc(&psSu128(spr1->sadr), data, qwc); - spr1->sadr += qwc * 16; + memcpy_qwc(&psSu128(spr1ch.sadr), data, qwc); + spr1ch.sadr += qwc * 16; } int _SPR1chain() { tDMA_TAG *pMem; - if (spr1->qwc == 0) return 0; + if (spr1ch.qwc == 0) return 0; - pMem = SPRdmaGetAddr(spr1->madr, false); + pMem = SPRdmaGetAddr(spr1ch.madr, false); if (pMem == NULL) return -1; - SPR1transfer(pMem, spr1->qwc); - spr1->madr += spr1->qwc * 16; + SPR1transfer(pMem, spr1ch.qwc); + spr1ch.madr += spr1ch.qwc * 16; - return (spr1->qwc); + return (spr1ch.qwc); } __fi void SPR1chain() { CPU_INT(DMAC_TO_SPR, _SPR1chain() / BIAS); - spr1->qwc = 0; + spr1ch.qwc = 0; } void _SPR1interleave() { - int qwc = spr1->qwc; - int sqwc = dmacRegs->sqwc.SQWC; - int tqwc = dmacRegs->sqwc.TQWC; + int qwc = spr1ch.qwc; + int sqwc = dmacRegs.sqwc.SQWC; + int tqwc = dmacRegs.sqwc.TQWC; tDMA_TAG *pMem; if (tqwc == 0) tqwc = qwc; SPR_LOG("SPR1 interleave size=%d, tqwc=%d, sqwc=%d, addr=%lx sadr=%lx", - spr1->qwc, tqwc, sqwc, spr1->madr, spr1->sadr); + spr1ch.qwc, tqwc, sqwc, spr1ch.madr, spr1ch.sadr); CPU_INT(DMAC_TO_SPR, qwc / BIAS); while (qwc > 0) { - spr1->qwc = std::min(tqwc, qwc); - qwc -= spr1->qwc; - pMem = SPRdmaGetAddr(spr1->madr, false); - memcpy_qwc(&psSu128(spr1->sadr), pMem, spr1->qwc); - spr1->sadr += spr1->qwc * 16; - spr1->madr += (sqwc + spr1->qwc) * 16; + spr1ch.qwc = std::min(tqwc, qwc); + qwc -= spr1ch.qwc; + pMem = SPRdmaGetAddr(spr1ch.madr, false); + memcpy_qwc(&psSu128(spr1ch.sadr), pMem, spr1ch.qwc); + spr1ch.sadr += spr1ch.qwc * 16; + spr1ch.madr += (sqwc + spr1ch.qwc) * 16; } - spr1->qwc = 0; + spr1ch.qwc = 0; } void _dmaSPR1() // toSPR work function { - switch(spr1->chcr.MOD) + switch(spr1ch.chcr.MOD) { case NORMAL_MODE: { @@ -341,39 +341,39 @@ void _dmaSPR1() // toSPR work function tDMA_TAG *ptag; bool done = false; - if (spr1->qwc > 0) + if (spr1ch.qwc > 0) { - SPR_LOG("spr1 Normal or in Progress size=%d, addr=%lx taddr=%lx saddr=%lx", spr1->qwc, spr1->madr, spr1->tadr, spr1->sadr); + SPR_LOG("spr1 Normal or in Progress size=%d, addr=%lx taddr=%lx saddr=%lx", spr1ch.qwc, spr1ch.madr, spr1ch.tadr, spr1ch.sadr); // Transfer Dn_QWC from Dn_MADR to SPR1 SPR1chain(); return; } // Chain Mode - ptag = SPRdmaGetAddr(spr1->tadr, false); //Set memory pointer to TADR + ptag = SPRdmaGetAddr(spr1ch.tadr, false); //Set memory pointer to TADR - if (!spr1->transfer("SPR1 Tag", ptag)) + if (!spr1ch.transfer("SPR1 Tag", ptag)) { done = true; spr1finished = done; } - spr1->madr = ptag[1]._u32; //MADR = ADDR field + SPR + spr1ch.madr = ptag[1]._u32; //MADR = ADDR field + SPR // Transfer dma tag if tte is set - if (spr1->chcr.TTE) + if (spr1ch.chcr.TTE) { SPR_LOG("SPR TTE: %x_%x\n", ptag[3]._u32, ptag[2]._u32); SPR1transfer(ptag, 1); //Transfer Tag } SPR_LOG("spr1 dmaChain %8.8x_%8.8x size=%d, id=%d, addr=%lx taddr=%lx saddr=%lx", - ptag[1]._u32, ptag[0]._u32, spr1->qwc, ptag->ID, spr1->madr, spr1->tadr, spr1->sadr); + ptag[1]._u32, ptag[0]._u32, spr1ch.qwc, ptag->ID, spr1ch.madr, spr1ch.tadr, spr1ch.sadr); - done = (hwDmacSrcChain(spr1, ptag->ID)); + done = (hwDmacSrcChain(spr1ch, ptag->ID)); SPR1chain(); //Transfers the data set by the switch - if (spr1->chcr.TIE && ptag->IRQ) //Check TIE bit of CHCR and IRQ bit of tag + if (spr1ch.chcr.TIE && ptag->IRQ) //Check TIE bit of CHCR and IRQ bit of tag { SPR_LOG("dmaIrq Set"); @@ -398,15 +398,15 @@ void dmaSPR1() // toSPR { SPR_LOG("dmaSPR1 chcr = 0x%x, madr = 0x%x, qwc = 0x%x\n" " tadr = 0x%x, sadr = 0x%x", - spr1->chcr._u32, spr1->madr, spr1->qwc, - spr1->tadr, spr1->sadr); + spr1ch.chcr._u32, spr1ch.madr, spr1ch.qwc, + spr1ch.tadr, spr1ch.sadr); spr1finished = false; //Init - if(spr1->chcr.MOD == CHAIN_MODE && spr1->qwc > 0) + if(spr1ch.chcr.MOD == CHAIN_MODE && spr1ch.qwc > 0) { - //DevCon.Warning(L"SPR1 QWC on Chain " + spr1->chcr.desc()); - if ((spr1->chcr.tag().ID == TAG_END) || (spr1->chcr.tag().ID == TAG_REFE)) + //DevCon.Warning(L"SPR1 QWC on Chain " + spr1ch.chcr.desc()); + if ((spr1ch.chcr.tag().ID == TAG_END) || (spr1ch.chcr.tag().ID == TAG_REFE)) { spr1finished = true; } @@ -418,14 +418,14 @@ void dmaSPR1() // toSPR void SPRTOinterrupt() { SPR_LOG("SPR1 Interrupt"); - if (!spr1finished || spr1->qwc > 0) + if (!spr1finished || spr1ch.qwc > 0) { _dmaSPR1(); return; } SPR_LOG("SPR1 End"); - spr1->chcr.STR = false; + spr1ch.chcr.STR = false; hwDmacIrq(DMAC_TO_SPR); } diff --git a/pcsx2/SaveState.cpp b/pcsx2/SaveState.cpp index 651a1e9029..4967971662 100644 --- a/pcsx2/SaveState.cpp +++ b/pcsx2/SaveState.cpp @@ -154,7 +154,7 @@ void SaveStateBase::FreezeMainMemory() // --------------------------- FreezeMem(eeMem->Main, Ps2MemSize::Base); // 32 MB main memory FreezeMem(eeMem->Scratch, Ps2MemSize::Scratch); // scratch pad - FreezeMem(eeMem->HW, Ps2MemSize::Hardware); // hardware memory + FreezeMem(eeHw, Ps2MemSize::Hardware); // hardware memory FreezeMem(psxM, Ps2MemSize::IopRam); // 2 MB main memory FreezeMem(psxH, Ps2MemSize::IopHardware); // hardware memory @@ -194,6 +194,7 @@ void SaveStateBase::FreezeRegisters() vif1Freeze(); sifFreeze(); ipuFreeze(); + ipuDmaFreeze(); gifFreeze(); sprFreeze(); diff --git a/pcsx2/SaveState.h b/pcsx2/SaveState.h index 5d2783a545..f1bcda1950 100644 --- a/pcsx2/SaveState.h +++ b/pcsx2/SaveState.h @@ -24,7 +24,7 @@ // the lower 16 bit value. IF the change is breaking of all compatibility with old // states, increment the upper 16 bit value, and clear the lower 16 bits to 0. -static const u32 g_SaveVersion = 0x8b480000; +static const u32 g_SaveVersion = 0x8b490000; // this function is meant to be used in the place of GSfreeze, and provides a safe layer // between the GS saving function and the MTGS's needs. :) @@ -214,6 +214,7 @@ protected: #endif void sifFreeze(); void ipuFreeze(); + void ipuDmaFreeze(); void gifFreeze(); void sprFreeze(); diff --git a/pcsx2/Sif.cpp b/pcsx2/Sif.cpp index a8c580e242..196298d18a 100644 --- a/pcsx2/Sif.cpp +++ b/pcsx2/Sif.cpp @@ -28,9 +28,9 @@ void sifInit() __fi void dmaSIF2() { - SIF_LOG(wxString(L"dmaSIF2" + sif2dma->cmq_to_str()).To8BitData()); + SIF_LOG(wxString(L"dmaSIF2" + sif2dma.cmq_to_str()).To8BitData()); - sif2dma->chcr.STR = false; + sif2dma.chcr.STR = false; hwDmacIrq(DMAC_SIF2); Console.WriteLn("*PCSX2*: dmaSIF2"); } diff --git a/pcsx2/Sif.h b/pcsx2/Sif.h index 5744dee6cc..9d276a4a78 100644 --- a/pcsx2/Sif.h +++ b/pcsx2/Sif.h @@ -16,7 +16,12 @@ #ifndef __SIF_H__ #define __SIF_H__ -#define FIFO_SIF_W 128 +static const int FIFO_SIF_W = 128; + +static DMACh& sif0dma = (DMACh&)eeHw[0xc000]; +static DMACh& sif1dma = (DMACh&)eeHw[0xc400]; +static DMACh& sif2dma = (DMACh&)eeHw[0xc800]; + struct sifData { diff --git a/pcsx2/Sif0.cpp b/pcsx2/Sif0.cpp index af60bb60af..29ecc0ea90 100644 --- a/pcsx2/Sif0.cpp +++ b/pcsx2/Sif0.cpp @@ -35,14 +35,14 @@ static __fi void Sif0Init() // Write from Fifo to EE. static __fi bool WriteFifoToEE() { - const int readSize = min((s32)sif0dma->qwc, sif0.fifo.size >> 2); + const int readSize = min((s32)sif0dma.qwc, sif0.fifo.size >> 2); tDMA_TAG *ptag; - //SIF_LOG(" EE SIF doing transfer %04Xqw to %08X", readSize, sif0dma->madr); - SIF_LOG("Write Fifo to EE: ----------- %lX of %lX", readSize << 2, sif0dma->qwc << 2); + //SIF_LOG(" EE SIF doing transfer %04Xqw to %08X", readSize, sif0dma.madr); + SIF_LOG("Write Fifo to EE: ----------- %lX of %lX", readSize << 2, sif0dma.qwc << 2); - ptag = sif0dma->getAddr(sif0dma->madr, DMAC_SIF0, true); + ptag = sif0dma.getAddr(sif0dma.madr, DMAC_SIF0, true); if (ptag == NULL) { DevCon.Warning("Write Fifo to EE: ptag == NULL"); @@ -52,11 +52,11 @@ static __fi bool WriteFifoToEE() sif0.fifo.read((u32*)ptag, readSize << 2); // Clearing handled by vtlb memory protection and manual blocks. - //Cpu->Clear(sif0dma->madr, readSize*4); + //Cpu->Clear(sif0dma.madr, readSize*4); - sif0dma->madr += readSize << 4; + sif0dma.madr += readSize << 4; sif0.ee.cycles += readSize; // fixme : BIAS is factored in above - sif0dma->qwc -= readSize; + sif0dma.qwc -= readSize; return true; } @@ -87,14 +87,14 @@ static __fi bool ProcessEETag() sif0.fifo.read((u32*)&tag[0], 4); // Tag SIF_LOG("SIF0 EE read tag: %x %x %x %x", tag[0], tag[1], tag[2], tag[3]); - sif0dma->unsafeTransfer(((tDMA_TAG*)(tag))); - sif0dma->madr = tag[1]; + sif0dma.unsafeTransfer(((tDMA_TAG*)(tag))); + sif0dma.madr = tag[1]; tDMA_TAG ptag(tag[0]); SIF_LOG("SIF0 EE dest chain tag madr:%08X qwc:%04X id:%X irq:%d(%08X_%08X)", - sif0dma->madr, sif0dma->qwc, ptag.ID, ptag.IRQ, tag[1], tag[0]); + sif0dma.madr, sif0dma.qwc, ptag.ID, ptag.IRQ, tag[1], tag[0]); - if (sif0dma->chcr.TIE && ptag.IRQ) + if (sif0dma.chcr.TIE && ptag.IRQ) { //Console.WriteLn("SIF0 TIE"); sif0.ee.end = true; @@ -104,13 +104,13 @@ static __fi bool ProcessEETag() { case TAG_REFE: sif0.ee.end = true; - if (dmacRegs->ctrl.STS != NO_STS) - dmacRegs->stadr.ADDR = sif0dma->madr + (sif0dma->qwc * 16); + if (dmacRegs.ctrl.STS != NO_STS) + dmacRegs.stadr.ADDR = sif0dma.madr + (sif0dma.qwc * 16); break; case TAG_REFS: - if (dmacRegs->ctrl.STS != NO_STS) - dmacRegs->stadr.ADDR = sif0dma->madr + (sif0dma->qwc * 16); + if (dmacRegs.ctrl.STS != NO_STS) + dmacRegs.stadr.ADDR = sif0dma.madr + (sif0dma.qwc * 16); break; case TAG_END: @@ -177,7 +177,7 @@ static __fi void EndIOP() // Handle the EE transfer. static __fi void HandleEETransfer() { - if(sif0dma->chcr.STR == false) + if(sif0dma.chcr.STR == false) { DevCon.Warning("Replacement for irq prevention hack EE SIF0"); sif0.ee.end = false; @@ -185,22 +185,22 @@ static __fi void HandleEETransfer() return; } - if (dmacRegs->ctrl.STS == STS_SIF0) + if (dmacRegs.ctrl.STS == STS_SIF0) { DevCon.Warning("SIF0 stall control"); } - /*if (sif0dma->qwc == 0) - if (sif0dma->chcr.MOD == NORMAL_MODE) + /*if (sif0dma.qwc == 0) + if (sif0dma.chcr.MOD == NORMAL_MODE) if (!sif0.ee.end){ DevCon.Warning("sif0 irq prevented"); done = true; return; }*/ - if (sif0dma->qwc <= 0) + if (sif0dma.qwc <= 0) { - if ((sif0dma->chcr.MOD == NORMAL_MODE) || sif0.ee.end) + if ((sif0dma.chcr.MOD == NORMAL_MODE) || sif0.ee.end) { // Stop transferring ee, and signal an interrupt. done = true; @@ -214,7 +214,7 @@ static __fi void HandleEETransfer() } } - if (sif0dma->qwc > 0) // If we're writing something, continue to do so. + if (sif0dma.qwc > 0) // If we're writing something, continue to do so. { // Write from Fifo to EE. if (sif0.fifo.size > 0) @@ -306,7 +306,7 @@ __fi void SIF0Dma() } if (sif0.ee.busy) { - if(sif0.fifo.size >= 4 || (sif0.ee.end == true && sif0dma->qwc == 0)) + if(sif0.fifo.size >= 4 || (sif0.ee.end == true && sif0dma.qwc == 0)) { BusyCheck++; HandleEETransfer(); @@ -326,19 +326,19 @@ __fi void sif0Interrupt() __fi void EEsif0Interrupt() { hwDmacIrq(DMAC_SIF0); - sif0dma->chcr.STR = false; + sif0dma.chcr.STR = false; } __fi void dmaSIF0() { - SIF_LOG(wxString(L"dmaSIF0" + sif0dma->cmqt_to_str()).To8BitData()); + SIF_LOG(wxString(L"dmaSIF0" + sif0dma.cmqt_to_str()).To8BitData()); if (sif0.fifo.readPos != sif0.fifo.writePos) { SIF_LOG("warning, sif0.fifoReadPos != sif0.fifoWritePos"); } - //if(sif0dma->chcr.MOD == CHAIN_MODE && sif0dma->qwc > 0) DevCon.Warning(L"SIF0 QWC on Chain CHCR " + sif0dma->chcr.desc()); + //if(sif0dma.chcr.MOD == CHAIN_MODE && sif0dma.qwc > 0) DevCon.Warning(L"SIF0 QWC on Chain CHCR " + sif0dma.chcr.desc()); psHu32(SBUS_F240) |= 0x2000; sif0.ee.busy = true; diff --git a/pcsx2/Sif1.cpp b/pcsx2/Sif1.cpp index 9581f15fca..58bb072af0 100644 --- a/pcsx2/Sif1.cpp +++ b/pcsx2/Sif1.cpp @@ -38,11 +38,11 @@ static __fi bool WriteEEtoFifo() // There's some data ready to transfer into the fifo.. SIF_LOG("Sif 1: Write EE to Fifo"); - const int writeSize = min((s32)sif1dma->qwc, sif1.fifo.free() >> 2); + const int writeSize = min((s32)sif1dma.qwc, sif1.fifo.free() >> 2); tDMA_TAG *ptag; - ptag = sif1dma->getAddr(sif1dma->madr, DMAC_SIF1, false); + ptag = sif1dma.getAddr(sif1dma.madr, DMAC_SIF1, false); if (ptag == NULL) { DevCon.Warning("Write EE to Fifo: ptag == NULL"); @@ -51,9 +51,9 @@ static __fi bool WriteEEtoFifo() sif1.fifo.write((u32*)ptag, writeSize << 2); - sif1dma->madr += writeSize << 4; + sif1dma.madr += writeSize << 4; sif1.ee.cycles += writeSize; // fixme : BIAS is factored in above - sif1dma->qwc -= writeSize; + sif1dma.qwc -= writeSize; return true; } @@ -84,21 +84,21 @@ static __fi bool ProcessEETag() tDMA_TAG *ptag; SIF_LOG("Sif1: ProcessEETag"); - // Process DMA tag at sif1dma->tadr - ptag = sif1dma->DMAtransfer(sif1dma->tadr, DMAC_SIF1); + // Process DMA tag at sif1dma.tadr + ptag = sif1dma.DMAtransfer(sif1dma.tadr, DMAC_SIF1); if (ptag == NULL) { Console.WriteLn("Sif1 ProcessEETag: ptag = NULL"); return false; } - if (sif1dma->chcr.TTE) + if (sif1dma.chcr.TTE) { Console.WriteLn("SIF1 TTE"); sif1.fifo.write((u32*)ptag + 2, 2); } - if (sif1dma->chcr.TIE && ptag->IRQ) + if (sif1dma.chcr.TIE && ptag->IRQ) { Console.WriteLn("SIF1 TIE"); sif1.ee.end = true; @@ -109,30 +109,30 @@ static __fi bool ProcessEETag() { case TAG_REFE: sif1.ee.end = true; - sif1dma->madr = ptag[1]._u32; - sif1dma->tadr += 16; + sif1dma.madr = ptag[1]._u32; + sif1dma.tadr += 16; break; case TAG_CNT: - sif1dma->madr = sif1dma->tadr + 16; - sif1dma->tadr = sif1dma->madr + (sif1dma->qwc << 4); + sif1dma.madr = sif1dma.tadr + 16; + sif1dma.tadr = sif1dma.madr + (sif1dma.qwc << 4); break; case TAG_NEXT: - sif1dma->madr = sif1dma->tadr + 16; - sif1dma->tadr = ptag[1]._u32; + sif1dma.madr = sif1dma.tadr + 16; + sif1dma.tadr = ptag[1]._u32; break; case TAG_REF: case TAG_REFS: - sif1dma->madr = ptag[1]._u32; - sif1dma->tadr += 16; + sif1dma.madr = ptag[1]._u32; + sif1dma.tadr += 16; break; case TAG_END: sif1.ee.end = true; - sif1dma->madr = sif1dma->tadr + 16; - sif1dma->tadr = sif1dma->madr + (sif1dma->qwc << 4); + sif1dma.madr = sif1dma.tadr + 16; + sif1dma.tadr = sif1dma.madr + (sif1dma.qwc << 4); break; default: @@ -203,31 +203,31 @@ static __fi void EndIOP() // Handle the EE transfer. static __fi void HandleEETransfer() { - if(sif1dma->chcr.STR == false) + if(sif1dma.chcr.STR == false) { DevCon.Warning("Replacement for irq prevention hack EE SIF1"); sif1.ee.end = false; sif1.ee.busy = false; return; } - if (dmacRegs->ctrl.STD == STD_SIF1) + if (dmacRegs.ctrl.STD == STD_SIF1) { DevCon.Warning("SIF1 stall control"); // STD == fromSIF1 } - /*if (sif1dma->qwc == 0) - if (sif1dma->chcr.MOD == NORMAL_MODE) + /*if (sif1dma.qwc == 0) + if (sif1dma.chcr.MOD == NORMAL_MODE) if (!sif1.ee.end){ - DevCon.Warning("sif1 irq prevented CHCR %x QWC %x", sif1dma->chcr, sif1dma->qwc); + DevCon.Warning("sif1 irq prevented CHCR %x QWC %x", sif1dma.chcr, sif1dma.qwc); done = true; return; }*/ // If there's no more to transfer. - if (sif1dma->qwc <= 0) + if (sif1dma.qwc <= 0) { // If NORMAL mode or end of CHAIN then stop DMA. - if ((sif1dma->chcr.MOD == NORMAL_MODE) || sif1.ee.end) + if ((sif1dma.chcr.MOD == NORMAL_MODE) || sif1.ee.end) { done = true; EndEE(); @@ -292,7 +292,7 @@ __fi void SIF1Dma() if (sif1.ee.busy) { - if(sif1.fifo.free() > 0 || (sif1.ee.end == true && sif1dma->qwc == 0)) + if(sif1.fifo.free() > 0 || (sif1.ee.end == true && sif1dma.qwc == 0)) { BusyCheck++; HandleEETransfer(); @@ -322,21 +322,21 @@ __fi void sif1Interrupt() __fi void EEsif1Interrupt() { hwDmacIrq(DMAC_SIF1); - sif1dma->chcr.STR = false; + sif1dma.chcr.STR = false; } // Do almost exactly the same thing as psxDma10 in IopDma.cpp. // Main difference is this checks for iop, where psxDma10 checks for ee. __fi void dmaSIF1() { - SIF_LOG(wxString(L"dmaSIF1" + sif1dma->cmqt_to_str()).To8BitData()); + SIF_LOG(wxString(L"dmaSIF1" + sif1dma.cmqt_to_str()).To8BitData()); if (sif1.fifo.readPos != sif1.fifo.writePos) { SIF_LOG("warning, sif1.fifoReadPos != sif1.fifoWritePos"); } - //if(sif1dma->chcr.MOD == CHAIN_MODE && sif1dma->qwc > 0) DevCon.Warning(L"SIF1 QWC on Chain CHCR " + sif1dma->chcr.desc()); + //if(sif1dma.chcr.MOD == CHAIN_MODE && sif1dma.qwc > 0) DevCon.Warning(L"SIF1 QWC on Chain CHCR " + sif1dma.chcr.desc()); psHu32(SBUS_F240) |= 0x4000; sif1.ee.busy = true; diff --git a/pcsx2/VU.h b/pcsx2/VU.h index bec6ae8ebf..3159a964b3 100644 --- a/pcsx2/VU.h +++ b/pcsx2/VU.h @@ -16,10 +16,6 @@ #pragma once #include "Vif.h" -#ifdef _MSC_VER // Most of the structs here should be packed -# pragma pack(1) -#endif - enum VURegFlags { REG_STATUS_FLAG = 16, @@ -68,7 +64,7 @@ union VECTOR { s16 SS[8]; u8 UC[16]; s8 SC[16]; -} __packed; +}; struct REG_VI { union { @@ -82,7 +78,7 @@ struct REG_VI { }; u32 padding[3]; // needs padding to make them 128bit; VU0 maps VU1's VI regs as 128bits to addr 0x4xx0 in // VU0 mem, with only lower 16 bits valid, and the upper 112bits are hardwired to 0 (cottonvibes) -} __packed; +}; //#define VUFLAG_BREAKONMFLAG 0x00000001 #define VUFLAG_MFLAGSET 0x00000002 @@ -120,45 +116,61 @@ struct ialuPipe { u32 Cycle; }; -struct VURegs { +struct __aligned16 VURegs { VECTOR VF[32]; // VF and VI need to be first in this struct for proper mapping REG_VI VI[32]; // needs to be 128bit x 32 (cottonvibes) + VECTOR ACC; REG_VI q; REG_VI p; + uint idx; // VU index (0 or 1) + + // flags/cycle are needed by VIF dma code, so they have to be here (for now) + // We may replace these by accessors in the future, if merited. + u32 cycle; + u32 flags; + + // Current opcode being interpreted or recompiled (this var is used by Interps and superVU + // but not microVU. Would like to have it local to their respective classes... someday) + u32 code; + + // branch/branchpc are used by interpreter only, but making them local to the interpreter + // classes requires considerable code refactoring. Maybe later. >_< + u32 branch; + u32 branchpc; + + // MAC/Status flags -- these are used by interpreters and superVU, but are kind of hacky + // and shouldn't be relied on for any useful/valid info. Would like to move them out of + // this struct eventually. u32 macflag; u32 statusflag; u32 clipflag; - u32 cycle; - u32 flags; - - void (*vuExec)(VURegs*); - VIFregisters *vifRegs; - u8 *Mem; u8 *Micro; - u32 code; - u32 maxmem; - u32 maxmicro; - - u16 branch; - u16 ebit; - u32 branchpc; + u32 ebit; fmacPipe fmac[8]; fdivPipe fdiv; efuPipe efu; ialuPipe ialu[8]; - VURegs() : - Mem( NULL ) - , Micro( NULL ) + VURegs() { + Mem = NULL; + Micro = NULL; } -} __packed; + + bool IsVU1() const; + bool IsVU0() const; + + VIFregisters& GetVifRegs() const + { + return IsVU1() ? vif1Regs : vif0Regs; + } +}; enum VUPipeState { @@ -171,27 +183,16 @@ enum VUPipeState VUPIPE_XGKICK }; -struct _VURegsNum { - u8 pipe; // if 0xff, COP2 - u8 VFwrite; - u8 VFwxyzw; - u8 VFr0xyzw; - u8 VFr1xyzw; - u8 VFread0; - u8 VFread1; - u32 VIwrite; - u32 VIread; - int cycles; -}; +extern __aligned16 VURegs vuRegs[2]; -#ifdef _MSC_VER // Restore to default pack alignment -# pragma pack() -#endif +// Obsolete(?) -- I think I'd rather use vu0Regs/vu1Regs or actually have these explicit to any +// CPP file that needs them only. --air +static VURegs& VU0 = vuRegs[0]; +static VURegs& VU1 = vuRegs[1]; -extern VURegs* g_pVU1; -extern __aligned16 VURegs VU0; - -#define VU1 (*g_pVU1) +// Do not use __fi here because it fires 'multiple definition' error in GCC +inline bool VURegs::IsVU1() const { return this == &vuRegs[1]; } +inline bool VURegs::IsVU0() const { return this == &vuRegs[0]; } extern u32* GET_VU_MEM(VURegs* VU, u32 addr); diff --git a/pcsx2/VU0.cpp b/pcsx2/VU0.cpp index cd14811666..9ece6dd2d5 100644 --- a/pcsx2/VU0.cpp +++ b/pcsx2/VU0.cpp @@ -44,8 +44,6 @@ using namespace R5900; -__aligned16 VURegs VU0; - void COP2_BC2() { Int_COP2BC2PrintTable[_Rt_]();} void COP2_SPECIAL() { Int_COP2SPECIAL1PrintTable[_Funct_]();} @@ -88,15 +86,10 @@ namespace OpcodeImpl void LQC2() { u32 addr = cpuRegs.GPR.r[_Rs_].UL[0] + (s16)cpuRegs.code; if (_Ft_) { -#ifdef __LINUX__ - // Ifdeffing mainly because I haven't gotten around to checking it in Windows yet. - memRead128(addr, &VU0.VF[_Ft_].UQ); -#else - memRead128(addr, VU0.VF[_Ft_].UD); -#endif + memRead128(addr, VU0.VF[_Ft_].UQ); } else { - u64 val[2]; - memRead128(addr, val); + u128 val; + memRead128(addr, val); } } @@ -105,9 +98,7 @@ namespace OpcodeImpl // HUH why ? doesn't make any sense ... void SQC2() { u32 addr = _Imm_ + cpuRegs.GPR.r[_Rs_].UL[0]; - //memWrite64(addr, VU0.VF[_Ft_].UD[0]); - //memWrite64(addr+8,VU0.VF[_Ft_].UD[1]); - memWrite128(addr, VU0.VF[_Ft_].UD); + memWrite128(addr, VU0.VF[_Ft_].UQ); } }}} @@ -180,158 +171,3 @@ void CTC2() { break; } } - -//--------------------------------------------------------------------------------------- - - -__fi void SYNCMSFLAGS() -{ - VU0.VI[REG_STATUS_FLAG].UL = VU0.statusflag; - VU0.VI[REG_MAC_FLAG].UL = VU0.macflag; -} - -__fi void SYNCFDIV() -{ - VU0.VI[REG_Q].UL = VU0.q.UL; - VU0.VI[REG_STATUS_FLAG].UL = VU0.statusflag; -} - -void VABS() { VU0.code = cpuRegs.code; _vuABS(&VU0); } -void VADD() { VU0.code = cpuRegs.code; _vuADD(&VU0); SYNCMSFLAGS(); } -void VADDi() { VU0.code = cpuRegs.code; _vuADDi(&VU0); SYNCMSFLAGS(); } -void VADDq() { VU0.code = cpuRegs.code; _vuADDq(&VU0); SYNCMSFLAGS(); } -void VADDx() { VU0.code = cpuRegs.code; _vuADDx(&VU0); SYNCMSFLAGS(); } -void VADDy() { VU0.code = cpuRegs.code; _vuADDy(&VU0); SYNCMSFLAGS(); } -void VADDz() { VU0.code = cpuRegs.code; _vuADDz(&VU0); SYNCMSFLAGS(); } -void VADDw() { VU0.code = cpuRegs.code; _vuADDw(&VU0); SYNCMSFLAGS(); } -void VADDA() { VU0.code = cpuRegs.code; _vuADDA(&VU0); SYNCMSFLAGS(); } -void VADDAi() { VU0.code = cpuRegs.code; _vuADDAi(&VU0); SYNCMSFLAGS(); } -void VADDAq() { VU0.code = cpuRegs.code; _vuADDAq(&VU0); SYNCMSFLAGS(); } -void VADDAx() { VU0.code = cpuRegs.code; _vuADDAx(&VU0); SYNCMSFLAGS(); } -void VADDAy() { VU0.code = cpuRegs.code; _vuADDAy(&VU0); SYNCMSFLAGS(); } -void VADDAz() { VU0.code = cpuRegs.code; _vuADDAz(&VU0); SYNCMSFLAGS(); } -void VADDAw() { VU0.code = cpuRegs.code; _vuADDAw(&VU0); SYNCMSFLAGS(); } -void VSUB() { VU0.code = cpuRegs.code; _vuSUB(&VU0); SYNCMSFLAGS(); } -void VSUBi() { VU0.code = cpuRegs.code; _vuSUBi(&VU0); SYNCMSFLAGS(); } -void VSUBq() { VU0.code = cpuRegs.code; _vuSUBq(&VU0); SYNCMSFLAGS(); } -void VSUBx() { VU0.code = cpuRegs.code; _vuSUBx(&VU0); SYNCMSFLAGS(); } -void VSUBy() { VU0.code = cpuRegs.code; _vuSUBy(&VU0); SYNCMSFLAGS(); } -void VSUBz() { VU0.code = cpuRegs.code; _vuSUBz(&VU0); SYNCMSFLAGS(); } -void VSUBw() { VU0.code = cpuRegs.code; _vuSUBw(&VU0); SYNCMSFLAGS(); } -void VSUBA() { VU0.code = cpuRegs.code; _vuSUBA(&VU0); SYNCMSFLAGS(); } -void VSUBAi() { VU0.code = cpuRegs.code; _vuSUBAi(&VU0); SYNCMSFLAGS(); } -void VSUBAq() { VU0.code = cpuRegs.code; _vuSUBAq(&VU0); SYNCMSFLAGS(); } -void VSUBAx() { VU0.code = cpuRegs.code; _vuSUBAx(&VU0); SYNCMSFLAGS(); } -void VSUBAy() { VU0.code = cpuRegs.code; _vuSUBAy(&VU0); SYNCMSFLAGS(); } -void VSUBAz() { VU0.code = cpuRegs.code; _vuSUBAz(&VU0); SYNCMSFLAGS(); } -void VSUBAw() { VU0.code = cpuRegs.code; _vuSUBAw(&VU0); SYNCMSFLAGS(); } -void VMUL() { VU0.code = cpuRegs.code; _vuMUL(&VU0); SYNCMSFLAGS(); } -void VMULi() { VU0.code = cpuRegs.code; _vuMULi(&VU0); SYNCMSFLAGS(); } -void VMULq() { VU0.code = cpuRegs.code; _vuMULq(&VU0); SYNCMSFLAGS(); } -void VMULx() { VU0.code = cpuRegs.code; _vuMULx(&VU0); SYNCMSFLAGS(); } -void VMULy() { VU0.code = cpuRegs.code; _vuMULy(&VU0); SYNCMSFLAGS(); } -void VMULz() { VU0.code = cpuRegs.code; _vuMULz(&VU0); SYNCMSFLAGS(); } -void VMULw() { VU0.code = cpuRegs.code; _vuMULw(&VU0); SYNCMSFLAGS(); } -void VMULA() { VU0.code = cpuRegs.code; _vuMULA(&VU0); SYNCMSFLAGS(); } -void VMULAi() { VU0.code = cpuRegs.code; _vuMULAi(&VU0); SYNCMSFLAGS(); } -void VMULAq() { VU0.code = cpuRegs.code; _vuMULAq(&VU0); SYNCMSFLAGS(); } -void VMULAx() { VU0.code = cpuRegs.code; _vuMULAx(&VU0); SYNCMSFLAGS(); } -void VMULAy() { VU0.code = cpuRegs.code; _vuMULAy(&VU0); SYNCMSFLAGS(); } -void VMULAz() { VU0.code = cpuRegs.code; _vuMULAz(&VU0); SYNCMSFLAGS(); } -void VMULAw() { VU0.code = cpuRegs.code; _vuMULAw(&VU0); SYNCMSFLAGS(); } -void VMADD() { VU0.code = cpuRegs.code; _vuMADD(&VU0); SYNCMSFLAGS(); } -void VMADDi() { VU0.code = cpuRegs.code; _vuMADDi(&VU0); SYNCMSFLAGS(); } -void VMADDq() { VU0.code = cpuRegs.code; _vuMADDq(&VU0); SYNCMSFLAGS(); } -void VMADDx() { VU0.code = cpuRegs.code; _vuMADDx(&VU0); SYNCMSFLAGS(); } -void VMADDy() { VU0.code = cpuRegs.code; _vuMADDy(&VU0); SYNCMSFLAGS(); } -void VMADDz() { VU0.code = cpuRegs.code; _vuMADDz(&VU0); SYNCMSFLAGS(); } -void VMADDw() { VU0.code = cpuRegs.code; _vuMADDw(&VU0); SYNCMSFLAGS(); } -void VMADDA() { VU0.code = cpuRegs.code; _vuMADDA(&VU0); SYNCMSFLAGS(); } -void VMADDAi() { VU0.code = cpuRegs.code; _vuMADDAi(&VU0); SYNCMSFLAGS(); } -void VMADDAq() { VU0.code = cpuRegs.code; _vuMADDAq(&VU0); SYNCMSFLAGS(); } -void VMADDAx() { VU0.code = cpuRegs.code; _vuMADDAx(&VU0); SYNCMSFLAGS(); } -void VMADDAy() { VU0.code = cpuRegs.code; _vuMADDAy(&VU0); SYNCMSFLAGS(); } -void VMADDAz() { VU0.code = cpuRegs.code; _vuMADDAz(&VU0); SYNCMSFLAGS(); } -void VMADDAw() { VU0.code = cpuRegs.code; _vuMADDAw(&VU0); SYNCMSFLAGS(); } -void VMSUB() { VU0.code = cpuRegs.code; _vuMSUB(&VU0); SYNCMSFLAGS(); } -void VMSUBi() { VU0.code = cpuRegs.code; _vuMSUBi(&VU0); SYNCMSFLAGS(); } -void VMSUBq() { VU0.code = cpuRegs.code; _vuMSUBq(&VU0); SYNCMSFLAGS(); } -void VMSUBx() { VU0.code = cpuRegs.code; _vuMSUBx(&VU0); SYNCMSFLAGS(); } -void VMSUBy() { VU0.code = cpuRegs.code; _vuMSUBy(&VU0); SYNCMSFLAGS(); } -void VMSUBz() { VU0.code = cpuRegs.code; _vuMSUBz(&VU0); SYNCMSFLAGS(); } -void VMSUBw() { VU0.code = cpuRegs.code; _vuMSUBw(&VU0); SYNCMSFLAGS(); } -void VMSUBA() { VU0.code = cpuRegs.code; _vuMSUBA(&VU0); SYNCMSFLAGS(); } -void VMSUBAi() { VU0.code = cpuRegs.code; _vuMSUBAi(&VU0); SYNCMSFLAGS(); } -void VMSUBAq() { VU0.code = cpuRegs.code; _vuMSUBAq(&VU0); SYNCMSFLAGS(); } -void VMSUBAx() { VU0.code = cpuRegs.code; _vuMSUBAx(&VU0); SYNCMSFLAGS(); } -void VMSUBAy() { VU0.code = cpuRegs.code; _vuMSUBAy(&VU0); SYNCMSFLAGS(); } -void VMSUBAz() { VU0.code = cpuRegs.code; _vuMSUBAz(&VU0); SYNCMSFLAGS(); } -void VMSUBAw() { VU0.code = cpuRegs.code; _vuMSUBAw(&VU0); SYNCMSFLAGS(); } -void VMAX() { VU0.code = cpuRegs.code; _vuMAX(&VU0); } -void VMAXi() { VU0.code = cpuRegs.code; _vuMAXi(&VU0); } -void VMAXx() { VU0.code = cpuRegs.code; _vuMAXx(&VU0); } -void VMAXy() { VU0.code = cpuRegs.code; _vuMAXy(&VU0); } -void VMAXz() { VU0.code = cpuRegs.code; _vuMAXz(&VU0); } -void VMAXw() { VU0.code = cpuRegs.code; _vuMAXw(&VU0); } -void VMINI() { VU0.code = cpuRegs.code; _vuMINI(&VU0); } -void VMINIi() { VU0.code = cpuRegs.code; _vuMINIi(&VU0); } -void VMINIx() { VU0.code = cpuRegs.code; _vuMINIx(&VU0); } -void VMINIy() { VU0.code = cpuRegs.code; _vuMINIy(&VU0); } -void VMINIz() { VU0.code = cpuRegs.code; _vuMINIz(&VU0); } -void VMINIw() { VU0.code = cpuRegs.code; _vuMINIw(&VU0); } -void VOPMULA() { VU0.code = cpuRegs.code; _vuOPMULA(&VU0); SYNCMSFLAGS(); } -void VOPMSUB() { VU0.code = cpuRegs.code; _vuOPMSUB(&VU0); SYNCMSFLAGS(); } -void VNOP() { VU0.code = cpuRegs.code; _vuNOP(&VU0); } -void VFTOI0() { VU0.code = cpuRegs.code; _vuFTOI0(&VU0); } -void VFTOI4() { VU0.code = cpuRegs.code; _vuFTOI4(&VU0); } -void VFTOI12() { VU0.code = cpuRegs.code; _vuFTOI12(&VU0); } -void VFTOI15() { VU0.code = cpuRegs.code; _vuFTOI15(&VU0); } -void VITOF0() { VU0.code = cpuRegs.code; _vuITOF0(&VU0); } -void VITOF4() { VU0.code = cpuRegs.code; _vuITOF4(&VU0); } -void VITOF12() { VU0.code = cpuRegs.code; _vuITOF12(&VU0); } -void VITOF15() { VU0.code = cpuRegs.code; _vuITOF15(&VU0); } -void VCLIPw() { VU0.code = cpuRegs.code; _vuCLIP(&VU0); VU0.VI[REG_CLIP_FLAG].UL = VU0.clipflag; } - -void VDIV() { VU0.code = cpuRegs.code; _vuDIV(&VU0); SYNCFDIV(); } -void VSQRT() { VU0.code = cpuRegs.code; _vuSQRT(&VU0); SYNCFDIV(); } -void VRSQRT() { VU0.code = cpuRegs.code; _vuRSQRT(&VU0); SYNCFDIV(); } -void VIADD() { VU0.code = cpuRegs.code; _vuIADD(&VU0); } -void VIADDI() { VU0.code = cpuRegs.code; _vuIADDI(&VU0); } -void VIADDIU() { VU0.code = cpuRegs.code; _vuIADDIU(&VU0); } -void VIAND() { VU0.code = cpuRegs.code; _vuIAND(&VU0); } -void VIOR() { VU0.code = cpuRegs.code; _vuIOR(&VU0); } -void VISUB() { VU0.code = cpuRegs.code; _vuISUB(&VU0); } -void VISUBIU() { VU0.code = cpuRegs.code; _vuISUBIU(&VU0); } -void VMOVE() { VU0.code = cpuRegs.code; _vuMOVE(&VU0); } -void VMFIR() { VU0.code = cpuRegs.code; _vuMFIR(&VU0); } -void VMTIR() { VU0.code = cpuRegs.code; _vuMTIR(&VU0); } -void VMR32() { VU0.code = cpuRegs.code; _vuMR32(&VU0); } -void VLQ() { VU0.code = cpuRegs.code; _vuLQ(&VU0); } -void VLQD() { VU0.code = cpuRegs.code; _vuLQD(&VU0); } -void VLQI() { VU0.code = cpuRegs.code; _vuLQI(&VU0); } -void VSQ() { VU0.code = cpuRegs.code; _vuSQ(&VU0); } -void VSQD() { VU0.code = cpuRegs.code; _vuSQD(&VU0); } -void VSQI() { VU0.code = cpuRegs.code; _vuSQI(&VU0); } -void VILW() { VU0.code = cpuRegs.code; _vuILW(&VU0); } -void VISW() { VU0.code = cpuRegs.code; _vuISW(&VU0); } -void VILWR() { VU0.code = cpuRegs.code; _vuILWR(&VU0); } -void VISWR() { VU0.code = cpuRegs.code; _vuISWR(&VU0); } -void VRINIT() { VU0.code = cpuRegs.code; _vuRINIT(&VU0); } -void VRGET() { VU0.code = cpuRegs.code; _vuRGET(&VU0); } -void VRNEXT() { VU0.code = cpuRegs.code; _vuRNEXT(&VU0); } -void VRXOR() { VU0.code = cpuRegs.code; _vuRXOR(&VU0); } -void VWAITQ() { VU0.code = cpuRegs.code; _vuWAITQ(&VU0); } -void VFSAND() { VU0.code = cpuRegs.code; _vuFSAND(&VU0); } -void VFSEQ() { VU0.code = cpuRegs.code; _vuFSEQ(&VU0); } -void VFSOR() { VU0.code = cpuRegs.code; _vuFSOR(&VU0); } -void VFSSET() { VU0.code = cpuRegs.code; _vuFSSET(&VU0); } -void VFMAND() { VU0.code = cpuRegs.code; _vuFMAND(&VU0); } -void VFMEQ() { VU0.code = cpuRegs.code; _vuFMEQ(&VU0); } -void VFMOR() { VU0.code = cpuRegs.code; _vuFMOR(&VU0); } -void VFCAND() { VU0.code = cpuRegs.code; _vuFCAND(&VU0); } -void VFCEQ() { VU0.code = cpuRegs.code; _vuFCEQ(&VU0); } -void VFCOR() { VU0.code = cpuRegs.code; _vuFCOR(&VU0); } -void VFCSET() { VU0.code = cpuRegs.code; _vuFCSET(&VU0); } -void VFCGET() { VU0.code = cpuRegs.code; _vuFCGET(&VU0); } -void VXITOP() { VU0.code = cpuRegs.code; _vuXITOP(&VU0); } - diff --git a/pcsx2/VU0micro.cpp b/pcsx2/VU0micro.cpp index c44693bc63..d9e5d853f6 100644 --- a/pcsx2/VU0micro.cpp +++ b/pcsx2/VU0micro.cpp @@ -20,11 +20,10 @@ #include "PrecompiledHeader.h" #include "Common.h" +#include "VUmicro.h" #include -#include "VUmicro.h" - using namespace R5900; #define VF_VAL(x) ((x==0x80000000)?0:(x)) @@ -34,13 +33,7 @@ void vu0ResetRegs() { VU0.VI[REG_VPU_STAT].UL &= ~0xff; // stop vu0 VU0.VI[REG_FBRST].UL &= ~0xff; // stop vu0 - vif0Regs->stat.VEW = false; -} - -void VU0MI_XGKICK() { -} - -void VU0MI_XTOP() { + vif0Regs.stat.VEW = false; } void __fastcall vu0ExecMicro(u32 addr) { @@ -58,362 +51,3 @@ void __fastcall vu0ExecMicro(u32 addr) { _vuExecMicroDebug(VU0); CpuVU0->ExecuteBlock(1); } - -void VU0unknown() { - pxFailDev("Unknown VU micromode opcode called"); - CPU_LOG("Unknown VU micromode opcode called"); -} - -void VU0regsunknown(_VURegsNum *VUregsn) { - pxFailDev("Unknown VU micromode opcode called"); - CPU_LOG("Unknown VU micromode opcode called"); -} - -_vuRegsTables(VU0, VU0regs); - - -/****************************************/ -/* VU Micromode Upper instructions */ -/****************************************/ - -void VU0MI_ABS() { _vuABS(&VU0); } -void VU0MI_ADD() { _vuADD(&VU0); } -void VU0MI_ADDi() { _vuADDi(&VU0); } -void VU0MI_ADDq() { _vuADDq(&VU0); } -void VU0MI_ADDx() { _vuADDx(&VU0); } -void VU0MI_ADDy() { _vuADDy(&VU0); } -void VU0MI_ADDz() { _vuADDz(&VU0); } -void VU0MI_ADDw() { _vuADDw(&VU0); } -void VU0MI_ADDA() { _vuADDA(&VU0); } -void VU0MI_ADDAi() { _vuADDAi(&VU0); } -void VU0MI_ADDAq() { _vuADDAq(&VU0); } -void VU0MI_ADDAx() { _vuADDAx(&VU0); } -void VU0MI_ADDAy() { _vuADDAy(&VU0); } -void VU0MI_ADDAz() { _vuADDAz(&VU0); } -void VU0MI_ADDAw() { _vuADDAw(&VU0); } -void VU0MI_SUB() { _vuSUB(&VU0); } -void VU0MI_SUBi() { _vuSUBi(&VU0); } -void VU0MI_SUBq() { _vuSUBq(&VU0); } -void VU0MI_SUBx() { _vuSUBx(&VU0); } -void VU0MI_SUBy() { _vuSUBy(&VU0); } -void VU0MI_SUBz() { _vuSUBz(&VU0); } -void VU0MI_SUBw() { _vuSUBw(&VU0); } -void VU0MI_SUBA() { _vuSUBA(&VU0); } -void VU0MI_SUBAi() { _vuSUBAi(&VU0); } -void VU0MI_SUBAq() { _vuSUBAq(&VU0); } -void VU0MI_SUBAx() { _vuSUBAx(&VU0); } -void VU0MI_SUBAy() { _vuSUBAy(&VU0); } -void VU0MI_SUBAz() { _vuSUBAz(&VU0); } -void VU0MI_SUBAw() { _vuSUBAw(&VU0); } -void VU0MI_MUL() { _vuMUL(&VU0); } -void VU0MI_MULi() { _vuMULi(&VU0); } -void VU0MI_MULq() { _vuMULq(&VU0); } -void VU0MI_MULx() { _vuMULx(&VU0); } -void VU0MI_MULy() { _vuMULy(&VU0); } -void VU0MI_MULz() { _vuMULz(&VU0); } -void VU0MI_MULw() { _vuMULw(&VU0); } -void VU0MI_MULA() { _vuMULA(&VU0); } -void VU0MI_MULAi() { _vuMULAi(&VU0); } -void VU0MI_MULAq() { _vuMULAq(&VU0); } -void VU0MI_MULAx() { _vuMULAx(&VU0); } -void VU0MI_MULAy() { _vuMULAy(&VU0); } -void VU0MI_MULAz() { _vuMULAz(&VU0); } -void VU0MI_MULAw() { _vuMULAw(&VU0); } -void VU0MI_MADD() { _vuMADD(&VU0); } -void VU0MI_MADDi() { _vuMADDi(&VU0); } -void VU0MI_MADDq() { _vuMADDq(&VU0); } -void VU0MI_MADDx() { _vuMADDx(&VU0); } -void VU0MI_MADDy() { _vuMADDy(&VU0); } -void VU0MI_MADDz() { _vuMADDz(&VU0); } -void VU0MI_MADDw() { _vuMADDw(&VU0); } -void VU0MI_MADDA() { _vuMADDA(&VU0); } -void VU0MI_MADDAi() { _vuMADDAi(&VU0); } -void VU0MI_MADDAq() { _vuMADDAq(&VU0); } -void VU0MI_MADDAx() { _vuMADDAx(&VU0); } -void VU0MI_MADDAy() { _vuMADDAy(&VU0); } -void VU0MI_MADDAz() { _vuMADDAz(&VU0); } -void VU0MI_MADDAw() { _vuMADDAw(&VU0); } -void VU0MI_MSUB() { _vuMSUB(&VU0); } -void VU0MI_MSUBi() { _vuMSUBi(&VU0); } -void VU0MI_MSUBq() { _vuMSUBq(&VU0); } -void VU0MI_MSUBx() { _vuMSUBx(&VU0); } -void VU0MI_MSUBy() { _vuMSUBy(&VU0); } -void VU0MI_MSUBz() { _vuMSUBz(&VU0); } -void VU0MI_MSUBw() { _vuMSUBw(&VU0); } -void VU0MI_MSUBA() { _vuMSUBA(&VU0); } -void VU0MI_MSUBAi() { _vuMSUBAi(&VU0); } -void VU0MI_MSUBAq() { _vuMSUBAq(&VU0); } -void VU0MI_MSUBAx() { _vuMSUBAx(&VU0); } -void VU0MI_MSUBAy() { _vuMSUBAy(&VU0); } -void VU0MI_MSUBAz() { _vuMSUBAz(&VU0); } -void VU0MI_MSUBAw() { _vuMSUBAw(&VU0); } -void VU0MI_MAX() { _vuMAX(&VU0); } -void VU0MI_MAXi() { _vuMAXi(&VU0); } -void VU0MI_MAXx() { _vuMAXx(&VU0); } -void VU0MI_MAXy() { _vuMAXy(&VU0); } -void VU0MI_MAXz() { _vuMAXz(&VU0); } -void VU0MI_MAXw() { _vuMAXw(&VU0); } -void VU0MI_MINI() { _vuMINI(&VU0); } -void VU0MI_MINIi() { _vuMINIi(&VU0); } -void VU0MI_MINIx() { _vuMINIx(&VU0); } -void VU0MI_MINIy() { _vuMINIy(&VU0); } -void VU0MI_MINIz() { _vuMINIz(&VU0); } -void VU0MI_MINIw() { _vuMINIw(&VU0); } -void VU0MI_OPMULA() { _vuOPMULA(&VU0); } -void VU0MI_OPMSUB() { _vuOPMSUB(&VU0); } -void VU0MI_NOP() { _vuNOP(&VU0); } -void VU0MI_FTOI0() { _vuFTOI0(&VU0); } -void VU0MI_FTOI4() { _vuFTOI4(&VU0); } -void VU0MI_FTOI12() { _vuFTOI12(&VU0); } -void VU0MI_FTOI15() { _vuFTOI15(&VU0); } -void VU0MI_ITOF0() { _vuITOF0(&VU0); } -void VU0MI_ITOF4() { _vuITOF4(&VU0); } -void VU0MI_ITOF12() { _vuITOF12(&VU0); } -void VU0MI_ITOF15() { _vuITOF15(&VU0); } -void VU0MI_CLIP() { _vuCLIP(&VU0); } - -/*****************************************/ -/* VU Micromode Lower instructions */ -/*****************************************/ - -void VU0MI_DIV() { _vuDIV(&VU0); } -void VU0MI_SQRT() { _vuSQRT(&VU0); } -void VU0MI_RSQRT() { _vuRSQRT(&VU0); } -void VU0MI_IADD() { _vuIADD(&VU0); } -void VU0MI_IADDI() { _vuIADDI(&VU0); } -void VU0MI_IADDIU() { _vuIADDIU(&VU0); } -void VU0MI_IAND() { _vuIAND(&VU0); } -void VU0MI_IOR() { _vuIOR(&VU0); } -void VU0MI_ISUB() { _vuISUB(&VU0); } -void VU0MI_ISUBIU() { _vuISUBIU(&VU0); } -void VU0MI_MOVE() { _vuMOVE(&VU0); } -void VU0MI_MFIR() { _vuMFIR(&VU0); } -void VU0MI_MTIR() { _vuMTIR(&VU0); } -void VU0MI_MR32() { _vuMR32(&VU0); } -void VU0MI_LQ() { _vuLQ(&VU0); } -void VU0MI_LQD() { _vuLQD(&VU0); } -void VU0MI_LQI() { _vuLQI(&VU0); } -void VU0MI_SQ() { _vuSQ(&VU0); } -void VU0MI_SQD() { _vuSQD(&VU0); } -void VU0MI_SQI() { _vuSQI(&VU0); } -void VU0MI_ILW() { _vuILW(&VU0); } -void VU0MI_ISW() { _vuISW(&VU0); } -void VU0MI_ILWR() { _vuILWR(&VU0); } -void VU0MI_ISWR() { _vuISWR(&VU0); } -void VU0MI_RINIT() { _vuRINIT(&VU0); } -void VU0MI_RGET() { _vuRGET(&VU0); } -void VU0MI_RNEXT() { _vuRNEXT(&VU0); } -void VU0MI_RXOR() { _vuRXOR(&VU0); } -void VU0MI_WAITQ() { _vuWAITQ(&VU0); } -void VU0MI_FSAND() { _vuFSAND(&VU0); } -void VU0MI_FSEQ() { _vuFSEQ(&VU0); } -void VU0MI_FSOR() { _vuFSOR(&VU0); } -void VU0MI_FSSET() { _vuFSSET(&VU0); } -void VU0MI_FMAND() { _vuFMAND(&VU0); } -void VU0MI_FMEQ() { _vuFMEQ(&VU0); } -void VU0MI_FMOR() { _vuFMOR(&VU0); } -void VU0MI_FCAND() { _vuFCAND(&VU0); } -void VU0MI_FCEQ() { _vuFCEQ(&VU0); } -void VU0MI_FCOR() { _vuFCOR(&VU0); } -void VU0MI_FCSET() { _vuFCSET(&VU0); } -void VU0MI_FCGET() { _vuFCGET(&VU0); } -void VU0MI_IBEQ() { _vuIBEQ(&VU0); } -void VU0MI_IBGEZ() { _vuIBGEZ(&VU0); } -void VU0MI_IBGTZ() { _vuIBGTZ(&VU0); } -void VU0MI_IBLTZ() { _vuIBLTZ(&VU0); } -void VU0MI_IBLEZ() { _vuIBLEZ(&VU0); } -void VU0MI_IBNE() { _vuIBNE(&VU0); } -void VU0MI_B() { _vuB(&VU0); } -void VU0MI_BAL() { _vuBAL(&VU0); } -void VU0MI_JR() { _vuJR(&VU0); } -void VU0MI_JALR() { _vuJALR(&VU0); } -void VU0MI_MFP() { _vuMFP(&VU0); } -void VU0MI_WAITP() { _vuWAITP(&VU0); } -void VU0MI_ESADD() { _vuESADD(&VU0); } -void VU0MI_ERSADD() { _vuERSADD(&VU0); } -void VU0MI_ELENG() { _vuELENG(&VU0); } -void VU0MI_ERLENG() { _vuERLENG(&VU0); } -void VU0MI_EATANxy() { _vuEATANxy(&VU0); } -void VU0MI_EATANxz() { _vuEATANxz(&VU0); } -void VU0MI_ESUM() { _vuESUM(&VU0); } -void VU0MI_ERCPR() { _vuERCPR(&VU0); } -void VU0MI_ESQRT() { _vuESQRT(&VU0); } -void VU0MI_ERSQRT() { _vuERSQRT(&VU0); } -void VU0MI_ESIN() { _vuESIN(&VU0); } -void VU0MI_EATAN() { _vuEATAN(&VU0); } -void VU0MI_EEXP() { _vuEEXP(&VU0); } -void VU0MI_XITOP() { _vuXITOP(&VU0); } - -/****************************************/ -/* VU Micromode Upper instructions */ -/****************************************/ - -void VU0regsMI_ABS(_VURegsNum *VUregsn) { _vuRegsABS(&VU0, VUregsn); } -void VU0regsMI_ADD(_VURegsNum *VUregsn) { _vuRegsADD(&VU0, VUregsn); } -void VU0regsMI_ADDi(_VURegsNum *VUregsn) { _vuRegsADDi(&VU0, VUregsn); } -void VU0regsMI_ADDq(_VURegsNum *VUregsn) { _vuRegsADDq(&VU0, VUregsn); } -void VU0regsMI_ADDx(_VURegsNum *VUregsn) { _vuRegsADDx(&VU0, VUregsn); } -void VU0regsMI_ADDy(_VURegsNum *VUregsn) { _vuRegsADDy(&VU0, VUregsn); } -void VU0regsMI_ADDz(_VURegsNum *VUregsn) { _vuRegsADDz(&VU0, VUregsn); } -void VU0regsMI_ADDw(_VURegsNum *VUregsn) { _vuRegsADDw(&VU0, VUregsn); } -void VU0regsMI_ADDA(_VURegsNum *VUregsn) { _vuRegsADDA(&VU0, VUregsn); } -void VU0regsMI_ADDAi(_VURegsNum *VUregsn) { _vuRegsADDAi(&VU0, VUregsn); } -void VU0regsMI_ADDAq(_VURegsNum *VUregsn) { _vuRegsADDAq(&VU0, VUregsn); } -void VU0regsMI_ADDAx(_VURegsNum *VUregsn) { _vuRegsADDAx(&VU0, VUregsn); } -void VU0regsMI_ADDAy(_VURegsNum *VUregsn) { _vuRegsADDAy(&VU0, VUregsn); } -void VU0regsMI_ADDAz(_VURegsNum *VUregsn) { _vuRegsADDAz(&VU0, VUregsn); } -void VU0regsMI_ADDAw(_VURegsNum *VUregsn) { _vuRegsADDAw(&VU0, VUregsn); } -void VU0regsMI_SUB(_VURegsNum *VUregsn) { _vuRegsSUB(&VU0, VUregsn); } -void VU0regsMI_SUBi(_VURegsNum *VUregsn) { _vuRegsSUBi(&VU0, VUregsn); } -void VU0regsMI_SUBq(_VURegsNum *VUregsn) { _vuRegsSUBq(&VU0, VUregsn); } -void VU0regsMI_SUBx(_VURegsNum *VUregsn) { _vuRegsSUBx(&VU0, VUregsn); } -void VU0regsMI_SUBy(_VURegsNum *VUregsn) { _vuRegsSUBy(&VU0, VUregsn); } -void VU0regsMI_SUBz(_VURegsNum *VUregsn) { _vuRegsSUBz(&VU0, VUregsn); } -void VU0regsMI_SUBw(_VURegsNum *VUregsn) { _vuRegsSUBw(&VU0, VUregsn); } -void VU0regsMI_SUBA(_VURegsNum *VUregsn) { _vuRegsSUBA(&VU0, VUregsn); } -void VU0regsMI_SUBAi(_VURegsNum *VUregsn) { _vuRegsSUBAi(&VU0, VUregsn); } -void VU0regsMI_SUBAq(_VURegsNum *VUregsn) { _vuRegsSUBAq(&VU0, VUregsn); } -void VU0regsMI_SUBAx(_VURegsNum *VUregsn) { _vuRegsSUBAx(&VU0, VUregsn); } -void VU0regsMI_SUBAy(_VURegsNum *VUregsn) { _vuRegsSUBAy(&VU0, VUregsn); } -void VU0regsMI_SUBAz(_VURegsNum *VUregsn) { _vuRegsSUBAz(&VU0, VUregsn); } -void VU0regsMI_SUBAw(_VURegsNum *VUregsn) { _vuRegsSUBAw(&VU0, VUregsn); } -void VU0regsMI_MUL(_VURegsNum *VUregsn) { _vuRegsMUL(&VU0, VUregsn); } -void VU0regsMI_MULi(_VURegsNum *VUregsn) { _vuRegsMULi(&VU0, VUregsn); } -void VU0regsMI_MULq(_VURegsNum *VUregsn) { _vuRegsMULq(&VU0, VUregsn); } -void VU0regsMI_MULx(_VURegsNum *VUregsn) { _vuRegsMULx(&VU0, VUregsn); } -void VU0regsMI_MULy(_VURegsNum *VUregsn) { _vuRegsMULy(&VU0, VUregsn); } -void VU0regsMI_MULz(_VURegsNum *VUregsn) { _vuRegsMULz(&VU0, VUregsn); } -void VU0regsMI_MULw(_VURegsNum *VUregsn) { _vuRegsMULw(&VU0, VUregsn); } -void VU0regsMI_MULA(_VURegsNum *VUregsn) { _vuRegsMULA(&VU0, VUregsn); } -void VU0regsMI_MULAi(_VURegsNum *VUregsn) { _vuRegsMULAi(&VU0, VUregsn); } -void VU0regsMI_MULAq(_VURegsNum *VUregsn) { _vuRegsMULAq(&VU0, VUregsn); } -void VU0regsMI_MULAx(_VURegsNum *VUregsn) { _vuRegsMULAx(&VU0, VUregsn); } -void VU0regsMI_MULAy(_VURegsNum *VUregsn) { _vuRegsMULAy(&VU0, VUregsn); } -void VU0regsMI_MULAz(_VURegsNum *VUregsn) { _vuRegsMULAz(&VU0, VUregsn); } -void VU0regsMI_MULAw(_VURegsNum *VUregsn) { _vuRegsMULAw(&VU0, VUregsn); } -void VU0regsMI_MADD(_VURegsNum *VUregsn) { _vuRegsMADD(&VU0, VUregsn); } -void VU0regsMI_MADDi(_VURegsNum *VUregsn) { _vuRegsMADDi(&VU0, VUregsn); } -void VU0regsMI_MADDq(_VURegsNum *VUregsn) { _vuRegsMADDq(&VU0, VUregsn); } -void VU0regsMI_MADDx(_VURegsNum *VUregsn) { _vuRegsMADDx(&VU0, VUregsn); } -void VU0regsMI_MADDy(_VURegsNum *VUregsn) { _vuRegsMADDy(&VU0, VUregsn); } -void VU0regsMI_MADDz(_VURegsNum *VUregsn) { _vuRegsMADDz(&VU0, VUregsn); } -void VU0regsMI_MADDw(_VURegsNum *VUregsn) { _vuRegsMADDw(&VU0, VUregsn); } -void VU0regsMI_MADDA(_VURegsNum *VUregsn) { _vuRegsMADDA(&VU0, VUregsn); } -void VU0regsMI_MADDAi(_VURegsNum *VUregsn) { _vuRegsMADDAi(&VU0, VUregsn); } -void VU0regsMI_MADDAq(_VURegsNum *VUregsn) { _vuRegsMADDAq(&VU0, VUregsn); } -void VU0regsMI_MADDAx(_VURegsNum *VUregsn) { _vuRegsMADDAx(&VU0, VUregsn); } -void VU0regsMI_MADDAy(_VURegsNum *VUregsn) { _vuRegsMADDAy(&VU0, VUregsn); } -void VU0regsMI_MADDAz(_VURegsNum *VUregsn) { _vuRegsMADDAz(&VU0, VUregsn); } -void VU0regsMI_MADDAw(_VURegsNum *VUregsn) { _vuRegsMADDAw(&VU0, VUregsn); } -void VU0regsMI_MSUB(_VURegsNum *VUregsn) { _vuRegsMSUB(&VU0, VUregsn); } -void VU0regsMI_MSUBi(_VURegsNum *VUregsn) { _vuRegsMSUBi(&VU0, VUregsn); } -void VU0regsMI_MSUBq(_VURegsNum *VUregsn) { _vuRegsMSUBq(&VU0, VUregsn); } -void VU0regsMI_MSUBx(_VURegsNum *VUregsn) { _vuRegsMSUBx(&VU0, VUregsn); } -void VU0regsMI_MSUBy(_VURegsNum *VUregsn) { _vuRegsMSUBy(&VU0, VUregsn); } -void VU0regsMI_MSUBz(_VURegsNum *VUregsn) { _vuRegsMSUBz(&VU0, VUregsn); } -void VU0regsMI_MSUBw(_VURegsNum *VUregsn) { _vuRegsMSUBw(&VU0, VUregsn); } -void VU0regsMI_MSUBA(_VURegsNum *VUregsn) { _vuRegsMSUBA(&VU0, VUregsn); } -void VU0regsMI_MSUBAi(_VURegsNum *VUregsn) { _vuRegsMSUBAi(&VU0, VUregsn); } -void VU0regsMI_MSUBAq(_VURegsNum *VUregsn) { _vuRegsMSUBAq(&VU0, VUregsn); } -void VU0regsMI_MSUBAx(_VURegsNum *VUregsn) { _vuRegsMSUBAx(&VU0, VUregsn); } -void VU0regsMI_MSUBAy(_VURegsNum *VUregsn) { _vuRegsMSUBAy(&VU0, VUregsn); } -void VU0regsMI_MSUBAz(_VURegsNum *VUregsn) { _vuRegsMSUBAz(&VU0, VUregsn); } -void VU0regsMI_MSUBAw(_VURegsNum *VUregsn) { _vuRegsMSUBAw(&VU0, VUregsn); } -void VU0regsMI_MAX(_VURegsNum *VUregsn) { _vuRegsMAX(&VU0, VUregsn); } -void VU0regsMI_MAXi(_VURegsNum *VUregsn) { _vuRegsMAXi(&VU0, VUregsn); } -void VU0regsMI_MAXx(_VURegsNum *VUregsn) { _vuRegsMAXx(&VU0, VUregsn); } -void VU0regsMI_MAXy(_VURegsNum *VUregsn) { _vuRegsMAXy(&VU0, VUregsn); } -void VU0regsMI_MAXz(_VURegsNum *VUregsn) { _vuRegsMAXz(&VU0, VUregsn); } -void VU0regsMI_MAXw(_VURegsNum *VUregsn) { _vuRegsMAXw(&VU0, VUregsn); } -void VU0regsMI_MINI(_VURegsNum *VUregsn) { _vuRegsMINI(&VU0, VUregsn); } -void VU0regsMI_MINIi(_VURegsNum *VUregsn) { _vuRegsMINIi(&VU0, VUregsn); } -void VU0regsMI_MINIx(_VURegsNum *VUregsn) { _vuRegsMINIx(&VU0, VUregsn); } -void VU0regsMI_MINIy(_VURegsNum *VUregsn) { _vuRegsMINIy(&VU0, VUregsn); } -void VU0regsMI_MINIz(_VURegsNum *VUregsn) { _vuRegsMINIz(&VU0, VUregsn); } -void VU0regsMI_MINIw(_VURegsNum *VUregsn) { _vuRegsMINIw(&VU0, VUregsn); } -void VU0regsMI_OPMULA(_VURegsNum *VUregsn) { _vuRegsOPMULA(&VU0, VUregsn); } -void VU0regsMI_OPMSUB(_VURegsNum *VUregsn) { _vuRegsOPMSUB(&VU0, VUregsn); } -void VU0regsMI_NOP(_VURegsNum *VUregsn) { _vuRegsNOP(&VU0, VUregsn); } -void VU0regsMI_FTOI0(_VURegsNum *VUregsn) { _vuRegsFTOI0(&VU0, VUregsn); } -void VU0regsMI_FTOI4(_VURegsNum *VUregsn) { _vuRegsFTOI4(&VU0, VUregsn); } -void VU0regsMI_FTOI12(_VURegsNum *VUregsn) { _vuRegsFTOI12(&VU0, VUregsn); } -void VU0regsMI_FTOI15(_VURegsNum *VUregsn) { _vuRegsFTOI15(&VU0, VUregsn); } -void VU0regsMI_ITOF0(_VURegsNum *VUregsn) { _vuRegsITOF0(&VU0, VUregsn); } -void VU0regsMI_ITOF4(_VURegsNum *VUregsn) { _vuRegsITOF4(&VU0, VUregsn); } -void VU0regsMI_ITOF12(_VURegsNum *VUregsn) { _vuRegsITOF12(&VU0, VUregsn); } -void VU0regsMI_ITOF15(_VURegsNum *VUregsn) { _vuRegsITOF15(&VU0, VUregsn); } -void VU0regsMI_CLIP(_VURegsNum *VUregsn) { _vuRegsCLIP(&VU0, VUregsn); } - -/*****************************************/ -/* VU Micromode Lower instructions */ -/*****************************************/ - -void VU0regsMI_DIV(_VURegsNum *VUregsn) { _vuRegsDIV(&VU0, VUregsn); } -void VU0regsMI_SQRT(_VURegsNum *VUregsn) { _vuRegsSQRT(&VU0, VUregsn); } -void VU0regsMI_RSQRT(_VURegsNum *VUregsn) { _vuRegsRSQRT(&VU0, VUregsn); } -void VU0regsMI_IADD(_VURegsNum *VUregsn) { _vuRegsIADD(&VU0, VUregsn); } -void VU0regsMI_IADDI(_VURegsNum *VUregsn) { _vuRegsIADDI(&VU0, VUregsn); } -void VU0regsMI_IADDIU(_VURegsNum *VUregsn) { _vuRegsIADDIU(&VU0, VUregsn); } -void VU0regsMI_IAND(_VURegsNum *VUregsn) { _vuRegsIAND(&VU0, VUregsn); } -void VU0regsMI_IOR(_VURegsNum *VUregsn) { _vuRegsIOR(&VU0, VUregsn); } -void VU0regsMI_ISUB(_VURegsNum *VUregsn) { _vuRegsISUB(&VU0, VUregsn); } -void VU0regsMI_ISUBIU(_VURegsNum *VUregsn) { _vuRegsISUBIU(&VU0, VUregsn); } -void VU0regsMI_MOVE(_VURegsNum *VUregsn) { _vuRegsMOVE(&VU0, VUregsn); } -void VU0regsMI_MFIR(_VURegsNum *VUregsn) { _vuRegsMFIR(&VU0, VUregsn); } -void VU0regsMI_MTIR(_VURegsNum *VUregsn) { _vuRegsMTIR(&VU0, VUregsn); } -void VU0regsMI_MR32(_VURegsNum *VUregsn) { _vuRegsMR32(&VU0, VUregsn); } -void VU0regsMI_LQ(_VURegsNum *VUregsn) { _vuRegsLQ(&VU0, VUregsn); } -void VU0regsMI_LQD(_VURegsNum *VUregsn) { _vuRegsLQD(&VU0, VUregsn); } -void VU0regsMI_LQI(_VURegsNum *VUregsn) { _vuRegsLQI(&VU0, VUregsn); } -void VU0regsMI_SQ(_VURegsNum *VUregsn) { _vuRegsSQ(&VU0, VUregsn); } -void VU0regsMI_SQD(_VURegsNum *VUregsn) { _vuRegsSQD(&VU0, VUregsn); } -void VU0regsMI_SQI(_VURegsNum *VUregsn) { _vuRegsSQI(&VU0, VUregsn); } -void VU0regsMI_ILW(_VURegsNum *VUregsn) { _vuRegsILW(&VU0, VUregsn); } -void VU0regsMI_ISW(_VURegsNum *VUregsn) { _vuRegsISW(&VU0, VUregsn); } -void VU0regsMI_ILWR(_VURegsNum *VUregsn) { _vuRegsILWR(&VU0, VUregsn); } -void VU0regsMI_ISWR(_VURegsNum *VUregsn) { _vuRegsISWR(&VU0, VUregsn); } -void VU0regsMI_RINIT(_VURegsNum *VUregsn) { _vuRegsRINIT(&VU0, VUregsn); } -void VU0regsMI_RGET(_VURegsNum *VUregsn) { _vuRegsRGET(&VU0, VUregsn); } -void VU0regsMI_RNEXT(_VURegsNum *VUregsn) { _vuRegsRNEXT(&VU0, VUregsn); } -void VU0regsMI_RXOR(_VURegsNum *VUregsn) { _vuRegsRXOR(&VU0, VUregsn); } -void VU0regsMI_WAITQ(_VURegsNum *VUregsn) { _vuRegsWAITQ(&VU0, VUregsn); } -void VU0regsMI_FSAND(_VURegsNum *VUregsn) { _vuRegsFSAND(&VU0, VUregsn); } -void VU0regsMI_FSEQ(_VURegsNum *VUregsn) { _vuRegsFSEQ(&VU0, VUregsn); } -void VU0regsMI_FSOR(_VURegsNum *VUregsn) { _vuRegsFSOR(&VU0, VUregsn); } -void VU0regsMI_FSSET(_VURegsNum *VUregsn) { _vuRegsFSSET(&VU0, VUregsn); } -void VU0regsMI_FMAND(_VURegsNum *VUregsn) { _vuRegsFMAND(&VU0, VUregsn); } -void VU0regsMI_FMEQ(_VURegsNum *VUregsn) { _vuRegsFMEQ(&VU0, VUregsn); } -void VU0regsMI_FMOR(_VURegsNum *VUregsn) { _vuRegsFMOR(&VU0, VUregsn); } -void VU0regsMI_FCAND(_VURegsNum *VUregsn) { _vuRegsFCAND(&VU0, VUregsn); } -void VU0regsMI_FCEQ(_VURegsNum *VUregsn) { _vuRegsFCEQ(&VU0, VUregsn); } -void VU0regsMI_FCOR(_VURegsNum *VUregsn) { _vuRegsFCOR(&VU0, VUregsn); } -void VU0regsMI_FCSET(_VURegsNum *VUregsn) { _vuRegsFCSET(&VU0, VUregsn); } -void VU0regsMI_FCGET(_VURegsNum *VUregsn) { _vuRegsFCGET(&VU0, VUregsn); } -void VU0regsMI_IBEQ(_VURegsNum *VUregsn) { _vuRegsIBEQ(&VU0, VUregsn); } -void VU0regsMI_IBGEZ(_VURegsNum *VUregsn) { _vuRegsIBGEZ(&VU0, VUregsn); } -void VU0regsMI_IBGTZ(_VURegsNum *VUregsn) { _vuRegsIBGTZ(&VU0, VUregsn); } -void VU0regsMI_IBLTZ(_VURegsNum *VUregsn) { _vuRegsIBLTZ(&VU0, VUregsn); } -void VU0regsMI_IBLEZ(_VURegsNum *VUregsn) { _vuRegsIBLEZ(&VU0, VUregsn); } -void VU0regsMI_IBNE(_VURegsNum *VUregsn) { _vuRegsIBNE(&VU0, VUregsn); } -void VU0regsMI_B(_VURegsNum *VUregsn) { _vuRegsB(&VU0, VUregsn); } -void VU0regsMI_BAL(_VURegsNum *VUregsn) { _vuRegsBAL(&VU0, VUregsn); } -void VU0regsMI_JR(_VURegsNum *VUregsn) { _vuRegsJR(&VU0, VUregsn); } -void VU0regsMI_JALR(_VURegsNum *VUregsn) { _vuRegsJALR(&VU0, VUregsn); } -void VU0regsMI_MFP(_VURegsNum *VUregsn) { _vuRegsMFP(&VU0, VUregsn); } -void VU0regsMI_WAITP(_VURegsNum *VUregsn) { _vuRegsWAITP(&VU0, VUregsn); } -void VU0regsMI_ESADD(_VURegsNum *VUregsn) { _vuRegsESADD(&VU0, VUregsn); } -void VU0regsMI_ERSADD(_VURegsNum *VUregsn) { _vuRegsERSADD(&VU0, VUregsn); } -void VU0regsMI_ELENG(_VURegsNum *VUregsn) { _vuRegsELENG(&VU0, VUregsn); } -void VU0regsMI_ERLENG(_VURegsNum *VUregsn) { _vuRegsERLENG(&VU0, VUregsn); } -void VU0regsMI_EATANxy(_VURegsNum *VUregsn) { _vuRegsEATANxy(&VU0, VUregsn); } -void VU0regsMI_EATANxz(_VURegsNum *VUregsn) { _vuRegsEATANxz(&VU0, VUregsn); } -void VU0regsMI_ESUM(_VURegsNum *VUregsn) { _vuRegsESUM(&VU0, VUregsn); } -void VU0regsMI_ERCPR(_VURegsNum *VUregsn) { _vuRegsERCPR(&VU0, VUregsn); } -void VU0regsMI_ESQRT(_VURegsNum *VUregsn) { _vuRegsESQRT(&VU0, VUregsn); } -void VU0regsMI_ERSQRT(_VURegsNum *VUregsn) { _vuRegsERSQRT(&VU0, VUregsn); } -void VU0regsMI_ESIN(_VURegsNum *VUregsn) { _vuRegsESIN(&VU0, VUregsn); } -void VU0regsMI_EATAN(_VURegsNum *VUregsn) { _vuRegsEATAN(&VU0, VUregsn); } -void VU0regsMI_EEXP(_VURegsNum *VUregsn) { _vuRegsEEXP(&VU0, VUregsn); } -void VU0regsMI_XITOP(_VURegsNum *VUregsn) { _vuRegsXITOP(&VU0, VUregsn); } -void VU0regsMI_XGKICK(_VURegsNum *VUregsn) { _vuRegsXGKICK(&VU0, VUregsn); } -void VU0regsMI_XTOP(_VURegsNum *VUregsn) { _vuRegsXTOP(&VU0, VUregsn); } diff --git a/pcsx2/VU0microInterp.cpp b/pcsx2/VU0microInterp.cpp index da7e37b761..a35fd25661 100644 --- a/pcsx2/VU0microInterp.cpp +++ b/pcsx2/VU0microInterp.cpp @@ -21,15 +21,13 @@ extern void _vuFlushAll(VURegs* VU); -_vuTables(VU0, VU0); - -void _vu0ExecUpper(VURegs* VU, u32 *ptr) { +static void _vu0ExecUpper(VURegs* VU, u32 *ptr) { VU->code = ptr[1]; IdebugUPPER(VU0); VU0_UPPER_OPCODE[VU->code & 0x3f](); } -void _vu0ExecLower(VURegs* VU, u32 *ptr) { +static void _vu0ExecLower(VURegs* VU, u32 *ptr) { VU->code = ptr[0]; IdebugLOWER(VU0); VU0_LOWER_OPCODE[VU->code >> 25](); @@ -49,15 +47,6 @@ static void _vu0Exec(VURegs* VU) int vireg; int discard=0; - if(VU0.VI[REG_TPC].UL >= VU0.maxmicro){ -#ifdef CPU_LOG - Console.WriteLn("VU0 memory overflow!!: %x", VU->VI[REG_TPC].UL); -#endif - VU0.VI[REG_VPU_STAT].UL&= ~0x1; - VU->cycle++; - return; - } - ptr = (u32*)&VU->Micro[VU->VI[REG_TPC].UL]; VU->VI[REG_TPC].UL+=8; @@ -166,21 +155,15 @@ static void _vu0Exec(VURegs* VU) if( VU->ebit-- == 1 ) { _vuFlushAll(VU); VU0.VI[REG_VPU_STAT].UL&= ~0x1; /* E flag */ - vif0Regs->stat.VEW = false; + vif0Regs.stat.VEW = false; } } } void vu0Exec(VURegs* VU) { - if (VU->VI[REG_TPC].UL >= VU->maxmicro) { -#ifdef CPU_LOG - Console.Warning("VU0 memory overflow!!: %x", VU->VI[REG_TPC].UL); -#endif - VU0.VI[REG_VPU_STAT].UL&= ~0x1; - } else { - _vu0Exec(VU); - } + VU0.VI[REG_TPC].UL &= VU0_PROGMASK; + _vu0Exec(VU); VU->cycle++; if (VU->VI[0].UL != 0) DbgCon.Error("VI[0] != 0!!!!\n"); diff --git a/pcsx2/VU1micro.cpp b/pcsx2/VU1micro.cpp index abfbbc25e3..2b9240bee9 100644 --- a/pcsx2/VU1micro.cpp +++ b/pcsx2/VU1micro.cpp @@ -24,8 +24,6 @@ #include "VUmicro.h" -VURegs* g_pVU1; - #ifdef PCSX2_DEBUG u32 vudump = 0; #endif @@ -37,7 +35,7 @@ void vu1ResetRegs() { VU0.VI[REG_VPU_STAT].UL &= ~0xff00; // stop vu1 VU0.VI[REG_FBRST].UL &= ~0xff00; // stop vu1 - vif1Regs->stat.VEW = false; + vif1Regs.stat.VEW = false; } void vu1Finish() { @@ -58,373 +56,9 @@ void __fastcall vu1ExecMicro(u32 addr) VU0.VI[REG_VPU_STAT].UL &= ~0xFF00; VU0.VI[REG_VPU_STAT].UL |= 0x0100; - vif1Regs->stat.VEW = true; + vif1Regs.stat.VEW = true; if ((s32)addr != -1) VU1.VI[REG_TPC].UL = addr; _vuExecMicroDebug(VU1); CpuVU1->Execute(vu1RunCycles); } - -_vuRegsTables(VU1, VU1regs); - -void VU1unknown() { - //assert(0); - CPU_LOG("Unknown VU micromode opcode called"); -} - -void VU1regsunknown(_VURegsNum *VUregsn) { - //assert(0); - CPU_LOG("Unknown VU micromode opcode called"); -} - - - -/****************************************/ -/* VU Micromode Upper instructions */ -/****************************************/ - -void VU1MI_ABS() { _vuABS(&VU1); } -void VU1MI_ADD() { _vuADD(&VU1); } -void VU1MI_ADDi() { _vuADDi(&VU1); } -void VU1MI_ADDq() { _vuADDq(&VU1); } -void VU1MI_ADDx() { _vuADDx(&VU1); } -void VU1MI_ADDy() { _vuADDy(&VU1); } -void VU1MI_ADDz() { _vuADDz(&VU1); } -void VU1MI_ADDw() { _vuADDw(&VU1); } -void VU1MI_ADDA() { _vuADDA(&VU1); } -void VU1MI_ADDAi() { _vuADDAi(&VU1); } -void VU1MI_ADDAq() { _vuADDAq(&VU1); } -void VU1MI_ADDAx() { _vuADDAx(&VU1); } -void VU1MI_ADDAy() { _vuADDAy(&VU1); } -void VU1MI_ADDAz() { _vuADDAz(&VU1); } -void VU1MI_ADDAw() { _vuADDAw(&VU1); } -void VU1MI_SUB() { _vuSUB(&VU1); } -void VU1MI_SUBi() { _vuSUBi(&VU1); } -void VU1MI_SUBq() { _vuSUBq(&VU1); } -void VU1MI_SUBx() { _vuSUBx(&VU1); } -void VU1MI_SUBy() { _vuSUBy(&VU1); } -void VU1MI_SUBz() { _vuSUBz(&VU1); } -void VU1MI_SUBw() { _vuSUBw(&VU1); } -void VU1MI_SUBA() { _vuSUBA(&VU1); } -void VU1MI_SUBAi() { _vuSUBAi(&VU1); } -void VU1MI_SUBAq() { _vuSUBAq(&VU1); } -void VU1MI_SUBAx() { _vuSUBAx(&VU1); } -void VU1MI_SUBAy() { _vuSUBAy(&VU1); } -void VU1MI_SUBAz() { _vuSUBAz(&VU1); } -void VU1MI_SUBAw() { _vuSUBAw(&VU1); } -void VU1MI_MUL() { _vuMUL(&VU1); } -void VU1MI_MULi() { _vuMULi(&VU1); } -void VU1MI_MULq() { _vuMULq(&VU1); } -void VU1MI_MULx() { _vuMULx(&VU1); } -void VU1MI_MULy() { _vuMULy(&VU1); } -void VU1MI_MULz() { _vuMULz(&VU1); } -void VU1MI_MULw() { _vuMULw(&VU1); } -void VU1MI_MULA() { _vuMULA(&VU1); } -void VU1MI_MULAi() { _vuMULAi(&VU1); } -void VU1MI_MULAq() { _vuMULAq(&VU1); } -void VU1MI_MULAx() { _vuMULAx(&VU1); } -void VU1MI_MULAy() { _vuMULAy(&VU1); } -void VU1MI_MULAz() { _vuMULAz(&VU1); } -void VU1MI_MULAw() { _vuMULAw(&VU1); } -void VU1MI_MADD() { _vuMADD(&VU1); } -void VU1MI_MADDi() { _vuMADDi(&VU1); } -void VU1MI_MADDq() { _vuMADDq(&VU1); } -void VU1MI_MADDx() { _vuMADDx(&VU1); } -void VU1MI_MADDy() { _vuMADDy(&VU1); } -void VU1MI_MADDz() { _vuMADDz(&VU1); } -void VU1MI_MADDw() { _vuMADDw(&VU1); } -void VU1MI_MADDA() { _vuMADDA(&VU1); } -void VU1MI_MADDAi() { _vuMADDAi(&VU1); } -void VU1MI_MADDAq() { _vuMADDAq(&VU1); } -void VU1MI_MADDAx() { _vuMADDAx(&VU1); } -void VU1MI_MADDAy() { _vuMADDAy(&VU1); } -void VU1MI_MADDAz() { _vuMADDAz(&VU1); } -void VU1MI_MADDAw() { _vuMADDAw(&VU1); } -void VU1MI_MSUB() { _vuMSUB(&VU1); } -void VU1MI_MSUBi() { _vuMSUBi(&VU1); } -void VU1MI_MSUBq() { _vuMSUBq(&VU1); } -void VU1MI_MSUBx() { _vuMSUBx(&VU1); } -void VU1MI_MSUBy() { _vuMSUBy(&VU1); } -void VU1MI_MSUBz() { _vuMSUBz(&VU1); } -void VU1MI_MSUBw() { _vuMSUBw(&VU1); } -void VU1MI_MSUBA() { _vuMSUBA(&VU1); } -void VU1MI_MSUBAi() { _vuMSUBAi(&VU1); } -void VU1MI_MSUBAq() { _vuMSUBAq(&VU1); } -void VU1MI_MSUBAx() { _vuMSUBAx(&VU1); } -void VU1MI_MSUBAy() { _vuMSUBAy(&VU1); } -void VU1MI_MSUBAz() { _vuMSUBAz(&VU1); } -void VU1MI_MSUBAw() { _vuMSUBAw(&VU1); } -void VU1MI_MAX() { _vuMAX(&VU1); } -void VU1MI_MAXi() { _vuMAXi(&VU1); } -void VU1MI_MAXx() { _vuMAXx(&VU1); } -void VU1MI_MAXy() { _vuMAXy(&VU1); } -void VU1MI_MAXz() { _vuMAXz(&VU1); } -void VU1MI_MAXw() { _vuMAXw(&VU1); } -void VU1MI_MINI() { _vuMINI(&VU1); } -void VU1MI_MINIi() { _vuMINIi(&VU1); } -void VU1MI_MINIx() { _vuMINIx(&VU1); } -void VU1MI_MINIy() { _vuMINIy(&VU1); } -void VU1MI_MINIz() { _vuMINIz(&VU1); } -void VU1MI_MINIw() { _vuMINIw(&VU1); } -void VU1MI_OPMULA() { _vuOPMULA(&VU1); } -void VU1MI_OPMSUB() { _vuOPMSUB(&VU1); } -void VU1MI_NOP() { _vuNOP(&VU1); } -void VU1MI_FTOI0() { _vuFTOI0(&VU1); } -void VU1MI_FTOI4() { _vuFTOI4(&VU1); } -void VU1MI_FTOI12() { _vuFTOI12(&VU1); } -void VU1MI_FTOI15() { _vuFTOI15(&VU1); } -void VU1MI_ITOF0() { _vuITOF0(&VU1); } -void VU1MI_ITOF4() { _vuITOF4(&VU1); } -void VU1MI_ITOF12() { _vuITOF12(&VU1); } -void VU1MI_ITOF15() { _vuITOF15(&VU1); } -void VU1MI_CLIP() { _vuCLIP(&VU1); } - -/*****************************************/ -/* VU Micromode Lower instructions */ -/*****************************************/ - -void VU1MI_DIV() { _vuDIV(&VU1); } -void VU1MI_SQRT() { _vuSQRT(&VU1); } -void VU1MI_RSQRT() { _vuRSQRT(&VU1); } -void VU1MI_IADD() { _vuIADD(&VU1); } -void VU1MI_IADDI() { _vuIADDI(&VU1); } -void VU1MI_IADDIU() { _vuIADDIU(&VU1); } -void VU1MI_IAND() { _vuIAND(&VU1); } -void VU1MI_IOR() { _vuIOR(&VU1); } -void VU1MI_ISUB() { _vuISUB(&VU1); } -void VU1MI_ISUBIU() { _vuISUBIU(&VU1); } -void VU1MI_MOVE() { _vuMOVE(&VU1); } -void VU1MI_MFIR() { _vuMFIR(&VU1); } -void VU1MI_MTIR() { _vuMTIR(&VU1); } -void VU1MI_MR32() { _vuMR32(&VU1); } -void VU1MI_LQ() { _vuLQ(&VU1); } -void VU1MI_LQD() { _vuLQD(&VU1); } -void VU1MI_LQI() { _vuLQI(&VU1); } -void VU1MI_SQ() { _vuSQ(&VU1); } -void VU1MI_SQD() { _vuSQD(&VU1); } -void VU1MI_SQI() { _vuSQI(&VU1); } -void VU1MI_ILW() { _vuILW(&VU1); } -void VU1MI_ISW() { _vuISW(&VU1); } -void VU1MI_ILWR() { _vuILWR(&VU1); } -void VU1MI_ISWR() { _vuISWR(&VU1); } -void VU1MI_RINIT() { _vuRINIT(&VU1); } -void VU1MI_RGET() { _vuRGET(&VU1); } -void VU1MI_RNEXT() { _vuRNEXT(&VU1); } -void VU1MI_RXOR() { _vuRXOR(&VU1); } -void VU1MI_WAITQ() { _vuWAITQ(&VU1); } -void VU1MI_FSAND() { _vuFSAND(&VU1); } -void VU1MI_FSEQ() { _vuFSEQ(&VU1); } -void VU1MI_FSOR() { _vuFSOR(&VU1); } -void VU1MI_FSSET() { _vuFSSET(&VU1); } -void VU1MI_FMAND() { _vuFMAND(&VU1); } -void VU1MI_FMEQ() { _vuFMEQ(&VU1); } -void VU1MI_FMOR() { _vuFMOR(&VU1); } -void VU1MI_FCAND() { _vuFCAND(&VU1); } -void VU1MI_FCEQ() { _vuFCEQ(&VU1); } -void VU1MI_FCOR() { _vuFCOR(&VU1); } -void VU1MI_FCSET() { _vuFCSET(&VU1); } -void VU1MI_FCGET() { _vuFCGET(&VU1); } -void VU1MI_IBEQ() { _vuIBEQ(&VU1); } -void VU1MI_IBGEZ() { _vuIBGEZ(&VU1); } -void VU1MI_IBGTZ() { _vuIBGTZ(&VU1); } -void VU1MI_IBLTZ() { _vuIBLTZ(&VU1); } -void VU1MI_IBLEZ() { _vuIBLEZ(&VU1); } -void VU1MI_IBNE() { _vuIBNE(&VU1); } -void VU1MI_B() { _vuB(&VU1); } -void VU1MI_BAL() { _vuBAL(&VU1); } -void VU1MI_JR() { _vuJR(&VU1); } -void VU1MI_JALR() { _vuJALR(&VU1); } -void VU1MI_MFP() { _vuMFP(&VU1); } -void VU1MI_WAITP() { _vuWAITP(&VU1); } -void VU1MI_ESADD() { _vuESADD(&VU1); } -void VU1MI_ERSADD() { _vuERSADD(&VU1); } -void VU1MI_ELENG() { _vuELENG(&VU1); } -void VU1MI_ERLENG() { _vuERLENG(&VU1); } -void VU1MI_EATANxy() { _vuEATANxy(&VU1); } -void VU1MI_EATANxz() { _vuEATANxz(&VU1); } -void VU1MI_ESUM() { _vuESUM(&VU1); } -void VU1MI_ERCPR() { _vuERCPR(&VU1); } -void VU1MI_ESQRT() { _vuESQRT(&VU1); } -void VU1MI_ERSQRT() { _vuERSQRT(&VU1); } -void VU1MI_ESIN() { _vuESIN(&VU1); } -void VU1MI_EATAN() { _vuEATAN(&VU1); } -void VU1MI_EEXP() { _vuEEXP(&VU1); } -void VU1MI_XITOP() { _vuXITOP(&VU1); } -void VU1MI_XGKICK() { _vuXGKICK(&VU1); } -void VU1MI_XTOP() { _vuXTOP(&VU1); } - - - -/****************************************/ -/* VU Micromode Upper instructions */ -/****************************************/ - -void VU1regsMI_ABS(_VURegsNum *VUregsn) { _vuRegsABS(&VU1, VUregsn); } -void VU1regsMI_ADD(_VURegsNum *VUregsn) { _vuRegsADD(&VU1, VUregsn); } -void VU1regsMI_ADDi(_VURegsNum *VUregsn) { _vuRegsADDi(&VU1, VUregsn); } -void VU1regsMI_ADDq(_VURegsNum *VUregsn) { _vuRegsADDq(&VU1, VUregsn); } -void VU1regsMI_ADDx(_VURegsNum *VUregsn) { _vuRegsADDx(&VU1, VUregsn); } -void VU1regsMI_ADDy(_VURegsNum *VUregsn) { _vuRegsADDy(&VU1, VUregsn); } -void VU1regsMI_ADDz(_VURegsNum *VUregsn) { _vuRegsADDz(&VU1, VUregsn); } -void VU1regsMI_ADDw(_VURegsNum *VUregsn) { _vuRegsADDw(&VU1, VUregsn); } -void VU1regsMI_ADDA(_VURegsNum *VUregsn) { _vuRegsADDA(&VU1, VUregsn); } -void VU1regsMI_ADDAi(_VURegsNum *VUregsn) { _vuRegsADDAi(&VU1, VUregsn); } -void VU1regsMI_ADDAq(_VURegsNum *VUregsn) { _vuRegsADDAq(&VU1, VUregsn); } -void VU1regsMI_ADDAx(_VURegsNum *VUregsn) { _vuRegsADDAx(&VU1, VUregsn); } -void VU1regsMI_ADDAy(_VURegsNum *VUregsn) { _vuRegsADDAy(&VU1, VUregsn); } -void VU1regsMI_ADDAz(_VURegsNum *VUregsn) { _vuRegsADDAz(&VU1, VUregsn); } -void VU1regsMI_ADDAw(_VURegsNum *VUregsn) { _vuRegsADDAw(&VU1, VUregsn); } -void VU1regsMI_SUB(_VURegsNum *VUregsn) { _vuRegsSUB(&VU1, VUregsn); } -void VU1regsMI_SUBi(_VURegsNum *VUregsn) { _vuRegsSUBi(&VU1, VUregsn); } -void VU1regsMI_SUBq(_VURegsNum *VUregsn) { _vuRegsSUBq(&VU1, VUregsn); } -void VU1regsMI_SUBx(_VURegsNum *VUregsn) { _vuRegsSUBx(&VU1, VUregsn); } -void VU1regsMI_SUBy(_VURegsNum *VUregsn) { _vuRegsSUBy(&VU1, VUregsn); } -void VU1regsMI_SUBz(_VURegsNum *VUregsn) { _vuRegsSUBz(&VU1, VUregsn); } -void VU1regsMI_SUBw(_VURegsNum *VUregsn) { _vuRegsSUBw(&VU1, VUregsn); } -void VU1regsMI_SUBA(_VURegsNum *VUregsn) { _vuRegsSUBA(&VU1, VUregsn); } -void VU1regsMI_SUBAi(_VURegsNum *VUregsn) { _vuRegsSUBAi(&VU1, VUregsn); } -void VU1regsMI_SUBAq(_VURegsNum *VUregsn) { _vuRegsSUBAq(&VU1, VUregsn); } -void VU1regsMI_SUBAx(_VURegsNum *VUregsn) { _vuRegsSUBAx(&VU1, VUregsn); } -void VU1regsMI_SUBAy(_VURegsNum *VUregsn) { _vuRegsSUBAy(&VU1, VUregsn); } -void VU1regsMI_SUBAz(_VURegsNum *VUregsn) { _vuRegsSUBAz(&VU1, VUregsn); } -void VU1regsMI_SUBAw(_VURegsNum *VUregsn) { _vuRegsSUBAw(&VU1, VUregsn); } -void VU1regsMI_MUL(_VURegsNum *VUregsn) { _vuRegsMUL(&VU1, VUregsn); } -void VU1regsMI_MULi(_VURegsNum *VUregsn) { _vuRegsMULi(&VU1, VUregsn); } -void VU1regsMI_MULq(_VURegsNum *VUregsn) { _vuRegsMULq(&VU1, VUregsn); } -void VU1regsMI_MULx(_VURegsNum *VUregsn) { _vuRegsMULx(&VU1, VUregsn); } -void VU1regsMI_MULy(_VURegsNum *VUregsn) { _vuRegsMULy(&VU1, VUregsn); } -void VU1regsMI_MULz(_VURegsNum *VUregsn) { _vuRegsMULz(&VU1, VUregsn); } -void VU1regsMI_MULw(_VURegsNum *VUregsn) { _vuRegsMULw(&VU1, VUregsn); } -void VU1regsMI_MULA(_VURegsNum *VUregsn) { _vuRegsMULA(&VU1, VUregsn); } -void VU1regsMI_MULAi(_VURegsNum *VUregsn) { _vuRegsMULAi(&VU1, VUregsn); } -void VU1regsMI_MULAq(_VURegsNum *VUregsn) { _vuRegsMULAq(&VU1, VUregsn); } -void VU1regsMI_MULAx(_VURegsNum *VUregsn) { _vuRegsMULAx(&VU1, VUregsn); } -void VU1regsMI_MULAy(_VURegsNum *VUregsn) { _vuRegsMULAy(&VU1, VUregsn); } -void VU1regsMI_MULAz(_VURegsNum *VUregsn) { _vuRegsMULAz(&VU1, VUregsn); } -void VU1regsMI_MULAw(_VURegsNum *VUregsn) { _vuRegsMULAw(&VU1, VUregsn); } -void VU1regsMI_MADD(_VURegsNum *VUregsn) { _vuRegsMADD(&VU1, VUregsn); } -void VU1regsMI_MADDi(_VURegsNum *VUregsn) { _vuRegsMADDi(&VU1, VUregsn); } -void VU1regsMI_MADDq(_VURegsNum *VUregsn) { _vuRegsMADDq(&VU1, VUregsn); } -void VU1regsMI_MADDx(_VURegsNum *VUregsn) { _vuRegsMADDx(&VU1, VUregsn); } -void VU1regsMI_MADDy(_VURegsNum *VUregsn) { _vuRegsMADDy(&VU1, VUregsn); } -void VU1regsMI_MADDz(_VURegsNum *VUregsn) { _vuRegsMADDz(&VU1, VUregsn); } -void VU1regsMI_MADDw(_VURegsNum *VUregsn) { _vuRegsMADDw(&VU1, VUregsn); } -void VU1regsMI_MADDA(_VURegsNum *VUregsn) { _vuRegsMADDA(&VU1, VUregsn); } -void VU1regsMI_MADDAi(_VURegsNum *VUregsn) { _vuRegsMADDAi(&VU1, VUregsn); } -void VU1regsMI_MADDAq(_VURegsNum *VUregsn) { _vuRegsMADDAq(&VU1, VUregsn); } -void VU1regsMI_MADDAx(_VURegsNum *VUregsn) { _vuRegsMADDAx(&VU1, VUregsn); } -void VU1regsMI_MADDAy(_VURegsNum *VUregsn) { _vuRegsMADDAy(&VU1, VUregsn); } -void VU1regsMI_MADDAz(_VURegsNum *VUregsn) { _vuRegsMADDAz(&VU1, VUregsn); } -void VU1regsMI_MADDAw(_VURegsNum *VUregsn) { _vuRegsMADDAw(&VU1, VUregsn); } -void VU1regsMI_MSUB(_VURegsNum *VUregsn) { _vuRegsMSUB(&VU1, VUregsn); } -void VU1regsMI_MSUBi(_VURegsNum *VUregsn) { _vuRegsMSUBi(&VU1, VUregsn); } -void VU1regsMI_MSUBq(_VURegsNum *VUregsn) { _vuRegsMSUBq(&VU1, VUregsn); } -void VU1regsMI_MSUBx(_VURegsNum *VUregsn) { _vuRegsMSUBx(&VU1, VUregsn); } -void VU1regsMI_MSUBy(_VURegsNum *VUregsn) { _vuRegsMSUBy(&VU1, VUregsn); } -void VU1regsMI_MSUBz(_VURegsNum *VUregsn) { _vuRegsMSUBz(&VU1, VUregsn); } -void VU1regsMI_MSUBw(_VURegsNum *VUregsn) { _vuRegsMSUBw(&VU1, VUregsn); } -void VU1regsMI_MSUBA(_VURegsNum *VUregsn) { _vuRegsMSUBA(&VU1, VUregsn); } -void VU1regsMI_MSUBAi(_VURegsNum *VUregsn) { _vuRegsMSUBAi(&VU1, VUregsn); } -void VU1regsMI_MSUBAq(_VURegsNum *VUregsn) { _vuRegsMSUBAq(&VU1, VUregsn); } -void VU1regsMI_MSUBAx(_VURegsNum *VUregsn) { _vuRegsMSUBAx(&VU1, VUregsn); } -void VU1regsMI_MSUBAy(_VURegsNum *VUregsn) { _vuRegsMSUBAy(&VU1, VUregsn); } -void VU1regsMI_MSUBAz(_VURegsNum *VUregsn) { _vuRegsMSUBAz(&VU1, VUregsn); } -void VU1regsMI_MSUBAw(_VURegsNum *VUregsn) { _vuRegsMSUBAw(&VU1, VUregsn); } -void VU1regsMI_MAX(_VURegsNum *VUregsn) { _vuRegsMAX(&VU1, VUregsn); } -void VU1regsMI_MAXi(_VURegsNum *VUregsn) { _vuRegsMAXi(&VU1, VUregsn); } -void VU1regsMI_MAXx(_VURegsNum *VUregsn) { _vuRegsMAXx(&VU1, VUregsn); } -void VU1regsMI_MAXy(_VURegsNum *VUregsn) { _vuRegsMAXy(&VU1, VUregsn); } -void VU1regsMI_MAXz(_VURegsNum *VUregsn) { _vuRegsMAXz(&VU1, VUregsn); } -void VU1regsMI_MAXw(_VURegsNum *VUregsn) { _vuRegsMAXw(&VU1, VUregsn); } -void VU1regsMI_MINI(_VURegsNum *VUregsn) { _vuRegsMINI(&VU1, VUregsn); } -void VU1regsMI_MINIi(_VURegsNum *VUregsn) { _vuRegsMINIi(&VU1, VUregsn); } -void VU1regsMI_MINIx(_VURegsNum *VUregsn) { _vuRegsMINIx(&VU1, VUregsn); } -void VU1regsMI_MINIy(_VURegsNum *VUregsn) { _vuRegsMINIy(&VU1, VUregsn); } -void VU1regsMI_MINIz(_VURegsNum *VUregsn) { _vuRegsMINIz(&VU1, VUregsn); } -void VU1regsMI_MINIw(_VURegsNum *VUregsn) { _vuRegsMINIw(&VU1, VUregsn); } -void VU1regsMI_OPMULA(_VURegsNum *VUregsn) { _vuRegsOPMULA(&VU1, VUregsn); } -void VU1regsMI_OPMSUB(_VURegsNum *VUregsn) { _vuRegsOPMSUB(&VU1, VUregsn); } -void VU1regsMI_NOP(_VURegsNum *VUregsn) { _vuRegsNOP(&VU1, VUregsn); } -void VU1regsMI_FTOI0(_VURegsNum *VUregsn) { _vuRegsFTOI0(&VU1, VUregsn); } -void VU1regsMI_FTOI4(_VURegsNum *VUregsn) { _vuRegsFTOI4(&VU1, VUregsn); } -void VU1regsMI_FTOI12(_VURegsNum *VUregsn) { _vuRegsFTOI12(&VU1, VUregsn); } -void VU1regsMI_FTOI15(_VURegsNum *VUregsn) { _vuRegsFTOI15(&VU1, VUregsn); } -void VU1regsMI_ITOF0(_VURegsNum *VUregsn) { _vuRegsITOF0(&VU1, VUregsn); } -void VU1regsMI_ITOF4(_VURegsNum *VUregsn) { _vuRegsITOF4(&VU1, VUregsn); } -void VU1regsMI_ITOF12(_VURegsNum *VUregsn) { _vuRegsITOF12(&VU1, VUregsn); } -void VU1regsMI_ITOF15(_VURegsNum *VUregsn) { _vuRegsITOF15(&VU1, VUregsn); } -void VU1regsMI_CLIP(_VURegsNum *VUregsn) { _vuRegsCLIP(&VU1, VUregsn); } - -/*****************************************/ -/* VU Micromode Lower instructions */ -/*****************************************/ - -void VU1regsMI_DIV(_VURegsNum *VUregsn) { _vuRegsDIV(&VU1, VUregsn); } -void VU1regsMI_SQRT(_VURegsNum *VUregsn) { _vuRegsSQRT(&VU1, VUregsn); } -void VU1regsMI_RSQRT(_VURegsNum *VUregsn) { _vuRegsRSQRT(&VU1, VUregsn); } -void VU1regsMI_IADD(_VURegsNum *VUregsn) { _vuRegsIADD(&VU1, VUregsn); } -void VU1regsMI_IADDI(_VURegsNum *VUregsn) { _vuRegsIADDI(&VU1, VUregsn); } -void VU1regsMI_IADDIU(_VURegsNum *VUregsn) { _vuRegsIADDIU(&VU1, VUregsn); } -void VU1regsMI_IAND(_VURegsNum *VUregsn) { _vuRegsIAND(&VU1, VUregsn); } -void VU1regsMI_IOR(_VURegsNum *VUregsn) { _vuRegsIOR(&VU1, VUregsn); } -void VU1regsMI_ISUB(_VURegsNum *VUregsn) { _vuRegsISUB(&VU1, VUregsn); } -void VU1regsMI_ISUBIU(_VURegsNum *VUregsn) { _vuRegsISUBIU(&VU1, VUregsn); } -void VU1regsMI_MOVE(_VURegsNum *VUregsn) { _vuRegsMOVE(&VU1, VUregsn); } -void VU1regsMI_MFIR(_VURegsNum *VUregsn) { _vuRegsMFIR(&VU1, VUregsn); } -void VU1regsMI_MTIR(_VURegsNum *VUregsn) { _vuRegsMTIR(&VU1, VUregsn); } -void VU1regsMI_MR32(_VURegsNum *VUregsn) { _vuRegsMR32(&VU1, VUregsn); } -void VU1regsMI_LQ(_VURegsNum *VUregsn) { _vuRegsLQ(&VU1, VUregsn); } -void VU1regsMI_LQD(_VURegsNum *VUregsn) { _vuRegsLQD(&VU1, VUregsn); } -void VU1regsMI_LQI(_VURegsNum *VUregsn) { _vuRegsLQI(&VU1, VUregsn); } -void VU1regsMI_SQ(_VURegsNum *VUregsn) { _vuRegsSQ(&VU1, VUregsn); } -void VU1regsMI_SQD(_VURegsNum *VUregsn) { _vuRegsSQD(&VU1, VUregsn); } -void VU1regsMI_SQI(_VURegsNum *VUregsn) { _vuRegsSQI(&VU1, VUregsn); } -void VU1regsMI_ILW(_VURegsNum *VUregsn) { _vuRegsILW(&VU1, VUregsn); } -void VU1regsMI_ISW(_VURegsNum *VUregsn) { _vuRegsISW(&VU1, VUregsn); } -void VU1regsMI_ILWR(_VURegsNum *VUregsn) { _vuRegsILWR(&VU1, VUregsn); } -void VU1regsMI_ISWR(_VURegsNum *VUregsn) { _vuRegsISWR(&VU1, VUregsn); } -void VU1regsMI_RINIT(_VURegsNum *VUregsn) { _vuRegsRINIT(&VU1, VUregsn); } -void VU1regsMI_RGET(_VURegsNum *VUregsn) { _vuRegsRGET(&VU1, VUregsn); } -void VU1regsMI_RNEXT(_VURegsNum *VUregsn) { _vuRegsRNEXT(&VU1, VUregsn); } -void VU1regsMI_RXOR(_VURegsNum *VUregsn) { _vuRegsRXOR(&VU1, VUregsn); } -void VU1regsMI_WAITQ(_VURegsNum *VUregsn) { _vuRegsWAITQ(&VU1, VUregsn); } -void VU1regsMI_FSAND(_VURegsNum *VUregsn) { _vuRegsFSAND(&VU1, VUregsn); } -void VU1regsMI_FSEQ(_VURegsNum *VUregsn) { _vuRegsFSEQ(&VU1, VUregsn); } -void VU1regsMI_FSOR(_VURegsNum *VUregsn) { _vuRegsFSOR(&VU1, VUregsn); } -void VU1regsMI_FSSET(_VURegsNum *VUregsn) { _vuRegsFSSET(&VU1, VUregsn); } -void VU1regsMI_FMAND(_VURegsNum *VUregsn) { _vuRegsFMAND(&VU1, VUregsn); } -void VU1regsMI_FMEQ(_VURegsNum *VUregsn) { _vuRegsFMEQ(&VU1, VUregsn); } -void VU1regsMI_FMOR(_VURegsNum *VUregsn) { _vuRegsFMOR(&VU1, VUregsn); } -void VU1regsMI_FCAND(_VURegsNum *VUregsn) { _vuRegsFCAND(&VU1, VUregsn); } -void VU1regsMI_FCEQ(_VURegsNum *VUregsn) { _vuRegsFCEQ(&VU1, VUregsn); } -void VU1regsMI_FCOR(_VURegsNum *VUregsn) { _vuRegsFCOR(&VU1, VUregsn); } -void VU1regsMI_FCSET(_VURegsNum *VUregsn) { _vuRegsFCSET(&VU1, VUregsn); } -void VU1regsMI_FCGET(_VURegsNum *VUregsn) { _vuRegsFCGET(&VU1, VUregsn); } -void VU1regsMI_IBEQ(_VURegsNum *VUregsn) { _vuRegsIBEQ(&VU1, VUregsn); } -void VU1regsMI_IBGEZ(_VURegsNum *VUregsn) { _vuRegsIBGEZ(&VU1, VUregsn); } -void VU1regsMI_IBGTZ(_VURegsNum *VUregsn) { _vuRegsIBGTZ(&VU1, VUregsn); } -void VU1regsMI_IBLTZ(_VURegsNum *VUregsn) { _vuRegsIBLTZ(&VU1, VUregsn); } -void VU1regsMI_IBLEZ(_VURegsNum *VUregsn) { _vuRegsIBLEZ(&VU1, VUregsn); } -void VU1regsMI_IBNE(_VURegsNum *VUregsn) { _vuRegsIBNE(&VU1, VUregsn); } -void VU1regsMI_B(_VURegsNum *VUregsn) { _vuRegsB(&VU1, VUregsn); } -void VU1regsMI_BAL(_VURegsNum *VUregsn) { _vuRegsBAL(&VU1, VUregsn); } -void VU1regsMI_JR(_VURegsNum *VUregsn) { _vuRegsJR(&VU1, VUregsn); } -void VU1regsMI_JALR(_VURegsNum *VUregsn) { _vuRegsJALR(&VU1, VUregsn); } -void VU1regsMI_MFP(_VURegsNum *VUregsn) { _vuRegsMFP(&VU1, VUregsn); } -void VU1regsMI_WAITP(_VURegsNum *VUregsn) { _vuRegsWAITP(&VU1, VUregsn); } -void VU1regsMI_ESADD(_VURegsNum *VUregsn) { _vuRegsESADD(&VU1, VUregsn); } -void VU1regsMI_ERSADD(_VURegsNum *VUregsn) { _vuRegsERSADD(&VU1, VUregsn); } -void VU1regsMI_ELENG(_VURegsNum *VUregsn) { _vuRegsELENG(&VU1, VUregsn); } -void VU1regsMI_ERLENG(_VURegsNum *VUregsn) { _vuRegsERLENG(&VU1, VUregsn); } -void VU1regsMI_EATANxy(_VURegsNum *VUregsn) { _vuRegsEATANxy(&VU1, VUregsn); } -void VU1regsMI_EATANxz(_VURegsNum *VUregsn) { _vuRegsEATANxz(&VU1, VUregsn); } -void VU1regsMI_ESUM(_VURegsNum *VUregsn) { _vuRegsESUM(&VU1, VUregsn); } -void VU1regsMI_ERCPR(_VURegsNum *VUregsn) { _vuRegsERCPR(&VU1, VUregsn); } -void VU1regsMI_ESQRT(_VURegsNum *VUregsn) { _vuRegsESQRT(&VU1, VUregsn); } -void VU1regsMI_ERSQRT(_VURegsNum *VUregsn) { _vuRegsERSQRT(&VU1, VUregsn); } -void VU1regsMI_ESIN(_VURegsNum *VUregsn) { _vuRegsESIN(&VU1, VUregsn); } -void VU1regsMI_EATAN(_VURegsNum *VUregsn) { _vuRegsEATAN(&VU1, VUregsn); } -void VU1regsMI_EEXP(_VURegsNum *VUregsn) { _vuRegsEEXP(&VU1, VUregsn); } -void VU1regsMI_XITOP(_VURegsNum *VUregsn) { _vuRegsXITOP(&VU1, VUregsn); } -void VU1regsMI_XGKICK(_VURegsNum *VUregsn) { _vuRegsXGKICK(&VU1, VUregsn); } -void VU1regsMI_XTOP(_VURegsNum *VUregsn) { _vuRegsXTOP(&VU1, VUregsn); } diff --git a/pcsx2/VU1microInterp.cpp b/pcsx2/VU1microInterp.cpp index c6b1c7b85e..2446b1a967 100644 --- a/pcsx2/VU1microInterp.cpp +++ b/pcsx2/VU1microInterp.cpp @@ -21,8 +21,6 @@ extern void _vuFlushAll(VURegs* VU); -_vuTables(VU1, VU1); - void _vu1ExecUpper(VURegs* VU, u32 *ptr) { VU->code = ptr[1]; IdebugUPPER(VU1); @@ -50,13 +48,6 @@ static void _vu1Exec(VURegs* VU) int vireg; int discard=0; - if(VU->VI[REG_TPC].UL >= VU->maxmicro){ - CPU_LOG("VU1 memory overflow!!: %x", VU->VI[REG_TPC].UL); - VU->VI[REG_TPC].UL &= 0x3FFF; - /*VU0.VI[REG_VPU_STAT].UL&= ~0x100; - VU->cycle++; - return;*/ - } ptr = (u32*)&VU->Micro[VU->VI[REG_TPC].UL]; VU->VI[REG_TPC].UL+=8; @@ -159,7 +150,7 @@ static void _vu1Exec(VURegs* VU) if( VU->ebit-- == 1 ) { _vuFlushAll(VU); VU0.VI[REG_VPU_STAT].UL &= ~0x100; - vif1Regs->stat.VEW = false; + vif1Regs.stat.VEW = false; } } } @@ -184,6 +175,7 @@ InterpVU1::InterpVU1() void InterpVU1::Step() { + VU1.VI[REG_TPC].UL &= VU1_PROGMASK; vu1Exec( &VU1 ); } @@ -192,11 +184,11 @@ void InterpVU1::Execute(u32 cycles) for (int i = (int)cycles; i > 0 ; i--) { if (!(VU0.VI[REG_VPU_STAT].UL & 0x100)) { if (VU1.branch || VU1.ebit) { - vu1Exec(&VU1); // run branch delay slot? + Step(); // run branch delay slot? } break; } - vu1Exec(&VU1); + Step(); } } diff --git a/pcsx2/VUmicro.h b/pcsx2/VUmicro.h index a8d76706b0..652d9f9afc 100644 --- a/pcsx2/VUmicro.h +++ b/pcsx2/VUmicro.h @@ -14,9 +14,21 @@ */ #pragma once + #include "VU.h" #include "VUops.h" #include "R5900.h" + +static const uint VU0_MEMSIZE = 0x1000; +static const uint VU0_PROGSIZE = 0x1000; +static const uint VU1_MEMSIZE = 0x4000; +static const uint VU1_PROGSIZE = 0x4000; + +static const uint VU0_MEMMASK = VU0_MEMSIZE-1; +static const uint VU0_PROGMASK = VU0_PROGSIZE-1; +static const uint VU1_MEMMASK = VU1_MEMSIZE-1; +static const uint VU1_PROGMASK = VU1_PROGSIZE-1; + #define vuRunCycles (512*12) // Cycles to run ExecuteBlockJIT() for (called from within recs) #define vu0RunCycles (512*12) // Cycles to run vu0 for whenever ExecuteBlock() is called #define vu1RunCycles (3000000) // mVU1 uses this for inf loop detection on dev builds @@ -240,38 +252,6 @@ extern BaseVUmicroCPU* CpuVU0; extern BaseVUmicroCPU* CpuVU1; -extern void (*VU0_LOWER_OPCODE[128])(); -extern void (*VU0_UPPER_OPCODE[64])(); - -extern void (*VU0_UPPER_FD_00_TABLE[32])(); -extern void (*VU0_UPPER_FD_01_TABLE[32])(); -extern void (*VU0_UPPER_FD_10_TABLE[32])(); -extern void (*VU0_UPPER_FD_11_TABLE[32])(); - -extern void (*VU0regs_LOWER_OPCODE[128])(_VURegsNum *VUregsn); -extern void (*VU0regs_UPPER_OPCODE[64])(_VURegsNum *VUregsn); - -extern void (*VU0regs_UPPER_FD_00_TABLE[32])(_VURegsNum *VUregsn); -extern void (*VU0regs_UPPER_FD_01_TABLE[32])(_VURegsNum *VUregsn); -extern void (*VU0regs_UPPER_FD_10_TABLE[32])(_VURegsNum *VUregsn); -extern void (*VU0regs_UPPER_FD_11_TABLE[32])(_VURegsNum *VUregsn); - -extern void (*VU1_LOWER_OPCODE[128])(); -extern void (*VU1_UPPER_OPCODE[64])(); - -extern void (*VU1_UPPER_FD_00_TABLE[32])(); -extern void (*VU1_UPPER_FD_01_TABLE[32])(); -extern void (*VU1_UPPER_FD_10_TABLE[32])(); -extern void (*VU1_UPPER_FD_11_TABLE[32])(); - -extern void (*VU1regs_LOWER_OPCODE[128])(_VURegsNum *VUregsn); -extern void (*VU1regs_UPPER_OPCODE[64])(_VURegsNum *VUregsn); - -extern void (*VU1regs_UPPER_FD_00_TABLE[32])(_VURegsNum *VUregsn); -extern void (*VU1regs_UPPER_FD_01_TABLE[32])(_VURegsNum *VUregsn); -extern void (*VU1regs_UPPER_FD_10_TABLE[32])(_VURegsNum *VUregsn); -extern void (*VU1regs_UPPER_FD_11_TABLE[32])(_VURegsNum *VUregsn); - extern void vuMicroMemAlloc(); extern void vuMicroMemShutdown(); extern void vuMicroMemReset(); @@ -281,7 +261,6 @@ extern void vu0ResetRegs(); extern void __fastcall vu0ExecMicro(u32 addr); extern void vu0Exec(VURegs* VU); extern void vu0Finish(); -extern void recResetVU0( void ); extern void iDumpVU0Registers(); // VU1 @@ -291,1166 +270,6 @@ extern void __fastcall vu1ExecMicro(u32 addr); extern void vu1Exec(VURegs* VU); extern void iDumpVU1Registers(); -void VU0_UPPER_FD_00(); -void VU0_UPPER_FD_01(); -void VU0_UPPER_FD_10(); -void VU0_UPPER_FD_11(); - -void VU0LowerOP(); -void VU0LowerOP_T3_00(); -void VU0LowerOP_T3_01(); -void VU0LowerOP_T3_10(); -void VU0LowerOP_T3_11(); - -void VU0unknown(); - -void VU1_UPPER_FD_00(); -void VU1_UPPER_FD_01(); -void VU1_UPPER_FD_10(); -void VU1_UPPER_FD_11(); - -void VU1LowerOP(); -void VU1LowerOP_T3_00(); -void VU1LowerOP_T3_01(); -void VU1LowerOP_T3_10(); -void VU1LowerOP_T3_11(); - -void VU1unknown(); - -void VU0regs_UPPER_FD_00(_VURegsNum *VUregsn); -void VU0regs_UPPER_FD_01(_VURegsNum *VUregsn); -void VU0regs_UPPER_FD_10(_VURegsNum *VUregsn); -void VU0regs_UPPER_FD_11(_VURegsNum *VUregsn); - -void VU0regsLowerOP(_VURegsNum *VUregsn); -void VU0regsLowerOP_T3_00(_VURegsNum *VUregsn); -void VU0regsLowerOP_T3_01(_VURegsNum *VUregsn); -void VU0regsLowerOP_T3_10(_VURegsNum *VUregsn); -void VU0regsLowerOP_T3_11(_VURegsNum *VUregsn); - -void VU0regsunknown(_VURegsNum *VUregsn); - -void VU1regs_UPPER_FD_00(_VURegsNum *VUregsn); -void VU1regs_UPPER_FD_01(_VURegsNum *VUregsn); -void VU1regs_UPPER_FD_10(_VURegsNum *VUregsn); -void VU1regs_UPPER_FD_11(_VURegsNum *VUregsn); - -void VU1regsLowerOP(_VURegsNum *VUregsn); -void VU1regsLowerOP_T3_00(_VURegsNum *VUregsn); -void VU1regsLowerOP_T3_01(_VURegsNum *VUregsn); -void VU1regsLowerOP_T3_10(_VURegsNum *VUregsn); -void VU1regsLowerOP_T3_11(_VURegsNum *VUregsn); - -void VU1regsunknown(_VURegsNum *VUregsn); - -/***************************************** - VU0 Micromode Upper instructions -*****************************************/ - -void VU0MI_ABS(); -void VU0MI_ADD(); -void VU0MI_ADDi(); -void VU0MI_ADDq(); -void VU0MI_ADDx(); -void VU0MI_ADDy(); -void VU0MI_ADDz(); -void VU0MI_ADDw(); -void VU0MI_ADDA(); -void VU0MI_ADDAi(); -void VU0MI_ADDAq(); -void VU0MI_ADDAx(); -void VU0MI_ADDAy(); -void VU0MI_ADDAz(); -void VU0MI_ADDAw(); -void VU0MI_SUB(); -void VU0MI_SUBi(); -void VU0MI_SUBq(); -void VU0MI_SUBx(); -void VU0MI_SUBy(); -void VU0MI_SUBz(); -void VU0MI_SUBw(); -void VU0MI_SUBA(); -void VU0MI_SUBAi(); -void VU0MI_SUBAq(); -void VU0MI_SUBAx(); -void VU0MI_SUBAy(); -void VU0MI_SUBAz(); -void VU0MI_SUBAw(); -void VU0MI_MUL(); -void VU0MI_MULi(); -void VU0MI_MULq(); -void VU0MI_MULx(); -void VU0MI_MULy(); -void VU0MI_MULz(); -void VU0MI_MULw(); -void VU0MI_MULA(); -void VU0MI_MULAi(); -void VU0MI_MULAq(); -void VU0MI_MULAx(); -void VU0MI_MULAy(); -void VU0MI_MULAz(); -void VU0MI_MULAw(); -void VU0MI_MADD(); -void VU0MI_MADDi(); -void VU0MI_MADDq(); -void VU0MI_MADDx(); -void VU0MI_MADDy(); -void VU0MI_MADDz(); -void VU0MI_MADDw(); -void VU0MI_MADDA(); -void VU0MI_MADDAi(); -void VU0MI_MADDAq(); -void VU0MI_MADDAx(); -void VU0MI_MADDAy(); -void VU0MI_MADDAz(); -void VU0MI_MADDAw(); -void VU0MI_MSUB(); -void VU0MI_MSUBi(); -void VU0MI_MSUBq(); -void VU0MI_MSUBx(); -void VU0MI_MSUBy(); -void VU0MI_MSUBz(); -void VU0MI_MSUBw(); -void VU0MI_MSUBA(); -void VU0MI_MSUBAi(); -void VU0MI_MSUBAq(); -void VU0MI_MSUBAx(); -void VU0MI_MSUBAy(); -void VU0MI_MSUBAz(); -void VU0MI_MSUBAw(); -void VU0MI_MAX(); -void VU0MI_MAXi(); -void VU0MI_MAXx(); -void VU0MI_MAXy(); -void VU0MI_MAXz(); -void VU0MI_MAXw(); -void VU0MI_MINI(); -void VU0MI_MINIi(); -void VU0MI_MINIx(); -void VU0MI_MINIy(); -void VU0MI_MINIz(); -void VU0MI_MINIw(); -void VU0MI_OPMULA(); -void VU0MI_OPMSUB(); -void VU0MI_NOP(); -void VU0MI_FTOI0(); -void VU0MI_FTOI4(); -void VU0MI_FTOI12(); -void VU0MI_FTOI15(); -void VU0MI_ITOF0(); -void VU0MI_ITOF4(); -void VU0MI_ITOF12(); -void VU0MI_ITOF15(); -void VU0MI_CLIP(); - -/***************************************** - VU0 Micromode Lower instructions -*****************************************/ - -void VU0MI_DIV(); -void VU0MI_SQRT(); -void VU0MI_RSQRT(); -void VU0MI_IADD(); -void VU0MI_IADDI(); -void VU0MI_IADDIU(); -void VU0MI_IAND(); -void VU0MI_IOR(); -void VU0MI_ISUB(); -void VU0MI_ISUBIU(); -void VU0MI_MOVE(); -void VU0MI_MFIR(); -void VU0MI_MTIR(); -void VU0MI_MR32(); -void VU0MI_LQ(); -void VU0MI_LQD(); -void VU0MI_LQI(); -void VU0MI_SQ(); -void VU0MI_SQD(); -void VU0MI_SQI(); -void VU0MI_ILW(); -void VU0MI_ISW(); -void VU0MI_ILWR(); -void VU0MI_ISWR(); -void VU0MI_LOI(); -void VU0MI_RINIT(); -void VU0MI_RGET(); -void VU0MI_RNEXT(); -void VU0MI_RXOR(); -void VU0MI_WAITQ(); -void VU0MI_FSAND(); -void VU0MI_FSEQ(); -void VU0MI_FSOR(); -void VU0MI_FSSET(); -void VU0MI_FMAND(); -void VU0MI_FMEQ(); -void VU0MI_FMOR(); -void VU0MI_FCAND(); -void VU0MI_FCEQ(); -void VU0MI_FCOR(); -void VU0MI_FCSET(); -void VU0MI_FCGET(); -void VU0MI_IBEQ(); -void VU0MI_IBGEZ(); -void VU0MI_IBGTZ(); -void VU0MI_IBLEZ(); -void VU0MI_IBLTZ(); -void VU0MI_IBNE(); -void VU0MI_B(); -void VU0MI_BAL(); -void VU0MI_JR(); -void VU0MI_JALR(); -void VU0MI_MFP(); -void VU0MI_WAITP(); -void VU0MI_ESADD(); -void VU0MI_ERSADD(); -void VU0MI_ELENG(); -void VU0MI_ERLENG(); -void VU0MI_EATANxy(); -void VU0MI_EATANxz(); -void VU0MI_ESUM(); -void VU0MI_ERCPR(); -void VU0MI_ESQRT(); -void VU0MI_ERSQRT(); -void VU0MI_ESIN(); -void VU0MI_EATAN(); -void VU0MI_EEXP(); -void VU0MI_XGKICK(); -void VU0MI_XTOP(); -void VU0MI_XITOP(); - -/***************************************** - VU1 Micromode Upper instructions -*****************************************/ - -void VU0regsMI_ABS(_VURegsNum *VUregsn); -void VU0regsMI_ADD(_VURegsNum *VUregsn); -void VU0regsMI_ADDi(_VURegsNum *VUregsn); -void VU0regsMI_ADDq(_VURegsNum *VUregsn); -void VU0regsMI_ADDx(_VURegsNum *VUregsn); -void VU0regsMI_ADDy(_VURegsNum *VUregsn); -void VU0regsMI_ADDz(_VURegsNum *VUregsn); -void VU0regsMI_ADDw(_VURegsNum *VUregsn); -void VU0regsMI_ADDA(_VURegsNum *VUregsn); -void VU0regsMI_ADDAi(_VURegsNum *VUregsn); -void VU0regsMI_ADDAq(_VURegsNum *VUregsn); -void VU0regsMI_ADDAx(_VURegsNum *VUregsn); -void VU0regsMI_ADDAy(_VURegsNum *VUregsn); -void VU0regsMI_ADDAz(_VURegsNum *VUregsn); -void VU0regsMI_ADDAw(_VURegsNum *VUregsn); -void VU0regsMI_SUB(_VURegsNum *VUregsn); -void VU0regsMI_SUBi(_VURegsNum *VUregsn); -void VU0regsMI_SUBq(_VURegsNum *VUregsn); -void VU0regsMI_SUBx(_VURegsNum *VUregsn); -void VU0regsMI_SUBy(_VURegsNum *VUregsn); -void VU0regsMI_SUBz(_VURegsNum *VUregsn); -void VU0regsMI_SUBw(_VURegsNum *VUregsn); -void VU0regsMI_SUBA(_VURegsNum *VUregsn); -void VU0regsMI_SUBAi(_VURegsNum *VUregsn); -void VU0regsMI_SUBAq(_VURegsNum *VUregsn); -void VU0regsMI_SUBAx(_VURegsNum *VUregsn); -void VU0regsMI_SUBAy(_VURegsNum *VUregsn); -void VU0regsMI_SUBAz(_VURegsNum *VUregsn); -void VU0regsMI_SUBAw(_VURegsNum *VUregsn); -void VU0regsMI_MUL(_VURegsNum *VUregsn); -void VU0regsMI_MULi(_VURegsNum *VUregsn); -void VU0regsMI_MULq(_VURegsNum *VUregsn); -void VU0regsMI_MULx(_VURegsNum *VUregsn); -void VU0regsMI_MULy(_VURegsNum *VUregsn); -void VU0regsMI_MULz(_VURegsNum *VUregsn); -void VU0regsMI_MULw(_VURegsNum *VUregsn); -void VU0regsMI_MULA(_VURegsNum *VUregsn); -void VU0regsMI_MULAi(_VURegsNum *VUregsn); -void VU0regsMI_MULAq(_VURegsNum *VUregsn); -void VU0regsMI_MULAx(_VURegsNum *VUregsn); -void VU0regsMI_MULAy(_VURegsNum *VUregsn); -void VU0regsMI_MULAz(_VURegsNum *VUregsn); -void VU0regsMI_MULAw(_VURegsNum *VUregsn); -void VU0regsMI_MADD(_VURegsNum *VUregsn); -void VU0regsMI_MADDi(_VURegsNum *VUregsn); -void VU0regsMI_MADDq(_VURegsNum *VUregsn); -void VU0regsMI_MADDx(_VURegsNum *VUregsn); -void VU0regsMI_MADDy(_VURegsNum *VUregsn); -void VU0regsMI_MADDz(_VURegsNum *VUregsn); -void VU0regsMI_MADDw(_VURegsNum *VUregsn); -void VU0regsMI_MADDA(_VURegsNum *VUregsn); -void VU0regsMI_MADDAi(_VURegsNum *VUregsn); -void VU0regsMI_MADDAq(_VURegsNum *VUregsn); -void VU0regsMI_MADDAx(_VURegsNum *VUregsn); -void VU0regsMI_MADDAy(_VURegsNum *VUregsn); -void VU0regsMI_MADDAz(_VURegsNum *VUregsn); -void VU0regsMI_MADDAw(_VURegsNum *VUregsn); -void VU0regsMI_MSUB(_VURegsNum *VUregsn); -void VU0regsMI_MSUBi(_VURegsNum *VUregsn); -void VU0regsMI_MSUBq(_VURegsNum *VUregsn); -void VU0regsMI_MSUBx(_VURegsNum *VUregsn); -void VU0regsMI_MSUBy(_VURegsNum *VUregsn); -void VU0regsMI_MSUBz(_VURegsNum *VUregsn); -void VU0regsMI_MSUBw(_VURegsNum *VUregsn); -void VU0regsMI_MSUBA(_VURegsNum *VUregsn); -void VU0regsMI_MSUBAi(_VURegsNum *VUregsn); -void VU0regsMI_MSUBAq(_VURegsNum *VUregsn); -void VU0regsMI_MSUBAx(_VURegsNum *VUregsn); -void VU0regsMI_MSUBAy(_VURegsNum *VUregsn); -void VU0regsMI_MSUBAz(_VURegsNum *VUregsn); -void VU0regsMI_MSUBAw(_VURegsNum *VUregsn); -void VU0regsMI_MAX(_VURegsNum *VUregsn); -void VU0regsMI_MAXi(_VURegsNum *VUregsn); -void VU0regsMI_MAXx(_VURegsNum *VUregsn); -void VU0regsMI_MAXy(_VURegsNum *VUregsn); -void VU0regsMI_MAXz(_VURegsNum *VUregsn); -void VU0regsMI_MAXw(_VURegsNum *VUregsn); -void VU0regsMI_MINI(_VURegsNum *VUregsn); -void VU0regsMI_MINIi(_VURegsNum *VUregsn); -void VU0regsMI_MINIx(_VURegsNum *VUregsn); -void VU0regsMI_MINIy(_VURegsNum *VUregsn); -void VU0regsMI_MINIz(_VURegsNum *VUregsn); -void VU0regsMI_MINIw(_VURegsNum *VUregsn); -void VU0regsMI_OPMULA(_VURegsNum *VUregsn); -void VU0regsMI_OPMSUB(_VURegsNum *VUregsn); -void VU0regsMI_NOP(_VURegsNum *VUregsn); -void VU0regsMI_FTOI0(_VURegsNum *VUregsn); -void VU0regsMI_FTOI4(_VURegsNum *VUregsn); -void VU0regsMI_FTOI12(_VURegsNum *VUregsn); -void VU0regsMI_FTOI15(_VURegsNum *VUregsn); -void VU0regsMI_ITOF0(_VURegsNum *VUregsn); -void VU0regsMI_ITOF4(_VURegsNum *VUregsn); -void VU0regsMI_ITOF12(_VURegsNum *VUregsn); -void VU0regsMI_ITOF15(_VURegsNum *VUregsn); -void VU0regsMI_CLIP(_VURegsNum *VUregsn); - -/***************************************** - VU0 Micromode Lower instructions -*****************************************/ - -void VU0regsMI_DIV(_VURegsNum *VUregsn); -void VU0regsMI_SQRT(_VURegsNum *VUregsn); -void VU0regsMI_RSQRT(_VURegsNum *VUregsn); -void VU0regsMI_IADD(_VURegsNum *VUregsn); -void VU0regsMI_IADDI(_VURegsNum *VUregsn); -void VU0regsMI_IADDIU(_VURegsNum *VUregsn); -void VU0regsMI_IAND(_VURegsNum *VUregsn); -void VU0regsMI_IOR(_VURegsNum *VUregsn); -void VU0regsMI_ISUB(_VURegsNum *VUregsn); -void VU0regsMI_ISUBIU(_VURegsNum *VUregsn); -void VU0regsMI_MOVE(_VURegsNum *VUregsn); -void VU0regsMI_MFIR(_VURegsNum *VUregsn); -void VU0regsMI_MTIR(_VURegsNum *VUregsn); -void VU0regsMI_MR32(_VURegsNum *VUregsn); -void VU0regsMI_LQ(_VURegsNum *VUregsn); -void VU0regsMI_LQD(_VURegsNum *VUregsn); -void VU0regsMI_LQI(_VURegsNum *VUregsn); -void VU0regsMI_SQ(_VURegsNum *VUregsn); -void VU0regsMI_SQD(_VURegsNum *VUregsn); -void VU0regsMI_SQI(_VURegsNum *VUregsn); -void VU0regsMI_ILW(_VURegsNum *VUregsn); -void VU0regsMI_ISW(_VURegsNum *VUregsn); -void VU0regsMI_ILWR(_VURegsNum *VUregsn); -void VU0regsMI_ISWR(_VURegsNum *VUregsn); -void VU0regsMI_LOI(_VURegsNum *VUregsn); -void VU0regsMI_RINIT(_VURegsNum *VUregsn); -void VU0regsMI_RGET(_VURegsNum *VUregsn); -void VU0regsMI_RNEXT(_VURegsNum *VUregsn); -void VU0regsMI_RXOR(_VURegsNum *VUregsn); -void VU0regsMI_WAITQ(_VURegsNum *VUregsn); -void VU0regsMI_FSAND(_VURegsNum *VUregsn); -void VU0regsMI_FSEQ(_VURegsNum *VUregsn); -void VU0regsMI_FSOR(_VURegsNum *VUregsn); -void VU0regsMI_FSSET(_VURegsNum *VUregsn); -void VU0regsMI_FMAND(_VURegsNum *VUregsn); -void VU0regsMI_FMEQ(_VURegsNum *VUregsn); -void VU0regsMI_FMOR(_VURegsNum *VUregsn); -void VU0regsMI_FCAND(_VURegsNum *VUregsn); -void VU0regsMI_FCEQ(_VURegsNum *VUregsn); -void VU0regsMI_FCOR(_VURegsNum *VUregsn); -void VU0regsMI_FCSET(_VURegsNum *VUregsn); -void VU0regsMI_FCGET(_VURegsNum *VUregsn); -void VU0regsMI_IBEQ(_VURegsNum *VUregsn); -void VU0regsMI_IBGEZ(_VURegsNum *VUregsn); -void VU0regsMI_IBGTZ(_VURegsNum *VUregsn); -void VU0regsMI_IBLTZ(_VURegsNum *VUregsn); -void VU0regsMI_IBLEZ(_VURegsNum *VUregsn); -void VU0regsMI_IBNE(_VURegsNum *VUregsn); -void VU0regsMI_B(_VURegsNum *VUregsn); -void VU0regsMI_BAL(_VURegsNum *VUregsn); -void VU0regsMI_JR(_VURegsNum *VUregsn); -void VU0regsMI_JALR(_VURegsNum *VUregsn); -void VU0regsMI_MFP(_VURegsNum *VUregsn); -void VU0regsMI_WAITP(_VURegsNum *VUregsn); -void VU0regsMI_ESADD(_VURegsNum *VUregsn); -void VU0regsMI_ERSADD(_VURegsNum *VUregsn); -void VU0regsMI_ELENG(_VURegsNum *VUregsn); -void VU0regsMI_ERLENG(_VURegsNum *VUregsn); -void VU0regsMI_EATANxy(_VURegsNum *VUregsn); -void VU0regsMI_EATANxz(_VURegsNum *VUregsn); -void VU0regsMI_ESUM(_VURegsNum *VUregsn); -void VU0regsMI_ERCPR(_VURegsNum *VUregsn); -void VU0regsMI_ESQRT(_VURegsNum *VUregsn); -void VU0regsMI_ERSQRT(_VURegsNum *VUregsn); -void VU0regsMI_ESIN(_VURegsNum *VUregsn); -void VU0regsMI_EATAN(_VURegsNum *VUregsn); -void VU0regsMI_EEXP(_VURegsNum *VUregsn); -void VU0regsMI_XGKICK(_VURegsNum *VUregsn); -void VU0regsMI_XTOP(_VURegsNum *VUregsn); -void VU0regsMI_XITOP(_VURegsNum *VUregsn); - -/***************************************** - VU1 Micromode Upper instructions -*****************************************/ - -void VU1MI_ABS(); -void VU1MI_ADD(); -void VU1MI_ADDi(); -void VU1MI_ADDq(); -void VU1MI_ADDx(); -void VU1MI_ADDy(); -void VU1MI_ADDz(); -void VU1MI_ADDw(); -void VU1MI_ADDA(); -void VU1MI_ADDAi(); -void VU1MI_ADDAq(); -void VU1MI_ADDAx(); -void VU1MI_ADDAy(); -void VU1MI_ADDAz(); -void VU1MI_ADDAw(); -void VU1MI_SUB(); -void VU1MI_SUBi(); -void VU1MI_SUBq(); -void VU1MI_SUBx(); -void VU1MI_SUBy(); -void VU1MI_SUBz(); -void VU1MI_SUBw(); -void VU1MI_SUBA(); -void VU1MI_SUBAi(); -void VU1MI_SUBAq(); -void VU1MI_SUBAx(); -void VU1MI_SUBAy(); -void VU1MI_SUBAz(); -void VU1MI_SUBAw(); -void VU1MI_MUL(); -void VU1MI_MULi(); -void VU1MI_MULq(); -void VU1MI_MULx(); -void VU1MI_MULy(); -void VU1MI_MULz(); -void VU1MI_MULw(); -void VU1MI_MULA(); -void VU1MI_MULAi(); -void VU1MI_MULAq(); -void VU1MI_MULAx(); -void VU1MI_MULAy(); -void VU1MI_MULAz(); -void VU1MI_MULAw(); -void VU1MI_MADD(); -void VU1MI_MADDi(); -void VU1MI_MADDq(); -void VU1MI_MADDx(); -void VU1MI_MADDy(); -void VU1MI_MADDz(); -void VU1MI_MADDw(); -void VU1MI_MADDA(); -void VU1MI_MADDAi(); -void VU1MI_MADDAq(); -void VU1MI_MADDAx(); -void VU1MI_MADDAy(); -void VU1MI_MADDAz(); -void VU1MI_MADDAw(); -void VU1MI_MSUB(); -void VU1MI_MSUBi(); -void VU1MI_MSUBq(); -void VU1MI_MSUBx(); -void VU1MI_MSUBy(); -void VU1MI_MSUBz(); -void VU1MI_MSUBw(); -void VU1MI_MSUBA(); -void VU1MI_MSUBAi(); -void VU1MI_MSUBAq(); -void VU1MI_MSUBAx(); -void VU1MI_MSUBAy(); -void VU1MI_MSUBAz(); -void VU1MI_MSUBAw(); -void VU1MI_MAX(); -void VU1MI_MAXi(); -void VU1MI_MAXx(); -void VU1MI_MAXy(); -void VU1MI_MAXz(); -void VU1MI_MAXw(); -void VU1MI_MINI(); -void VU1MI_MINIi(); -void VU1MI_MINIx(); -void VU1MI_MINIy(); -void VU1MI_MINIz(); -void VU1MI_MINIw(); -void VU1MI_OPMULA(); -void VU1MI_OPMSUB(); -void VU1MI_NOP(); -void VU1MI_FTOI0(); -void VU1MI_FTOI4(); -void VU1MI_FTOI12(); -void VU1MI_FTOI15(); -void VU1MI_ITOF0(); -void VU1MI_ITOF4(); -void VU1MI_ITOF12(); -void VU1MI_ITOF15(); -void VU1MI_CLIP(); - -/***************************************** - VU1 Micromode Lower instructions -*****************************************/ - -void VU1MI_DIV(); -void VU1MI_SQRT(); -void VU1MI_RSQRT(); -void VU1MI_IADD(); -void VU1MI_IADDI(); -void VU1MI_IADDIU(); -void VU1MI_IAND(); -void VU1MI_IOR(); -void VU1MI_ISUB(); -void VU1MI_ISUBIU(); -void VU1MI_MOVE(); -void VU1MI_MFIR(); -void VU1MI_MTIR(); -void VU1MI_MR32(); -void VU1MI_LQ(); -void VU1MI_LQD(); -void VU1MI_LQI(); -void VU1MI_SQ(); -void VU1MI_SQD(); -void VU1MI_SQI(); -void VU1MI_ILW(); -void VU1MI_ISW(); -void VU1MI_ILWR(); -void VU1MI_ISWR(); -void VU1MI_LOI(); -void VU1MI_RINIT(); -void VU1MI_RGET(); -void VU1MI_RNEXT(); -void VU1MI_RXOR(); -void VU1MI_WAITQ(); -void VU1MI_FSAND(); -void VU1MI_FSEQ(); -void VU1MI_FSOR(); -void VU1MI_FSSET(); -void VU1MI_FMAND(); -void VU1MI_FMEQ(); -void VU1MI_FMOR(); -void VU1MI_FCAND(); -void VU1MI_FCEQ(); -void VU1MI_FCOR(); -void VU1MI_FCSET(); -void VU1MI_FCGET(); -void VU1MI_IBEQ(); -void VU1MI_IBGEZ(); -void VU1MI_IBGTZ(); -void VU1MI_IBLTZ(); -void VU1MI_IBLEZ(); -void VU1MI_IBNE(); -void VU1MI_B(); -void VU1MI_BAL(); -void VU1MI_JR(); -void VU1MI_JALR(); -void VU1MI_MFP(); -void VU1MI_WAITP(); -void VU1MI_ESADD(); -void VU1MI_ERSADD(); -void VU1MI_ELENG(); -void VU1MI_ERLENG(); -void VU1MI_EATANxy(); -void VU1MI_EATANxz(); -void VU1MI_ESUM(); -void VU1MI_ERCPR(); -void VU1MI_ESQRT(); -void VU1MI_ERSQRT(); -void VU1MI_ESIN(); -void VU1MI_EATAN(); -void VU1MI_EEXP(); -void VU1MI_XGKICK(); -void VU1MI_XTOP(); -void VU1MI_XITOP(); - -/***************************************** - VU1 Micromode Upper instructions -*****************************************/ - -void VU1regsMI_ABS(_VURegsNum *VUregsn); -void VU1regsMI_ADD(_VURegsNum *VUregsn); -void VU1regsMI_ADDi(_VURegsNum *VUregsn); -void VU1regsMI_ADDq(_VURegsNum *VUregsn); -void VU1regsMI_ADDx(_VURegsNum *VUregsn); -void VU1regsMI_ADDy(_VURegsNum *VUregsn); -void VU1regsMI_ADDz(_VURegsNum *VUregsn); -void VU1regsMI_ADDw(_VURegsNum *VUregsn); -void VU1regsMI_ADDA(_VURegsNum *VUregsn); -void VU1regsMI_ADDAi(_VURegsNum *VUregsn); -void VU1regsMI_ADDAq(_VURegsNum *VUregsn); -void VU1regsMI_ADDAx(_VURegsNum *VUregsn); -void VU1regsMI_ADDAy(_VURegsNum *VUregsn); -void VU1regsMI_ADDAz(_VURegsNum *VUregsn); -void VU1regsMI_ADDAw(_VURegsNum *VUregsn); -void VU1regsMI_SUB(_VURegsNum *VUregsn); -void VU1regsMI_SUBi(_VURegsNum *VUregsn); -void VU1regsMI_SUBq(_VURegsNum *VUregsn); -void VU1regsMI_SUBx(_VURegsNum *VUregsn); -void VU1regsMI_SUBy(_VURegsNum *VUregsn); -void VU1regsMI_SUBz(_VURegsNum *VUregsn); -void VU1regsMI_SUBw(_VURegsNum *VUregsn); -void VU1regsMI_SUBA(_VURegsNum *VUregsn); -void VU1regsMI_SUBAi(_VURegsNum *VUregsn); -void VU1regsMI_SUBAq(_VURegsNum *VUregsn); -void VU1regsMI_SUBAx(_VURegsNum *VUregsn); -void VU1regsMI_SUBAy(_VURegsNum *VUregsn); -void VU1regsMI_SUBAz(_VURegsNum *VUregsn); -void VU1regsMI_SUBAw(_VURegsNum *VUregsn); -void VU1regsMI_MUL(_VURegsNum *VUregsn); -void VU1regsMI_MULi(_VURegsNum *VUregsn); -void VU1regsMI_MULq(_VURegsNum *VUregsn); -void VU1regsMI_MULx(_VURegsNum *VUregsn); -void VU1regsMI_MULy(_VURegsNum *VUregsn); -void VU1regsMI_MULz(_VURegsNum *VUregsn); -void VU1regsMI_MULw(_VURegsNum *VUregsn); -void VU1regsMI_MULA(_VURegsNum *VUregsn); -void VU1regsMI_MULAi(_VURegsNum *VUregsn); -void VU1regsMI_MULAq(_VURegsNum *VUregsn); -void VU1regsMI_MULAx(_VURegsNum *VUregsn); -void VU1regsMI_MULAy(_VURegsNum *VUregsn); -void VU1regsMI_MULAz(_VURegsNum *VUregsn); -void VU1regsMI_MULAw(_VURegsNum *VUregsn); -void VU1regsMI_MADD(_VURegsNum *VUregsn); -void VU1regsMI_MADDi(_VURegsNum *VUregsn); -void VU1regsMI_MADDq(_VURegsNum *VUregsn); -void VU1regsMI_MADDx(_VURegsNum *VUregsn); -void VU1regsMI_MADDy(_VURegsNum *VUregsn); -void VU1regsMI_MADDz(_VURegsNum *VUregsn); -void VU1regsMI_MADDw(_VURegsNum *VUregsn); -void VU1regsMI_MADDA(_VURegsNum *VUregsn); -void VU1regsMI_MADDAi(_VURegsNum *VUregsn); -void VU1regsMI_MADDAq(_VURegsNum *VUregsn); -void VU1regsMI_MADDAx(_VURegsNum *VUregsn); -void VU1regsMI_MADDAy(_VURegsNum *VUregsn); -void VU1regsMI_MADDAz(_VURegsNum *VUregsn); -void VU1regsMI_MADDAw(_VURegsNum *VUregsn); -void VU1regsMI_MSUB(_VURegsNum *VUregsn); -void VU1regsMI_MSUBi(_VURegsNum *VUregsn); -void VU1regsMI_MSUBq(_VURegsNum *VUregsn); -void VU1regsMI_MSUBx(_VURegsNum *VUregsn); -void VU1regsMI_MSUBy(_VURegsNum *VUregsn); -void VU1regsMI_MSUBz(_VURegsNum *VUregsn); -void VU1regsMI_MSUBw(_VURegsNum *VUregsn); -void VU1regsMI_MSUBA(_VURegsNum *VUregsn); -void VU1regsMI_MSUBAi(_VURegsNum *VUregsn); -void VU1regsMI_MSUBAq(_VURegsNum *VUregsn); -void VU1regsMI_MSUBAx(_VURegsNum *VUregsn); -void VU1regsMI_MSUBAy(_VURegsNum *VUregsn); -void VU1regsMI_MSUBAz(_VURegsNum *VUregsn); -void VU1regsMI_MSUBAw(_VURegsNum *VUregsn); -void VU1regsMI_MAX(_VURegsNum *VUregsn); -void VU1regsMI_MAXi(_VURegsNum *VUregsn); -void VU1regsMI_MAXx(_VURegsNum *VUregsn); -void VU1regsMI_MAXy(_VURegsNum *VUregsn); -void VU1regsMI_MAXz(_VURegsNum *VUregsn); -void VU1regsMI_MAXw(_VURegsNum *VUregsn); -void VU1regsMI_MINI(_VURegsNum *VUregsn); -void VU1regsMI_MINIi(_VURegsNum *VUregsn); -void VU1regsMI_MINIx(_VURegsNum *VUregsn); -void VU1regsMI_MINIy(_VURegsNum *VUregsn); -void VU1regsMI_MINIz(_VURegsNum *VUregsn); -void VU1regsMI_MINIw(_VURegsNum *VUregsn); -void VU1regsMI_OPMULA(_VURegsNum *VUregsn); -void VU1regsMI_OPMSUB(_VURegsNum *VUregsn); -void VU1regsMI_NOP(_VURegsNum *VUregsn); -void VU1regsMI_FTOI0(_VURegsNum *VUregsn); -void VU1regsMI_FTOI4(_VURegsNum *VUregsn); -void VU1regsMI_FTOI12(_VURegsNum *VUregsn); -void VU1regsMI_FTOI15(_VURegsNum *VUregsn); -void VU1regsMI_ITOF0(_VURegsNum *VUregsn); -void VU1regsMI_ITOF4(_VURegsNum *VUregsn); -void VU1regsMI_ITOF12(_VURegsNum *VUregsn); -void VU1regsMI_ITOF15(_VURegsNum *VUregsn); -void VU1regsMI_CLIP(_VURegsNum *VUregsn); - -/***************************************** - VU1 Micromode Lower instructions -*****************************************/ - -void VU1regsMI_DIV(_VURegsNum *VUregsn); -void VU1regsMI_SQRT(_VURegsNum *VUregsn); -void VU1regsMI_RSQRT(_VURegsNum *VUregsn); -void VU1regsMI_IADD(_VURegsNum *VUregsn); -void VU1regsMI_IADDI(_VURegsNum *VUregsn); -void VU1regsMI_IADDIU(_VURegsNum *VUregsn); -void VU1regsMI_IAND(_VURegsNum *VUregsn); -void VU1regsMI_IOR(_VURegsNum *VUregsn); -void VU1regsMI_ISUB(_VURegsNum *VUregsn); -void VU1regsMI_ISUBIU(_VURegsNum *VUregsn); -void VU1regsMI_MOVE(_VURegsNum *VUregsn); -void VU1regsMI_MFIR(_VURegsNum *VUregsn); -void VU1regsMI_MTIR(_VURegsNum *VUregsn); -void VU1regsMI_MR32(_VURegsNum *VUregsn); -void VU1regsMI_LQ(_VURegsNum *VUregsn); -void VU1regsMI_LQD(_VURegsNum *VUregsn); -void VU1regsMI_LQI(_VURegsNum *VUregsn); -void VU1regsMI_SQ(_VURegsNum *VUregsn); -void VU1regsMI_SQD(_VURegsNum *VUregsn); -void VU1regsMI_SQI(_VURegsNum *VUregsn); -void VU1regsMI_ILW(_VURegsNum *VUregsn); -void VU1regsMI_ISW(_VURegsNum *VUregsn); -void VU1regsMI_ILWR(_VURegsNum *VUregsn); -void VU1regsMI_ISWR(_VURegsNum *VUregsn); -void VU1regsMI_LOI(_VURegsNum *VUregsn); -void VU1regsMI_RINIT(_VURegsNum *VUregsn); -void VU1regsMI_RGET(_VURegsNum *VUregsn); -void VU1regsMI_RNEXT(_VURegsNum *VUregsn); -void VU1regsMI_RXOR(_VURegsNum *VUregsn); -void VU1regsMI_WAITQ(_VURegsNum *VUregsn); -void VU1regsMI_FSAND(_VURegsNum *VUregsn); -void VU1regsMI_FSEQ(_VURegsNum *VUregsn); -void VU1regsMI_FSOR(_VURegsNum *VUregsn); -void VU1regsMI_FSSET(_VURegsNum *VUregsn); -void VU1regsMI_FMAND(_VURegsNum *VUregsn); -void VU1regsMI_FMEQ(_VURegsNum *VUregsn); -void VU1regsMI_FMOR(_VURegsNum *VUregsn); -void VU1regsMI_FCAND(_VURegsNum *VUregsn); -void VU1regsMI_FCEQ(_VURegsNum *VUregsn); -void VU1regsMI_FCOR(_VURegsNum *VUregsn); -void VU1regsMI_FCSET(_VURegsNum *VUregsn); -void VU1regsMI_FCGET(_VURegsNum *VUregsn); -void VU1regsMI_IBEQ(_VURegsNum *VUregsn); -void VU1regsMI_IBGEZ(_VURegsNum *VUregsn); -void VU1regsMI_IBGTZ(_VURegsNum *VUregsn); -void VU1regsMI_IBLTZ(_VURegsNum *VUregsn); -void VU1regsMI_IBLEZ(_VURegsNum *VUregsn); -void VU1regsMI_IBNE(_VURegsNum *VUregsn); -void VU1regsMI_B(_VURegsNum *VUregsn); -void VU1regsMI_BAL(_VURegsNum *VUregsn); -void VU1regsMI_JR(_VURegsNum *VUregsn); -void VU1regsMI_JALR(_VURegsNum *VUregsn); -void VU1regsMI_MFP(_VURegsNum *VUregsn); -void VU1regsMI_WAITP(_VURegsNum *VUregsn); -void VU1regsMI_ESADD(_VURegsNum *VUregsn); -void VU1regsMI_ERSADD(_VURegsNum *VUregsn); -void VU1regsMI_ELENG(_VURegsNum *VUregsn); -void VU1regsMI_ERLENG(_VURegsNum *VUregsn); -void VU1regsMI_EATANxy(_VURegsNum *VUregsn); -void VU1regsMI_EATANxz(_VURegsNum *VUregsn); -void VU1regsMI_ESUM(_VURegsNum *VUregsn); -void VU1regsMI_ERCPR(_VURegsNum *VUregsn); -void VU1regsMI_ESQRT(_VURegsNum *VUregsn); -void VU1regsMI_ERSQRT(_VURegsNum *VUregsn); -void VU1regsMI_ESIN(_VURegsNum *VUregsn); -void VU1regsMI_EATAN(_VURegsNum *VUregsn); -void VU1regsMI_EEXP(_VURegsNum *VUregsn); -void VU1regsMI_XGKICK(_VURegsNum *VUregsn); -void VU1regsMI_XTOP(_VURegsNum *VUregsn); -void VU1regsMI_XITOP(_VURegsNum *VUregsn); - -/***************************************** - VU Micromode Tables/Opcodes defs macros -*****************************************/ - - -#define _vuTables(VU, PREFIX) \ - \ -void (*PREFIX##_LOWER_OPCODE[128])() = { \ - PREFIX##MI_LQ , PREFIX##MI_SQ , PREFIX##unknown , PREFIX##unknown, \ - PREFIX##MI_ILW , PREFIX##MI_ISW , PREFIX##unknown , PREFIX##unknown, \ - PREFIX##MI_IADDIU, PREFIX##MI_ISUBIU, PREFIX##unknown , PREFIX##unknown, \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ - PREFIX##MI_FCEQ , PREFIX##MI_FCSET , PREFIX##MI_FCAND, PREFIX##MI_FCOR, /* 0x10 */ \ - PREFIX##MI_FSEQ , PREFIX##MI_FSSET , PREFIX##MI_FSAND, PREFIX##MI_FSOR, \ - PREFIX##MI_FMEQ , PREFIX##unknown , PREFIX##MI_FMAND, PREFIX##MI_FMOR, \ - PREFIX##MI_FCGET , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ - PREFIX##MI_B , PREFIX##MI_BAL , PREFIX##unknown , PREFIX##unknown, /* 0x20 */ \ - PREFIX##MI_JR , PREFIX##MI_JALR , PREFIX##unknown , PREFIX##unknown, \ - PREFIX##MI_IBEQ , PREFIX##MI_IBNE , PREFIX##unknown , PREFIX##unknown, \ - PREFIX##MI_IBLTZ , PREFIX##MI_IBGTZ , PREFIX##MI_IBLEZ, PREFIX##MI_IBGEZ, \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, /* 0x30 */ \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ - PREFIX##LowerOP , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, /* 0x40*/ \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, /* 0x50 */ \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, /* 0x60 */ \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, /* 0x70 */ \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ -}; \ - \ - void (*PREFIX##LowerOP_T3_00_OPCODE[32])() = { \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ - PREFIX##MI_MOVE , PREFIX##MI_LQI , PREFIX##MI_DIV , PREFIX##MI_MTIR, \ - PREFIX##MI_RNEXT , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, /* 0x10 */ \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ - PREFIX##unknown , PREFIX##MI_MFP , PREFIX##MI_XTOP , PREFIX##MI_XGKICK, \ - PREFIX##MI_ESADD , PREFIX##MI_EATANxy, PREFIX##MI_ESQRT, PREFIX##MI_ESIN, \ -}; \ - \ - void (*PREFIX##LowerOP_T3_01_OPCODE[32])() = { \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ - PREFIX##MI_MR32 , PREFIX##MI_SQI , PREFIX##MI_SQRT , PREFIX##MI_MFIR, \ - PREFIX##MI_RGET , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, /* 0x10 */ \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ - PREFIX##unknown , PREFIX##unknown , PREFIX##MI_XITOP, PREFIX##unknown, \ - PREFIX##MI_ERSADD, PREFIX##MI_EATANxz, PREFIX##MI_ERSQRT, PREFIX##MI_EATAN, \ -}; \ - \ - void (*PREFIX##LowerOP_T3_10_OPCODE[32])() = { \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ - PREFIX##unknown , PREFIX##MI_LQD , PREFIX##MI_RSQRT, PREFIX##MI_ILWR, \ - PREFIX##MI_RINIT , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, /* 0x10 */ \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ - PREFIX##MI_ELENG , PREFIX##MI_ESUM , PREFIX##MI_ERCPR, PREFIX##MI_EEXP, \ -}; \ - \ - void (*PREFIX##LowerOP_T3_11_OPCODE[32])() = { \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ - PREFIX##unknown , PREFIX##MI_SQD , PREFIX##MI_WAITQ, PREFIX##MI_ISWR, \ - PREFIX##MI_RXOR , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, /* 0x10 */ \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ - PREFIX##MI_ERLENG, PREFIX##unknown , PREFIX##MI_WAITP, PREFIX##unknown, \ -}; \ - \ - void (*PREFIX##LowerOP_OPCODE[64])() = { \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, /* 0x10 */ \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, /* 0x20 */ \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ - PREFIX##MI_IADD , PREFIX##MI_ISUB , PREFIX##MI_IADDI, PREFIX##unknown, /* 0x30 */ \ - PREFIX##MI_IAND , PREFIX##MI_IOR , PREFIX##unknown , PREFIX##unknown, \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ - PREFIX##LowerOP_T3_00, PREFIX##LowerOP_T3_01, PREFIX##LowerOP_T3_10, PREFIX##LowerOP_T3_11, \ -}; \ - \ - void (*PREFIX##_UPPER_OPCODE[64])() = { \ - PREFIX##MI_ADDx , PREFIX##MI_ADDy , PREFIX##MI_ADDz , PREFIX##MI_ADDw, \ - PREFIX##MI_SUBx , PREFIX##MI_SUBy , PREFIX##MI_SUBz , PREFIX##MI_SUBw, \ - PREFIX##MI_MADDx , PREFIX##MI_MADDy , PREFIX##MI_MADDz , PREFIX##MI_MADDw, \ - PREFIX##MI_MSUBx , PREFIX##MI_MSUBy , PREFIX##MI_MSUBz , PREFIX##MI_MSUBw, \ - PREFIX##MI_MAXx , PREFIX##MI_MAXy , PREFIX##MI_MAXz , PREFIX##MI_MAXw, /* 0x10 */ \ - PREFIX##MI_MINIx , PREFIX##MI_MINIy , PREFIX##MI_MINIz , PREFIX##MI_MINIw, \ - PREFIX##MI_MULx , PREFIX##MI_MULy , PREFIX##MI_MULz , PREFIX##MI_MULw, \ - PREFIX##MI_MULq , PREFIX##MI_MAXi , PREFIX##MI_MULi , PREFIX##MI_MINIi, \ - PREFIX##MI_ADDq , PREFIX##MI_MADDq , PREFIX##MI_ADDi , PREFIX##MI_MADDi, /* 0x20 */ \ - PREFIX##MI_SUBq , PREFIX##MI_MSUBq , PREFIX##MI_SUBi , PREFIX##MI_MSUBi, \ - PREFIX##MI_ADD , PREFIX##MI_MADD , PREFIX##MI_MUL , PREFIX##MI_MAX, \ - PREFIX##MI_SUB , PREFIX##MI_MSUB , PREFIX##MI_OPMSUB, PREFIX##MI_MINI, \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, /* 0x30 */ \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ - PREFIX##_UPPER_FD_00, PREFIX##_UPPER_FD_01, PREFIX##_UPPER_FD_10, PREFIX##_UPPER_FD_11, \ -}; \ - \ - void (*PREFIX##_UPPER_FD_00_TABLE[32])() = { \ - PREFIX##MI_ADDAx, PREFIX##MI_SUBAx , PREFIX##MI_MADDAx, PREFIX##MI_MSUBAx, \ - PREFIX##MI_ITOF0, PREFIX##MI_FTOI0, PREFIX##MI_MULAx , PREFIX##MI_MULAq , \ - PREFIX##MI_ADDAq, PREFIX##MI_SUBAq, PREFIX##MI_ADDA , PREFIX##MI_SUBA , \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , \ -}; \ - \ - void (*PREFIX##_UPPER_FD_01_TABLE[32])() = { \ - PREFIX##MI_ADDAy , PREFIX##MI_SUBAy , PREFIX##MI_MADDAy, PREFIX##MI_MSUBAy, \ - PREFIX##MI_ITOF4 , PREFIX##MI_FTOI4 , PREFIX##MI_MULAy , PREFIX##MI_ABS , \ - PREFIX##MI_MADDAq, PREFIX##MI_MSUBAq, PREFIX##MI_MADDA , PREFIX##MI_MSUBA , \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , \ -}; \ - \ - void (*PREFIX##_UPPER_FD_10_TABLE[32])() = { \ - PREFIX##MI_ADDAz , PREFIX##MI_SUBAz , PREFIX##MI_MADDAz, PREFIX##MI_MSUBAz, \ - PREFIX##MI_ITOF12, PREFIX##MI_FTOI12, PREFIX##MI_MULAz , PREFIX##MI_MULAi , \ - PREFIX##MI_ADDAi, PREFIX##MI_SUBAi , PREFIX##MI_MULA , PREFIX##MI_OPMULA, \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , \ -}; \ - \ - void (*PREFIX##_UPPER_FD_11_TABLE[32])() = { \ - PREFIX##MI_ADDAw , PREFIX##MI_SUBAw , PREFIX##MI_MADDAw, PREFIX##MI_MSUBAw, \ - PREFIX##MI_ITOF15, PREFIX##MI_FTOI15, PREFIX##MI_MULAw , PREFIX##MI_CLIP , \ - PREFIX##MI_MADDAi, PREFIX##MI_MSUBAi, PREFIX##unknown , PREFIX##MI_NOP , \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , \ -}; \ - \ - \ - \ - void PREFIX##_UPPER_FD_00() { \ - PREFIX##_UPPER_FD_00_TABLE[(VU.code >> 6) & 0x1f ](); \ -} \ - \ - void PREFIX##_UPPER_FD_01() { \ - PREFIX##_UPPER_FD_01_TABLE[(VU.code >> 6) & 0x1f](); \ -} \ - \ - void PREFIX##_UPPER_FD_10() { \ - PREFIX##_UPPER_FD_10_TABLE[(VU.code >> 6) & 0x1f](); \ -} \ - \ - void PREFIX##_UPPER_FD_11() { \ - PREFIX##_UPPER_FD_11_TABLE[(VU.code >> 6) & 0x1f](); \ -} \ - \ - void PREFIX##LowerOP() { \ - PREFIX##LowerOP_OPCODE[VU.code & 0x3f](); \ -} \ - \ - void PREFIX##LowerOP_T3_00() { \ - PREFIX##LowerOP_T3_00_OPCODE[(VU.code >> 6) & 0x1f](); \ -} \ - \ - void PREFIX##LowerOP_T3_01() { \ - PREFIX##LowerOP_T3_01_OPCODE[(VU.code >> 6) & 0x1f](); \ -} \ - \ - void PREFIX##LowerOP_T3_10() { \ - PREFIX##LowerOP_T3_10_OPCODE[(VU.code >> 6) & 0x1f](); \ -} \ - \ - void PREFIX##LowerOP_T3_11() { \ - PREFIX##LowerOP_T3_11_OPCODE[(VU.code >> 6) & 0x1f](); \ -} - -#define _vuRegsTables(VU, PREFIX) \ - \ -void (*PREFIX##_LOWER_OPCODE[128])(_VURegsNum *VUregsn) = { \ - PREFIX##MI_LQ , PREFIX##MI_SQ , PREFIX##unknown , PREFIX##unknown, \ - PREFIX##MI_ILW , PREFIX##MI_ISW , PREFIX##unknown , PREFIX##unknown, \ - PREFIX##MI_IADDIU, PREFIX##MI_ISUBIU, PREFIX##unknown , PREFIX##unknown, \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ - PREFIX##MI_FCEQ , PREFIX##MI_FCSET , PREFIX##MI_FCAND, PREFIX##MI_FCOR, /* 0x10 */ \ - PREFIX##MI_FSEQ , PREFIX##MI_FSSET , PREFIX##MI_FSAND, PREFIX##MI_FSOR, \ - PREFIX##MI_FMEQ , PREFIX##unknown , PREFIX##MI_FMAND, PREFIX##MI_FMOR, \ - PREFIX##MI_FCGET , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ - PREFIX##MI_B , PREFIX##MI_BAL , PREFIX##unknown , PREFIX##unknown, /* 0x20 */ \ - PREFIX##MI_JR , PREFIX##MI_JALR , PREFIX##unknown , PREFIX##unknown, \ - PREFIX##MI_IBEQ , PREFIX##MI_IBNE , PREFIX##unknown , PREFIX##unknown, \ - PREFIX##MI_IBLTZ , PREFIX##MI_IBGTZ , PREFIX##MI_IBLEZ, PREFIX##MI_IBGEZ, \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, /* 0x30 */ \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ - PREFIX##LowerOP , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, /* 0x40*/ \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, /* 0x50 */ \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, /* 0x60 */ \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, /* 0x70 */ \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ -}; \ - \ - void (*PREFIX##LowerOP_T3_00_OPCODE[32])(_VURegsNum *VUregsn) = { \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ - PREFIX##MI_MOVE , PREFIX##MI_LQI , PREFIX##MI_DIV , PREFIX##MI_MTIR, \ - PREFIX##MI_RNEXT , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, /* 0x10 */ \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ - PREFIX##unknown , PREFIX##MI_MFP , PREFIX##MI_XTOP , PREFIX##MI_XGKICK, \ - PREFIX##MI_ESADD , PREFIX##MI_EATANxy, PREFIX##MI_ESQRT, PREFIX##MI_ESIN, \ -}; \ - \ - void (*PREFIX##LowerOP_T3_01_OPCODE[32])(_VURegsNum *VUregsn) = { \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ - PREFIX##MI_MR32 , PREFIX##MI_SQI , PREFIX##MI_SQRT , PREFIX##MI_MFIR, \ - PREFIX##MI_RGET , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, /* 0x10 */ \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ - PREFIX##unknown , PREFIX##unknown , PREFIX##MI_XITOP, PREFIX##unknown, \ - PREFIX##MI_ERSADD, PREFIX##MI_EATANxz, PREFIX##MI_ERSQRT, PREFIX##MI_EATAN, \ -}; \ - \ - void (*PREFIX##LowerOP_T3_10_OPCODE[32])(_VURegsNum *VUregsn) = { \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ - PREFIX##unknown , PREFIX##MI_LQD , PREFIX##MI_RSQRT, PREFIX##MI_ILWR, \ - PREFIX##MI_RINIT , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, /* 0x10 */ \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ - PREFIX##MI_ELENG , PREFIX##MI_ESUM , PREFIX##MI_ERCPR, PREFIX##MI_EEXP, \ -}; \ - \ - void (*PREFIX##LowerOP_T3_11_OPCODE[32])(_VURegsNum *VUregsn) = { \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ - PREFIX##unknown , PREFIX##MI_SQD , PREFIX##MI_WAITQ, PREFIX##MI_ISWR, \ - PREFIX##MI_RXOR , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, /* 0x10 */ \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ - PREFIX##MI_ERLENG, PREFIX##unknown , PREFIX##MI_WAITP, PREFIX##unknown, \ -}; \ - \ - void (*PREFIX##LowerOP_OPCODE[64])(_VURegsNum *VUregsn) = { \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, /* 0x10 */ \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, /* 0x20 */ \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ - PREFIX##MI_IADD , PREFIX##MI_ISUB , PREFIX##MI_IADDI, PREFIX##unknown, /* 0x30 */ \ - PREFIX##MI_IAND , PREFIX##MI_IOR , PREFIX##unknown , PREFIX##unknown, \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ - PREFIX##LowerOP_T3_00, PREFIX##LowerOP_T3_01, PREFIX##LowerOP_T3_10, PREFIX##LowerOP_T3_11, \ -}; \ - \ - void (*PREFIX##_UPPER_OPCODE[64])(_VURegsNum *VUregsn) = { \ - PREFIX##MI_ADDx , PREFIX##MI_ADDy , PREFIX##MI_ADDz , PREFIX##MI_ADDw, \ - PREFIX##MI_SUBx , PREFIX##MI_SUBy , PREFIX##MI_SUBz , PREFIX##MI_SUBw, \ - PREFIX##MI_MADDx , PREFIX##MI_MADDy , PREFIX##MI_MADDz , PREFIX##MI_MADDw, \ - PREFIX##MI_MSUBx , PREFIX##MI_MSUBy , PREFIX##MI_MSUBz , PREFIX##MI_MSUBw, \ - PREFIX##MI_MAXx , PREFIX##MI_MAXy , PREFIX##MI_MAXz , PREFIX##MI_MAXw, /* 0x10 */ \ - PREFIX##MI_MINIx , PREFIX##MI_MINIy , PREFIX##MI_MINIz , PREFIX##MI_MINIw, \ - PREFIX##MI_MULx , PREFIX##MI_MULy , PREFIX##MI_MULz , PREFIX##MI_MULw, \ - PREFIX##MI_MULq , PREFIX##MI_MAXi , PREFIX##MI_MULi , PREFIX##MI_MINIi, \ - PREFIX##MI_ADDq , PREFIX##MI_MADDq , PREFIX##MI_ADDi , PREFIX##MI_MADDi, /* 0x20 */ \ - PREFIX##MI_SUBq , PREFIX##MI_MSUBq , PREFIX##MI_SUBi , PREFIX##MI_MSUBi, \ - PREFIX##MI_ADD , PREFIX##MI_MADD , PREFIX##MI_MUL , PREFIX##MI_MAX, \ - PREFIX##MI_SUB , PREFIX##MI_MSUB , PREFIX##MI_OPMSUB, PREFIX##MI_MINI, \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, /* 0x30 */ \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ - PREFIX##_UPPER_FD_00, PREFIX##_UPPER_FD_01, PREFIX##_UPPER_FD_10, PREFIX##_UPPER_FD_11, \ -}; \ - \ - void (*PREFIX##_UPPER_FD_00_TABLE[32])(_VURegsNum *VUregsn) = { \ - PREFIX##MI_ADDAx, PREFIX##MI_SUBAx , PREFIX##MI_MADDAx, PREFIX##MI_MSUBAx, \ - PREFIX##MI_ITOF0, PREFIX##MI_FTOI0, PREFIX##MI_MULAx , PREFIX##MI_MULAq , \ - PREFIX##MI_ADDAq, PREFIX##MI_SUBAq, PREFIX##MI_ADDA , PREFIX##MI_SUBA , \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , \ -}; \ - \ - void (*PREFIX##_UPPER_FD_01_TABLE[32])(_VURegsNum *VUregsn) = { \ - PREFIX##MI_ADDAy , PREFIX##MI_SUBAy , PREFIX##MI_MADDAy, PREFIX##MI_MSUBAy, \ - PREFIX##MI_ITOF4 , PREFIX##MI_FTOI4 , PREFIX##MI_MULAy , PREFIX##MI_ABS , \ - PREFIX##MI_MADDAq, PREFIX##MI_MSUBAq, PREFIX##MI_MADDA , PREFIX##MI_MSUBA , \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , \ -}; \ - \ - void (*PREFIX##_UPPER_FD_10_TABLE[32])(_VURegsNum *VUregsn) = { \ - PREFIX##MI_ADDAz , PREFIX##MI_SUBAz , PREFIX##MI_MADDAz, PREFIX##MI_MSUBAz, \ - PREFIX##MI_ITOF12, PREFIX##MI_FTOI12, PREFIX##MI_MULAz , PREFIX##MI_MULAi , \ - PREFIX##MI_ADDAi, PREFIX##MI_SUBAi , PREFIX##MI_MULA , PREFIX##MI_OPMULA, \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , \ -}; \ - \ - void (*PREFIX##_UPPER_FD_11_TABLE[32])(_VURegsNum *VUregsn) = { \ - PREFIX##MI_ADDAw , PREFIX##MI_SUBAw , PREFIX##MI_MADDAw, PREFIX##MI_MSUBAw, \ - PREFIX##MI_ITOF15, PREFIX##MI_FTOI15, PREFIX##MI_MULAw , PREFIX##MI_CLIP , \ - PREFIX##MI_MADDAi, PREFIX##MI_MSUBAi, PREFIX##unknown , PREFIX##MI_NOP , \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , \ - PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , \ -}; \ - \ - \ - \ - void PREFIX##_UPPER_FD_00(_VURegsNum *VUregsn) { \ - PREFIX##_UPPER_FD_00_TABLE[(VU.code >> 6) & 0x1f ](VUregsn); \ -} \ - \ - void PREFIX##_UPPER_FD_01(_VURegsNum *VUregsn) { \ - PREFIX##_UPPER_FD_01_TABLE[(VU.code >> 6) & 0x1f](VUregsn); \ -} \ - \ - void PREFIX##_UPPER_FD_10(_VURegsNum *VUregsn) { \ - PREFIX##_UPPER_FD_10_TABLE[(VU.code >> 6) & 0x1f](VUregsn); \ -} \ - \ - void PREFIX##_UPPER_FD_11(_VURegsNum *VUregsn) { \ - PREFIX##_UPPER_FD_11_TABLE[(VU.code >> 6) & 0x1f](VUregsn); \ -} \ - \ - void PREFIX##LowerOP(_VURegsNum *VUregsn) { \ - PREFIX##LowerOP_OPCODE[VU.code & 0x3f](VUregsn); \ -} \ - \ - void PREFIX##LowerOP_T3_00(_VURegsNum *VUregsn) { \ - PREFIX##LowerOP_T3_00_OPCODE[(VU.code >> 6) & 0x1f](VUregsn); \ -} \ - \ - void PREFIX##LowerOP_T3_01(_VURegsNum *VUregsn) { \ - PREFIX##LowerOP_T3_01_OPCODE[(VU.code >> 6) & 0x1f](VUregsn); \ -} \ - \ - void PREFIX##LowerOP_T3_10(_VURegsNum *VUregsn) { \ - PREFIX##LowerOP_T3_10_OPCODE[(VU.code >> 6) & 0x1f](VUregsn); \ -} \ - \ - void PREFIX##LowerOP_T3_11(_VURegsNum *VUregsn) { \ - PREFIX##LowerOP_T3_11_OPCODE[(VU.code >> 6) & 0x1f](VUregsn); \ -} - - #ifdef VUM_LOG #define IdebugUPPER(VU) \ diff --git a/pcsx2/VUmicroMem.cpp b/pcsx2/VUmicroMem.cpp index b61a024b33..d0aad70822 100644 --- a/pcsx2/VUmicroMem.cpp +++ b/pcsx2/VUmicroMem.cpp @@ -18,10 +18,12 @@ #include "Common.h" #include "VUmicro.h" +__aligned16 VURegs vuRegs[2]; + static u8* m_vuAllMem = NULL; static const uint m_vuMemSize = 0x1000 + // VU0micro memory - 0x4000+0x800 + // VU0 memory and VU1 registers + 0x4000 + // VU0 memory 0x4000 + // VU1 memory 0x4000; @@ -33,12 +35,9 @@ void vuMicroMemAlloc() if( m_vuAllMem == NULL ) throw Exception::OutOfMemory( L"VU0 and VU1 on-chip memory" ); - pxAssume( sizeof( VURegs ) <= 0x800 ); - u8* curpos = m_vuAllMem; VU0.Micro = curpos; curpos += 0x1000; VU0.Mem = curpos; curpos += 0x4000; - g_pVU1 = (VURegs*)curpos; curpos += 0x800; VU1.Micro = curpos; curpos += 0x4000; VU1.Mem = curpos; //curpos += 0x4000; @@ -50,7 +49,6 @@ void vuMicroMemShutdown() vtlb_free( m_vuAllMem, m_vuMemSize ); m_vuAllMem = NULL; - g_pVU1 = NULL; } void vuMicroMemReset() @@ -72,17 +70,6 @@ void vuMicroMemReset() memzero_ptr<4*1024>(VU0.Mem); memzero_ptr<4*1024>(VU0.Micro); - /* this is kinda tricky, maxmem is set to 0x4400 here, - tho it's not 100% accurate, since the mem goes from - 0x0000 - 0x1000 (Mem) and 0x4000 - 0x4400 (VU1 Regs), - i guess it shouldn't be a problem, - at least hope so :) (linuz) - */ - VU0.maxmem = 0x4800-4; //We are allocating 0x800 for vu1 reg's - VU0.maxmicro = 0x1000-4; - VU0.vuExec = vu0Exec; - VU0.vifRegs = vif0Regs; - // === VU1 Initialization === memzero(VU1.ACC); memzero(VU1.VF); @@ -94,13 +81,6 @@ void vuMicroMemReset() VU1.VI[0].UL = 0; memzero_ptr<16*1024>(VU1.Mem); memzero_ptr<16*1024>(VU1.Micro); - - VU1.maxmem = 0x4000-4;//16*1024-4; - VU1.maxmicro = 0x4000-4; -// VU1.VF = (VECTOR*)(VU0.Mem + 0x4000); -// VU1.VI = (REG_VI*)(VU0.Mem + 0x4200); - VU1.vuExec = vu1Exec; - VU1.vifRegs = vif1Regs; } void SaveStateBase::vuMicroFreeze() diff --git a/pcsx2/VUops.cpp b/pcsx2/VUops.cpp index f3fc402fc6..ac20e72d88 100644 --- a/pcsx2/VUops.cpp +++ b/pcsx2/VUops.cpp @@ -15,12 +15,11 @@ #include "PrecompiledHeader.h" #include "Common.h" - -#include - #include "VUops.h" #include "GS.h" +#include + //Lower/Upper instructions can use that.. #define _Ft_ ((VU->code >> 16) & 0x1F) // The rt part of the instruction register #define _Fs_ ((VU->code >> 11) & 0x1F) // The rd part of the instruction register @@ -348,7 +347,7 @@ void _vuABS(VURegs * VU) { }/*Reworked from define to function. asadr*/ -void _vuADD(VURegs * VU) { +static __fi void _vuADD(VURegs * VU) { VECTOR * dst; if (_Fd_ == 0) dst = &RDzero; else dst = &VU->VF[_Fd_]; @@ -361,7 +360,7 @@ void _vuADD(VURegs * VU) { }/*Reworked from define to function. asadr*/ -void _vuADDi(VURegs * VU) { +static __fi void _vuADDi(VURegs * VU) { VECTOR * dst; if (_Fd_ == 0) dst = &RDzero; else dst = &VU->VF[_Fd_]; @@ -373,7 +372,7 @@ void _vuADDi(VURegs * VU) { VU_STAT_UPDATE(VU); }/*Reworked from define to function. asadr*/ -void _vuADDq(VURegs * VU) { +static __fi void _vuADDq(VURegs * VU) { VECTOR * dst; if (_Fd_ == 0) dst = &RDzero; else dst = &VU->VF[_Fd_]; @@ -386,7 +385,7 @@ void _vuADDq(VURegs * VU) { }/*Reworked from define to function. asadr*/ -void _vuADDx(VURegs * VU) { +static __fi void _vuADDx(VURegs * VU) { float ftx; VECTOR * dst; if (_Fd_ == 0) dst = &RDzero; @@ -400,7 +399,7 @@ void _vuADDx(VURegs * VU) { VU_STAT_UPDATE(VU); }/*Reworked from define to function. asadr*/ -void _vuADDy(VURegs * VU) { +static __fi void _vuADDy(VURegs * VU) { float fty; VECTOR * dst; if (_Fd_ == 0) dst = &RDzero; @@ -414,7 +413,7 @@ void _vuADDy(VURegs * VU) { VU_STAT_UPDATE(VU); }/*Reworked from define to function. asadr*/ -void _vuADDz(VURegs * VU) { +static __fi void _vuADDz(VURegs * VU) { float ftz; VECTOR * dst; if (_Fd_ == 0) dst = &RDzero; @@ -428,7 +427,7 @@ void _vuADDz(VURegs * VU) { VU_STAT_UPDATE(VU); }/*Reworked from define to function. asadr*/ -void _vuADDw(VURegs * VU) { +static __fi void _vuADDw(VURegs * VU) { float ftw; VECTOR * dst; if (_Fd_ == 0) dst = &RDzero; @@ -442,7 +441,7 @@ void _vuADDw(VURegs * VU) { VU_STAT_UPDATE(VU); }/*Reworked from define to function. asadr*/ -void _vuADDA(VURegs * VU) { +static __fi void _vuADDA(VURegs * VU) { if (_X){ VU->ACC.i.x = VU_MACx_UPDATE(VU, vuDouble(VU->VF[_Fs_].i.x) + vuDouble(VU->VF[_Ft_].i.x)); } else VU_MACx_CLEAR(VU); if (_Y){ VU->ACC.i.y = VU_MACy_UPDATE(VU, vuDouble(VU->VF[_Fs_].i.y) + vuDouble(VU->VF[_Ft_].i.y)); } else VU_MACy_CLEAR(VU); if (_Z){ VU->ACC.i.z = VU_MACz_UPDATE(VU, vuDouble(VU->VF[_Fs_].i.z) + vuDouble(VU->VF[_Ft_].i.z)); } else VU_MACz_CLEAR(VU); @@ -450,7 +449,7 @@ void _vuADDA(VURegs * VU) { VU_STAT_UPDATE(VU); }/*Reworked from define to function. asadr*/ -void _vuADDAi(VURegs * VU) { +static __fi void _vuADDAi(VURegs * VU) { float ti = vuDouble(VU->VI[REG_I].UL); if (_X){ VU->ACC.i.x = VU_MACx_UPDATE(VU, vuDouble(VU->VF[_Fs_].i.x) + ti); } else VU_MACx_CLEAR(VU); @@ -460,7 +459,7 @@ void _vuADDAi(VURegs * VU) { VU_STAT_UPDATE(VU); }/*Reworked from define to function. asadr*/ -void _vuADDAq(VURegs * VU) { +static __fi void _vuADDAq(VURegs * VU) { float tf = vuDouble(VU->VI[REG_Q].UL); if (_X){ VU->ACC.i.x = VU_MACx_UPDATE(VU, vuDouble(VU->VF[_Fs_].i.x) + tf); } else VU_MACx_CLEAR(VU); @@ -470,7 +469,7 @@ void _vuADDAq(VURegs * VU) { VU_STAT_UPDATE(VU); }/*Reworked from define to function. asadr*/ -void _vuADDAx(VURegs * VU) { +static __fi void _vuADDAx(VURegs * VU) { float tx = vuDouble(VU->VF[_Ft_].i.x); if (_X){ VU->ACC.i.x = VU_MACx_UPDATE(VU, vuDouble(VU->VF[_Fs_].i.x) + tx); } else VU_MACx_CLEAR(VU); @@ -480,7 +479,7 @@ void _vuADDAx(VURegs * VU) { VU_STAT_UPDATE(VU); }/*Reworked from define to function. asadr*/ -void _vuADDAy(VURegs * VU) { +static __fi void _vuADDAy(VURegs * VU) { float ty = vuDouble(VU->VF[_Ft_].i.y); if (_X){ VU->ACC.i.x = VU_MACx_UPDATE(VU, vuDouble(VU->VF[_Fs_].i.x) + ty); } else VU_MACx_CLEAR(VU); @@ -490,7 +489,7 @@ void _vuADDAy(VURegs * VU) { VU_STAT_UPDATE(VU); }/*Reworked from define to function. asadr*/ -void _vuADDAz(VURegs * VU) { +static __fi void _vuADDAz(VURegs * VU) { float tz = vuDouble(VU->VF[_Ft_].i.z); if (_X){ VU->ACC.i.x = VU_MACx_UPDATE(VU, vuDouble(VU->VF[_Fs_].i.x) + tz); } else VU_MACx_CLEAR(VU); @@ -500,7 +499,7 @@ void _vuADDAz(VURegs * VU) { VU_STAT_UPDATE(VU); }/*Reworked from define to function. asadr*/ -void _vuADDAw(VURegs * VU) { +static __fi void _vuADDAw(VURegs * VU) { float tw = vuDouble(VU->VF[_Ft_].i.w); if (_X){ VU->ACC.i.x = VU_MACx_UPDATE(VU, vuDouble(VU->VF[_Fs_].i.x) + tw); } else VU_MACx_CLEAR(VU); @@ -511,7 +510,7 @@ void _vuADDAw(VURegs * VU) { }/*Reworked from define to function. asadr*/ -void _vuSUB(VURegs * VU) { +static __fi void _vuSUB(VURegs * VU) { VECTOR * dst; if (_Fd_ == 0) dst = &RDzero; else dst = &VU->VF[_Fd_]; @@ -523,7 +522,7 @@ void _vuSUB(VURegs * VU) { VU_STAT_UPDATE(VU); }//updated 10/05/03 shadow -void _vuSUBi(VURegs * VU) { +static __fi void _vuSUBi(VURegs * VU) { VECTOR * dst; if (_Fd_ == 0) dst = &RDzero; else dst = &VU->VF[_Fd_]; @@ -535,7 +534,7 @@ void _vuSUBi(VURegs * VU) { VU_STAT_UPDATE(VU); }//updated 10/05/03 shadow -void _vuSUBq(VURegs * VU) { +static __fi void _vuSUBq(VURegs * VU) { VECTOR * dst; if (_Fd_ == 0) dst = &RDzero; else dst = &VU->VF[_Fd_]; @@ -547,7 +546,7 @@ void _vuSUBq(VURegs * VU) { VU_STAT_UPDATE(VU); }//updated 10/05/03 shadow -void _vuSUBx(VURegs * VU) { +static __fi void _vuSUBx(VURegs * VU) { float ftx; VECTOR * dst; if (_Fd_ == 0) dst = &RDzero; @@ -561,7 +560,7 @@ void _vuSUBx(VURegs * VU) { VU_STAT_UPDATE(VU); }//updated 10/05/03 shadow -void _vuSUBy(VURegs * VU) { +static __fi void _vuSUBy(VURegs * VU) { float fty; VECTOR * dst; if (_Fd_ == 0) dst = &RDzero; @@ -575,7 +574,7 @@ void _vuSUBy(VURegs * VU) { VU_STAT_UPDATE(VU); }//updated 10/05/03 shadow -void _vuSUBz(VURegs * VU) { +static __fi void _vuSUBz(VURegs * VU) { float ftz; VECTOR * dst; if (_Fd_ == 0) dst = &RDzero; @@ -589,7 +588,7 @@ void _vuSUBz(VURegs * VU) { VU_STAT_UPDATE(VU); }//updated 10/05/03 shadow -void _vuSUBw(VURegs * VU) { +static __fi void _vuSUBw(VURegs * VU) { float ftw; VECTOR * dst; if (_Fd_ == 0) dst = &RDzero; @@ -604,7 +603,7 @@ void _vuSUBw(VURegs * VU) { }//updated 10/05/03 shadow -void _vuSUBA(VURegs * VU) { +static __fi void _vuSUBA(VURegs * VU) { if (_X){ VU->ACC.i.x = VU_MACx_UPDATE(VU, vuDouble(VU->VF[_Fs_].i.x) - vuDouble(VU->VF[_Ft_].i.x)); } else VU_MACx_CLEAR(VU); if (_Y){ VU->ACC.i.y = VU_MACy_UPDATE(VU, vuDouble(VU->VF[_Fs_].i.y) - vuDouble(VU->VF[_Ft_].i.y)); } else VU_MACy_CLEAR(VU); if (_Z){ VU->ACC.i.z = VU_MACz_UPDATE(VU, vuDouble(VU->VF[_Fs_].i.z) - vuDouble(VU->VF[_Ft_].i.z)); } else VU_MACz_CLEAR(VU); @@ -612,7 +611,7 @@ void _vuSUBA(VURegs * VU) { VU_STAT_UPDATE(VU); }//updated 10/05/03 shadow -void _vuSUBAi(VURegs * VU) { +static __fi void _vuSUBAi(VURegs * VU) { if (_X){ VU->ACC.i.x = VU_MACx_UPDATE(VU, vuDouble(VU->VF[_Fs_].i.x) - vuDouble(VU->VI[REG_I].UL)); } else VU_MACx_CLEAR(VU); if (_Y){ VU->ACC.i.y = VU_MACy_UPDATE(VU, vuDouble(VU->VF[_Fs_].i.y) - vuDouble(VU->VI[REG_I].UL)); } else VU_MACy_CLEAR(VU); if (_Z){ VU->ACC.i.z = VU_MACz_UPDATE(VU, vuDouble(VU->VF[_Fs_].i.z) - vuDouble(VU->VI[REG_I].UL)); } else VU_MACz_CLEAR(VU); @@ -620,7 +619,7 @@ void _vuSUBAi(VURegs * VU) { VU_STAT_UPDATE(VU); }//updated 10/05/03 shadow -void _vuSUBAq(VURegs * VU) { +static __fi void _vuSUBAq(VURegs * VU) { if (_X){ VU->ACC.i.x = VU_MACx_UPDATE(VU, vuDouble(VU->VF[_Fs_].i.x) - vuDouble(VU->VI[REG_Q].UL)); } else VU_MACx_CLEAR(VU); if (_Y){ VU->ACC.i.y = VU_MACy_UPDATE(VU, vuDouble(VU->VF[_Fs_].i.y) - vuDouble(VU->VI[REG_Q].UL)); } else VU_MACy_CLEAR(VU); if (_Z){ VU->ACC.i.z = VU_MACz_UPDATE(VU, vuDouble(VU->VF[_Fs_].i.z) - vuDouble(VU->VI[REG_Q].UL)); } else VU_MACz_CLEAR(VU); @@ -628,7 +627,7 @@ void _vuSUBAq(VURegs * VU) { VU_STAT_UPDATE(VU); }//updated 10/05/03 shadow -void _vuSUBAx(VURegs * VU) { +static __fi void _vuSUBAx(VURegs * VU) { float tx = vuDouble(VU->VF[_Ft_].i.x); if (_X){ VU->ACC.i.x = VU_MACx_UPDATE(VU, vuDouble(VU->VF[_Fs_].i.x) - tx); } else VU_MACx_CLEAR(VU); @@ -638,7 +637,7 @@ void _vuSUBAx(VURegs * VU) { VU_STAT_UPDATE(VU); }//updated 10/05/03 shadow -void _vuSUBAy(VURegs * VU) { +static __fi void _vuSUBAy(VURegs * VU) { float ty = vuDouble(VU->VF[_Ft_].i.y); if (_X){ VU->ACC.i.x = VU_MACx_UPDATE(VU, vuDouble(VU->VF[_Fs_].i.x) - ty); } else VU_MACx_CLEAR(VU); @@ -648,7 +647,7 @@ void _vuSUBAy(VURegs * VU) { VU_STAT_UPDATE(VU); }//updated 10/05/03 shadow -void _vuSUBAz(VURegs * VU) { +static __fi void _vuSUBAz(VURegs * VU) { float tz = vuDouble(VU->VF[_Ft_].i.z); if (_X){ VU->ACC.i.x = VU_MACx_UPDATE(VU, vuDouble(VU->VF[_Fs_].i.x) - tz); } else VU_MACx_CLEAR(VU); @@ -658,7 +657,7 @@ void _vuSUBAz(VURegs * VU) { VU_STAT_UPDATE(VU); }//updated 10/05/03 shadow -void _vuSUBAw(VURegs * VU) { +static __fi void _vuSUBAw(VURegs * VU) { float tw = vuDouble(VU->VF[_Ft_].i.w); if (_X){ VU->ACC.i.x = VU_MACx_UPDATE(VU, vuDouble(VU->VF[_Fs_].i.x) - tw); } else VU_MACx_CLEAR(VU); @@ -668,7 +667,7 @@ void _vuSUBAw(VURegs * VU) { VU_STAT_UPDATE(VU); }//updated 10/05/03 shadow -void _vuMUL(VURegs * VU) { +static __fi void _vuMUL(VURegs * VU) { VECTOR * dst; if (_Fd_ == 0) dst = &RDzero; else dst = &VU->VF[_Fd_]; @@ -681,7 +680,7 @@ void _vuMUL(VURegs * VU) { }/* last update 8/05/03 shadow */ /* No need to presave I reg in ti. asadr */ -void _vuMULi(VURegs * VU) { +static __fi void _vuMULi(VURegs * VU) { VECTOR * dst; if (_Fd_ == 0) dst = &RDzero; else dst = &VU->VF[_Fd_]; @@ -693,7 +692,7 @@ void _vuMULi(VURegs * VU) { VU_STAT_UPDATE(VU); }/* last update 8/05/03 shadow */ -void _vuMULq(VURegs * VU) { +static __fi void _vuMULq(VURegs * VU) { VECTOR * dst; if (_Fd_ == 0) dst = &RDzero; else dst = &VU->VF[_Fd_]; @@ -705,7 +704,7 @@ void _vuMULq(VURegs * VU) { VU_STAT_UPDATE(VU); }/* last update 8/05/03 shadow */ -void _vuMULx(VURegs * VU) { +static __fi void _vuMULx(VURegs * VU) { float ftx; VECTOR * dst; if (_Fd_ == 0) dst = &RDzero; @@ -720,7 +719,7 @@ void _vuMULx(VURegs * VU) { }/* last update 8/05/03 shadow */ -void _vuMULy(VURegs * VU) { +static __fi void _vuMULy(VURegs * VU) { float fty; VECTOR * dst; if (_Fd_ == 0) dst = &RDzero; @@ -734,7 +733,7 @@ void _vuMULy(VURegs * VU) { VU_STAT_UPDATE(VU); }/* last update 8/05/03 shadow */ -void _vuMULz(VURegs * VU) { +static __fi void _vuMULz(VURegs * VU) { float ftz; VECTOR * dst; if (_Fd_ == 0) dst = &RDzero; @@ -748,7 +747,7 @@ void _vuMULz(VURegs * VU) { VU_STAT_UPDATE(VU); }/* last update 8/05/03 shadow */ -void _vuMULw(VURegs * VU) { +static __fi void _vuMULw(VURegs * VU) { float ftw; VECTOR * dst; if (_Fd_ == 0) dst = &RDzero; @@ -763,7 +762,7 @@ void _vuMULw(VURegs * VU) { }/* last update 8/05/03 shadow */ -void _vuMULA(VURegs * VU) { +static __fi void _vuMULA(VURegs * VU) { if (_X){ VU->ACC.i.x = VU_MACx_UPDATE(VU, vuDouble(VU->VF[_Fs_].i.x) * vuDouble(VU->VF[_Ft_].i.x)); } else VU_MACx_CLEAR(VU); if (_Y){ VU->ACC.i.y = VU_MACy_UPDATE(VU, vuDouble(VU->VF[_Fs_].i.y) * vuDouble(VU->VF[_Ft_].i.y)); } else VU_MACy_CLEAR(VU); if (_Z){ VU->ACC.i.z = VU_MACz_UPDATE(VU, vuDouble(VU->VF[_Fs_].i.z) * vuDouble(VU->VF[_Ft_].i.z)); } else VU_MACz_CLEAR(VU); @@ -772,7 +771,7 @@ void _vuMULA(VURegs * VU) { }/* last update 8/05/03 shadow */ /* No need to presave I reg in ti. asadr */ -void _vuMULAi(VURegs * VU) { +static __fi void _vuMULAi(VURegs * VU) { if (_X){ VU->ACC.i.x = VU_MACx_UPDATE(VU, vuDouble(VU->VF[_Fs_].i.x) * vuDouble(VU->VI[REG_I].UL)); } else VU_MACx_CLEAR(VU); if (_Y){ VU->ACC.i.y = VU_MACy_UPDATE(VU, vuDouble(VU->VF[_Fs_].i.y) * vuDouble(VU->VI[REG_I].UL)); } else VU_MACy_CLEAR(VU); if (_Z){ VU->ACC.i.z = VU_MACz_UPDATE(VU, vuDouble(VU->VF[_Fs_].i.z) * vuDouble(VU->VI[REG_I].UL)); } else VU_MACz_CLEAR(VU); @@ -781,7 +780,7 @@ void _vuMULAi(VURegs * VU) { }/* last update 8/05/03 shadow */ /* No need to presave Q reg in ti. asadr */ -void _vuMULAq(VURegs * VU) { +static __fi void _vuMULAq(VURegs * VU) { if (_X){ VU->ACC.i.x = VU_MACx_UPDATE(VU, vuDouble(VU->VF[_Fs_].i.x) * vuDouble(VU->VI[REG_Q].UL)); } else VU_MACx_CLEAR(VU); if (_Y){ VU->ACC.i.y = VU_MACy_UPDATE(VU, vuDouble(VU->VF[_Fs_].i.y) * vuDouble(VU->VI[REG_Q].UL)); } else VU_MACy_CLEAR(VU); if (_Z){ VU->ACC.i.z = VU_MACz_UPDATE(VU, vuDouble(VU->VF[_Fs_].i.z) * vuDouble(VU->VI[REG_Q].UL)); } else VU_MACz_CLEAR(VU); @@ -790,7 +789,7 @@ void _vuMULAq(VURegs * VU) { }/* last update 8/05/03 shadow */ /* No need to presave X reg in ti. asadr */ -void _vuMULAx(VURegs * VU) { +static __fi void _vuMULAx(VURegs * VU) { if (_X){ VU->ACC.i.x = VU_MACx_UPDATE(VU, vuDouble(VU->VF[_Fs_].i.x) * vuDouble(VU->VF[_Ft_].i.x)); } else VU_MACx_CLEAR(VU); if (_Y){ VU->ACC.i.y = VU_MACy_UPDATE(VU, vuDouble(VU->VF[_Fs_].i.y) * vuDouble(VU->VF[_Ft_].i.x)); } else VU_MACy_CLEAR(VU); if (_Z){ VU->ACC.i.z = VU_MACz_UPDATE(VU, vuDouble(VU->VF[_Fs_].i.z) * vuDouble(VU->VF[_Ft_].i.x)); } else VU_MACz_CLEAR(VU); @@ -798,7 +797,7 @@ void _vuMULAx(VURegs * VU) { VU_STAT_UPDATE(VU); }/* last update 8/05/03 shadow */ -void _vuMULAy(VURegs * VU) { +static __fi void _vuMULAy(VURegs * VU) { if (_X){ VU->ACC.i.x = VU_MACx_UPDATE(VU, vuDouble(VU->VF[_Fs_].i.x) * vuDouble(VU->VF[_Ft_].i.y)); } else VU_MACx_CLEAR(VU); if (_Y){ VU->ACC.i.y = VU_MACy_UPDATE(VU, vuDouble(VU->VF[_Fs_].i.y) * vuDouble(VU->VF[_Ft_].i.y)); } else VU_MACy_CLEAR(VU); if (_Z){ VU->ACC.i.z = VU_MACz_UPDATE(VU, vuDouble(VU->VF[_Fs_].i.z) * vuDouble(VU->VF[_Ft_].i.y)); } else VU_MACz_CLEAR(VU); @@ -806,7 +805,7 @@ void _vuMULAy(VURegs * VU) { VU_STAT_UPDATE(VU); }/* last update 8/05/03 shadow */ -void _vuMULAz(VURegs * VU) { +static __fi void _vuMULAz(VURegs * VU) { if (_X){ VU->ACC.i.x = VU_MACx_UPDATE(VU, vuDouble(VU->VF[_Fs_].i.x) * vuDouble(VU->VF[_Ft_].i.z)); } else VU_MACx_CLEAR(VU); if (_Y){ VU->ACC.i.y = VU_MACy_UPDATE(VU, vuDouble(VU->VF[_Fs_].i.y) * vuDouble(VU->VF[_Ft_].i.z)); } else VU_MACy_CLEAR(VU); if (_Z){ VU->ACC.i.z = VU_MACz_UPDATE(VU, vuDouble(VU->VF[_Fs_].i.z) * vuDouble(VU->VF[_Ft_].i.z)); } else VU_MACz_CLEAR(VU); @@ -814,7 +813,7 @@ void _vuMULAz(VURegs * VU) { VU_STAT_UPDATE(VU); }/* last update 8/05/03 shadow */ -void _vuMULAw(VURegs * VU) { +static __fi void _vuMULAw(VURegs * VU) { if (_X){ VU->ACC.i.x = VU_MACx_UPDATE(VU, vuDouble(VU->VF[_Fs_].i.x) * vuDouble(VU->VF[_Ft_].i.w)); } else VU_MACx_CLEAR(VU); if (_Y){ VU->ACC.i.y = VU_MACy_UPDATE(VU, vuDouble(VU->VF[_Fs_].i.y) * vuDouble(VU->VF[_Ft_].i.w)); } else VU_MACy_CLEAR(VU); if (_Z){ VU->ACC.i.z = VU_MACz_UPDATE(VU, vuDouble(VU->VF[_Fs_].i.z) * vuDouble(VU->VF[_Ft_].i.w)); } else VU_MACz_CLEAR(VU); @@ -822,7 +821,7 @@ void _vuMULAw(VURegs * VU) { VU_STAT_UPDATE(VU); }/* last update 8/05/03 shadow */ -void _vuMADD(VURegs * VU) { +static __fi void _vuMADD(VURegs * VU) { VECTOR * dst; if (_Fd_ == 0) dst = &RDzero; else dst = &VU->VF[_Fd_]; @@ -835,7 +834,7 @@ void _vuMADD(VURegs * VU) { }/* last update 10/05/03 shadow */ -void _vuMADDi(VURegs * VU) { +static __fi void _vuMADDi(VURegs * VU) { VECTOR * dst; if (_Fd_ == 0) dst = &RDzero; else dst = &VU->VF[_Fd_]; @@ -848,7 +847,7 @@ void _vuMADDi(VURegs * VU) { }/* last update 10/05/03 shadow */ /* No need to presave . asadr */ -void _vuMADDq(VURegs * VU) { +static __fi void _vuMADDq(VURegs * VU) { VECTOR * dst; if (_Fd_ == 0) dst = &RDzero; else dst = &VU->VF[_Fd_]; @@ -860,7 +859,7 @@ void _vuMADDq(VURegs * VU) { VU_STAT_UPDATE(VU); }/* last update 10/05/03 shadow */ -void _vuMADDx(VURegs * VU) { +static __fi void _vuMADDx(VURegs * VU) { float ftx; VECTOR * dst; if (_Fd_ == 0) dst = &RDzero; @@ -874,7 +873,7 @@ void _vuMADDx(VURegs * VU) { VU_STAT_UPDATE(VU); }/* last update 10/05/03 shadow */ -void _vuMADDy(VURegs * VU) { +static __fi void _vuMADDy(VURegs * VU) { float fty; VECTOR * dst; if (_Fd_ == 0) dst = &RDzero; @@ -888,7 +887,7 @@ void _vuMADDy(VURegs * VU) { VU_STAT_UPDATE(VU); }/* last update 10/05/03 shadow */ -void _vuMADDz(VURegs * VU) { +static __fi void _vuMADDz(VURegs * VU) { float ftz; VECTOR * dst; if (_Fd_ == 0) dst = &RDzero; @@ -902,7 +901,7 @@ void _vuMADDz(VURegs * VU) { VU_STAT_UPDATE(VU); }/* last update 10/05/03 shadow */ -void _vuMADDw(VURegs * VU) { +static __fi void _vuMADDw(VURegs * VU) { float ftw; VECTOR * dst; if (_Fd_ == 0) dst = &RDzero; @@ -916,7 +915,7 @@ void _vuMADDw(VURegs * VU) { VU_STAT_UPDATE(VU); }/* last update 10/05/03 shadow */ -void _vuMADDA(VURegs * VU) { +static __fi void _vuMADDA(VURegs * VU) { if (_X) VU->ACC.i.x = VU_MACx_UPDATE(VU, vuDouble(VU->ACC.i.x) + (vuDouble(VU->VF[_Fs_].i.x) * vuDouble(VU->VF[_Ft_].i.x))); else VU_MACx_CLEAR(VU); if (_Y) VU->ACC.i.y = VU_MACy_UPDATE(VU, vuDouble(VU->ACC.i.y) + (vuDouble(VU->VF[_Fs_].i.y) * vuDouble(VU->VF[_Ft_].i.y))); else VU_MACy_CLEAR(VU); if (_Z) VU->ACC.i.z = VU_MACz_UPDATE(VU, vuDouble(VU->ACC.i.z) + (vuDouble(VU->VF[_Fs_].i.z) * vuDouble(VU->VF[_Ft_].i.z))); else VU_MACz_CLEAR(VU); @@ -924,7 +923,7 @@ void _vuMADDA(VURegs * VU) { VU_STAT_UPDATE(VU); }/*last updated 10/05/03 shadow*/ -void _vuMADDAi(VURegs * VU) { +static __fi void _vuMADDAi(VURegs * VU) { float ti = vuDouble(VU->VI[REG_I].UL); if (_X) VU->ACC.i.x = VU_MACx_UPDATE(VU, vuDouble(VU->ACC.i.x) + ( vuDouble(VU->VF[_Fs_].i.x) * ti)); else VU_MACx_CLEAR(VU); @@ -934,7 +933,7 @@ void _vuMADDAi(VURegs * VU) { VU_STAT_UPDATE(VU); }/*last updated 10/05/03 shadow*/ -void _vuMADDAq(VURegs * VU) { +static __fi void _vuMADDAq(VURegs * VU) { float tq = vuDouble(VU->VI[REG_Q].UL); if (_X) VU->ACC.i.x = VU_MACx_UPDATE(VU, vuDouble(VU->ACC.i.x) + ( vuDouble(VU->VF[_Fs_].i.x) * tq)); else VU_MACx_CLEAR(VU); @@ -944,7 +943,7 @@ void _vuMADDAq(VURegs * VU) { VU_STAT_UPDATE(VU); }/*last update 10/05/03 shadow*/ -void _vuMADDAx(VURegs * VU) { +static __fi void _vuMADDAx(VURegs * VU) { if (_X) VU->ACC.i.x = VU_MACx_UPDATE(VU, vuDouble(VU->ACC.i.x) + ( vuDouble(VU->VF[_Fs_].i.x) * vuDouble(VU->VF[_Ft_].i.x))); else VU_MACx_CLEAR(VU); if (_Y) VU->ACC.i.y = VU_MACy_UPDATE(VU, vuDouble(VU->ACC.i.y) + ( vuDouble(VU->VF[_Fs_].i.y) * vuDouble(VU->VF[_Ft_].i.x))); else VU_MACy_CLEAR(VU); if (_Z) VU->ACC.i.z = VU_MACz_UPDATE(VU, vuDouble(VU->ACC.i.z) + ( vuDouble(VU->VF[_Fs_].i.z) * vuDouble(VU->VF[_Ft_].i.x))); else VU_MACz_CLEAR(VU); @@ -952,7 +951,7 @@ void _vuMADDAx(VURegs * VU) { VU_STAT_UPDATE(VU); }/*last update 11/05/03 shadow*/ -void _vuMADDAy(VURegs * VU) { +static __fi void _vuMADDAy(VURegs * VU) { if (_X) VU->ACC.i.x = VU_MACx_UPDATE(VU, vuDouble(VU->ACC.i.x) + ( vuDouble(VU->VF[_Fs_].i.x) * vuDouble(VU->VF[_Ft_].i.y))); else VU_MACx_CLEAR(VU); if (_Y) VU->ACC.i.y = VU_MACy_UPDATE(VU, vuDouble(VU->ACC.i.y) + ( vuDouble(VU->VF[_Fs_].i.y) * vuDouble(VU->VF[_Ft_].i.y))); else VU_MACy_CLEAR(VU); if (_Z) VU->ACC.i.z = VU_MACz_UPDATE(VU, vuDouble(VU->ACC.i.z) + ( vuDouble(VU->VF[_Fs_].i.z) * vuDouble(VU->VF[_Ft_].i.y))); else VU_MACz_CLEAR(VU); @@ -960,7 +959,7 @@ void _vuMADDAy(VURegs * VU) { VU_STAT_UPDATE(VU); }/*last update 11/05/03 shadow*/ -void _vuMADDAz(VURegs * VU) { +static __fi void _vuMADDAz(VURegs * VU) { if (_X) VU->ACC.i.x = VU_MACx_UPDATE(VU, vuDouble(VU->ACC.i.x) + ( vuDouble(VU->VF[_Fs_].i.x) * vuDouble(VU->VF[_Ft_].i.z))); else VU_MACx_CLEAR(VU); if (_Y) VU->ACC.i.y = VU_MACy_UPDATE(VU, vuDouble(VU->ACC.i.y) + ( vuDouble(VU->VF[_Fs_].i.y) * vuDouble(VU->VF[_Ft_].i.z))); else VU_MACy_CLEAR(VU); if (_Z) VU->ACC.i.z = VU_MACz_UPDATE(VU, vuDouble(VU->ACC.i.z) + ( vuDouble(VU->VF[_Fs_].i.z) * vuDouble(VU->VF[_Ft_].i.z))); else VU_MACz_CLEAR(VU); @@ -968,7 +967,7 @@ void _vuMADDAz(VURegs * VU) { VU_STAT_UPDATE(VU); }/*last update 11/05/03 shadow*/ -void _vuMADDAw(VURegs * VU) { +static __fi void _vuMADDAw(VURegs * VU) { if (_X) VU->ACC.i.x = VU_MACx_UPDATE(VU, vuDouble(VU->ACC.i.x) + ( vuDouble(VU->VF[_Fs_].i.x) * vuDouble(VU->VF[_Ft_].i.w))); else VU_MACx_CLEAR(VU); if (_Y) VU->ACC.i.y = VU_MACy_UPDATE(VU, vuDouble(VU->ACC.i.y) + ( vuDouble(VU->VF[_Fs_].i.y) * vuDouble(VU->VF[_Ft_].i.w))); else VU_MACy_CLEAR(VU); if (_Z) VU->ACC.i.z = VU_MACz_UPDATE(VU, vuDouble(VU->ACC.i.z) + ( vuDouble(VU->VF[_Fs_].i.z) * vuDouble(VU->VF[_Ft_].i.w))); else VU_MACz_CLEAR(VU); @@ -976,7 +975,7 @@ void _vuMADDAw(VURegs * VU) { VU_STAT_UPDATE(VU); }/*last update 11/05/03 shadow*/ -void _vuMSUB(VURegs * VU) { +static __fi void _vuMSUB(VURegs * VU) { VECTOR * dst; if (_Fd_ == 0) dst = &RDzero; else dst = &VU->VF[_Fd_]; @@ -988,7 +987,7 @@ void _vuMSUB(VURegs * VU) { VU_STAT_UPDATE(VU); }/* last update 11/05/03 shadow */ -void _vuMSUBi(VURegs * VU) { +static __fi void _vuMSUBi(VURegs * VU) { float ti = vuDouble(VU->VI[REG_I].UL); VECTOR * dst; if (_Fd_ == 0) dst = &RDzero; @@ -1001,7 +1000,7 @@ void _vuMSUBi(VURegs * VU) { VU_STAT_UPDATE(VU); }/* last update 11/05/03 shadow */ -void _vuMSUBq(VURegs * VU) { +static __fi void _vuMSUBq(VURegs * VU) { float tq = vuDouble(VU->VI[REG_Q].UL); VECTOR * dst; if (_Fd_ == 0) dst = &RDzero; @@ -1015,7 +1014,7 @@ void _vuMSUBq(VURegs * VU) { }/* last update 11/05/03 shadow */ -void _vuMSUBx(VURegs * VU) { +static __fi void _vuMSUBx(VURegs * VU) { float ftx; VECTOR * dst; if (_Fd_ == 0) dst = &RDzero; @@ -1030,7 +1029,7 @@ void _vuMSUBx(VURegs * VU) { }/* last update 11/05/03 shadow */ -void _vuMSUBy(VURegs * VU) { +static __fi void _vuMSUBy(VURegs * VU) { float fty; VECTOR * dst; if (_Fd_ == 0) dst = &RDzero; @@ -1045,7 +1044,7 @@ void _vuMSUBy(VURegs * VU) { }/* last update 11/05/03 shadow */ -void _vuMSUBz(VURegs * VU) { +static __fi void _vuMSUBz(VURegs * VU) { float ftz; VECTOR * dst; if (_Fd_ == 0) dst = &RDzero; @@ -1059,7 +1058,7 @@ void _vuMSUBz(VURegs * VU) { VU_STAT_UPDATE(VU); }/* last update 11/05/03 shadow */ -void _vuMSUBw(VURegs * VU) { +static __fi void _vuMSUBw(VURegs * VU) { float ftw; VECTOR * dst; if (_Fd_ == 0) dst = &RDzero; @@ -1074,7 +1073,7 @@ void _vuMSUBw(VURegs * VU) { }/* last update 11/05/03 shadow */ -void _vuMSUBA(VURegs * VU) { +static __fi void _vuMSUBA(VURegs * VU) { if (_X) VU->ACC.i.x = VU_MACx_UPDATE(VU, vuDouble(VU->ACC.i.x) - ( vuDouble(VU->VF[_Fs_].i.x) * vuDouble(VU->VF[_Ft_].i.x))); else VU_MACx_CLEAR(VU); if (_Y) VU->ACC.i.y = VU_MACy_UPDATE(VU, vuDouble(VU->ACC.i.y) - ( vuDouble(VU->VF[_Fs_].i.y) * vuDouble(VU->VF[_Ft_].i.y))); else VU_MACy_CLEAR(VU); if (_Z) VU->ACC.i.z = VU_MACz_UPDATE(VU, vuDouble(VU->ACC.i.z) - ( vuDouble(VU->VF[_Fs_].i.z) * vuDouble(VU->VF[_Ft_].i.z))); else VU_MACz_CLEAR(VU); @@ -1082,7 +1081,7 @@ void _vuMSUBA(VURegs * VU) { VU_STAT_UPDATE(VU); }/*last updated 11/05/03 shadow*/ -void _vuMSUBAi(VURegs * VU) { +static __fi void _vuMSUBAi(VURegs * VU) { if (_X) VU->ACC.i.x = VU_MACx_UPDATE(VU, vuDouble(VU->ACC.i.x) - ( vuDouble(VU->VF[_Fs_].i.x) * vuDouble(VU->VI[REG_I].UL))); else VU_MACx_CLEAR(VU); if (_Y) VU->ACC.i.y = VU_MACy_UPDATE(VU, vuDouble(VU->ACC.i.y) - ( vuDouble(VU->VF[_Fs_].i.y) * vuDouble(VU->VI[REG_I].UL))); else VU_MACy_CLEAR(VU); if (_Z) VU->ACC.i.z = VU_MACz_UPDATE(VU, vuDouble(VU->ACC.i.z) - ( vuDouble(VU->VF[_Fs_].i.z) * vuDouble(VU->VI[REG_I].UL))); else VU_MACz_CLEAR(VU); @@ -1090,7 +1089,7 @@ void _vuMSUBAi(VURegs * VU) { VU_STAT_UPDATE(VU); }/*last updated 11/05/03 shadow*/ -void _vuMSUBAq(VURegs * VU) { +static __fi void _vuMSUBAq(VURegs * VU) { if (_X) VU->ACC.i.x = VU_MACx_UPDATE(VU, vuDouble(VU->ACC.i.x) - ( vuDouble(VU->VF[_Fs_].i.x) * vuDouble(VU->VI[REG_Q].UL))); else VU_MACx_CLEAR(VU); if (_Y) VU->ACC.i.y = VU_MACy_UPDATE(VU, vuDouble(VU->ACC.i.y) - ( vuDouble(VU->VF[_Fs_].i.y) * vuDouble(VU->VI[REG_Q].UL))); else VU_MACy_CLEAR(VU); if (_Z) VU->ACC.i.z = VU_MACz_UPDATE(VU, vuDouble(VU->ACC.i.z) - ( vuDouble(VU->VF[_Fs_].i.z) * vuDouble(VU->VI[REG_Q].UL))); else VU_MACz_CLEAR(VU); @@ -1098,7 +1097,7 @@ void _vuMSUBAq(VURegs * VU) { VU_STAT_UPDATE(VU); }/*last updated 11/05/03 shadow*/ -void _vuMSUBAx(VURegs * VU) { +static __fi void _vuMSUBAx(VURegs * VU) { float tx = vuDouble(VU->VF[_Ft_].i.x); if (_X) VU->ACC.i.x = VU_MACx_UPDATE(VU, vuDouble(VU->ACC.i.x) - ( vuDouble(VU->VF[_Fs_].i.x) * tx)); else VU_MACx_CLEAR(VU); @@ -1108,7 +1107,7 @@ void _vuMSUBAx(VURegs * VU) { VU_STAT_UPDATE(VU); }/*last updated 11/05/03 shadow*/ -void _vuMSUBAy(VURegs * VU) { +static __fi void _vuMSUBAy(VURegs * VU) { float ty = vuDouble(VU->VF[_Ft_].i.y); if (_X) VU->ACC.i.x = VU_MACx_UPDATE(VU, vuDouble(VU->ACC.i.x) - ( vuDouble(VU->VF[_Fs_].i.x) * ty)); else VU_MACx_CLEAR(VU); @@ -1118,7 +1117,7 @@ void _vuMSUBAy(VURegs * VU) { VU_STAT_UPDATE(VU); }/*last updated 11/05/03 shadow*/ -void _vuMSUBAz(VURegs * VU) { +static __fi void _vuMSUBAz(VURegs * VU) { float tz = vuDouble(VU->VF[_Ft_].i.z); if (_X) VU->ACC.i.x = VU_MACx_UPDATE(VU, vuDouble(VU->ACC.i.x) - ( vuDouble(VU->VF[_Fs_].i.x) * tz)); else VU_MACx_CLEAR(VU); @@ -1128,7 +1127,7 @@ void _vuMSUBAz(VURegs * VU) { VU_STAT_UPDATE(VU); }/*last updated 11/05/03 shadow*/ -void _vuMSUBAw(VURegs * VU) { +static __fi void _vuMSUBAw(VURegs * VU) { float tw = vuDouble(VU->VF[_Ft_].i.w); if (_X) VU->ACC.i.x = VU_MACx_UPDATE(VU, vuDouble(VU->ACC.i.x) - ( vuDouble(VU->VF[_Fs_].i.x) * tw)); else VU_MACx_CLEAR(VU); @@ -1156,7 +1155,7 @@ u32 _MAX(u32 a, u32 b) { return 0; } -void _vuMAX(VURegs * VU) { +static __fi void _vuMAX(VURegs * VU) { if (_Fd_ == 0) return; /* ft is bc */ @@ -1166,7 +1165,7 @@ void _vuMAX(VURegs * VU) { if (_W) VU->VF[_Fd_].i.w = _MAX(VU->VF[_Fs_].i.w, (s32)VU->VF[_Ft_].i.w); }//checked 13/05/03 shadow -void _vuMAXi(VURegs * VU) { +static __fi void _vuMAXi(VURegs * VU) { if (_Fd_ == 0) return; /* ft is bc */ @@ -1176,7 +1175,7 @@ void _vuMAXi(VURegs * VU) { if (_W) VU->VF[_Fd_].i.w = _MAX(VU->VF[_Fs_].i.w, VU->VI[REG_I].UL); }//checked 13/05/03 shadow -void _vuMAXx(VURegs * VU) { +static __fi void _vuMAXx(VURegs * VU) { s32 ftx; if (_Fd_ == 0) return; @@ -1188,7 +1187,7 @@ void _vuMAXx(VURegs * VU) { } //checked 13/05/03 shadow -void _vuMAXy(VURegs * VU) { +static __fi void _vuMAXy(VURegs * VU) { s32 fty; if (_Fd_ == 0) return; @@ -1199,7 +1198,7 @@ void _vuMAXy(VURegs * VU) { if (_W) VU->VF[_Fd_].i.w = _MAX(VU->VF[_Fs_].i.w, fty); }//checked 13/05/03 shadow -void _vuMAXz(VURegs * VU) { +static __fi void _vuMAXz(VURegs * VU) { s32 ftz; if (_Fd_ == 0) return; @@ -1210,7 +1209,7 @@ void _vuMAXz(VURegs * VU) { if (_W) VU->VF[_Fd_].i.w = _MAX(VU->VF[_Fs_].i.w, ftz); } -void _vuMAXw(VURegs * VU) { +static __fi void _vuMAXw(VURegs * VU) { s32 ftw; if (_Fd_ == 0) return; @@ -1239,7 +1238,7 @@ u32 _MINI(u32 a, u32 b) { return 0; } -void _vuMINI(VURegs * VU) { +static __fi void _vuMINI(VURegs * VU) { if (_Fd_ == 0) return; /* ft is bc */ @@ -1249,7 +1248,7 @@ void _vuMINI(VURegs * VU) { if (_W) VU->VF[_Fd_].i.w = _MINI(VU->VF[_Fs_].i.w, (s32)VU->VF[_Ft_].i.w); }//checked 13/05/03 shadow -void _vuMINIi(VURegs * VU) { +static __fi void _vuMINIi(VURegs * VU) { if (_Fd_ == 0) return; /* ft is bc */ @@ -1259,7 +1258,7 @@ void _vuMINIi(VURegs * VU) { if (_W) VU->VF[_Fd_].i.w = _MINI(VU->VF[_Fs_].i.w, VU->VI[REG_I].UL); }//checked 13/05/03 shadow -void _vuMINIx(VURegs * VU) { +static __fi void _vuMINIx(VURegs * VU) { s32 ftx; if (_Fd_ == 0) return; @@ -1271,7 +1270,7 @@ void _vuMINIx(VURegs * VU) { } //checked 13/05/03 shadow -void _vuMINIy(VURegs * VU) { +static __fi void _vuMINIy(VURegs * VU) { s32 fty; if (_Fd_ == 0) return; @@ -1282,7 +1281,7 @@ void _vuMINIy(VURegs * VU) { if (_W) VU->VF[_Fd_].i.w = _MINI(VU->VF[_Fs_].i.w, fty); }//checked 13/05/03 shadow -void _vuMINIz(VURegs * VU) { +static __fi void _vuMINIz(VURegs * VU) { s32 ftz; if (_Fd_ == 0) return; @@ -1293,7 +1292,7 @@ void _vuMINIz(VURegs * VU) { if (_W) VU->VF[_Fd_].i.w = _MINI(VU->VF[_Fs_].i.w, ftz); } -void _vuMINIw(VURegs * VU) { +static __fi void _vuMINIw(VURegs * VU) { s32 ftw; if (_Fd_ == 0) return; @@ -1304,14 +1303,14 @@ void _vuMINIw(VURegs * VU) { if (_W) VU->VF[_Fd_].i.w = _MINI(VU->VF[_Fs_].i.w, ftw); } -void _vuOPMULA(VURegs * VU) { +static __fi void _vuOPMULA(VURegs * VU) { VU->ACC.i.x = VU_MACx_UPDATE(VU, vuDouble(VU->VF[_Fs_].i.y) * vuDouble(VU->VF[_Ft_].i.z)); VU->ACC.i.y = VU_MACy_UPDATE(VU, vuDouble(VU->VF[_Fs_].i.z) * vuDouble(VU->VF[_Ft_].i.x)); VU->ACC.i.z = VU_MACz_UPDATE(VU, vuDouble(VU->VF[_Fs_].i.x) * vuDouble(VU->VF[_Ft_].i.y)); VU_STAT_UPDATE(VU); }/*last updated 8/05/03 shadow*/ -void _vuOPMSUB(VURegs * VU) { +static __fi void _vuOPMSUB(VURegs * VU) { VECTOR * dst; float ftx, fty, ftz; float fsx, fsy, fsz; @@ -1328,10 +1327,10 @@ void _vuOPMSUB(VURegs * VU) { VU_STAT_UPDATE(VU); }/*last updated 8/05/03 shadow*/ -void _vuNOP(VURegs * VU) { +static __fi void _vuNOP(VURegs * VU) { } -void _vuFTOI0(VURegs * VU) { +static __fi void _vuFTOI0(VURegs * VU) { if (_Ft_ == 0) return; if (_X) VU->VF[_Ft_].SL[0] = (s32)vuDouble(VU->VF[_Fs_].i.x); @@ -1340,7 +1339,7 @@ void _vuFTOI0(VURegs * VU) { if (_W) VU->VF[_Ft_].SL[3] = (s32)vuDouble(VU->VF[_Fs_].i.w); } -void _vuFTOI4(VURegs * VU) { +static __fi void _vuFTOI4(VURegs * VU) { if (_Ft_ == 0) return; if (_X) VU->VF[_Ft_].SL[0] = float_to_int4(vuDouble(VU->VF[_Fs_].i.x)); @@ -1349,7 +1348,7 @@ void _vuFTOI4(VURegs * VU) { if (_W) VU->VF[_Ft_].SL[3] = float_to_int4(vuDouble(VU->VF[_Fs_].i.w)); } -void _vuFTOI12(VURegs * VU) { +static __fi void _vuFTOI12(VURegs * VU) { if (_Ft_ == 0) return; if (_X) VU->VF[_Ft_].SL[0] = float_to_int12(vuDouble(VU->VF[_Fs_].i.x)); @@ -1358,7 +1357,7 @@ void _vuFTOI12(VURegs * VU) { if (_W) VU->VF[_Ft_].SL[3] = float_to_int12(vuDouble(VU->VF[_Fs_].i.w)); } -void _vuFTOI15(VURegs * VU) { +static __fi void _vuFTOI15(VURegs * VU) { if (_Ft_ == 0) return; if (_X) VU->VF[_Ft_].SL[0] = float_to_int15(vuDouble(VU->VF[_Fs_].i.x)); @@ -1367,7 +1366,7 @@ void _vuFTOI15(VURegs * VU) { if (_W) VU->VF[_Ft_].SL[3] = float_to_int15(vuDouble(VU->VF[_Fs_].i.w)); } -void _vuITOF0(VURegs * VU) { +static __fi void _vuITOF0(VURegs * VU) { if (_Ft_ == 0) return; if (_X) VU->VF[_Ft_].f.x = (float)VU->VF[_Fs_].SL[0]; @@ -1376,7 +1375,7 @@ void _vuITOF0(VURegs * VU) { if (_W) VU->VF[_Ft_].f.w = (float)VU->VF[_Fs_].SL[3]; } -void _vuITOF4(VURegs * VU) { +static __fi void _vuITOF4(VURegs * VU) { if (_Ft_ == 0) return; if (_X) VU->VF[_Ft_].f.x = int4_to_float(VU->VF[_Fs_].SL[0]); @@ -1385,7 +1384,7 @@ void _vuITOF4(VURegs * VU) { if (_W) VU->VF[_Ft_].f.w = int4_to_float(VU->VF[_Fs_].SL[3]); } -void _vuITOF12(VURegs * VU) { +static __fi void _vuITOF12(VURegs * VU) { if (_Ft_ == 0) return; if (_X) VU->VF[_Ft_].f.x = int12_to_float(VU->VF[_Fs_].SL[0]); @@ -1394,7 +1393,7 @@ void _vuITOF12(VURegs * VU) { if (_W) VU->VF[_Ft_].f.w = int12_to_float(VU->VF[_Fs_].SL[3]); } -void _vuITOF15(VURegs * VU) { +static __fi void _vuITOF15(VURegs * VU) { if (_Ft_ == 0) return; if (_X) VU->VF[_Ft_].f.x = int15_to_float(VU->VF[_Fs_].SL[0]); @@ -1404,7 +1403,7 @@ void _vuITOF15(VURegs * VU) { } /* Different type of clipping by presaving w. asadr */ -void _vuCLIP(VURegs * VU) { +static __fi void _vuCLIP(VURegs * VU) { float value = fabs(vuDouble(VU->VF[_Ft_].i.w)); VU->clipflag <<= 6; @@ -1425,7 +1424,7 @@ void _vuCLIP(VURegs * VU) { /* VU Lower instructions */ /******************************/ -void _vuDIV(VURegs * VU) { +static __fi void _vuDIV(VURegs * VU) { float ft = vuDouble(VU->VF[_Ft_].UL[_Ftf_]); float fs = vuDouble(VU->VF[_Fs_].UL[_Fsf_]); @@ -1449,7 +1448,7 @@ void _vuDIV(VURegs * VU) { } } //last update 15/01/06 zerofrog -void _vuSQRT(VURegs * VU) { +static __fi void _vuSQRT(VURegs * VU) { float ft = vuDouble(VU->VF[_Ft_].UL[_Ftf_]); VU->statusflag = (VU->statusflag&0xfcf)|((VU->statusflag&0x30)<<6); @@ -1461,7 +1460,7 @@ void _vuSQRT(VURegs * VU) { /* Eminent Bug - Dvisior == 0 Check Missing ( D Flag Not Set ) */ /* REFIXED....ASADR; rerefixed....zerofrog */ -void _vuRSQRT(VURegs * VU) { +static __fi void _vuRSQRT(VURegs * VU) { float ft = vuDouble(VU->VF[_Ft_].UL[_Ftf_]); float fs = vuDouble(VU->VF[_Fs_].UL[_Fsf_]); float temp; @@ -1501,44 +1500,44 @@ void _vuRSQRT(VURegs * VU) { } } //last update 15/01/06 zerofrog -void _vuIADDI(VURegs * VU) { +static __fi void _vuIADDI(VURegs * VU) { s16 imm = ((VU->code >> 6) & 0x1f); imm = ((imm & 0x10 ? 0xfff0 : 0) | (imm & 0xf)); if(_It_ == 0) return; VU->VI[_It_].SS[0] = VU->VI[_Is_].SS[0] + imm; }//last checked 17/05/03 shadow NOTE: not quite sure about that -void _vuIADDIU(VURegs * VU) { +static __fi void _vuIADDIU(VURegs * VU) { if(_It_ == 0) return; VU->VI[_It_].SS[0] = VU->VI[_Is_].SS[0] + (((VU->code >> 10) & 0x7800) | (VU->code & 0x7ff)); }//last checked 17/05/03 shadow -void _vuIADD(VURegs * VU) { +static __fi void _vuIADD(VURegs * VU) { if(_Id_ == 0) return; VU->VI[_Id_].SS[0] = VU->VI[_Is_].SS[0] + VU->VI[_It_].SS[0]; }//last checked 17/05/03 shadow -void _vuIAND(VURegs * VU) { +static __fi void _vuIAND(VURegs * VU) { if(_Id_ == 0) return; VU->VI[_Id_].US[0] = VU->VI[_Is_].US[0] & VU->VI[_It_].US[0]; }//last checked 17/05/03 shadow -void _vuIOR(VURegs * VU) { +static __fi void _vuIOR(VURegs * VU) { if(_Id_ == 0) return; VU->VI[_Id_].US[0] = VU->VI[_Is_].US[0] | VU->VI[_It_].US[0]; } -void _vuISUB(VURegs * VU) { +static __fi void _vuISUB(VURegs * VU) { if(_Id_ == 0) return; VU->VI[_Id_].SS[0] = VU->VI[_Is_].SS[0] - VU->VI[_It_].SS[0]; } -void _vuISUBIU(VURegs * VU) { +static __fi void _vuISUBIU(VURegs * VU) { if(_It_ == 0) return; VU->VI[_It_].SS[0] = VU->VI[_Is_].SS[0] - (((VU->code >> 10) & 0x7800) | (VU->code & 0x7ff)); } -void _vuMOVE(VURegs * VU) { +static __fi void _vuMOVE(VURegs * VU) { if(_Ft_ == 0) return; if (_X) VU->VF[_Ft_].UL[0] = VU->VF[_Fs_].UL[0]; @@ -1547,7 +1546,7 @@ void _vuMOVE(VURegs * VU) { if (_W) VU->VF[_Ft_].UL[3] = VU->VF[_Fs_].UL[3]; }//last checked 17/05/03 shadow -void _vuMFIR(VURegs * VU) { +static __fi void _vuMFIR(VURegs * VU) { if (_Ft_ == 0) return; if (_X) VU->VF[_Ft_].SL[0] = (s32)VU->VI[_Is_].SS[0]; @@ -1557,12 +1556,12 @@ void _vuMFIR(VURegs * VU) { } // Big bug!!! mov from fs to ft not ft to fs. asadr -void _vuMTIR(VURegs * VU) { +static __fi void _vuMTIR(VURegs * VU) { if(_It_ == 0) return; VU->VI[_It_].US[0] = *(u16*)&VU->VF[_Fs_].F[_Fsf_]; } -void _vuMR32(VURegs * VU) { +static __fi void _vuMR32(VURegs * VU) { u32 tx; if (_Ft_ == 0) return; @@ -1579,50 +1578,40 @@ void _vuMR32(VURegs * VU) { __fi u32* GET_VU_MEM(VURegs* VU, u32 addr) // non-static, also used by sVU for now. { - if( VU == g_pVU1 ) return (u32*)(VU1.Mem+(addr&0x3fff)); - if( addr >= 0x4000 ) return (u32*)(VU0.Mem+(addr&0x43f0)); // get VF and VI regs (they're mapped to 0x4xx0 in VU0 mem!) - return (u32*)(VU0.Mem+(addr&0x0fff)); // for addr 0x0000 to 0x4000 just wrap around + if( VU == &vuRegs[1] ) return (u32*)(vuRegs[1].Mem+(addr&0x3fff)); + if( addr & 0x4000 ) return (u32*)(vuRegs[1].VF+(addr&0x3f0)); // get VF and VI regs (they're mapped to 0x4xx0 in VU0 mem!) + return (u32*)(vuRegs[0].Mem+(addr&0x0fff)); // for addr 0x0000 to 0x4000 just wrap around } -void _vuLQ(VURegs * VU) { - s16 imm; - u16 addr; - u32 *ptr; - +static __ri void _vuLQ(VURegs * VU) { if (_Ft_ == 0) return; - imm = (VU->code & 0x400) ? (VU->code & 0x3ff) | 0xfc00 : (VU->code & 0x3ff); - addr = ((imm + VU->VI[_Is_].SS[0]) * 16)& (VU == &VU1 ? 0x3fff : 0xfff); + s16 imm = (VU->code & 0x400) ? (VU->code & 0x3ff) | 0xfc00 : (VU->code & 0x3ff); + u16 addr = ((imm + VU->VI[_Is_].SS[0]) * 16); - ptr = (u32*)GET_VU_MEM(VU, addr); + u32* ptr = (u32*)GET_VU_MEM(VU, addr); if (_X) VU->VF[_Ft_].UL[0] = ptr[0]; if (_Y) VU->VF[_Ft_].UL[1] = ptr[1]; if (_Z) VU->VF[_Ft_].UL[2] = ptr[2]; if (_W) VU->VF[_Ft_].UL[3] = ptr[3]; } -void _vuLQD( VURegs * VU ) { - u32 addr; - u32 *ptr; - +static __ri void _vuLQD( VURegs * VU ) { if (_Is_ != 0) VU->VI[_Is_].US[0]--; if (_Ft_ == 0) return; - addr = (VU->VI[_Is_].US[0] * 16) & (VU == &VU1 ? 0x3fff : 0xfff); - ptr = (u32*)GET_VU_MEM(VU, addr); + u32 addr = (VU->VI[_Is_].US[0] * 16); + u32* ptr = (u32*)GET_VU_MEM(VU, addr); if (_X) VU->VF[_Ft_].UL[0] = ptr[0]; if (_Y) VU->VF[_Ft_].UL[1] = ptr[1]; if (_Z) VU->VF[_Ft_].UL[2] = ptr[2]; if (_W) VU->VF[_Ft_].UL[3] = ptr[3]; } -void _vuLQI(VURegs * VU) { +static __ri void _vuLQI(VURegs * VU) { if (_Ft_) { - u32 addr; - u32 *ptr; - - addr = (VU->VI[_Is_].US[0] * 16)& (VU == &VU1 ? 0x3fff : 0xfff); - ptr = (u32*)GET_VU_MEM(VU, addr); + u32 addr = (VU->VI[_Is_].US[0] * 16); + u32* ptr = (u32*)GET_VU_MEM(VU, addr); if (_X) VU->VF[_Ft_].UL[0] = ptr[0]; if (_Y) VU->VF[_Ft_].UL[1] = ptr[1]; if (_Z) VU->VF[_Ft_].UL[2] = ptr[2]; @@ -1632,39 +1621,29 @@ void _vuLQI(VURegs * VU) { } /* addr is now signed. Asadr */ -void _vuSQ(VURegs * VU) { - s16 imm; - u16 addr; - u32 *ptr; - - imm = (VU->code & 0x400) ? (VU->code & 0x3ff) | 0xfc00 : (VU->code & 0x3ff); - addr = ((imm + VU->VI[_It_].SS[0]) * 16)& (VU == &VU1 ? 0x3fff : 0xfff); - ptr = (u32*)GET_VU_MEM(VU, addr); +static __ri void _vuSQ(VURegs * VU) { + s16 imm = (VU->code & 0x400) ? (VU->code & 0x3ff) | 0xfc00 : (VU->code & 0x3ff); + u16 addr = ((imm + VU->VI[_It_].SS[0]) * 16); + u32* ptr = (u32*)GET_VU_MEM(VU, addr); if (_X) ptr[0] = VU->VF[_Fs_].UL[0]; if (_Y) ptr[1] = VU->VF[_Fs_].UL[1]; if (_Z) ptr[2] = VU->VF[_Fs_].UL[2]; if (_W) ptr[3] = VU->VF[_Fs_].UL[3]; } -void _vuSQD(VURegs * VU) { - u32 addr; - u32 *ptr; - +static __ri void _vuSQD(VURegs * VU) { if(_Ft_ != 0) VU->VI[_It_].US[0]--; - addr = (VU->VI[_It_].US[0] * 16)& (VU == &VU1 ? 0x3fff : 0xfff); - ptr = (u32*)GET_VU_MEM(VU, addr); + u32 addr = (VU->VI[_It_].US[0] * 16); + u32* ptr = (u32*)GET_VU_MEM(VU, addr); if (_X) ptr[0] = VU->VF[_Fs_].UL[0]; if (_Y) ptr[1] = VU->VF[_Fs_].UL[1]; if (_Z) ptr[2] = VU->VF[_Fs_].UL[2]; if (_W) ptr[3] = VU->VF[_Fs_].UL[3]; } -void _vuSQI(VURegs * VU) { - u32 addr; - u32 *ptr; - - addr = (VU->VI[_It_].US[0] * 16)& (VU == &VU1 ? 0x3fff : 0xfff); - ptr = (u32*)GET_VU_MEM(VU, addr); +static __ri void _vuSQI(VURegs * VU) { + u32 addr = (VU->VI[_It_].US[0] * 16); + u32* ptr = (u32*)GET_VU_MEM(VU, addr); if (_X) ptr[0] = VU->VF[_Fs_].UL[0]; if (_Y) ptr[1] = VU->VF[_Fs_].UL[1]; if (_Z) ptr[2] = VU->VF[_Fs_].UL[2]; @@ -1673,54 +1652,42 @@ void _vuSQI(VURegs * VU) { } /* addr now signed. asadr */ -void _vuILW(VURegs * VU) { - s16 imm; - u16 addr; - u16 *ptr; +static __ri void _vuILW(VURegs * VU) { if (_It_ == 0) return; - imm = (VU->code & 0x400) ? (VU->code & 0x3ff) | 0xfc00 : (VU->code & 0x3ff); - addr = ((imm + VU->VI[_Is_].SS[0]) * 16)& (VU == &VU1 ? 0x3fff : 0xfff); - ptr = (u16*)GET_VU_MEM(VU, addr); + s16 imm = (VU->code & 0x400) ? (VU->code & 0x3ff) | 0xfc00 : (VU->code & 0x3ff); + u16 addr = ((imm + VU->VI[_Is_].SS[0]) * 16); + u16* ptr = (u16*)GET_VU_MEM(VU, addr); if (_X) VU->VI[_It_].US[0] = ptr[0]; if (_Y) VU->VI[_It_].US[0] = ptr[2]; if (_Z) VU->VI[_It_].US[0] = ptr[4]; if (_W) VU->VI[_It_].US[0] = ptr[6]; } -void _vuISW(VURegs * VU) { - s16 imm; - u16 addr; - u16 *ptr; - - imm = (VU->code & 0x400) ? (VU->code & 0x3ff) | 0xfc00 : (VU->code & 0x3ff); - addr = ((imm + VU->VI[_Is_].SS[0]) * 16)& (VU == &VU1 ? 0x3fff : 0xfff); - ptr = (u16*)GET_VU_MEM(VU, addr); +static __fi void _vuISW(VURegs * VU) { + s16 imm = (VU->code & 0x400) ? (VU->code & 0x3ff) | 0xfc00 : (VU->code & 0x3ff); + u16 addr = ((imm + VU->VI[_Is_].SS[0]) * 16); + u16* ptr = (u16*)GET_VU_MEM(VU, addr); if (_X) { ptr[0] = VU->VI[_It_].US[0]; ptr[1] = 0; } if (_Y) { ptr[2] = VU->VI[_It_].US[0]; ptr[3] = 0; } if (_Z) { ptr[4] = VU->VI[_It_].US[0]; ptr[5] = 0; } if (_W) { ptr[6] = VU->VI[_It_].US[0]; ptr[7] = 0; } } -void _vuILWR(VURegs * VU) { - u32 addr; - u16 *ptr; +static __ri void _vuILWR(VURegs * VU) { if (_It_ == 0) return; - addr = (VU->VI[_Is_].US[0] * 16)& (VU == &VU1 ? 0x3fff : 0xfff); - ptr = (u16*)GET_VU_MEM(VU, addr); + u32 addr = (VU->VI[_Is_].US[0] * 16); + u16* ptr = (u16*)GET_VU_MEM(VU, addr); if (_X) VU->VI[_It_].US[0] = ptr[0]; if (_Y) VU->VI[_It_].US[0] = ptr[2]; if (_Z) VU->VI[_It_].US[0] = ptr[4]; if (_W) VU->VI[_It_].US[0] = ptr[6]; } -void _vuISWR(VURegs * VU) { - u32 addr; - u16 *ptr; - - addr = (VU->VI[_Is_].US[0] * 16) & (VU == &VU1 ? 0x3fff : 0xfff); - ptr = (u16*)GET_VU_MEM(VU, addr); +static __ri void _vuISWR(VURegs * VU) { + u32 addr = (VU->VI[_Is_].US[0] * 16); + u16* ptr = (u16*)GET_VU_MEM(VU, addr); if (_X) { ptr[0] = VU->VI[_It_].US[0]; ptr[1] = 0; } if (_Y) { ptr[2] = VU->VI[_It_].US[0]; ptr[3] = 0; } if (_Z) { ptr[4] = VU->VI[_It_].US[0]; ptr[5] = 0; } @@ -1740,13 +1707,13 @@ As an example for setting the polynomial variable correctly, the 23-bit M-series //The two-tap 23 stage M-series polynomials are x23+x18 and x23+x14 ((1 << 18) and (1 << 14), respectively). //The reverse sequences can be generated by x23+x(23-18) and x23+x(23-14) ((1 << 9) and (1 << 5), respectively) -u32 poly = 1 << 5; +static u32 poly = 1 << 5; -void SetPoly(u32 newPoly) { +static __ri void SetPoly(u32 newPoly) { poly = poly & ~1; } -void AdvanceLFSR(VURegs * VU) { +static __ri void AdvanceLFSR(VURegs * VU) { // code from www.project-fao.org (which is no longer there) int x = (VU->VI[REG_R].UL >> 4) & 1; int y = (VU->VI[REG_R].UL >> 22) & 1; @@ -1755,11 +1722,11 @@ void AdvanceLFSR(VURegs * VU) { VU->VI[REG_R].UL = (VU->VI[REG_R].UL&0x7fffff)|0x3f800000; } -void _vuRINIT(VURegs * VU) { +static __ri void _vuRINIT(VURegs * VU) { VU->VI[REG_R].UL = 0x3F800000 | (VU->VF[_Fs_].UL[_Fsf_] & 0x007FFFFF); } -void _vuRGET(VURegs * VU) { +static __ri void _vuRGET(VURegs * VU) { if (_Ft_ == 0) return; if (_X) VU->VF[_Ft_].UL[0] = VU->VI[REG_R].UL; @@ -1768,7 +1735,7 @@ void _vuRGET(VURegs * VU) { if (_W) VU->VF[_Ft_].UL[3] = VU->VI[REG_R].UL; } -void _vuRNEXT(VURegs * VU) { +static __ri void _vuRNEXT(VURegs * VU) { if (_Ft_ == 0) return; AdvanceLFSR(VU); if (_X) VU->VF[_Ft_].UL[0] = VU->VI[REG_R].UL; @@ -1777,21 +1744,21 @@ void _vuRNEXT(VURegs * VU) { if (_W) VU->VF[_Ft_].UL[3] = VU->VI[REG_R].UL; } -void _vuRXOR(VURegs * VU) { +static __ri void _vuRXOR(VURegs * VU) { VU->VI[REG_R].UL = 0x3F800000 | ((VU->VI[REG_R].UL ^ VU->VF[_Fs_].UL[_Fsf_]) & 0x007FFFFF); } -void _vuWAITQ(VURegs * VU) { +static __ri void _vuWAITQ(VURegs * VU) { } -void _vuFSAND(VURegs * VU) { +static __ri void _vuFSAND(VURegs * VU) { u16 imm; imm = (((VU->code >> 21 ) & 0x1) << 11) | (VU->code & 0x7ff); if(_It_ == 0) return; VU->VI[_It_].US[0] = (VU->VI[REG_STATUS_FLAG].US[0] & 0xFFF) & imm; } -void _vuFSEQ(VURegs * VU) { +static __ri void _vuFSEQ(VURegs * VU) { u16 imm; imm = (((VU->code >> 21 ) & 0x1) << 11) | (VU->code & 0x7ff); if(_It_ == 0) return; @@ -1799,57 +1766,57 @@ void _vuFSEQ(VURegs * VU) { else VU->VI[_It_].US[0] = 0; } -void _vuFSOR(VURegs * VU) { +static __ri void _vuFSOR(VURegs * VU) { u16 imm; imm = (((VU->code >> 21 ) & 0x1) << 11) | (VU->code & 0x7ff); if(_It_ == 0) return; VU->VI[_It_].US[0] = (VU->VI[REG_STATUS_FLAG].US[0] & 0xFFF) | imm; } -void _vuFSSET(VURegs * VU) { +static __ri void _vuFSSET(VURegs * VU) { u16 imm = 0; imm = (((VU->code >> 21 ) & 0x1) << 11) | (VU->code & 0x7FF); VU->statusflag = (imm & 0xFC0) | (VU->VI[REG_STATUS_FLAG].US[0] & 0x3F); } -void _vuFMAND(VURegs * VU) { +static __ri void _vuFMAND(VURegs * VU) { if(_It_ == 0) return; VU->VI[_It_].US[0] = VU->VI[_Is_].US[0] & (VU->VI[REG_MAC_FLAG].UL & 0xFFFF); } -void _vuFMEQ(VURegs * VU) { +static __fi void _vuFMEQ(VURegs * VU) { if(_It_ == 0) return; if((VU->VI[REG_MAC_FLAG].UL & 0xFFFF) == VU->VI[_Is_].US[0]){ VU->VI[_It_].US[0] =1;} else { VU->VI[_It_].US[0] =0; } } -void _vuFMOR(VURegs * VU) { +static __fi void _vuFMOR(VURegs * VU) { if(_It_ == 0) return; VU->VI[_It_].US[0] = (VU->VI[REG_MAC_FLAG].UL & 0xFFFF) | VU->VI[_Is_].US[0]; } -void _vuFCAND(VURegs * VU) { +static __fi void _vuFCAND(VURegs * VU) { if((VU->VI[REG_CLIP_FLAG].UL & 0xFFFFFF) & (VU->code & 0xFFFFFF)) VU->VI[1].US[0] = 1; else VU->VI[1].US[0] = 0; } -void _vuFCEQ(VURegs * VU) { +static __fi void _vuFCEQ(VURegs * VU) { if((VU->VI[REG_CLIP_FLAG].UL & 0xFFFFFF) == (VU->code & 0xFFFFFF)) VU->VI[1].US[0] = 1; else VU->VI[1].US[0] = 0; } -void _vuFCOR(VURegs * VU) { +static __fi void _vuFCOR(VURegs * VU) { u32 hold = (VU->VI[REG_CLIP_FLAG].UL & 0xFFFFFF) | ( VU->code & 0xFFFFFF); if(hold == 0xFFFFFF) VU->VI[1].US[0] = 1; else VU->VI[1].US[0] = 0; } -void _vuFCSET(VURegs * VU) { +static __fi void _vuFCSET(VURegs * VU) { VU->clipflag = (u32) (VU->code & 0xFFFFFF); VU->VI[REG_CLIP_FLAG].UL = (u32) (VU->code & 0xFFFFFF); } -void _vuFCGET(VURegs * VU) { +static __fi void _vuFCGET(VURegs * VU) { if(_It_ == 0) return; VU->VI[_It_].US[0] = VU->VI[REG_CLIP_FLAG].UL & 0x0FFF; } @@ -1860,59 +1827,59 @@ s32 _branchAddr(VURegs * VU) { return bpc; } -void _setBranch(VURegs * VU, u32 bpc) { +static __fi void _setBranch(VURegs * VU, u32 bpc) { VU->branch = 2; VU->branchpc = bpc; } -void _vuIBEQ(VURegs * VU) { +static __ri void _vuIBEQ(VURegs * VU) { if (VU->VI[_It_].US[0] == VU->VI[_Is_].US[0]) { s32 bpc = _branchAddr(VU); _setBranch(VU, bpc); } } -void _vuIBGEZ(VURegs * VU) { +static __ri void _vuIBGEZ(VURegs * VU) { if (VU->VI[_Is_].SS[0] >= 0) { s32 bpc = _branchAddr(VU); _setBranch(VU, bpc); } } -void _vuIBGTZ(VURegs * VU) { +static __ri void _vuIBGTZ(VURegs * VU) { if (VU->VI[_Is_].SS[0] > 0) { s32 bpc = _branchAddr(VU); _setBranch(VU, bpc); } } -void _vuIBLEZ(VURegs * VU) { +static __ri void _vuIBLEZ(VURegs * VU) { if (VU->VI[_Is_].SS[0] <= 0) { s32 bpc = _branchAddr(VU); _setBranch(VU, bpc); } } -void _vuIBLTZ(VURegs * VU) { +static __ri void _vuIBLTZ(VURegs * VU) { if (VU->VI[_Is_].SS[0] < 0) { s32 bpc = _branchAddr(VU); _setBranch(VU, bpc); } } -void _vuIBNE(VURegs * VU) { +static __ri void _vuIBNE(VURegs * VU) { if (VU->VI[_It_].US[0] != VU->VI[_Is_].US[0]) { s32 bpc = _branchAddr(VU); _setBranch(VU, bpc); } } -void _vuB(VURegs * VU) { +static __ri void _vuB(VURegs * VU) { s32 bpc = _branchAddr(VU); _setBranch(VU, bpc); } -void _vuBAL(VURegs * VU) { +static __ri void _vuBAL(VURegs * VU) { s32 bpc = _branchAddr(VU); if (_It_) VU->VI[_It_].US[0] = (VU->VI[REG_TPC].UL + 8)/8; @@ -1920,19 +1887,19 @@ void _vuBAL(VURegs * VU) { _setBranch(VU, bpc); } -void _vuJR(VURegs * VU) { +static __ri void _vuJR(VURegs * VU) { u32 bpc = VU->VI[_Is_].US[0] * 8; _setBranch(VU, bpc); } -void _vuJALR(VURegs * VU) { +static __ri void _vuJALR(VURegs * VU) { u32 bpc = VU->VI[_Is_].US[0] * 8; if (_It_) VU->VI[_It_].US[0] = (VU->VI[REG_TPC].UL + 8)/8; _setBranch(VU, bpc); } -void _vuMFP(VURegs * VU) { +static __ri void _vuMFP(VURegs * VU) { if (_Ft_ == 0) return; if (_X) VU->VF[_Ft_].i.x = VU->VI[REG_P].UL; @@ -1941,15 +1908,15 @@ void _vuMFP(VURegs * VU) { if (_W) VU->VF[_Ft_].i.w = VU->VI[REG_P].UL; } -void _vuWAITP(VURegs * VU) { +static __ri void _vuWAITP(VURegs * VU) { } -void _vuESADD(VURegs * VU) { +static __ri void _vuESADD(VURegs * VU) { float p = vuDouble(VU->VF[_Fs_].i.x) * vuDouble(VU->VF[_Fs_].i.x) + vuDouble(VU->VF[_Fs_].i.y) * vuDouble(VU->VF[_Fs_].i.y) + vuDouble(VU->VF[_Fs_].i.z) * vuDouble(VU->VF[_Fs_].i.z); VU->p.F = p; } -void _vuERSADD(VURegs * VU) { +static __ri void _vuERSADD(VURegs * VU) { float p = (vuDouble(VU->VF[_Fs_].i.x) * vuDouble(VU->VF[_Fs_].i.x)) + (vuDouble(VU->VF[_Fs_].i.y) * vuDouble(VU->VF[_Fs_].i.y)) + (vuDouble(VU->VF[_Fs_].i.z) * vuDouble(VU->VF[_Fs_].i.z)); if (p != 0.0) p = 1.0f / p; @@ -1957,7 +1924,7 @@ void _vuERSADD(VURegs * VU) { } /* Fixed. Could have caused crash due to value being -ve for sqrt *asadr */ -void _vuELENG(VURegs * VU) { +static __ri void _vuELENG(VURegs * VU) { float p = vuDouble(VU->VF[_Fs_].i.x) * vuDouble(VU->VF[_Fs_].i.x) + vuDouble(VU->VF[_Fs_].i.y) * vuDouble(VU->VF[_Fs_].i.y) + vuDouble(VU->VF[_Fs_].i.z) * vuDouble(VU->VF[_Fs_].i.z); if(p >= 0){ p = sqrt(p); @@ -1966,7 +1933,7 @@ void _vuELENG(VURegs * VU) { } /* Fixed. Could have caused crash due to divisor being = 0 *asadr */ -void _vuERLENG(VURegs * VU) { +static __ri void _vuERLENG(VURegs * VU) { float p = vuDouble(VU->VF[_Fs_].i.x) * vuDouble(VU->VF[_Fs_].i.x) + vuDouble(VU->VF[_Fs_].i.y) * vuDouble(VU->VF[_Fs_].i.y) + vuDouble(VU->VF[_Fs_].i.z) * vuDouble(VU->VF[_Fs_].i.z); if (p >= 0) { p = sqrt(p); @@ -1978,7 +1945,7 @@ void _vuERLENG(VURegs * VU) { } /* Fixed. Could have caused crash due to divisor being = 0 *asadr */ -void _vuEATANxy(VURegs * VU) { +static __ri void _vuEATANxy(VURegs * VU) { float p = 0; if(vuDouble(VU->VF[_Fs_].i.x) != 0) { p = atan2(vuDouble(VU->VF[_Fs_].i.y), vuDouble(VU->VF[_Fs_].i.x)); @@ -1987,7 +1954,7 @@ void _vuEATANxy(VURegs * VU) { } /* Fixed. Could have caused crash due to divisor being = 0 *asadr */ -void _vuEATANxz(VURegs * VU) { +static __ri void _vuEATANxz(VURegs * VU) { float p = 0; if(vuDouble(VU->VF[_Fs_].i.x) != 0) { p = atan2(vuDouble(VU->VF[_Fs_].i.z), vuDouble(VU->VF[_Fs_].i.x)); @@ -1995,13 +1962,13 @@ void _vuEATANxz(VURegs * VU) { VU->p.F = p; } -void _vuESUM(VURegs * VU) { +static __ri void _vuESUM(VURegs * VU) { float p = vuDouble(VU->VF[_Fs_].i.x) + vuDouble(VU->VF[_Fs_].i.y) + vuDouble(VU->VF[_Fs_].i.z) + vuDouble(VU->VF[_Fs_].i.w); VU->p.F = p; } /* Fixed. Could have caused crash due to divisor being = 0 *asadr */ -void _vuERCPR(VURegs * VU) { +static __ri void _vuERCPR(VURegs * VU) { float p = vuDouble(VU->VF[_Fs_].UL[_Fsf_]); if (p != 0){ p = 1.0 / p; @@ -2010,7 +1977,7 @@ void _vuERCPR(VURegs * VU) { } /* Fixed. Could have caused crash due to Value being -ve for sqrt *asadr */ -void _vuESQRT(VURegs * VU) { +static __ri void _vuESQRT(VURegs * VU) { float p = vuDouble(VU->VF[_Fs_].UL[_Fsf_]); if (p >= 0){ p = sqrt(p); @@ -2019,7 +1986,7 @@ void _vuESQRT(VURegs * VU) { } /* Fixed. Could have caused crash due to divisor being = 0 *asadr */ -void _vuERSQRT(VURegs * VU) { +static __ri void _vuERSQRT(VURegs * VU) { float p = vuDouble(VU->VF[_Fs_].UL[_Fsf_]); if (p >= 0) { p = sqrt(p); @@ -2030,27 +1997,27 @@ void _vuERSQRT(VURegs * VU) { VU->p.F = p; } -void _vuESIN(VURegs * VU) { +static __ri void _vuESIN(VURegs * VU) { float p = sin(vuDouble(VU->VF[_Fs_].UL[_Fsf_])); VU->p.F = p; } -void _vuEATAN(VURegs * VU) { +static __ri void _vuEATAN(VURegs * VU) { float p = atan(vuDouble(VU->VF[_Fs_].UL[_Fsf_])); VU->p.F = p; } -void _vuEEXP(VURegs * VU) { +static __ri void _vuEEXP(VURegs * VU) { float p = exp(-(vuDouble(VU->VF[_Fs_].UL[_Fsf_]))); VU->p.F = p; } -void _vuXITOP(VURegs * VU) { +static __ri void _vuXITOP(VURegs * VU) { if (_It_ == 0) return; - VU->VI[_It_].US[0] = VU->vifRegs->itop; + VU->VI[_It_].US[0] = VU->GetVifRegs().itop; } -void _vuXGKICK(VURegs * VU) +static __ri void _vuXGKICK(VURegs * VU) { // flush all pipelines first (in the right order) _vuFlushAll(VU); @@ -2062,15 +2029,15 @@ void _vuXGKICK(VURegs * VU) GetMTGS().SendDataPacket(); } -void _vuXTOP(VURegs * VU) { +static __ri void _vuXTOP(VURegs * VU) { if(_It_ == 0) return; - VU->VI[_It_].US[0] = (u16)VU->vifRegs->top; + VU->VI[_It_].US[0] = (u16)VU->GetVifRegs().top; } #define GET_VF0_FLAG(reg) (((reg)==0)?(1<pipe = VUPIPE_FMAC; \ VUregsn->VFwrite = _Fd_; \ VUregsn->VFwxyzw = _XYZW; \ @@ -2082,7 +2049,7 @@ void _vuRegs##OP(VURegs * VU, _VURegsNum *VUregsn) { \ } #define VUREGS_FDFSQ(OP, ACC) \ -void _vuRegs##OP(VURegs * VU, _VURegsNum *VUregsn) { \ +static __ri void _vuRegs##OP(const VURegs* VU, _VURegsNum *VUregsn) { \ VUregsn->pipe = VUPIPE_FMAC; \ VUregsn->VFwrite = _Fd_; \ VUregsn->VFwxyzw = _XYZW; \ @@ -2094,7 +2061,7 @@ void _vuRegs##OP(VURegs * VU, _VURegsNum *VUregsn) { \ } #define VUREGS_FDFSFT(OP, ACC) \ -void _vuRegs##OP(VURegs * VU, _VURegsNum *VUregsn) { \ +static __ri void _vuRegs##OP(const VURegs* VU, _VURegsNum *VUregsn) { \ VUregsn->pipe = VUPIPE_FMAC; \ VUregsn->VFwrite = _Fd_; \ VUregsn->VFwxyzw = _XYZW; \ @@ -2107,7 +2074,7 @@ void _vuRegs##OP(VURegs * VU, _VURegsNum *VUregsn) { \ } #define VUREGS_FDFSFTxyzw(OP, xyzw, ACC) \ -void _vuRegs##OP(VURegs * VU, _VURegsNum *VUregsn) { \ +static __ri void _vuRegs##OP(const VURegs* VU, _VURegsNum *VUregsn) { \ VUregsn->pipe = VUPIPE_FMAC; \ VUregsn->VFwrite = _Fd_; \ VUregsn->VFwxyzw = _XYZW; \ @@ -2126,7 +2093,7 @@ void _vuRegs##OP(VURegs * VU, _VURegsNum *VUregsn) { \ #define VUREGS_ACCFSI(OP, readacc) \ -void _vuRegs##OP(VURegs * VU, _VURegsNum *VUregsn) { \ +static __ri void _vuRegs##OP(const VURegs* VU, _VURegsNum *VUregsn) { \ VUregsn->pipe = VUPIPE_FMAC; \ VUregsn->VFwrite = 0; \ VUregsn->VFwxyzw= _XYZW; \ @@ -2138,7 +2105,7 @@ void _vuRegs##OP(VURegs * VU, _VURegsNum *VUregsn) { \ } #define VUREGS_ACCFSQ(OP, readacc) \ -void _vuRegs##OP(VURegs * VU, _VURegsNum *VUregsn) { \ +static __ri void _vuRegs##OP(const VURegs* VU, _VURegsNum *VUregsn) { \ VUregsn->pipe = VUPIPE_FMAC; \ VUregsn->VFwrite = 0; \ VUregsn->VFwxyzw= _XYZW; \ @@ -2150,7 +2117,7 @@ void _vuRegs##OP(VURegs * VU, _VURegsNum *VUregsn) { \ } #define VUREGS_ACCFSFT(OP, readacc) \ -void _vuRegs##OP(VURegs * VU, _VURegsNum *VUregsn) { \ +static __ri void _vuRegs##OP(const VURegs* VU, _VURegsNum *VUregsn) { \ VUregsn->pipe = VUPIPE_FMAC; \ VUregsn->VFwrite = 0; \ VUregsn->VFwxyzw= _XYZW; \ @@ -2163,7 +2130,7 @@ void _vuRegs##OP(VURegs * VU, _VURegsNum *VUregsn) { \ } #define VUREGS_ACCFSFTxyzw(OP, xyzw, readacc) \ -void _vuRegs##OP(VURegs * VU, _VURegsNum *VUregsn) { \ +static __ri void _vuRegs##OP(const VURegs* VU, _VURegsNum *VUregsn) { \ VUregsn->pipe = VUPIPE_FMAC; \ VUregsn->VFwrite = 0; \ VUregsn->VFwxyzw= _XYZW; \ @@ -2181,7 +2148,7 @@ void _vuRegs##OP(VURegs * VU, _VURegsNum *VUregsn) { \ #define VUREGS_ACCFSFTw(OP, readacc) VUREGS_ACCFSFTxyzw(OP, 1, readacc) #define VUREGS_FTFS(OP) \ -void _vuRegs##OP(VURegs * VU, _VURegsNum *VUregsn) { \ +static __ri void _vuRegs##OP(const VURegs* VU, _VURegsNum *VUregsn) { \ VUregsn->pipe = VUPIPE_FMAC; \ VUregsn->VFwrite = _Ft_; \ VUregsn->VFwxyzw = _XYZW; \ @@ -2194,7 +2161,7 @@ void _vuRegs##OP(VURegs * VU, _VURegsNum *VUregsn) { \ } #define VUREGS_IDISIT(OP) \ -void _vuRegs##OP(VURegs * VU, _VURegsNum *VUregsn) { \ +static __ri void _vuRegs##OP(const VURegs* VU, _VURegsNum *VUregsn) { \ VUregsn->pipe = VUPIPE_IALU; \ VUregsn->VFwrite = 0; \ VUregsn->VFread0 = 0; \ @@ -2205,7 +2172,7 @@ void _vuRegs##OP(VURegs * VU, _VURegsNum *VUregsn) { \ } #define VUREGS_ITIS(OP) \ -void _vuRegs##OP(VURegs * VU, _VURegsNum *VUregsn) { \ +static __ri void _vuRegs##OP(const VURegs* VU, _VURegsNum *VUregsn) { \ VUregsn->pipe = VUPIPE_IALU; \ VUregsn->VFwrite = 0; \ VUregsn->VFread0 = 0; \ @@ -2216,7 +2183,7 @@ void _vuRegs##OP(VURegs * VU, _VURegsNum *VUregsn) { \ } #define VUREGS_PFS_xyzw(OP, _cycles) \ -void _vuRegs##OP(VURegs * VU, _VURegsNum *VUregsn) { \ +static __ri void _vuRegs##OP(const VURegs* VU, _VURegsNum *VUregsn) { \ VUregsn->pipe = VUPIPE_EFU; \ VUregsn->VFwrite = 0; \ VUregsn->VFread0 = _Fs_; \ @@ -2228,7 +2195,7 @@ void _vuRegs##OP(VURegs * VU, _VURegsNum *VUregsn) { \ } #define VUREGS_PFS_fsf(OP, _cycles) \ -void _vuRegs##OP(VURegs * VU, _VURegsNum *VUregsn) { \ +static __ri void _vuRegs##OP(const VURegs* VU, _VURegsNum *VUregsn) { \ VUregsn->pipe = VUPIPE_EFU; \ VUregsn->VFwrite = 0; \ VUregsn->VFread0 = _Fs_; \ @@ -2274,7 +2241,7 @@ VUREGS_ACCFSFTz(SUBAz, 0); VUREGS_ACCFSFTw(SUBAw, 0); #define VUREGS_FDFSFTxyzw_MUL(OP, ACC, xyzw) \ -void _vuRegs##OP(VURegs * VU, _VURegsNum *VUregsn) { \ +static __ri void _vuRegs##OP(const VURegs* VU, _VURegsNum *VUregsn) { \ if( _Ft_ == 0 && xyzw > 1 && _XYZW == 0xf ) { /* resetting to 0 */ \ VUregsn->pipe = VUPIPE_FMAC; \ VUregsn->VFwrite = ACC?0:_Fd_; \ @@ -2320,7 +2287,7 @@ VUREGS_FDFSI(MADDi, 1); VUREGS_FDFSQ(MADDq, 1); #define VUREGS_FDFSFT_0_xyzw(OP, xyzw) \ -void _vuRegs##OP(VURegs * VU, _VURegsNum *VUregsn) { \ +static __ri void _vuRegs##OP(const VURegs* VU, _VURegsNum *VUregsn) { \ VUregsn->pipe = VUPIPE_FMAC; \ VUregsn->VFwrite = _Fd_; \ VUregsn->VFwxyzw = _XYZW; \ @@ -2336,7 +2303,7 @@ VUREGS_FDFSFT_0_xyzw(MADDx, 8); VUREGS_FDFSFT_0_xyzw(MADDy, 4); VUREGS_FDFSFT_0_xyzw(MADDz, 2); -void _vuRegsMADDw(VURegs * VU, _VURegsNum *VUregsn) { +static __ri void _vuRegsMADDw(const VURegs* VU, _VURegsNum *VUregsn) { VUregsn->pipe = VUPIPE_FMAC; VUregsn->VFwrite = _Fd_; VUregsn->VFwxyzw = _XYZW; @@ -2379,19 +2346,19 @@ VUREGS_FDFSFTy(MAXy_, 0); VUREGS_FDFSFTz(MAXz_, 0); VUREGS_FDFSFTw(MAXw_, 0); -void _vuRegsMAXx(VURegs * VU, _VURegsNum *VUregsn) { +static __ri void _vuRegsMAXx(const VURegs* VU, _VURegsNum *VUregsn) { _vuRegsMAXx_(VU, VUregsn); if( _Fs_ == 0 && _Ft_ == 0 ) VUregsn->VIread &= ~(1<VIread &= ~(1<VIread &= ~(1<VIread &= ~(1<pipe = VUPIPE_FMAC; VUregsn->VFwrite = 0; VUregsn->VFwxyzw= 0xE; @@ -2415,7 +2382,7 @@ void _vuRegsOPMULA(VURegs * VU, _VURegsNum *VUregsn) { VUregsn->VIread = GET_VF0_FLAG(_Fs_)|GET_VF0_FLAG(_Ft_)|(1<pipe = VUPIPE_FMAC; VUregsn->VFwrite = _Fd_; VUregsn->VFwxyzw= 0xE; @@ -2427,7 +2394,7 @@ void _vuRegsOPMSUB(VURegs * VU, _VURegsNum *VUregsn) { VUregsn->VIread = GET_VF0_FLAG(_Fs_)|GET_VF0_FLAG(_Ft_)|(1<pipe = VUPIPE_NONE; VUregsn->VFwrite = 0; VUregsn->VFread0 = 0; @@ -2445,7 +2412,7 @@ VUREGS_FTFS(ITOF4); VUREGS_FTFS(ITOF12); VUREGS_FTFS(ITOF15); -void _vuRegsCLIP(VURegs * VU, _VURegsNum *VUregsn) { +static __ri void _vuRegsCLIP(const VURegs* VU, _VURegsNum *VUregsn) { VUregsn->pipe = VUPIPE_FMAC; VUregsn->VFwrite = 0; VUregsn->VFread0 = _Fs_; @@ -2460,7 +2427,7 @@ void _vuRegsCLIP(VURegs * VU, _VURegsNum *VUregsn) { /* VU Lower instructions */ /******************************/ -void _vuRegsDIV(VURegs * VU, _VURegsNum *VUregsn) { +static __ri void _vuRegsDIV(const VURegs* VU, _VURegsNum *VUregsn) { VUregsn->pipe = VUPIPE_FDIV; VUregsn->VFwrite = 0; VUregsn->VFread0 = _Fs_; @@ -2472,7 +2439,7 @@ void _vuRegsDIV(VURegs * VU, _VURegsNum *VUregsn) { VUregsn->cycles = 6; } -void _vuRegsSQRT(VURegs * VU, _VURegsNum *VUregsn) { +static __ri void _vuRegsSQRT(const VURegs* VU, _VURegsNum *VUregsn) { VUregsn->pipe = VUPIPE_FDIV; VUregsn->VFwrite = 0; VUregsn->VFread0 = 0; @@ -2484,7 +2451,7 @@ void _vuRegsSQRT(VURegs * VU, _VURegsNum *VUregsn) { VUregsn->cycles = 6; } -void _vuRegsRSQRT(VURegs * VU, _VURegsNum *VUregsn) { +static __ri void _vuRegsRSQRT(const VURegs* VU, _VURegsNum *VUregsn) { VUregsn->pipe = VUPIPE_FDIV; VUregsn->VFwrite = 0; VUregsn->VFread0 = _Fs_; @@ -2506,7 +2473,7 @@ VUREGS_ITIS(ISUBIU); VUREGS_FTFS(MOVE); -void _vuRegsMFIR(VURegs * VU, _VURegsNum *VUregsn) { +static __ri void _vuRegsMFIR(const VURegs* VU, _VURegsNum *VUregsn) { VUregsn->pipe = VUPIPE_FMAC; VUregsn->VFwrite = _Ft_; VUregsn->VFwxyzw = _XYZW; @@ -2516,7 +2483,7 @@ void _vuRegsMFIR(VURegs * VU, _VURegsNum *VUregsn) { VUregsn->VIread = 1 << _Is_; } -void _vuRegsMTIR(VURegs * VU, _VURegsNum *VUregsn) { +static __ri void _vuRegsMTIR(const VURegs* VU, _VURegsNum *VUregsn) { VUregsn->pipe = VUPIPE_FMAC; VUregsn->VFwrite = 0; VUregsn->VFread0 = _Fs_; @@ -2526,7 +2493,7 @@ void _vuRegsMTIR(VURegs * VU, _VURegsNum *VUregsn) { VUregsn->VIread = GET_VF0_FLAG(_Fs_); } -void _vuRegsMR32(VURegs * VU, _VURegsNum *VUregsn) { +static __ri void _vuRegsMR32(const VURegs* VU, _VURegsNum *VUregsn) { VUregsn->pipe = VUPIPE_FMAC; VUregsn->VFwrite = _Ft_; VUregsn->VFwxyzw = _XYZW; @@ -2538,7 +2505,7 @@ void _vuRegsMR32(VURegs * VU, _VURegsNum *VUregsn) { VUregsn->VIread = (_Ft_ ? GET_VF0_FLAG(_Fs_) : 0); } -void _vuRegsLQ(VURegs * VU, _VURegsNum *VUregsn) { +static __ri void _vuRegsLQ(const VURegs* VU, _VURegsNum *VUregsn) { VUregsn->pipe = VUPIPE_FMAC; VUregsn->VFwrite = _Ft_; VUregsn->VFwxyzw = _XYZW; @@ -2548,7 +2515,7 @@ void _vuRegsLQ(VURegs * VU, _VURegsNum *VUregsn) { VUregsn->VIread = 1 << _Is_; } -void _vuRegsLQD(VURegs * VU, _VURegsNum *VUregsn) { +static __ri void _vuRegsLQD(const VURegs* VU, _VURegsNum *VUregsn) { VUregsn->pipe = VUPIPE_FMAC; VUregsn->VFwrite = _Ft_; VUregsn->VFwxyzw = _XYZW; @@ -2558,7 +2525,7 @@ void _vuRegsLQD(VURegs * VU, _VURegsNum *VUregsn) { VUregsn->VIread = 1 << _Is_; } -void _vuRegsLQI(VURegs * VU, _VURegsNum *VUregsn) { +static __ri void _vuRegsLQI(const VURegs* VU, _VURegsNum *VUregsn) { VUregsn->pipe = VUPIPE_FMAC; VUregsn->VFwrite = _Ft_; VUregsn->VFwxyzw = _XYZW; @@ -2568,7 +2535,7 @@ void _vuRegsLQI(VURegs * VU, _VURegsNum *VUregsn) { VUregsn->VIread = 1 << _Is_; } -void _vuRegsSQ(VURegs * VU, _VURegsNum *VUregsn) { +static __ri void _vuRegsSQ(const VURegs* VU, _VURegsNum *VUregsn) { VUregsn->pipe = VUPIPE_FMAC; VUregsn->VFwrite = 0; VUregsn->VFread0 = _Fs_; @@ -2578,7 +2545,7 @@ void _vuRegsSQ(VURegs * VU, _VURegsNum *VUregsn) { VUregsn->VIread = 1 << _It_; } -void _vuRegsSQD(VURegs * VU, _VURegsNum *VUregsn) { +static __ri void _vuRegsSQD(const VURegs* VU, _VURegsNum *VUregsn) { VUregsn->pipe = VUPIPE_FMAC; VUregsn->VFwrite = 0; VUregsn->VFread0 = _Fs_; @@ -2588,7 +2555,7 @@ void _vuRegsSQD(VURegs * VU, _VURegsNum *VUregsn) { VUregsn->VIread = 1 << _It_; } -void _vuRegsSQI(VURegs * VU, _VURegsNum *VUregsn) { +static __ri void _vuRegsSQI(const VURegs* VU, _VURegsNum *VUregsn) { VUregsn->pipe = VUPIPE_FMAC; VUregsn->VFwrite = 0; VUregsn->VFread0 = _Fs_; @@ -2598,7 +2565,7 @@ void _vuRegsSQI(VURegs * VU, _VURegsNum *VUregsn) { VUregsn->VIread = 1 << _It_; } -void _vuRegsILW(VURegs * VU, _VURegsNum *VUregsn) { +static __ri void _vuRegsILW(const VURegs* VU, _VURegsNum *VUregsn) { VUregsn->pipe = VUPIPE_IALU; VUregsn->VFwrite = 0; VUregsn->VFread0 = 0; @@ -2608,7 +2575,7 @@ void _vuRegsILW(VURegs * VU, _VURegsNum *VUregsn) { VUregsn->cycles = 3; } -void _vuRegsISW(VURegs * VU, _VURegsNum *VUregsn) { +static __ri void _vuRegsISW(const VURegs* VU, _VURegsNum *VUregsn) { VUregsn->pipe = VUPIPE_IALU; VUregsn->VFwrite = 0; VUregsn->VFread0 = 0; @@ -2617,7 +2584,7 @@ void _vuRegsISW(VURegs * VU, _VURegsNum *VUregsn) { VUregsn->VIread = (1 << _Is_) | (1 << _It_); } -void _vuRegsILWR(VURegs * VU, _VURegsNum *VUregsn) { +static __ri void _vuRegsILWR(const VURegs* VU, _VURegsNum *VUregsn) { VUregsn->pipe = VUPIPE_IALU; VUregsn->VFwrite = 0; VUregsn->VFread0 = 0; @@ -2627,7 +2594,7 @@ void _vuRegsILWR(VURegs * VU, _VURegsNum *VUregsn) { VUregsn->cycles = 3; } -void _vuRegsISWR(VURegs * VU, _VURegsNum *VUregsn) { +static __ri void _vuRegsISWR(const VURegs* VU, _VURegsNum *VUregsn) { VUregsn->pipe = VUPIPE_IALU; VUregsn->VFwrite = 0; VUregsn->VFread0 = 0; @@ -2636,7 +2603,7 @@ void _vuRegsISWR(VURegs * VU, _VURegsNum *VUregsn) { VUregsn->VIread = (1 << _Is_) | (1 << _It_); } -void _vuRegsRINIT(VURegs * VU, _VURegsNum *VUregsn) { +static __ri void _vuRegsRINIT(const VURegs* VU, _VURegsNum *VUregsn) { VUregsn->pipe = VUPIPE_FMAC; VUregsn->VFwrite = 0; VUregsn->VFread0 = _Fs_; @@ -2646,7 +2613,7 @@ void _vuRegsRINIT(VURegs * VU, _VURegsNum *VUregsn) { VUregsn->VIread = GET_VF0_FLAG(_Fs_); } -void _vuRegsRGET(VURegs * VU, _VURegsNum *VUregsn) { +static __ri void _vuRegsRGET(const VURegs* VU, _VURegsNum *VUregsn) { VUregsn->pipe = VUPIPE_FMAC; VUregsn->VFwrite = _Ft_; VUregsn->VFwxyzw = _XYZW; @@ -2656,7 +2623,7 @@ void _vuRegsRGET(VURegs * VU, _VURegsNum *VUregsn) { VUregsn->VIread = 1 << REG_R; } -void _vuRegsRNEXT(VURegs * VU, _VURegsNum *VUregsn) { +static __ri void _vuRegsRNEXT(const VURegs* VU, _VURegsNum *VUregsn) { VUregsn->pipe = VUPIPE_FMAC; VUregsn->VFwrite = _Ft_; VUregsn->VFwxyzw = _XYZW; @@ -2666,7 +2633,7 @@ void _vuRegsRNEXT(VURegs * VU, _VURegsNum *VUregsn) { VUregsn->VIread = 1 << REG_R; } -void _vuRegsRXOR(VURegs * VU, _VURegsNum *VUregsn) { +static __ri void _vuRegsRXOR(const VURegs* VU, _VURegsNum *VUregsn) { VUregsn->pipe = VUPIPE_FMAC; VUregsn->VFwrite = 0; VUregsn->VFread0 = _Fs_; @@ -2676,7 +2643,7 @@ void _vuRegsRXOR(VURegs * VU, _VURegsNum *VUregsn) { VUregsn->VIread = (1 << REG_R)|GET_VF0_FLAG(_Fs_); } -void _vuRegsWAITQ(VURegs * VU, _VURegsNum *VUregsn) { +static __ri void _vuRegsWAITQ(const VURegs* VU, _VURegsNum *VUregsn) { VUregsn->pipe = VUPIPE_FDIV; VUregsn->VFwrite = 0; VUregsn->VFread0 = 0; @@ -2685,7 +2652,7 @@ void _vuRegsWAITQ(VURegs * VU, _VURegsNum *VUregsn) { VUregsn->VIread = 0; } -void _vuRegsFSAND(VURegs * VU, _VURegsNum *VUregsn) { +static __ri void _vuRegsFSAND(const VURegs* VU, _VURegsNum *VUregsn) { VUregsn->pipe = VUPIPE_FMAC; VUregsn->VFwrite = 0; VUregsn->VFread0 = 0; @@ -2694,7 +2661,7 @@ void _vuRegsFSAND(VURegs * VU, _VURegsNum *VUregsn) { VUregsn->VIread = 1 << REG_STATUS_FLAG; } -void _vuRegsFSEQ(VURegs * VU, _VURegsNum *VUregsn) { +static __ri void _vuRegsFSEQ(const VURegs* VU, _VURegsNum *VUregsn) { VUregsn->pipe = VUPIPE_FMAC; VUregsn->VFwrite = 0; VUregsn->VFread0 = 0; @@ -2703,7 +2670,7 @@ void _vuRegsFSEQ(VURegs * VU, _VURegsNum *VUregsn) { VUregsn->VIread = 1 << REG_STATUS_FLAG; } -void _vuRegsFSOR(VURegs * VU, _VURegsNum *VUregsn) { +static __ri void _vuRegsFSOR(const VURegs* VU, _VURegsNum *VUregsn) { VUregsn->pipe = VUPIPE_FMAC; VUregsn->VFwrite = 0; VUregsn->VFread0 = 0; @@ -2712,7 +2679,7 @@ void _vuRegsFSOR(VURegs * VU, _VURegsNum *VUregsn) { VUregsn->VIread = 1 << REG_STATUS_FLAG; } -void _vuRegsFSSET(VURegs * VU, _VURegsNum *VUregsn) { +static __ri void _vuRegsFSSET(const VURegs* VU, _VURegsNum *VUregsn) { VUregsn->pipe = VUPIPE_FMAC; VUregsn->VFwrite = 0; VUregsn->VFread0 = 0; @@ -2721,7 +2688,7 @@ void _vuRegsFSSET(VURegs * VU, _VURegsNum *VUregsn) { VUregsn->VIread = 0; } -void _vuRegsFMAND(VURegs * VU, _VURegsNum *VUregsn) { +static __ri void _vuRegsFMAND(const VURegs* VU, _VURegsNum *VUregsn) { VUregsn->pipe = VUPIPE_FMAC; VUregsn->VFwrite = 0; VUregsn->VFread0 = 0; @@ -2730,7 +2697,7 @@ void _vuRegsFMAND(VURegs * VU, _VURegsNum *VUregsn) { VUregsn->VIread = (1 << REG_MAC_FLAG) | (1 << _Is_); } -void _vuRegsFMEQ(VURegs * VU, _VURegsNum *VUregsn) { +static __ri void _vuRegsFMEQ(const VURegs* VU, _VURegsNum *VUregsn) { VUregsn->pipe = VUPIPE_FMAC; VUregsn->VFwrite = 0; VUregsn->VFread0 = 0; @@ -2739,7 +2706,7 @@ void _vuRegsFMEQ(VURegs * VU, _VURegsNum *VUregsn) { VUregsn->VIread = (1 << REG_MAC_FLAG) | (1 << _Is_); } -void _vuRegsFMOR(VURegs * VU, _VURegsNum *VUregsn) { +static __ri void _vuRegsFMOR(const VURegs* VU, _VURegsNum *VUregsn) { VUregsn->pipe = VUPIPE_FMAC; VUregsn->VFwrite = 0; VUregsn->VFread0 = 0; @@ -2748,7 +2715,7 @@ void _vuRegsFMOR(VURegs * VU, _VURegsNum *VUregsn) { VUregsn->VIread = (1 << REG_MAC_FLAG) | (1 << _Is_); } -void _vuRegsFCAND(VURegs * VU, _VURegsNum *VUregsn) { +static __ri void _vuRegsFCAND(const VURegs* VU, _VURegsNum *VUregsn) { VUregsn->pipe = VUPIPE_FMAC; VUregsn->VFwrite = 0; VUregsn->VFread0 = 0; @@ -2757,7 +2724,7 @@ void _vuRegsFCAND(VURegs * VU, _VURegsNum *VUregsn) { VUregsn->VIread = 1 << REG_CLIP_FLAG; } -void _vuRegsFCEQ(VURegs * VU, _VURegsNum *VUregsn) { +static __ri void _vuRegsFCEQ(const VURegs* VU, _VURegsNum *VUregsn) { VUregsn->pipe = VUPIPE_FMAC; VUregsn->VFwrite = 0; VUregsn->VFread0 = 0; @@ -2766,7 +2733,7 @@ void _vuRegsFCEQ(VURegs * VU, _VURegsNum *VUregsn) { VUregsn->VIread = 1 << REG_CLIP_FLAG; } -void _vuRegsFCOR(VURegs * VU, _VURegsNum *VUregsn) { +static __ri void _vuRegsFCOR(const VURegs* VU, _VURegsNum *VUregsn) { VUregsn->pipe = VUPIPE_FMAC; VUregsn->VFwrite = 0; VUregsn->VFread0 = 0; @@ -2775,7 +2742,7 @@ void _vuRegsFCOR(VURegs * VU, _VURegsNum *VUregsn) { VUregsn->VIread = 1 << REG_CLIP_FLAG; } -void _vuRegsFCSET(VURegs * VU, _VURegsNum *VUregsn) { +static __ri void _vuRegsFCSET(const VURegs* VU, _VURegsNum *VUregsn) { VUregsn->pipe = VUPIPE_FMAC; VUregsn->VFwrite = 0; VUregsn->VFread0 = 0; @@ -2784,7 +2751,7 @@ void _vuRegsFCSET(VURegs * VU, _VURegsNum *VUregsn) { VUregsn->VIread = 0; } -void _vuRegsFCGET(VURegs * VU, _VURegsNum *VUregsn) { +static __ri void _vuRegsFCGET(const VURegs* VU, _VURegsNum *VUregsn) { VUregsn->pipe = VUPIPE_FMAC; VUregsn->VFwrite = 0; VUregsn->VFread0 = 0; @@ -2793,7 +2760,7 @@ void _vuRegsFCGET(VURegs * VU, _VURegsNum *VUregsn) { VUregsn->VIread = 1 << REG_CLIP_FLAG; } -void _vuRegsIBEQ(VURegs * VU, _VURegsNum *VUregsn) { +static __ri void _vuRegsIBEQ(const VURegs* VU, _VURegsNum *VUregsn) { VUregsn->pipe = VUPIPE_BRANCH; VUregsn->VFwrite = 0; VUregsn->VFread0 = 0; @@ -2802,7 +2769,7 @@ void _vuRegsIBEQ(VURegs * VU, _VURegsNum *VUregsn) { VUregsn->VIread = (1 << _Is_) | (1 << _It_); } -void _vuRegsIBGEZ(VURegs * VU, _VURegsNum *VUregsn) { +static __ri void _vuRegsIBGEZ(const VURegs* VU, _VURegsNum *VUregsn) { VUregsn->pipe = VUPIPE_BRANCH; VUregsn->VFwrite = 0; VUregsn->VFread0 = 0; @@ -2811,7 +2778,7 @@ void _vuRegsIBGEZ(VURegs * VU, _VURegsNum *VUregsn) { VUregsn->VIread = 1 << _Is_; } -void _vuRegsIBGTZ(VURegs * VU, _VURegsNum *VUregsn) { +static __ri void _vuRegsIBGTZ(const VURegs* VU, _VURegsNum *VUregsn) { VUregsn->pipe = VUPIPE_BRANCH; VUregsn->VFwrite = 0; VUregsn->VFread0 = 0; @@ -2820,7 +2787,7 @@ void _vuRegsIBGTZ(VURegs * VU, _VURegsNum *VUregsn) { VUregsn->VIread = 1 << _Is_; } -void _vuRegsIBLEZ(VURegs * VU, _VURegsNum *VUregsn) { +static __ri void _vuRegsIBLEZ(const VURegs* VU, _VURegsNum *VUregsn) { VUregsn->pipe = VUPIPE_BRANCH; VUregsn->VFwrite = 0; VUregsn->VFread0 = 0; @@ -2829,7 +2796,7 @@ void _vuRegsIBLEZ(VURegs * VU, _VURegsNum *VUregsn) { VUregsn->VIread = 1 << _Is_; } -void _vuRegsIBLTZ(VURegs * VU, _VURegsNum *VUregsn) { +static __ri void _vuRegsIBLTZ(const VURegs* VU, _VURegsNum *VUregsn) { VUregsn->pipe = VUPIPE_BRANCH; VUregsn->VFwrite = 0; VUregsn->VFread0 = 0; @@ -2838,7 +2805,7 @@ void _vuRegsIBLTZ(VURegs * VU, _VURegsNum *VUregsn) { VUregsn->VIread = 1 << _Is_; } -void _vuRegsIBNE(VURegs * VU, _VURegsNum *VUregsn) { +static __ri void _vuRegsIBNE(const VURegs* VU, _VURegsNum *VUregsn) { VUregsn->pipe = VUPIPE_BRANCH; VUregsn->VFwrite = 0; VUregsn->VFread0 = 0; @@ -2847,7 +2814,7 @@ void _vuRegsIBNE(VURegs * VU, _VURegsNum *VUregsn) { VUregsn->VIread = (1 << _Is_) | (1 << _It_); } -void _vuRegsB(VURegs * VU, _VURegsNum *VUregsn) { +static __ri void _vuRegsB(const VURegs* VU, _VURegsNum *VUregsn) { VUregsn->pipe = VUPIPE_BRANCH; VUregsn->VFwrite = 0; VUregsn->VFread0 = 0; @@ -2856,7 +2823,7 @@ void _vuRegsB(VURegs * VU, _VURegsNum *VUregsn) { VUregsn->VIread = 0; } -void _vuRegsBAL(VURegs * VU, _VURegsNum *VUregsn) { +static __ri void _vuRegsBAL(const VURegs* VU, _VURegsNum *VUregsn) { VUregsn->pipe = VUPIPE_BRANCH; VUregsn->VFwrite = 0; VUregsn->VFread0 = 0; @@ -2865,7 +2832,7 @@ void _vuRegsBAL(VURegs * VU, _VURegsNum *VUregsn) { VUregsn->VIread = 0; } -void _vuRegsJR(VURegs * VU, _VURegsNum *VUregsn) { +static __ri void _vuRegsJR(const VURegs* VU, _VURegsNum *VUregsn) { VUregsn->pipe = VUPIPE_BRANCH; VUregsn->VFwrite = 0; VUregsn->VFread0 = 0; @@ -2874,7 +2841,7 @@ void _vuRegsJR(VURegs * VU, _VURegsNum *VUregsn) { VUregsn->VIread = 1 << _Is_; } -void _vuRegsJALR(VURegs * VU, _VURegsNum *VUregsn) { +static __ri void _vuRegsJALR(const VURegs* VU, _VURegsNum *VUregsn) { VUregsn->pipe = VUPIPE_BRANCH; VUregsn->VFwrite = 0; VUregsn->VFread0 = 0; @@ -2883,7 +2850,7 @@ void _vuRegsJALR(VURegs * VU, _VURegsNum *VUregsn) { VUregsn->VIread = 1 << _Is_; } -void _vuRegsMFP(VURegs * VU, _VURegsNum *VUregsn) { +static __ri void _vuRegsMFP(const VURegs* VU, _VURegsNum *VUregsn) { VUregsn->pipe = VUPIPE_FMAC; VUregsn->VFwrite = _Ft_; VUregsn->VFwxyzw = _XYZW; @@ -2893,7 +2860,7 @@ void _vuRegsMFP(VURegs * VU, _VURegsNum *VUregsn) { VUregsn->VIread = 1 << REG_P; } -void _vuRegsWAITP(VURegs * VU, _VURegsNum *VUregsn) { +static __ri void _vuRegsWAITP(const VURegs* VU, _VURegsNum *VUregsn) { VUregsn->pipe = VUPIPE_EFU; VUregsn->VFwrite = 0; VUregsn->VFread0 = 0; @@ -2916,7 +2883,7 @@ VUREGS_PFS_fsf(ESIN, 28); VUREGS_PFS_fsf(EATAN, 53); VUREGS_PFS_fsf(EEXP, 43); -void _vuRegsXITOP(VURegs * VU, _VURegsNum *VUregsn) { +static __ri void _vuRegsXITOP(const VURegs* VU, _VURegsNum *VUregsn) { VUregsn->pipe = VUPIPE_IALU; VUregsn->VFwrite = 0; VUregsn->VFread0 = 0; @@ -2926,7 +2893,7 @@ void _vuRegsXITOP(VURegs * VU, _VURegsNum *VUregsn) { VUregsn->cycles = 0; } -void _vuRegsXGKICK(VURegs * VU, _VURegsNum *VUregsn) { +static __ri void _vuRegsXGKICK(const VURegs* VU, _VURegsNum *VUregsn) { VUregsn->pipe = VUPIPE_XGKICK; VUregsn->VFwrite = 0; VUregsn->VFread0 = 0; @@ -2935,7 +2902,7 @@ void _vuRegsXGKICK(VURegs * VU, _VURegsNum *VUregsn) { VUregsn->VIread = 1 << _Is_; } -void _vuRegsXTOP(VURegs * VU, _VURegsNum *VUregsn) { +static __ri void _vuRegsXTOP(const VURegs* VU, _VURegsNum *VUregsn) { VUregsn->pipe = VUPIPE_IALU; VUregsn->VFwrite = 0; VUregsn->VFread0 = 0; @@ -2944,3 +2911,1170 @@ void _vuRegsXTOP(VURegs * VU, _VURegsNum *VUregsn) { VUregsn->VIread = 0; VUregsn->cycles = 0; } + +// -------------------------------------------------------------------------------------- +// VU0 +// -------------------------------------------------------------------------------------- + +/****************************************/ +/* VU Micromode Upper instructions */ +/****************************************/ + +static void VU0MI_ABS() { _vuABS(&VU0); } +static void VU0MI_ADD() { _vuADD(&VU0); } +static void VU0MI_ADDi() { _vuADDi(&VU0); } +static void VU0MI_ADDq() { _vuADDq(&VU0); } +static void VU0MI_ADDx() { _vuADDx(&VU0); } +static void VU0MI_ADDy() { _vuADDy(&VU0); } +static void VU0MI_ADDz() { _vuADDz(&VU0); } +static void VU0MI_ADDw() { _vuADDw(&VU0); } +static void VU0MI_ADDA() { _vuADDA(&VU0); } +static void VU0MI_ADDAi() { _vuADDAi(&VU0); } +static void VU0MI_ADDAq() { _vuADDAq(&VU0); } +static void VU0MI_ADDAx() { _vuADDAx(&VU0); } +static void VU0MI_ADDAy() { _vuADDAy(&VU0); } +static void VU0MI_ADDAz() { _vuADDAz(&VU0); } +static void VU0MI_ADDAw() { _vuADDAw(&VU0); } +static void VU0MI_SUB() { _vuSUB(&VU0); } +static void VU0MI_SUBi() { _vuSUBi(&VU0); } +static void VU0MI_SUBq() { _vuSUBq(&VU0); } +static void VU0MI_SUBx() { _vuSUBx(&VU0); } +static void VU0MI_SUBy() { _vuSUBy(&VU0); } +static void VU0MI_SUBz() { _vuSUBz(&VU0); } +static void VU0MI_SUBw() { _vuSUBw(&VU0); } +static void VU0MI_SUBA() { _vuSUBA(&VU0); } +static void VU0MI_SUBAi() { _vuSUBAi(&VU0); } +static void VU0MI_SUBAq() { _vuSUBAq(&VU0); } +static void VU0MI_SUBAx() { _vuSUBAx(&VU0); } +static void VU0MI_SUBAy() { _vuSUBAy(&VU0); } +static void VU0MI_SUBAz() { _vuSUBAz(&VU0); } +static void VU0MI_SUBAw() { _vuSUBAw(&VU0); } +static void VU0MI_MUL() { _vuMUL(&VU0); } +static void VU0MI_MULi() { _vuMULi(&VU0); } +static void VU0MI_MULq() { _vuMULq(&VU0); } +static void VU0MI_MULx() { _vuMULx(&VU0); } +static void VU0MI_MULy() { _vuMULy(&VU0); } +static void VU0MI_MULz() { _vuMULz(&VU0); } +static void VU0MI_MULw() { _vuMULw(&VU0); } +static void VU0MI_MULA() { _vuMULA(&VU0); } +static void VU0MI_MULAi() { _vuMULAi(&VU0); } +static void VU0MI_MULAq() { _vuMULAq(&VU0); } +static void VU0MI_MULAx() { _vuMULAx(&VU0); } +static void VU0MI_MULAy() { _vuMULAy(&VU0); } +static void VU0MI_MULAz() { _vuMULAz(&VU0); } +static void VU0MI_MULAw() { _vuMULAw(&VU0); } +static void VU0MI_MADD() { _vuMADD(&VU0); } +static void VU0MI_MADDi() { _vuMADDi(&VU0); } +static void VU0MI_MADDq() { _vuMADDq(&VU0); } +static void VU0MI_MADDx() { _vuMADDx(&VU0); } +static void VU0MI_MADDy() { _vuMADDy(&VU0); } +static void VU0MI_MADDz() { _vuMADDz(&VU0); } +static void VU0MI_MADDw() { _vuMADDw(&VU0); } +static void VU0MI_MADDA() { _vuMADDA(&VU0); } +static void VU0MI_MADDAi() { _vuMADDAi(&VU0); } +static void VU0MI_MADDAq() { _vuMADDAq(&VU0); } +static void VU0MI_MADDAx() { _vuMADDAx(&VU0); } +static void VU0MI_MADDAy() { _vuMADDAy(&VU0); } +static void VU0MI_MADDAz() { _vuMADDAz(&VU0); } +static void VU0MI_MADDAw() { _vuMADDAw(&VU0); } +static void VU0MI_MSUB() { _vuMSUB(&VU0); } +static void VU0MI_MSUBi() { _vuMSUBi(&VU0); } +static void VU0MI_MSUBq() { _vuMSUBq(&VU0); } +static void VU0MI_MSUBx() { _vuMSUBx(&VU0); } +static void VU0MI_MSUBy() { _vuMSUBy(&VU0); } +static void VU0MI_MSUBz() { _vuMSUBz(&VU0); } +static void VU0MI_MSUBw() { _vuMSUBw(&VU0); } +static void VU0MI_MSUBA() { _vuMSUBA(&VU0); } +static void VU0MI_MSUBAi() { _vuMSUBAi(&VU0); } +static void VU0MI_MSUBAq() { _vuMSUBAq(&VU0); } +static void VU0MI_MSUBAx() { _vuMSUBAx(&VU0); } +static void VU0MI_MSUBAy() { _vuMSUBAy(&VU0); } +static void VU0MI_MSUBAz() { _vuMSUBAz(&VU0); } +static void VU0MI_MSUBAw() { _vuMSUBAw(&VU0); } +static void VU0MI_MAX() { _vuMAX(&VU0); } +static void VU0MI_MAXi() { _vuMAXi(&VU0); } +static void VU0MI_MAXx() { _vuMAXx(&VU0); } +static void VU0MI_MAXy() { _vuMAXy(&VU0); } +static void VU0MI_MAXz() { _vuMAXz(&VU0); } +static void VU0MI_MAXw() { _vuMAXw(&VU0); } +static void VU0MI_MINI() { _vuMINI(&VU0); } +static void VU0MI_MINIi() { _vuMINIi(&VU0); } +static void VU0MI_MINIx() { _vuMINIx(&VU0); } +static void VU0MI_MINIy() { _vuMINIy(&VU0); } +static void VU0MI_MINIz() { _vuMINIz(&VU0); } +static void VU0MI_MINIw() { _vuMINIw(&VU0); } +static void VU0MI_OPMULA() { _vuOPMULA(&VU0); } +static void VU0MI_OPMSUB() { _vuOPMSUB(&VU0); } +static void VU0MI_NOP() { _vuNOP(&VU0); } +static void VU0MI_FTOI0() { _vuFTOI0(&VU0); } +static void VU0MI_FTOI4() { _vuFTOI4(&VU0); } +static void VU0MI_FTOI12() { _vuFTOI12(&VU0); } +static void VU0MI_FTOI15() { _vuFTOI15(&VU0); } +static void VU0MI_ITOF0() { _vuITOF0(&VU0); } +static void VU0MI_ITOF4() { _vuITOF4(&VU0); } +static void VU0MI_ITOF12() { _vuITOF12(&VU0); } +static void VU0MI_ITOF15() { _vuITOF15(&VU0); } +static void VU0MI_CLIP() { _vuCLIP(&VU0); } + +/*****************************************/ +/* VU Micromode Lower instructions */ +/*****************************************/ + +static void VU0MI_DIV() { _vuDIV(&VU0); } +static void VU0MI_SQRT() { _vuSQRT(&VU0); } +static void VU0MI_RSQRT() { _vuRSQRT(&VU0); } +static void VU0MI_IADD() { _vuIADD(&VU0); } +static void VU0MI_IADDI() { _vuIADDI(&VU0); } +static void VU0MI_IADDIU() { _vuIADDIU(&VU0); } +static void VU0MI_IAND() { _vuIAND(&VU0); } +static void VU0MI_IOR() { _vuIOR(&VU0); } +static void VU0MI_ISUB() { _vuISUB(&VU0); } +static void VU0MI_ISUBIU() { _vuISUBIU(&VU0); } +static void VU0MI_MOVE() { _vuMOVE(&VU0); } +static void VU0MI_MFIR() { _vuMFIR(&VU0); } +static void VU0MI_MTIR() { _vuMTIR(&VU0); } +static void VU0MI_MR32() { _vuMR32(&VU0); } +static void VU0MI_LQ() { _vuLQ(&VU0); } +static void VU0MI_LQD() { _vuLQD(&VU0); } +static void VU0MI_LQI() { _vuLQI(&VU0); } +static void VU0MI_SQ() { _vuSQ(&VU0); } +static void VU0MI_SQD() { _vuSQD(&VU0); } +static void VU0MI_SQI() { _vuSQI(&VU0); } +static void VU0MI_ILW() { _vuILW(&VU0); } +static void VU0MI_ISW() { _vuISW(&VU0); } +static void VU0MI_ILWR() { _vuILWR(&VU0); } +static void VU0MI_ISWR() { _vuISWR(&VU0); } +static void VU0MI_RINIT() { _vuRINIT(&VU0); } +static void VU0MI_RGET() { _vuRGET(&VU0); } +static void VU0MI_RNEXT() { _vuRNEXT(&VU0); } +static void VU0MI_RXOR() { _vuRXOR(&VU0); } +static void VU0MI_WAITQ() { _vuWAITQ(&VU0); } +static void VU0MI_FSAND() { _vuFSAND(&VU0); } +static void VU0MI_FSEQ() { _vuFSEQ(&VU0); } +static void VU0MI_FSOR() { _vuFSOR(&VU0); } +static void VU0MI_FSSET() { _vuFSSET(&VU0); } +static void VU0MI_FMAND() { _vuFMAND(&VU0); } +static void VU0MI_FMEQ() { _vuFMEQ(&VU0); } +static void VU0MI_FMOR() { _vuFMOR(&VU0); } +static void VU0MI_FCAND() { _vuFCAND(&VU0); } +static void VU0MI_FCEQ() { _vuFCEQ(&VU0); } +static void VU0MI_FCOR() { _vuFCOR(&VU0); } +static void VU0MI_FCSET() { _vuFCSET(&VU0); } +static void VU0MI_FCGET() { _vuFCGET(&VU0); } +static void VU0MI_IBEQ() { _vuIBEQ(&VU0); } +static void VU0MI_IBGEZ() { _vuIBGEZ(&VU0); } +static void VU0MI_IBGTZ() { _vuIBGTZ(&VU0); } +static void VU0MI_IBLTZ() { _vuIBLTZ(&VU0); } +static void VU0MI_IBLEZ() { _vuIBLEZ(&VU0); } +static void VU0MI_IBNE() { _vuIBNE(&VU0); } +static void VU0MI_B() { _vuB(&VU0); } +static void VU0MI_BAL() { _vuBAL(&VU0); } +static void VU0MI_JR() { _vuJR(&VU0); } +static void VU0MI_JALR() { _vuJALR(&VU0); } +static void VU0MI_MFP() { _vuMFP(&VU0); } +static void VU0MI_WAITP() { _vuWAITP(&VU0); } +static void VU0MI_ESADD() { _vuESADD(&VU0); } +static void VU0MI_ERSADD() { _vuERSADD(&VU0); } +static void VU0MI_ELENG() { _vuELENG(&VU0); } +static void VU0MI_ERLENG() { _vuERLENG(&VU0); } +static void VU0MI_EATANxy() { _vuEATANxy(&VU0); } +static void VU0MI_EATANxz() { _vuEATANxz(&VU0); } +static void VU0MI_ESUM() { _vuESUM(&VU0); } +static void VU0MI_ERCPR() { _vuERCPR(&VU0); } +static void VU0MI_ESQRT() { _vuESQRT(&VU0); } +static void VU0MI_ERSQRT() { _vuERSQRT(&VU0); } +static void VU0MI_ESIN() { _vuESIN(&VU0); } +static void VU0MI_EATAN() { _vuEATAN(&VU0); } +static void VU0MI_EEXP() { _vuEEXP(&VU0); } +static void VU0MI_XITOP() { _vuXITOP(&VU0); } +static void VU0MI_XGKICK() {} +static void VU0MI_XTOP() {} + +/****************************************/ +/* VU Micromode Upper instructions */ +/****************************************/ + +static void __vuRegsCall VU0regsMI_ABS(_VURegsNum *VUregsn) { _vuRegsABS(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_ADD(_VURegsNum *VUregsn) { _vuRegsADD(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_ADDi(_VURegsNum *VUregsn) { _vuRegsADDi(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_ADDq(_VURegsNum *VUregsn) { _vuRegsADDq(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_ADDx(_VURegsNum *VUregsn) { _vuRegsADDx(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_ADDy(_VURegsNum *VUregsn) { _vuRegsADDy(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_ADDz(_VURegsNum *VUregsn) { _vuRegsADDz(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_ADDw(_VURegsNum *VUregsn) { _vuRegsADDw(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_ADDA(_VURegsNum *VUregsn) { _vuRegsADDA(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_ADDAi(_VURegsNum *VUregsn) { _vuRegsADDAi(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_ADDAq(_VURegsNum *VUregsn) { _vuRegsADDAq(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_ADDAx(_VURegsNum *VUregsn) { _vuRegsADDAx(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_ADDAy(_VURegsNum *VUregsn) { _vuRegsADDAy(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_ADDAz(_VURegsNum *VUregsn) { _vuRegsADDAz(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_ADDAw(_VURegsNum *VUregsn) { _vuRegsADDAw(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_SUB(_VURegsNum *VUregsn) { _vuRegsSUB(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_SUBi(_VURegsNum *VUregsn) { _vuRegsSUBi(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_SUBq(_VURegsNum *VUregsn) { _vuRegsSUBq(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_SUBx(_VURegsNum *VUregsn) { _vuRegsSUBx(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_SUBy(_VURegsNum *VUregsn) { _vuRegsSUBy(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_SUBz(_VURegsNum *VUregsn) { _vuRegsSUBz(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_SUBw(_VURegsNum *VUregsn) { _vuRegsSUBw(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_SUBA(_VURegsNum *VUregsn) { _vuRegsSUBA(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_SUBAi(_VURegsNum *VUregsn) { _vuRegsSUBAi(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_SUBAq(_VURegsNum *VUregsn) { _vuRegsSUBAq(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_SUBAx(_VURegsNum *VUregsn) { _vuRegsSUBAx(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_SUBAy(_VURegsNum *VUregsn) { _vuRegsSUBAy(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_SUBAz(_VURegsNum *VUregsn) { _vuRegsSUBAz(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_SUBAw(_VURegsNum *VUregsn) { _vuRegsSUBAw(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_MUL(_VURegsNum *VUregsn) { _vuRegsMUL(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_MULi(_VURegsNum *VUregsn) { _vuRegsMULi(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_MULq(_VURegsNum *VUregsn) { _vuRegsMULq(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_MULx(_VURegsNum *VUregsn) { _vuRegsMULx(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_MULy(_VURegsNum *VUregsn) { _vuRegsMULy(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_MULz(_VURegsNum *VUregsn) { _vuRegsMULz(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_MULw(_VURegsNum *VUregsn) { _vuRegsMULw(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_MULA(_VURegsNum *VUregsn) { _vuRegsMULA(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_MULAi(_VURegsNum *VUregsn) { _vuRegsMULAi(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_MULAq(_VURegsNum *VUregsn) { _vuRegsMULAq(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_MULAx(_VURegsNum *VUregsn) { _vuRegsMULAx(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_MULAy(_VURegsNum *VUregsn) { _vuRegsMULAy(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_MULAz(_VURegsNum *VUregsn) { _vuRegsMULAz(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_MULAw(_VURegsNum *VUregsn) { _vuRegsMULAw(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_MADD(_VURegsNum *VUregsn) { _vuRegsMADD(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_MADDi(_VURegsNum *VUregsn) { _vuRegsMADDi(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_MADDq(_VURegsNum *VUregsn) { _vuRegsMADDq(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_MADDx(_VURegsNum *VUregsn) { _vuRegsMADDx(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_MADDy(_VURegsNum *VUregsn) { _vuRegsMADDy(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_MADDz(_VURegsNum *VUregsn) { _vuRegsMADDz(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_MADDw(_VURegsNum *VUregsn) { _vuRegsMADDw(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_MADDA(_VURegsNum *VUregsn) { _vuRegsMADDA(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_MADDAi(_VURegsNum *VUregsn) { _vuRegsMADDAi(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_MADDAq(_VURegsNum *VUregsn) { _vuRegsMADDAq(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_MADDAx(_VURegsNum *VUregsn) { _vuRegsMADDAx(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_MADDAy(_VURegsNum *VUregsn) { _vuRegsMADDAy(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_MADDAz(_VURegsNum *VUregsn) { _vuRegsMADDAz(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_MADDAw(_VURegsNum *VUregsn) { _vuRegsMADDAw(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_MSUB(_VURegsNum *VUregsn) { _vuRegsMSUB(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_MSUBi(_VURegsNum *VUregsn) { _vuRegsMSUBi(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_MSUBq(_VURegsNum *VUregsn) { _vuRegsMSUBq(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_MSUBx(_VURegsNum *VUregsn) { _vuRegsMSUBx(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_MSUBy(_VURegsNum *VUregsn) { _vuRegsMSUBy(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_MSUBz(_VURegsNum *VUregsn) { _vuRegsMSUBz(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_MSUBw(_VURegsNum *VUregsn) { _vuRegsMSUBw(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_MSUBA(_VURegsNum *VUregsn) { _vuRegsMSUBA(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_MSUBAi(_VURegsNum *VUregsn) { _vuRegsMSUBAi(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_MSUBAq(_VURegsNum *VUregsn) { _vuRegsMSUBAq(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_MSUBAx(_VURegsNum *VUregsn) { _vuRegsMSUBAx(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_MSUBAy(_VURegsNum *VUregsn) { _vuRegsMSUBAy(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_MSUBAz(_VURegsNum *VUregsn) { _vuRegsMSUBAz(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_MSUBAw(_VURegsNum *VUregsn) { _vuRegsMSUBAw(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_MAX(_VURegsNum *VUregsn) { _vuRegsMAX(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_MAXi(_VURegsNum *VUregsn) { _vuRegsMAXi(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_MAXx(_VURegsNum *VUregsn) { _vuRegsMAXx(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_MAXy(_VURegsNum *VUregsn) { _vuRegsMAXy(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_MAXz(_VURegsNum *VUregsn) { _vuRegsMAXz(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_MAXw(_VURegsNum *VUregsn) { _vuRegsMAXw(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_MINI(_VURegsNum *VUregsn) { _vuRegsMINI(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_MINIi(_VURegsNum *VUregsn) { _vuRegsMINIi(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_MINIx(_VURegsNum *VUregsn) { _vuRegsMINIx(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_MINIy(_VURegsNum *VUregsn) { _vuRegsMINIy(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_MINIz(_VURegsNum *VUregsn) { _vuRegsMINIz(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_MINIw(_VURegsNum *VUregsn) { _vuRegsMINIw(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_OPMULA(_VURegsNum *VUregsn) { _vuRegsOPMULA(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_OPMSUB(_VURegsNum *VUregsn) { _vuRegsOPMSUB(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_NOP(_VURegsNum *VUregsn) { _vuRegsNOP(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_FTOI0(_VURegsNum *VUregsn) { _vuRegsFTOI0(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_FTOI4(_VURegsNum *VUregsn) { _vuRegsFTOI4(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_FTOI12(_VURegsNum *VUregsn) { _vuRegsFTOI12(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_FTOI15(_VURegsNum *VUregsn) { _vuRegsFTOI15(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_ITOF0(_VURegsNum *VUregsn) { _vuRegsITOF0(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_ITOF4(_VURegsNum *VUregsn) { _vuRegsITOF4(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_ITOF12(_VURegsNum *VUregsn) { _vuRegsITOF12(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_ITOF15(_VURegsNum *VUregsn) { _vuRegsITOF15(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_CLIP(_VURegsNum *VUregsn) { _vuRegsCLIP(&VU0, VUregsn); } + +/*****************************************/ +/* VU Micromode Lower instructions */ +/*****************************************/ + +static void __vuRegsCall VU0regsMI_DIV(_VURegsNum *VUregsn) { _vuRegsDIV(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_SQRT(_VURegsNum *VUregsn) { _vuRegsSQRT(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_RSQRT(_VURegsNum *VUregsn) { _vuRegsRSQRT(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_IADD(_VURegsNum *VUregsn) { _vuRegsIADD(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_IADDI(_VURegsNum *VUregsn) { _vuRegsIADDI(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_IADDIU(_VURegsNum *VUregsn) { _vuRegsIADDIU(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_IAND(_VURegsNum *VUregsn) { _vuRegsIAND(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_IOR(_VURegsNum *VUregsn) { _vuRegsIOR(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_ISUB(_VURegsNum *VUregsn) { _vuRegsISUB(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_ISUBIU(_VURegsNum *VUregsn) { _vuRegsISUBIU(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_MOVE(_VURegsNum *VUregsn) { _vuRegsMOVE(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_MFIR(_VURegsNum *VUregsn) { _vuRegsMFIR(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_MTIR(_VURegsNum *VUregsn) { _vuRegsMTIR(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_MR32(_VURegsNum *VUregsn) { _vuRegsMR32(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_LQ(_VURegsNum *VUregsn) { _vuRegsLQ(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_LQD(_VURegsNum *VUregsn) { _vuRegsLQD(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_LQI(_VURegsNum *VUregsn) { _vuRegsLQI(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_SQ(_VURegsNum *VUregsn) { _vuRegsSQ(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_SQD(_VURegsNum *VUregsn) { _vuRegsSQD(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_SQI(_VURegsNum *VUregsn) { _vuRegsSQI(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_ILW(_VURegsNum *VUregsn) { _vuRegsILW(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_ISW(_VURegsNum *VUregsn) { _vuRegsISW(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_ILWR(_VURegsNum *VUregsn) { _vuRegsILWR(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_ISWR(_VURegsNum *VUregsn) { _vuRegsISWR(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_RINIT(_VURegsNum *VUregsn) { _vuRegsRINIT(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_RGET(_VURegsNum *VUregsn) { _vuRegsRGET(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_RNEXT(_VURegsNum *VUregsn) { _vuRegsRNEXT(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_RXOR(_VURegsNum *VUregsn) { _vuRegsRXOR(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_WAITQ(_VURegsNum *VUregsn) { _vuRegsWAITQ(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_FSAND(_VURegsNum *VUregsn) { _vuRegsFSAND(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_FSEQ(_VURegsNum *VUregsn) { _vuRegsFSEQ(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_FSOR(_VURegsNum *VUregsn) { _vuRegsFSOR(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_FSSET(_VURegsNum *VUregsn) { _vuRegsFSSET(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_FMAND(_VURegsNum *VUregsn) { _vuRegsFMAND(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_FMEQ(_VURegsNum *VUregsn) { _vuRegsFMEQ(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_FMOR(_VURegsNum *VUregsn) { _vuRegsFMOR(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_FCAND(_VURegsNum *VUregsn) { _vuRegsFCAND(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_FCEQ(_VURegsNum *VUregsn) { _vuRegsFCEQ(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_FCOR(_VURegsNum *VUregsn) { _vuRegsFCOR(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_FCSET(_VURegsNum *VUregsn) { _vuRegsFCSET(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_FCGET(_VURegsNum *VUregsn) { _vuRegsFCGET(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_IBEQ(_VURegsNum *VUregsn) { _vuRegsIBEQ(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_IBGEZ(_VURegsNum *VUregsn) { _vuRegsIBGEZ(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_IBGTZ(_VURegsNum *VUregsn) { _vuRegsIBGTZ(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_IBLTZ(_VURegsNum *VUregsn) { _vuRegsIBLTZ(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_IBLEZ(_VURegsNum *VUregsn) { _vuRegsIBLEZ(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_IBNE(_VURegsNum *VUregsn) { _vuRegsIBNE(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_B(_VURegsNum *VUregsn) { _vuRegsB(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_BAL(_VURegsNum *VUregsn) { _vuRegsBAL(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_JR(_VURegsNum *VUregsn) { _vuRegsJR(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_JALR(_VURegsNum *VUregsn) { _vuRegsJALR(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_MFP(_VURegsNum *VUregsn) { _vuRegsMFP(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_WAITP(_VURegsNum *VUregsn) { _vuRegsWAITP(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_ESADD(_VURegsNum *VUregsn) { _vuRegsESADD(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_ERSADD(_VURegsNum *VUregsn) { _vuRegsERSADD(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_ELENG(_VURegsNum *VUregsn) { _vuRegsELENG(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_ERLENG(_VURegsNum *VUregsn) { _vuRegsERLENG(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_EATANxy(_VURegsNum *VUregsn) { _vuRegsEATANxy(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_EATANxz(_VURegsNum *VUregsn) { _vuRegsEATANxz(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_ESUM(_VURegsNum *VUregsn) { _vuRegsESUM(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_ERCPR(_VURegsNum *VUregsn) { _vuRegsERCPR(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_ESQRT(_VURegsNum *VUregsn) { _vuRegsESQRT(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_ERSQRT(_VURegsNum *VUregsn) { _vuRegsERSQRT(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_ESIN(_VURegsNum *VUregsn) { _vuRegsESIN(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_EATAN(_VURegsNum *VUregsn) { _vuRegsEATAN(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_EEXP(_VURegsNum *VUregsn) { _vuRegsEEXP(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_XITOP(_VURegsNum *VUregsn) { _vuRegsXITOP(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_XGKICK(_VURegsNum *VUregsn) { _vuRegsXGKICK(&VU0, VUregsn); } +static void __vuRegsCall VU0regsMI_XTOP(_VURegsNum *VUregsn) { _vuRegsXTOP(&VU0, VUregsn); } + +void VU0unknown() { + pxFailDev("Unknown VU micromode opcode called"); + CPU_LOG("Unknown VU micromode opcode called"); +} + +static void __vuRegsCall VU0regsunknown(_VURegsNum *VUregsn) { + pxFailDev("Unknown VU micromode opcode called"); + CPU_LOG("Unknown VU micromode opcode called"); +} + +// -------------------------------------------------------------------------------------- +// VU1 +// -------------------------------------------------------------------------------------- + +/****************************************/ +/* VU Micromode Upper instructions */ +/****************************************/ + +static void VU1MI_ABS() { _vuABS(&VU1); } +static void VU1MI_ADD() { _vuADD(&VU1); } +static void VU1MI_ADDi() { _vuADDi(&VU1); } +static void VU1MI_ADDq() { _vuADDq(&VU1); } +static void VU1MI_ADDx() { _vuADDx(&VU1); } +static void VU1MI_ADDy() { _vuADDy(&VU1); } +static void VU1MI_ADDz() { _vuADDz(&VU1); } +static void VU1MI_ADDw() { _vuADDw(&VU1); } +static void VU1MI_ADDA() { _vuADDA(&VU1); } +static void VU1MI_ADDAi() { _vuADDAi(&VU1); } +static void VU1MI_ADDAq() { _vuADDAq(&VU1); } +static void VU1MI_ADDAx() { _vuADDAx(&VU1); } +static void VU1MI_ADDAy() { _vuADDAy(&VU1); } +static void VU1MI_ADDAz() { _vuADDAz(&VU1); } +static void VU1MI_ADDAw() { _vuADDAw(&VU1); } +static void VU1MI_SUB() { _vuSUB(&VU1); } +static void VU1MI_SUBi() { _vuSUBi(&VU1); } +static void VU1MI_SUBq() { _vuSUBq(&VU1); } +static void VU1MI_SUBx() { _vuSUBx(&VU1); } +static void VU1MI_SUBy() { _vuSUBy(&VU1); } +static void VU1MI_SUBz() { _vuSUBz(&VU1); } +static void VU1MI_SUBw() { _vuSUBw(&VU1); } +static void VU1MI_SUBA() { _vuSUBA(&VU1); } +static void VU1MI_SUBAi() { _vuSUBAi(&VU1); } +static void VU1MI_SUBAq() { _vuSUBAq(&VU1); } +static void VU1MI_SUBAx() { _vuSUBAx(&VU1); } +static void VU1MI_SUBAy() { _vuSUBAy(&VU1); } +static void VU1MI_SUBAz() { _vuSUBAz(&VU1); } +static void VU1MI_SUBAw() { _vuSUBAw(&VU1); } +static void VU1MI_MUL() { _vuMUL(&VU1); } +static void VU1MI_MULi() { _vuMULi(&VU1); } +static void VU1MI_MULq() { _vuMULq(&VU1); } +static void VU1MI_MULx() { _vuMULx(&VU1); } +static void VU1MI_MULy() { _vuMULy(&VU1); } +static void VU1MI_MULz() { _vuMULz(&VU1); } +static void VU1MI_MULw() { _vuMULw(&VU1); } +static void VU1MI_MULA() { _vuMULA(&VU1); } +static void VU1MI_MULAi() { _vuMULAi(&VU1); } +static void VU1MI_MULAq() { _vuMULAq(&VU1); } +static void VU1MI_MULAx() { _vuMULAx(&VU1); } +static void VU1MI_MULAy() { _vuMULAy(&VU1); } +static void VU1MI_MULAz() { _vuMULAz(&VU1); } +static void VU1MI_MULAw() { _vuMULAw(&VU1); } +static void VU1MI_MADD() { _vuMADD(&VU1); } +static void VU1MI_MADDi() { _vuMADDi(&VU1); } +static void VU1MI_MADDq() { _vuMADDq(&VU1); } +static void VU1MI_MADDx() { _vuMADDx(&VU1); } +static void VU1MI_MADDy() { _vuMADDy(&VU1); } +static void VU1MI_MADDz() { _vuMADDz(&VU1); } +static void VU1MI_MADDw() { _vuMADDw(&VU1); } +static void VU1MI_MADDA() { _vuMADDA(&VU1); } +static void VU1MI_MADDAi() { _vuMADDAi(&VU1); } +static void VU1MI_MADDAq() { _vuMADDAq(&VU1); } +static void VU1MI_MADDAx() { _vuMADDAx(&VU1); } +static void VU1MI_MADDAy() { _vuMADDAy(&VU1); } +static void VU1MI_MADDAz() { _vuMADDAz(&VU1); } +static void VU1MI_MADDAw() { _vuMADDAw(&VU1); } +static void VU1MI_MSUB() { _vuMSUB(&VU1); } +static void VU1MI_MSUBi() { _vuMSUBi(&VU1); } +static void VU1MI_MSUBq() { _vuMSUBq(&VU1); } +static void VU1MI_MSUBx() { _vuMSUBx(&VU1); } +static void VU1MI_MSUBy() { _vuMSUBy(&VU1); } +static void VU1MI_MSUBz() { _vuMSUBz(&VU1); } +static void VU1MI_MSUBw() { _vuMSUBw(&VU1); } +static void VU1MI_MSUBA() { _vuMSUBA(&VU1); } +static void VU1MI_MSUBAi() { _vuMSUBAi(&VU1); } +static void VU1MI_MSUBAq() { _vuMSUBAq(&VU1); } +static void VU1MI_MSUBAx() { _vuMSUBAx(&VU1); } +static void VU1MI_MSUBAy() { _vuMSUBAy(&VU1); } +static void VU1MI_MSUBAz() { _vuMSUBAz(&VU1); } +static void VU1MI_MSUBAw() { _vuMSUBAw(&VU1); } +static void VU1MI_MAX() { _vuMAX(&VU1); } +static void VU1MI_MAXi() { _vuMAXi(&VU1); } +static void VU1MI_MAXx() { _vuMAXx(&VU1); } +static void VU1MI_MAXy() { _vuMAXy(&VU1); } +static void VU1MI_MAXz() { _vuMAXz(&VU1); } +static void VU1MI_MAXw() { _vuMAXw(&VU1); } +static void VU1MI_MINI() { _vuMINI(&VU1); } +static void VU1MI_MINIi() { _vuMINIi(&VU1); } +static void VU1MI_MINIx() { _vuMINIx(&VU1); } +static void VU1MI_MINIy() { _vuMINIy(&VU1); } +static void VU1MI_MINIz() { _vuMINIz(&VU1); } +static void VU1MI_MINIw() { _vuMINIw(&VU1); } +static void VU1MI_OPMULA() { _vuOPMULA(&VU1); } +static void VU1MI_OPMSUB() { _vuOPMSUB(&VU1); } +static void VU1MI_NOP() { _vuNOP(&VU1); } +static void VU1MI_FTOI0() { _vuFTOI0(&VU1); } +static void VU1MI_FTOI4() { _vuFTOI4(&VU1); } +static void VU1MI_FTOI12() { _vuFTOI12(&VU1); } +static void VU1MI_FTOI15() { _vuFTOI15(&VU1); } +static void VU1MI_ITOF0() { _vuITOF0(&VU1); } +static void VU1MI_ITOF4() { _vuITOF4(&VU1); } +static void VU1MI_ITOF12() { _vuITOF12(&VU1); } +static void VU1MI_ITOF15() { _vuITOF15(&VU1); } +static void VU1MI_CLIP() { _vuCLIP(&VU1); } + +/*****************************************/ +/* VU Micromode Lower instructions */ +/*****************************************/ + +static void VU1MI_DIV() { _vuDIV(&VU1); } +static void VU1MI_SQRT() { _vuSQRT(&VU1); } +static void VU1MI_RSQRT() { _vuRSQRT(&VU1); } +static void VU1MI_IADD() { _vuIADD(&VU1); } +static void VU1MI_IADDI() { _vuIADDI(&VU1); } +static void VU1MI_IADDIU() { _vuIADDIU(&VU1); } +static void VU1MI_IAND() { _vuIAND(&VU1); } +static void VU1MI_IOR() { _vuIOR(&VU1); } +static void VU1MI_ISUB() { _vuISUB(&VU1); } +static void VU1MI_ISUBIU() { _vuISUBIU(&VU1); } +static void VU1MI_MOVE() { _vuMOVE(&VU1); } +static void VU1MI_MFIR() { _vuMFIR(&VU1); } +static void VU1MI_MTIR() { _vuMTIR(&VU1); } +static void VU1MI_MR32() { _vuMR32(&VU1); } +static void VU1MI_LQ() { _vuLQ(&VU1); } +static void VU1MI_LQD() { _vuLQD(&VU1); } +static void VU1MI_LQI() { _vuLQI(&VU1); } +static void VU1MI_SQ() { _vuSQ(&VU1); } +static void VU1MI_SQD() { _vuSQD(&VU1); } +static void VU1MI_SQI() { _vuSQI(&VU1); } +static void VU1MI_ILW() { _vuILW(&VU1); } +static void VU1MI_ISW() { _vuISW(&VU1); } +static void VU1MI_ILWR() { _vuILWR(&VU1); } +static void VU1MI_ISWR() { _vuISWR(&VU1); } +static void VU1MI_RINIT() { _vuRINIT(&VU1); } +static void VU1MI_RGET() { _vuRGET(&VU1); } +static void VU1MI_RNEXT() { _vuRNEXT(&VU1); } +static void VU1MI_RXOR() { _vuRXOR(&VU1); } +static void VU1MI_WAITQ() { _vuWAITQ(&VU1); } +static void VU1MI_FSAND() { _vuFSAND(&VU1); } +static void VU1MI_FSEQ() { _vuFSEQ(&VU1); } +static void VU1MI_FSOR() { _vuFSOR(&VU1); } +static void VU1MI_FSSET() { _vuFSSET(&VU1); } +static void VU1MI_FMAND() { _vuFMAND(&VU1); } +static void VU1MI_FMEQ() { _vuFMEQ(&VU1); } +static void VU1MI_FMOR() { _vuFMOR(&VU1); } +static void VU1MI_FCAND() { _vuFCAND(&VU1); } +static void VU1MI_FCEQ() { _vuFCEQ(&VU1); } +static void VU1MI_FCOR() { _vuFCOR(&VU1); } +static void VU1MI_FCSET() { _vuFCSET(&VU1); } +static void VU1MI_FCGET() { _vuFCGET(&VU1); } +static void VU1MI_IBEQ() { _vuIBEQ(&VU1); } +static void VU1MI_IBGEZ() { _vuIBGEZ(&VU1); } +static void VU1MI_IBGTZ() { _vuIBGTZ(&VU1); } +static void VU1MI_IBLTZ() { _vuIBLTZ(&VU1); } +static void VU1MI_IBLEZ() { _vuIBLEZ(&VU1); } +static void VU1MI_IBNE() { _vuIBNE(&VU1); } +static void VU1MI_B() { _vuB(&VU1); } +static void VU1MI_BAL() { _vuBAL(&VU1); } +static void VU1MI_JR() { _vuJR(&VU1); } +static void VU1MI_JALR() { _vuJALR(&VU1); } +static void VU1MI_MFP() { _vuMFP(&VU1); } +static void VU1MI_WAITP() { _vuWAITP(&VU1); } +static void VU1MI_ESADD() { _vuESADD(&VU1); } +static void VU1MI_ERSADD() { _vuERSADD(&VU1); } +static void VU1MI_ELENG() { _vuELENG(&VU1); } +static void VU1MI_ERLENG() { _vuERLENG(&VU1); } +static void VU1MI_EATANxy() { _vuEATANxy(&VU1); } +static void VU1MI_EATANxz() { _vuEATANxz(&VU1); } +static void VU1MI_ESUM() { _vuESUM(&VU1); } +static void VU1MI_ERCPR() { _vuERCPR(&VU1); } +static void VU1MI_ESQRT() { _vuESQRT(&VU1); } +static void VU1MI_ERSQRT() { _vuERSQRT(&VU1); } +static void VU1MI_ESIN() { _vuESIN(&VU1); } +static void VU1MI_EATAN() { _vuEATAN(&VU1); } +static void VU1MI_EEXP() { _vuEEXP(&VU1); } +static void VU1MI_XITOP() { _vuXITOP(&VU1); } +static void VU1MI_XGKICK() { _vuXGKICK(&VU1); } +static void VU1MI_XTOP() { _vuXTOP(&VU1); } + + + +/****************************************/ +/* VU Micromode Upper instructions */ +/****************************************/ + +static void __vuRegsCall VU1regsMI_ABS(_VURegsNum *VUregsn) { _vuRegsABS(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_ADD(_VURegsNum *VUregsn) { _vuRegsADD(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_ADDi(_VURegsNum *VUregsn) { _vuRegsADDi(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_ADDq(_VURegsNum *VUregsn) { _vuRegsADDq(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_ADDx(_VURegsNum *VUregsn) { _vuRegsADDx(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_ADDy(_VURegsNum *VUregsn) { _vuRegsADDy(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_ADDz(_VURegsNum *VUregsn) { _vuRegsADDz(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_ADDw(_VURegsNum *VUregsn) { _vuRegsADDw(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_ADDA(_VURegsNum *VUregsn) { _vuRegsADDA(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_ADDAi(_VURegsNum *VUregsn) { _vuRegsADDAi(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_ADDAq(_VURegsNum *VUregsn) { _vuRegsADDAq(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_ADDAx(_VURegsNum *VUregsn) { _vuRegsADDAx(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_ADDAy(_VURegsNum *VUregsn) { _vuRegsADDAy(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_ADDAz(_VURegsNum *VUregsn) { _vuRegsADDAz(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_ADDAw(_VURegsNum *VUregsn) { _vuRegsADDAw(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_SUB(_VURegsNum *VUregsn) { _vuRegsSUB(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_SUBi(_VURegsNum *VUregsn) { _vuRegsSUBi(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_SUBq(_VURegsNum *VUregsn) { _vuRegsSUBq(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_SUBx(_VURegsNum *VUregsn) { _vuRegsSUBx(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_SUBy(_VURegsNum *VUregsn) { _vuRegsSUBy(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_SUBz(_VURegsNum *VUregsn) { _vuRegsSUBz(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_SUBw(_VURegsNum *VUregsn) { _vuRegsSUBw(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_SUBA(_VURegsNum *VUregsn) { _vuRegsSUBA(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_SUBAi(_VURegsNum *VUregsn) { _vuRegsSUBAi(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_SUBAq(_VURegsNum *VUregsn) { _vuRegsSUBAq(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_SUBAx(_VURegsNum *VUregsn) { _vuRegsSUBAx(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_SUBAy(_VURegsNum *VUregsn) { _vuRegsSUBAy(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_SUBAz(_VURegsNum *VUregsn) { _vuRegsSUBAz(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_SUBAw(_VURegsNum *VUregsn) { _vuRegsSUBAw(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_MUL(_VURegsNum *VUregsn) { _vuRegsMUL(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_MULi(_VURegsNum *VUregsn) { _vuRegsMULi(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_MULq(_VURegsNum *VUregsn) { _vuRegsMULq(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_MULx(_VURegsNum *VUregsn) { _vuRegsMULx(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_MULy(_VURegsNum *VUregsn) { _vuRegsMULy(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_MULz(_VURegsNum *VUregsn) { _vuRegsMULz(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_MULw(_VURegsNum *VUregsn) { _vuRegsMULw(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_MULA(_VURegsNum *VUregsn) { _vuRegsMULA(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_MULAi(_VURegsNum *VUregsn) { _vuRegsMULAi(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_MULAq(_VURegsNum *VUregsn) { _vuRegsMULAq(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_MULAx(_VURegsNum *VUregsn) { _vuRegsMULAx(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_MULAy(_VURegsNum *VUregsn) { _vuRegsMULAy(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_MULAz(_VURegsNum *VUregsn) { _vuRegsMULAz(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_MULAw(_VURegsNum *VUregsn) { _vuRegsMULAw(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_MADD(_VURegsNum *VUregsn) { _vuRegsMADD(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_MADDi(_VURegsNum *VUregsn) { _vuRegsMADDi(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_MADDq(_VURegsNum *VUregsn) { _vuRegsMADDq(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_MADDx(_VURegsNum *VUregsn) { _vuRegsMADDx(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_MADDy(_VURegsNum *VUregsn) { _vuRegsMADDy(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_MADDz(_VURegsNum *VUregsn) { _vuRegsMADDz(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_MADDw(_VURegsNum *VUregsn) { _vuRegsMADDw(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_MADDA(_VURegsNum *VUregsn) { _vuRegsMADDA(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_MADDAi(_VURegsNum *VUregsn) { _vuRegsMADDAi(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_MADDAq(_VURegsNum *VUregsn) { _vuRegsMADDAq(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_MADDAx(_VURegsNum *VUregsn) { _vuRegsMADDAx(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_MADDAy(_VURegsNum *VUregsn) { _vuRegsMADDAy(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_MADDAz(_VURegsNum *VUregsn) { _vuRegsMADDAz(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_MADDAw(_VURegsNum *VUregsn) { _vuRegsMADDAw(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_MSUB(_VURegsNum *VUregsn) { _vuRegsMSUB(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_MSUBi(_VURegsNum *VUregsn) { _vuRegsMSUBi(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_MSUBq(_VURegsNum *VUregsn) { _vuRegsMSUBq(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_MSUBx(_VURegsNum *VUregsn) { _vuRegsMSUBx(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_MSUBy(_VURegsNum *VUregsn) { _vuRegsMSUBy(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_MSUBz(_VURegsNum *VUregsn) { _vuRegsMSUBz(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_MSUBw(_VURegsNum *VUregsn) { _vuRegsMSUBw(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_MSUBA(_VURegsNum *VUregsn) { _vuRegsMSUBA(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_MSUBAi(_VURegsNum *VUregsn) { _vuRegsMSUBAi(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_MSUBAq(_VURegsNum *VUregsn) { _vuRegsMSUBAq(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_MSUBAx(_VURegsNum *VUregsn) { _vuRegsMSUBAx(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_MSUBAy(_VURegsNum *VUregsn) { _vuRegsMSUBAy(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_MSUBAz(_VURegsNum *VUregsn) { _vuRegsMSUBAz(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_MSUBAw(_VURegsNum *VUregsn) { _vuRegsMSUBAw(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_MAX(_VURegsNum *VUregsn) { _vuRegsMAX(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_MAXi(_VURegsNum *VUregsn) { _vuRegsMAXi(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_MAXx(_VURegsNum *VUregsn) { _vuRegsMAXx(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_MAXy(_VURegsNum *VUregsn) { _vuRegsMAXy(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_MAXz(_VURegsNum *VUregsn) { _vuRegsMAXz(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_MAXw(_VURegsNum *VUregsn) { _vuRegsMAXw(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_MINI(_VURegsNum *VUregsn) { _vuRegsMINI(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_MINIi(_VURegsNum *VUregsn) { _vuRegsMINIi(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_MINIx(_VURegsNum *VUregsn) { _vuRegsMINIx(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_MINIy(_VURegsNum *VUregsn) { _vuRegsMINIy(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_MINIz(_VURegsNum *VUregsn) { _vuRegsMINIz(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_MINIw(_VURegsNum *VUregsn) { _vuRegsMINIw(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_OPMULA(_VURegsNum *VUregsn) { _vuRegsOPMULA(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_OPMSUB(_VURegsNum *VUregsn) { _vuRegsOPMSUB(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_NOP(_VURegsNum *VUregsn) { _vuRegsNOP(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_FTOI0(_VURegsNum *VUregsn) { _vuRegsFTOI0(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_FTOI4(_VURegsNum *VUregsn) { _vuRegsFTOI4(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_FTOI12(_VURegsNum *VUregsn) { _vuRegsFTOI12(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_FTOI15(_VURegsNum *VUregsn) { _vuRegsFTOI15(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_ITOF0(_VURegsNum *VUregsn) { _vuRegsITOF0(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_ITOF4(_VURegsNum *VUregsn) { _vuRegsITOF4(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_ITOF12(_VURegsNum *VUregsn) { _vuRegsITOF12(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_ITOF15(_VURegsNum *VUregsn) { _vuRegsITOF15(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_CLIP(_VURegsNum *VUregsn) { _vuRegsCLIP(&VU1, VUregsn); } + +/*****************************************/ +/* VU Micromode Lower instructions */ +/*****************************************/ + +static void __vuRegsCall VU1regsMI_DIV(_VURegsNum *VUregsn) { _vuRegsDIV(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_SQRT(_VURegsNum *VUregsn) { _vuRegsSQRT(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_RSQRT(_VURegsNum *VUregsn) { _vuRegsRSQRT(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_IADD(_VURegsNum *VUregsn) { _vuRegsIADD(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_IADDI(_VURegsNum *VUregsn) { _vuRegsIADDI(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_IADDIU(_VURegsNum *VUregsn) { _vuRegsIADDIU(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_IAND(_VURegsNum *VUregsn) { _vuRegsIAND(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_IOR(_VURegsNum *VUregsn) { _vuRegsIOR(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_ISUB(_VURegsNum *VUregsn) { _vuRegsISUB(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_ISUBIU(_VURegsNum *VUregsn) { _vuRegsISUBIU(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_MOVE(_VURegsNum *VUregsn) { _vuRegsMOVE(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_MFIR(_VURegsNum *VUregsn) { _vuRegsMFIR(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_MTIR(_VURegsNum *VUregsn) { _vuRegsMTIR(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_MR32(_VURegsNum *VUregsn) { _vuRegsMR32(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_LQ(_VURegsNum *VUregsn) { _vuRegsLQ(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_LQD(_VURegsNum *VUregsn) { _vuRegsLQD(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_LQI(_VURegsNum *VUregsn) { _vuRegsLQI(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_SQ(_VURegsNum *VUregsn) { _vuRegsSQ(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_SQD(_VURegsNum *VUregsn) { _vuRegsSQD(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_SQI(_VURegsNum *VUregsn) { _vuRegsSQI(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_ILW(_VURegsNum *VUregsn) { _vuRegsILW(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_ISW(_VURegsNum *VUregsn) { _vuRegsISW(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_ILWR(_VURegsNum *VUregsn) { _vuRegsILWR(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_ISWR(_VURegsNum *VUregsn) { _vuRegsISWR(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_RINIT(_VURegsNum *VUregsn) { _vuRegsRINIT(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_RGET(_VURegsNum *VUregsn) { _vuRegsRGET(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_RNEXT(_VURegsNum *VUregsn) { _vuRegsRNEXT(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_RXOR(_VURegsNum *VUregsn) { _vuRegsRXOR(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_WAITQ(_VURegsNum *VUregsn) { _vuRegsWAITQ(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_FSAND(_VURegsNum *VUregsn) { _vuRegsFSAND(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_FSEQ(_VURegsNum *VUregsn) { _vuRegsFSEQ(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_FSOR(_VURegsNum *VUregsn) { _vuRegsFSOR(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_FSSET(_VURegsNum *VUregsn) { _vuRegsFSSET(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_FMAND(_VURegsNum *VUregsn) { _vuRegsFMAND(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_FMEQ(_VURegsNum *VUregsn) { _vuRegsFMEQ(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_FMOR(_VURegsNum *VUregsn) { _vuRegsFMOR(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_FCAND(_VURegsNum *VUregsn) { _vuRegsFCAND(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_FCEQ(_VURegsNum *VUregsn) { _vuRegsFCEQ(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_FCOR(_VURegsNum *VUregsn) { _vuRegsFCOR(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_FCSET(_VURegsNum *VUregsn) { _vuRegsFCSET(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_FCGET(_VURegsNum *VUregsn) { _vuRegsFCGET(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_IBEQ(_VURegsNum *VUregsn) { _vuRegsIBEQ(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_IBGEZ(_VURegsNum *VUregsn) { _vuRegsIBGEZ(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_IBGTZ(_VURegsNum *VUregsn) { _vuRegsIBGTZ(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_IBLTZ(_VURegsNum *VUregsn) { _vuRegsIBLTZ(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_IBLEZ(_VURegsNum *VUregsn) { _vuRegsIBLEZ(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_IBNE(_VURegsNum *VUregsn) { _vuRegsIBNE(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_B(_VURegsNum *VUregsn) { _vuRegsB(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_BAL(_VURegsNum *VUregsn) { _vuRegsBAL(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_JR(_VURegsNum *VUregsn) { _vuRegsJR(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_JALR(_VURegsNum *VUregsn) { _vuRegsJALR(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_MFP(_VURegsNum *VUregsn) { _vuRegsMFP(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_WAITP(_VURegsNum *VUregsn) { _vuRegsWAITP(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_ESADD(_VURegsNum *VUregsn) { _vuRegsESADD(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_ERSADD(_VURegsNum *VUregsn) { _vuRegsERSADD(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_ELENG(_VURegsNum *VUregsn) { _vuRegsELENG(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_ERLENG(_VURegsNum *VUregsn) { _vuRegsERLENG(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_EATANxy(_VURegsNum *VUregsn) { _vuRegsEATANxy(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_EATANxz(_VURegsNum *VUregsn) { _vuRegsEATANxz(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_ESUM(_VURegsNum *VUregsn) { _vuRegsESUM(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_ERCPR(_VURegsNum *VUregsn) { _vuRegsERCPR(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_ESQRT(_VURegsNum *VUregsn) { _vuRegsESQRT(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_ERSQRT(_VURegsNum *VUregsn) { _vuRegsERSQRT(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_ESIN(_VURegsNum *VUregsn) { _vuRegsESIN(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_EATAN(_VURegsNum *VUregsn) { _vuRegsEATAN(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_EEXP(_VURegsNum *VUregsn) { _vuRegsEEXP(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_XITOP(_VURegsNum *VUregsn) { _vuRegsXITOP(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_XGKICK(_VURegsNum *VUregsn) { _vuRegsXGKICK(&VU1, VUregsn); } +static void __vuRegsCall VU1regsMI_XTOP(_VURegsNum *VUregsn) { _vuRegsXTOP(&VU1, VUregsn); } + +static void VU1unknown() { + pxFailDev("Unknown VU micromode opcode called"); + CPU_LOG("Unknown VU micromode opcode called"); +} + +static void __vuRegsCall VU1regsunknown(_VURegsNum *VUregsn) { + pxFailDev("Unknown VU micromode opcode called"); + CPU_LOG("Unknown VU micromode opcode called"); +} + + + +// -------------------------------------------------------------------------------------- +// VU Micromode Tables/Opcodes defs macros +// -------------------------------------------------------------------------------------- + +#define _vuTablesMess(PREFIX, FNTYPE) \ + static __aligned16 const FNTYPE PREFIX##LowerOP_T3_00_OPCODE[32] = { \ + PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ + PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ + PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ + PREFIX##MI_MOVE , PREFIX##MI_LQI , PREFIX##MI_DIV , PREFIX##MI_MTIR, \ + PREFIX##MI_RNEXT , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, /* 0x10 */ \ + PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ + PREFIX##unknown , PREFIX##MI_MFP , PREFIX##MI_XTOP , PREFIX##MI_XGKICK, \ + PREFIX##MI_ESADD , PREFIX##MI_EATANxy, PREFIX##MI_ESQRT, PREFIX##MI_ESIN, \ +}; \ + \ + static __aligned16 const FNTYPE PREFIX##LowerOP_T3_01_OPCODE[32] = { \ + PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ + PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ + PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ + PREFIX##MI_MR32 , PREFIX##MI_SQI , PREFIX##MI_SQRT , PREFIX##MI_MFIR, \ + PREFIX##MI_RGET , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, /* 0x10 */ \ + PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ + PREFIX##unknown , PREFIX##unknown , PREFIX##MI_XITOP, PREFIX##unknown, \ + PREFIX##MI_ERSADD, PREFIX##MI_EATANxz, PREFIX##MI_ERSQRT, PREFIX##MI_EATAN, \ +}; \ + \ + static __aligned16 const FNTYPE PREFIX##LowerOP_T3_10_OPCODE[32] = { \ + PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ + PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ + PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ + PREFIX##unknown , PREFIX##MI_LQD , PREFIX##MI_RSQRT, PREFIX##MI_ILWR, \ + PREFIX##MI_RINIT , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, /* 0x10 */ \ + PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ + PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ + PREFIX##MI_ELENG , PREFIX##MI_ESUM , PREFIX##MI_ERCPR, PREFIX##MI_EEXP, \ +}; \ + \ + static __aligned16 const FNTYPE PREFIX##LowerOP_T3_11_OPCODE[32] = { \ + PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ + PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ + PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ + PREFIX##unknown , PREFIX##MI_SQD , PREFIX##MI_WAITQ, PREFIX##MI_ISWR, \ + PREFIX##MI_RXOR , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, /* 0x10 */ \ + PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ + PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ + PREFIX##MI_ERLENG, PREFIX##unknown , PREFIX##MI_WAITP, PREFIX##unknown, \ +}; \ + \ + static __aligned16 const FNTYPE PREFIX##LowerOP_OPCODE[64] = { \ + PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ + PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ + PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ + PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ + PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, /* 0x10 */ \ + PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ + PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ + PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ + PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, /* 0x20 */ \ + PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ + PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ + PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ + PREFIX##MI_IADD , PREFIX##MI_ISUB , PREFIX##MI_IADDI, PREFIX##unknown, /* 0x30 */ \ + PREFIX##MI_IAND , PREFIX##MI_IOR , PREFIX##unknown , PREFIX##unknown, \ + PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ + PREFIX##LowerOP_T3_00, PREFIX##LowerOP_T3_01, PREFIX##LowerOP_T3_10, PREFIX##LowerOP_T3_11, \ +}; \ + \ +__aligned16 const FNTYPE PREFIX##_LOWER_OPCODE[128] = { \ + PREFIX##MI_LQ , PREFIX##MI_SQ , PREFIX##unknown , PREFIX##unknown, \ + PREFIX##MI_ILW , PREFIX##MI_ISW , PREFIX##unknown , PREFIX##unknown, \ + PREFIX##MI_IADDIU, PREFIX##MI_ISUBIU, PREFIX##unknown , PREFIX##unknown, \ + PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ + PREFIX##MI_FCEQ , PREFIX##MI_FCSET , PREFIX##MI_FCAND, PREFIX##MI_FCOR, /* 0x10 */ \ + PREFIX##MI_FSEQ , PREFIX##MI_FSSET , PREFIX##MI_FSAND, PREFIX##MI_FSOR, \ + PREFIX##MI_FMEQ , PREFIX##unknown , PREFIX##MI_FMAND, PREFIX##MI_FMOR, \ + PREFIX##MI_FCGET , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ + PREFIX##MI_B , PREFIX##MI_BAL , PREFIX##unknown , PREFIX##unknown, /* 0x20 */ \ + PREFIX##MI_JR , PREFIX##MI_JALR , PREFIX##unknown , PREFIX##unknown, \ + PREFIX##MI_IBEQ , PREFIX##MI_IBNE , PREFIX##unknown , PREFIX##unknown, \ + PREFIX##MI_IBLTZ , PREFIX##MI_IBGTZ , PREFIX##MI_IBLEZ, PREFIX##MI_IBGEZ, \ + PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, /* 0x30 */ \ + PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ + PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ + PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ + PREFIX##LowerOP , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, /* 0x40*/ \ + PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ + PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ + PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ + PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, /* 0x50 */ \ + PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ + PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ + PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ + PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, /* 0x60 */ \ + PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ + PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ + PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ + PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, /* 0x70 */ \ + PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ + PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ + PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ +}; \ + \ + static __aligned16 const FNTYPE PREFIX##_UPPER_FD_00_TABLE[32] = { \ + PREFIX##MI_ADDAx, PREFIX##MI_SUBAx , PREFIX##MI_MADDAx, PREFIX##MI_MSUBAx, \ + PREFIX##MI_ITOF0, PREFIX##MI_FTOI0, PREFIX##MI_MULAx , PREFIX##MI_MULAq , \ + PREFIX##MI_ADDAq, PREFIX##MI_SUBAq, PREFIX##MI_ADDA , PREFIX##MI_SUBA , \ + PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , \ + PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , \ + PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , \ + PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , \ + PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , \ +}; \ + \ + static __aligned16 const FNTYPE PREFIX##_UPPER_FD_01_TABLE[32] = { \ + PREFIX##MI_ADDAy , PREFIX##MI_SUBAy , PREFIX##MI_MADDAy, PREFIX##MI_MSUBAy, \ + PREFIX##MI_ITOF4 , PREFIX##MI_FTOI4 , PREFIX##MI_MULAy , PREFIX##MI_ABS , \ + PREFIX##MI_MADDAq, PREFIX##MI_MSUBAq, PREFIX##MI_MADDA , PREFIX##MI_MSUBA , \ + PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , \ + PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , \ + PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , \ + PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , \ + PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , \ +}; \ + \ + static __aligned16 const FNTYPE PREFIX##_UPPER_FD_10_TABLE[32] = { \ + PREFIX##MI_ADDAz , PREFIX##MI_SUBAz , PREFIX##MI_MADDAz, PREFIX##MI_MSUBAz, \ + PREFIX##MI_ITOF12, PREFIX##MI_FTOI12, PREFIX##MI_MULAz , PREFIX##MI_MULAi , \ + PREFIX##MI_ADDAi, PREFIX##MI_SUBAi , PREFIX##MI_MULA , PREFIX##MI_OPMULA, \ + PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , \ + PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , \ + PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , \ + PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , \ + PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , \ +}; \ + \ + static __aligned16 const FNTYPE PREFIX##_UPPER_FD_11_TABLE[32] = { \ + PREFIX##MI_ADDAw , PREFIX##MI_SUBAw , PREFIX##MI_MADDAw, PREFIX##MI_MSUBAw, \ + PREFIX##MI_ITOF15, PREFIX##MI_FTOI15, PREFIX##MI_MULAw , PREFIX##MI_CLIP , \ + PREFIX##MI_MADDAi, PREFIX##MI_MSUBAi, PREFIX##unknown , PREFIX##MI_NOP , \ + PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , \ + PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , \ + PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , \ + PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , \ + PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , \ +}; \ + \ + __aligned16 const FNTYPE PREFIX##_UPPER_OPCODE[64] = { \ + PREFIX##MI_ADDx , PREFIX##MI_ADDy , PREFIX##MI_ADDz , PREFIX##MI_ADDw, \ + PREFIX##MI_SUBx , PREFIX##MI_SUBy , PREFIX##MI_SUBz , PREFIX##MI_SUBw, \ + PREFIX##MI_MADDx , PREFIX##MI_MADDy , PREFIX##MI_MADDz , PREFIX##MI_MADDw, \ + PREFIX##MI_MSUBx , PREFIX##MI_MSUBy , PREFIX##MI_MSUBz , PREFIX##MI_MSUBw, \ + PREFIX##MI_MAXx , PREFIX##MI_MAXy , PREFIX##MI_MAXz , PREFIX##MI_MAXw, /* 0x10 */ \ + PREFIX##MI_MINIx , PREFIX##MI_MINIy , PREFIX##MI_MINIz , PREFIX##MI_MINIw, \ + PREFIX##MI_MULx , PREFIX##MI_MULy , PREFIX##MI_MULz , PREFIX##MI_MULw, \ + PREFIX##MI_MULq , PREFIX##MI_MAXi , PREFIX##MI_MULi , PREFIX##MI_MINIi, \ + PREFIX##MI_ADDq , PREFIX##MI_MADDq , PREFIX##MI_ADDi , PREFIX##MI_MADDi, /* 0x20 */ \ + PREFIX##MI_SUBq , PREFIX##MI_MSUBq , PREFIX##MI_SUBi , PREFIX##MI_MSUBi, \ + PREFIX##MI_ADD , PREFIX##MI_MADD , PREFIX##MI_MUL , PREFIX##MI_MAX, \ + PREFIX##MI_SUB , PREFIX##MI_MSUB , PREFIX##MI_OPMSUB, PREFIX##MI_MINI, \ + PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, /* 0x30 */ \ + PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ + PREFIX##unknown , PREFIX##unknown , PREFIX##unknown , PREFIX##unknown, \ + PREFIX##_UPPER_FD_00, PREFIX##_UPPER_FD_01, PREFIX##_UPPER_FD_10, PREFIX##_UPPER_FD_11, \ +}; + + +#define _vuTablesPre(VU, PREFIX) \ + \ + static void PREFIX##_UPPER_FD_00(); \ + static void PREFIX##_UPPER_FD_01(); \ + static void PREFIX##_UPPER_FD_10(); \ + static void PREFIX##_UPPER_FD_11(); \ + static void PREFIX##LowerOP(); \ + static void PREFIX##LowerOP_T3_00(); \ + static void PREFIX##LowerOP_T3_01(); \ + static void PREFIX##LowerOP_T3_10(); \ + static void PREFIX##LowerOP_T3_11(); \ + +#define _vuTablesPost(VU, PREFIX) \ + \ + static void PREFIX##_UPPER_FD_00() { \ + PREFIX##_UPPER_FD_00_TABLE[(VU.code >> 6) & 0x1f ](); \ +} \ + \ + static void PREFIX##_UPPER_FD_01() { \ + PREFIX##_UPPER_FD_01_TABLE[(VU.code >> 6) & 0x1f](); \ +} \ + \ + static void PREFIX##_UPPER_FD_10() { \ + PREFIX##_UPPER_FD_10_TABLE[(VU.code >> 6) & 0x1f](); \ +} \ + \ + static void PREFIX##_UPPER_FD_11() { \ + PREFIX##_UPPER_FD_11_TABLE[(VU.code >> 6) & 0x1f](); \ +} \ + \ + static void PREFIX##LowerOP() { \ + PREFIX##LowerOP_OPCODE[VU.code & 0x3f](); \ +} \ + \ + static void PREFIX##LowerOP_T3_00() { \ + PREFIX##LowerOP_T3_00_OPCODE[(VU.code >> 6) & 0x1f](); \ +} \ + \ + static void PREFIX##LowerOP_T3_01() { \ + PREFIX##LowerOP_T3_01_OPCODE[(VU.code >> 6) & 0x1f](); \ +} \ + \ + static void PREFIX##LowerOP_T3_10() { \ + PREFIX##LowerOP_T3_10_OPCODE[(VU.code >> 6) & 0x1f](); \ +} \ + \ + static void PREFIX##LowerOP_T3_11() { \ + PREFIX##LowerOP_T3_11_OPCODE[(VU.code >> 6) & 0x1f](); \ +} \ + + +// -------------------------------------------------------------------------------------- +// VuRegsN Tables +// -------------------------------------------------------------------------------------- + +#define _vuRegsTables(VU, PREFIX, FNTYPE) \ + static void __vuRegsCall PREFIX##_UPPER_FD_00(_VURegsNum *VUregsn); \ + static void __vuRegsCall PREFIX##_UPPER_FD_01(_VURegsNum *VUregsn); \ + static void __vuRegsCall PREFIX##_UPPER_FD_10(_VURegsNum *VUregsn); \ + static void __vuRegsCall PREFIX##_UPPER_FD_11(_VURegsNum *VUregsn); \ + static void __vuRegsCall PREFIX##LowerOP(_VURegsNum *VUregsn); \ + static void __vuRegsCall PREFIX##LowerOP_T3_00(_VURegsNum *VUregsn); \ + static void __vuRegsCall PREFIX##LowerOP_T3_01(_VURegsNum *VUregsn); \ + static void __vuRegsCall PREFIX##LowerOP_T3_10(_VURegsNum *VUregsn); \ + static void __vuRegsCall PREFIX##LowerOP_T3_11(_VURegsNum *VUregsn); \ + \ + _vuTablesMess(PREFIX, FNTYPE) \ + \ + static void __vuRegsCall PREFIX##_UPPER_FD_00(_VURegsNum *VUregsn) { \ + PREFIX##_UPPER_FD_00_TABLE[(VU.code >> 6) & 0x1f ](VUregsn); \ +} \ + \ + static void __vuRegsCall PREFIX##_UPPER_FD_01(_VURegsNum *VUregsn) { \ + PREFIX##_UPPER_FD_01_TABLE[(VU.code >> 6) & 0x1f](VUregsn); \ +} \ + \ + static void __vuRegsCall PREFIX##_UPPER_FD_10(_VURegsNum *VUregsn) { \ + PREFIX##_UPPER_FD_10_TABLE[(VU.code >> 6) & 0x1f](VUregsn); \ +} \ + \ + static void __vuRegsCall PREFIX##_UPPER_FD_11(_VURegsNum *VUregsn) { \ + PREFIX##_UPPER_FD_11_TABLE[(VU.code >> 6) & 0x1f](VUregsn); \ +} \ + \ + static void __vuRegsCall PREFIX##LowerOP(_VURegsNum *VUregsn) { \ + PREFIX##LowerOP_OPCODE[VU.code & 0x3f](VUregsn); \ +} \ + \ + static void __vuRegsCall PREFIX##LowerOP_T3_00(_VURegsNum *VUregsn) { \ + PREFIX##LowerOP_T3_00_OPCODE[(VU.code >> 6) & 0x1f](VUregsn); \ +} \ + \ + static void __vuRegsCall PREFIX##LowerOP_T3_01(_VURegsNum *VUregsn) { \ + PREFIX##LowerOP_T3_01_OPCODE[(VU.code >> 6) & 0x1f](VUregsn); \ +} \ + \ + static void __vuRegsCall PREFIX##LowerOP_T3_10(_VURegsNum *VUregsn) { \ + PREFIX##LowerOP_T3_10_OPCODE[(VU.code >> 6) & 0x1f](VUregsn); \ +} \ + \ + static void __vuRegsCall PREFIX##LowerOP_T3_11(_VURegsNum *VUregsn) { \ + PREFIX##LowerOP_T3_11_OPCODE[(VU.code >> 6) & 0x1f](VUregsn); \ +} \ + +_vuTablesPre(VU0, VU0) +_vuTablesMess(VU0, Fnptr_Void) +_vuTablesPost(VU0, VU0) + +_vuTablesPre(VU1, VU1) +_vuTablesMess(VU1, Fnptr_Void) +_vuTablesPost(VU1, VU1) + +_vuRegsTables(VU0, VU0regs, Fnptr_VuRegsN) +_vuRegsTables(VU1, VU1regs, Fnptr_VuRegsN) + + +// -------------------------------------------------------------------------------------- +// VU0macro (COP2) +// -------------------------------------------------------------------------------------- + +static __fi void SYNCMSFLAGS() +{ + VU0.VI[REG_STATUS_FLAG].UL = VU0.statusflag; + VU0.VI[REG_MAC_FLAG].UL = VU0.macflag; +} + +static __fi void SYNCFDIV() +{ + VU0.VI[REG_Q].UL = VU0.q.UL; + VU0.VI[REG_STATUS_FLAG].UL = VU0.statusflag; +} + +void VABS() { VU0.code = cpuRegs.code; _vuABS(&VU0); } +void VADD() { VU0.code = cpuRegs.code; _vuADD(&VU0); SYNCMSFLAGS(); } +void VADDi() { VU0.code = cpuRegs.code; _vuADDi(&VU0); SYNCMSFLAGS(); } +void VADDq() { VU0.code = cpuRegs.code; _vuADDq(&VU0); SYNCMSFLAGS(); } +void VADDx() { VU0.code = cpuRegs.code; _vuADDx(&VU0); SYNCMSFLAGS(); } +void VADDy() { VU0.code = cpuRegs.code; _vuADDy(&VU0); SYNCMSFLAGS(); } +void VADDz() { VU0.code = cpuRegs.code; _vuADDz(&VU0); SYNCMSFLAGS(); } +void VADDw() { VU0.code = cpuRegs.code; _vuADDw(&VU0); SYNCMSFLAGS(); } +void VADDA() { VU0.code = cpuRegs.code; _vuADDA(&VU0); SYNCMSFLAGS(); } +void VADDAi() { VU0.code = cpuRegs.code; _vuADDAi(&VU0); SYNCMSFLAGS(); } +void VADDAq() { VU0.code = cpuRegs.code; _vuADDAq(&VU0); SYNCMSFLAGS(); } +void VADDAx() { VU0.code = cpuRegs.code; _vuADDAx(&VU0); SYNCMSFLAGS(); } +void VADDAy() { VU0.code = cpuRegs.code; _vuADDAy(&VU0); SYNCMSFLAGS(); } +void VADDAz() { VU0.code = cpuRegs.code; _vuADDAz(&VU0); SYNCMSFLAGS(); } +void VADDAw() { VU0.code = cpuRegs.code; _vuADDAw(&VU0); SYNCMSFLAGS(); } +void VSUB() { VU0.code = cpuRegs.code; _vuSUB(&VU0); SYNCMSFLAGS(); } +void VSUBi() { VU0.code = cpuRegs.code; _vuSUBi(&VU0); SYNCMSFLAGS(); } +void VSUBq() { VU0.code = cpuRegs.code; _vuSUBq(&VU0); SYNCMSFLAGS(); } +void VSUBx() { VU0.code = cpuRegs.code; _vuSUBx(&VU0); SYNCMSFLAGS(); } +void VSUBy() { VU0.code = cpuRegs.code; _vuSUBy(&VU0); SYNCMSFLAGS(); } +void VSUBz() { VU0.code = cpuRegs.code; _vuSUBz(&VU0); SYNCMSFLAGS(); } +void VSUBw() { VU0.code = cpuRegs.code; _vuSUBw(&VU0); SYNCMSFLAGS(); } +void VSUBA() { VU0.code = cpuRegs.code; _vuSUBA(&VU0); SYNCMSFLAGS(); } +void VSUBAi() { VU0.code = cpuRegs.code; _vuSUBAi(&VU0); SYNCMSFLAGS(); } +void VSUBAq() { VU0.code = cpuRegs.code; _vuSUBAq(&VU0); SYNCMSFLAGS(); } +void VSUBAx() { VU0.code = cpuRegs.code; _vuSUBAx(&VU0); SYNCMSFLAGS(); } +void VSUBAy() { VU0.code = cpuRegs.code; _vuSUBAy(&VU0); SYNCMSFLAGS(); } +void VSUBAz() { VU0.code = cpuRegs.code; _vuSUBAz(&VU0); SYNCMSFLAGS(); } +void VSUBAw() { VU0.code = cpuRegs.code; _vuSUBAw(&VU0); SYNCMSFLAGS(); } +void VMUL() { VU0.code = cpuRegs.code; _vuMUL(&VU0); SYNCMSFLAGS(); } +void VMULi() { VU0.code = cpuRegs.code; _vuMULi(&VU0); SYNCMSFLAGS(); } +void VMULq() { VU0.code = cpuRegs.code; _vuMULq(&VU0); SYNCMSFLAGS(); } +void VMULx() { VU0.code = cpuRegs.code; _vuMULx(&VU0); SYNCMSFLAGS(); } +void VMULy() { VU0.code = cpuRegs.code; _vuMULy(&VU0); SYNCMSFLAGS(); } +void VMULz() { VU0.code = cpuRegs.code; _vuMULz(&VU0); SYNCMSFLAGS(); } +void VMULw() { VU0.code = cpuRegs.code; _vuMULw(&VU0); SYNCMSFLAGS(); } +void VMULA() { VU0.code = cpuRegs.code; _vuMULA(&VU0); SYNCMSFLAGS(); } +void VMULAi() { VU0.code = cpuRegs.code; _vuMULAi(&VU0); SYNCMSFLAGS(); } +void VMULAq() { VU0.code = cpuRegs.code; _vuMULAq(&VU0); SYNCMSFLAGS(); } +void VMULAx() { VU0.code = cpuRegs.code; _vuMULAx(&VU0); SYNCMSFLAGS(); } +void VMULAy() { VU0.code = cpuRegs.code; _vuMULAy(&VU0); SYNCMSFLAGS(); } +void VMULAz() { VU0.code = cpuRegs.code; _vuMULAz(&VU0); SYNCMSFLAGS(); } +void VMULAw() { VU0.code = cpuRegs.code; _vuMULAw(&VU0); SYNCMSFLAGS(); } +void VMADD() { VU0.code = cpuRegs.code; _vuMADD(&VU0); SYNCMSFLAGS(); } +void VMADDi() { VU0.code = cpuRegs.code; _vuMADDi(&VU0); SYNCMSFLAGS(); } +void VMADDq() { VU0.code = cpuRegs.code; _vuMADDq(&VU0); SYNCMSFLAGS(); } +void VMADDx() { VU0.code = cpuRegs.code; _vuMADDx(&VU0); SYNCMSFLAGS(); } +void VMADDy() { VU0.code = cpuRegs.code; _vuMADDy(&VU0); SYNCMSFLAGS(); } +void VMADDz() { VU0.code = cpuRegs.code; _vuMADDz(&VU0); SYNCMSFLAGS(); } +void VMADDw() { VU0.code = cpuRegs.code; _vuMADDw(&VU0); SYNCMSFLAGS(); } +void VMADDA() { VU0.code = cpuRegs.code; _vuMADDA(&VU0); SYNCMSFLAGS(); } +void VMADDAi() { VU0.code = cpuRegs.code; _vuMADDAi(&VU0); SYNCMSFLAGS(); } +void VMADDAq() { VU0.code = cpuRegs.code; _vuMADDAq(&VU0); SYNCMSFLAGS(); } +void VMADDAx() { VU0.code = cpuRegs.code; _vuMADDAx(&VU0); SYNCMSFLAGS(); } +void VMADDAy() { VU0.code = cpuRegs.code; _vuMADDAy(&VU0); SYNCMSFLAGS(); } +void VMADDAz() { VU0.code = cpuRegs.code; _vuMADDAz(&VU0); SYNCMSFLAGS(); } +void VMADDAw() { VU0.code = cpuRegs.code; _vuMADDAw(&VU0); SYNCMSFLAGS(); } +void VMSUB() { VU0.code = cpuRegs.code; _vuMSUB(&VU0); SYNCMSFLAGS(); } +void VMSUBi() { VU0.code = cpuRegs.code; _vuMSUBi(&VU0); SYNCMSFLAGS(); } +void VMSUBq() { VU0.code = cpuRegs.code; _vuMSUBq(&VU0); SYNCMSFLAGS(); } +void VMSUBx() { VU0.code = cpuRegs.code; _vuMSUBx(&VU0); SYNCMSFLAGS(); } +void VMSUBy() { VU0.code = cpuRegs.code; _vuMSUBy(&VU0); SYNCMSFLAGS(); } +void VMSUBz() { VU0.code = cpuRegs.code; _vuMSUBz(&VU0); SYNCMSFLAGS(); } +void VMSUBw() { VU0.code = cpuRegs.code; _vuMSUBw(&VU0); SYNCMSFLAGS(); } +void VMSUBA() { VU0.code = cpuRegs.code; _vuMSUBA(&VU0); SYNCMSFLAGS(); } +void VMSUBAi() { VU0.code = cpuRegs.code; _vuMSUBAi(&VU0); SYNCMSFLAGS(); } +void VMSUBAq() { VU0.code = cpuRegs.code; _vuMSUBAq(&VU0); SYNCMSFLAGS(); } +void VMSUBAx() { VU0.code = cpuRegs.code; _vuMSUBAx(&VU0); SYNCMSFLAGS(); } +void VMSUBAy() { VU0.code = cpuRegs.code; _vuMSUBAy(&VU0); SYNCMSFLAGS(); } +void VMSUBAz() { VU0.code = cpuRegs.code; _vuMSUBAz(&VU0); SYNCMSFLAGS(); } +void VMSUBAw() { VU0.code = cpuRegs.code; _vuMSUBAw(&VU0); SYNCMSFLAGS(); } +void VMAX() { VU0.code = cpuRegs.code; _vuMAX(&VU0); } +void VMAXi() { VU0.code = cpuRegs.code; _vuMAXi(&VU0); } +void VMAXx() { VU0.code = cpuRegs.code; _vuMAXx(&VU0); } +void VMAXy() { VU0.code = cpuRegs.code; _vuMAXy(&VU0); } +void VMAXz() { VU0.code = cpuRegs.code; _vuMAXz(&VU0); } +void VMAXw() { VU0.code = cpuRegs.code; _vuMAXw(&VU0); } +void VMINI() { VU0.code = cpuRegs.code; _vuMINI(&VU0); } +void VMINIi() { VU0.code = cpuRegs.code; _vuMINIi(&VU0); } +void VMINIx() { VU0.code = cpuRegs.code; _vuMINIx(&VU0); } +void VMINIy() { VU0.code = cpuRegs.code; _vuMINIy(&VU0); } +void VMINIz() { VU0.code = cpuRegs.code; _vuMINIz(&VU0); } +void VMINIw() { VU0.code = cpuRegs.code; _vuMINIw(&VU0); } +void VOPMULA() { VU0.code = cpuRegs.code; _vuOPMULA(&VU0); SYNCMSFLAGS(); } +void VOPMSUB() { VU0.code = cpuRegs.code; _vuOPMSUB(&VU0); SYNCMSFLAGS(); } +void VNOP() { VU0.code = cpuRegs.code; _vuNOP(&VU0); } +void VFTOI0() { VU0.code = cpuRegs.code; _vuFTOI0(&VU0); } +void VFTOI4() { VU0.code = cpuRegs.code; _vuFTOI4(&VU0); } +void VFTOI12() { VU0.code = cpuRegs.code; _vuFTOI12(&VU0); } +void VFTOI15() { VU0.code = cpuRegs.code; _vuFTOI15(&VU0); } +void VITOF0() { VU0.code = cpuRegs.code; _vuITOF0(&VU0); } +void VITOF4() { VU0.code = cpuRegs.code; _vuITOF4(&VU0); } +void VITOF12() { VU0.code = cpuRegs.code; _vuITOF12(&VU0); } +void VITOF15() { VU0.code = cpuRegs.code; _vuITOF15(&VU0); } +void VCLIPw() { VU0.code = cpuRegs.code; _vuCLIP(&VU0); VU0.VI[REG_CLIP_FLAG].UL = VU0.clipflag; } + +void VDIV() { VU0.code = cpuRegs.code; _vuDIV(&VU0); SYNCFDIV(); } +void VSQRT() { VU0.code = cpuRegs.code; _vuSQRT(&VU0); SYNCFDIV(); } +void VRSQRT() { VU0.code = cpuRegs.code; _vuRSQRT(&VU0); SYNCFDIV(); } +void VIADD() { VU0.code = cpuRegs.code; _vuIADD(&VU0); } +void VIADDI() { VU0.code = cpuRegs.code; _vuIADDI(&VU0); } +void VIADDIU() { VU0.code = cpuRegs.code; _vuIADDIU(&VU0); } +void VIAND() { VU0.code = cpuRegs.code; _vuIAND(&VU0); } +void VIOR() { VU0.code = cpuRegs.code; _vuIOR(&VU0); } +void VISUB() { VU0.code = cpuRegs.code; _vuISUB(&VU0); } +void VISUBIU() { VU0.code = cpuRegs.code; _vuISUBIU(&VU0); } +void VMOVE() { VU0.code = cpuRegs.code; _vuMOVE(&VU0); } +void VMFIR() { VU0.code = cpuRegs.code; _vuMFIR(&VU0); } +void VMTIR() { VU0.code = cpuRegs.code; _vuMTIR(&VU0); } +void VMR32() { VU0.code = cpuRegs.code; _vuMR32(&VU0); } +void VLQ() { VU0.code = cpuRegs.code; _vuLQ(&VU0); } +void VLQD() { VU0.code = cpuRegs.code; _vuLQD(&VU0); } +void VLQI() { VU0.code = cpuRegs.code; _vuLQI(&VU0); } +void VSQ() { VU0.code = cpuRegs.code; _vuSQ(&VU0); } +void VSQD() { VU0.code = cpuRegs.code; _vuSQD(&VU0); } +void VSQI() { VU0.code = cpuRegs.code; _vuSQI(&VU0); } +void VILW() { VU0.code = cpuRegs.code; _vuILW(&VU0); } +void VISW() { VU0.code = cpuRegs.code; _vuISW(&VU0); } +void VILWR() { VU0.code = cpuRegs.code; _vuILWR(&VU0); } +void VISWR() { VU0.code = cpuRegs.code; _vuISWR(&VU0); } +void VRINIT() { VU0.code = cpuRegs.code; _vuRINIT(&VU0); } +void VRGET() { VU0.code = cpuRegs.code; _vuRGET(&VU0); } +void VRNEXT() { VU0.code = cpuRegs.code; _vuRNEXT(&VU0); } +void VRXOR() { VU0.code = cpuRegs.code; _vuRXOR(&VU0); } +void VWAITQ() { VU0.code = cpuRegs.code; _vuWAITQ(&VU0); } +void VFSAND() { VU0.code = cpuRegs.code; _vuFSAND(&VU0); } +void VFSEQ() { VU0.code = cpuRegs.code; _vuFSEQ(&VU0); } +void VFSOR() { VU0.code = cpuRegs.code; _vuFSOR(&VU0); } +void VFSSET() { VU0.code = cpuRegs.code; _vuFSSET(&VU0); } +void VFMAND() { VU0.code = cpuRegs.code; _vuFMAND(&VU0); } +void VFMEQ() { VU0.code = cpuRegs.code; _vuFMEQ(&VU0); } +void VFMOR() { VU0.code = cpuRegs.code; _vuFMOR(&VU0); } +void VFCAND() { VU0.code = cpuRegs.code; _vuFCAND(&VU0); } +void VFCEQ() { VU0.code = cpuRegs.code; _vuFCEQ(&VU0); } +void VFCOR() { VU0.code = cpuRegs.code; _vuFCOR(&VU0); } +void VFCSET() { VU0.code = cpuRegs.code; _vuFCSET(&VU0); } +void VFCGET() { VU0.code = cpuRegs.code; _vuFCGET(&VU0); } +void VXITOP() { VU0.code = cpuRegs.code; _vuXITOP(&VU0); } + diff --git a/pcsx2/VUops.h b/pcsx2/VUops.h index e89f084265..fdbd623fe4 100644 --- a/pcsx2/VUops.h +++ b/pcsx2/VUops.h @@ -27,354 +27,35 @@ #define MAC_Reset( VU ) VU->VI[REG_MAC_FLAG].UL = VU->VI[REG_MAC_FLAG].UL & (~0xFFFF) +struct _VURegsNum { + u8 pipe; // if 0xff, COP2 + u8 VFwrite; + u8 VFwxyzw; + u8 VFr0xyzw; + u8 VFr1xyzw; + u8 VFread0; + u8 VFread1; + u32 VIwrite; + u32 VIread; + int cycles; +}; + +#define __vuRegsCall __fastcall +typedef void __vuRegsCall FnType_VuRegsN(_VURegsNum *VUregsn); +typedef FnType_VuRegsN* Fnptr_VuRegsN; + +extern __aligned16 const Fnptr_Void VU0_LOWER_OPCODE[128]; +extern __aligned16 const Fnptr_Void VU0_UPPER_OPCODE[64]; +extern __aligned16 const Fnptr_VuRegsN VU0regs_LOWER_OPCODE[128]; +extern __aligned16 const Fnptr_VuRegsN VU0regs_UPPER_OPCODE[64]; + +extern __aligned16 const Fnptr_Void VU1_LOWER_OPCODE[128]; +extern __aligned16 const Fnptr_Void VU1_UPPER_OPCODE[64]; +extern __aligned16 const Fnptr_VuRegsN VU1regs_LOWER_OPCODE[128]; +extern __aligned16 const Fnptr_VuRegsN VU1regs_UPPER_OPCODE[64]; + extern void _vuTestPipes(VURegs * VU); extern void _vuTestUpperStalls(VURegs * VU, _VURegsNum *VUregsn); extern void _vuTestLowerStalls(VURegs * VU, _VURegsNum *VUregsn); extern void _vuAddUpperStalls(VURegs * VU, _VURegsNum *VUregsn); extern void _vuAddLowerStalls(VURegs * VU, _VURegsNum *VUregsn); - -/******************************/ -/* VU Upper instructions */ -/******************************/ - -void _vuABS(VURegs * VU); -void _vuADD(VURegs * VU); -void _vuADDi(VURegs * VU); -void _vuADDq(VURegs * VU); -void _vuADDx(VURegs * VU); -void _vuADDy(VURegs * VU); -void _vuADDz(VURegs * VU); -void _vuADDw(VURegs * VU); -void _vuADDA(VURegs * VU); -void _vuADDAi(VURegs * VU); -void _vuADDAq(VURegs * VU); -void _vuADDAx(VURegs * VU); -void _vuADDAy(VURegs * VU); -void _vuADDAz(VURegs * VU); -void _vuADDAw(VURegs * VU); -void _vuSUB(VURegs * VU); -void _vuSUBi(VURegs * VU); -void _vuSUBq(VURegs * VU); -void _vuSUBx(VURegs * VU); -void _vuSUBy(VURegs * VU); -void _vuSUBz(VURegs * VU); -void _vuSUBw(VURegs * VU); -void _vuSUBA(VURegs * VU); -void _vuSUBAi(VURegs * VU); -void _vuSUBAq(VURegs * VU); -void _vuSUBAx(VURegs * VU); -void _vuSUBAy(VURegs * VU); -void _vuSUBAz(VURegs * VU); -void _vuSUBAw(VURegs * VU); -void _vuMUL(VURegs * VU); -void _vuMULi(VURegs * VU); -void _vuMULq(VURegs * VU); -void _vuMULx(VURegs * VU); -void _vuMULy(VURegs * VU); -void _vuMULz(VURegs * VU); -void _vuMULw(VURegs * VU); -void _vuMULA(VURegs * VU); -void _vuMULAi(VURegs * VU); -void _vuMULAq(VURegs * VU); -void _vuMULAx(VURegs * VU); -void _vuMULAy(VURegs * VU); -void _vuMULAz(VURegs * VU); -void _vuMULAw(VURegs * VU); -void _vuMADD(VURegs * VU) ; -void _vuMADDi(VURegs * VU); -void _vuMADDq(VURegs * VU); -void _vuMADDx(VURegs * VU); -void _vuMADDy(VURegs * VU); -void _vuMADDz(VURegs * VU); -void _vuMADDw(VURegs * VU); -void _vuMADDA(VURegs * VU); -void _vuMADDAi(VURegs * VU); -void _vuMADDAq(VURegs * VU); -void _vuMADDAx(VURegs * VU); -void _vuMADDAy(VURegs * VU); -void _vuMADDAz(VURegs * VU); -void _vuMADDAw(VURegs * VU); -void _vuMSUB(VURegs * VU); -void _vuMSUBi(VURegs * VU); -void _vuMSUBq(VURegs * VU); -void _vuMSUBx(VURegs * VU); -void _vuMSUBy(VURegs * VU); -void _vuMSUBz(VURegs * VU) ; -void _vuMSUBw(VURegs * VU) ; -void _vuMSUBA(VURegs * VU); -void _vuMSUBAi(VURegs * VU); -void _vuMSUBAq(VURegs * VU); -void _vuMSUBAx(VURegs * VU); -void _vuMSUBAy(VURegs * VU); -void _vuMSUBAz(VURegs * VU); -void _vuMSUBAw(VURegs * VU); -void _vuMAX(VURegs * VU); -void _vuMAXi(VURegs * VU); -void _vuMAXx(VURegs * VU); -void _vuMAXy(VURegs * VU); -void _vuMAXz(VURegs * VU); -void _vuMAXw(VURegs * VU); -void _vuMINI(VURegs * VU); -void _vuMINIi(VURegs * VU); -void _vuMINIx(VURegs * VU); -void _vuMINIy(VURegs * VU); -void _vuMINIz(VURegs * VU); -void _vuMINIw(VURegs * VU); -void _vuOPMULA(VURegs * VU); -void _vuOPMSUB(VURegs * VU); -void _vuNOP(VURegs * VU); -void _vuFTOI0(VURegs * VU); -void _vuFTOI4(VURegs * VU); -void _vuFTOI12(VURegs * VU); -void _vuFTOI15(VURegs * VU); -void _vuITOF0(VURegs * VU) ; -void _vuITOF4(VURegs * VU) ; -void _vuITOF12(VURegs * VU); -void _vuITOF15(VURegs * VU); -void _vuCLIP(VURegs * VU); -/******************************/ -/* VU Lower instructions */ -/******************************/ -void _vuDIV(VURegs * VU); -void _vuSQRT(VURegs * VU); -void _vuRSQRT(VURegs * VU); -void _vuIADDI(VURegs * VU); -void _vuIADDIU(VURegs * VU); -void _vuIADD(VURegs * VU); -void _vuIAND(VURegs * VU); -void _vuIOR(VURegs * VU); -void _vuISUB(VURegs * VU); -void _vuISUBIU(VURegs * VU); -void _vuMOVE(VURegs * VU); -void _vuMFIR(VURegs * VU); -void _vuMTIR(VURegs * VU); -void _vuMR32(VURegs * VU); -void _vuLQ(VURegs * VU) ; -void _vuLQD(VURegs * VU); -void _vuLQI(VURegs * VU); -void _vuSQ(VURegs * VU); -void _vuSQD(VURegs * VU); -void _vuSQI(VURegs * VU); -void _vuILW(VURegs * VU); -void _vuISW(VURegs * VU); -void _vuILWR(VURegs * VU); -void _vuISWR(VURegs * VU); -void _vuLOI(VURegs * VU); -void _vuRINIT(VURegs * VU); -void _vuRGET(VURegs * VU); -void _vuRNEXT(VURegs * VU); -void _vuRXOR(VURegs * VU); -void _vuWAITQ(VURegs * VU); -void _vuFSAND(VURegs * VU); -void _vuFSEQ(VURegs * VU); -void _vuFSOR(VURegs * VU); -void _vuFSSET(VURegs * VU); -void _vuFMAND(VURegs * VU); -void _vuFMEQ(VURegs * VU); -void _vuFMOR(VURegs * VU); -void _vuFCAND(VURegs * VU); -void _vuFCEQ(VURegs * VU); -void _vuFCOR(VURegs * VU); -void _vuFCSET(VURegs * VU); -void _vuFCGET(VURegs * VU); -void _vuIBEQ(VURegs * VU); -void _vuIBGEZ(VURegs * VU); -void _vuIBGTZ(VURegs * VU); -void _vuIBLEZ(VURegs * VU); -void _vuIBLTZ(VURegs * VU); -void _vuIBNE(VURegs * VU); -void _vuB(VURegs * VU); -void _vuBAL(VURegs * VU); -void _vuJR(VURegs * VU); -void _vuJALR(VURegs * VU); -void _vuMFP(VURegs * VU); -void _vuWAITP(VURegs * VU); -void _vuESADD(VURegs * VU); -void _vuERSADD(VURegs * VU); -void _vuELENG(VURegs * VU); -void _vuERLENG(VURegs * VU); -void _vuEATANxy(VURegs * VU); -void _vuEATANxz(VURegs * VU); -void _vuESUM(VURegs * VU); -void _vuERCPR(VURegs * VU); -void _vuESQRT(VURegs * VU); -void _vuERSQRT(VURegs * VU); -void _vuESIN(VURegs * VU); -void _vuEATAN(VURegs * VU); -void _vuEEXP(VURegs * VU); -void _vuXITOP(VURegs * VU); -void _vuXGKICK(VURegs * VU); -void _vuXTOP(VURegs * VU); - -/******************************/ -/* VU Upper instructions */ -/******************************/ - -void _vuRegsABS(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsADD(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsADDi(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsADDq(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsADDx(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsADDy(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsADDz(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsADDw(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsADDA(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsADDAi(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsADDAq(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsADDAx(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsADDAy(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsADDAz(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsADDAw(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsSUB(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsSUBi(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsSUBq(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsSUBx(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsSUBy(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsSUBz(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsSUBw(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsSUBA(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsSUBAi(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsSUBAq(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsSUBAx(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsSUBAy(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsSUBAz(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsSUBAw(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsMUL(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsMULi(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsMULq(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsMULx(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsMULy(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsMULz(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsMULw(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsMULA(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsMULAi(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsMULAq(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsMULAx(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsMULAy(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsMULAz(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsMULAw(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsMADD(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsMADDi(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsMADDq(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsMADDx(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsMADDy(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsMADDz(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsMADDw(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsMADDA(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsMADDAi(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsMADDAq(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsMADDAx(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsMADDAy(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsMADDAz(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsMADDAw(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsMSUB(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsMSUBi(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsMSUBq(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsMSUBx(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsMSUBy(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsMSUBz(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsMSUBw(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsMSUBA(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsMSUBAi(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsMSUBAq(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsMSUBAx(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsMSUBAy(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsMSUBAz(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsMSUBAw(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsMAX(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsMAXi(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsMAXx(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsMAXy(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsMAXz(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsMAXw(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsMINI(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsMINIi(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsMINIx(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsMINIy(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsMINIz(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsMINIw(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsOPMULA(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsOPMSUB(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsNOP(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsFTOI0(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsFTOI4(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsFTOI12(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsFTOI15(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsITOF0(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsITOF4(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsITOF12(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsITOF15(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsCLIP(VURegs * VU, _VURegsNum *VUregsn); -/******************************/ -/* VU Lower instructions */ -/******************************/ -void _vuRegsDIV(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsSQRT(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsRSQRT(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsIADDI(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsIADDIU(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsIADD(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsIAND(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsIOR(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsISUB(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsISUBIU(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsMOVE(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsMFIR(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsMTIR(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsMR32(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsLQ(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsLQD(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsLQI(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsSQ(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsSQD(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsSQI(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsILW(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsISW(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsILWR(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsISWR(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsLOI(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsRINIT(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsRGET(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsRNEXT(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsRXOR(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsWAITQ(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsFSAND(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsFSEQ(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsFSOR(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsFSSET(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsFMAND(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsFMEQ(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsFMOR(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsFCAND(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsFCEQ(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsFCOR(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsFCSET(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsFCGET(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsIBEQ(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsIBGEZ(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsIBGTZ(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsIBLEZ(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsIBLTZ(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsIBNE(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsB(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsBAL(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsJR(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsJALR(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsMFP(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsWAITP(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsESADD(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsERSADD(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsELENG(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsERLENG(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsEATANxy(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsEATANxz(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsESUM(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsERCPR(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsESQRT(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsERSQRT(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsESIN(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsEATAN(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsEEXP(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsXITOP(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsXGKICK(VURegs * VU, _VURegsNum *VUregsn); -void _vuRegsXTOP(VURegs * VU, _VURegsNum *VUregsn); diff --git a/pcsx2/Vif.cpp b/pcsx2/Vif.cpp index a17dd47190..183579b978 100644 --- a/pcsx2/Vif.cpp +++ b/pcsx2/Vif.cpp @@ -29,13 +29,13 @@ void vif0Reset() { /* Reset the whole VIF, meaning the internal pcsx2 vars and all the registers */ memzero(vif0); - memzero(*vif0Regs); + memzero(vif0Regs); psHu64(VIF0_FIFO) = 0; psHu64(VIF0_FIFO + 8) = 0; - vif0Regs->stat.VPS = VPS_IDLE; - vif0Regs->stat.FQC = 0; + vif0Regs.stat.VPS = VPS_IDLE; + vif0Regs.stat.FQC = 0; vif0.done = false; @@ -46,13 +46,13 @@ void vif1Reset() { /* Reset the whole VIF, meaning the internal pcsx2 vars, and all the registers */ memzero(vif1); - memzero(*vif1Regs); + memzero(vif1Regs); psHu64(VIF1_FIFO) = 0; psHu64(VIF1_FIFO + 8) = 0; - vif1Regs->stat.VPS = VPS_IDLE; - vif1Regs->stat.FQC = 0; // FQC=0 + vif1Regs.stat.VPS = VPS_IDLE; + vif1Regs.stat.FQC = 0; // FQC=0 vif1.done = false; cpuRegs.interrupt &= ~((1 << 1) | (1 << 10)); //Stop all vif1 DMA's @@ -91,16 +91,16 @@ __fi void vif0FBRST(u32 value) { if (value & 0x1) // Reset Vif. { - //Console.WriteLn("Vif0 Reset %x", vif0Regs->stat._u32); + //Console.WriteLn("Vif0 Reset %x", vif0Regs.stat._u32); memzero(vif0); - vif0ch->qwc = 0; //? + vif0ch.qwc = 0; //? cpuRegs.interrupt &= ~1; //Stop all vif0 DMA's psHu64(VIF0_FIFO) = 0; psHu64(VIF0_FIFO + 8) = 0; vif0.done = false; - vif0Regs->err.reset(); - vif0Regs->stat.clear_flags(VIF0_STAT_FQC | VIF0_STAT_INT | VIF0_STAT_VSS | VIF0_STAT_VIS | VIF0_STAT_VFS | VIF0_STAT_VPS); // FQC=0 + vif0Regs.err.reset(); + vif0Regs.stat.clear_flags(VIF0_STAT_FQC | VIF0_STAT_INT | VIF0_STAT_VSS | VIF0_STAT_VIS | VIF0_STAT_VFS | VIF0_STAT_VPS); // FQC=0 } /* Fixme: Forcebreaks are pretty unknown for operation, presumption is it just stops it what its doing @@ -109,8 +109,8 @@ __fi void vif0FBRST(u32 value) { { /* I guess we should stop the VIF dma here, but not 100% sure (linuz) */ cpuRegs.interrupt &= ~1; //Stop all vif0 DMA's - vif0Regs->stat.VFS = true; - vif0Regs->stat.VPS = VPS_IDLE; + vif0Regs.stat.VFS = true; + vif0Regs.stat.VPS = VPS_IDLE; Console.WriteLn("vif0 force break"); } @@ -118,8 +118,8 @@ __fi void vif0FBRST(u32 value) { { // Not completely sure about this, can't remember what game, used this, but 'draining' the VIF helped it, instead of // just stoppin the VIF (linuz). - vif0Regs->stat.VSS = true; - vif0Regs->stat.VPS = VPS_IDLE; + vif0Regs.stat.VSS = true; + vif0Regs.stat.VPS = VPS_IDLE; vif0.vifstalled = true; } @@ -128,10 +128,10 @@ __fi void vif0FBRST(u32 value) { bool cancel = false; /* Cancel stall, first check if there is a stall to cancel, and then clear VIF0_STAT VSS|VFS|VIS|INT|ER0|ER1 bits */ - if (vif0Regs->stat.test(VIF0_STAT_VSS | VIF0_STAT_VIS | VIF0_STAT_VFS)) + if (vif0Regs.stat.test(VIF0_STAT_VSS | VIF0_STAT_VIS | VIF0_STAT_VFS)) cancel = true; - vif0Regs->stat.clear_flags(VIF0_STAT_VSS | VIF0_STAT_VFS | VIF0_STAT_VIS | + vif0Regs.stat.clear_flags(VIF0_STAT_VSS | VIF0_STAT_VFS | VIF0_STAT_VIS | VIF0_STAT_INT | VIF0_STAT_ER0 | VIF0_STAT_ER1); if (cancel) { @@ -140,8 +140,8 @@ __fi void vif0FBRST(u32 value) { g_vifCycles = 0; // loop necessary for spiderman - //vif0ch->chcr.STR = true; - if(vif0ch->chcr.STR) CPU_INT(DMAC_VIF0, 0); // Gets the timing right - Flatout + //vif0ch.chcr.STR = true; + if(vif0ch.chcr.STR) CPU_INT(DMAC_VIF0, 0); // Gets the timing right - Flatout } } } @@ -154,29 +154,29 @@ __fi void vif1FBRST(u32 value) { { memzero(vif1); //cpuRegs.interrupt &= ~((1 << 1) | (1 << 10)); //Stop all vif1 DMA's - vif1ch->qwc -= min((int)vif1ch->qwc, 16); //? + vif1ch.qwc -= min((int)vif1ch.qwc, 16); //? psHu64(VIF1_FIFO) = 0; psHu64(VIF1_FIFO + 8) = 0; //vif1.done = false; - //DevCon.Warning("VIF FBRST Reset MSK = %x", vif1Regs->mskpath3); - if(vif1Regs->mskpath3 == 1 && GSTransferStatus.PTH3 == STOPPED_MODE && gif->chcr.STR == true) + //DevCon.Warning("VIF FBRST Reset MSK = %x", vif1Regs.mskpath3); + if(vif1Regs.mskpath3 == 1 && GSTransferStatus.PTH3 == STOPPED_MODE && gifch.chcr.STR == true) { - //DevCon.Warning("VIF Path3 Resume on FBRST MSK = %x", vif1Regs->mskpath3); + //DevCon.Warning("VIF Path3 Resume on FBRST MSK = %x", vif1Regs.mskpath3); gsInterrupt(); - vif1Regs->mskpath3 = false; - gifRegs->stat.M3P = 0; + vif1Regs.mskpath3 = false; + gifRegs.stat.M3P = 0; } - vif1Regs->mskpath3 = false; - gifRegs->stat.M3P = 0; - vif1Regs->err.reset(); + vif1Regs.mskpath3 = false; + gifRegs.stat.M3P = 0; + vif1Regs.err.reset(); vif1.inprogress = 0; vif1.cmd = 0; vif1.vifstalled = false; - vif1Regs->stat.FQC = 0; - vif1Regs->stat.clear_flags(VIF1_STAT_FDR | VIF1_STAT_INT | VIF1_STAT_VSS | VIF1_STAT_VIS | VIF1_STAT_VFS | VIF1_STAT_VPS); + vif1Regs.stat.FQC = 0; + vif1Regs.stat.clear_flags(VIF1_STAT_FDR | VIF1_STAT_INT | VIF1_STAT_VSS | VIF1_STAT_VIS | VIF1_STAT_VFS | VIF1_STAT_VPS); } /* Fixme: Forcebreaks are pretty unknown for operation, presumption is it just stops it what its doing @@ -185,8 +185,8 @@ __fi void vif1FBRST(u32 value) { if (FBRST(value).FBK) // Forcebreak Vif. { /* I guess we should stop the VIF dma here, but not 100% sure (linuz) */ - vif1Regs->stat.VFS = true; - vif1Regs->stat.VPS = VPS_IDLE; + vif1Regs.stat.VFS = true; + vif1Regs.stat.VPS = VPS_IDLE; cpuRegs.interrupt &= ~((1 << 1) | (1 << 10)); //Stop all vif1 DMA's Console.WriteLn("vif1 force break"); } @@ -195,8 +195,8 @@ __fi void vif1FBRST(u32 value) { { // Not completely sure about this, can't remember what game used this, but 'draining' the VIF helped it, instead of // just stoppin the VIF (linuz). - vif1Regs->stat.VSS = true; - vif1Regs->stat.VPS = VPS_IDLE; + vif1Regs.stat.VSS = true; + vif1Regs.stat.VPS = VPS_IDLE; cpuRegs.interrupt &= ~((1 << 1) | (1 << 10)); //Stop all vif1 DMA's vif1.vifstalled = true; } @@ -206,12 +206,12 @@ __fi void vif1FBRST(u32 value) { bool cancel = false; /* Cancel stall, first check if there is a stall to cancel, and then clear VIF1_STAT VSS|VFS|VIS|INT|ER0|ER1 bits */ - if (vif1Regs->stat.test(VIF1_STAT_VSS | VIF1_STAT_VIS | VIF1_STAT_VFS)) + if (vif1Regs.stat.test(VIF1_STAT_VSS | VIF1_STAT_VIS | VIF1_STAT_VFS)) { cancel = true; } - vif1Regs->stat.clear_flags(VIF1_STAT_VSS | VIF1_STAT_VFS | VIF1_STAT_VIS | + vif1Regs.stat.clear_flags(VIF1_STAT_VSS | VIF1_STAT_VFS | VIF1_STAT_VIS | VIF1_STAT_INT | VIF1_STAT_ER0 | VIF1_STAT_ER1); if (cancel) @@ -220,22 +220,22 @@ __fi void vif1FBRST(u32 value) { { g_vifCycles = 0; // loop necessary for spiderman - switch(dmacRegs->ctrl.MFD) + switch(dmacRegs.ctrl.MFD) { case MFD_VIF1: //Console.WriteLn("MFIFO Stall"); - if(vif1ch->chcr.STR == true) CPU_INT(DMAC_MFIFO_VIF, 0); + if(vif1ch.chcr.STR == true) CPU_INT(DMAC_MFIFO_VIF, 0); break; case NO_MFD: case MFD_RESERVED: case MFD_GIF: // Wonder if this should be with VIF? // Gets the timing right - Flatout - if(vif1ch->chcr.STR == true) CPU_INT(DMAC_VIF1, 0); + if(vif1ch.chcr.STR == true) CPU_INT(DMAC_VIF1, 0); break; } - //vif1ch->chcr.STR = true; + //vif1ch.chcr.STR = true; } } } @@ -245,16 +245,16 @@ __fi void vif1STAT(u32 value) { VIF_LOG("VIF1_STAT write32 0x%8.8x", value); /* Only FDR bit is writable, so mask the rest */ - if ((vif1Regs->stat.FDR) ^ ((tVIF_STAT&)value).FDR) { + if ((vif1Regs.stat.FDR) ^ ((tVIF_STAT&)value).FDR) { // different so can't be stalled - if (vif1Regs->stat.test(VIF1_STAT_INT | VIF1_STAT_VSS | VIF1_STAT_VIS | VIF1_STAT_VFS)) { + if (vif1Regs.stat.test(VIF1_STAT_INT | VIF1_STAT_VSS | VIF1_STAT_VIS | VIF1_STAT_VFS)) { DevCon.WriteLn("changing dir when vif1 fifo stalled"); } } - vif1Regs->stat.FDR = VIF_STAT(value).FDR; + vif1Regs.stat.FDR = VIF_STAT(value).FDR; - if (vif1Regs->stat.FDR) // Vif transferring to memory. + if (vif1Regs.stat.FDR) // Vif transferring to memory. { // Hack but it checks this is true before transfer? (fatal frame) // Update Refraction: Use of this function has been investigated and understood. @@ -263,7 +263,7 @@ __fi void vif1STAT(u32 value) { // As far as the GS is concerned, the transfer starts as soon as TRXDIR is accessed, which is why fatal frame // was expecting data, the GS should already be sending it over (buffering in the FIFO) - vif1Regs->stat.FQC = min((u32)16, vif1.GSLastDownloadSize); + vif1Regs.stat.FQC = min((u32)16, vif1.GSLastDownloadSize); //Console.Warning("Reversing VIF Transfer for %x QWC", vif1.GSLastDownloadSize); } @@ -271,69 +271,65 @@ __fi void vif1STAT(u32 value) { { //Sometimes the value from the GS is bigger than vif wanted, so it just sets it back and cancels it. //Other times it can read it off ;) - vif1Regs->stat.FQC = 0; + vif1Regs.stat.FQC = 0; } } #define caseVif(x) (idx ? VIF1_##x : VIF0_##x) -_vifT void vifWrite32(u32 mem, u32 value) { +// returns FALSE if no writeback is needed (or writeback is handled internally) +// returns TRUE if the caller should writeback the value to the eeHw register map. +_vifT __fi bool vifWrite32(u32 mem, u32 value) { switch (mem) { case caseVif(MARK): VIF_LOG("VIF%d_MARK write32 0x%8.8x", idx, value); - vifXRegs->stat.MRK = false; - vifXRegs->mark = value; - break; + vifXRegs.stat.MRK = false; + //vifXRegs.mark = value; + break; case caseVif(FBRST): if (!idx) vif0FBRST(value); else vif1FBRST(value); - break; - - case caseVif(ERR): - VIF_LOG("VIF%d_ERR write32 0x%8.8x", idx, value); - vifXRegs->err.write(value); - break; + return false; case caseVif(STAT): if (idx) { // Only Vif1 does this stuff? vif1STAT(value); } - else { - Console.WriteLn("Unknown Vif%d write to %x", idx, mem); - psHu32(mem) = value; - } - break; + return false; + case caseVif(ERR): case caseVif(MODE): - vifXRegs->mode = value; - break; + // standard register writes -- handled by caller. + break; - case caseVif(R0): - case caseVif(R1): - case caseVif(R2): - case caseVif(R3): - if (!idx) g_vifmask.Row0[ (mem>>4)&3 ] = value; - else g_vifmask.Row1[ (mem>>4)&3 ] = value; - ((u32*)&vifXRegs->r0) [((mem>>4)&3)*4] = value; - break; + case caseVif(ROW0): + case caseVif(ROW1): + case caseVif(ROW2): + case caseVif(ROW3): + // Here's a neat way to obfuscate code. This is a super-fancy-complicated version + // of a standard psHu32(mem) = value; writeback. Handled by caller for us, thanks! --air + //if (!idx) g_vifmask.Row0[ (mem>>4)&3 ] = value; + //else g_vifmask.Row1[ (mem>>4)&3 ] = value; + //((u32*)&vifXRegs.r0) [((mem>>4)&3)*4] = value; + break; - case caseVif(C0): - case caseVif(C1): - case caseVif(C2): - case caseVif(C3): - if (!idx) g_vifmask.Col0[ (mem>>4)&3 ] = value; - else g_vifmask.Col1[ (mem>>4)&3 ] = value; - ((u32*)&vifXRegs->c0) [((mem>>4)&3)*4] = value; - break; - - default: - Console.WriteLn("Unknown Vif%d write to %x", idx, mem); - psHu32(mem) = value; - break; + case caseVif(COL0): + case caseVif(COL1): + case caseVif(COL2): + case caseVif(COL3): + // Here's a neat way to obfuscate code. This is a super-fancy-complicated version + // of a standard psHu32(mem) = value; writeback. Handled by caller for us, thanks! --air + //if (!idx) g_vifmask.Col0[ (mem>>4)&3 ] = value; + //else g_vifmask.Col1[ (mem>>4)&3 ] = value; + //((u32*)&vifXRegs.c0) [((mem>>4)&3)*4] = value; + break; } - /* Other registers are read-only so do nothing for them */ + + // fall-through case: issue standard writeback behavior. + return true; } -void vif0Write32(u32 mem, u32 value) { vifWrite32<0>(mem, value); } -void vif1Write32(u32 mem, u32 value) { vifWrite32<1>(mem, value); } + +template bool vifWrite32<0>(u32 mem, u32 value); +template bool vifWrite32<1>(u32 mem, u32 value); diff --git a/pcsx2/Vif.h b/pcsx2/Vif.h index 654a44969c..93381f0065 100644 --- a/pcsx2/Vif.h +++ b/pcsx2/Vif.h @@ -15,6 +15,7 @@ #pragma once +#include "MemoryTypes.h" #include "R5900.h" enum vif0_stat_flags @@ -214,10 +215,8 @@ struct VIFregisters { extern VIFregisters *vifRegs; -#define vif0RegsRef ((VIFregisters&)eeMem->HW[0x3800]) -#define vif1RegsRef ((VIFregisters&)eeMem->HW[0x3c00]) -#define vif0Regs (&vif0RegsRef) -#define vif1Regs (&vif1RegsRef) +static VIFregisters& vif0Regs = (VIFregisters&)eeHw[0x3800]; +static VIFregisters& vif1Regs = (VIFregisters&)eeHw[0x3C00]; #define _vifT template #define GetVifX (idx ? (vif1) : (vif0)) diff --git a/pcsx2/Vif0_Dma.cpp b/pcsx2/Vif0_Dma.cpp index 2adfadded2..b0a39138fe 100644 --- a/pcsx2/Vif0_Dma.cpp +++ b/pcsx2/Vif0_Dma.cpp @@ -54,28 +54,28 @@ bool _VIF0chain() { u32 *pMem; - if (vif0ch->qwc == 0) + if (vif0ch.qwc == 0) { vif0.inprogress = 0; return true; } - pMem = (u32*)dmaGetAddr(vif0ch->madr, false); + pMem = (u32*)dmaGetAddr(vif0ch.madr, false); if (pMem == NULL) { vif0.cmd = 0; vif0.tag.size = 0; - vif0ch->qwc = 0; + vif0ch.qwc = 0; return true; } VIF_LOG("VIF0chain size=%d, madr=%lx, tadr=%lx", - vif0ch->qwc, vif0ch->madr, vif0ch->tadr); + vif0ch.qwc, vif0ch.madr, vif0ch.tadr); if (vif0.vifstalled) - return VIF0transfer(pMem + vif0.irqoffset, vif0ch->qwc * 4 - vif0.irqoffset); + return VIF0transfer(pMem + vif0.irqoffset, vif0ch.qwc * 4 - vif0.irqoffset); else - return VIF0transfer(pMem, vif0ch->qwc * 4); + return VIF0transfer(pMem, vif0ch.qwc * 4); } __fi void vif0SetupTransfer() @@ -91,21 +91,21 @@ __fi void vif0SetupTransfer() break; case VIF_CHAIN_MODE: - ptag = dmaGetAddr(vif0ch->tadr, false); //Set memory pointer to TADR + ptag = dmaGetAddr(vif0ch.tadr, false); //Set memory pointer to TADR - if (!(vif0ch->transfer("vif0 Tag", ptag))) return; + if (!(vif0ch.transfer("vif0 Tag", ptag))) return; - vif0ch->madr = ptag[1]._u32; //MADR = ADDR field + SPR + vif0ch.madr = ptag[1]._u32; //MADR = ADDR field + SPR g_vifCycles += 1; // Add 1 g_vifCycles from the QW read for the tag // Transfer dma tag if tte is set VIF_LOG("vif0 Tag %8.8x_%8.8x size=%d, id=%d, madr=%lx, tadr=%lx", - ptag[1]._u32, ptag[0]._u32, vif0ch->qwc, ptag->ID, vif0ch->madr, vif0ch->tadr); + ptag[1]._u32, ptag[0]._u32, vif0ch.qwc, ptag->ID, vif0ch.madr, vif0ch.tadr); vif0.inprogress = 0; - if (vif0ch->chcr.TTE) + if (vif0ch.chcr.TTE) { bool ret; @@ -124,9 +124,9 @@ __fi void vif0SetupTransfer() vif0.irqoffset = 0; vif0.done |= hwDmacSrcChainWithStack(vif0ch, ptag->ID); - if(vif0ch->qwc > 0) vif0.inprogress = 1; + if(vif0ch.qwc > 0) vif0.inprogress = 1; //Check TIE bit of CHCR and IRQ bit of tag - if (vif0ch->chcr.TIE && ptag->IRQ) + if (vif0ch.chcr.TIE && ptag->IRQ) { VIF_LOG("dmaIrq Set"); @@ -144,29 +144,29 @@ __fi void vif0Interrupt() g_vifCycles = 0; - if (!(vif0ch->chcr.STR)) Console.WriteLn("vif0 running when CHCR == %x", vif0ch->chcr._u32); + if (!(vif0ch.chcr.STR)) Console.WriteLn("vif0 running when CHCR == %x", vif0ch.chcr._u32); if (vif0.cmd) { - if(vif0.done == true && vif0ch->qwc == 0) vif0Regs->stat.VPS = VPS_WAITING; + if(vif0.done == true && vif0ch.qwc == 0) vif0Regs.stat.VPS = VPS_WAITING; } else { - vif0Regs->stat.VPS = VPS_IDLE; + vif0Regs.stat.VPS = VPS_IDLE; } if (vif0.irq && vif0.tag.size == 0) { - vif0Regs->stat.INT = true; + vif0Regs.stat.INT = true; hwIntcIrq(VIF0intc); --vif0.irq; - if (vif0Regs->stat.test(VIF0_STAT_VSS | VIF0_STAT_VIS | VIF0_STAT_VFS)) + if (vif0Regs.stat.test(VIF0_STAT_VSS | VIF0_STAT_VIS | VIF0_STAT_VFS)) { - vif0Regs->stat.FQC = 0; + vif0Regs.stat.FQC = 0; // One game doesn't like vif stalling at end, can't remember what. Spiderman isn't keen on it tho - //vif0ch->chcr.STR = false; - if(vif0ch->qwc > 0 || !vif0.done) return; + //vif0ch.chcr.STR = false; + if(vif0ch.qwc > 0 || !vif0.done) return; } } @@ -180,7 +180,7 @@ __fi void vif0Interrupt() if (!vif0.done) { - if (!(dmacRegs->ctrl.DMAE)) + if (!(dmacRegs.ctrl.DMAE)) { Console.WriteLn("vif0 dma masked"); return; @@ -199,22 +199,22 @@ __fi void vif0Interrupt() return; //Dont want to end if vif is stalled. } #ifdef PCSX2_DEVBUILD - if (vif0ch->qwc > 0) Console.WriteLn("vif0 Ending with %x QWC left"); + if (vif0ch.qwc > 0) Console.WriteLn("vif0 Ending with %x QWC left"); if (vif0.cmd != 0) Console.WriteLn("vif0.cmd still set %x tag size %x", vif0.cmd, vif0.tag.size); #endif - vif0ch->chcr.STR = false; + vif0ch.chcr.STR = false; g_vifCycles = 0; hwDmacIrq(DMAC_VIF0); - vif0Regs->stat.FQC = 0; + vif0Regs.stat.FQC = 0; } void dmaVIF0() { VIF_LOG("dmaVIF0 chcr = %lx, madr = %lx, qwc = %lx\n" " tadr = %lx, asr0 = %lx, asr1 = %lx", - vif0ch->chcr._u32, vif0ch->madr, vif0ch->qwc, - vif0ch->tadr, vif0ch->asr0, vif0ch->asr1); + vif0ch.chcr._u32, vif0ch.madr, vif0ch.qwc, + vif0ch.tadr, vif0ch.asr0, vif0ch.asr1); g_vifCycles = 0; g_vu0Cycles = 0; @@ -224,18 +224,18 @@ void dmaVIF0() vif0.inprogress = 0; vif0.done = false;*/ - if ((vif0ch->chcr.MOD == NORMAL_MODE) || vif0ch->qwc > 0) // Normal Mode + if ((vif0ch.chcr.MOD == NORMAL_MODE) || vif0ch.qwc > 0) // Normal Mode { vif0.dmamode = VIF_NORMAL_TO_MEM_MODE; vif0.done = false; - if(vif0ch->chcr.MOD == CHAIN_MODE && vif0ch->qwc > 0) + if(vif0ch.chcr.MOD == CHAIN_MODE && vif0ch.qwc > 0) { vif0.dmamode = VIF_CHAIN_MODE; - DevCon.Warning(L"VIF0 QWC on Chain CHCR " + vif0ch->chcr.desc()); + DevCon.Warning(L"VIF0 QWC on Chain CHCR " + vif0ch.chcr.desc()); - if ((vif0ch->chcr.tag().ID == TAG_REFE) || (vif0ch->chcr.tag().ID == TAG_END)) + if ((vif0ch.chcr.tag().ID == TAG_REFE) || (vif0ch.chcr.tag().ID == TAG_END)) { vif0.done = true; } @@ -247,7 +247,7 @@ void dmaVIF0() vif0.done = false; } - vif0Regs->stat.FQC = min((u16)0x8, vif0ch->qwc); + vif0Regs.stat.FQC = min((u16)0x8, vif0ch.qwc); //Using a delay as Beyond Good and Evil does the DMA twice with 2 different TADR's (no checks in the middle, all one block of code), //the first bit it sends isnt required for it to work. diff --git a/pcsx2/Vif1_Dma.cpp b/pcsx2/Vif1_Dma.cpp index 0adc11b3ed..7b7ff73bb9 100644 --- a/pcsx2/Vif1_Dma.cpp +++ b/pcsx2/Vif1_Dma.cpp @@ -46,10 +46,10 @@ __fi void vif1FLUSH() //DevCon.Warning("VIF1 adding %x cycles", (VU1.cycle - _cycles) * BIAS); g_vifCycles += (VU1.cycle - _cycles) * BIAS; } - if(gifRegs->stat.P1Q && ((vif1.cmd & 0x7f) != 0x14) && ((vif1.cmd & 0x7f) != 0x17)) + if(gifRegs.stat.P1Q && ((vif1.cmd & 0x7f) != 0x14) && ((vif1.cmd & 0x7f) != 0x17)) { vif1.vifstalled = true; - vif1Regs->stat.VGW = true; + vif1Regs.stat.VGW = true; vif1.GifWaitState = 2; } @@ -58,16 +58,16 @@ __fi void vif1FLUSH() void vif1TransferToMemory() { u32 size; - u64* pMem = (u64*)dmaGetAddr(vif1ch->madr, false); + u64* pMem = (u64*)dmaGetAddr(vif1ch.madr, false); // VIF from gsMemory if (pMem == NULL) //Is vif0ptag empty? { Console.WriteLn("Vif1 Tag BUSERR"); - dmacRegs->stat.BEIS = true; //Bus Error - vif1Regs->stat.FQC = 0; + dmacRegs.stat.BEIS = true; //Bus Error + vif1Regs.stat.FQC = 0; - vif1ch->qwc = 0; + vif1ch.qwc = 0; vif1.done = true; CPU_INT(DMAC_VIF1, 0); return; //An error has occurred. @@ -76,8 +76,8 @@ void vif1TransferToMemory() // MTGS concerns: The MTGS is inherently disagreeable with the idea of downloading // stuff from the GS. The *only* way to handle this case safely is to flush the GS // completely and execute the transfer there-after. - //Console.Warning("Real QWC %x", vif1ch->qwc); - size = min((u32)vif1ch->qwc, vif1.GSLastDownloadSize); + //Console.Warning("Real QWC %x", vif1ch.qwc); + size = min((u32)vif1ch.qwc, vif1.GSLastDownloadSize); if (GSreadFIFO2 == NULL) { @@ -90,10 +90,10 @@ void vif1TransferToMemory() pMem[1] = psHu64(VIF1_FIFO + 8); pMem += 2; } - if(vif1ch->qwc > vif1.GSLastDownloadSize) + if(vif1ch.qwc > vif1.GSLastDownloadSize) { DevCon.Warning("GS Transfer < VIF QWC, Clearing end of space"); - for (size = vif1ch->qwc - vif1.GSLastDownloadSize; size > 0; --size) + for (size = vif1ch.qwc - vif1.GSLastDownloadSize; size > 0; --size) { psHu64(VIF1_FIFO) = 0; psHu64(VIF1_FIFO + 8) = 0; @@ -112,10 +112,10 @@ void vif1TransferToMemory() psHu64(VIF1_FIFO) = pMem[2*size-2]; psHu64(VIF1_FIFO + 8) = pMem[2*size-1]; pMem += size * 2; - if(vif1ch->qwc > vif1.GSLastDownloadSize) + if(vif1ch.qwc > vif1.GSLastDownloadSize) { DevCon.Warning("GS Transfer < VIF QWC, Clearing end of space"); - for (size = vif1ch->qwc - vif1.GSLastDownloadSize; size > 0; --size) + for (size = vif1ch.qwc - vif1.GSLastDownloadSize; size > 0; --size) { psHu64(VIF1_FIFO) = 0; psHu64(VIF1_FIFO + 8) = 0; @@ -127,27 +127,27 @@ void vif1TransferToMemory() } - g_vifCycles += vif1ch->qwc * 2; - vif1ch->madr += vif1ch->qwc * 16; // mgs3 scene changes - if(vif1.GSLastDownloadSize >= vif1ch->qwc) + g_vifCycles += vif1ch.qwc * 2; + vif1ch.madr += vif1ch.qwc * 16; // mgs3 scene changes + if(vif1.GSLastDownloadSize >= vif1ch.qwc) { - vif1.GSLastDownloadSize -= vif1ch->qwc; - vif1Regs->stat.FQC = min((u32)16, vif1.GSLastDownloadSize); + vif1.GSLastDownloadSize -= vif1ch.qwc; + vif1Regs.stat.FQC = min((u32)16, vif1.GSLastDownloadSize); } else { - vif1Regs->stat.FQC = 0; + vif1Regs.stat.FQC = 0; vif1.GSLastDownloadSize = 0; } - vif1ch->qwc = 0; + vif1ch.qwc = 0; } bool _VIF1chain() { u32 *pMem; - if (vif1ch->qwc == 0) + if (vif1ch.qwc == 0) { vif1.inprogress &= ~1; vif1.irqoffset = 0; @@ -162,28 +162,27 @@ bool _VIF1chain() return true; } - pMem = (u32*)dmaGetAddr(vif1ch->madr, !vif1ch->chcr.DIR); + pMem = (u32*)dmaGetAddr(vif1ch.madr, !vif1ch.chcr.DIR); if (pMem == NULL) { vif1.cmd = 0; vif1.tag.size = 0; - vif1ch->qwc = 0; + vif1ch.qwc = 0; return true; } VIF_LOG("VIF1chain size=%d, madr=%lx, tadr=%lx", - vif1ch->qwc, vif1ch->madr, vif1ch->tadr); + vif1ch.qwc, vif1ch.madr, vif1ch.tadr); if (vif1.vifstalled) - return VIF1transfer(pMem + vif1.irqoffset, vif1ch->qwc * 4 - vif1.irqoffset); + return VIF1transfer(pMem + vif1.irqoffset, vif1ch.qwc * 4 - vif1.irqoffset); else - return VIF1transfer(pMem, vif1ch->qwc * 4); + return VIF1transfer(pMem, vif1ch.qwc * 4); } __fi void vif1SetupTransfer() { tDMA_TAG *ptag; - DMACh& vif1c = (DMACh&)eeMem->HW[0x9000]; switch (vif1.dmamode) { @@ -195,20 +194,20 @@ __fi void vif1SetupTransfer() break; case VIF_CHAIN_MODE: - ptag = dmaGetAddr(vif1c.tadr, false); //Set memory pointer to TADR + ptag = dmaGetAddr(vif1ch.tadr, false); //Set memory pointer to TADR - if (!(vif1c.transfer("Vif1 Tag", ptag))) return; + if (!(vif1ch.transfer("Vif1 Tag", ptag))) return; - vif1c.madr = ptag[1]._u32; //MADR = ADDR field + SPR + vif1ch.madr = ptag[1]._u32; //MADR = ADDR field + SPR g_vifCycles += 1; // Add 1 g_vifCycles from the QW read for the tag VIF_LOG("VIF1 Tag %8.8x_%8.8x size=%d, id=%d, madr=%lx, tadr=%lx", - ptag[1]._u32, ptag[0]._u32, vif1c.qwc, ptag->ID, vif1c.madr, vif1c.tadr); + ptag[1]._u32, ptag[0]._u32, vif1ch.qwc, ptag->ID, vif1ch.madr, vif1ch.tadr); - if (!vif1.done && ((dmacRegs->ctrl.STD == STD_VIF1) && (ptag->ID == TAG_REFS))) // STD == VIF1 + if (!vif1.done && ((dmacRegs.ctrl.STD == STD_VIF1) && (ptag->ID == TAG_REFS))) // STD == VIF1 { // there are still bugs, need to also check if gif->madr +16*qwc >= stadr, if not, stall - if ((vif1c.madr + vif1c.qwc * 16) >= dmacRegs->stadr.ADDR) + if ((vif1ch.madr + vif1ch.qwc * 16) >= dmacRegs.stadr.ADDR) { // stalled hwDmacIrq(DMAC_STALL_SIS); @@ -219,7 +218,7 @@ __fi void vif1SetupTransfer() vif1.inprogress &= ~1; - if (vif1c.chcr.TTE) + if (vif1ch.chcr.TTE) { // Transfer dma tag if tte is set @@ -243,10 +242,10 @@ __fi void vif1SetupTransfer() vif1.done |= hwDmacSrcChainWithStack(vif1ch, ptag->ID); - if(vif1c.qwc > 0) vif1.inprogress |= 1; + if(vif1ch.qwc > 0) vif1.inprogress |= 1; //Check TIE bit of CHCR and IRQ bit of tag - if (vif1c.chcr.TIE && ptag->IRQ) + if (vif1ch.chcr.TIE && ptag->IRQ) { VIF_LOG("dmaIrq Set"); @@ -262,73 +261,73 @@ extern bool SIGNAL_IMR_Pending; bool CheckPath2GIF(EE_EventType channel) { - if ((vif1Regs->stat.VGW)) + if ((vif1Regs.stat.VGW)) { if( vif1.GifWaitState == 0 ) //DIRECT/HL Check { - if(GSTransferStatus.PTH3 < IDLE_MODE || gifRegs->stat.P1Q) + if(GSTransferStatus.PTH3 < IDLE_MODE || gifRegs.stat.P1Q) { - if(gifRegs->stat.IMT && GSTransferStatus.PTH3 <= IMAGE_MODE && (vif1.cmd & 0x7f) == 0x50 && gifRegs->stat.P1Q == false) + if(gifRegs.stat.IMT && GSTransferStatus.PTH3 <= IMAGE_MODE && (vif1.cmd & 0x7f) == 0x50 && gifRegs.stat.P1Q == false) { - vif1Regs->stat.VGW = false; + vif1Regs.stat.VGW = false; } else { - //DevCon.Warning("VIF1-0 stall P1Q %x P2Q %x APATH %x PTH3 %x vif1cmd %x", gifRegs->stat.P1Q, gifRegs->stat.P2Q, gifRegs->stat.APATH, GSTransferStatus.PTH3, vif1.cmd); + //DevCon.Warning("VIF1-0 stall P1Q %x P2Q %x APATH %x PTH3 %x vif1cmd %x", gifRegs.stat.P1Q, gifRegs.stat.P2Q, gifRegs.stat.APATH, GSTransferStatus.PTH3, vif1.cmd); CPU_INT(channel, 128); return false; } } else { - vif1Regs->stat.VGW = false; + vif1Regs.stat.VGW = false; } } else if( vif1.GifWaitState == 1 ) // Else we're flushing path3 :), but of course waiting for the microprogram to finish { - if (gifRegs->stat.P1Q) + if (gifRegs.stat.P1Q) { - //DevCon.Warning("VIF1-1 stall P1Q %x P2Q %x APATH %x PTH3 %x vif1cmd %x", gifRegs->stat.P1Q, gifRegs->stat.P2Q, gifRegs->stat.APATH, GSTransferStatus.PTH3, vif1.cmd); + //DevCon.Warning("VIF1-1 stall P1Q %x P2Q %x APATH %x PTH3 %x vif1cmd %x", gifRegs.stat.P1Q, gifRegs.stat.P2Q, gifRegs.stat.APATH, GSTransferStatus.PTH3, vif1.cmd); CPU_INT(channel, 128); return false; } if (GSTransferStatus.PTH3 < IDLE_MODE) { - //DevCon.Warning("VIF1-11 stall P1Q %x P2Q %x APATH %x PTH3 %x vif1cmd %x", gifRegs->stat.P1Q, gifRegs->stat.P2Q, gifRegs->stat.APATH, GSTransferStatus.PTH3, vif1.cmd); - //DevCon.Warning("PTH3 %x P1Q %x P3Q %x IP3 %x", GSTransferStatus.PTH3, gifRegs->stat.P1Q, gifRegs->stat.P3Q, gifRegs->stat.IP3 ); + //DevCon.Warning("VIF1-11 stall P1Q %x P2Q %x APATH %x PTH3 %x vif1cmd %x", gifRegs.stat.P1Q, gifRegs.stat.P2Q, gifRegs.stat.APATH, GSTransferStatus.PTH3, vif1.cmd); + //DevCon.Warning("PTH3 %x P1Q %x P3Q %x IP3 %x", GSTransferStatus.PTH3, gifRegs.stat.P1Q, gifRegs.stat.P3Q, gifRegs.stat.IP3 ); CPU_INT(channel, 8); return false; } else { - vif1Regs->stat.VGW = false; + vif1Regs.stat.VGW = false; } } else if( vif1.GifWaitState == 3 ) // Else we're flushing path3 :), but of course waiting for the microprogram to finish { - if (gifRegs->ctrl.PSE) + if (gifRegs.ctrl.PSE) { - //DevCon.Warning("VIF1-1 stall P1Q %x P2Q %x APATH %x PTH3 %x vif1cmd %x", gifRegs->stat.P1Q, gifRegs->stat.P2Q, gifRegs->stat.APATH, GSTransferStatus.PTH3, vif1.cmd); + //DevCon.Warning("VIF1-1 stall P1Q %x P2Q %x APATH %x PTH3 %x vif1cmd %x", gifRegs.stat.P1Q, gifRegs.stat.P2Q, gifRegs.stat.APATH, GSTransferStatus.PTH3, vif1.cmd); CPU_INT(channel, 128); return false; } else { - vif1Regs->stat.VGW = false; + vif1Regs.stat.VGW = false; } } else //Normal Flush { - if (gifRegs->stat.P1Q) + if (gifRegs.stat.P1Q) { - //DevCon.Warning("VIF1-2 stall P1Q %x P2Q %x APATH %x PTH3 %x vif1cmd %x", gifRegs->stat.P1Q, gifRegs->stat.P2Q, gifRegs->stat.APATH, GSTransferStatus.PTH3, vif1.cmd); + //DevCon.Warning("VIF1-2 stall P1Q %x P2Q %x APATH %x PTH3 %x vif1cmd %x", gifRegs.stat.P1Q, gifRegs.stat.P2Q, gifRegs.stat.APATH, GSTransferStatus.PTH3, vif1.cmd); CPU_INT(channel, 128); return false; } else { - vif1Regs->stat.VGW = false; + vif1Regs.stat.VGW = false; } } } @@ -346,11 +345,11 @@ __fi void vif1Interrupt() g_vifCycles = 0; - if(GSTransferStatus.PTH2 == STOPPED_MODE && gifRegs->stat.APATH == GIF_APATH2) + if(GSTransferStatus.PTH2 == STOPPED_MODE && gifRegs.stat.APATH == GIF_APATH2) { - gifRegs->stat.OPH = false; - gifRegs->stat.APATH = GIF_APATH_IDLE; - if(gifRegs->stat.P1Q) gsPath1Interrupt(); + gifRegs.stat.OPH = false; + gifRegs.stat.APATH = GIF_APATH_IDLE; + if(gifRegs.stat.P1Q) gsPath1Interrupt(); } if (schedulepath3msk & 0x10) @@ -360,48 +359,48 @@ __fi void vif1Interrupt() return; } //Some games (Fahrenheit being one) start vif first, let it loop through blankness while it sets MFIFO mode, so we need to check it here. - if (dmacRegs->ctrl.MFD == MFD_VIF1) + if (dmacRegs.ctrl.MFD == MFD_VIF1) { //Console.WriteLn("VIFMFIFO\n"); // Test changed because the Final Fantasy 12 opening somehow has the tag in *Undefined* mode, which is not in the documentation that I saw. - if (vif1ch->chcr.MOD == NORMAL_MODE) Console.WriteLn("MFIFO mode is normal (which isn't normal here)! %x", vif1ch->chcr._u32); - vif1Regs->stat.FQC = min((u16)0x10, vif1ch->qwc); + if (vif1ch.chcr.MOD == NORMAL_MODE) Console.WriteLn("MFIFO mode is normal (which isn't normal here)! %x", vif1ch.chcr._u32); + vif1Regs.stat.FQC = min((u16)0x10, vif1ch.qwc); vifMFIFOInterrupt(); return; } //We need to check the direction, if it is downloading from the GS, we handle that separately (KH2 for testing) - if (vif1ch->chcr.DIR) + if (vif1ch.chcr.DIR) { if (!CheckPath2GIF(DMAC_VIF1)) return; - vif1Regs->stat.FQC = min(vif1ch->qwc, (u16)16); + vif1Regs.stat.FQC = min(vif1ch.qwc, (u16)16); //Simulated GS transfer time done, clear the flags } - if (!vif1ch->chcr.STR) Console.WriteLn("Vif1 running when CHCR == %x", vif1ch->chcr._u32); + if (!vif1ch.chcr.STR) Console.WriteLn("Vif1 running when CHCR == %x", vif1ch.chcr._u32); if (vif1.cmd) { - if (vif1.done && (vif1ch->qwc == 0)) vif1Regs->stat.VPS = VPS_WAITING; + if (vif1.done && (vif1ch.qwc == 0)) vif1Regs.stat.VPS = VPS_WAITING; } else { - vif1Regs->stat.VPS = VPS_IDLE; + vif1Regs.stat.VPS = VPS_IDLE; } if (vif1.irq && vif1.tag.size == 0) { - vif1Regs->stat.INT = true; + vif1Regs.stat.INT = true; hwIntcIrq(VIF1intc); --vif1.irq; - if (vif1Regs->stat.test(VIF1_STAT_VSS | VIF1_STAT_VIS | VIF1_STAT_VFS)) + if (vif1Regs.stat.test(VIF1_STAT_VSS | VIF1_STAT_VIS | VIF1_STAT_VFS)) { - //vif1Regs->stat.FQC = 0; + //vif1Regs.stat.FQC = 0; //NFSHPS stalls when the whole packet has gone across (it stalls in the last 32bit cmd) //In this case VIF will end - if(vif1ch->qwc > 0 || !vif1.done) return; + if(vif1ch.qwc > 0 || !vif1.done) return; } } @@ -410,7 +409,7 @@ __fi void vif1Interrupt() _VIF1chain(); // VIF_NORMAL_FROM_MEM_MODE is a very slow operation. // Timesplitters 2 depends on this beeing a bit higher than 128. - if (vif1ch->chcr.DIR) vif1Regs->stat.FQC = min(vif1ch->qwc, (u16)16); + if (vif1ch.chcr.DIR) vif1Regs.stat.FQC = min(vif1ch.qwc, (u16)16); // Refraction - Removing voodoo timings for now, completely messes a lot of Path3 masked games. /*if (vif1.dmamode == VIF_NORMAL_FROM_MEM_MODE ) CPU_INT(DMAC_VIF1, 1024); else */CPU_INT(DMAC_VIF1, g_vifCycles /*VifCycleVoodoo*/); @@ -420,14 +419,14 @@ __fi void vif1Interrupt() if (!vif1.done) { - if (!(dmacRegs->ctrl.DMAE)) + if (!(dmacRegs.ctrl.DMAE)) { Console.WriteLn("vif1 dma masked"); return; } if ((vif1.inprogress & 0x1) == 0) vif1SetupTransfer(); - if (vif1ch->chcr.DIR) vif1Regs->stat.FQC = min(vif1ch->qwc, (u16)16); + if (vif1ch.chcr.DIR) vif1Regs.stat.FQC = min(vif1ch.qwc, (u16)16); CPU_INT(DMAC_VIF1, g_vifCycles); return; } @@ -439,17 +438,17 @@ __fi void vif1Interrupt() return; //Dont want to end if vif is stalled. } #ifdef PCSX2_DEVBUILD - if (vif1ch->qwc > 0) Console.WriteLn("VIF1 Ending with %x QWC left", vif1ch->qwc); + if (vif1ch.qwc > 0) Console.WriteLn("VIF1 Ending with %x QWC left", vif1ch.qwc); if (vif1.cmd != 0) Console.WriteLn("vif1.cmd still set %x tag size %x", vif1.cmd, vif1.tag.size); #endif - if((vif1ch->chcr.DIR == VIF_NORMAL_TO_MEM_MODE) && vif1.GSLastDownloadSize <= 16) + if((vif1ch.chcr.DIR == VIF_NORMAL_TO_MEM_MODE) && vif1.GSLastDownloadSize <= 16) { //Reverse fifo has finished and nothing is left, so lets clear the outputting flag - gifRegs->stat.OPH = false; + gifRegs.stat.OPH = false; } - vif1ch->chcr.STR = false; + vif1ch.chcr.STR = false; vif1.vifstalled = false; g_vifCycles = 0; g_vu1Cycles = 0; @@ -462,8 +461,8 @@ void dmaVIF1() { VIF_LOG("dmaVIF1 chcr = %lx, madr = %lx, qwc = %lx\n" " tadr = %lx, asr0 = %lx, asr1 = %lx", - vif1ch->chcr._u32, vif1ch->madr, vif1ch->qwc, - vif1ch->tadr, vif1ch->asr0, vif1ch->asr1); + vif1ch.chcr._u32, vif1ch.madr, vif1ch.qwc, + vif1ch.tadr, vif1ch.asr0, vif1ch.asr1); // vif1.done = false; @@ -475,19 +474,19 @@ void dmaVIF1() g_vu1Cycles = 0; #ifdef PCSX2_DEVBUILD - if (dmacRegs->ctrl.STD == STD_VIF1) + if (dmacRegs.ctrl.STD == STD_VIF1) { //DevCon.WriteLn("VIF Stall Control Source = %x, Drain = %x", (psHu32(0xe000) >> 4) & 0x3, (psHu32(0xe000) >> 6) & 0x3); } #endif - if ((vif1ch->chcr.MOD == NORMAL_MODE) || vif1ch->qwc > 0) // Normal Mode + if ((vif1ch.chcr.MOD == NORMAL_MODE) || vif1ch.qwc > 0) // Normal Mode { - if (dmacRegs->ctrl.STD == STD_VIF1) + if (dmacRegs.ctrl.STD == STD_VIF1) Console.WriteLn("DMA Stall Control on VIF1 normal"); - if (vif1ch->chcr.DIR) // to Memory + if (vif1ch.chcr.DIR) // to Memory vif1.dmamode = VIF_NORMAL_FROM_MEM_MODE; else vif1.dmamode = VIF_NORMAL_TO_MEM_MODE; @@ -495,12 +494,12 @@ void dmaVIF1() vif1.done = false; // ignore tag if it's a GS download (Def Jam Fight for NY) - if(vif1ch->chcr.MOD == CHAIN_MODE && vif1.dmamode != VIF_NORMAL_TO_MEM_MODE) + if(vif1ch.chcr.MOD == CHAIN_MODE && vif1.dmamode != VIF_NORMAL_TO_MEM_MODE) { vif1.dmamode = VIF_CHAIN_MODE; - DevCon.Warning(L"VIF1 QWC on Chain CHCR " + vif1ch->chcr.desc()); + DevCon.Warning(L"VIF1 QWC on Chain CHCR " + vif1ch.chcr.desc()); - if ((vif1ch->chcr.tag().ID == TAG_REFE) || (vif1ch->chcr.tag().ID == TAG_END)) + if ((vif1ch.chcr.tag().ID == TAG_REFE) || (vif1ch.chcr.tag().ID == TAG_END)) { vif1.done = true; } @@ -512,7 +511,7 @@ void dmaVIF1() vif1.done = false; } - if (vif1ch->chcr.DIR) vif1Regs->stat.FQC = min((u16)0x10, vif1ch->qwc); + if (vif1ch.chcr.DIR) vif1Regs.stat.FQC = min((u16)0x10, vif1ch.qwc); // Chain Mode CPU_INT(DMAC_VIF1, 4); diff --git a/pcsx2/Vif1_MFIFO.cpp b/pcsx2/Vif1_MFIFO.cpp index fc2ce4f818..490b00dd4c 100644 --- a/pcsx2/Vif1_MFIFO.cpp +++ b/pcsx2/Vif1_MFIFO.cpp @@ -33,26 +33,26 @@ extern u32 g_vifCycles; static u32 qwctag(u32 mask) { - return (dmacRegs->rbor.ADDR + (mask & dmacRegs->rbsr.RMSK)); + return (dmacRegs.rbor.ADDR + (mask & dmacRegs.rbsr.RMSK)); } static __fi bool mfifoVIF1rbTransfer() { - u32 maddr = dmacRegs->rbor.ADDR; - u32 msize = dmacRegs->rbor.ADDR + dmacRegs->rbsr.RMSK + 16; - u16 mfifoqwc = std::min(vif1ch->qwc, vifqwc); + u32 maddr = dmacRegs.rbor.ADDR; + u32 msize = dmacRegs.rbor.ADDR + dmacRegs.rbsr.RMSK + 16; + u16 mfifoqwc = std::min(vif1ch.qwc, vifqwc); u32 *src; bool ret; /* Check if the transfer should wrap around the ring buffer */ - if ((vif1ch->madr + (mfifoqwc << 4)) > (msize)) + if ((vif1ch.madr + (mfifoqwc << 4)) > (msize)) { - int s1 = ((msize) - vif1ch->madr) >> 2; + int s1 = ((msize) - vif1ch.madr) >> 2; SPR_LOG("Split MFIFO"); /* it does, so first copy 's1' bytes from 'addr' to 'data' */ - src = (u32*)PSM(vif1ch->madr); + src = (u32*)PSM(vif1ch.madr); if (src == NULL) return false; if (vif1.vifstalled) @@ -60,18 +60,18 @@ static __fi bool mfifoVIF1rbTransfer() else ret = VIF1transfer(src, s1); - vif1ch->madr = qwctag(vif1ch->madr); + vif1ch.madr = qwctag(vif1ch.madr); if (ret) { /* and second copy 's2' bytes from 'maddr' to '&data[s1]' */ - vif1ch->madr = maddr; + vif1ch.madr = maddr; src = (u32*)PSM(maddr); if (src == NULL) return false; VIF1transfer(src, ((mfifoqwc << 2) - s1)); } - vif1ch->madr = qwctag(vif1ch->madr); + vif1ch.madr = qwctag(vif1ch.madr); } else @@ -79,7 +79,7 @@ static __fi bool mfifoVIF1rbTransfer() SPR_LOG("Direct MFIFO"); /* it doesn't, so just transfer 'qwc*4' words */ - src = (u32*)PSM(vif1ch->madr); + src = (u32*)PSM(vif1ch.madr); if (src == NULL) return false; if (vif1.vifstalled) @@ -87,7 +87,7 @@ static __fi bool mfifoVIF1rbTransfer() else ret = VIF1transfer(src, mfifoqwc << 2); - vif1ch->madr = qwctag(vif1ch->madr); + vif1ch.madr = qwctag(vif1ch.madr); } return ret; @@ -96,25 +96,25 @@ static __fi bool mfifoVIF1rbTransfer() static __fi void mfifo_VIF1chain() { /* Is QWC = 0? if so there is nothing to transfer */ - if ((vif1ch->qwc == 0)) + if ((vif1ch.qwc == 0)) { vif1.inprogress &= ~1; return; } - if (vif1ch->madr >= dmacRegs->rbor.ADDR && - vif1ch->madr <= (dmacRegs->rbor.ADDR + dmacRegs->rbsr.RMSK)) + if (vif1ch.madr >= dmacRegs.rbor.ADDR && + vif1ch.madr <= (dmacRegs.rbor.ADDR + dmacRegs.rbsr.RMSK)) { //Need to exit on mfifo locations, if the madr is matching the madr of spr, we dont have any data left :( - u16 startqwc = vif1ch->qwc; + u16 startqwc = vif1ch.qwc; mfifoVIF1rbTransfer(); - vifqwc -= startqwc - vif1ch->qwc; + vifqwc -= startqwc - vif1ch.qwc; } else { - tDMA_TAG *pMem = dmaGetAddr(vif1ch->madr, !vif1ch->chcr.DIR); + tDMA_TAG *pMem = dmaGetAddr(vif1ch.madr, !vif1ch.chcr.DIR); SPR_LOG("Non-MFIFO Location"); //No need to exit on non-mfifo as it is indirect anyway, so it can be transferring this while spr refills the mfifo @@ -122,9 +122,9 @@ static __fi void mfifo_VIF1chain() if (pMem == NULL) return; if (vif1.vifstalled) - VIF1transfer((u32*)pMem + vif1.irqoffset, vif1ch->qwc * 4 - vif1.irqoffset); + VIF1transfer((u32*)pMem + vif1.irqoffset, vif1ch.qwc * 4 - vif1.irqoffset); else - VIF1transfer((u32*)pMem, vif1ch->qwc << 2); + VIF1transfer((u32*)pMem, vif1ch.qwc << 2); } } @@ -139,23 +139,23 @@ void mfifoVIF1transfer(int qwc) if (qwc > 0) { vifqwc += qwc; - SPR_LOG("Added %x qw to mfifo, total now %x - Vif CHCR %x Stalled %x done %x", qwc, vifqwc, vif1ch->chcr._u32, vif1.vifstalled, vif1.done); + SPR_LOG("Added %x qw to mfifo, total now %x - Vif CHCR %x Stalled %x done %x", qwc, vifqwc, vif1ch.chcr._u32, vif1.vifstalled, vif1.done); if (vif1.inprogress & 0x10) { - if(vif1ch->chcr.STR == true)CPU_INT(DMAC_MFIFO_VIF, 4); + if(vif1ch.chcr.STR == true)CPU_INT(DMAC_MFIFO_VIF, 4); - vif1Regs->stat.FQC = 0x10; // FQC=16 + vif1Regs.stat.FQC = 0x10; // FQC=16 } vif1.inprogress &= ~0x10; return; } - if (vif1ch->qwc == 0 && vifqwc > 0) + if (vif1ch.qwc == 0 && vifqwc > 0) { - ptag = dmaGetAddr(vif1ch->tadr, false); + ptag = dmaGetAddr(vif1ch.tadr, false); - if (vif1ch->chcr.TTE) + if (vif1ch.chcr.TTE) { bool ret; @@ -173,62 +173,62 @@ void mfifoVIF1transfer(int qwc) vif1.irqoffset = 0; - vif1ch->unsafeTransfer(ptag); + vif1ch.unsafeTransfer(ptag); - vif1ch->madr = ptag[1]._u32; + vif1ch.madr = ptag[1]._u32; vifqwc--; SPR_LOG("dmaChain %8.8x_%8.8x size=%d, id=%d, madr=%lx, tadr=%lx mfifo qwc = %x spr0 madr = %x", - ptag[1]._u32, ptag[0]._u32, vif1ch->qwc, ptag->ID, vif1ch->madr, vif1ch->tadr, vifqwc, spr0->madr); + ptag[1]._u32, ptag[0]._u32, vif1ch.qwc, ptag->ID, vif1ch.madr, vif1ch.tadr, vifqwc, spr0ch.madr); switch (ptag->ID) { case TAG_REFE: // Refe - Transfer Packet According to ADDR field - vif1ch->tadr = qwctag(vif1ch->tadr + 16); + vif1ch.tadr = qwctag(vif1ch.tadr + 16); vif1.done = true; //End Transfer break; case TAG_CNT: // CNT - Transfer QWC following the tag. - vif1ch->madr = qwctag(vif1ch->tadr + 16); //Set MADR to QW after Tag - vif1ch->tadr = qwctag(vif1ch->madr + (vif1ch->qwc << 4)); //Set TADR to QW following the data + vif1ch.madr = qwctag(vif1ch.tadr + 16); //Set MADR to QW after Tag + vif1ch.tadr = qwctag(vif1ch.madr + (vif1ch.qwc << 4)); //Set TADR to QW following the data vif1.done = false; break; case TAG_NEXT: // Next - Transfer QWC following tag. TADR = ADDR { - int temp = vif1ch->madr; //Temporarily Store ADDR - vif1ch->madr = qwctag(vif1ch->tadr + 16); //Set MADR to QW following the tag - vif1ch->tadr = temp; //Copy temporarily stored ADDR to Tag - if ((temp & dmacRegs->rbsr.RMSK) != dmacRegs->rbor.ADDR) Console.WriteLn("Next tag = %x outside ring %x size %x", temp, psHu32(DMAC_RBOR), psHu32(DMAC_RBSR)); + int temp = vif1ch.madr; //Temporarily Store ADDR + vif1ch.madr = qwctag(vif1ch.tadr + 16); //Set MADR to QW following the tag + vif1ch.tadr = temp; //Copy temporarily stored ADDR to Tag + if ((temp & dmacRegs.rbsr.RMSK) != dmacRegs.rbor.ADDR) Console.WriteLn("Next tag = %x outside ring %x size %x", temp, psHu32(DMAC_RBOR), psHu32(DMAC_RBSR)); vif1.done = false; break; } case TAG_REF: // Ref - Transfer QWC from ADDR field case TAG_REFS: // Refs - Transfer QWC from ADDR field (Stall Control) - vif1ch->tadr = qwctag(vif1ch->tadr + 16); //Set TADR to next tag + vif1ch.tadr = qwctag(vif1ch.tadr + 16); //Set TADR to next tag vif1.done = false; break; case TAG_END: // End - Transfer QWC following the tag - vif1ch->madr = qwctag(vif1ch->tadr + 16); //Set MADR to data following the tag - vif1ch->tadr = qwctag(vif1ch->madr + (vif1ch->qwc << 4)); //Set TADR to QW following the data + vif1ch.madr = qwctag(vif1ch.tadr + 16); //Set MADR to data following the tag + vif1ch.tadr = qwctag(vif1ch.madr + (vif1ch.qwc << 4)); //Set TADR to QW following the data vif1.done = true; //End Transfer break; } - if (vif1ch->chcr.TIE && ptag->IRQ) + if (vif1ch.chcr.TIE && ptag->IRQ) { VIF_LOG("dmaIrq Set"); vif1.done = true; } - vif1Regs->stat.FQC = min(vif1ch->qwc, (u16)16); + vif1Regs.stat.FQC = min(vif1ch.qwc, (u16)16); vif1.inprogress |= 1; } - SPR_LOG("mfifoVIF1transfer end %x madr %x, tadr %x vifqwc %x", vif1ch->chcr._u32, vif1ch->madr, vif1ch->tadr, vifqwc); + SPR_LOG("mfifoVIF1transfer end %x madr %x, tadr %x vifqwc %x", vif1ch.chcr._u32, vif1ch.madr, vif1ch.tadr, vifqwc); } void vifMFIFOInterrupt() @@ -236,52 +236,52 @@ void vifMFIFOInterrupt() g_vifCycles = 0; VIF_LOG("vif mfifo interrupt"); - if(GSTransferStatus.PTH2 == STOPPED_MODE && gifRegs->stat.APATH == GIF_APATH2) + if(GSTransferStatus.PTH2 == STOPPED_MODE && gifRegs.stat.APATH == GIF_APATH2) { GSTransferStatus.PTH2 = STOPPED_MODE; - if(gifRegs->stat.DIR == 0)gifRegs->stat.OPH = false; - gifRegs->stat.APATH = GIF_APATH_IDLE; - if(gifRegs->stat.P1Q) gsPath1Interrupt(); - /*gifRegs->stat.APATH = GIF_APATH_IDLE; - if(gifRegs->stat.DIR == 0)gifRegs->stat.OPH = false;*/ + if(gifRegs.stat.DIR == 0)gifRegs.stat.OPH = false; + gifRegs.stat.APATH = GIF_APATH_IDLE; + if(gifRegs.stat.P1Q) gsPath1Interrupt(); + /*gifRegs.stat.APATH = GIF_APATH_IDLE; + if(gifRegs.stat.DIR == 0)gifRegs.stat.OPH = false;*/ } if (schedulepath3msk & 0x10) Vif1MskPath3(); - if(vif1ch->chcr.DIR && CheckPath2GIF(DMAC_MFIFO_VIF) == false) return; + if(vif1ch.chcr.DIR && CheckPath2GIF(DMAC_MFIFO_VIF) == false) return; //We need to check the direction, if it is downloading from the GS, we handle that seperately (KH2 for testing) //Simulated GS transfer time done, clear the flags if (vif1.cmd) { - if(vif1.done == true && vif1ch->qwc == 0) vif1Regs->stat.VPS = VPS_WAITING; + if(vif1.done == true && vif1ch.qwc == 0) vif1Regs.stat.VPS = VPS_WAITING; } else { - vif1Regs->stat.VPS = VPS_IDLE; + vif1Regs.stat.VPS = VPS_IDLE; } if (vif1.irq && vif1.tag.size == 0) { - vif1Regs->stat.INT = true; + vif1Regs.stat.INT = true; hwIntcIrq(INTC_VIF1); --vif1.irq; - if (vif1Regs->stat.test(VIF1_STAT_VSS | VIF1_STAT_VIS | VIF1_STAT_VFS)) + if (vif1Regs.stat.test(VIF1_STAT_VSS | VIF1_STAT_VIS | VIF1_STAT_VFS)) { - /*vif1Regs->stat.FQC = 0; // FQC=0 - vif1ch->chcr.STR = false;*/ - if(vif1ch->qwc > 0 || !vif1.done) return; + /*vif1Regs.stat.FQC = 0; // FQC=0 + vif1ch.chcr.STR = false;*/ + if(vif1ch.qwc > 0 || !vif1.done) return; } } - if (vif1.done == false || vif1ch->qwc) + if (vif1.done == false || vif1ch.qwc) { switch(vif1.inprogress & 1) { case 0: //Set up transfer - if (vif1ch->tadr == spr0->madr) + if (vif1ch.tadr == spr0ch.madr) { // Console.WriteLn("Empty 1"); vifqwc = 0; @@ -290,7 +290,7 @@ void vifMFIFOInterrupt() hwDmacIrq(DMAC_MFIFO_EMPTY); vif1.inprogress |= 0x10; } - vif1Regs->stat.FQC = 0; + vif1Regs.stat.FQC = 0; return; } @@ -310,7 +310,7 @@ void vifMFIFOInterrupt() //FF7 Dirge of Cerberus seems to like the mfifo to tell it when it's empty, even if it's ending. //Doesn't seem to care about the vif1 dma interrupting (possibly disabled the interrupt?) - if (vif1ch->tadr == spr0->madr) + if (vif1ch.tadr == spr0ch.madr) { vifqwc = 0; if((vif1.inprogress & 0x10) == 0) @@ -322,9 +322,9 @@ void vifMFIFOInterrupt() vif1.vifstalled = false; vif1.done = 1; g_vifCycles = 0; - vif1ch->chcr.STR = false; + vif1ch.chcr.STR = false; hwDmacIrq(DMAC_VIF1); VIF_LOG("vif mfifo dma end"); - vif1Regs->stat.FQC = 0; + vif1Regs.stat.FQC = 0; } diff --git a/pcsx2/Vif_Codes.cpp b/pcsx2/Vif_Codes.cpp index 6d0d37a783..dff45af4f6 100644 --- a/pcsx2/Vif_Codes.cpp +++ b/pcsx2/Vif_Codes.cpp @@ -39,32 +39,33 @@ static __fi void vifFlush(int idx) { static __fi void vuExecMicro(int idx, u32 addr) { VURegs* VU = nVif[idx].VU; + VIFregisters& vifRegs = VU->GetVifRegs(); int startcycles = 0; //vifFlush(idx); //if(vifX.vifstalled == true) return; - if (VU->vifRegs->itops > (idx ? 0x3ffu : 0xffu)) { - Console.WriteLn("VIF%d ITOP overrun! %x", idx, VU->vifRegs->itops); - VU->vifRegs->itops &= (idx ? 0x3ffu : 0xffu); + if (vifRegs.itops > (idx ? 0x3ffu : 0xffu)) { + Console.WriteLn("VIF%d ITOP overrun! %x", idx, vifRegs.itops); + vifRegs.itops &= (idx ? 0x3ffu : 0xffu); } - VU->vifRegs->itop = VU->vifRegs->itops; + vifRegs.itop = vifRegs.itops; if (idx) { // in case we're handling a VIF1 execMicro, set the top with the tops value - VU->vifRegs->top = VU->vifRegs->tops & 0x3ff; + vifRegs.top = vifRegs.tops & 0x3ff; // is DBF flag set in VIF_STAT? - if (VU->vifRegs->stat.DBF) { + if (vifRegs.stat.DBF) { // it is, so set tops with base, and clear the stat DBF flag - VU->vifRegs->tops = VU->vifRegs->base; - VU->vifRegs->stat.DBF = false; + vifRegs.tops = vifRegs.base; + vifRegs.stat.DBF = false; } else { // it is not, so set tops with base + offset, and set stat DBF flag - VU->vifRegs->tops = VU->vifRegs->base + VU->vifRegs->ofst; - VU->vifRegs->stat.DBF = true; + vifRegs.tops = vifRegs.base + vifRegs.ofst; + vifRegs.stat.DBF = true; } } @@ -84,16 +85,16 @@ u8 schedulepath3msk = 0; void Vif1MskPath3() { - vif1Regs->mskpath3 = schedulepath3msk & 0x1; - GIF_LOG("VIF MSKPATH3 %x gif str %x path3 status %x", vif1Regs->mskpath3, gif->chcr.STR, GSTransferStatus.PTH3); - gifRegs->stat.M3P = vif1Regs->mskpath3; + vif1Regs.mskpath3 = schedulepath3msk & 0x1; + GIF_LOG("VIF MSKPATH3 %x gif str %x path3 status %x", vif1Regs.mskpath3, gifch.chcr.STR, GSTransferStatus.PTH3); + gifRegs.stat.M3P = vif1Regs.mskpath3; - if (!vif1Regs->mskpath3) + if (!vif1Regs.mskpath3) { //if(GSTransferStatus.PTH3 > TRANSFER_MODE && gif->chcr.STR) GSTransferStatus.PTH3 = TRANSFER_MODE; //DevCon.Warning("Mask off"); //if(GSTransferStatus.PTH3 >= PENDINGSTOP_MODE) GSTransferStatus.PTH3 = IDLE_MODE; - if(gifRegs->stat.P3Q) + if(gifRegs.stat.P3Q) { gsInterrupt();//gsInterrupt(); } @@ -109,7 +110,7 @@ void Vif1MskPath3() { vifOp(vifCode_Base) { vif1Only(); - pass1 { vif1Regs->base = vif1Regs->code & 0x3ff; vif1.cmd = 0; } + pass1 { vif1Regs.base = vif1Regs.code & 0x3ff; vif1.cmd = 0; } pass3 { VifCodeLog("Base"); } return 0; } @@ -119,15 +120,15 @@ extern bool SIGNAL_IMR_Pending; template __fi int _vifCode_Direct(int pass, const u8* data, bool isDirectHL) { pass1 { vif1Only(); - int vifImm = (u16)vif1Regs->code; + int vifImm = (u16)vif1Regs.code; vif1.tag.size = vifImm ? (vifImm*4) : (65536*4); vif1.vifstalled = true; - gifRegs->stat.P2Q = true; - if (gifRegs->stat.PSE) // temporarily stop + gifRegs.stat.P2Q = true; + if (gifRegs.stat.PSE) // temporarily stop { Console.WriteLn("Gif dma temp paused? VIF DIRECT"); vif1.GifWaitState = 3; - vif1Regs->stat.VGW = true; + vif1Regs.stat.VGW = true; } //Should cause this to split here to try and time PATH3 right. return 0; @@ -135,18 +136,18 @@ template __fi int _vifCode_Direct(int pass, const u8* data, bool isDire pass2 { vif1Only(); - if (GSTransferStatus.PTH3 < IDLE_MODE || gifRegs->stat.P1Q == true) + if (GSTransferStatus.PTH3 < IDLE_MODE || gifRegs.stat.P1Q == true) { - if(gifRegs->stat.APATH == GIF_APATH2 || ((GSTransferStatus.PTH3 <= IMAGE_MODE && gifRegs->stat.IMT && (vif1.cmd & 0x7f) == 0x50)) && gifRegs->stat.P1Q == false) + if(gifRegs.stat.APATH == GIF_APATH2 || ((GSTransferStatus.PTH3 <= IMAGE_MODE && gifRegs.stat.IMT && (vif1.cmd & 0x7f) == 0x50)) && gifRegs.stat.P1Q == false) { //Do nothing, allow it - vif1Regs->stat.VGW = false; - //if(gifRegs->stat.APATH != GIF_APATH2)DevCon.Warning("Continue DIRECT/HL %x P3 %x APATH %x P1Q %x", vif1.cmd, GSTransferStatus.PTH3, gifRegs->stat.APATH, gifRegs->stat.P1Q); + vif1Regs.stat.VGW = false; + //if(gifRegs.stat.APATH != GIF_APATH2)DevCon.Warning("Continue DIRECT/HL %x P3 %x APATH %x P1Q %x", vif1.cmd, GSTransferStatus.PTH3, gifRegs.stat.APATH, gifRegs.stat.P1Q); } else { - //DevCon.Warning("Stall DIRECT/HL %x P3 %x APATH %x P1Q %x", vif1.cmd, GSTransferStatus.PTH3, gifRegs->stat.APATH, gifRegs->stat.P1Q); - vif1Regs->stat.VGW = true; // PATH3 is in image mode (DIRECTHL), or busy (BOTH no IMT) + //DevCon.Warning("Stall DIRECT/HL %x P3 %x APATH %x P1Q %x", vif1.cmd, GSTransferStatus.PTH3, gifRegs.stat.APATH, gifRegs.stat.P1Q); + vif1Regs.stat.VGW = true; // PATH3 is in image mode (DIRECTHL), or busy (BOTH no IMT) vif1.GifWaitState = 0; vif1.vifstalled = true; return 0; @@ -158,19 +159,19 @@ template __fi int _vifCode_Direct(int pass, const u8* data, bool isDire vif1.vifstalled = true; return 0; } - if (gifRegs->stat.PSE) // temporarily stop + if (gifRegs.stat.PSE) // temporarily stop { Console.WriteLn("Gif dma temp paused? VIF DIRECT"); vif1.GifWaitState = 3; vif1.vifstalled = true; - vif1Regs->stat.VGW = true; + vif1Regs.stat.VGW = true; return 0; } // HACK ATTACK! // we shouldn't be clearing the queue flag here at all. Ideally, the queue statuses // should be checked, handled, and cleared from the EOP check in GIFPath only. --air - gifRegs->stat.clear_flags(GIF_STAT_P2Q); + gifRegs.stat.clear_flags(GIF_STAT_P2Q); uint minSize = aMin(vif1.vifpacketsize, vif1.tag.size); uint ret; @@ -259,12 +260,12 @@ vifOp(vifCode_FlushA) { pass1 { vifFlush(idx); // Gif is already transferring so wait for it. - if (gifRegs->stat.P1Q || GSTransferStatus.PTH3 <= PENDINGSTOP_MODE) { - //DevCon.Warning("VIF FlushA Wait MSK = %x", vif1Regs->mskpath3); + if (gifRegs.stat.P1Q || GSTransferStatus.PTH3 <= PENDINGSTOP_MODE) { + //DevCon.Warning("VIF FlushA Wait MSK = %x", vif1Regs.mskpath3); // //DevCon.WriteLn("FlushA path3 Wait! PTH3 MD %x STR %x", GSTransferStatus.PTH3, gif->chcr.STR); - vif1Regs->stat.VGW = true; + vif1Regs.stat.VGW = true; vifX.GifWaitState = 1; vifX.vifstalled = true; } // else DevCon.WriteLn("FlushA path3 no Wait! PTH3 MD %x STR %x", GSTransferStatus.PTH3, gif->chcr.STR); @@ -284,7 +285,7 @@ vifOp(vifCode_FlushE) { } vifOp(vifCode_ITop) { - pass1 { vifXRegs->itops = vifXRegs->code & 0x3ff; GetVifX.cmd = 0; } + pass1 { vifXRegs.itops = vifXRegs.code & 0x3ff; GetVifX.cmd = 0; } pass3 { VifCodeLog("ITop"); } return 0; } @@ -292,8 +293,8 @@ vifOp(vifCode_ITop) { vifOp(vifCode_Mark) { vifStruct& vifX = GetVifX; pass1 { - vifXRegs->mark = (u16)vifXRegs->code; - vifXRegs->stat.MRK = true; + vifXRegs.mark = (u16)vifXRegs.code; + vifXRegs.stat.MRK = true; vifX.cmd = 0; } pass3 { VifCodeLog("Mark"); } @@ -316,8 +317,8 @@ static __fi void _vifCode_MPG(int idx, u32 addr, const u32 *data, int size) { vifOp(vifCode_MPG) { vifStruct& vifX = GetVifX; pass1 { - int vifNum = (u8)(vifXRegs->code >> 16); - vifX.tag.addr = (u16)(vifXRegs->code << 3) & (idx ? 0x3fff : 0xfff); + int vifNum = (u8)(vifXRegs.code >> 16); + vifX.tag.addr = (u16)(vifXRegs.code << 3) & (idx ? 0x3fff : 0xfff); vifX.tag.size = vifNum ? (vifNum*2) : 512; //vifFlush(idx); return 1; @@ -349,14 +350,14 @@ vifOp(vifCode_MPG) { vifOp(vifCode_MSCAL) { vifStruct& vifX = GetVifX; - pass1 { vifFlush(idx); vuExecMicro(idx, (u16)(vifXRegs->code) << 3); vifX.cmd = 0;} + pass1 { vifFlush(idx); vuExecMicro(idx, (u16)(vifXRegs.code) << 3); vifX.cmd = 0;} pass3 { VifCodeLog("MSCAL"); } return 0; } vifOp(vifCode_MSCALF) { vifStruct& vifX = GetVifX; - pass1 { vifFlush(idx); vuExecMicro(idx, (u16)(vifXRegs->code) << 3); vifX.cmd = 0; } + pass1 { vifFlush(idx); vuExecMicro(idx, (u16)(vifXRegs.code) << 3); vifX.cmd = 0; } pass3 { VifCodeLog("MSCALF"); } return 0; } @@ -372,12 +373,12 @@ vifOp(vifCode_MSCNT) { vifOp(vifCode_MskPath3) { vif1Only(); pass1 { - if (vif1ch->chcr.STR && vif1.lastcmd != 0x13) { - schedulepath3msk = 0x10 | ((vif1Regs->code >> 15) & 0x1); + if (vif1ch.chcr.STR && vif1.lastcmd != 0x13) { + schedulepath3msk = 0x10 | ((vif1Regs.code >> 15) & 0x1); vif1.vifstalled = true; } else { - schedulepath3msk = (vif1Regs->code >> 15) & 0x1; + schedulepath3msk = (vif1Regs.code >> 15) & 0x1; Vif1MskPath3(); } vif1.cmd = 0; @@ -397,9 +398,9 @@ vifOp(vifCode_Null) { vifStruct& vifX = GetVifX; pass1 { // if ME1, then force the vif to interrupt - if (!(vifXRegs->err.ME1)) { // Ignore vifcode and tag mismatch error + if (!(vifXRegs.err.ME1)) { // Ignore vifcode and tag mismatch error Console.WriteLn("Vif%d: Unknown VifCmd! [%x]", idx, vifX.cmd); - vifXRegs->stat.ER1 = true; + vifXRegs.stat.ER1 = true; vifX.vifstalled = true; //vifX.irq++; } @@ -413,9 +414,9 @@ vifOp(vifCode_Null) { vifOp(vifCode_Offset) { vif1Only(); pass1 { - vif1Regs->stat.DBF = false; - vif1Regs->ofst = vif1Regs->code & 0x3ff; - vif1Regs->tops = vif1Regs->base; + vif1Regs.stat.DBF = false; + vif1Regs.ofst = vif1Regs.code & 0x3ff; + vif1Regs.tops = vif1Regs.base; vif1.cmd = 0; } pass3 { VifCodeLog("Offset"); } @@ -462,7 +463,7 @@ vifOp(vifCode_STCol) { } pass2 { u32* cols = idx ? g_vifmask.Col1 : g_vifmask.Col0; - u32* pmem1 = &vifXRegs->c0 + (vifX.tag.addr << 2); + u32* pmem1 = &vifXRegs.c0 + (vifX.tag.addr << 2); u32* pmem2 = cols + vifX.tag.addr; return _vifCode_STColRow(data, pmem1, pmem2); } @@ -480,7 +481,7 @@ vifOp(vifCode_STRow) { } pass2 { u32* rows = idx ? g_vifmask.Row1 : g_vifmask.Row0; - u32* pmem1 = &vifXRegs->r0 + (vifX.tag.addr << 2); + u32* pmem1 = &vifXRegs.r0 + (vifX.tag.addr << 2); u32* pmem2 = rows + vifX.tag.addr; return _vifCode_STColRow(data, pmem1, pmem2); } @@ -491,8 +492,8 @@ vifOp(vifCode_STRow) { vifOp(vifCode_STCycl) { vifStruct& vifX = GetVifX; pass1 { - vifXRegs->cycle.cl = (u8)(vifXRegs->code); - vifXRegs->cycle.wl = (u8)(vifXRegs->code >> 8); + vifXRegs.cycle.cl = (u8)(vifXRegs.code); + vifXRegs.cycle.wl = (u8)(vifXRegs.code >> 8); vifX.cmd = 0; } pass3 { VifCodeLog("STCycl"); } @@ -502,13 +503,13 @@ vifOp(vifCode_STCycl) { vifOp(vifCode_STMask) { vifStruct& vifX = GetVifX; pass1 { vifX.tag.size = 1; } - pass2 { vifXRegs->mask = data[0]; vifX.tag.size = 0; vifX.cmd = 0; } + pass2 { vifXRegs.mask = data[0]; vifX.tag.size = 0; vifX.cmd = 0; } pass3 { VifCodeLog("STMask"); } return 1; } vifOp(vifCode_STMod) { - pass1 { vifXRegs->mode = vifXRegs->code & 0x3; GetVifX.cmd = 0; } + pass1 { vifXRegs.mode = vifXRegs.code & 0x3; GetVifX.cmd = 0; } pass3 { VifCodeLog("STMod"); } return 0; } diff --git a/pcsx2/Vif_Dma.h b/pcsx2/Vif_Dma.h index 2b66f7db7f..402d473d3e 100644 --- a/pcsx2/Vif_Dma.h +++ b/pcsx2/Vif_Dma.h @@ -14,6 +14,8 @@ */ #pragma once + +#include "Vif.h" #include "Vif_Unpack.h" struct vifCode { @@ -84,13 +86,13 @@ extern vifStruct* vif; extern vifStruct vif0, vif1; extern u8 schedulepath3msk; +_vifT extern bool vifWrite32(u32 mem, u32 value); + extern void vif0Interrupt(); -extern void vif0Write32(u32 mem, u32 value); extern void vif0Reset(); extern void vif1Interrupt(); extern void Vif1MskPath3(); -extern void vif1Write32(u32 mem, u32 value); extern void vif1Reset(); typedef int __fastcall FnType_VifCmdHandler(int pass, const u32 *data); diff --git a/pcsx2/Vif_Transfer.cpp b/pcsx2/Vif_Transfer.cpp index 4db328cc4c..d48a00d872 100644 --- a/pcsx2/Vif_Transfer.cpp +++ b/pcsx2/Vif_Transfer.cpp @@ -24,7 +24,7 @@ // Doesn't stall if the next vifCode is the Mark command _vifT bool runMark(u32* &data) { - if (((vifXRegs->code >> 24) & 0x7f) == 0x7) { + if (((vifXRegs.code >> 24) & 0x7f) == 0x7) { Console.WriteLn("Vif%d: Running Mark with I-bit", idx); return 1; // No Stall? } @@ -34,7 +34,7 @@ _vifT bool runMark(u32* &data) { // Returns 1 if i-bit && finished vifcode && i-bit not masked _vifT bool analyzeIbit(u32* &data, int iBit) { vifStruct& vifX = GetVifX; - if (iBit && !vifX.cmd && !vifXRegs->err.MII) { + if (iBit && !vifX.cmd && !vifXRegs.err.MII) { //DevCon.WriteLn("Vif I-Bit IRQ"); vifX.irq++; @@ -75,14 +75,14 @@ _vifT void vifTransferLoop(u32* &data) { u32& pSize = vifX.vifpacketsize; int iBit = vifX.cmd >> 7; - vifXRegs->stat.VPS |= VPS_TRANSFERRING; - vifXRegs->stat.ER1 = false; + vifXRegs.stat.VPS |= VPS_TRANSFERRING; + vifXRegs.stat.ER1 = false; while (pSize > 0 && !vifX.vifstalled) { if(!vifX.cmd) { // Get new VifCode - vifX.lastcmd = (vifXRegs->code >> 24) & 0x7f; - vifXRegs->code = data[0]; + vifX.lastcmd = (vifXRegs.code >> 24) & 0x7f; + vifXRegs.code = data[0]; vifX.cmd = data[0] >> 24; iBit = data[0] >> 31; @@ -135,20 +135,20 @@ _vifT static __fi bool vifTransfer(u32 *data, int size) { transferred = transferred >> 2; - vifXch->madr +=(transferred << 4); - vifXch->qwc -= transferred; + vifXch.madr +=(transferred << 4); + vifXch.qwc -= transferred; - if (!vifXch->qwc && !vifX.irqoffset) vifX.inprogress &= ~0x1; + if (!vifXch.qwc && !vifX.irqoffset) vifX.inprogress &= ~0x1; if (vifX.irq && vifX.cmd == 0) { //DevCon.WriteLn("Vif IRQ!"); - if(((vifXRegs->code >> 24) & 0x7f) != 0x7) + if(((vifXRegs.code >> 24) & 0x7f) != 0x7) { vifX.vifstalled = true; - vifXRegs->stat.VIS = true; // Note: commenting this out fixes WALL-E? + vifXRegs.stat.VIS = true; // Note: commenting this out fixes WALL-E? } - if (!vifXch->qwc && !vifX.irqoffset) vifX.inprogress &= ~1; + if (!vifXch.qwc && !vifX.irqoffset) vifX.inprogress &= ~1; return false; } diff --git a/pcsx2/Vif_Unpack.cpp b/pcsx2/Vif_Unpack.cpp index ba125623c3..c407bc977a 100644 --- a/pcsx2/Vif_Unpack.cpp +++ b/pcsx2/Vif_Unpack.cpp @@ -302,8 +302,8 @@ _vifT void vifUnpackSetup(const u32 *data) { vifStruct& vifX = GetVifX; - if ((vifXRegs->cycle.wl == 0) && (vifXRegs->cycle.wl < vifXRegs->cycle.cl)) { - Console.WriteLn("Vif%d CL %d, WL %d", idx, vifXRegs->cycle.cl, vifXRegs->cycle.wl); + if ((vifXRegs.cycle.wl == 0) && (vifXRegs.cycle.wl < vifXRegs.cycle.cl)) { + Console.WriteLn("Vif%d CL %d, WL %d", idx, vifXRegs.cycle.cl, vifXRegs.cycle.wl); vifX.cmd = 0; return; // Skipping write and 0 write-cycles, so do nothing! } @@ -311,33 +311,33 @@ _vifT void vifUnpackSetup(const u32 *data) { //if (!idx) vif0FLUSH(); // Only VU0? - vifX.usn = (vifXRegs->code >> 14) & 0x01; - int vifNum = (vifXRegs->code >> 16) & 0xff; + vifX.usn = (vifXRegs.code >> 14) & 0x01; + int vifNum = (vifXRegs.code >> 16) & 0xff; if (vifNum == 0) vifNum = 256; - vifXRegs->num = vifNum; + vifXRegs.num = vifNum; - if (vifXRegs->cycle.wl <= vifXRegs->cycle.cl) { + if (vifXRegs.cycle.wl <= vifXRegs.cycle.cl) { if (!idx) vif0.tag.size = ((vifNum * VIFfuncTable[ vif0.cmd & 0xf ].gsize) + 3) >> 2; else vif1.tag.size = ((vifNum * VIFfuncTable[ vif1.cmd & 0xf ].gsize) + 3) >> 2; } else { - int n = vifXRegs->cycle.cl * (vifNum / vifXRegs->cycle.wl) + - _limit(vifNum % vifXRegs->cycle.wl, vifXRegs->cycle.cl); + int n = vifXRegs.cycle.cl * (vifNum / vifXRegs.cycle.wl) + + _limit(vifNum % vifXRegs.cycle.wl, vifXRegs.cycle.cl); if (!idx) vif0.tag.size = ((n * VIFfuncTable[ vif0.cmd & 0xf ].gsize) + 3) >> 2; else vif1.tag.size = ((n * VIFfuncTable[ vif1.cmd & 0xf ].gsize) + 3) >> 2; } - u32 addr = vifXRegs->code; - if (idx && ((addr>>15)&1)) addr += vif1Regs->tops; + u32 addr = vifXRegs.code; + if (idx && ((addr>>15)&1)) addr += vif1Regs.tops; vifX.tag.addr = (addr<<4) & (idx ? 0x3ff0 : 0xff0); VIF_LOG("Unpack VIF%x, QWC %x tagsize %x", idx, vifNum, vif0.tag.size); vifX.cl = 0; vifX.tag.cmd = vifX.cmd; - vifXRegs->offset = 0; + vifXRegs.offset = 0; } template void vifUnpackSetup<0>(const u32 *data); diff --git a/pcsx2/Vif_Unpack.inl b/pcsx2/Vif_Unpack.inl index ed7825c51d..8462e63d73 100644 --- a/pcsx2/Vif_Unpack.inl +++ b/pcsx2/Vif_Unpack.inl @@ -26,12 +26,12 @@ template void VIFunpack(u32 *data, vifCode *v, u32 size) { if (VIFdmanum == 0) { VU = &VU0; - vifRegs = vif0Regs; + vifRegs = &vif0Regs; vif = &vif0; } else { VU = &VU1; - vifRegs = vif1Regs; + vifRegs = &vif1Regs; vif = &vif1; } diff --git a/pcsx2/gui/ConsoleLogger.cpp b/pcsx2/gui/ConsoleLogger.cpp index a3319d8790..2f6457b64f 100644 --- a/pcsx2/gui/ConsoleLogger.cpp +++ b/pcsx2/gui/ConsoleLogger.cpp @@ -993,7 +993,7 @@ void Pcsx2App::ProgramLog_PostEvent( wxEvent& evt ) static void __concall ConsoleToFile_Newline() { #ifdef __LINUX__ - if (g_Conf->EmuOptions.ConsoleToStdio) ConsoleWriter_Stdout.Newline(); + if ((g_Conf) && (g_Conf->EmuOptions.ConsoleToStdio)) ConsoleWriter_Stdout.Newline(); #endif #ifdef __LINUX__ @@ -1006,7 +1006,7 @@ static void __concall ConsoleToFile_Newline() static void __concall ConsoleToFile_DoWrite( const wxString& fmt ) { #ifdef __LINUX__ - if (g_Conf->EmuOptions.ConsoleToStdio) ConsoleWriter_Stdout.WriteRaw(fmt); + if ((g_Conf) && (g_Conf->EmuOptions.ConsoleToStdio)) ConsoleWriter_Stdout.WriteRaw(fmt); #endif px_fputs( emuLog, fmt.ToUTF8() ); diff --git a/pcsx2/ps2/GIFpath.cpp b/pcsx2/ps2/GIFpath.cpp index 4ed7b20866..726cb9811d 100644 --- a/pcsx2/ps2/GIFpath.cpp +++ b/pcsx2/ps2/GIFpath.cpp @@ -358,7 +358,7 @@ static __fi void gsHandler(const u8* pMem) // games must take care to ensure transfer rectangles are exact multiples of a qword vif1.GSLastDownloadSize = vif1.TRXREG.RRW * vif1.TRXREG.RRH * bpp >> 7; //DevCon.Warning("GS download in progress"); - gifRegs->stat.OPH = true; + gifRegs.stat.OPH = true; } } if (reg >= 0x60) @@ -602,7 +602,7 @@ __fi int GIFPath::CopyTag(const u128* pMem128, u32 size) else GSTransferStatus.PTH2 = TRANSFER_MODE; break; case GIF_PATH_3: - if(vif1Regs->mskpath3 == 1 && GSTransferStatus.PTH3 == STOPPED_MODE) + if(vif1Regs.mskpath3 == 1 && GSTransferStatus.PTH3 == STOPPED_MODE) { GSTransferStatus.PTH3 = IDLE_MODE; @@ -618,8 +618,8 @@ __fi int GIFPath::CopyTag(const u128* pMem128, u32 size) } if(GSTransferStatus.PTH3 < PENDINGSTOP_MODE || pathidx != 2) { - gifRegs->stat.OPH = true; - gifRegs->stat.APATH = pathidx + 1; + gifRegs.stat.OPH = true; + gifRegs.stat.APATH = pathidx + 1; } if(pathidx == GIF_PATH_3) @@ -645,8 +645,8 @@ __fi int GIFPath::CopyTag(const u128* pMem128, u32 size) break; } - gifRegs->stat.APATH = pathidx + 1; - gifRegs->stat.OPH = true; + gifRegs.stat.APATH = pathidx + 1; + gifRegs.stat.OPH = true; switch(tag.FLG) { case GIF_FLG_PACKED: @@ -809,10 +809,10 @@ __fi int GIFPath::CopyTag(const u128* pMem128, u32 size) // FINISH is *not* a per-path register, and it seems to pretty clearly indicate that all active // drawing *and* image transfer actions must be finished before the IRQ raises. - if(gifRegs->stat.P1Q || gifRegs->stat.P2Q || gifRegs->stat.P3Q) + if(gifRegs.stat.P1Q || gifRegs.stat.P2Q || gifRegs.stat.P3Q) { //GH3 and possibly others have path data queued waiting for another path to finish! we need to check they are done too - //DevCon.Warning("Early FINISH signal! P1 %x P2 %x P3 %x", gifRegs->stat.P1Q, gifRegs->stat.P2Q, gifRegs->stat.P3Q); + //DevCon.Warning("Early FINISH signal! P1 %x P2 %x P3 %x", gifRegs.stat.P1Q, gifRegs.stat.P2Q, gifRegs.stat.P3Q); } else if (!(GSIMR&0x200) && !s_gifPath.path[0].IsActive() && !s_gifPath.path[1].IsActive() && !s_gifPath.path[2].IsActive()) { @@ -835,8 +835,8 @@ __fi int GIFPath::CopyTag(const u128* pMem128, u32 size) if (tag.EOP && nloop == 0) { - /*if(gifRegs->stat.DIR == 0)gifRegs->stat.OPH = false; - gifRegs->stat.APATH = GIF_APATH_IDLE;*/ + /*if(gifRegs.stat.DIR == 0)gifRegs.stat.OPH = false; + gifRegs.stat.APATH = GIF_APATH_IDLE;*/ switch(pathidx) { case GIF_PATH_1: @@ -849,10 +849,10 @@ __fi int GIFPath::CopyTag(const u128* pMem128, u32 size) //For huge chunks we may have delay problems, so we need to stall it till the interrupt, else we get desync (Lemmings) if(size > 8) GSTransferStatus.PTH3 = PENDINGSTOP_MODE; else GSTransferStatus.PTH3 = STOPPED_MODE; - if (gif->chcr.STR) { //Make sure we are really doing a DMA and not using FIFO + if (gifch.chcr.STR) { //Make sure we are really doing a DMA and not using FIFO //GIF_LOG("Path3 end EOP %x NLOOP %x Status %x", tag.EOP, nloop, GSTransferStatus.PTH3); - gif->madr += size * 16; - gif->qwc -= size; + gifch.madr += size * 16; + gifch.qwc -= size; } break; } @@ -860,10 +860,10 @@ __fi int GIFPath::CopyTag(const u128* pMem128, u32 size) else if(pathidx == 2) { //if(nloop <= 16 && GSTransferStatus.PTH3 == IMAGE_MODE)GSTransferStatus.PTH3 = PENDINGIMAGE_MODE; - if (gif->chcr.STR) { //Make sure we are really doing a DMA and not using FIFO + if (gifch.chcr.STR) { //Make sure we are really doing a DMA and not using FIFO //GIF_LOG("Path3 end EOP %x NLOOP %x Status %x", tag.EOP, nloop, GSTransferStatus.PTH3); - gif->madr += size * 16; - gif->qwc -= size; + gifch.madr += size * 16; + gifch.qwc -= size; } } diff --git a/pcsx2/ps2/HwInternal.h b/pcsx2/ps2/HwInternal.h new file mode 100644 index 0000000000..22ad65e576 --- /dev/null +++ b/pcsx2/ps2/HwInternal.h @@ -0,0 +1,79 @@ +/* PCSX2 - PS2 Emulator for PCs + * Copyright (C) 2002-2010 PCSX2 Dev Team + * + * PCSX2 is free software: you can redistribute it and/or modify it under the terms + * of the GNU Lesser General Public License as published by the Free Software Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with PCSX2. + * If not, see . + */ + +#pragma once + +#include "Hw.h" + +// -------------------------------------------------------------------------------------- +// IsPageFor() / iswitch() / icase() [macros!] +// -------------------------------------------------------------------------------------- +// Page-granulated switch helpers: In order for the compiler to optimize hardware register +// handlers, which dispatch registers along a series of switches, the compiler needs to know +// that the case entry applies to the current page only. Under MSVC, I tried all manners of +// bitmasks against the templated page value, and this was the only one that worked: +// +// Note: MSVC 2008 actually fails to optimize "switch" properly due to being overly aggressive +// about trying to use its clever BSP-tree logic for long switches. It adds the BSP tree logic, +// even though most of the "tree" is empty (resulting in several compare/jumps that do nothing). +// Explained: Even though only one or two of the switch entires are valid, MSVC will still +// compile in its BSP tree check (which divides the switch into 2 or 4 ranges of values). Three +// of the ranges just link to "RET", while the fourth range contains the handler for the one +// register operation contained in the templated page. + +#define IsPageFor(_mem) ((page<<12) == (_mem&(0xf<<12))) +#define icase(ugh) if(IsPageFor(ugh) && (mem==ugh)) +#define iswitch(mem) + +// hw read functions +template< uint page > extern mem8_t __fastcall hwRead8 (u32 mem); +template< uint page > extern mem16_t __fastcall hwRead16 (u32 mem); +template< uint page > extern mem32_t __fastcall hwRead32 (u32 mem); +template< uint page > extern void __fastcall hwRead64 (u32 mem, mem64_t* out ); +template< uint page > extern void __fastcall hwRead128(u32 mem, mem128_t* out); + +// Internal hwRead32 which does not log reads, used by hwWrite8/16 to perform +// read-modify-write operations. +template< uint page, bool intcstathack > +extern mem32_t __fastcall _hwRead32(u32 mem); + +extern mem16_t __fastcall hwRead16_page_0F_INTC_HACK(u32 mem); +extern mem32_t __fastcall hwRead32_page_0F_INTC_HACK(u32 mem); + + +// hw write functions +template extern void __fastcall hwWrite8 (u32 mem, u8 value); +template extern void __fastcall hwWrite16 (u32 mem, u16 value); + +template extern void __fastcall hwWrite32 (u32 mem, mem32_t value); +template extern void __fastcall hwWrite64 (u32 mem, const mem64_t* srcval); +template extern void __fastcall hwWrite128(u32 mem, const mem128_t* srcval); + +// -------------------------------------------------------------------------------------- +// Hardware FIFOs (128 bit access only!) +// -------------------------------------------------------------------------------------- +// VIF0 -- 0x10004000 -- eeHw[0x4000] +// VIF1 -- 0x10005000 -- eeHw[0x5000] +// GIF -- 0x10006000 -- eeHw[0x6000] +// IPUout -- 0x10007000 -- eeHw[0x7000] +// IPUin -- 0x10007010 -- eeHw[0x7010] + +extern void __fastcall ReadFIFO_VIF1(mem128_t* out); +extern void __fastcall ReadFIFO_IPUout(mem128_t* out); + +extern void __fastcall WriteFIFO_VIF0(const mem128_t* value); +extern void __fastcall WriteFIFO_VIF1(const mem128_t* value); +extern void __fastcall WriteFIFO_GIF(const mem128_t* value); +extern void __fastcall WriteFIFO_IPUin(const mem128_t* value); diff --git a/pcsx2/ps2/Iop/IopHwRead.cpp b/pcsx2/ps2/Iop/IopHwRead.cpp index 837defb524..31998d30f4 100644 --- a/pcsx2/ps2/Iop/IopHwRead.cpp +++ b/pcsx2/ps2/Iop/IopHwRead.cpp @@ -51,28 +51,28 @@ mem8_t __fastcall iopHwRead8_Page1( u32 addr ) default: if( masked_addr >= 0x100 && masked_addr < 0x130 ) { - DevCon.Warning( "HwRead8 from Counter16 [ignored], addr 0x%08x = 0x%02x", addr, psxHu8(addr) ); + DevCon.Warning( "HwRead8 from Counter16 [ignored] @ 0x%08x = 0x%02x", addr, psxHu8(addr) ); ret = psxHu8( addr ); } else if( masked_addr >= 0x480 && masked_addr < 0x4a0 ) { - DevCon.Warning( "HwRead8 from Counter32 [ignored], addr 0x%08x = 0x%02x", addr, psxHu8(addr) ); + DevCon.Warning( "HwRead8 from Counter32 [ignored] @ 0x%08x = 0x%02x", addr, psxHu8(addr) ); ret = psxHu8( addr ); } else if( (masked_addr >= pgmsk(HW_USB_START)) && (masked_addr < pgmsk(HW_USB_END)) ) { ret = USBread8( addr ); - PSXHW_LOG( "HwRead8 from USB, addr 0x%08x = 0x%02x", addr, ret ); + PSXHW_LOG( "HwRead8 from USB @ 0x%08x = 0x%02x", addr, ret ); } else { ret = psxHu8(addr); - PSXUnkHW_LOG( "HwRead8 from Unknown, addr 0x%08x = 0x%02x", addr, ret ); + PSXUnkHW_LOG( "HwRead8 from Unknown @ 0x%08x = 0x%02x", addr, ret ); } return ret; } - IopHwTraceLog( addr, ret, "Read" ); + IopHwTraceLog( addr, ret, true ); return ret; } @@ -89,7 +89,7 @@ mem8_t __fastcall iopHwRead8_Page3( u32 addr ) else ret = psxHu8( addr ); - IopHwTraceLog( addr, ret, "Read" ); + IopHwTraceLog( addr, ret, true ); return ret; } @@ -107,7 +107,7 @@ mem8_t __fastcall iopHwRead8_Page8( u32 addr ) else ret = psxHu8( addr ); - IopHwTraceLog( addr, ret, "Read" ); + IopHwTraceLog( addr, ret, true ); return ret; } @@ -216,7 +216,7 @@ static __fi T _HwRead_16or32_Page1( u32 addr ) ret = SPU2read( addr ); else { - DevCon.Warning( "HwRead32 from SPU2? (addr=0x%08X) .. What manner of trickery is this?!", addr ); + DbgCon.Warning( "HwRead32 from SPU2? @ 0x%08X .. What manner of trickery is this?!", addr ); ret = psxHu32(addr); } } @@ -320,7 +320,7 @@ static __fi T _HwRead_16or32_Page1( u32 addr ) } } - IopHwTraceLog( addr, ret, "Read" ); + IopHwTraceLog( addr, ret, true ); return ret; } @@ -343,7 +343,7 @@ mem16_t __fastcall iopHwRead16_Page3( u32 addr ) jASSUME( (addr >> 12) == 0x1f803 ); mem16_t ret = psxHu16(addr); - IopHwTraceLog( addr, ret, "Read" ); + IopHwTraceLog( addr, ret, true ); return ret; } @@ -355,7 +355,7 @@ mem16_t __fastcall iopHwRead16_Page8( u32 addr ) jASSUME( (addr >> 12) == 0x1f808 ); mem16_t ret = psxHu16(addr); - IopHwTraceLog( addr, ret, "Read" ); + IopHwTraceLog( addr, ret, true ); return ret; } @@ -373,7 +373,7 @@ mem32_t __fastcall iopHwRead32_Page3( u32 addr ) // all addresses are assumed to be prefixed with 0x1f803xxx: jASSUME( (addr >> 12) == 0x1f803 ); const mem32_t ret = psxHu32(addr); - IopHwTraceLog( addr, ret, "Read" ); + IopHwTraceLog( addr, ret, true ); return ret; } @@ -437,7 +437,7 @@ mem32_t __fastcall iopHwRead32_Page8( u32 addr ) } else ret = psxHu32(addr); - IopHwTraceLog( addr, ret, "Read" ); + IopHwTraceLog( addr, ret, true ); return ret; } diff --git a/pcsx2/ps2/Iop/IopHwWrite.cpp b/pcsx2/ps2/Iop/IopHwWrite.cpp index d689ae6482..f2264aca43 100644 --- a/pcsx2/ps2/Iop/IopHwWrite.cpp +++ b/pcsx2/ps2/Iop/IopHwWrite.cpp @@ -33,7 +33,7 @@ template< typename T > static __fi void _generic_write( u32 addr, T val ) { //int bitsize = (sizeof(T) == 1) ? 8 : ( (sizeof(T) == 2) ? 16 : 32 ); - IopHwTraceLog( addr, val, "Write" ); + IopHwTraceLog( addr, val, false ); psxHu(addr) = val; } @@ -49,7 +49,7 @@ static __fi T _generic_read( u32 addr ) //int bitsize = (sizeof(T) == 1) ? 8 : ( (sizeof(T) == 2) ? 16 : 32 ); T ret = psxHu(addr); - IopHwTraceLog( addr, ret, "Read" ); + IopHwTraceLog( addr, ret, true ); return ret; } @@ -84,12 +84,12 @@ void __fastcall iopHwWrite8_Page1( u32 addr, mem8_t val ) default: if( masked_addr >= 0x100 && masked_addr < 0x130 ) { - DevCon.Warning( "HwWrite8 to Counter16 [ignored], addr 0x%08x = 0x%02x", addr, psxHu8(addr) ); + DbgCon.Warning( "HwWrite8 to Counter16 [ignored] @ addr 0x%08x = 0x%02x", addr, psxHu8(addr) ); psxHu8( addr ) = val; } else if( masked_addr >= 0x480 && masked_addr < 0x4a0 ) { - DevCon.Warning( "HwWrite8 to Counter32 [ignored], addr 0x%08x = 0x%02x", addr, psxHu8(addr) ); + DbgCon.Warning( "HwWrite8 to Counter32 [ignored] @ addr 0x%08x = 0x%02x", addr, psxHu8(addr) ); psxHu8( addr ) = val; } else if( (masked_addr >= pgmsk(HW_USB_START)) && (masked_addr < pgmsk(HW_USB_END)) ) @@ -103,7 +103,7 @@ void __fastcall iopHwWrite8_Page1( u32 addr, mem8_t val ) break; } - IopHwTraceLog( addr, val, "Write" ); + IopHwTraceLog( addr, val, false ); } void __fastcall iopHwWrite8_Page3( u32 addr, mem8_t val ) @@ -137,7 +137,7 @@ void __fastcall iopHwWrite8_Page3( u32 addr, mem8_t val ) } psxHu8( addr ) = val; - IopHwTraceLog( addr, val, "Write" ); + IopHwTraceLog( addr, val, false ); } void __fastcall iopHwWrite8_Page8( u32 addr, mem8_t val ) @@ -150,7 +150,7 @@ void __fastcall iopHwWrite8_Page8( u32 addr, mem8_t val ) else psxHu8( addr ) = val; - IopHwTraceLog( addr, val, "Write" ); + IopHwTraceLog( addr, val, false ); } ////////////////////////////////////////////////////////////////////////////////////////// @@ -244,7 +244,7 @@ static __fi void _HwWrite_16or32_Page1( u32 addr, T val ) SPU2write( addr, val ); else { - DevCon.Warning( "HwWrite32 to SPU2? (addr=0x%08X) .. What manner of trickery is this?!", addr ); + DbgCon.Warning( "HwWrite32 to SPU2? @ 0x%08X .. What manner of trickery is this?!", addr ); //psxHu(addr) = val; } } @@ -481,7 +481,7 @@ static __fi void _HwWrite_16or32_Page1( u32 addr, T val ) } } - IopHwTraceLog( addr, val, "Write" ); + IopHwTraceLog( addr, val, false ); } @@ -497,7 +497,7 @@ void __fastcall iopHwWrite16_Page3( u32 addr, mem16_t val ) // all addresses are assumed to be prefixed with 0x1f803xxx: pxAssert( (addr >> 12) == 0x1f803 ); psxHu16(addr) = val; - IopHwTraceLog( addr, val, "Write" ); + IopHwTraceLog( addr, val, false ); } void __fastcall iopHwWrite16_Page8( u32 addr, mem16_t val ) @@ -505,7 +505,7 @@ void __fastcall iopHwWrite16_Page8( u32 addr, mem16_t val ) // all addresses are assumed to be prefixed with 0x1f808xxx: pxAssert( (addr >> 12) == 0x1f808 ); psxHu16(addr) = val; - IopHwTraceLog( addr, val, "Write" ); + IopHwTraceLog( addr, val, false ); } ////////////////////////////////////////////////////////////////////////////////////////// @@ -520,7 +520,7 @@ void __fastcall iopHwWrite32_Page3( u32 addr, mem32_t val ) // all addresses are assumed to be prefixed with 0x1f803xxx: pxAssert( (addr >> 12) == 0x1f803 ); psxHu16(addr) = val; - IopHwTraceLog( addr, val, "Write" ); + IopHwTraceLog( addr, val, false ); } void __fastcall iopHwWrite32_Page8( u32 addr, mem32_t val ) @@ -567,7 +567,7 @@ void __fastcall iopHwWrite32_Page8( u32 addr, mem32_t val ) } else psxHu32(addr) = val; - IopHwTraceLog( addr, val, "Write" ); + IopHwTraceLog( addr, val, false ); } } diff --git a/pcsx2/ps2/Iop/IopHw_Internal.h b/pcsx2/ps2/Iop/IopHw_Internal.h index c5340c34f6..a6ced5bb75 100644 --- a/pcsx2/ps2/Iop/IopHw_Internal.h +++ b/pcsx2/ps2/Iop/IopHw_Internal.h @@ -38,7 +38,7 @@ namespace Internal { // template< typename T> -static __ri const char* _log_GetIopHwName( u32 addr, T val ) +static __ri const char* _ioplog_GetHwName( u32 addr, T val ) { switch( addr ) { @@ -200,20 +200,31 @@ static __ri const char* _log_GetIopHwName( u32 addr, T val ) } template< typename T> -static __ri void IopHwTraceLog( u32 addr, T val, const char* modestr ) +static __ri void IopHwTraceLog( u32 addr, T val, bool mode ) { - if( !EmuConfig.Trace.IOP.m_EnableRegisters ) return; + if (!IsDevBuild) return; + if (!EmuConfig.Trace.IOP.m_EnableRegisters) return; - static char *temp = "Hw%s%d from %s, addr 0x%08x = 0x%0*x"; + FastFormatAscii valStr; + FastFormatAscii labelStr; + labelStr.Write("Hw%s%u", mode ? "Read" : "Write", sizeof (T) * 8); - // Replace the * above with the operand size (this ensures nicely formatted - // zero-fill hex values): - temp[(sizeof temp)-3] = '0' + (sizeof(T)*2); + switch( sizeof (T) ) + { + case 1: valStr.Write("0x%02x", val); break; + case 2: valStr.Write("0x%04x", val); break; + case 4: valStr.Write("0x%08x", val); break; - if( const char* regname = _log_GetIopHwName( addr, val ) ) - PSXHW_LOG( temp, modestr, (sizeof (T)) * 8, regname, addr, val ); + case 8: valStr.Write("0x%08x.%08x", ((u32*)&val)[1], ((u32*)&val)[0]); break; + case 16: ((u128&)val).WriteTo(valStr); + } + + static const char* temp = "%-12s @ 0x%08X/%-16s %s %s"; + + if( const char* regname = _ioplog_GetHwName( addr, val ) ) + PSXHW_LOG( temp, labelStr.c_str(), addr, regname, mode ? "->" : "<-", valStr.c_str() ); else - PSXUnkHW_LOG( temp, modestr, (sizeof (T)) * 8, "Unknown", addr, val ); + PSXUnkHW_LOG( temp, labelStr.c_str(), addr, "Unknown", mode ? "->" : "<-", valStr.c_str() ); } } }; diff --git a/pcsx2/ps2/LegacyDmac.cpp b/pcsx2/ps2/LegacyDmac.cpp new file mode 100644 index 0000000000..7e67e49275 --- /dev/null +++ b/pcsx2/ps2/LegacyDmac.cpp @@ -0,0 +1,437 @@ +/* PCSX2 - PS2 Emulator for PCs + * Copyright (C) 2002-2010 PCSX2 Dev Team + * + * PCSX2 is free software: you can redistribute it and/or modify it under the terms + * of the GNU Lesser General Public License as published by the Free Software Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with PCSX2. + * If not, see . + */ + + +#include "PrecompiledHeader.h" +#include "Common.h" +#include "Hardware.h" + +#include "IPU/IPUdma.h" +#include "ps2/HwInternal.h" + +bool DMACh::transfer(const char *s, tDMA_TAG* ptag) +{ + if (ptag == NULL) // Is ptag empty? + { + throwBusError(s); + return false; + } + chcrTransfer(ptag); + + qwcTransfer(ptag); + return true; +} + +void DMACh::unsafeTransfer(tDMA_TAG* ptag) +{ + chcrTransfer(ptag); + qwcTransfer(ptag); +} + +tDMA_TAG *DMACh::getAddr(u32 addr, u32 num, bool write) +{ + tDMA_TAG *ptr = dmaGetAddr(addr, write); + if (ptr == NULL) + { + throwBusError("dmaGetAddr"); + setDmacStat(num); + chcr.STR = false; + } + + return ptr; +} + +tDMA_TAG *DMACh::DMAtransfer(u32 addr, u32 num) +{ + tDMA_TAG *tag = getAddr(addr, num, false); + + if (tag == NULL) return NULL; + + chcrTransfer(tag); + qwcTransfer(tag); + return tag; +} + +tDMA_TAG DMACh::dma_tag() +{ + return chcr.tag(); +} + +wxString DMACh::cmq_to_str() const +{ + return wxsFormat(L"chcr = %lx, madr = %lx, qwc = %lx", chcr._u32, madr, qwc); +} + +wxString DMACh::cmqt_to_str() const +{ + return wxsFormat(L"chcr = %lx, madr = %lx, qwc = %lx, tadr = %1x", chcr._u32, madr, qwc, tadr); +} + +__fi void throwBusError(const char *s) +{ + Console.Error("%s BUSERR", s); + dmacRegs.stat.BEIS = true; +} + +__fi void setDmacStat(u32 num) +{ + dmacRegs.stat.set_flags(1 << num); +} + +// Note: Dma addresses are guaranteed to be aligned to 16 bytes (128 bits) +__fi tDMA_TAG *SPRdmaGetAddr(u32 addr, bool write) +{ + // if (addr & 0xf) { DMA_LOG("*PCSX2*: DMA address not 128bit aligned: %8.8x", addr); } + + //For some reason Getaway references SPR Memory from itself using SPR0, oh well, let it i guess... + if((addr & 0x70000000) == 0x70000000) + { + return (tDMA_TAG*)&eeMem->Scratch[addr & 0x3ff0]; + } + + // FIXME: Why??? DMA uses physical addresses + addr &= 0x1ffffff0; + + if (addr < Ps2MemSize::Base) + { + return (tDMA_TAG*)&eeMem->Main[addr]; + } + else if (addr < 0x10000000) + { + return (tDMA_TAG*)(write ? eeMem->ZeroWrite : eeMem->ZeroRead); + } + else if ((addr >= 0x11004000) && (addr < 0x11010000)) + { + //Access for VU Memory + return (tDMA_TAG*)vtlb_GetPhyPtr(addr & 0x1FFFFFF0); + } + else + { + Console.Error( "*PCSX2*: DMA error: %8.8x", addr); + return NULL; + } +} + +// Note: Dma addresses are guaranteed to be aligned to 16 bytes (128 bits) +__ri tDMA_TAG *dmaGetAddr(u32 addr, bool write) +{ + // if (addr & 0xf) { DMA_LOG("*PCSX2*: DMA address not 128bit aligned: %8.8x", addr); } + if (DMA_TAG(addr).SPR) return (tDMA_TAG*)&eeMem->Scratch[addr & 0x3ff0]; + + // FIXME: Why??? DMA uses physical addresses + addr &= 0x1ffffff0; + + if (addr < Ps2MemSize::Base) + { + return (tDMA_TAG*)&eeMem->Main[addr]; + } + else if (addr < 0x10000000) + { + return (tDMA_TAG*)(write ? eeMem->ZeroWrite : eeMem->ZeroRead); + } + else if (addr < 0x10004000) + { + // Secret scratchpad address for DMA = end of maximum main memory? + //Console.Warning("Writing to the scratchpad without the SPR flag set!"); + return (tDMA_TAG*)&eeMem->Scratch[addr & 0x3ff0]; + } + else + { + Console.Error( "*PCSX2*: DMA error: %8.8x", addr); + return NULL; + } +} + + +// Returns true if the DMA is enabled and executed successfully. Returns false if execution +// was blocked (DMAE or master DMA enabler). +static bool QuickDmaExec( void (*func)(), u32 mem) +{ + bool ret = false; + DMACh& reg = (DMACh&)psHu32(mem); + + if (reg.chcr.STR && dmacRegs.ctrl.DMAE && !psHu8(DMAC_ENABLER+2)) + { + func(); + ret = true; + } + + return ret; +} + + +static tDMAC_QUEUE QueuedDMA(0); +static u32 oldvalue = 0; + +static void StartQueuedDMA() +{ + if (QueuedDMA.VIF0) { DMA_LOG("Resuming DMA for VIF0"); QueuedDMA.VIF0 = !QuickDmaExec(dmaVIF0, D0_CHCR); } + if (QueuedDMA.VIF1) { DMA_LOG("Resuming DMA for VIF1"); QueuedDMA.VIF1 = !QuickDmaExec(dmaVIF1, D1_CHCR); } + if (QueuedDMA.GIF ) { DMA_LOG("Resuming DMA for GIF" ); QueuedDMA.GIF = !QuickDmaExec(dmaGIF , D2_CHCR); } + if (QueuedDMA.IPU0) { DMA_LOG("Resuming DMA for IPU0"); QueuedDMA.IPU0 = !QuickDmaExec(dmaIPU0, D3_CHCR); } + if (QueuedDMA.IPU1) { DMA_LOG("Resuming DMA for IPU1"); QueuedDMA.IPU1 = !QuickDmaExec(dmaIPU1, D4_CHCR); } + if (QueuedDMA.SIF0) { DMA_LOG("Resuming DMA for SIF0"); QueuedDMA.SIF0 = !QuickDmaExec(dmaSIF0, D5_CHCR); } + if (QueuedDMA.SIF1) { DMA_LOG("Resuming DMA for SIF1"); QueuedDMA.SIF1 = !QuickDmaExec(dmaSIF1, D6_CHCR); } + if (QueuedDMA.SIF2) { DMA_LOG("Resuming DMA for SIF2"); QueuedDMA.SIF2 = !QuickDmaExec(dmaSIF2, D7_CHCR); } + if (QueuedDMA.SPR0) { DMA_LOG("Resuming DMA for SPR0"); QueuedDMA.SPR0 = !QuickDmaExec(dmaSPR0, D8_CHCR); } + if (QueuedDMA.SPR1) { DMA_LOG("Resuming DMA for SPR1"); QueuedDMA.SPR1 = !QuickDmaExec(dmaSPR1, D9_CHCR); } +} + +static __ri void DmaExec( void (*func)(), u32 mem, u32 value ) +{ + DMACh& reg = (DMACh&)psHu32(mem); + tDMA_CHCR chcr(value); + + //It's invalid for the hardware to write a DMA while it is active, not without Suspending the DMAC + if (reg.chcr.STR) + { + const uint channel = ChannelNumber(mem); + + if(psHu8(DMAC_ENABLER+2) == 1) //DMA is suspended so we can allow writes to anything + { + //If it stops the DMA, we need to clear any pending interrupts so the DMA doesnt continue. + if(chcr.STR == 0) + { + //DevCon.Warning(L"32bit %s DMA Stopped on Suspend", ChcrName(mem)); + if(channel == 1) + { + cpuClearInt( 10 ); + QueuedDMA._u16 &= ~(1 << 10); //Clear any queued DMA requests for this channel + } + else if(channel == 2) + { + cpuClearInt( 11 ); + QueuedDMA._u16 &= ~(1 << 11); //Clear any queued DMA requests for this channel + } + + cpuClearInt( channel ); + QueuedDMA._u16 &= ~(1 << channel); //Clear any queued DMA requests for this channel + } + //Sanity Check for possible future bug fix0rs ;p + //Spams on Persona 4 opening. + //if(reg.chcr.TAG != chcr.TAG) DevCon.Warning(L"32bit CHCR Tag on %s changed to %x from %x QWC = %x Channel Active", ChcrName(mem), chcr.TAG, reg.chcr.TAG, reg.qwc); + //Here we update the LOWER CHCR, if a chain is stopped half way through, it can be manipulated in to a different mode + //But we need to preserve the existing tag for now + reg.chcr.set((reg.chcr.TAG << 16) | chcr.lower()); + return; + } + else //Else the DMA is running (Not Suspended), so we cant touch it! + { + //As the manual states "Fields other than STR can only be written to when the DMA is stopped" + //Also "The DMA may not stop properly just by writing 0 to STR" + //So the presumption is that STR can be written to (ala force stop the DMA) but nothing else + + if(chcr.STR == 0) + { + //DevCon.Warning(L"32bit Force Stopping %s (Current CHCR %x) while DMA active", ChcrName(mem), reg.chcr._u32, chcr._u32); + reg.chcr.STR = 0; + //We need to clear any existing DMA loops that are in progress else they will continue! + + if(channel == 1) + { + cpuClearInt( 10 ); + QueuedDMA._u16 &= ~(1 << 10); //Clear any queued DMA requests for this channel + } + else if(channel == 2) + { + cpuClearInt( 11 ); + QueuedDMA._u16 &= ~(1 << 11); //Clear any queued DMA requests for this channel + } + + cpuClearInt( channel ); + QueuedDMA._u16 &= ~(1 << channel); //Clear any queued DMA requests for this channel + } + //else DevCon.Warning(L"32bit Attempted to change %s CHCR (Currently %x) with %x while DMA active, ignoring QWC = %x", ChcrName(mem), reg.chcr._u32, chcr._u32, reg.qwc); + return; + } + + } + + //if(reg.chcr.TAG != chcr.TAG && chcr.MOD == CHAIN_MODE) DevCon.Warning(L"32bit CHCR Tag on %s changed to %x from %x QWC = %x Channel Not Active", ChcrName(mem), chcr.TAG, reg.chcr.TAG, reg.qwc); + + reg.chcr.set(value); + + if (reg.chcr.STR && dmacRegs.ctrl.DMAE && !psHu8(DMAC_ENABLER+2)) + { + func(); + } + else if(reg.chcr.STR) + { + //DevCon.Warning(L"32bit %s DMA Start while DMAC Disabled\n", ChcrName(mem)); + QueuedDMA._u16 |= (1 << ChannelNumber(mem)); //Queue the DMA up to be started then the DMA's are Enabled and or the Suspend is lifted + } //else QueuedDMA._u16 &~= (1 << ChannelNumber(mem)); // +} + +template< uint page > +__fi u32 dmacRead32( u32 mem ) +{ + // Fixme: OPH hack. Toggle the flag on each GIF_STAT access. (rama) + if (IsPageFor(mem) && (mem == GIF_STAT) && CHECK_OPHFLAGHACK) + { + gifRegs.stat.OPH = !gifRegs.stat.OPH; + } + + return psHu32(mem); +} + +// Returns TRUE if the caller should do writeback of the register to eeHw; false if the +// register has no writeback, or if the writeback is handled internally. +template< uint page > +__fi bool dmacWrite32( u32 mem, mem32_t& value ) +{ + iswitch(mem) { + icase(D0_CHCR) // dma0 - vif0 + { + DMA_LOG("VIF0dma EXECUTE, value=0x%x", value); + DmaExec(dmaVIF0, mem, value); + return false; + } + + icase(D1_CHCR) // dma1 - vif1 - chcr + { + DMA_LOG("VIF1dma EXECUTE, value=0x%x", value); + DmaExec(dmaVIF1, mem, value); + return false; + } + + icase(D2_CHCR) // dma2 - gif + { + DMA_LOG("GIFdma EXECUTE, value=0x%x", value); + DmaExec(dmaGIF, mem, value); + return false; + } + + icase(D3_CHCR) // dma3 - fromIPU + { + DMA_LOG("IPU0dma EXECUTE, value=0x%x\n", value); + DmaExec(dmaIPU0, mem, value); + return false; + } + + icase(D4_CHCR) // dma4 - toIPU + { + DMA_LOG("IPU1dma EXECUTE, value=0x%x\n", value); + DmaExec(dmaIPU1, mem, value); + return false; + } + + icase(D5_CHCR) // dma5 - sif0 + { + DMA_LOG("SIF0dma EXECUTE, value=0x%x", value); + DmaExec(dmaSIF0, mem, value); + return false; + } + + icase(D6_CHCR) // dma6 - sif1 + { + DMA_LOG("SIF1dma EXECUTE, value=0x%x", value); + DmaExec(dmaSIF1, mem, value); + return false; + } + + icase(D7_CHCR) // dma7 - sif2 + { + DMA_LOG("SIF2dma EXECUTE, value=0x%x", value); + DmaExec(dmaSIF2, mem, value); + return false; + } + + icase(D8_CHCR) // dma8 - fromSPR + { + DMA_LOG("SPR0dma EXECUTE (fromSPR), value=0x%x", value); + DmaExec(dmaSPR0, mem, value); + return false; + } + + icase(D9_CHCR) // dma9 - toSPR + { + DMA_LOG("SPR1dma EXECUTE (toSPR), value=0x%x", value); + DmaExec(dmaSPR1, mem, value); + return false; + } + + icase(DMAC_CTRL) + { + u32 oldvalue = psHu32(mem); + + HW_LOG("DMAC_CTRL Write 32bit %x", value); + + psHu32(mem) = value; + //Check for DMAS that were started while the DMAC was disabled + if (((oldvalue & 0x1) == 0) && ((value & 0x1) == 1)) + { + if (!QueuedDMA.empty()) StartQueuedDMA(); + } + if ((oldvalue & 0x30) != (value & 0x30)) + { + DevCon.Warning("32bit Stall Source Changed to %x", (value & 0x30) >> 4); + } + if ((oldvalue & 0xC0) != (value & 0xC0)) + { + DevCon.Warning("32bit Stall Destination Changed to %x", (value & 0xC0) >> 4); + } + return false; + } + + icase(DMAC_STAT) + { + HW_LOG("DMAC_STAT Write 32bit %x", value); + + // lower 16 bits: clear on 1 + // upper 16 bits: reverse on 1 + + psHu16(0xe010) &= ~(value & 0xffff); + psHu16(0xe012) ^= (u16)(value >> 16); + + cpuTestDMACInts(); + return false; + } + + icase(DMAC_ENABLEW) + { + HW_LOG("DMAC_ENABLEW Write 32bit %lx", value); + oldvalue = psHu8(DMAC_ENABLEW + 2); + psHu32(DMAC_ENABLEW) = value; + psHu32(DMAC_ENABLER) = value; + if (((oldvalue & 0x1) == 1) && (((value >> 16) & 0x1) == 0)) + { + if (!QueuedDMA.empty()) StartQueuedDMA(); + } + return false; + } + } + + // fall-through: use the default writeback provided by caller. + return true; +} + +template u32 dmacRead32<0x03>( u32 mem ); + +template bool dmacWrite32<0x00>( u32 mem, mem32_t& value ); +template bool dmacWrite32<0x01>( u32 mem, mem32_t& value ); +template bool dmacWrite32<0x02>( u32 mem, mem32_t& value ); +template bool dmacWrite32<0x03>( u32 mem, mem32_t& value ); +template bool dmacWrite32<0x04>( u32 mem, mem32_t& value ); +template bool dmacWrite32<0x05>( u32 mem, mem32_t& value ); +template bool dmacWrite32<0x06>( u32 mem, mem32_t& value ); +template bool dmacWrite32<0x07>( u32 mem, mem32_t& value ); +template bool dmacWrite32<0x08>( u32 mem, mem32_t& value ); +template bool dmacWrite32<0x09>( u32 mem, mem32_t& value ); +template bool dmacWrite32<0x0a>( u32 mem, mem32_t& value ); +template bool dmacWrite32<0x0b>( u32 mem, mem32_t& value ); +template bool dmacWrite32<0x0c>( u32 mem, mem32_t& value ); +template bool dmacWrite32<0x0d>( u32 mem, mem32_t& value ); +template bool dmacWrite32<0x0e>( u32 mem, mem32_t& value ); +template bool dmacWrite32<0x0f>( u32 mem, mem32_t& value ); diff --git a/pcsx2/ps2/eeHwTraceLog.inl b/pcsx2/ps2/eeHwTraceLog.inl new file mode 100644 index 0000000000..388d40378a --- /dev/null +++ b/pcsx2/ps2/eeHwTraceLog.inl @@ -0,0 +1,268 @@ +/* PCSX2 - PS2 Emulator for PCs + * Copyright (C) 2002-2010 PCSX2 Dev Team + * + * PCSX2 is free software: you can redistribute it and/or modify it under the terms + * of the GNU Lesser General Public License as published by the Free Software Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with PCSX2. + * If not, see . + */ + +#pragma once + +template< typename T> +static __ri const char* _eelog_GetHwName( u32 addr, T val ) +{ +#define EasyCase(label) case label: return #label + + switch( addr ) + { + // Counters! + EasyCase(RCNT0_COUNT); + EasyCase(RCNT0_MODE); + EasyCase(RCNT0_TARGET); + EasyCase(RCNT0_HOLD); + + EasyCase(RCNT1_COUNT); + EasyCase(RCNT1_MODE); + EasyCase(RCNT1_TARGET); + EasyCase(RCNT1_HOLD); + + EasyCase(RCNT2_COUNT); + EasyCase(RCNT2_MODE); + EasyCase(RCNT2_TARGET); + + EasyCase(RCNT3_COUNT); + EasyCase(RCNT3_MODE); + EasyCase(RCNT3_TARGET); + + // IPU! + EasyCase(IPU_CMD); + EasyCase(IPU_CTRL); + EasyCase(IPU_BP); + EasyCase(IPU_TOP); + + // GIF! + EasyCase(GIF_CTRL); + EasyCase(GIF_MODE); + EasyCase(GIF_STAT); + EasyCase(GIF_TAG0); + EasyCase(GIF_TAG1); + EasyCase(GIF_TAG2); + EasyCase(GIF_TAG3); + EasyCase(GIF_CNT); + EasyCase(GIF_P3CNT); + EasyCase(GIF_P3TAG); + + // VIF! + EasyCase(VIF0_STAT); + EasyCase(VIF0_FBRST); + EasyCase(VIF0_ERR); + EasyCase(VIF0_MARK); + EasyCase(VIF0_CYCLE); + EasyCase(VIF0_MODE); + EasyCase(VIF0_NUM); + EasyCase(VIF0_MASK); + EasyCase(VIF0_CODE); + EasyCase(VIF0_ITOPS); + EasyCase(VIF0_ITOP); + EasyCase(VIF0_TOP); + EasyCase(VIF0_ROW0); + EasyCase(VIF0_ROW1); + EasyCase(VIF0_ROW2); + EasyCase(VIF0_ROW3); + EasyCase(VIF0_COL0); + EasyCase(VIF0_COL1); + EasyCase(VIF0_COL2); + EasyCase(VIF0_COL3); + + EasyCase(VIF1_STAT); + EasyCase(VIF1_FBRST); + EasyCase(VIF1_ERR); + EasyCase(VIF1_MARK); + EasyCase(VIF1_CYCLE); + EasyCase(VIF1_MODE); + EasyCase(VIF1_NUM); + EasyCase(VIF1_MASK); + EasyCase(VIF1_CODE); + EasyCase(VIF1_ITOPS); + EasyCase(VIF1_BASE); + EasyCase(VIF1_OFST); + EasyCase(VIF1_TOPS); + EasyCase(VIF1_ITOP); + EasyCase(VIF1_TOP); + EasyCase(VIF1_ROW0); + EasyCase(VIF1_ROW1); + EasyCase(VIF1_ROW2); + EasyCase(VIF1_ROW3); + EasyCase(VIF1_COL0); + EasyCase(VIF1_COL1); + EasyCase(VIF1_COL2); + EasyCase(VIF1_COL3); + + // VIF DMA! + EasyCase(VIF0_CHCR); + EasyCase(VIF0_MADR); + EasyCase(VIF0_QWC); + EasyCase(VIF0_TADR); + EasyCase(VIF0_ASR0); + EasyCase(VIF0_ASR1); + + EasyCase(VIF1_CHCR); + EasyCase(VIF1_QWC); + EasyCase(VIF1_TADR); + EasyCase(VIF1_ASR0); + EasyCase(VIF1_ASR1); + + // GIF DMA! + EasyCase(GIF_CHCR); + EasyCase(GIF_MADR); + EasyCase(GIF_QWC); + EasyCase(GIF_TADR); + EasyCase(GIF_ASR0); + EasyCase(GIF_ASR1); + + // IPU DMA! + EasyCase(fromIPU_CHCR); + EasyCase(fromIPU_MADR); + EasyCase(fromIPU_QWC); + EasyCase(fromIPU_TADR); + + EasyCase(toIPU_CHCR); + EasyCase(toIPU_MADR); + EasyCase(toIPU_QWC); + EasyCase(toIPU_TADR); + + // SIF DMA! + EasyCase(SIF0_CHCR); + EasyCase(SIF0_MADR); + EasyCase(SIF0_QWC); + + EasyCase(SIF1_CHCR); + EasyCase(SIF1_MADR); + EasyCase(SIF1_QWC); + + EasyCase(SIF2_CHCR); + EasyCase(SIF2_MADR); + EasyCase(SIF2_QWC); + + // Scratchpad DMA! (SPRdma) + + EasyCase(fromSPR_CHCR); + EasyCase(fromSPR_MADR); + EasyCase(fromSPR_QWC); + + EasyCase(toSPR_CHCR); + EasyCase(toSPR_MADR); + EasyCase(toSPR_QWC); + + // DMAC! + EasyCase(DMAC_CTRL); + EasyCase(DMAC_STAT); + EasyCase(DMAC_PCR); + EasyCase(DMAC_SQWC); + EasyCase(DMAC_RBSR); + EasyCase(DMAC_RBOR); + EasyCase(DMAC_STADR); + EasyCase(DMAC_ENABLER); + EasyCase(DMAC_ENABLEW); + + // INTC! + EasyCase(INTC_STAT); + EasyCase(INTC_MASK); + + // SIO + EasyCase(SIO_LCR); + EasyCase(SIO_LSR); + EasyCase(SIO_IER); + EasyCase(SIO_ISR); + EasyCase(SIO_FCR); + EasyCase(SIO_BGR); + EasyCase(SIO_TXFIFO); + EasyCase(SIO_RXFIFO); + + // SBUS (terribly mysterious!) + EasyCase(SBUS_F200); + EasyCase(SBUS_F210); + EasyCase(SBUS_F220); + EasyCase(SBUS_F230); + EasyCase(SBUS_F240); + EasyCase(SBUS_F250); + EasyCase(SBUS_F260); + + // MCH (vaguely mysterious!) + EasyCase(MCH_RICM); + EasyCase(MCH_DRD); + } + +#define EasyZone(zone) \ + if ((addr >= EEMemoryMap::zone##_Start) && (addr < EEMemoryMap::zone##_End)) return #zone + +#define EasyZoneR(zone) \ + EasyZone(zone) "_reserved" + + // Nothing discovered/handled : Check for "zoned" registers -- registers mirrored + // across large sections of memory (FIFOs mainly). + + EasyZone(VIF0_FIFO); EasyZone(VIF1_FIFO); EasyZone(GIF_FIFO); + + if( (addr >= EEMemoryMap::IPU_FIFO_Start) && (addr < EEMemoryMap::IPU_FIFO_End) ) + { + return (addr & 0x10) ? "IPUin_FIFO" : "IPUout_FIFO"; + } + + // Check for "reserved" regions -- registers that most likely discard writes and + // return 0 when read. To assist in having useful logs, we determine the general + // "zone" of the register address and return the zone name in the unknown string. + + EasyZoneR(RCNT0); EasyZoneR(RCNT1); + EasyZoneR(RCNT2); EasyZoneR(RCNT3); + + EasyZoneR(IPU); EasyZoneR(GIF); + EasyZoneR(VIF0); EasyZoneR(VIF1); + EasyZoneR(VIF0dma); EasyZoneR(VIF1dma); + EasyZoneR(GIFdma); EasyZoneR(fromIPU); EasyZoneR(toIPU); + EasyZoneR(SIF0dma); EasyZoneR(SIF1dma); EasyZoneR(SIF2dma); + EasyZoneR(fromSPR); EasyZoneR(toSPR); + + EasyZoneR(DMAC); EasyZoneR(INTC); + EasyZoneR(SIO); EasyZoneR(SBUS); + EasyZoneR(MCH); EasyZoneR(DMACext); + + // If we get this far it's an *unknown* register; plain and simple. + + return NULL; //"Unknown"; +} + +template< typename T> +static __ri void eeHwTraceLog( u32 addr, T val, bool mode ) +{ + if (!IsDevBuild) return; + if (!EmuConfig.Trace.EE.m_EnableRegisters) return; + + FastFormatAscii valStr; + FastFormatAscii labelStr; + labelStr.Write("Hw%s%u", mode ? "Read" : "Write", sizeof (T) * 8); + + switch( sizeof(T) ) + { + case 1: valStr.Write("0x%02x", val); break; + case 2: valStr.Write("0x%04x", val); break; + case 4: valStr.Write("0x%08x", val); break; + + case 8: valStr.Write("0x%08x.%08x", ((u32*)&val)[1], ((u32*)&val)[0]); break; + case 16: ((u128&)val).WriteTo(valStr); + } + + static const char* temp = "%-12s @ 0x%08X/%-16s %s %s"; + + if( const char* regname = _eelog_GetHwName( addr, val ) ) + HW_LOG( temp, labelStr.c_str(), addr, regname, mode ? "->" : "<-", valStr.c_str() ); + else + UnknownHW_LOG( temp, labelStr.c_str(), addr, "Unknown", mode ? "->" : "<-", valStr.c_str() ); +} \ No newline at end of file diff --git a/pcsx2/vtlb.cpp b/pcsx2/vtlb.cpp index 7d87bd4f9e..b0beb6783c 100644 --- a/pcsx2/vtlb.cpp +++ b/pcsx2/vtlb.cpp @@ -126,10 +126,6 @@ void __fastcall vtlb_memRead128(u32 mem, mem128_t *out) ((vtlbMemR128FP*)vtlbdata.RWFT[4][0][hand])(paddr, out); } } -void __fastcall vtlb_memRead128(u32 mem, u64 (&out)[2]) -{ - vtlb_memRead128(mem, (mem128_t*)out); -} template< typename DataType > void __fastcall vtlb_memWrite(u32 addr, DataType data) @@ -159,6 +155,7 @@ void __fastcall vtlb_memWrite(u32 addr, DataType data) } } } + void __fastcall vtlb_memWrite64(u32 mem, const mem64_t* value) { u32 vmv=vtlbdata.vmap[mem>>VTLB_PAGE_BITS]; @@ -197,11 +194,6 @@ void __fastcall vtlb_memWrite128(u32 mem, const mem128_t *value) } } -void __fastcall vtlb_memWrite128(u32 mem, const u64 (&out)[2]) -{ - vtlb_memWrite128(mem, (const mem128_t*)out); -} - template mem8_t vtlb_memRead(u32 mem); template mem16_t vtlb_memRead(u32 mem); template mem32_t vtlb_memRead(u32 mem); diff --git a/pcsx2/vtlb.h b/pcsx2/vtlb.h index 7957ac466f..5b048a384e 100644 --- a/pcsx2/vtlb.h +++ b/pcsx2/vtlb.h @@ -71,13 +71,11 @@ template< typename DataType > extern DataType __fastcall vtlb_memRead(u32 mem); extern void __fastcall vtlb_memRead64(u32 mem, mem64_t *out); extern void __fastcall vtlb_memRead128(u32 mem, mem128_t *out); -extern void __fastcall vtlb_memRead128(u32 mem, u64 (&out)[2]); template< typename DataType > extern void __fastcall vtlb_memWrite(u32 mem, DataType value); extern void __fastcall vtlb_memWrite64(u32 mem, const mem64_t* value); extern void __fastcall vtlb_memWrite128(u32 mem, const mem128_t* value); -extern void __fastcall vtlb_memWrite128(u32 mem, const u64 (&value)[2]); extern void vtlb_DynGenWrite(u32 sz); extern void vtlb_DynGenRead32(u32 bits, bool sign); diff --git a/pcsx2/windows/VCprojects/IopSif.cpp b/pcsx2/windows/VCprojects/IopSif.cpp index cb81f5860b..5085bd4cbe 100644 --- a/pcsx2/windows/VCprojects/IopSif.cpp +++ b/pcsx2/windows/VCprojects/IopSif.cpp @@ -33,14 +33,14 @@ s32 PrepareEERead() "\n\tread tag: %x %x %x %x", hw_dma(9).madr, hw_dma(9).tadr, sif0.iop.counter, sif0words, sif0data, tag[0], tag[1], tag[2], tag[3]); - sif0dma->unsafeTransfer(((tDMA_TAG*)(tag))); - sif0dma->madr = tag[1]; + sif0dma.unsafeTransfer(((tDMA_TAG*)(tag))); + sif0dma.madr = tag[1]; tDMA_TAG ptag(tag[0]); SIF_LOG("SIF0 EE dest chain tag madr:%08X qwc:%04X id:%X irq:%d(%08X_%08X)", - sif0dma->madr, sif0dma->qwc, ptag.ID, ptag.IRQ, tag[1], tag[0]); + sif0dma.madr, sif0dma.qwc, ptag.ID, ptag.IRQ, tag[1], tag[0]); - if (sif0dma->chcr.TIE && ptag.IRQ) + if (sif0dma.chcr.TIE && ptag.IRQ) { //Console.WriteLn("SIF0 TIE"); sif0.ee.end = true; @@ -50,13 +50,13 @@ s32 PrepareEERead() { case TAG_REFE: sif0.ee.end = true; - if (dmacRegs->ctrl.STS != NO_STS) - dmacRegs->stadr.ADDR = sif0dma->madr + (sif0dma->qwc * 16); + if (dmacRegs.ctrl.STS != NO_STS) + dmacRegs.stadr.ADDR = sif0dma.madr + (sif0dma.qwc * 16); break; case TAG_REFS: - if (dmacRegs->ctrl.STS != NO_STS) - dmacRegs->stadr.ADDR = sif0dma->madr + (sif0dma->qwc * 16); + if (dmacRegs.ctrl.STS != NO_STS) + dmacRegs.stadr.ADDR = sif0dma.madr + (sif0dma.qwc * 16); break; case TAG_END: @@ -91,7 +91,7 @@ s32 DoSifRead(u32 iopAvailable) SIF_LOG("Write IOP to EE: +++++++++++ %lX of %lX", transferSizeWords, sif0.iop.counter); - tDMA_TAG *ptag = sif0dma->getAddr(sif0dma->madr, DMAC_SIF0, true); + tDMA_TAG *ptag = sif0dma.getAddr(sif0dma.madr, DMAC_SIF0, true); if (ptag == NULL) { DevCon.Warning("Write IOP to EE: ptag == NULL"); @@ -101,11 +101,11 @@ s32 DoSifRead(u32 iopAvailable) memcpy((u32*)ptag, (u32*)iopPhysMem(hw_dma(9).madr), transferSizeBytes); // Clearing handled by vtlb memory protection and manual blocks. - //Cpu->Clear(sif0dma->madr, readSize*4); + //Cpu->Clear(sif0dma.madr, readSize*4); - sif0dma->madr += transferSizeBytes; + sif0dma.madr += transferSizeBytes; sif0.ee.cycles += transferSizeQWords * 2; - sif0dma->qwc -= transferSizeQWords; + sif0dma.qwc -= transferSizeQWords; return transferSizeBytes; } diff --git a/pcsx2/windows/VCprojects/pcsx2_2008.vcproj b/pcsx2/windows/VCprojects/pcsx2_2008.vcproj index f76dc73072..d9c30caaa3 100644 --- a/pcsx2/windows/VCprojects/pcsx2_2008.vcproj +++ b/pcsx2/windows/VCprojects/pcsx2_2008.vcproj @@ -513,6 +513,10 @@ RelativePath="..\..\Dmac.h" > + + @@ -529,6 +533,10 @@ RelativePath="..\..\Hw.h" > + + @@ -749,6 +757,10 @@ + + @@ -1318,6 +1330,14 @@ RelativePath="..\..\Ipu\IPU_Fifo.h" > + + + + diff --git a/pcsx2/x86/iR3000A.cpp b/pcsx2/x86/iR3000A.cpp index b6daf75a70..1c3644f2b8 100644 --- a/pcsx2/x86/iR3000A.cpp +++ b/pcsx2/x86/iR3000A.cpp @@ -670,7 +670,7 @@ void psxRecompileCodeConst1(R3000AFNPTR constcode, R3000AFNPTR_INFO noconstcode) const char *funcname = irxImportFuncname(libname, index); irxDEBUG debug = irxImportDebug(libname, index); - if (SysTrace.IOP.Bios.IsActive()) { + if (SysTraceActive(IOP.Bios)) { xMOV(ecx, (uptr)libname); xMOV(edx, index); xPUSH((uptr)funcname); diff --git a/pcsx2/x86/ix86-32/iR5900Move.cpp b/pcsx2/x86/ix86-32/iR5900Move.cpp index 62878d5d52..c63fe1ee36 100644 --- a/pcsx2/x86/ix86-32/iR5900Move.cpp +++ b/pcsx2/x86/ix86-32/iR5900Move.cpp @@ -21,11 +21,6 @@ #include "iR5900.h" -#ifdef _WIN32 -//#pragma warning(disable:4244) -//#pragma warning(disable:4761) -#endif - namespace R5900 { namespace Dynarec { namespace OpcodeImpl diff --git a/pcsx2/x86/microVU.cpp b/pcsx2/x86/microVU.cpp index 65724dd6a4..97b4fc3e68 100644 --- a/pcsx2/x86/microVU.cpp +++ b/pcsx2/x86/microVU.cpp @@ -19,6 +19,21 @@ #include "Common.h" #include "microVU.h" +// Include all the *.inl files (Needed because C++ sucks with templates and *.cpp files) +#include "microVU_Clamp.inl" +#include "microVU_Misc.inl" +#include "microVU_Log.inl" +#include "microVU_Analyze.inl" +#include "microVU_Alloc.inl" +#include "microVU_Upper.inl" +#include "microVU_Lower.inl" +#include "microVU_Tables.inl" +#include "microVU_Flags.inl" +#include "microVU_Branch.inl" +#include "microVU_Compile.inl" +#include "microVU_Execute.inl" +#include "microVU_Macro.inl" + //------------------------------------------------------------------ // Micro VU - Global Variables //------------------------------------------------------------------ @@ -70,107 +85,93 @@ static __fi void mVUthrowHardwareDeficiency(const wxChar* extFail, int vuIndex) } // Only run this once per VU! ;) -static __ri void mVUinit(int vuIndex) { +void microVU::init(uint vuIndex) { if(!x86caps.hasMultimediaExtensions) mVUthrowHardwareDeficiency( L"MMX", vuIndex ); if(!x86caps.hasStreamingSIMDExtensions) mVUthrowHardwareDeficiency( L"SSE", vuIndex ); if(!x86caps.hasStreamingSIMD2Extensions) mVUthrowHardwareDeficiency( L"SSE2", vuIndex ); - microVU* mVU = mVUx; - memzero(mVU->prog); + memzero(prog); - mVU->index = vuIndex; - mVU->cop2 = 0; - mVU->vuMemSize = (vuIndex ? 0x4000 : 0x1000); - mVU->microMemSize = (vuIndex ? 0x4000 : 0x1000); - mVU->progSize = (vuIndex ? 0x4000 : 0x1000) / 4; - mVU->progMemMask = mVU->progSize-1; - mVU->dispCache = NULL; - mVU->cache = NULL; - mVU->cacheSize = mVUcacheSize; - mVU->regAlloc = new microRegAlloc(); + index = vuIndex; + cop2 = 0; + vuMemSize = (index ? 0x4000 : 0x1000); + microMemSize = (index ? 0x4000 : 0x1000); + progSize = (index ? 0x4000 : 0x1000) / 4; + progMemMask = progSize-1; + dispCache = NULL; + cache = NULL; + cacheSize = mVUcacheSize; + regAlloc = new microRegAlloc(index); - for (u32 i = 0; i < (mVU->progSize / 2); i++) { - mVU->prog.prog[i] = new deque(); + for (u32 i = 0; i < (progSize / 2); i++) { + prog.prog[i] = new deque(); } - mVU->dispCache = SysMmapEx(0, mVUdispCacheSize, 0, (mVU->index ? "Micro VU1 Dispatcher" : "Micro VU0 Dispatcher")); - if (!mVU->dispCache) throw Exception::OutOfMemory( mVU->index ? L"Micro VU1 Dispatcher" : L"Micro VU0 Dispatcher" ); - memset(mVU->dispCache, 0xcc, mVUdispCacheSize); + dispCache = SysMmapEx(0, mVUdispCacheSize, 0, (index ? "Micro VU1 Dispatcher" : "Micro VU0 Dispatcher")); + if (!dispCache) throw Exception::OutOfMemory( index ? L"Micro VU1 Dispatcher" : L"Micro VU0 Dispatcher" ); + memset(dispCache, 0xcc, mVUdispCacheSize); // Allocates rec-cache and calls mVUreset() - mVUresizeCache(mVU, mVU->cacheSize + mVUcacheSafeZone); + mVUresizeCache(this, cacheSize + mVUcacheSafeZone); //if (vuIndex) gen_memcpy_vibes(); } // Resets Rec Data -// If vuRegsPtr is NUL, the current regs pointer assigned to the VU compiler is assumed. -static __fi void mVUreset(mV, VURegs* vuRegsPtr) { +void microVU::reset() { - static bool dispatchersGenerated = false; - - if (!vuRegsPtr) vuRegsPtr = mVU->regs; - if (!dispatchersGenerated || (mVU->regs != vuRegsPtr)) - { - // Setup Entrance/Exit Points - // These must be rebuilt whenever the vuRegsPtr has changed. - - dispatchersGenerated = true; - mVU->regs = vuRegsPtr; - - x86SetPtr(mVU->dispCache); - mVUdispatcherA(mVU); - mVUdispatcherB(mVU); - mVUemitSearch(); - } + x86SetPtr(dispCache); + mVUdispatcherA(this); + mVUdispatcherB(this); + mVUemitSearch(); // Clear All Program Data - //memset(&mVU->prog, 0, sizeof(mVU->prog)); - memset(&mVU->prog.lpState, 0, sizeof(mVU->prog.lpState)); - + //memset(&prog, 0, sizeof(prog)); + memset(&prog.lpState, 0, sizeof(prog.lpState)); + if (IsDevBuild) { // Release builds shouldn't need this - memset(mVU->cache, 0xcc, mVU->cacheSize); + memset(cache, 0xcc, cacheSize); } // Program Variables - mVU->prog.cleared = 1; - mVU->prog.isSame = -1; - mVU->prog.cur = NULL; - mVU->prog.total = 0; - mVU->prog.curFrame = 0; + prog.cleared = 1; + prog.isSame = -1; + prog.cur = NULL; + prog.total = 0; + prog.curFrame = 0; // Setup Dynarec Cache Limits for Each Program - u8* z = mVU->cache; - mVU->prog.x86start = z; - mVU->prog.x86ptr = z; - mVU->prog.x86end = (u8*)((uptr)z + (uptr)(mVU->cacheSize - mVUcacheSafeZone)); // "Safe Zone" + u8* z = cache; + prog.x86start = z; + prog.x86ptr = z; + prog.x86end = (u8*)((uptr)z + (uptr)(cacheSize - mVUcacheSafeZone)); // "Safe Zone" - for (u32 i = 0; i < (mVU->progSize / 2); i++) { - deque::iterator it(mVU->prog.prog[i]->begin()); - for ( ; it != mVU->prog.prog[i]->end(); ++it) { - if (!isVU1) mVUdeleteProg<0>(it[0]); - else mVUdeleteProg<1>(it[0]); + for (u32 i = 0; i < (progSize / 2); i++) { + deque::iterator it(prog.prog[i]->begin()); + for ( ; it != prog.prog[i]->end(); ++it) { + if (index) mVUdeleteProg<1>(it[0]); + else mVUdeleteProg<0>(it[0]); } - mVU->prog.prog[i]->clear(); - mVU->prog.quick[i].block = NULL; - mVU->prog.quick[i].prog = NULL; + prog.prog[i]->clear(); + prog.quick[i].block = NULL; + prog.quick[i].prog = NULL; } } // Free Allocated Resources -static __fi void mVUclose(mV) { +void microVU::close() { - if (mVU->dispCache) { HostSys::Munmap(mVU->dispCache, mVUdispCacheSize); mVU->dispCache = NULL; } - if (mVU->cache) { HostSys::Munmap(mVU->cache, mVU->cacheSize); mVU->cache = NULL; } + if (dispCache) { HostSys::Munmap(dispCache, mVUdispCacheSize); dispCache = NULL; } + if (cache) { HostSys::Munmap(cache, cacheSize); cache = NULL; } // Delete Programs and Block Managers - for (u32 i = 0; i < (mVU->progSize / 2); i++) { - deque::iterator it(mVU->prog.prog[i]->begin()); - for ( ; it != mVU->prog.prog[i]->end(); ++it) { - if (!isVU1) mVUdeleteProg<0>(it[0]); - else mVUdeleteProg<1>(it[0]); + for (u32 i = 0; i < (progSize / 2); i++) { + deque::iterator it(prog.prog[i]->begin()); + for ( ; it != prog.prog[i]->end(); ++it) { + if (index) mVUdeleteProg<1>(it[0]); + else mVUdeleteProg<0>(it[0]); } - safe_delete(mVU->prog.prog[i]); + safe_delete(prog.prog[i]); } } @@ -181,7 +182,7 @@ static void mVUresizeCache(mV, u32 size) { // We can't grow the rec any larger, so just reset it and start over. //(if we don't reset, the rec will eventually crash) Console.WriteLn(Color_Magenta, "microVU%d: Cannot grow cache, size limit reached! [%dmb]. Resetting rec.", mVU->index, mVU->cacheSize/_1mb); - mVUreset(mVU); + mVU->reset(); return; } size = mVUcacheMaxSize; @@ -191,7 +192,7 @@ static void mVUresizeCache(mV, u32 size) { u8* cache = SysMmapEx(0, size, 0, (mVU->index ? "Micro VU1 RecCache" : "Micro VU0 RecCache")); if(!cache && !mVU->cache) throw Exception::OutOfMemory( wxsFormat( L"Micro VU%d recompiled code cache", mVU->index) ); - if(!cache) { Console.Error("microVU%d Error - Cache Resize Failed...", mVU->index); mVUreset(mVU); return; } + if(!cache) { Console.Error("microVU%d Error - Cache Resize Failed...", mVU->index); mVU->reset(); return; } if (mVU->cache) { HostSys::Munmap(mVU->cache, mVU->cacheSize); ProfilerTerminateSource(isVU1?"mVU1 Rec":"mVU0 Rec"); @@ -200,7 +201,7 @@ static void mVUresizeCache(mV, u32 size) { mVU->cache = cache; mVU->cacheSize = size; ProfilerRegisterSource(isVU1?"mVU1 Rec":"mVU0 Rec", mVU->cache, mVU->cacheSize); - mVUreset(mVU); + mVU->reset(); } // Clears Block Data in specified range @@ -254,8 +255,8 @@ _mVUt __fi microProgram* mVUcreateProg(int startPC) { // Caches Micro Program _mVUt __fi void mVUcacheProg(microProgram& prog) { microVU* mVU = mVUx; - if (!vuIndex) memcpy_const(prog.data, mVU->regs->Micro, 0x1000); - else memcpy_const(prog.data, mVU->regs->Micro, 0x4000); + if (!vuIndex) memcpy_const(prog.data, mVU->regs().Micro, 0x1000); + else memcpy_const(prog.data, mVU->regs().Micro, 0x4000); mVUdumpProg(prog); } @@ -265,17 +266,17 @@ _mVUt __fi bool mVUcmpPartial(microProgram& prog) { deque::const_iterator it(prog.ranges->begin()); for ( ; it != prog.ranges->end(); ++it) { if((it[0].start<0)||(it[0].end<0)) { DevCon.Error("microVU%d: Negative Range![%d][%d]", mVU->index, it[0].start, it[0].end); } - if (memcmp_mmx(cmpOffset(prog.data), cmpOffset(mVU->regs->Micro), ((it[0].end + 8) - it[0].start))) { + if (memcmp_mmx(cmpOffset(prog.data), cmpOffset(mVU->regs().Micro), ((it[0].end + 8) - it[0].start))) { return 0; } } return 1; } -// Compare Cached microProgram to mVU->regs->Micro +// Compare Cached microProgram to mVU->regs().Micro _mVUt __fi bool mVUcmpProg(microProgram& prog, const bool cmpWholeProg) { microVU* mVU = mVUx; - if ((cmpWholeProg && !memcmp_mmx((u8*)prog.data, mVU->regs->Micro, mVU->microMemSize)) + if ((cmpWholeProg && !memcmp_mmx((u8*)prog.data, mVU->regs().Micro, mVU->microMemSize)) || (!cmpWholeProg && mVUcmpPartial(prog))) { mVU->prog.cleared = 0; mVU->prog.cur = &prog; @@ -334,14 +335,14 @@ void recMicroVU0::Allocate() { if(!m_AllocCount) { m_AllocCount++; if (AtomicExchange(mvu0_allocated, 1) == 0) - mVUinit(0); + microVU0.init(0); } } void recMicroVU1::Allocate() { if(!m_AllocCount) { m_AllocCount++; if (AtomicExchange(mvu1_allocated, 1) == 0) - mVUinit(1); + microVU1.init(1); } } @@ -349,24 +350,24 @@ void recMicroVU0::Shutdown() throw() { if (m_AllocCount > 0) { m_AllocCount--; if (AtomicExchange(mvu0_allocated, 0) == 1) - mVUclose(µVU0); + microVU0.close(); } } void recMicroVU1::Shutdown() throw() { if (m_AllocCount > 0) { m_AllocCount--; if (AtomicExchange(mvu1_allocated, 0) == 1) - mVUclose(µVU1); + microVU1.close(); } } void recMicroVU0::Reset() { if(!pxAssertDev(m_AllocCount, "MicroVU0 CPU Provider has not been allocated prior to reset!")) return; - mVUreset(µVU0, &VU0); + microVU0.reset(); } void recMicroVU1::Reset() { if(!pxAssertDev(m_AllocCount, "MicroVU1 CPU Provider has not been allocated prior to reset!")) return; - mVUreset(µVU1, &VU1); + microVU1.reset(); } void recMicroVU0::Execute(u32 cycles) { diff --git a/pcsx2/x86/microVU.h b/pcsx2/x86/microVU.h index adfa722ea6..df113ce718 100644 --- a/pcsx2/x86/microVU.h +++ b/pcsx2/x86/microVU.h @@ -33,86 +33,82 @@ using namespace x86Emitter; #include "microVU_IR.h" struct microBlockLink { - microBlock* block; + microBlock block; microBlockLink* next; }; class microBlockManager { private: - microBlockLink blockList; + microBlockLink* blockList; microBlockLink* blockEnd; int listI; public: microBlockManager() { - listI = -1; - blockList.block = NULL; - blockList.next = NULL; - blockEnd = &blockList; + listI = 0; + blockEnd = blockList = NULL; } ~microBlockManager() { reset(); } void reset() { - if (listI >= 0) { - microBlockLink* linkI = &blockList; - microBlockLink* linkD = NULL; - for (int i = 0; i <= listI; i++) { - safe_aligned_free(linkI->block); - linkI = linkI->next; - safe_delete(linkD); - linkD = linkI; - } - safe_delete(linkI); + microBlockLink* linkI = blockList; + while( linkI != NULL ) + { + microBlockLink* freeI = linkI; + linkI = linkI->next; + _aligned_free(freeI); } - listI = -1; - blockEnd = &blockList; + listI = 0; + blockEnd = blockList = NULL; }; microBlock* add(microBlock* pBlock) { microBlock* thisBlock = search(&pBlock->pState); if (!thisBlock) { listI++; - blockEnd->block = (microBlock*)_aligned_malloc(sizeof(microBlock), 16); - blockEnd->next = new microBlockLink; - memcpy_const(blockEnd->block, pBlock, sizeof(microBlock)); - thisBlock = blockEnd->block; - blockEnd = blockEnd->next; + microBlockLink* newBlock = (microBlockLink*)_aligned_malloc(sizeof(microBlockLink), 16); + newBlock->next = NULL; + + if (blockEnd) { + blockEnd->next = newBlock; + blockEnd = newBlock; + } + else { + blockEnd = blockList = newBlock; + } + + memcpy_const(&newBlock->block, pBlock, sizeof(microBlock)); + thisBlock = &newBlock->block; } return thisBlock; } __ri microBlock* search(microRegInfo* pState) { - microBlockLink* linkI = &blockList; if (pState->needExactMatch) { // Needs Detailed Search (Exact Match of Pipeline State) - for (int i = 0; i <= listI; i++) { - if (mVUquickSearch((void*)pState, (void*)&linkI->block->pState, sizeof(microRegInfo))) return linkI->block; - linkI = linkI->next; + for (microBlockLink* linkI = blockList; linkI != NULL; linkI = linkI->next) { + if (mVUquickSearch((void*)pState, (void*)&linkI->block.pState, sizeof(microRegInfo))) + return &linkI->block; } } else { // Can do Simple Search (Only Matches the Important Pipeline Stuff) - for (int i = 0; i <= listI; i++) { - if ((linkI->block->pState.q == pState->q) - && (linkI->block->pState.p == pState->p) - && ((linkI->block->pState.vi15 == pState->vi15) || !CHECK_VU_CONSTPROP) - && (linkI->block->pState.flags == pState->flags) - && (linkI->block->pState.xgkick == pState->xgkick) - && (linkI->block->pState.viBackUp == pState->viBackUp) - && (linkI->block->pState.blockType == pState->blockType) - && !(linkI->block->pState.needExactMatch & 7)) { return linkI->block; } - linkI = linkI->next; + for (microBlockLink* linkI = blockList; linkI != NULL; linkI = linkI->next) { + if (doConstProp && (linkI->block.pState.vi15 != pState->vi15)) continue; + if (linkI->block.pState.quick32[0] != pState->quick32[0]) continue; + if (linkI->block.pState.quick32[1] != pState->quick32[1]) continue; + return &linkI->block; } } return NULL; } void printInfo(int pc) { if (listI < 7) return; - microBlockLink* linkI = &blockList; + microBlockLink* linkI = blockList; for (int i = 0; i <= listI; i++) { u32 viCRC = 0, vfCRC = 0, crc = 0, z = sizeof(microRegInfo)/4; - for (u32 j = 0; j < 4; j++) viCRC -= ((u32*)linkI->block->pState.VI)[j]; - for (u32 j = 0; j < 32; j++) vfCRC -= linkI->block->pState.VF[j].reg; - for (u32 j = 0; j < z; j++) crc -= ((u32*)&linkI->block->pState)[j]; + for (u32 j = 0; j < 4; j++) viCRC -= ((u32*)linkI->block.pState.VI)[j]; + for (u32 j = 0; j < 32; j++) vfCRC -= linkI->block.pState.VF[j].reg; + for (u32 j = 0; j < z; j++) crc -= ((u32*)&linkI->block.pState)[j]; DevCon.WriteLn(Color_Green, "[%04x][Block #%d][crc=%08x][q=%02d][p=%02d][xgkick=%d][vi15=%08x][viBackup=%02d]" - "[flags=%02x][exactMatch=%x][blockType=%d][viCRC=%08x][vfCRC=%08x]", pc, i, crc, linkI->block->pState.q, - linkI->block->pState.p, linkI->block->pState.xgkick, linkI->block->pState.vi15, linkI->block->pState.viBackUp, - linkI->block->pState.flags, linkI->block->pState.needExactMatch, linkI->block->pState.blockType, viCRC, vfCRC); + "[flags=%02x][exactMatch=%x][blockType=%d][viCRC=%08x][vfCRC=%08x]", pc, i, crc, linkI->block.pState.q, + linkI->block.pState.p, linkI->block.pState.xgkick, linkI->block.pState.vi15, linkI->block.pState.viBackUp, + linkI->block.pState.flags, linkI->block.pState.needExactMatch, linkI->block.pState.blockType, viCRC, vfCRC); linkI = linkI->next; } } @@ -145,7 +141,7 @@ struct microProgManager { microProgramQuick quick[mProgSize/2]; // Quick reference to valid microPrograms for current execution microProgram* cur; // Pointer to currently running MicroProgram int total; // Total Number of valid MicroPrograms - int isSame; // Current cached microProgram is Exact Same program as mVU->regs->Micro (-1 = unknown, 0 = No, 1 = Yes) + int isSame; // Current cached microProgram is Exact Same program as mVU->regs().Micro (-1 = unknown, 0 = No, 1 = Yes) int cleared; // Micro Program is Indeterminate so must be searched for (and if no matches are found then recompile a new one) u32 curFrame; // Frame Counter u8* x86ptr; // Pointer to program's recompilation code @@ -155,17 +151,17 @@ struct microProgManager { }; #define mVUdispCacheSize (0x1000) // Dispatcher Cache Size -#define mVUcacheSize ((mVU->index) ? (_1mb * 17) : (_1mb * 7)) // Initial Size (Excluding Safe-Zone) +#define mVUcacheSize ((index) ? (_1mb * 17) : (_1mb * 7)) // Initial Size (Excluding Safe-Zone) #define mVUcacheMaxSize ((mVU->index) ? (_1mb * 100) : (_1mb * 50)) // Max Size allowed to grow to #define mVUcacheGrowBy ((mVU->index) ? (_1mb * 15) : (_1mb * 10)) // Grows by this amount -#define mVUcacheSafeZone ((mVU->index) ? (_1mb * 3) : (_1mb * 3)) // Safe-Zone for last program +#define mVUcacheSafeZone ((index) ? (_1mb * 3) : (_1mb * 3)) // Safe-Zone for last program struct microVU { - __aligned16 u32 macFlag[4]; // 4 instances of mac flag (used in execution) - __aligned16 u32 clipFlag[4]; // 4 instances of clip flag (used in execution) - __aligned16 u32 xmmPQb[4]; // Backup for xmmPQ - __aligned16 u32 xmmCTemp[4]; // Backup used in mVUclamp2() + __aligned16 u32 macFlag[4]; // 4 instances of mac flag (used in execution) + __aligned16 u32 clipFlag[4]; // 4 instances of clip flag (used in execution) + __aligned16 u32 xmmCTemp[4]; // Backup used in mVUclamp2() + __aligned16 u32 xmmBackup[8][4]; // Backup for xmm0~xmm7 u32 index; // VU Index (VU0 or VU1) u32 cop2; // VU is in COP2 mode? (No/Yes) @@ -179,7 +175,6 @@ struct microVU { ScopedPtr regAlloc; // Reg Alloc Class ScopedPtr logFile; // Log File Pointer - VURegs* regs; // VU Regs Struct u8* cache; // Dynarec Cache Start (where we will start writing the recompiled code to) u8* dispCache; // Dispatchers Cache (where startFunct and exitFunct are written to) u8* startFunct; // Ptr Function to the Start code for recompiled programs @@ -196,6 +191,13 @@ struct microVU { u32 totalCycles; // Total Cycles that mVU is expected to run for u32 cycles; // Cycles Counter + VURegs& regs() const { return ::vuRegs[index]; } + + VIFregisters& getVifRegs() const { return regs().GetVifRegs(); } + __fi REG_VI& getVI(uint reg) const { return regs().VI[reg]; } + __fi VECTOR& getVF(uint reg) const { return regs().VF[reg]; } + + __fi s16 Imm5() const { return ((code & 0x400) ? 0xfff0 : 0) | ((code >> 6) & 0xf); } __fi s32 Imm11() const { return (code & 0x400) ? (0xfffffc00 | (code & 0x3ff)) : (code & 0x3ff); } __fi u32 Imm12() const { return (((code >> 21) & 0x1) << 11) | (code & 0x7ff); } @@ -208,7 +210,7 @@ struct microVU { { prog.IRinfo.curPC += x; prog.IRinfo.curPC &= progMemMask; - code = ((u32*)regs->Micro)[prog.IRinfo.curPC]; + code = ((u32*)regs().Micro)[prog.IRinfo.curPC]; } __ri uint getBranchAddr() const @@ -222,6 +224,10 @@ struct microVU { pxAssumeDev((prog.IRinfo.curPC & 1) == 0, "microVU recompiler: Upper instructions cannot have valid branch addresses."); return (((prog.IRinfo.curPC + 4) + (Imm11() * 2)) & progMemMask) * 4; } + + void init(uint vuIndex); + void reset(); + void close(); }; // microVU rec structs @@ -232,9 +238,6 @@ extern __aligned16 microVU microVU1; int mVUdebugNow = 0; // Main Functions -static void mVUinit(int); -static void mVUreset(mV, VURegs* vuRegsPtr = NULL); -static void mVUclose(mV); static void mVUclear(mV, u32, u32); static void mVUresizeCache(mV, u32); static void* mVUblockFetch(microVU* mVU, u32 startPC, uptr pState); @@ -257,18 +260,3 @@ extern void* __fastcall mVUexecuteVU1(u32 startPC, u32 cycles); // recCall Function Pointer typedef void (__fastcall *mVUrecCall)(u32, u32); - -// Include all the *.inl files (Needed because C++ sucks with templates and *.cpp files) -#include "microVU_Clamp.inl" -#include "microVU_Misc.inl" -#include "microVU_Log.inl" -#include "microVU_Analyze.inl" -#include "microVU_Alloc.inl" -#include "microVU_Upper.inl" -#include "microVU_Lower.inl" -#include "microVU_Tables.inl" -#include "microVU_Flags.inl" -#include "microVU_Branch.inl" -#include "microVU_Compile.inl" -#include "microVU_Execute.inl" -#include "microVU_Macro.inl" diff --git a/pcsx2/x86/microVU_Alloc.inl b/pcsx2/x86/microVU_Alloc.inl index 7f01b560e5..8acab8f704 100644 --- a/pcsx2/x86/microVU_Alloc.inl +++ b/pcsx2/x86/microVU_Alloc.inl @@ -110,19 +110,19 @@ __fi void mVUallocMFLAGb(mV, const x32& reg, int fInstance) { //xAND(reg, 0xffff); if (fInstance < 4) xMOV(ptr32[&mVU->macFlag[fInstance]], reg); // microVU - else xMOV(ptr32[&mVU->regs->VI[REG_MAC_FLAG].UL], reg); // macroVU + else xMOV(ptr32[&mVU->regs().VI[REG_MAC_FLAG].UL], reg); // macroVU } __fi void mVUallocCFLAGa(mV, const x32& reg, int fInstance) { if (fInstance < 4) xMOV(reg, ptr32[&mVU->clipFlag[fInstance]]); // microVU - else xMOV(reg, ptr32[&mVU->regs->VI[REG_CLIP_FLAG].UL]); // macroVU + else xMOV(reg, ptr32[&mVU->regs().VI[REG_CLIP_FLAG].UL]); // macroVU } __fi void mVUallocCFLAGb(mV, const x32& reg, int fInstance) { if (fInstance < 4) xMOV(ptr32[&mVU->clipFlag[fInstance]], reg); // microVU - else xMOV(ptr32[&mVU->regs->VI[REG_CLIP_FLAG].UL], reg); // macroVU + else xMOV(ptr32[&mVU->regs().VI[REG_CLIP_FLAG].UL], reg); // macroVU } //------------------------------------------------------------------ @@ -135,19 +135,19 @@ __ri void mVUallocVIa(mV, const x32& GPRreg, int _reg_, bool signext = false) xXOR(GPRreg, GPRreg); else if (signext) - xMOVSX(GPRreg, ptr16[&mVU->regs->VI[_reg_].SL]); + xMOVSX(GPRreg, ptr16[&mVU->regs().VI[_reg_].SL]); else - xMOVZX(GPRreg, ptr16[&mVU->regs->VI[_reg_].UL]); + xMOVZX(GPRreg, ptr16[&mVU->regs().VI[_reg_].UL]); } __ri void mVUallocVIb(mV, const x32& GPRreg, int _reg_) { if (mVUlow.backupVI) { // Backs up reg to memory (used when VI is modified b4 a branch) - xMOVZX(gprT3, ptr16[&mVU->regs->VI[_reg_].UL]); + xMOVZX(gprT3, ptr16[&mVU->regs().VI[_reg_].UL]); xMOV (ptr32[&mVU->VIbackup], gprT3); } if (_reg_ == 0) { return; } - else if (_reg_ < 16) { xMOV(ptr16[&mVU->regs->VI[_reg_].UL], xRegister16(GPRreg.Id)); } + else if (_reg_ < 16) { xMOV(ptr16[&mVU->regs().VI[_reg_].UL], xRegister16(GPRreg.Id)); } } //------------------------------------------------------------------ diff --git a/pcsx2/x86/microVU_Analyze.inl b/pcsx2/x86/microVU_Analyze.inl index 0bc65f3931..1e4f8c6301 100644 --- a/pcsx2/x86/microVU_Analyze.inl +++ b/pcsx2/x86/microVU_Analyze.inl @@ -470,7 +470,7 @@ __fi void mVUanalyzeNormBranch(mV, int It, bool isBAL) { __ri void mVUanalyzeJump(mV, int Is, int It, bool isJALR) { mVUbranchCheck(mVU); mVUlow.branch = (isJALR) ? 10 : 9; - if (mVUconstReg[Is].isValid && CHECK_VU_CONSTPROP) { + if (mVUconstReg[Is].isValid && doConstProp) { mVUlow.constJump.isValid = 1; mVUlow.constJump.regValue = mVUconstReg[Is].regValue; //DevCon.Status("microVU%d: Constant JR/JALR Address Optimization", mVU->index); diff --git a/pcsx2/x86/microVU_Branch.inl b/pcsx2/x86/microVU_Branch.inl index ba0d8b6eb7..ad33e339cb 100644 --- a/pcsx2/x86/microVU_Branch.inl +++ b/pcsx2/x86/microVU_Branch.inl @@ -56,31 +56,31 @@ void mVUendProgram(mV, microFlagCycles* mFC, int isEbit) { // Save P/Q Regs if (qInst) { xPSHUF.D(xmmPQ, xmmPQ, 0xe5); } - xMOVSS(ptr32[&mVU->regs->VI[REG_Q].UL], xmmPQ); + xMOVSS(ptr32[&mVU->regs().VI[REG_Q].UL], xmmPQ); if (isVU1) { xPSHUF.D(xmmPQ, xmmPQ, pInst ? 3 : 2); - xMOVSS(ptr32[&mVU->regs->VI[REG_P].UL], xmmPQ); + xMOVSS(ptr32[&mVU->regs().VI[REG_P].UL], xmmPQ); } // Save Flag Instances #if 1 // CHECK_MACROVU0 - Always on now - xMOV(ptr32[&mVU->regs->VI[REG_STATUS_FLAG].UL], getFlagReg(fStatus)); + xMOV(ptr32[&mVU->regs().VI[REG_STATUS_FLAG].UL], getFlagReg(fStatus)); #else mVUallocSFLAGc(gprT1, gprT2, fStatus); - xMOV(ptr32[&mVU->regs->VI[REG_STATUS_FLAG].UL], gprT1); + xMOV(ptr32[&mVU->regs().VI[REG_STATUS_FLAG].UL], gprT1); #endif mVUallocMFLAGa(mVU, gprT1, fMac); mVUallocCFLAGa(mVU, gprT2, fClip); - xMOV(ptr32[&mVU->regs->VI[REG_MAC_FLAG].UL], gprT1); - xMOV(ptr32[&mVU->regs->VI[REG_CLIP_FLAG].UL], gprT2); + xMOV(ptr32[&mVU->regs().VI[REG_MAC_FLAG].UL], gprT1); + xMOV(ptr32[&mVU->regs().VI[REG_CLIP_FLAG].UL], gprT2); if (isEbit || isVU1) { // Clear 'is busy' Flags xAND(ptr32[&VU0.VI[REG_VPU_STAT].UL], (isVU1 ? ~0x100 : ~0x001)); // VBS0/VBS1 flag - xAND(ptr32[&mVU->regs->vifRegs->stat], ~VIF1_STAT_VEW); // Clear VU 'is busy' signal for vif + xAND(ptr32[&mVU->getVifRegs().stat], ~VIF1_STAT_VEW); // Clear VU 'is busy' signal for vif } if (isEbit != 2) { // Save PC, and Jump to Exit Point - xMOV(ptr32[&mVU->regs->VI[REG_TPC].UL], xPC); + xMOV(ptr32[&mVU->regs().VI[REG_TPC].UL], xPC); xJMP(mVU->exitFunct); } } @@ -137,12 +137,12 @@ void condBranch(mV, microFlagCycles& mFC, int JMPcc) { mVUendProgram(mVU, &mFC, 2); xForwardJump8 eJMP((JccComparisonType)JMPcc); incPC(1); // Set PC to First instruction of Non-Taken Side - xMOV(ptr32[&mVU->regs->VI[REG_TPC].UL], xPC); + xMOV(ptr32[&mVU->regs().VI[REG_TPC].UL], xPC); xJMP(mVU->exitFunct); eJMP.SetTarget(); incPC(-4); // Go Back to Branch Opcode to get branchAddr iPC = branchAddr/4; - xMOV(ptr32[&mVU->regs->VI[REG_TPC].UL], xPC); + xMOV(ptr32[&mVU->regs().VI[REG_TPC].UL], xPC); xJMP(mVU->exitFunct); return; } @@ -190,7 +190,7 @@ void normJump(mV, microFlagCycles& mFC) { if (mVUup.eBit) { // E-bit Jump mVUendProgram(mVU, &mFC, 2); xMOV(gprT1, ptr32[&mVU->branch]); - xMOV(ptr32[&mVU->regs->VI[REG_TPC].UL], gprT1); + xMOV(ptr32[&mVU->regs().VI[REG_TPC].UL], gprT1); xJMP(mVU->exitFunct); } else normJumpCompile(mVU, mFC, 0); diff --git a/pcsx2/x86/microVU_Compile.inl b/pcsx2/x86/microVU_Compile.inl index b725023fd1..aa08b473f8 100644 --- a/pcsx2/x86/microVU_Compile.inl +++ b/pcsx2/x86/microVU_Compile.inl @@ -15,37 +15,25 @@ #pragma once -//------------------------------------------------------------------ -// Helper Macros -//------------------------------------------------------------------ - -#define calcCycles(reg, x) { reg = ((reg > x) ? (reg - x) : 0); } -#define optimizeReg(rState) { rState = (rState==1) ? 0 : rState; } -#define tCycles(dest, src) { dest = aMax(dest, src); } -#define incP() { mVU->p = (mVU->p+1) & 1; } -#define incQ() { mVU->q = (mVU->q+1) & 1; } -#define doUpperOp() { mVUopU(mVU, 1); mVUdivSet(mVU); } -#define doLowerOp() { incPC(-1); mVUopL(mVU, 1); incPC(1); } - //------------------------------------------------------------------ // Messages Called at Execution Time... //------------------------------------------------------------------ -static void __fastcall mVUbadOp0(mV) { Console.Error("microVU0 Warning: Exiting... Block started with illegal opcode. [%04x] [%x]", xPC, mVU->prog.cur); } -static void __fastcall mVUbadOp1(mV) { Console.Error("microVU1 Warning: Exiting... Block started with illegal opcode. [%04x] [%x]", xPC, mVU->prog.cur); } -static void __fastcall mVUwarning0(mV) { Console.Error("microVU0 Warning: Exiting from Possible Infinite Loop [%04x] [%x]", xPC, mVU->prog.cur); } -static void __fastcall mVUwarning1(mV) { Console.Error("microVU1 Warning: Exiting from Possible Infinite Loop [%04x] [%x]", xPC, mVU->prog.cur); } -static void __fastcall mVUprintPC1(u32 PC) { Console.WriteLn("Block Start PC = 0x%04x", PC); } -static void __fastcall mVUprintPC2(u32 PC) { Console.WriteLn("Block End PC = 0x%04x", PC); } +static void __fastcall mVUbadOp0(u32 prog, u32 pc) { Console.Error("microVU0 Warning: Exiting... Block started with illegal opcode. [%04x] [%x]", pc, prog); } +static void __fastcall mVUbadOp1(u32 prog, u32 pc) { Console.Error("microVU1 Warning: Exiting... Block started with illegal opcode. [%04x] [%x]", pc, prog); } +static void __fastcall mVUwarning0(u32 prog) { Console.Error("microVU0 Warning: Exiting from Possible Infinite Loop [%04x] [%x]", prog); } +static void __fastcall mVUwarning1(u32 prog) { Console.Error("microVU1 Warning: Exiting from Possible Infinite Loop [%04x] [%x]", prog); } +static void __fastcall mVUprintPC1(u32 pc) { Console.WriteLn("Block Start PC = 0x%04x", pc); } +static void __fastcall mVUprintPC2(u32 pc) { Console.WriteLn("Block End PC = 0x%04x", pc); } //------------------------------------------------------------------ -// Helper Functions +// Program Range Checking and Setting up Ranges //------------------------------------------------------------------ // Used by mVUsetupRange static __fi void mVUcheckIsSame(mV) { if (mVU->prog.isSame == -1) { - mVU->prog.isSame = !memcmp_mmx((u8*)mVUcurProg.data, mVU->regs->Micro, mVU->microMemSize); + mVU->prog.isSame = !memcmp_mmx((u8*)mVUcurProg.data, mVU->regs().Micro, mVU->microMemSize); } if (mVU->prog.isSame == 0) { if (!isVU1) mVUcacheProg<0>(*mVU->prog.cur); @@ -99,20 +87,20 @@ static void mVUsetupRange(microVU* mVU, s32 pc, bool isStartPC) { } } else { - //DevCon.WriteLn(Color_Green, "microVU%d: Prog Range Wrap [%04x] [%d]", mVU->index, mVUrange.start, mVUrange.end); + DevCon.WriteLn(Color_Green, "microVU%d: Prog Range Wrap [%04x] [%d]", mVU->index, mVUrange.start, mVUrange.end); mVUrange.end = mVU->microMemSize; microRange mRange = {0, pc}; ranges->push_front(mRange); } } -static __fi void startLoop(mV) { - if (curI & _Mbit_) { Console.WriteLn(Color_Green, "microVU%d: M-bit set!", getIndex); } - if (curI & _Dbit_) { DevCon.WriteLn (Color_Green, "microVU%d: D-bit set!", getIndex); } - if (curI & _Tbit_) { DevCon.WriteLn (Color_Green, "microVU%d: T-bit set!", getIndex); } - memzero(mVUinfo); - memzero(mVUregsTemp); -} +//------------------------------------------------------------------ +// Execute VU Opcode/Instruction (Upper and Lower) +//------------------------------------------------------------------ + +__ri void doUpperOp(mV) { mVUopU(mVU, 1); mVUdivSet(mVU); } +__ri void doLowerOp(mV) { incPC(-1); mVUopL(mVU, 1); incPC(1); } +__ri void flushRegs(mV) { if (!doRegAlloc) mVU->regAlloc->flushAll(); } static void doIbit(mV) { if (mVUup.iBit) { @@ -126,7 +114,7 @@ static void doIbit(mV) { } else tempI = curI; - xMOV(ptr32[&mVU->regs->VI[REG_I].UL], tempI); + xMOV(ptr32[&mVU->getVI(REG_I)], tempI); incPC(1); } } @@ -150,16 +138,27 @@ static void doSwapOp(mV) { mVU->regAlloc->clearNeeded(t3); incPC(1); - doUpperOp(); + doUpperOp(mVU); const xmm& t4 = mVU->regAlloc->allocReg(-1, mVUlow.VF_write.reg, 0xf); xMOVAPS(t4, t2); mVU->regAlloc->clearNeeded(t4); mVU->regAlloc->clearNeeded(t2); } - else { mVUopL(mVU, 1); incPC(1); doUpperOp(); } + else { mVUopL(mVU, 1); incPC(1); flushRegs(mVU); doUpperOp(mVU); } } +static void mVUexecuteInstruction(mV) { + if (mVUlow.isNOP) { incPC(1); doUpperOp(mVU); flushRegs(mVU); doIbit(mVU); } + elif(!mVUinfo.swapOps) { incPC(1); doUpperOp(mVU); flushRegs(mVU); doLowerOp(mVU); } + else doSwapOp(mVU); + flushRegs(mVU); +} + +//------------------------------------------------------------------ +// Warnings / Errors / Illegal Instructions +//------------------------------------------------------------------ + // If 1st op in block is a bad opcode, then don't compile rest of block (Dawn of Mana Level 2) static __fi void mVUcheckBadOp(mV) { if (mVUinfo.isBadOp && mVUcount == 0) { @@ -171,9 +170,12 @@ static __fi void mVUcheckBadOp(mV) { // Prints msg when exiting block early if 1st op was a bad opcode (Dawn of Mana Level 2) static __fi void handleBadOp(mV, int count) { if (mVUinfo.isBadOp && count == 0) { - xMOV(gprT2, (uptr)mVU); + mVUbackupRegs(mVU, true); + xMOV(gprT2, mVU->prog.cur->idx); + xMOV(gprT3, xPC); if (!isVU1) xCALL(mVUbadOp0); else xCALL(mVUbadOp1); + mVUrestoreRegs(mVU, true); } } @@ -211,8 +213,20 @@ static __ri void eBitWarning(mV) { incPC(-2); } +//------------------------------------------------------------------ +// Cycles / Pipeline State / Early Exit from Execution +//------------------------------------------------------------------ +__fi void optimizeReg(u8& rState) { rState = (rState==1) ? 0 : rState; } +__fi void calcCycles(u8& reg, u8 x) { reg = ((reg > x) ? (reg - x) : 0); } +__fi void tCycles(u8& dest, u8& src) { dest = aMax(dest, src); } +__fi void incP(mV) { mVU->p ^= 1; } +__fi void incQ(mV) { mVU->q ^= 1; } + // Optimizes the End Pipeline State Removing Unnecessary Info -static __fi void mVUoptimizePipeState(mV) { +// If the cycles remaining is just '1', we don't have to transfer it to the next block +// because mVU automatically decrements this number at the start of its loop, +// so essentially '1' will be the same as '0'... +static void mVUoptimizePipeState(mV) { for (int i = 0; i < 32; i++) { optimizeReg(mVUregs.VF[i].x); optimizeReg(mVUregs.VF[i].y); @@ -222,12 +236,12 @@ static __fi void mVUoptimizePipeState(mV) { for (int i = 0; i < 16; i++) { optimizeReg(mVUregs.VI[i]); } - if (mVUregs.q) { optimizeReg(mVUregs.q); if (!mVUregs.q) { incQ(); } } - if (mVUregs.p) { optimizeReg(mVUregs.p); if (!mVUregs.p) { incP(); } } + if (mVUregs.q) { optimizeReg(mVUregs.q); if (!mVUregs.q) { incQ(mVU); } } + if (mVUregs.p) { optimizeReg(mVUregs.p); if (!mVUregs.p) { incP(mVU); } } mVUregs.r = 0; // There are no stalls on the R-reg, so its Safe to discard info } -__fi void mVUincCycles(mV, int x) { +void mVUincCycles(mV, int x) { mVUcycles += x; for (int z = 31; z > 0; z--) { calcCycles(mVUregs.VF[z].x, x); @@ -241,11 +255,11 @@ __fi void mVUincCycles(mV, int x) { if (mVUregs.q) { if (mVUregs.q > 4) { calcCycles(mVUregs.q, x); if (mVUregs.q <= 4) { mVUinfo.doDivFlag = 1; } } else { calcCycles(mVUregs.q, x); } - if (!mVUregs.q) { incQ(); } + if (!mVUregs.q) { incQ(mVU); } } if (mVUregs.p) { calcCycles(mVUregs.p, x); - if (!mVUregs.p || mVUregsTemp.p) { incP(); } + if (!mVUregs.p || mVUregsTemp.p) { incP(mVU); } } if (mVUregs.xgkick) { calcCycles(mVUregs.xgkick, x); @@ -254,14 +268,13 @@ __fi void mVUincCycles(mV, int x) { calcCycles(mVUregs.r, x); } -#define cmpVFregs(VFreg1, VFreg2, xVar) { \ - if (VFreg1.reg == VFreg2.reg) { \ - if ((VFreg1.x && VFreg2.x) \ - || (VFreg1.y && VFreg2.y) \ - || (VFreg1.z && VFreg2.z) \ - || (VFreg1.w && VFreg2.w)) \ - { xVar = 1; } \ - } \ +// Helps check if upper/lower ops read/write to same regs... +void cmpVFregs(microVFreg& VFreg1, microVFreg& VFreg2, bool& xVar) { + if (VFreg1.reg == VFreg2.reg) { + if ((VFreg1.x && VFreg2.x) || (VFreg1.y && VFreg2.y) + || (VFreg1.z && VFreg2.z) || (VFreg1.w && VFreg2.w)) + { xVar = 1; } + } } void mVUsetCycles(mV) { @@ -299,6 +312,17 @@ void mVUsetCycles(mV) { tCycles(mVUregs.xgkick, mVUregsTemp.xgkick); } +// Prints Start/End PC of blocks executed, for debugging... +static void mVUdebugPrintBlocks(microVU* mVU, bool isEndPC) { + if (mVUdebugNow) { + mVUbackupRegs(mVU, true); + xMOV(gprT2, xPC); + if (isEndPC) xCALL(mVUprintPC2); + else xCALL(mVUprintPC1); + mVUrestoreRegs(mVU, true); + } +} + // vu0 is allowed to exit early, so are dev builds (for inf loops) __fi bool doEarlyExit(microVU* mVU) { return IsDevBuild || !isVU1; @@ -312,15 +336,6 @@ static __fi void mVUsavePipelineState(microVU* mVU) { } } -// Prints Start/End PC of blocks executed, for debugging... -static void mVUdebugPrintBlocks(microVU* mVU, bool isEndPC) { - if (mVUdebugNow) { - xMOV(gprT2, xPC); - if (isEndPC) xCALL(mVUprintPC2); - else xCALL(mVUprintPC1); - } -} - // Test cycles to see if we need to exit-early... static void mVUtestCycles(microVU* mVU) { iPC = mVUstartPC; @@ -328,17 +343,21 @@ static void mVUtestCycles(microVU* mVU) { xCMP(ptr32[&mVU->cycles], 0); xForwardJG32 skip; if (isVU0) { - // TEST32ItoM((uptr)&mVU->regs->flags, VUFLAG_MFLAGSET); + // TEST32ItoM((uptr)&mVU->regs().flags, VUFLAG_MFLAGSET); // xFowardJZ32 vu0jmp; - // xMOV(gprT2, (uptr)mVU); + // mVUbackupRegs(mVU, true); + // xMOV(gprT2, mVU->prog.cur->idx); // xCALL(mVUwarning0); // VU0 is allowed early exit for COP2 Interlock Simulation - mVUsavePipelineState(mVU); - mVUendProgram(mVU, NULL, 0); + // mVUbackupRegs(mVU, true); + mVUsavePipelineState(mVU); + mVUendProgram(mVU, NULL, 0); // vu0jmp.SetTarget(); } else { - xMOV(gprT2, (uptr)mVU); + mVUbackupRegs(mVU, true); + xMOV(gprT2, mVU->prog.cur->idx); xCALL(mVUwarning1); + mVUbackupRegs(mVU, true); mVUsavePipelineState(mVU); mVUendProgram(mVU, NULL, 0); } @@ -347,6 +366,19 @@ static void mVUtestCycles(microVU* mVU) { xSUB(ptr32[&mVU->cycles], mVUcycles); } +//------------------------------------------------------------------ +// Initializing +//------------------------------------------------------------------ + +// This gets run at the start of every loop of mVU's first pass +static __fi void startLoop(mV) { + if (curI & _Mbit_) { Console.WriteLn(Color_Green, "microVU%d: M-bit set!", getIndex); } + if (curI & _Dbit_) { DevCon.WriteLn (Color_Green, "microVU%d: D-bit set!", getIndex); } + if (curI & _Tbit_) { DevCon.WriteLn (Color_Green, "microVU%d: T-bit set!", getIndex); } + memzero(mVUinfo); + memzero(mVUregsTemp); +} + // Initialize VI Constants (vi15 propagates through blocks) static __fi void mVUinitConstValues(microVU* mVU) { for (int i = 0; i < 16; i++) { @@ -393,8 +425,8 @@ void* mVUcompile(microVU* mVU, u32 startPC, uptr pState) { // First Pass iPC = startPC / 4; - mVUsetupRange(mVU, startPC, 1); // Setup Program Bounds/Range - mVU->regAlloc->reset(mVU->regs); // Reset regAlloc + mVUsetupRange(mVU, startPC, 1); // Setup Program Bounds/Range + mVU->regAlloc->reset(); // Reset regAlloc mVUinitFirstPass(mVU, pState, thisPtr); for (int branch = 0; mVUcount < endCount; mVUcount++) { incPC(1); @@ -419,7 +451,7 @@ void* mVUcompile(microVU* mVU, u32 startPC, uptr pState) { } // Fix up vi15 const info for propagation through blocks - mVUregs.vi15 = (mVUconstReg[15].isValid && CHECK_VU_CONSTPROP) ? ((1<<31) | (mVUconstReg[15].regValue&0xffff)) : 0; + mVUregs.vi15 = (mVUconstReg[15].isValid && doConstProp) ? ((1<<31) | (mVUconstReg[15].regValue&0xffff)) : 0; mVUsetFlags(mVU, mFC); // Sets Up Flag instances mVUoptimizePipeState(mVU); // Optimize the End Pipeline State for nicer Block Linking @@ -433,12 +465,9 @@ void* mVUcompile(microVU* mVU, u32 startPC, uptr pState) { u32 x = 0; for (; x < endCount; x++) { if (mVUinfo.isEOB) { handleBadOp(mVU, x); x = 0xffff; } - if (mVUup.mBit) { xOR(ptr32[&mVU->regs->flags], VUFLAG_MFLAGSET); } - if (mVUlow.isNOP) { incPC(1); doUpperOp(); doIbit(mVU); } - else if (!mVUinfo.swapOps) { incPC(1); doUpperOp(); doLowerOp(); } - else { doSwapOp(mVU); } + if (mVUup.mBit) { xOR(ptr32[&mVU->regs().flags], VUFLAG_MFLAGSET); } + mVUexecuteInstruction(mVU); if (mVUinfo.doXGKICK) { mVU_XGKICK_DELAY(mVU, 1); } - if (!doRegAlloc) { mVU->regAlloc->flushAll(); } if (isEvilBlock) { mVUsetupRange(mVU, xPC, 0); normJumpCompile(mVU, mFC, 1); return thisPtr; } else if (!mVUinfo.isBdelay) { incPC(1); } else { diff --git a/pcsx2/x86/microVU_Execute.inl b/pcsx2/x86/microVU_Execute.inl index 610ca5b095..198ab530da 100644 --- a/pcsx2/x86/microVU_Execute.inl +++ b/pcsx2/x86/microVU_Execute.inl @@ -43,24 +43,24 @@ void mVUdispatcherA(mV) { // Load Regs #if 1 // CHECK_MACROVU0 - Always on now - xMOV(gprF0, ptr32[&mVU->regs->VI[REG_STATUS_FLAG].UL]); + xMOV(gprF0, ptr32[&mVU->regs().VI[REG_STATUS_FLAG].UL]); xMOV(gprF1, gprF0); xMOV(gprF2, gprF0); xMOV(gprF3, gprF0); #else - mVUallocSFLAGd((uptr)&mVU->regs->VI[REG_STATUS_FLAG].UL, 1); + mVUallocSFLAGd((uptr)&mVU->regs().VI[REG_STATUS_FLAG].UL, 1); #endif - xMOVAPS(xmmT1, ptr128[&mVU->regs->VI[REG_MAC_FLAG].UL]); + xMOVAPS(xmmT1, ptr128[&mVU->regs().VI[REG_MAC_FLAG].UL]); xSHUF.PS(xmmT1, xmmT1, 0); xMOVAPS(ptr128[mVU->macFlag], xmmT1); - xMOVAPS(xmmT1, ptr128[&mVU->regs->VI[REG_CLIP_FLAG].UL]); + xMOVAPS(xmmT1, ptr128[&mVU->regs().VI[REG_CLIP_FLAG].UL]); xSHUF.PS(xmmT1, xmmT1, 0); xMOVAPS(ptr128[mVU->clipFlag], xmmT1); - xMOVAPS(xmmT1, ptr128[&mVU->regs->VI[REG_P].UL]); - xMOVAPS(xmmPQ, ptr128[&mVU->regs->VI[REG_Q].UL]); + xMOVAPS(xmmT1, ptr128[&mVU->regs().VI[REG_P].UL]); + xMOVAPS(xmmPQ, ptr128[&mVU->regs().VI[REG_Q].UL]); xSHUF.PS(xmmPQ, xmmT1, 0); // wzyx = PPQQ // Jump to Recompiled Code Block @@ -119,12 +119,12 @@ _mVUt void* __fastcall mVUexecute(u32 startPC, u32 cycles) { _mVUt void mVUcleanUp() { microVU* mVU = mVUx; //mVUprint("microVU: Program exited successfully!"); - //mVUprint("microVU: VF0 = {%x,%x,%x,%x}", mVU->regs->VF[0].UL[0], mVU->regs->VF[0].UL[1], mVU->regs->VF[0].UL[2], mVU->regs->VF[0].UL[3]); - //mVUprint("microVU: VI0 = %x", mVU->regs->VI[0].UL); + //mVUprint("microVU: VF0 = {%x,%x,%x,%x}", mVU->regs().VF[0].UL[0], mVU->regs().VF[0].UL[1], mVU->regs().VF[0].UL[2], mVU->regs().VF[0].UL[3]); + //mVUprint("microVU: VI0 = %x", mVU->regs().VI[0].UL); mVU->prog.x86ptr = x86Ptr; mVUcacheCheck(x86Ptr, mVU->prog.x86start, (uptr)(mVU->prog.x86end - mVU->prog.x86start)); mVU->cycles = mVU->totalCycles - mVU->cycles; - mVU->regs->cycle += mVU->cycles; + mVU->regs().cycle += mVU->cycles; cpuRegs.cycle += ((mVU->cycles < 3000) ? mVU->cycles : 3000) * EmuConfig.Speedhacks.VUCycleSteal; //static int ax = 0; ax++; //if (!(ax % 100000)) { diff --git a/pcsx2/x86/microVU_Flags.inl b/pcsx2/x86/microVU_Flags.inl index 5519f5af1f..9672d79135 100644 --- a/pcsx2/x86/microVU_Flags.inl +++ b/pcsx2/x86/microVU_Flags.inl @@ -286,7 +286,7 @@ void mVUflagPass(mV, u32 startPC, u32 sCount = 0, u32 found = 0) { __fi void mVUsetFlagInfo(mV) { branchType1 { incPC(-1); mVUflagPass(mVU, branchAddr); incPC(1); } branchType2 { // This case can possibly be turned off via a hack for a small speedup... - if (!mVUlow.constJump.isValid || !CHECK_VU_CONSTPROP) { mVUregs.needExactMatch |= 0x7; } + if (!mVUlow.constJump.isValid || !doConstProp) { mVUregs.needExactMatch |= 0x7; } else { mVUflagPass(mVU, (mVUlow.constJump.regValue*8)&(mVU->microMemSize-8)); } } branchType3 { diff --git a/pcsx2/x86/microVU_IR.h b/pcsx2/x86/microVU_IR.h index cbaed67c37..3828a776a0 100644 --- a/pcsx2/x86/microVU_IR.h +++ b/pcsx2/x86/microVU_IR.h @@ -25,34 +25,48 @@ union regInfo { }; }; -#ifdef _MSC_VER -# pragma pack(1) -#endif +// microRegInfo is carefully ordered for faster compares. The "important" information is +// housed in a union that is accessed via 'quick32' so that several u8 fields can be compared +// using a pair of 32-bit equalities. +// vi15 is only used if microVU const-prop is enabled (it is *not* by default). When constprop +// is disabled the vi15 field acts as additional padding that is required for 16 byte alignment +// needed by the xmm compare. +union __aligned16 microRegInfo { + struct { + u32 vi15; // Constant Prop Info for vi15 (only valid if sign-bit set) -struct __aligned16 microRegInfo { // Ordered for Faster Compares - u32 vi15; // Constant Prop Info for vi15 (only valid if sign-bit set) - u8 needExactMatch; // If set, block needs an exact match of pipeline state - u8 q; - u8 p; - u8 r; - u8 xgkick; - u8 viBackUp; // VI reg number that was written to on branch-delay slot - u8 VI[16]; - regInfo VF[32]; - u8 flags; // clip x2 :: status x2 - u8 blockType; // 0 = Normal; 1,2 = Compile one instruction (E-bit/Branch Ending) - u8 padding[5]; // 160 bytes -} __packed; + union { + struct { + u8 needExactMatch; // If set, block needs an exact match of pipeline state + u8 q; + u8 p; + u8 flags; // clip x2 :: status x2 + u8 xgkick; + u8 viBackUp; // VI reg number that was written to on branch-delay slot + u8 blockType; // 0 = Normal; 1,2 = Compile one instruction (E-bit/Branch Ending) + u8 r; + }; + u32 quick32[2]; + }; + + struct { + u8 VI[16]; + regInfo VF[32]; + }; + }; + + u128 full128[160/sizeof(u128)]; + u64 full64[160/sizeof(u64)]; + u32 full32[160/sizeof(u32)]; +}; + +C_ASSERT(sizeof(microRegInfo) == 160); struct __aligned16 microBlock { microRegInfo pState; // Detailed State of Pipeline microRegInfo pStateEnd; // Detailed State of Pipeline at End of Block (needed by JR/JALR opcodes) u8* x86ptrStart; // Start of code -} __packed; - -#ifdef _MSC_VER -# pragma pack() -#endif +}; struct microTempRegInfo { regInfo VF[2]; // Holds cycle info for Fd, VF[0] = Upper Instruction, VF[1] = Lower Instruction @@ -170,14 +184,25 @@ struct microMapXMM { bool isNeeded; // Is needed for current instruction }; -#define xmmTotal 7 // Don't allocate PQ? class microRegAlloc { -private: +protected: + static const u32 xmmTotal = 7; // Don't allocate PQ? microMapXMM xmmMap[xmmTotal]; - VURegs* vuRegs; - int counter; + int counter; // Current allocation count + int index; // VU0 or VU1 + + // Helper functions to get VU regs + VURegs& regs() const { return ::vuRegs[index]; } + __fi REG_VI& getVI(uint reg) const { return regs().VI[reg]; } + __fi VECTOR& getVF(uint reg) const { return regs().VF[reg]; } + + __ri void loadIreg(const xmm& reg, int xyzw) { + xMOVSSZX(reg, ptr32[&getVI(REG_I)]); + if (!_XYZWss(xyzw)) xSHUF.PS(reg, reg, 0); + } + int findFreeRegRec(int startIdx) { - for (int i = startIdx; i < xmmTotal; i++) { + for(int i = startIdx; i < xmmTotal; i++) { if (!xmmMap[i].isNeeded) { int x = findFreeRegRec(i+1); if (x == -1) return i; @@ -186,8 +211,9 @@ private: } return -1; } + int findFreeReg() { - for (int i = 0; i < xmmTotal; i++) { + for(int i = 0; i < xmmTotal; i++) { if (!xmmMap[i].isNeeded && (xmmMap[i].VFreg < 0)) { return i; // Reg is not needed and was a temp reg } @@ -198,119 +224,150 @@ private: } public: - microRegAlloc() { } + microRegAlloc(int _index) { + index = _index; + } - void reset(VURegs* vuRegsPtr) { - vuRegs = vuRegsPtr; - for (int i = 0; i < xmmTotal; i++) { + // Fully resets the regalloc by clearing all cached data + void reset() { + for(int i = 0; i < xmmTotal; i++) { clearReg(i); } counter = 0; } + + // Flushes all allocated registers (i.e. writes-back to memory all modified registers). + // If clearState is 0, then it keeps cached reg data valid + // If clearState is 1, then it invalidates all cached reg data after write-back void flushAll(bool clearState = 1) { - for (int i = 0; i < xmmTotal; i++) { + for(int i = 0; i < xmmTotal; i++) { writeBackReg(xmm(i)); if (clearState) clearReg(i); } } + void clearReg(const xmm& reg) { clearReg(reg.Id); } void clearReg(int regId) { - microMapXMM& clear( xmmMap[regId] ); + microMapXMM& clear = xmmMap[regId]; clear.VFreg = -1; clear.count = 0; clear.xyzw = 0; clear.isNeeded = 0; } + void clearRegVF(int VFreg) { - for (int i = 0; i < xmmTotal; i++) { + for(int i = 0; i < xmmTotal; i++) { if (xmmMap[i].VFreg == VFreg) clearReg(i); } } - void writeBackReg(const xmm& reg, bool invalidateRegs = 1) { - microMapXMM& write( xmmMap[reg.Id] ); - if ((write.VFreg > 0) && write.xyzw) { // Reg was modified and not Temp or vf0 - if (write.VFreg == 33) xMOVSS(ptr32[&vuRegs->VI[REG_I].UL], reg); - else if (write.VFreg == 32) mVUsaveReg(reg, ptr[&vuRegs->ACC.UL[0]], write.xyzw, 1); - else mVUsaveReg(reg, ptr[&vuRegs->VF[write.VFreg].UL[0]], write.xyzw, 1); + // Writes back modified reg to memory. + // If all vectors modified, then keeps the VF reg cached in the xmm register. + // If reg was not modified, then keeps the VF reg cached in the xmm register. + void writeBackReg(const xmm& reg, bool invalidateRegs = 1) { + microMapXMM& mapX = xmmMap[reg.Id]; + + if ((mapX.VFreg > 0) && mapX.xyzw) { // Reg was modified and not Temp or vf0 + if (mapX.VFreg == 33) xMOVSS(ptr32[&getVI(REG_I)], reg); + elif (mapX.VFreg == 32) mVUsaveReg(reg, ptr[®s().ACC], mapX.xyzw, 1); + else mVUsaveReg(reg, ptr[&getVF(mapX.VFreg)], mapX.xyzw, 1); if (invalidateRegs) { - for (int i = 0; i < xmmTotal; i++) { - microMapXMM& imap (xmmMap[i]); - if ((i == reg.Id) || imap.isNeeded) continue; - if (imap.VFreg == write.VFreg) { - if (imap.xyzw && imap.xyzw < 0xf) DevCon.Error("microVU Error: writeBackReg() [%d]", imap.VFreg); + for(int i = 0; i < xmmTotal; i++) { + microMapXMM& mapI = xmmMap[i]; + if ((i == reg.Id) || mapI.isNeeded) continue; + if (mapI.VFreg == mapX.VFreg) { + if (mapI.xyzw && mapI.xyzw < 0xf) DevCon.Error("microVU Error: writeBackReg() [%d]", mapI.VFreg); clearReg(i); // Invalidate any Cached Regs of same vf Reg } } } - if (write.xyzw == 0xf) { // Make Cached Reg if All Vectors were Modified - write.count = counter; - write.xyzw = 0; - write.isNeeded = 0; + if (mapX.xyzw == 0xf) { // Make Cached Reg if All Vectors were Modified + mapX.count = counter; + mapX.xyzw = 0; + mapX.isNeeded = 0; return; } + clearReg(reg); } - clearReg(reg); // Clear Reg + elif (mapX.xyzw) clearReg(reg); // Clear reg if modified and is VF0 or temp reg... } - void clearNeeded(const xmm& reg) - { - if ((reg.Id < 0) || (reg.Id >= xmmTotal)) return; - microMapXMM& clear (xmmMap[reg.Id]); + // Use this when done using the allocated register, it clears its "Needed" status. + // The register that was written to, should be cleared before other registers are cleared. + // This is to guarantee proper merging between registers... When a written-to reg is cleared, + // it invalidates other cached registers of the same VF reg, and merges partial-vector + // writes into them. + void clearNeeded(const xmm& reg) { + + if ((reg.Id < 0) || (reg.Id >= xmmTotal)) return; // Sometimes xmmPQ hits this + + microMapXMM& clear = xmmMap[reg.Id]; clear.isNeeded = 0; if (clear.xyzw) { // Reg was modified if (clear.VFreg > 0) { int mergeRegs = 0; - if (clear.xyzw < 0xf) { mergeRegs = 1; } // Try to merge partial writes - for (int i = 0; i < xmmTotal; i++) { // Invalidate any other read-only regs of same vfReg + if (clear.xyzw < 0xf) mergeRegs = 1; // Try to merge partial writes + for(int i = 0; i < xmmTotal; i++) { // Invalidate any other read-only regs of same vfReg if (i == reg.Id) continue; - microMapXMM& imap (xmmMap[i]); - if (imap.VFreg == clear.VFreg) { - if (imap.xyzw && imap.xyzw < 0xf) DevCon.Error("microVU Error: clearNeeded() [%d]", imap.VFreg); + microMapXMM& mapI = xmmMap[i]; + if (mapI.VFreg == clear.VFreg) { + if (mapI.xyzw && mapI.xyzw < 0xf) { + DevCon.Error("microVU Error: clearNeeded() [%d]", mapI.VFreg); + } if (mergeRegs == 1) { mVUmergeRegs(xmm(i), reg, clear.xyzw, 1); - imap.xyzw = 0xf; - imap.count = counter; - mergeRegs = 2; + mapI.xyzw = 0xf; + mapI.count = counter; + mergeRegs = 2; } - else clearReg(i); + else clearReg(i); // Clears when mergeRegs is 0 or 2 } } - if (mergeRegs == 2) clearReg(reg); // Clear Current Reg if Merged - else if (mergeRegs) writeBackReg(reg); // Write Back Partial Writes if couldn't merge + if (mergeRegs==2) clearReg(reg); // Clear Current Reg if Merged + elif (mergeRegs==1) writeBackReg(reg); // Write Back Partial Writes if couldn't merge } else clearReg(reg); // If Reg was temp or vf0, then invalidate itself } } + + // vfLoadReg = VF reg to be loaded to the xmm register + // vfWriteReg = VF reg that the returned xmm register will be considered as + // xyzw = XYZW vectors that will be modified (and loaded) + // cloneWrite = When loading a reg that will be written to, + // it copies it to its own xmm reg instead of overwriting the cached one... + // Notes: + // To load a temp reg use the default param values, vfLoadReg = -1 and vfWriteReg = -1. + // To load a full reg which won't be modified and you want cached, specify vfLoadReg >= 0 and vfWriteReg = -1 + // To load a reg which you don't want written back or cached, specify vfLoadReg >= 0 and vfWriteReg = 0 const xmm& allocReg(int vfLoadReg = -1, int vfWriteReg = -1, int xyzw = 0, bool cloneWrite = 1) { + //DevCon.WriteLn("vfLoadReg = %02d, vfWriteReg = %02d, xyzw = %x, clone = %d",vfLoadReg,vfWriteReg,xyzw,(int)cloneWrite); counter++; if (vfLoadReg >= 0) { // Search For Cached Regs - for (int i = 0; i < xmmTotal; i++) { - const xmm& xmmi(xmm::GetInstance(i)); - microMapXMM& imap (xmmMap[i]); - if ((imap.VFreg == vfLoadReg) && (!imap.xyzw // Reg Was Not Modified - || (imap.VFreg && (imap.xyzw==0xf)))) { // Reg Had All Vectors Modified and != VF0 + for(int i = 0; i < xmmTotal; i++) { + const xmm& xmmI = xmm::GetInstance(i); + microMapXMM& mapI = xmmMap[i]; + if ((mapI.VFreg == vfLoadReg) && (!mapI.xyzw // Reg Was Not Modified + || (mapI.VFreg && (mapI.xyzw==0xf)))) { // Reg Had All Vectors Modified and != VF0 int z = i; if (vfWriteReg >= 0) { // Reg will be modified if (cloneWrite) { // Clone Reg so as not to use the same Cached Reg z = findFreeReg(); - const xmm& xmmz(xmm::GetInstance(z)); - writeBackReg(xmmz); - if (z!=i && xyzw==8) xMOVAPS (xmmz, xmmi); - else if (xyzw == 4) xPSHUF.D(xmmz, xmmi, 1); - else if (xyzw == 2) xPSHUF.D(xmmz, xmmi, 2); - else if (xyzw == 1) xPSHUF.D(xmmz, xmmi, 3); - else if (z != i) xMOVAPS (xmmz, xmmi); - imap.count = counter; // Reg i was used, so update counter + const xmm& xmmZ = xmm::GetInstance(z); + writeBackReg(xmmZ); + if (xyzw == 4) xPSHUF.D(xmmZ, xmmI, 1); + elif (xyzw == 2) xPSHUF.D(xmmZ, xmmI, 2); + elif (xyzw == 1) xPSHUF.D(xmmZ, xmmI, 3); + elif (z != i) xMOVAPS (xmmZ, xmmI); + mapI.count = counter; // Reg i was used, so update counter } else { // Don't clone reg, but shuffle to adjust for SS ops - if ((vfLoadReg != vfWriteReg) || (xyzw != 0xf)) { writeBackReg(xmmi); } - if (xyzw == 4) xPSHUF.D(xmmi, xmmi, 1); - else if (xyzw == 2) xPSHUF.D(xmmi, xmmi, 2); - else if (xyzw == 1) xPSHUF.D(xmmi, xmmi, 3); + if ((vfLoadReg!=vfWriteReg)||(xyzw!=0xf)) writeBackReg(xmmI); + if (xyzw == 4) xPSHUF.D(xmmI, xmmI, 1); + elif (xyzw == 2) xPSHUF.D(xmmI, xmmI, 2); + elif (xyzw == 1) xPSHUF.D(xmmI, xmmI, 3); } - xmmMap[z].VFreg = vfWriteReg; - xmmMap[z].xyzw = xyzw; + xmmMap[z].VFreg = vfWriteReg; + xmmMap[z].xyzw = xyzw; } xmmMap[z].count = counter; xmmMap[z].isNeeded = 1; @@ -319,26 +376,26 @@ public: } } int x = findFreeReg(); - const xmm& xmmx = xmm::GetInstance(x); - writeBackReg(xmmx); + const xmm& xmmX = xmm::GetInstance(x); + writeBackReg(xmmX); if (vfWriteReg >= 0) { // Reg Will Be Modified (allow partial reg loading) - if ((vfLoadReg == 0) && !(xyzw & 1)) { xPXOR(xmmx, xmmx); } - else if (vfLoadReg == 33) mVUloadIreg(xmmx, xyzw, vuRegs); - else if (vfLoadReg == 32) mVUloadReg (xmmx, ptr[&vuRegs->ACC.UL[0]], xyzw); - else if (vfLoadReg >= 0) mVUloadReg (xmmx, ptr[&vuRegs->VF[vfLoadReg].UL[0]], xyzw); - xmmMap[x].VFreg = vfWriteReg; - xmmMap[x].xyzw = xyzw; + if ((vfLoadReg == 0) && !(xyzw & 1)) xPXOR(xmmX, xmmX); + elif (vfLoadReg == 33) loadIreg (xmmX, xyzw); + elif (vfLoadReg == 32) mVUloadReg(xmmX, ptr[®s().ACC], xyzw); + elif (vfLoadReg >= 0) mVUloadReg(xmmX, ptr[&getVF(vfLoadReg)], xyzw); + xmmMap[x].VFreg = vfWriteReg; + xmmMap[x].xyzw = xyzw; } else { // Reg Will Not Be Modified (always load full reg for caching) - if (vfLoadReg == 33) mVUloadIreg(xmmx, 0xf, vuRegs); - else if (vfLoadReg == 32) xMOVAPS(xmmx, ptr128[&vuRegs->ACC.UL[0]]); - else if (vfLoadReg >= 0) xMOVAPS(xmmx, ptr128[&vuRegs->VF[vfLoadReg].UL[0]]); - xmmMap[x].VFreg = vfLoadReg; - xmmMap[x].xyzw = 0; + if (vfLoadReg == 33) loadIreg(xmmX, 0xf); + elif (vfLoadReg == 32) xMOVAPS (xmmX, ptr128[®s().ACC]); + elif (vfLoadReg >= 0) xMOVAPS (xmmX, ptr128[&getVF(vfLoadReg)]); + xmmMap[x].VFreg = vfLoadReg; + xmmMap[x].xyzw = 0; } xmmMap[x].count = counter; xmmMap[x].isNeeded = 1; - return xmmx; + return xmmX; } }; diff --git a/pcsx2/x86/microVU_Lower.inl b/pcsx2/x86/microVU_Lower.inl index 3fcd9b9d84..f2a74b7d91 100644 --- a/pcsx2/x86/microVU_Lower.inl +++ b/pcsx2/x86/microVU_Lower.inl @@ -778,7 +778,7 @@ mVUop(mVU_MTIR) { mVUop(mVU_ILW) { pass1 { if (!_It_) { mVUlow.isNOP = 1; } analyzeVIreg1(_Is_, mVUlow.VI_read[0]); analyzeVIreg2(_It_, mVUlow.VI_write, 4); } pass2 { - xAddressVoid ptr(mVU->regs->Mem + offsetSS); + xAddressVoid ptr(mVU->regs().Mem + offsetSS); if (_Is_) { mVUallocVIa(mVU, gprT2, _Is_); xADD(gprT2, _Imm11_); @@ -796,7 +796,7 @@ mVUop(mVU_ILW) { mVUop(mVU_ILWR) { pass1 { if (!_It_) { mVUlow.isNOP = 1; } analyzeVIreg1(_Is_, mVUlow.VI_read[0]); analyzeVIreg2(_It_, mVUlow.VI_write, 4); } pass2 { - xAddressVoid ptr(mVU->regs->Mem + offsetSS); + xAddressVoid ptr(mVU->regs().Mem + offsetSS); if (_Is_) { mVUallocVIa(mVU, gprT2, _Is_); mVUaddrFix (mVU, gprT2); @@ -815,7 +815,7 @@ mVUop(mVU_ILWR) { mVUop(mVU_ISW) { pass1 { analyzeVIreg1(_Is_, mVUlow.VI_read[0]); analyzeVIreg1(_It_, mVUlow.VI_read[1]); } pass2 { - xAddressVoid ptr(mVU->regs->Mem); + xAddressVoid ptr(mVU->regs().Mem); if (_Is_) { mVUallocVIa(mVU, gprT2, _Is_); xADD(gprT2, _Imm11_); @@ -836,7 +836,7 @@ mVUop(mVU_ISW) { mVUop(mVU_ISWR) { pass1 { analyzeVIreg1(_Is_, mVUlow.VI_read[0]); analyzeVIreg1(_It_, mVUlow.VI_read[1]); } pass2 { - xAddressVoid ptr(mVU->regs->Mem); + xAddressVoid ptr(mVU->regs().Mem); if (_Is_) { mVUallocVIa(mVU, gprT2, _Is_); mVUaddrFix (mVU, gprT2); @@ -858,7 +858,7 @@ mVUop(mVU_ISWR) { mVUop(mVU_LQ) { pass1 { mVUanalyzeLQ(mVU, _Ft_, _Is_, 0); } pass2 { - xAddressVoid ptr(mVU->regs->Mem); + xAddressVoid ptr(mVU->regs().Mem); if (_Is_) { mVUallocVIa(mVU, gprT2, _Is_); xADD(gprT2, _Imm11_); @@ -877,7 +877,7 @@ mVUop(mVU_LQ) { mVUop(mVU_LQD) { pass1 { mVUanalyzeLQ(mVU, _Ft_, _Is_, 1); } pass2 { - xAddressVoid ptr(mVU->regs->Mem); + xAddressVoid ptr(mVU->regs().Mem); if (_Is_) { mVUallocVIa(mVU, gprT2, _Is_); xSUB(gprT2b, 1); @@ -897,7 +897,7 @@ mVUop(mVU_LQD) { mVUop(mVU_LQI) { pass1 { mVUanalyzeLQ(mVU, _Ft_, _Is_, 1); } pass2 { - xAddressVoid ptr(mVU->regs->Mem); + xAddressVoid ptr(mVU->regs().Mem); if (_Is_) { mVUallocVIa(mVU, gprT1, _Is_); xMOV(gprT2, gprT1); @@ -922,7 +922,7 @@ mVUop(mVU_LQI) { mVUop(mVU_SQ) { pass1 { mVUanalyzeSQ(mVU, _Fs_, _It_, 0); } pass2 { - xAddressVoid ptr(mVU->regs->Mem); + xAddressVoid ptr(mVU->regs().Mem); if (_It_) { mVUallocVIa(mVU, gprT2, _It_); xADD(gprT2, _Imm11_); @@ -941,7 +941,7 @@ mVUop(mVU_SQ) { mVUop(mVU_SQD) { pass1 { mVUanalyzeSQ(mVU, _Fs_, _It_, 1); } pass2 { - xAddressVoid ptr(mVU->regs->Mem); + xAddressVoid ptr(mVU->regs().Mem); if (_It_) { mVUallocVIa(mVU, gprT2, _It_); xSUB(gprT2b, 1); @@ -959,7 +959,7 @@ mVUop(mVU_SQD) { mVUop(mVU_SQI) { pass1 { mVUanalyzeSQ(mVU, _Fs_, _It_, 1); } pass2 { - xAddressVoid ptr(mVU->regs->Mem); + xAddressVoid ptr(mVU->regs().Mem); if (_It_) { mVUallocVIa(mVU, gprT1, _It_); xMOV(gprT2, gprT1); @@ -1069,7 +1069,7 @@ mVUop(mVU_WAITQ) { mVUop(mVU_XTOP) { pass1 { if (!_It_) { mVUlow.isNOP = 1; } analyzeVIreg2(_It_, mVUlow.VI_write, 1); } pass2 { - xMOVZX(gprT1, ptr16[&mVU->regs->vifRegs->top]); + xMOVZX(gprT1, ptr16[&mVU->getVifRegs().top]); mVUallocVIb(mVU, gprT1, _It_); } pass3 { mVUlog("XTOP vi%02d", _Ft_); } @@ -1078,7 +1078,7 @@ mVUop(mVU_XTOP) { mVUop(mVU_XITOP) { pass1 { if (!_It_) { mVUlow.isNOP = 1; } analyzeVIreg2(_It_, mVUlow.VI_write, 1); } pass2 { - xMOVZX(gprT1, ptr16[&mVU->regs->vifRegs->itop]); + xMOVZX(gprT1, ptr16[&mVU->getVifRegs().itop]); xAND(gprT1, isVU1 ? 0x3ff : 0xff); mVUallocVIb(mVU, gprT1, _It_); } @@ -1094,16 +1094,16 @@ extern bool SIGNAL_IMR_Pending; void __fastcall mVU_XGKICK_(u32 addr) { addr &= 0x3ff; - u8* data = microVU1.regs->Mem + (addr*16); + u8* data = vuRegs[1].Mem + (addr*16); u32 diff = 0x400 - addr; u32 size; - if(gifRegs->stat.APATH <= GIF_APATH1 || (gifRegs->stat.APATH == GIF_APATH3 && gifRegs->stat.IP3 == true) && SIGNAL_IMR_Pending == false) + if(gifRegs.stat.APATH <= GIF_APATH1 || (gifRegs.stat.APATH == GIF_APATH3 && gifRegs.stat.IP3 == true) && SIGNAL_IMR_Pending == false) { if(Path1WritePos != 0) { //Flush any pending transfers so things dont go up in the wrong order - while(gifRegs->stat.P1Q == true) gsPath1Interrupt(); + while(gifRegs.stat.P1Q == true) gsPath1Interrupt(); } GetMTGS().PrepDataPacket(GIF_PATH_1, 0x400); size = GIFPath_CopyTag(GIF_PATH_1, (u128*)data, diff); @@ -1111,13 +1111,13 @@ void __fastcall mVU_XGKICK_(u32 addr) { if(GSTransferStatus.PTH1 == STOPPED_MODE) { - gifRegs->stat.OPH = false; - gifRegs->stat.APATH = GIF_APATH_IDLE; + gifRegs.stat.OPH = false; + gifRegs.stat.APATH = GIF_APATH_IDLE; } } else { - //DevCon.Warning("GIF APATH busy %x Holding for later W %x, R %x", gifRegs->stat.APATH, Path1WritePos, Path1ReadPos); + //DevCon.Warning("GIF APATH busy %x Holding for later W %x, R %x", gifRegs.stat.APATH, Path1WritePos, Path1ReadPos); size = GIFPath_ParseTagQuick(GIF_PATH_1, data, diff); u8* pDest = &Path1Buffer[Path1WritePos*16]; @@ -1128,14 +1128,14 @@ void __fastcall mVU_XGKICK_(u32 addr) { if (size > diff) { //DevCon.Status("XGkick Wrap!"); - memcpy_qwc(pDest, microVU1.regs->Mem + (addr*16), diff); - memcpy_qwc(pDest+(diff*16), microVU1.regs->Mem, size-diff); + memcpy_qwc(pDest, vuRegs[1].Mem + (addr*16), diff); + memcpy_qwc(pDest+(diff*16), vuRegs[1].Mem, size-diff); } else { - memcpy_qwc(pDest, microVU1.regs->Mem + (addr*16), size); + memcpy_qwc(pDest, vuRegs[1].Mem + (addr*16), size); } - //if(!gifRegs->stat.P1Q) CPU_INT(28, 128); - gifRegs->stat.P1Q = true; + //if(!gifRegs.stat.P1Q) CPU_INT(28, 128); + gifRegs.stat.P1Q = true; } } diff --git a/pcsx2/x86/microVU_Macro.inl b/pcsx2/x86/microVU_Macro.inl index 4bd40e001d..ee2ae5c7ab 100644 --- a/pcsx2/x86/microVU_Macro.inl +++ b/pcsx2/x86/microVU_Macro.inl @@ -18,7 +18,7 @@ extern void _vu0WaitMicro(); extern void _vu0FinishMicro(); -typedef void FnType_Void(); +static VURegs& vu0Regs = vuRegs[0]; //------------------------------------------------------------------ // Macro VU - Helper Macros / Functions @@ -36,9 +36,9 @@ void setupMacroOp(int mode, const char* opName) { microVU0.code = cpuRegs.code; memset(µVU0.prog.IRinfo.info[0], 0, sizeof(microVU0.prog.IRinfo.info[0])); iFlushCall(FLUSH_EVERYTHING); - microVU0.regAlloc->reset(microVU0.regs); + microVU0.regAlloc->reset(); if (mode & 0x01) { // Q-Reg will be Read - xMOVSSZX(xmmPQ, ptr32[µVU0.regs->VI[REG_Q].UL]); + xMOVSSZX(xmmPQ, ptr32[&vu0Regs.VI[REG_Q].UL]); } if (mode & 0x08) { // Clip Instruction microVU0.prog.IRinfo.info[0].cFlag.write = 0xff; @@ -51,16 +51,16 @@ void setupMacroOp(int mode, const char* opName) { microVU0.prog.IRinfo.info[0].sFlag.lastWrite = 0; microVU0.prog.IRinfo.info[0].mFlag.doFlag = 1; microVU0.prog.IRinfo.info[0].mFlag.write = 0xff; - xMOV(gprF0, ptr32[µVU0.regs->VI[REG_STATUS_FLAG].UL]); + xMOV(gprF0, ptr32[&vu0Regs.VI[REG_STATUS_FLAG].UL]); } } void endMacroOp(int mode) { if (mode & 0x02) { // Q-Reg was Written To - xMOVSS(ptr32[µVU0.regs->VI[REG_Q].UL], xmmPQ); + xMOVSS(ptr32[&vu0Regs.VI[REG_Q].UL], xmmPQ); } if (mode & 0x10) { // Status/Mac Flags were Updated - xMOV(ptr32[µVU0.regs->VI[REG_STATUS_FLAG].UL], gprF0); + xMOV(ptr32[&vu0Regs.VI[REG_STATUS_FLAG].UL], gprF0); } microVU0.regAlloc->flushAll(); microVU0.cop2 = 0; @@ -269,10 +269,10 @@ static void recCFC2() { iFlushCall(FLUSH_EVERYTHING); if (_Rd_ == REG_STATUS_FLAG) { // Normalize Status Flag - xMOV(gprF0, ptr32[µVU0.regs->VI[REG_STATUS_FLAG].UL]); + xMOV(gprF0, ptr32[&vu0Regs.VI[REG_STATUS_FLAG].UL]); mVUallocSFLAGc(eax, gprF0, 0); } - else xMOV(eax, ptr32[µVU0.regs->VI[_Rd_].UL]); + else xMOV(eax, ptr32[&vu0Regs.VI[_Rd_].UL]); // FixMe: Should R-Reg have upper 9 bits 0? xMOV(ptr32[&cpuRegs.GPR.r[_Rt_].UL[0]], eax); @@ -300,14 +300,14 @@ static void recCTC2() { case REG_R: xMOV(eax, ptr32[&cpuRegs.GPR.r[_Rt_].UL[0]]); xOR (eax, 0x3f800000); - xMOV(ptr32[µVU0.regs->VI[REG_R].UL], eax); + xMOV(ptr32[&vu0Regs.VI[REG_R].UL], eax); break; case REG_STATUS_FLAG: if (_Rt_) { // Denormalizes flag into gprF1 mVUallocSFLAGd(&cpuRegs.GPR.r[_Rt_].UL[0], 0); - xMOV(ptr32[µVU0.regs->VI[_Rd_].UL], gprF1); + xMOV(ptr32[&vu0Regs.VI[_Rd_].UL], gprF1); } - else xMOV(ptr32[µVU0.regs->VI[_Rd_].UL], 0); + else xMOV(ptr32[&vu0Regs.VI[_Rd_].UL], 0); break; case REG_CMSAR1: // Execute VU1 Micro SubRoutine if (_Rt_) { @@ -318,7 +318,7 @@ static void recCTC2() { break; case REG_FBRST: if (!_Rt_) { - xMOV(ptr32[µVU0.regs->VI[REG_FBRST].UL], 0); + xMOV(ptr32[&vu0Regs.VI[REG_FBRST].UL], 0); return; } else xMOV(eax, ptr32[&cpuRegs.GPR.r[_Rt_].UL[0]]); @@ -327,12 +327,12 @@ static void recCTC2() { TEST_FBRST_RESET(vu1ResetRegs, 1); xAND(eax, 0x0C0C); - xMOV(ptr32[µVU0.regs->VI[REG_FBRST].UL], eax); + xMOV(ptr32[&vu0Regs.VI[REG_FBRST].UL], eax); break; default: // Executing vu0 block here fixes the intro of Ratchet and Clank // sVU's COP2 has a comment that "Donald Duck" needs this too... - if (_Rd_) _eeMoveGPRtoM((uptr)µVU0.regs->VI[_Rd_].UL, _Rt_); + if (_Rd_) _eeMoveGPRtoM((uptr)&vu0Regs.VI[_Rd_].UL, _Rt_); xMOV(ecx, (uptr)CpuVU0); xCALL(BaseVUmicroCPU::ExecuteBlockJIT); break; @@ -349,7 +349,7 @@ static void recQMFC2() { // FixMe: For some reason this line is needed or else games break: _eeOnWriteReg(_Rt_, 0); - xMOVAPS(xmmT1, ptr128[µVU0.regs->VF[_Rd_]]); + xMOVAPS(xmmT1, ptr128[&vu0Regs.VF[_Rd_]]); xMOVAPS(ptr128[&cpuRegs.GPR.r[_Rt_]], xmmT1); } @@ -361,7 +361,7 @@ static void recQMTC2() { iFlushCall(FLUSH_EVERYTHING); xMOVAPS(xmmT1, ptr128[&cpuRegs.GPR.r[_Rt_]]); - xMOVAPS(ptr128[µVU0.regs->VF[_Rd_]], xmmT1); + xMOVAPS(ptr128[&vu0Regs.VF[_Rd_]], xmmT1); } //------------------------------------------------------------------ diff --git a/pcsx2/x86/microVU_Misc.h b/pcsx2/x86/microVU_Misc.h index d80ae2856b..ef58dbe8ef 100644 --- a/pcsx2/x86/microVU_Misc.h +++ b/pcsx2/x86/microVU_Misc.h @@ -39,6 +39,16 @@ struct mVU_Globals { extern const __aligned(32) mVU_Globals mVUglob; +static const uint _Ibit_ = 1 << 31; +static const uint _Ebit_ = 1 << 30; +static const uint _Mbit_ = 1 << 29; +static const uint _Dbit_ = 1 << 28; +static const uint _Tbit_ = 1 << 27; +static const uint _DTbit_ = 0; //( _Dbit_ | _Tbit_ ) // ToDo: Implement this stuff... + +static const uint divI = 0x1040000; +static const uint divD = 0x2080000; + //------------------------------------------------------------------ // Helper Macros //------------------------------------------------------------------ @@ -71,29 +81,11 @@ extern const __aligned(32) mVU_Globals mVUglob; #define _Fsf_ ((mVU->code >> 21) & 0x03) #define _Ftf_ ((mVU->code >> 23) & 0x03) -#if 0 -#define _Imm5_ (s16)(((mVU->code & 0x400) ? 0xfff0 : 0) | ((mVU->code >> 6) & 0xf)) -#define _Imm11_ (s32)((mVU->code & 0x400) ? (0xfffffc00 | (mVU->code & 0x3ff)) : (mVU->code & 0x3ff)) -#define _Imm12_ (((mVU->code >> 21) & 0x1) << 11) | (mVU->code & 0x7ff) -#define _Imm15_ (((mVU->code >> 10) & 0x7800) | (mVU->code & 0x7ff)) -#define _Imm24_ (u32)(mVU->code & 0xffffff) -#else #define _Imm5_ (mVU->Imm5()) #define _Imm11_ (mVU->Imm11()) #define _Imm12_ (mVU->Imm12()) #define _Imm15_ (mVU->Imm15()) #define _Imm24_ (mVU->Imm24()) -#endif - -#define _Ibit_ (1<<31) -#define _Ebit_ (1<<30) -#define _Mbit_ (1<<29) -#define _Dbit_ (1<<28) -#define _Tbit_ (1<<27) -#define _DTbit_ 0 //( _Dbit_ | _Tbit_ ) // ToDo: Implement this stuff... - -#define divI 0x1040000 -#define divD 0x2080000 #define isCOP2 (mVU->cop2 != 0) #define isVU1 (mVU->index != 0) @@ -161,9 +153,6 @@ typedef Fntype_mVUrecInst* Fnptr_mVUrecInst; //------------------------------------------------------------------ // Define mVUquickSearch //------------------------------------------------------------------ -// FIXME: I changed the below saerchXMM extern from __aligned16 to __pagealigned. -// This *probably* fixes the crashing bugs in linux when using the optimized memcmp. -// Needs testing... --air #ifndef __LINUX__ extern __pagealigned u8 mVUsearchXMM[__pagesize]; typedef u32 (__fastcall *mVUCall)(void*, void*); @@ -205,24 +194,18 @@ typedef u32 (__fastcall *mVUCall)(void*, void*); #define isEvilBlock (mVUpBlock->pState.blockType == 2) #define isBadOrEvil (mVUlow.badBranch || mVUlow.evilBranch) #define xPC ((iPC / 2) * 8) -#define curI ((u32*)mVU->regs->Micro)[iPC] //mVUcurProg.data[iPC] +#define curI ((u32*)mVU->regs().Micro)[iPC] //mVUcurProg.data[iPC] #define setCode() { mVU->code = curI; } -#if 0 -#define incPC(x) { iPC = ((iPC + (x)) & (mVU->progSize-1)); setCode(); } -#define branchAddr ((xPC + 8 + (_Imm11_ * 8)) & (mVU->microMemSize-8)) -#define branchAddrN ((xPC + 16 + (_Imm11_ * 8)) & (mVU->microMemSize-8)) -#else #define incPC(x) (mVU->advancePC(x)) #define branchAddr mVU->getBranchAddr() #define branchAddrN mVU->getBranchAddrN() -#endif #define incPC2(x) { iPC = ((iPC + (x)) & mVU->progMemMask); } #define bSaveAddr (((xPC + 16) & (mVU->microMemSize-8)) / 8) #define shufflePQ (((mVU->p) ? 0xb0 : 0xe0) | ((mVU->q) ? 0x01 : 0x04)) #define cmpOffset(x) ((u8*)&(((u8*)x)[it[0].start])) -#define Rmem &mVU->regs->VI[REG_R].UL +#define Rmem &mVU->regs().VI[REG_R].UL #define aWrap(x, m) ((x > m) ? 0 : x) #define shuffleSS(x) ((x==1)?(0x27):((x==2)?(0xc6):((x==4)?(0xe1):(0xe4)))) #define clampE CHECK_VU_EXTRA_OVERFLOW @@ -262,12 +245,14 @@ typedef u32 (__fastcall *mVUCall)(void*, void*); //------------------------------------------------------------------ // Reg Alloc -#define doRegAlloc 1 // Set to 0 to flush every 64bit Instruction +static const bool doRegAlloc = 1; // Set to 0 to flush every 32bit Instruction // This turns off reg alloc for the most part, but reg alloc will still -// be done between Upper/Lower and within instructions... +// be done within instructions... Also on doSwapOp() regAlloc is needed between +// Lower and Upper instructions, so in this case it flushes after the full +// 64bit instruction (lower and upper) // No Flag Optimizations -#define noFlagOpts 0 // Set to 1 to disable all flag setting optimizations +static const bool noFlagOpts = 0; // Set to 1 to disable all flag setting optimizations // Note: The flag optimizations this disables should all be harmless, so // this option is mainly just for debugging... it effectively forces mVU // to always update Mac and Status Flags (both sticky and non-sticky) whenever @@ -275,7 +260,7 @@ typedef u32 (__fastcall *mVUCall)(void*, void*); // flag instances between blocks... // Constant Propagation -#define CHECK_VU_CONSTPROP 0 // Set to 1 to turn on vi15 const propagation +static const bool doConstProp = 0; // Set to 1 to turn on vi15 const propagation // Enables Constant Propagation for Jumps based on vi15 'link-register' // allowing us to know many indirect jump target addresses. // Makes GoW a lot slower due to extra recompilation time and extra code-gen! @@ -325,4 +310,3 @@ typedef u32 (__fastcall *mVUCall)(void*, void*); extern void mVUmergeRegs(const xmm& dest, const xmm& src, int xyzw, bool modXYZW=false); extern void mVUsaveReg(const xmm& reg, xAddressVoid ptr, int xyzw, bool modXYZW); extern void mVUloadReg(const xmm& reg, xAddressVoid ptr, int xyzw); -extern void mVUloadIreg(const xmm& reg, int xyzw, VURegs* vuRegs); \ No newline at end of file diff --git a/pcsx2/x86/microVU_Misc.inl b/pcsx2/x86/microVU_Misc.inl index 54c36d3a61..b25ec6b76b 100644 --- a/pcsx2/x86/microVU_Misc.inl +++ b/pcsx2/x86/microVU_Misc.inl @@ -213,6 +213,34 @@ void mVUmergeRegs(const xmm& dest, const xmm& src, int xyzw, bool modXYZW) // Micro VU - Misc Functions //------------------------------------------------------------------ +// Backup Volatile Regs (EAX, ECX, EDX, MM0~7, XMM0~7, are all volatile according to 32bit Win/Linux ABI) +__fi void mVUbackupRegs(microVU* mVU, bool toMemory = false) +{ + if (toMemory) { + for(int i = 0; i < 8; i++) { + xMOVAPS(ptr128[&mVU->xmmBackup[i][0]], xmm(i)); + } + } + else { + mVU->regAlloc->flushAll(); // Flush Regalloc + xMOVAPS(ptr128[&mVU->xmmBackup[xmmPQ.Id][0]], xmmPQ); + } +} + +// Restore Volatile Regs +__fi void mVUrestoreRegs(microVU* mVU, bool fromMemory = false) +{ + if (fromMemory) { + for(int i = 0; i < 8; i++) { + xMOVAPS(xmm(i), ptr128[&mVU->xmmBackup[i][0]]); + } + } + else xMOVAPS(xmmPQ, ptr128[&mVU->xmmBackup[xmmPQ.Id][0]]); +} + +// Gets called by mVUaddrFix at execution-time +static void __fastcall mVUwarningRegAccess(u32 prog, u32 pc) { Console.Error("microVU0 Warning: Accessing VU1 Regs! [%04x] [%x]", pc, prog); } + // Transforms the Address in gprReg to valid VU0/VU1 Address __fi void mVUaddrFix(mV, const x32& gprReg) { @@ -221,30 +249,31 @@ __fi void mVUaddrFix(mV, const x32& gprReg) xSHL(gprReg, 4); } else { - xCMP(gprReg, 0x400); - xForwardJL8 jmpA; // if addr >= 0x4000, reads VU1's VF regs and VI regs - xAND(gprReg, 0x43f); // ToDo: theres a potential problem if VU0 overrides VU1's VF0/VI0 regs! + if (IsDevBuild && !isCOP2) mVUbackupRegs(mVU, true); + xTEST(gprReg, 0x400); + xForwardJNZ8 jmpA; // if addr & 0x4000, reads VU1's VF regs and VI regs + xAND(gprReg, 0xff); // if !(addr & 0x4000), wrap around xForwardJump8 jmpB; jmpA.SetTarget(); - xAND(gprReg, 0xff); // if addr < 0x4000, wrap around + if (IsDevBuild && !isCOP2) { // Lets see which games do this! + xPUSH(gprT1); // Note: Kernel does it via COP2 to initialize VU1! + xPUSH(gprT2); // So we don't spam console, we'll only check micro-mode... + xPUSH(gprT3); + xMOV (gprT2, mVU->prog.cur->idx); + xMOV (gprT3, xPC); + xCALL(mVUwarningRegAccess); + xPOP (gprT3); + xPOP (gprT2); + xPOP (gprT1); + } + xAND(gprReg, 0x3f); // ToDo: theres a potential problem if VU0 overrides VU1's VF0/VI0 regs! + xADD(gprReg, (u128*)VU1.VF - (u128*)VU0.Mem); jmpB.SetTarget(); xSHL(gprReg, 4); // multiply by 16 (shift left by 4) + if (IsDevBuild && !isCOP2) mVUrestoreRegs(mVU, true); } } -// Backup Volatile Regs (EAX, ECX, EDX, MM0~7, XMM0~7, are all volatile according to 32bit Win/Linux ABI) -__fi void mVUbackupRegs(microVU* mVU) -{ - mVU->regAlloc->flushAll(); - xMOVAPS(ptr128[mVU->xmmPQb], xmmPQ); -} - -// Restore Volatile Regs -__fi void mVUrestoreRegs(microVU* mVU) -{ - xMOVAPS(xmmPQ, ptr128[mVU->xmmPQb]); -} - //------------------------------------------------------------------ // Micro VU - Custom SSE Instructions //------------------------------------------------------------------ diff --git a/pcsx2/x86/newVif.h b/pcsx2/x86/newVif.h index 9e8a64fa74..930215de27 100644 --- a/pcsx2/x86/newVif.h +++ b/pcsx2/x86/newVif.h @@ -82,7 +82,6 @@ struct nVifStruct { vifStruct* vif; // Vif Struct ptr VIFregisters* vifRegs; // Vif Regs ptr VURegs* VU; // VU Regs ptr - u8* vuMemEnd; // End of VU Memory u32 vuMemLimit; // Use for fast AND u32 bSize; // Size of 'buffer' u32 bPtr; diff --git a/pcsx2/x86/newVif_Dynarec.cpp b/pcsx2/x86/newVif_Dynarec.cpp index 8362ffa78f..eeb73db05c 100644 --- a/pcsx2/x86/newVif_Dynarec.cpp +++ b/pcsx2/x86/newVif_Dynarec.cpp @@ -194,25 +194,26 @@ void VifUnpackSSE_Dynarec::CompileRoutine() { xRET(); } -static __fi u8* dVifsetVUptr(const nVifStruct& v, int cl, int wl, bool isFill) { - u8* endPtr; // Check if we need to wrap around VU memory - u8* ptr = (u8*)(v.VU->Mem + (v.vif->tag.addr & v.vuMemLimit)); - if (!isFill) { // Account for skip-cycles - int skipSize = cl - wl; - int blocks = _vBlock.num / wl; - int skips = (blocks * skipSize + _vBlock.num) * 16; +static __noinline u8* dVifsetVUptr(const nVifStruct& v, int cl, int wl, bool isFill) { + u8* startmem = v.VU->Mem + (v.vif->tag.addr & v.vuMemLimit); + u8* endmem = v.VU->Mem + (v.vuMemLimit+0x10); + uint length = _vBlock.num * 16; - //We must do skips - 1 here else skip calculation adds an extra skip which can overflow - //causing the emu to drop back to the interpreter (do not need to skip on last block write) - Refraction - if(skipSize > 0) skips -= skipSize * 16; - endPtr = ptr + skips; + if (!isFill) { + // Accounting for skipping mode: Subtract the last skip cycle, since the skipped part of the run + // shouldn't count as wrapped data. Otherwise, a trailing skip can cause the emu to drop back + // to the interpreter. -- Refraction (test with MGS3) + + int skipSize = (cl - wl) * 16; + int blocks = _vBlock.num / wl; + length += (blocks-1) * skipSize; } - else endPtr = ptr + (_vBlock.num * 16); - if ( endPtr > v.vuMemEnd ) { - //DevCon.WriteLn("nVif%x - VU Mem Ptr Overflow; falling back to interpreter. Start = %x End = %x num = %x, wl = %x, cl = %x", v.idx, v.vif->tag.addr, v.vif->tag.addr + (_vBlock.num * 16), _vBlock.num, wl, cl); - ptr = NULL; // Fall Back to Interpreters which have wrap-around logic + + if ( (startmem+length) <= endmem ) { + return startmem; } - return ptr; + //Console.WriteLn("nVif%x - VU Mem Ptr Overflow; falling back to interpreter. Start = %x End = %x num = %x, wl = %x, cl = %x", v.idx, v.vif->tag.addr, v.vif->tag.addr + (_vBlock.num * 16), _vBlock.num, wl, cl); + return NULL; // Fall Back to Interpreters which have wrap-around logic } // [TODO] : Finish implementing support for VIF's growable recBlocks buffer. Currently diff --git a/pcsx2/x86/newVif_Unpack.cpp b/pcsx2/x86/newVif_Unpack.cpp index d3c695aa2c..882c579575 100644 --- a/pcsx2/x86/newVif_Unpack.cpp +++ b/pcsx2/x86/newVif_Unpack.cpp @@ -76,11 +76,10 @@ void resetNewVif(int idx) // changed for some reason. nVif[idx].idx = idx; - nVif[idx].VU = idx ? &VU1 : &VU0; - nVif[idx].vif = idx ? &vif1 : &vif0; - nVif[idx].vifRegs = idx ? vif1Regs : vif0Regs; - nVif[idx].vuMemEnd = idx ? ((u8*)(VU1.Mem + 0x4000)) : ((u8*)(VU0.Mem + 0x1000)); + nVif[idx].VU = idx ? &VU1 : &VU0; nVif[idx].vuMemLimit = idx ? 0x3ff0 : 0xff0; + nVif[idx].vif = &GetVifX; + nVif[idx].vifRegs = &vifXRegs; nVif[idx].bSize = 0; memzero(nVif[idx].buffer); diff --git a/pcsx2/x86/newVif_UnpackSSE.cpp b/pcsx2/x86/newVif_UnpackSSE.cpp index 32cc3c1f0a..465cd4e8a5 100644 --- a/pcsx2/x86/newVif_UnpackSSE.cpp +++ b/pcsx2/x86/newVif_UnpackSSE.cpp @@ -166,7 +166,7 @@ void VifUnpackSSE_Base::xUPK_V2_8() const { } void VifUnpackSSE_Base::xUPK_V3_32() const { - xMOV128 (destReg, ptr32[srcIndirect]); + xMOV128 (destReg, ptr128[srcIndirect]); } void VifUnpackSSE_Base::xUPK_V3_16() const { diff --git a/pcsx2/x86/sVU_Lower.cpp b/pcsx2/x86/sVU_Lower.cpp index 2ea05d0986..9e1294964f 100644 --- a/pcsx2/x86/sVU_Lower.cpp +++ b/pcsx2/x86/sVU_Lower.cpp @@ -27,6 +27,8 @@ #include "sVU_Debug.h" #include "sVU_zerorec.h" #include "Gif.h" + +using namespace x86Emitter; //------------------------------------------------------------------ //------------------------------------------------------------------ @@ -678,7 +680,6 @@ void _loadEAX(VURegs *VU, int x86reg, uptr offset, int info) //------------------------------------------------------------------ int recVUTransformAddr(int x86reg, VURegs* VU, int vireg, int imm) { - u8* pjmp[2]; if( x86reg == EAX ) { if (imm) ADD32ItoR(x86reg, imm); } @@ -694,16 +695,17 @@ int recVUTransformAddr(int x86reg, VURegs* VU, int vireg, int imm) else { // VU0 has a somewhat interesting memory mapping: - // if addr >= 0x4000, reads VU1's VF regs and VI regs - // if addr < 0x4000, wrap around at 0x1000 + // if addr & 0x4000, reads VU1's VF regs and VI regs + // otherwise, wrap around at 0x1000 - CMP32ItoR(EAX, 0x400); - pjmp[0] = JL8(0); // if addr >= 0x4000, reads VU1's VF regs and VI regs - AND32ItoR(EAX, 0x43f); - pjmp[1] = JMP8(0); - x86SetJ8(pjmp[0]); - AND32ItoR(EAX, 0xff); // if addr < 0x4000, wrap around - x86SetJ8(pjmp[1]); + xTEST(eax, 0x400); + xForwardJNZ8 vu1regs; // if addr & 0x4000, reads VU1's VF regs and VI regs + xAND(eax, 0xff); // if !(addr & 0x4000), wrap around + xForwardJump8 done; + vu1regs.SetTarget(); + xAND(eax, 0x3f); + xADD(eax, (u128*)VU1.VF - (u128*)VU0.Mem); + done.SetTarget(); SHL32ItoR(EAX, 4); // multiply by 16 (shift left by 4) } @@ -1948,7 +1950,7 @@ void recVUMI_XITOP( VURegs *VU, int info ) if (_It_ == 0) return; //Console.WriteLn("recVUMI_XITOP"); itreg = ALLOCVI(_It_, MODE_WRITE); - MOVZX32M16toR( itreg, (uptr)&VU->vifRegs->itop ); + MOVZX32M16toR( itreg, (uptr)&VU->GetVifRegs().itop ); } //------------------------------------------------------------------ @@ -1962,7 +1964,7 @@ void recVUMI_XTOP( VURegs *VU, int info ) if ( _It_ == 0 ) return; //Console.WriteLn("recVUMI_XTOP"); itreg = ALLOCVI(_It_, MODE_WRITE); - MOVZX32M16toR( itreg, (uptr)&VU->vifRegs->top ); + MOVZX32M16toR( itreg, (uptr)&VU->GetVifRegs().top ); } //------------------------------------------------------------------ @@ -1980,12 +1982,12 @@ void __fastcall VU1XGKICK_MTGSTransfer(u32 *pMem, u32 addr) u32 size; u8* pDest; - if(gifRegs->stat.APATH <= GIF_APATH1 || (gifRegs->stat.APATH == GIF_APATH3 && gifRegs->stat.IP3 == true) && SIGNAL_IMR_Pending == false) + if(gifRegs.stat.APATH <= GIF_APATH1 || (gifRegs.stat.APATH == GIF_APATH3 && gifRegs.stat.IP3 == true) && SIGNAL_IMR_Pending == false) { if(Path1WritePos != 0) { //Flush any pending transfers so things dont go up in the wrong order - while(gifRegs->stat.P1Q == true) gsPath1Interrupt(); + while(gifRegs.stat.P1Q == true) gsPath1Interrupt(); } GetMTGS().PrepDataPacket(GIF_PATH_1, 0x400); size = GIFPath_CopyTag(GIF_PATH_1, (u128*)data, diff); @@ -1993,13 +1995,13 @@ void __fastcall VU1XGKICK_MTGSTransfer(u32 *pMem, u32 addr) if(GSTransferStatus.PTH1 == STOPPED_MODE ) { - gifRegs->stat.OPH = false; - gifRegs->stat.APATH = GIF_APATH_IDLE; + gifRegs.stat.OPH = false; + gifRegs.stat.APATH = GIF_APATH_IDLE; } } else { - //DevCon.Warning("GIF APATH busy %x Holding for later W %x, R %x", gifRegs->stat.APATH, Path1WritePos, Path1ReadPos); + //DevCon.Warning("GIF APATH busy %x Holding for later W %x, R %x", gifRegs.stat.APATH, Path1WritePos, Path1ReadPos); size = GIFPath_ParseTagQuick(GIF_PATH_1, data, diff); pDest = &Path1Buffer[Path1WritePos*16]; @@ -2015,8 +2017,8 @@ void __fastcall VU1XGKICK_MTGSTransfer(u32 *pMem, u32 addr) else { memcpy_qwc(pDest, VU1.Mem + addr, size); } - //if(!gifRegs->stat.P1Q) CPU_INT(28, 128); - gifRegs->stat.P1Q = true; + //if(!gifRegs.stat.P1Q) CPU_INT(28, 128); + gifRegs.stat.P1Q = true; } diff --git a/pcsx2/x86/sVU_Micro.h b/pcsx2/x86/sVU_Micro.h index 22cf3ae413..0b78827d98 100644 --- a/pcsx2/x86/sVU_Micro.h +++ b/pcsx2/x86/sVU_Micro.h @@ -19,20 +19,6 @@ extern u32 vudump; -#define VU0_MEMSIZE 0x1000 -#define VU1_MEMSIZE 0x4000 - -void recResetVU0(); -void recExecuteVU0Block(); -void recClearVU0( u32 Addr, u32 Size ); - -void recVU1Init(); -void recVU1Shutdown(); -void recResetVU1(); -void recExecuteVU1Block(); -void recClearVU1( u32 Addr, u32 Size ); - - u32 GetVIAddr(VURegs * VU, int reg, int read, int info); // returns the correct VI addr void recUpdateFlags(VURegs * VU, int reg, int info); diff --git a/pcsx2/x86/sVU_zerorec.cpp b/pcsx2/x86/sVU_zerorec.cpp index 173c612bd4..5cb0c98c08 100644 --- a/pcsx2/x86/sVU_zerorec.cpp +++ b/pcsx2/x86/sVU_zerorec.cpp @@ -2750,7 +2750,7 @@ static void SuperVURecompile() pxAssert(pchild->blocks.size() == 0); AND32ItoM((uptr)&VU0.VI[ REG_VPU_STAT ].UL, s_vu ? ~0x100 : ~0x001); // E flag - AND32ItoM((uptr)&VU->vifRegs->stat, ~VIF1_STAT_VEW); + AND32ItoM((uptr)&VU->GetVifRegs().stat, ~VIF1_STAT_VEW); MOV32ItoM((uptr)&VU->VI[REG_TPC], pchild->endpc); JMP32((uptr)SuperVUEndProgram - ((uptr)x86Ptr + 5)); @@ -3023,7 +3023,7 @@ void VuBaseBlock::Recompile() _freeXMMregs(); _freeX86regs(); AND32ItoM((uptr)&VU0.VI[ REG_VPU_STAT ].UL, s_vu ? ~0x100 : ~0x001); // E flag - AND32ItoM((uptr)&VU->vifRegs->stat, ~VIF1_STAT_VEW); + AND32ItoM((uptr)&VU->GetVifRegs().stat, ~VIF1_STAT_VEW); if (!branch) MOV32ItoM((uptr)&VU->VI[REG_TPC], endpc); @@ -4680,12 +4680,8 @@ void recSuperVU1::Execute(u32 cycles) // [TODO] Debugging pre- and post- hooks? - if (VU1.VI[REG_TPC].UL >= VU1.maxmicro) { - Console.Error("VU1 memory overflow!!: %x", VU1.VI[REG_TPC].UL); - } - do { // while loop needed since not always will return finished - SuperVUExecuteProgram(VU1.VI[REG_TPC].UL & 0x3fff, 1); + SuperVUExecuteProgram(VU1.VI[REG_TPC].UL & VU1_PROGMASK, 1); } while( VU0.VI[REG_VPU_STAT].UL&0x100 ); } diff --git a/plugins/CDVDiso/src/CDVDisop.cpp b/plugins/CDVDiso/src/CDVDisop.cpp index 42379583a4..8b77d3c6f1 100644 --- a/plugins/CDVDiso/src/CDVDisop.cpp +++ b/plugins/CDVDiso/src/CDVDisop.cpp @@ -170,7 +170,7 @@ EXPORT_C_(s32) CDVDopen(const char* pTitle) iso = isoOpen(IsoFile); if (iso == NULL) { - SysMessage("Error loading %s\n", IsoFile); + SysMessage("Error loading %s\nMake sure the iso file is not mounted in any disk emulation software!", IsoFile); return -1; } diff --git a/plugins/CDVDiso/src/CMakeLists.txt b/plugins/CDVDiso/src/CMakeLists.txt index 25a841ec25..1fb3fe162e 100644 --- a/plugins/CDVDiso/src/CMakeLists.txt +++ b/plugins/CDVDiso/src/CMakeLists.txt @@ -12,7 +12,6 @@ set(Output CDVDiso) set(CommonFlags -fvisibility=hidden -Wall - -fpermissive ) set(OptimizationFlags diff --git a/plugins/CDVDiso/src/Linux/Config.cpp b/plugins/CDVDiso/src/Linux/Config.cpp index 1630943796..92da1ce65f 100644 --- a/plugins/CDVDiso/src/Linux/Config.cpp +++ b/plugins/CDVDiso/src/Linux/Config.cpp @@ -91,7 +91,7 @@ void SysMessage(char *fmt, ...) void OnFile_Ok() { - gchar *File; + const gchar *File; gtk_widget_hide(FileSel); File = gtk_file_selection_get_filename(GTK_FILE_SELECTION(FileSel)); @@ -183,7 +183,7 @@ void SysMessageLoc(char *fmt, ...) void OnOk (GtkButton *button, gpointer user_data) { - char *tmp; + const char *tmp; stop = true; tmp = gtk_entry_get_text(GTK_ENTRY(Edit)); @@ -210,7 +210,7 @@ void OnCancel(GtkButton *button, gpointer user_data) void OnFileSel_Ok() { - gchar *File; + const gchar *File; File = gtk_file_selection_get_filename(GTK_FILE_SELECTION(FileSel)); gtk_entry_set_text(GTK_ENTRY(Edit), File); @@ -278,7 +278,6 @@ EXPORT_C_(void) CDVDconfigure() gtk_widget_show_all(ConfDlg); gtk_main(); - return 0; } void OnAboutOk(GtkMenuItem * menuitem, gpointer userdata) diff --git a/plugins/CDVDiso/src/Linux/Linux.cpp b/plugins/CDVDiso/src/Linux/Linux.cpp index d94105565e..0f9926dde1 100644 --- a/plugins/CDVDiso/src/Linux/Linux.cpp +++ b/plugins/CDVDiso/src/Linux/Linux.cpp @@ -45,7 +45,7 @@ void OnStop(GtkButton *button, gpointer user_data) void UpdZmode() { - char *tmp; + const char *tmp; tmp = gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(Method)->entry)); if (!strcmp(tmp, methods[0])) Zmode = 1; @@ -60,7 +60,7 @@ void OnCompress(GtkButton *button, gpointer user_data) u32 lsn; u8 cdbuff[10*2352]; char Zfile[256]; - char *tmp; + const char *tmp; int ret; isoFile *src; isoFile *dst; @@ -334,7 +334,7 @@ long CDR_getTD(unsigned char track, unsigned char *buffer) // byte 0 - minute // byte 1 - second // byte 2 - frame -char *CDR_readTrack(unsigned char *time) +unsigned char *CDR_readTrack(unsigned char *time) { cr.msf.cdmsf_min0 = time[0]; cr.msf.cdmsf_sec0 = time[1]; @@ -356,7 +356,7 @@ void OnCreate(GtkButton *button, gpointer user_data) unsigned char *buffer; unsigned char bufferz[2352]; unsigned char start[4], end[4]; - char *tmp; + const char *tmp; #ifdef VERBOSE unsigned long count = 0; int i = 0; @@ -495,7 +495,7 @@ void OnCreateZ(GtkButton *button, gpointer user_data) unsigned char bufferz[2352]; unsigned char start[4], end[4]; char table[256]; - char *tmp; + const char *tmp; int b, blocks; #ifdef VERBOSE unsigned long count = 0; @@ -618,7 +618,7 @@ void OnCreateZ(GtkButton *button, gpointer user_data) if (Zmode == 1) compress(Zbuf, &size, cdbuffer, CD_FRAMESIZE_RAW); else - BZ2_bzBuffToBuffCompress(Zbuf, (unsigned int*)&size, cdbuffer, CD_FRAMESIZE_RAW * 10, 1, 0, 30); + BZ2_bzBuffToBuffCompress((char*)Zbuf, (unsigned int*)&size, (char*)cdbuffer, CD_FRAMESIZE_RAW * 10, 1, 0, 30); fwrite(&c, 1, 4, t); if (Zmode == 1) fwrite(&size, 1, 2, t); diff --git a/plugins/CDVDiso/src/libiso.cpp b/plugins/CDVDiso/src/libiso.cpp index 97591936f5..b32d5602a8 100644 --- a/plugins/CDVDiso/src/libiso.cpp +++ b/plugins/CDVDiso/src/libiso.cpp @@ -166,7 +166,7 @@ int _readfile(void *handle, void *dst, int size) return ret; } -int _writefile(void *handle, void *src, int size) +int _writefile(void *handle, const void *src, int size) { DWORD ret; @@ -198,11 +198,12 @@ void *_openfile(const char *filename, int flags) u64 _tellfile(void *handle) { - s64 cursize = ftell(handle); + FILE* fp = (FILE*)handle; + s64 cursize = ftell(fp); if (cursize == -1) { // try 64bit - cursize = ftello64(handle); + cursize = ftello64(fp); if (cursize < -1) { // zero top 32 bits @@ -214,7 +215,7 @@ u64 _tellfile(void *handle) int _seekfile(void *handle, u64 offset, int whence) { - int seekerr = fseeko64(handle, offset, whence); + int seekerr = fseeko64((FILE*)handle, offset, whence); if (seekerr == -1) printf("failed to seek\n"); @@ -223,17 +224,17 @@ int _seekfile(void *handle, u64 offset, int whence) int _readfile(void *handle, void *dst, int size) { - return fread(dst, 1, size, handle); + return fread(dst, 1, size, (FILE*)handle); } -int _writefile(void *handle, void *src, int size) +int _writefile(void *handle, const void *src, int size) { - return fwrite(src, 1, size, handle); + return fwrite(src, 1, size, (FILE*)handle); } void _closefile(void *handle) { - fclose(handle); + fclose((FILE*)handle); } #endif diff --git a/plugins/CDVDiso/src/libiso.h b/plugins/CDVDiso/src/libiso.h index 48249837ba..9b19f878c1 100644 --- a/plugins/CDVDiso/src/libiso.h +++ b/plugins/CDVDiso/src/libiso.h @@ -61,7 +61,7 @@ void *_openfile(const char *filename, int flags); u64 _tellfile(void *handle); int _seekfile(void *handle, u64 offset, int whence); int _readfile(void *handle, void *dst, int size); -int _writefile(void *handle, void *src, int size); +int _writefile(void *handle, const void *src, int size); void _closefile(void *handle); #endif /* __LIBISO_H__ */ diff --git a/plugins/GSdx/GSSettingsDlg.cpp b/plugins/GSdx/GSSettingsDlg.cpp index 174942fad8..5b8bafbc34 100644 --- a/plugins/GSdx/GSSettingsDlg.cpp +++ b/plugins/GSdx/GSSettingsDlg.cpp @@ -219,6 +219,9 @@ bool GSSettingsDlg::OnCommand(HWND hWnd, UINT id, UINT code) theApp.SetConfig("UserHacks_AlphaHack", (int)IsDlgButtonChecked(m_hWnd, IDC_ALPHAHACK)); theApp.SetConfig("UserHacks_HalfPixelOffset", (int)IsDlgButtonChecked(m_hWnd, IDC_OFFSETHACK)); theApp.SetConfig("UserHacks_SkipDraw", (int)SendMessage(GetDlgItem(m_hWnd, IDC_SKIPDRAWHACK), UDM_GETPOS, 0, 0)); + + bool allowHacks = !!theApp.GetConfig("allowHacks", 0); + theApp.SetConfig("allowHacks", allowHacks); } return __super::OnCommand(hWnd, id, code); @@ -228,7 +231,6 @@ void GSSettingsDlg::UpdateControls() { INT_PTR i; - // Simple check only bool allowHacks = !!theApp.GetConfig("allowHacks", 0); if(ComboBoxGetSelData(IDC_RENDERER, i)) @@ -263,12 +265,16 @@ void GSSettingsDlg::UpdateControls() EnableWindow(GetDlgItem(m_hWnd, IDC_MSAAEDIT), hw); EnableWindow(GetDlgItem(m_hWnd, IDC_MSAA), hw); - ShowWindow(GetDlgItem(m_hWnd, IDC_USERHACKS), allowHacks && hw)?SW_SHOW:SW_HIDE; + //ShowWindow(GetDlgItem(m_hWnd, IDC_USERHACKS), allowHacks && hw)?SW_SHOW:SW_HIDE; //Don't disable the "Hacks" frame + ShowWindow(GetDlgItem(m_hWnd, IDC_MSAAEDIT), allowHacks && hw)?SW_SHOW:SW_HIDE; + ShowWindow(GetDlgItem(m_hWnd, IDC_MSAA), allowHacks && hw)?SW_SHOW:SW_HIDE; + ShowWindow(GetDlgItem(m_hWnd, IDC_STATIC_TEXT_HWAA), allowHacks && hw)?SW_SHOW:SW_HIDE; + ShowWindow(GetDlgItem(m_hWnd, IDC_ALPHAHACK), allowHacks && hw)?SW_SHOW:SW_HIDE; ShowWindow(GetDlgItem(m_hWnd, IDC_OFFSETHACK), allowHacks && hw)?SW_SHOW:SW_HIDE; + ShowWindow(GetDlgItem(m_hWnd, IDC_SKIPDRAWHACKEDIT), allowHacks && hw)?SW_SHOW:SW_HIDE; - ShowWindow(GetDlgItem(m_hWnd, IDC_STATIC10), allowHacks && hw)?SW_SHOW:SW_HIDE; ShowWindow(GetDlgItem(m_hWnd, IDC_SKIPDRAWHACK), allowHacks && hw)?SW_SHOW:SW_HIDE; - + ShowWindow(GetDlgItem(m_hWnd, IDC_STATIC_TEXT_SKIPDRAW), allowHacks && hw)?SW_SHOW:SW_HIDE; } } diff --git a/plugins/GSdx/GSdx.rc b/plugins/GSdx/GSdx.rc index b5d9f1abdb..8cde0cbf75 100644 --- a/plugins/GSdx/GSdx.rc +++ b/plugins/GSdx/GSdx.rc @@ -7,8 +7,7 @@ // // Generated from the TEXTINCLUDE 2 resource. // -#include "afxres.h" - +#include "afxres.h" ///////////////////////////////////////////////////////////////////////////// #undef APSTUDIO_READONLY_SYMBOLS @@ -71,7 +70,7 @@ IDB_LOGO10 BITMAP "res\\logo10.bmp" // Dialog // -IDD_CONFIG DIALOGEX 0, 0, 189, 343 +IDD_CONFIG DIALOGEX 0, 0, 189, 351 STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Settings..." FONT 8, "MS Shell Dlg", 400, 0, 0x1 @@ -86,9 +85,9 @@ BEGIN COMBOBOX IDC_INTERLACE,71,86,111,98,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP LTEXT "Aspect Ratio (F6):",IDC_STATIC,7,104,60,8 COMBOBOX IDC_ASPECTRATIO,71,101,111,98,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - DEFPUSHBUTTON "OK",IDOK,43,312,50,14 - PUSHBUTTON "Cancel",IDCANCEL,96,312,50,14 - CONTROL "Windowed",IDC_WINDOWED,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,89,250,93,10 + DEFPUSHBUTTON "OK",IDOK,43,323,50,14 + PUSHBUTTON "Cancel",IDCANCEL,96,323,50,14 + CONTROL "Windowed",IDC_WINDOWED,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,89,231,93,10 LTEXT "D3D internal res:",IDC_STATIC,18,135,55,8 EDITTEXT IDC_RESX_EDIT,82,132,35,13,ES_AUTOHSCROLL | ES_NUMBER CONTROL "",IDC_RESX,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | UDS_NOTHOUSANDS,110,135,11,14 @@ -98,24 +97,24 @@ BEGIN COMBOBOX IDC_UPSCALE_MULTIPLIER,82,147,74,98,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP LTEXT "Or use Scaling:",IDC_STATIC,18,150,49,8 LTEXT "Or use original PS2 resolution :",IDC_STATIC,18,165,99,8 - EDITTEXT IDC_MSAAEDIT,123,182,35,13,ES_AUTOHSCROLL | ES_NUMBER - CONTROL "",IDC_MSAA,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | UDS_NOTHOUSANDS,157,185,11,14 - LTEXT "Experimental HW Anti Aliasing",IDC_STATIC,18,185,96,8 - GROUPBOX "D3D Enhancements (can cause glitches)",IDC_STATIC,7,117,175,86 - LTEXT "SW rend. threads:",IDC_STATIC,7,208,60,8 - EDITTEXT IDC_SWTHREADS_EDIT,71,206,35,13,ES_AUTOHSCROLL | ES_NUMBER - CONTROL "",IDC_SWTHREADS,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | UDS_NOTHOUSANDS,99,209,11,14 - CONTROL "Texture filtering",IDC_FILTER,"Button",BS_AUTO3STATE | WS_TABSTOP,7,222,67,10 - CONTROL "Logarithmic Z",IDC_LOGZ,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,89,223,58,10 - CONTROL "Allow 8-bit textures",IDC_PALTEX,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,236,82,10 - CONTROL "Alpha correction (FBA)",IDC_FBA,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,89,236,93,10 - CONTROL "Edge anti-aliasing",IDC_AA1,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,250,72,10 - CONTROL "Alpha Hack",IDC_ALPHAHACK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,20,275,51,10 - CONTROL "Offset Hack",IDC_OFFSETHACK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,85,275,51,10 - GROUPBOX "Hacks (try to fix bad graphics)",IDC_USERHACKS,13,264,161,43,BS_CENTER - EDITTEXT IDC_SKIPDRAWHACKEDIT,55,287,40,14,ES_AUTOHSCROLL | ES_NUMBER - CONTROL "",IDC_SKIPDRAWHACK,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | UDS_NOTHOUSANDS,94,289,11,14 - LTEXT "SkipDraw:",IDC_STATIC,20,289,33,8 + EDITTEXT IDC_MSAAEDIT,75,258,35,13,ES_AUTOHSCROLL | ES_NUMBER + CONTROL "",IDC_MSAA,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | UDS_NOTHOUSANDS,109,261,11,14 + LTEXT "HW Anti Aliasing",IDC_STATIC_TEXT_HWAA,18,261,53,8 + GROUPBOX "D3D Enhancements (can cause glitches)",IDC_STATIC,7,117,175,66 + LTEXT "SW rend. threads:",IDC_STATIC,7,189,60,8 + EDITTEXT IDC_SWTHREADS_EDIT,71,187,35,13,ES_AUTOHSCROLL | ES_NUMBER + CONTROL "",IDC_SWTHREADS,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | UDS_NOTHOUSANDS,99,190,11,14 + CONTROL "Texture filtering",IDC_FILTER,"Button",BS_AUTO3STATE | WS_TABSTOP,7,203,67,10 + CONTROL "Logarithmic Z",IDC_LOGZ,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,89,204,58,10 + CONTROL "Allow 8-bit textures",IDC_PALTEX,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,217,82,10 + CONTROL "Alpha correction (FBA)",IDC_FBA,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,89,217,93,10 + CONTROL "Edge anti-aliasing",IDC_AA1,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,231,72,10 + CONTROL "Alpha Hack",IDC_ALPHAHACK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,20,279,51,10 + CONTROL "Offset Hack",IDC_OFFSETHACK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,85,279,51,10 + GROUPBOX "Hacks",IDC_USERHACKS,13,244,161,71,BS_CENTER + EDITTEXT IDC_SKIPDRAWHACKEDIT,55,291,40,14,ES_AUTOHSCROLL | ES_NUMBER + CONTROL "",IDC_SKIPDRAWHACK,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | UDS_NOTHOUSANDS,94,293,11,14 + LTEXT "SkipDraw:",IDC_STATIC_TEXT_SKIPDRAW,20,293,33,8 END IDD_CAPTURE DIALOGEX 0, 0, 279, 71 @@ -161,46 +160,48 @@ BEGIN CONTROL "Windowed",IDC_WINDOWED,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,129,157,49,10 END -IDD_CONFIG2 DIALOGEX 0, 0, 187, 314 +IDD_CONFIG2 DIALOGEX 0, 0, 187, 341 STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Settings..." FONT 8, "MS Shell Dlg", 400, 0, 0x1 BEGIN CONTROL 2022,IDC_LOGO10,"Static",SS_BITMAP,6,6,173,42 - DEFPUSHBUTTON "OK",IDOK,41,289,50,14 + DEFPUSHBUTTON "OK",IDOK,41,312,50,14 LTEXT "Renderer:",IDC_STATIC,6,57,34,8 COMBOBOX IDC_RENDERER,70,55,111,118,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "Interlacing (F5):",IDC_STATIC,6,73,53,8 + LTEXT "Interlacing (F5):",IDC_STATIC,6,73,81,8 COMBOBOX IDC_INTERLACE,70,70,111,98,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "D3D internal res:",IDC_STATIC,17,105,55,8 - EDITTEXT IDC_RESX_EDIT,81,102,35,13,ES_AUTOHSCROLL | ES_NUMBER - CONTROL "",IDC_RESX,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | UDS_NOTHOUSANDS,109,105,11,14 - EDITTEXT IDC_RESY_EDIT,119,102,35,13,ES_AUTOHSCROLL | ES_NUMBER - CONTROL "",IDC_RESY,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | UDS_NOTHOUSANDS,143,105,11,14 + LTEXT "D3D internal res:",IDC_STATIC,27,105,55,8 + EDITTEXT IDC_RESX_EDIT,87,102,35,13,ES_AUTOHSCROLL | ES_NUMBER + CONTROL "",IDC_RESX,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | UDS_NOTHOUSANDS,115,105,11,14 + EDITTEXT IDC_RESY_EDIT,125,102,35,13,ES_AUTOHSCROLL | ES_NUMBER + CONTROL "",IDC_RESY,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | UDS_NOTHOUSANDS,149,105,11,14 CONTROL "Native",IDC_NATIVERES,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,122,135,33,10 - LTEXT "SW rend. threads:",IDC_STATIC,6,179,60,8 - EDITTEXT IDC_SWTHREADS_EDIT,70,177,35,13,ES_AUTOHSCROLL | ES_NUMBER - CONTROL "",IDC_SWTHREADS,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | UDS_NOTHOUSANDS,98,180,11,14 - COMBOBOX IDC_UPSCALE_MULTIPLIER,81,117,74,98,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "Or use Scaling:",IDC_STATIC,17,120,49,8 + LTEXT "Rendering threads:",IDC_STATIC,19,214,63,8 + EDITTEXT IDC_SWTHREADS_EDIT,87,212,35,13,ES_AUTOHSCROLL | ES_NUMBER + CONTROL "",IDC_SWTHREADS,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | UDS_NOTHOUSANDS,115,215,11,14 + COMBOBOX IDC_UPSCALE_MULTIPLIER,87,117,74,98,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + LTEXT "Or use Scaling:",IDC_STATIC,33,120,49,8 LTEXT "Or use original PS2 resolution :",IDC_STATIC,17,135,99,8 - CONTROL "Texture filtering",IDC_FILTER,"Button",BS_AUTO3STATE | WS_TABSTOP,6,193,67,10 - CONTROL "Logarithmic Z",IDC_LOGZ,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,88,194,58,10 - CONTROL "Allow 8-bit textures",IDC_PALTEX,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,6,207,82,10 - CONTROL "Alpha correction (FBA)",IDC_FBA,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,88,207,93,10 - CONTROL "Edge anti-aliasing (AA1, sw-mode only)",IDC_AA1,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,6,221,141,10 - PUSHBUTTON "Cancel",IDCANCEL,95,289,50,14 + CONTROL "Edge anti-aliasing (AA1)",IDC_AA1,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,230,93,10 + PUSHBUTTON "Cancel",IDCANCEL,95,312,50,14 CONTROL 2021,IDC_LOGO9,"Static",SS_BITMAP,6,6,175,44 - CONTROL "Alpha Hack",IDC_ALPHAHACK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,20,251,51,10 - CONTROL "Offset Hack",IDC_OFFSETHACK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,85,251,51,10 - GROUPBOX "Hacks (try to fix bad graphics)",IDC_USERHACKS,13,240,161,40,BS_CENTER - EDITTEXT IDC_SKIPDRAWHACKEDIT,55,263,40,14,ES_AUTOHSCROLL | ES_NUMBER - CONTROL "",IDC_SKIPDRAWHACK,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | UDS_NOTHOUSANDS,94,265,11,14 - LTEXT "SkipDraw:",IDC_STATIC,20,265,33,8 - EDITTEXT IDC_MSAAEDIT,122,152,35,13,ES_AUTOHSCROLL | ES_NUMBER - CONTROL "",IDC_MSAA,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | UDS_NOTHOUSANDS,156,155,11,14 - LTEXT "Experimental HW Anti Aliasing",IDC_STATIC,17,155,96,8 - GROUPBOX "D3D Enhancements (can cause glitches)",IDC_STATIC,6,87,175,86 + CONTROL "Alpha Hack",IDC_ALPHAHACK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,275,51,10 + CONTROL "Offset Hack",IDC_OFFSETHACK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,87,275,51,10 + GROUPBOX "Hacks",IDC_USERHACKS,6,250,175,55,BS_CENTER + EDITTEXT IDC_SKIPDRAWHACKEDIT,65,286,40,14,ES_AUTOHSCROLL | ES_NUMBER + CONTROL "",IDC_SKIPDRAWHACK,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | UDS_NOTHOUSANDS,104,288,11,14 + LTEXT "Skipdraw Hack:",IDC_STATIC_TEXT_SKIPDRAW,11,289,50,8 + EDITTEXT IDC_MSAAEDIT,69,260,35,13,ES_AUTOHSCROLL | ES_NUMBER + CONTROL "",IDC_MSAA,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | UDS_NOTHOUSANDS,103,263,11,14 + GROUPBOX "D3D Upscaling (can cause glitches)",IDC_STATIC,6,87,175,64,BS_CENTER + GROUPBOX "Software Mode Settings",IDC_STATIC,6,198,175,50,BS_CENTER + GROUPBOX "Hardware Mode Settings",IDC_STATIC,6,152,175,45,BS_CENTER + CONTROL "Logarithmic Z",IDC_LOGZ,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,88,166,58,10 + CONTROL "Alpha correction (FBA)",IDC_FBA,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,88,179,87,10 + CONTROL "Allow 8-bit textures",IDC_PALTEX,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,6,179,82,10 + CONTROL "Texture filtering",IDC_FILTER,"Button",BS_AUTO3STATE | WS_TABSTOP,6,165,67,10 + LTEXT "HW Anti Aliasing",IDC_STATIC_TEXT_HWAA,11,263,53,8 END @@ -220,7 +221,7 @@ BEGIN VERTGUIDE, 89 VERTGUIDE, 182 TOPMARGIN, 7 - BOTTOMMARGIN, 336 + BOTTOMMARGIN, 344 HORZGUIDE, 49 END @@ -246,8 +247,9 @@ BEGIN BEGIN LEFTMARGIN, 6 RIGHTMARGIN, 181 + VERTGUIDE, 87 TOPMARGIN, 6 - BOTTOMMARGIN, 307 + BOTTOMMARGIN, 334 END END #endif // APSTUDIO_INVOKED @@ -305,8 +307,7 @@ END #include "res/tfx.fx" #include "res/convert.fx" #include "res/interlace.fx" -#include "res/merge.fx" - +#include "res/merge.fx" ///////////////////////////////////////////////////////////////////////////// #endif // not APSTUDIO_INVOKED diff --git a/plugins/GSdx/resource.h b/plugins/GSdx/resource.h index 55e71dbe9d..d6a1ca2f1e 100644 --- a/plugins/GSdx/resource.h +++ b/plugins/GSdx/resource.h @@ -46,11 +46,13 @@ #define IDC_WIDTH 2040 #define IDC_HEIGHT 2041 #define IDC_CONFIGURE 2042 -#define IDC_ALPHAHACK2 2043 -#define IDC_WINDOWED 2044 -#define IDC_USERHACKS 2045 -#define IDC_SKIPDRAWHACKEDIT 2046 -#define IDC_STATIC10 2047 +#define IDC_STATIC_TEXT_HWAA 2043 +#define IDC_ALPHAHACK2 2044 +#define IDC_STATIC_TEXT_SKIPDRAW 2045 +#define IDC_WINDOWED 2046 +#define IDC_USERHACKS 2047 +#define IDC_SKIPDRAWHACKEDIT 2048 +#define IDC_STATIC10 2049 #define IDR_CONVERT_FX 10000 #define IDR_TFX_FX 10001 #define IDR_MERGE_FX 10002 @@ -59,12 +61,12 @@ #define IDD_CONFIG2 10004 // Next default values for new objects -// +// #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS #define _APS_NEXT_RESOURCE_VALUE 10005 #define _APS_NEXT_COMMAND_VALUE 32771 -#define _APS_NEXT_CONTROL_VALUE 2042 +#define _APS_NEXT_CONTROL_VALUE 2050 #define _APS_NEXT_SYMED_VALUE 5000 #endif #endif diff --git a/plugins/PadNull/Pad.cpp b/plugins/PadNull/Pad.cpp index 0bba334a08..c818cbde80 100644 --- a/plugins/PadNull/Pad.cpp +++ b/plugins/PadNull/Pad.cpp @@ -102,7 +102,10 @@ EXPORT_C_(void) PADsetLogDir(const char* dir) s_strLogPath = (dir==NULL) ? "logs/" : dir; // Reload the log file after updated the path - if (padLog) fclose(padLog); + if (padLog) { + fclose(padLog); + padLog = NULL; + } OpenLog(); } @@ -118,7 +121,7 @@ EXPORT_C_(s32) PADinit(u32 flags) EXPORT_C_(void) PADshutdown() { #ifdef PAD_LOG - if (padLog != NULL) + if (padLog) { fclose(padLog); padLog = NULL; diff --git a/plugins/onepad/onepad.cpp b/plugins/onepad/onepad.cpp index 37d023ed51..5ab1bcca02 100644 --- a/plugins/onepad/onepad.cpp +++ b/plugins/onepad/onepad.cpp @@ -44,6 +44,7 @@ u16 status[2]; int pressure; static keyEvent s_event; std::string s_strIniPath("inis/"); +std::string s_strLogPath("logs/"); bool toggleAutoRepeat = true; const u32 version = PS2E_PAD_VERSION; @@ -215,15 +216,29 @@ void __LogToConsole(const char *fmt, ...) void initLogging() { #ifdef PAD_LOG - if (padLog == NULL) - { - padLog = fopen("logs/padLog.txt", "w"); - if (padLog) setvbuf(padLog, NULL, _IONBF, 0); - } + if (padLog) return; + + const std::string LogFile(s_strLogPath + "padLog.txt"); + padLog = fopen(LogFile.c_str(), "w"); + + if (padLog) + setvbuf(padLog, NULL, _IONBF, 0); + PAD_LOG("PADinit\n"); #endif } +void CloseLogging() +{ +#ifdef PAD_LOG + if (padLog) + { + fclose(padLog); + padLog = NULL; + } +#endif +} + void clearPAD() { for (int pad = 0; pad < MAX_SUB_KEYS; pad++) @@ -256,13 +271,7 @@ EXPORT_C_(s32) PADinit(u32 flags) EXPORT_C_(void) PADshutdown() { -#ifdef PAD_LOG - if (padLog != NULL) - { - fclose(padLog); - padLog = NULL; - } -#endif + CloseLogging(); } EXPORT_C_(s32) PADopen(void *pDsp) @@ -285,6 +294,15 @@ EXPORT_C_(void) PADsetSettingsDir(const char* dir) s_strIniPath = (dir==NULL) ? "inis/" : dir; } +EXPORT_C_(void) PADsetLogDir(const char* dir) +{ + // Get the path to the log directory. + s_strLogPath = (dir==NULL) ? "logs/" : dir; + + // Reload the log file after updated the path + CloseLogging(); + initLogging(); +} EXPORT_C_(void) PADclose() { diff --git a/plugins/spu2-x/src/defs.h b/plugins/spu2-x/src/defs.h index 2cc3f2b592..3a7aaf13b6 100644 --- a/plugins/spu2-x/src/defs.h +++ b/plugins/spu2-x/src/defs.h @@ -446,7 +446,7 @@ struct V_Core // uninitialized constructor V_Core() : Index( -1 ), DMAPtr( NULL ) {} V_Core( int idx ); // our badass constructor - virtual ~V_Core() throw(); + ~V_Core() throw(); void Reset( int index ); void Init( int index ); diff --git a/plugins/spu2-x/src/spu2sys.cpp b/plugins/spu2-x/src/spu2sys.cpp index 3053fcb229..4952845210 100644 --- a/plugins/spu2-x/src/spu2sys.cpp +++ b/plugins/spu2-x/src/spu2sys.cpp @@ -168,7 +168,7 @@ void V_Core::Init( int index ) void V_Core::Reset( int index ) { - ConLog( "* SPU2-X: Init SPU2 core %d \n", index ); + ConLog( "* SPU2-X: Reset SPU2 core %d \n", index ); memset( this, 0, sizeof(V_Core) ); const int c = Index = index; diff --git a/plugins/zzogl-pg/opengl/CRC.h b/plugins/zzogl-pg/opengl/CRC.h index a173473ef1..d778602148 100644 --- a/plugins/zzogl-pg/opengl/CRC.h +++ b/plugins/zzogl-pg/opengl/CRC.h @@ -17,7 +17,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ -#ifndef CRC_H_INCLUDED +#ifndef CRC_H_INCLUDED #define CRC_H_INCLUDED // don't change these values! @@ -437,7 +437,7 @@ static const Game_Info crc_game_list[] = // End of game settings from the patch folder. }; -#define GAME_INFO_INDEX (sizeof(crc_game_list)/sizeof(Game_Info)) +#define GAME_INFO_INDEX (sizeof(crc_game_list)/sizeof(Game_Info)) - -#endif // CRC_H_INCLUDED + +#endif // CRC_H_INCLUDED diff --git a/plugins/zzogl-pg/opengl/GLWin.h b/plugins/zzogl-pg/opengl/GLWin.h new file mode 100644 index 0000000000..bca595fe1b --- /dev/null +++ b/plugins/zzogl-pg/opengl/GLWin.h @@ -0,0 +1,73 @@ +/* ZZ Open GL graphics plugin + * Copyright (c)2009-2010 zeydlitz@gmail.com, arcum42@gmail.com + * Based on Zerofrog's ZeroGS KOSMOS (c)2005-2008 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef GLWIN_H_INCLUDED +#define GLWIN_H_INCLUDED + + +#ifdef _WIN32 +#define GL_WIN32_WINDOW +#else +#define GL_X11_WINDOW +#endif + +#undef CreateWindow // Undo Windows.h global namespace pollution + +#ifdef GL_X11_WINDOW +#include +#endif + +class GLWindow +{ + private: +#ifdef GL_X11_WINDOW + Display *glDisplay; + int glScreen; + GLXContext context; + XVisualInfo *vi; + + Window glWindow; + XSetWindowAttributes attr; + + // Original desktop video mode + XF86VidModeModeInfo deskMode; + + bool CreateVisual(); + void GetGLXVersion(); + void GetGLXVidModeVersion(); + void GetWindowSize(); +#endif + bool fullScreen, doubleBuffered; + s32 x, y; + u32 width, height, depth; + + public: + void SwapGLBuffers(); + bool ReleaseContext(); + + bool CreateWindow(void *pDisplay); + void CloseWindow(); + bool DisplayWindow(int _width, int _height); + void SetTitle(char *strtitle); + void ResizeCheck(); +}; + +extern GLWindow GLWin; + +#endif // GLWIN_H_INCLUDED diff --git a/plugins/zzogl-pg/opengl/GLWin32.cpp b/plugins/zzogl-pg/opengl/GLWin32.cpp index 849c8d1db0..e154de0b3d 100644 --- a/plugins/zzogl-pg/opengl/GLWin32.cpp +++ b/plugins/zzogl-pg/opengl/GLWin32.cpp @@ -19,6 +19,7 @@ #include "GS.h" #include "zerogs.h" +#include "GLWin.h" #ifdef GL_WIN32_WINDOW @@ -138,7 +139,7 @@ bool GLWindow::CreateWindow(void *pDisplay) return (pDisplay != NULL); } -bool GLWindow::ReleaseWindow() +bool GLWindow::ReleaseContext() { if (hRC) // Do We Have A Rendering Context? { @@ -305,7 +306,7 @@ void GLWindow::SwapGLBuffers() void GLWindow::SetTitle(char *strtitle) { - SetWindowText(GShwnd, strtitle); + if (!conf.fullscreen()) SetWindowText(GShwnd, strtitle); } void GLWindow::ResizeCheck() diff --git a/plugins/zzogl-pg/opengl/GLWinX11.cpp b/plugins/zzogl-pg/opengl/GLWinX11.cpp index a296d1940c..70b15c6ad6 100644 --- a/plugins/zzogl-pg/opengl/GLWinX11.cpp +++ b/plugins/zzogl-pg/opengl/GLWinX11.cpp @@ -17,10 +17,10 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "GS.h" +#include "Util.h" +#include "GLWin.h" #include "zerogs.h" - #ifdef GL_X11_WINDOW #include @@ -37,19 +37,28 @@ bool GLWindow::CreateWindow(void *pDisplay) return true; } -bool GLWindow::ReleaseWindow() +bool GLWindow::ReleaseContext() { - if (context) + if (context && (glDisplay != NULL)) { if (!glXMakeCurrent(glDisplay, None, NULL)) { ZZLog::Error_Log("Could not release drawing context."); } - + glXDestroyContext(glDisplay, context); context = NULL; } + + return true; +} + +void GLWindow::CloseWindow() +{ + conf.x = x; + conf.y = y; + SaveConfig(); /* switch back to original desktop resolution if we were in fullscreen */ if (glDisplay != NULL) @@ -60,16 +69,7 @@ bool GLWindow::ReleaseWindow() XF86VidModeSetViewPort(glDisplay, glScreen, 0, 0); } } - - return true; -} - -void GLWindow::CloseWindow() -{ - conf.x = x; - conf.y = y; - SaveConfig(); - + if (glDisplay != NULL) { XCloseDisplay(glDisplay); @@ -77,21 +77,8 @@ void GLWindow::CloseWindow() } } -bool GLWindow::DisplayWindow(int _width, int _height) +bool GLWindow::CreateVisual() { - int i; - XVisualInfo *vi; - Colormap cmap; - int dpyWidth, dpyHeight; - int glxMajorVersion, glxMinorVersion; - int vidModeMajorVersion, vidModeMinorVersion; - Atom wmDelete; - Window winDummy; - unsigned int borderDummy; - - x = conf.x; - y = conf.y; - // attributes for a single buffered visual in RGBA format with at least // 8 bits per color and a 24 bit depth buffer int attrListSgl[] = {GLX_RGBA, GLX_RED_SIZE, 8, @@ -111,8 +98,6 @@ bool GLWindow::DisplayWindow(int _width, int _height) None }; - GLWin.fullScreen = (conf.fullscreen()); - /* get an appropriate visual */ vi = glXChooseVisual(glDisplay, glScreen, attrListDbl); @@ -133,32 +118,67 @@ bool GLWindow::DisplayWindow(int _width, int _height) ZZLog::Error_Log("Failed to get buffered Visual!"); return false; } + return true; +} +void GLWindow::GetWindowSize() +{ + unsigned int borderDummy; + Window winDummy; + + XGetGeometry(glDisplay, glWindow, &winDummy, &x, &y, &width, &height, &borderDummy, &depth); + ZZLog::Error_Log("Depth %d", depth); +} + +void GLWindow::GetGLXVersion() +{ + int glxMajorVersion, glxMinorVersion; + glXQueryVersion(glDisplay, &glxMajorVersion, &glxMinorVersion); ZZLog::Error_Log("glX-Version %d.%d", glxMajorVersion, glxMinorVersion); +} +void GLWindow::GetGLXVidModeVersion() +{ + int vidModeMajorVersion, vidModeMinorVersion; + + XF86VidModeQueryVersion(glDisplay, &vidModeMajorVersion, &vidModeMinorVersion); + + ZZLog::Error_Log("XF86VidModeExtension-Version %d.%d.", vidModeMajorVersion, vidModeMinorVersion); +} + +bool GLWindow::DisplayWindow(int _width, int _height) +{ + Colormap cmap; + + x = conf.x; + y = conf.y; + fullScreen = (conf.fullscreen()); + + if (!CreateVisual()) return false; + /* create a GLX context */ context = glXCreateContext(glDisplay, vi, NULL, GL_TRUE); - + /* create a color map */ cmap = XCreateColormap(glDisplay, RootWindow(glDisplay, vi->screen), vi->visual, AllocNone); + attr.colormap = cmap; attr.border_pixel = 0; + attr.event_mask = ExposureMask | KeyPressMask | ButtonPressMask | StructureNotifyMask; - // get a connection - XF86VidModeQueryVersion(glDisplay, &vidModeMajorVersion, &vidModeMinorVersion); - + GetGLXVersion(); + if (fullScreen) { + int dpyWidth, dpyHeight; + int modeNum = 0, bestMode = 0; XF86VidModeModeInfo **modes = NULL; - int modeNum = 0; - int bestMode = 0; - - // set best mode to current - bestMode = 0; - ZZLog::Error_Log("XF86VidModeExtension-Version %d.%d.", vidModeMajorVersion, vidModeMinorVersion); + + GetGLXVidModeVersion(); + XF86VidModeGetAllModeLines(glDisplay, glScreen, &modeNum, &modes); if (modeNum > 0 && modes != NULL) @@ -168,7 +188,7 @@ bool GLWindow::DisplayWindow(int _width, int _height) /* look for mode with requested resolution */ - for (i = 0; i < modeNum; i++) + for (int i = 0; i < modeNum; i++) { if ((modes[i]->hdisplay == _width) && (modes[i]->vdisplay == _height)) { @@ -186,7 +206,6 @@ bool GLWindow::DisplayWindow(int _width, int _height) /* create a fullscreen window */ attr.override_redirect = True; - attr.event_mask = ExposureMask | KeyPressMask | ButtonPressMask | StructureNotifyMask; glWindow = XCreateWindow(glDisplay, RootWindow(glDisplay, vi->screen), 0, 0, dpyWidth, dpyHeight, 0, vi->depth, InputOutput, vi->visual, CWBorderPixel | CWColormap | CWEventMask | CWOverrideRedirect, @@ -209,15 +228,15 @@ bool GLWindow::DisplayWindow(int _width, int _height) if (!fullScreen) { // create a window in window mode - attr.event_mask = ExposureMask | KeyPressMask | ButtonPressMask | StructureNotifyMask; glWindow = XCreateWindow(glDisplay, RootWindow(glDisplay, vi->screen), 0, 0, _width, _height, 0, vi->depth, InputOutput, vi->visual, CWBorderPixel | CWColormap | CWEventMask, &attr); // only set window title and handle wm_delete_events if in windowed mode + Atom wmDelete; wmDelete = XInternAtom(glDisplay, "WM_DELETE_WINDOW", True); - XSetWMProtocols(glDisplay, glWindow, &wmDelete, 1); + XSetStandardProperties(glDisplay, glWindow, "ZZOgl-PG", "ZZOgl-PG", None, NULL, 0, NULL); XMapRaised(glDisplay, glWindow); XMoveWindow(glDisplay, glWindow, x, y); @@ -225,10 +244,8 @@ bool GLWindow::DisplayWindow(int _width, int _height) // connect the glx-context to the window glXMakeCurrent(glDisplay, glWindow, context); - - XGetGeometry(glDisplay, glWindow, &winDummy, &x, &y, &width, &height, &borderDummy, &depth); - - ZZLog::Error_Log("Depth %d", depth); + + GetWindowSize(); if (glXIsDirect(glDisplay, context)) ZZLog::Error_Log("You have Direct Rendering!"); @@ -250,14 +267,17 @@ void GLWindow::SwapGLBuffers() void GLWindow::SetTitle(char *strtitle) { - XTextProperty prop; - memset(&prop, 0, sizeof(prop)); - char* ptitle = strtitle; + if (!conf.fullscreen()) + { + XTextProperty prop; + memset(&prop, 0, sizeof(prop)); + char* ptitle = strtitle; - if (XStringListToTextProperty(&ptitle, 1, &prop)) - XSetWMName(glDisplay, glWindow, &prop); + if (XStringListToTextProperty(&ptitle, 1, &prop)) + XSetWMName(glDisplay, glWindow, &prop); - XFree(prop.value); + XFree(prop.value); + } } void GLWindow::ResizeCheck() @@ -275,6 +295,8 @@ void GLWindow::ResizeCheck() if ((event.xconfigure.x != x) || (event.xconfigure.y != y)) { + // Fixme; x&y occassionally gives values near the top left corner rather then the real values, + // causing the window to change positions when adjusting ZZOgl's settings. x = event.xconfigure.x; y = event.xconfigure.y; } diff --git a/plugins/zzogl-pg/opengl/GS.h b/plugins/zzogl-pg/opengl/GS.h index 0a6989b305..1ecc5c4bba 100644 --- a/plugins/zzogl-pg/opengl/GS.h +++ b/plugins/zzogl-pg/opengl/GS.h @@ -26,51 +26,14 @@ #include "Util.h" #include "GifTransfer.h" -extern float fFPS; - using namespace std; -#ifdef _WIN32 -#define GL_WIN32_WINDOW -#else -#define GL_X11_WINDOW -#endif - -#undef CreateWindow // Undo Windows.h global namespace pollution - -#ifdef GL_X11_WINDOW -#include -#endif +extern float fFPS; #define MEMORY_END 0x00400000 -class GLWindow -{ - - private: -#ifdef GL_X11_WINDOW - Display *glDisplay; - Window glWindow; - int glScreen; - GLXContext context; - XSetWindowAttributes attr; - XF86VidModeModeInfo deskMode; -#endif - bool fullScreen, doubleBuffered; - s32 x, y; - u32 width, height, depth; - - public: - void SwapGLBuffers(); - void SetTitle(char *strtitle); - bool CreateWindow(void *pDisplay); - bool ReleaseWindow(); - void CloseWindow(); - bool DisplayWindow(int _width, int _height); - void ResizeCheck(); -}; - -extern GLWindow GLWin; +extern int g_LastCRC; +extern u8* g_pBasePS2Mem; extern u8* g_pbyGSMemory; @@ -95,195 +58,14 @@ class GSClut u8* get(u32 addr); u8* get_raw(u32 addr); }; + struct Vector_16F { u16 x, y, z, w; }; -REG64_(GSReg, BGCOLOR) - u32 R:8; - u32 G:8; - u32 B:8; - u32 _PAD1:8; - u32 _PAD2:32; -REG_END - -REG64_(GSReg, BUSDIR) - u32 DIR:1; - u32 _PAD1:31; - u32 _PAD2:32; -REG_END - -REG64_(GSReg, CSR) - u32 SIGNAL:1; - u32 FINISH:1; - u32 HSINT:1; - u32 VSINT:1; - u32 EDWINT:1; - u32 ZERO1:1; - u32 ZERO2:1; - u32 _PAD1:1; - u32 FLUSH:1; - u32 RESET:1; - u32 _PAD2:2; - u32 NFIELD:1; - u32 FIELD:1; - u32 FIFO:2; - u32 REV:8; - u32 ID:8; - u32 _PAD3:32; -REG_END - -REG64_(GSReg, DISPFB) // (-1/2) - u32 FBP:9; - u32 FBW:6; - u32 PSM:5; - u32 _PAD:12; - u32 DBX:11; - u32 DBY:11; - u32 _PAD2:10; -REG_END - -REG64_(GSReg, DISPLAY) // (-1/2) - u32 DX:12; - u32 DY:11; - u32 MAGH:4; - u32 MAGV:2; - u32 _PAD:3; - u32 DW:12; - u32 DH:11; - u32 _PAD2:9; -REG_END - -REG64_(GSReg, EXTBUF) - u32 EXBP:14; - u32 EXBW:6; - u32 FBIN:2; - u32 WFFMD:1; - u32 EMODA:2; - u32 EMODC:2; - u32 _PAD1:5; - u32 WDX:11; - u32 WDY:11; - u32 _PAD2:10; -REG_END - -REG64_(GSReg, EXTDATA) - u32 SX:12; - u32 SY:11; - u32 SMPH:4; - u32 SMPV:2; - u32 _PAD1:3; - u32 WW:12; - u32 WH:11; - u32 _PAD2:9; -REG_END - -REG64_(GSReg, EXTWRITE) - u32 WRITE; - u32 _PAD2:32; -REG_END - -REG64_(GSReg, IMR) - u32 _PAD1:8; - u32 SIGMSK:1; - u32 FINISHMSK:1; - u32 HSMSK:1; - u32 VSMSK:1; - u32 EDWMSK:1; - u32 _PAD2:19; - u32 _PAD3:32; -REG_END - -REG64_(GSReg, PMODE) - u32 EN1:1; - u32 EN2:1; - u32 CRTMD:3; - u32 MMOD:1; - u32 AMOD:1; - u32 SLBG:1; - u32 ALP:8; - u32 _PAD:16; - u32 _PAD1:32; -REG_END - -REG64_(GSReg, SIGLBLID) - u32 SIGID:32; - u32 LBLID:32; -REG_END - -REG64_(GSReg, SMODE1) - u32 RC:3; - u32 LC:7; - u32 T1248:2; - u32 SLCK:1; - u32 CMOD:2; - u32 EX:1; - u32 PRST:1; - u32 SINT:1; - u32 XPCK:1; - u32 PCK2:2; - u32 SPML:4; - u32 GCONT:1; - u32 PHS:1; - u32 PVS:1; - u32 PEHS:1; - u32 PEVS:1; - u32 CLKSEL:2; - u32 NVCK:1; - u32 SLCK2:1; - u32 VCKSEL:2; - u32 VHP:1; - u32 _PAD1:27; -REG_END - -REG64_(GSReg, SMODE2) - u32 INT:1; - u32 FFMD:1; - u32 DPMS:2; - u32 _PAD2:28; - u32 _PAD3:32; -REG_END - -REG64_(GSReg, SIGBLID) - u32 SIGID; - u32 LBLID; -REG_END - -extern int g_LastCRC; -extern u8* g_pBasePS2Mem; - -#define PMODE ((GSRegPMODE*)(g_pBasePS2Mem+0x0000)) -#define SMODE1 ((GSRegSMODE1*)(g_pBasePS2Mem+0x0010)) -#define SMODE2 ((GSRegSMODE2*)(g_pBasePS2Mem+0x0020)) -// SRFSH -#define SYNCH1 ((GSRegSYNCH1*)(g_pBasePS2Mem+0x0040)) -#define SYNCH2 ((GSRegSYNCH2*)(g_pBasePS2Mem+0x0050)) -#define SYNCV ((GSRegSYNCV*)(g_pBasePS2Mem+0x0060)) -#define DISPFB1 ((GSRegDISPFB*)(g_pBasePS2Mem+0x0070)) -#define DISPLAY1 ((GSRegDISPLAY*)(g_pBasePS2Mem+0x0080)) -#define DISPFB2 ((GSRegDISPFB*)(g_pBasePS2Mem+0x0090)) -#define DISPLAY2 ((GSRegDISPLAY*)(g_pBasePS2Mem+0x00a0)) -#define EXTBUF ((GSRegEXTBUF*)(g_pBasePS2Mem+0x00b0)) -#define EXTDATA ((GSRegEXTDATA*)(g_pBasePS2Mem+0x00c0)) -#define EXTWRITE ((GSRegEXTWRITE*)(g_pBasePS2Mem+0x00d0)) -#define BGCOLOR ((GSRegBGCOLOR*)(g_pBasePS2Mem+0x00e0)) -#define CSR ((GSRegCSR*)(g_pBasePS2Mem+0x1000)) -#define IMR ((GSRegIMR*)(g_pBasePS2Mem+0x1010)) -#define BUSDIR ((GSRegBUSDIR*)(g_pBasePS2Mem+0x1040)) -#define SIGLBLID ((GSRegSIGBLID*)(g_pBasePS2Mem+0x1080)) - -#define GET_GSFPS (((SMODE1->CMOD&1) ? 50 : 60) / (SMODE2->INT ? 1 : 2)) - -// -// sps2tags.h -// -#define GET_GIF_REG(tag, reg) \ - (((tag).ai32[2 + ((reg) >> 3)] >> (((reg) & 7) << 2)) & 0xf) - // PS2 vertex - struct VertexGPU { // gained from XYZ2, XYZ3, XYZF2, XYZF3, @@ -299,7 +81,7 @@ struct VertexGPU float s, t, q; }; -// Almost same with previous, controlled by prim.fst flagf +// Almost same as previous, controlled by prim.fst flags struct Vertex { @@ -527,10 +309,9 @@ union tex_0_info u32 _u32[2]; u16 _u16[4]; u8 _u8[8]; + tex_0_info(u64 data) { _u64 = data; } - tex_0_info(u32 data) { _u32[0] = data; _u32[1] = 0; } - tex_0_info(u32 data0, u32 data1) { _u32[0] = data0; _u32[1] = data1; } u32 tbw_mult() diff --git a/plugins/zzogl-pg/opengl/GSmain.cpp b/plugins/zzogl-pg/opengl/GSmain.cpp index bddb78d267..7e815ba685 100644 --- a/plugins/zzogl-pg/opengl/GSmain.cpp +++ b/plugins/zzogl-pg/opengl/GSmain.cpp @@ -32,6 +32,7 @@ using namespace std; #include "Mem.h" #include "Regs.h" #include "Profile.h" +#include "GLWin.h" #include "zerogs.h" #include "targets.h" @@ -373,13 +374,11 @@ void CALLBACK GSshutdown() ZZLog::Close(); } - void CALLBACK GSclose() { FUNCLOG ZeroGS::Destroy(1); - GLWin.CloseWindow(); SaveStateFile = NULL; @@ -497,7 +496,7 @@ static __forceinline void SetGSTitle() // ZZLog::Debug_Log("Set profile."); // g_bWriteProfile = 1; // } - if (!(conf.fullscreen())) GLWin.SetTitle(strtitle); + GLWin.SetTitle(strtitle); } void CALLBACK GSvsync(int interlace) diff --git a/plugins/zzogl-pg/opengl/Linux/Linux.cpp b/plugins/zzogl-pg/opengl/Linux/Linux.cpp index d7670e1439..78169e9033 100644 --- a/plugins/zzogl-pg/opengl/Linux/Linux.cpp +++ b/plugins/zzogl-pg/opengl/Linux/Linux.cpp @@ -25,6 +25,7 @@ #include "GS.h" #include "Linux.h" #include "zerogs.h" +#include "GLWin.h" #include @@ -52,7 +53,10 @@ void CALLBACK GSkeyEvent(keyEvent *ev) break; case XK_Escape: - if (conf.fullscreen()) GSclose(); + if (conf.fullscreen()) + { + GSclose(); + } break; case XK_Shift_L: @@ -206,7 +210,6 @@ void OnToggle_advopts(GtkCellRendererToggle *cell, gchar *path, gpointer user_da void DisplayAdvancedDialog() { - int return_value; GtkWidget *dialog; GtkWidget *advanced_frame, *advanced_box; diff --git a/plugins/zzogl-pg/opengl/Linux/zzogl-pg/zzogl-pg.cbp b/plugins/zzogl-pg/opengl/Linux/zzogl-pg/zzogl-pg.cbp index eecb6f67a5..cecbc5e79a 100644 --- a/plugins/zzogl-pg/opengl/Linux/zzogl-pg/zzogl-pg.cbp +++ b/plugins/zzogl-pg/opengl/Linux/zzogl-pg/zzogl-pg.cbp @@ -98,6 +98,7 @@ + diff --git a/plugins/zzogl-pg/opengl/Regs.cpp b/plugins/zzogl-pg/opengl/Regs.cpp index b096d47a7a..ed470969b4 100644 --- a/plugins/zzogl-pg/opengl/Regs.cpp +++ b/plugins/zzogl-pg/opengl/Regs.cpp @@ -238,7 +238,7 @@ void tex0Write(int i, const u32 *data) } // check if csa is the same!! (ffx bisaid island, grass) - else if ((data[1] & 0x1f780000) != (ZeroGS::vb[i].uCurTex0Data[1] & 0x1f780000)) + else if ((data[1] & CPSM_CSA_BITMASK) != (ZeroGS::vb[i].uCurTex0Data[1] & CPSM_CSA_BITMASK)) { ZeroGS::Flush(i); // flush any previous entries } diff --git a/plugins/zzogl-pg/opengl/Regs.h b/plugins/zzogl-pg/opengl/Regs.h index 4c881e8b02..a3578b635d 100644 --- a/plugins/zzogl-pg/opengl/Regs.h +++ b/plugins/zzogl-pg/opengl/Regs.h @@ -764,6 +764,185 @@ REG128_SET(GIFPackedReg) GIFPackedNOP NOP; REG_SET_END + +REG64_(GSReg, BGCOLOR) + u32 R:8; + u32 G:8; + u32 B:8; + u32 _PAD1:8; + u32 _PAD2:32; +REG_END + +REG64_(GSReg, BUSDIR) + u32 DIR:1; + u32 _PAD1:31; + u32 _PAD2:32; +REG_END + +REG64_(GSReg, CSR) + u32 SIGNAL:1; + u32 FINISH:1; + u32 HSINT:1; + u32 VSINT:1; + u32 EDWINT:1; + u32 ZERO1:1; + u32 ZERO2:1; + u32 _PAD1:1; + u32 FLUSH:1; + u32 RESET:1; + u32 _PAD2:2; + u32 NFIELD:1; + u32 FIELD:1; + u32 FIFO:2; + u32 REV:8; + u32 ID:8; + u32 _PAD3:32; +REG_END + +REG64_(GSReg, DISPFB) // (-1/2) + u32 FBP:9; + u32 FBW:6; + u32 PSM:5; + u32 _PAD:12; + u32 DBX:11; + u32 DBY:11; + u32 _PAD2:10; +REG_END + +REG64_(GSReg, DISPLAY) // (-1/2) + u32 DX:12; + u32 DY:11; + u32 MAGH:4; + u32 MAGV:2; + u32 _PAD:3; + u32 DW:12; + u32 DH:11; + u32 _PAD2:9; +REG_END + +REG64_(GSReg, EXTBUF) + u32 EXBP:14; + u32 EXBW:6; + u32 FBIN:2; + u32 WFFMD:1; + u32 EMODA:2; + u32 EMODC:2; + u32 _PAD1:5; + u32 WDX:11; + u32 WDY:11; + u32 _PAD2:10; +REG_END + +REG64_(GSReg, EXTDATA) + u32 SX:12; + u32 SY:11; + u32 SMPH:4; + u32 SMPV:2; + u32 _PAD1:3; + u32 WW:12; + u32 WH:11; + u32 _PAD2:9; +REG_END + +REG64_(GSReg, EXTWRITE) + u32 WRITE; + u32 _PAD2:32; +REG_END + +REG64_(GSReg, IMR) + u32 _PAD1:8; + u32 SIGMSK:1; + u32 FINISHMSK:1; + u32 HSMSK:1; + u32 VSMSK:1; + u32 EDWMSK:1; + u32 _PAD2:19; + u32 _PAD3:32; +REG_END + +REG64_(GSReg, PMODE) + u32 EN1:1; + u32 EN2:1; + u32 CRTMD:3; + u32 MMOD:1; + u32 AMOD:1; + u32 SLBG:1; + u32 ALP:8; + u32 _PAD:16; + u32 _PAD1:32; +REG_END + +REG64_(GSReg, SIGLBLID) + u32 SIGID:32; + u32 LBLID:32; +REG_END + +REG64_(GSReg, SMODE1) + u32 RC:3; + u32 LC:7; + u32 T1248:2; + u32 SLCK:1; + u32 CMOD:2; + u32 EX:1; + u32 PRST:1; + u32 SINT:1; + u32 XPCK:1; + u32 PCK2:2; + u32 SPML:4; + u32 GCONT:1; + u32 PHS:1; + u32 PVS:1; + u32 PEHS:1; + u32 PEVS:1; + u32 CLKSEL:2; + u32 NVCK:1; + u32 SLCK2:1; + u32 VCKSEL:2; + u32 VHP:1; + u32 _PAD1:27; +REG_END + +REG64_(GSReg, SMODE2) + u32 INT:1; + u32 FFMD:1; + u32 DPMS:2; + u32 _PAD2:28; + u32 _PAD3:32; +REG_END + +REG64_(GSReg, SIGBLID) + u32 SIGID; + u32 LBLID; +REG_END + +#define PMODE ((GSRegPMODE*)(g_pBasePS2Mem+0x0000)) +#define SMODE1 ((GSRegSMODE1*)(g_pBasePS2Mem+0x0010)) +#define SMODE2 ((GSRegSMODE2*)(g_pBasePS2Mem+0x0020)) +// SRFSH +#define SYNCH1 ((GSRegSYNCH1*)(g_pBasePS2Mem+0x0040)) +#define SYNCH2 ((GSRegSYNCH2*)(g_pBasePS2Mem+0x0050)) +#define SYNCV ((GSRegSYNCV*)(g_pBasePS2Mem+0x0060)) +#define DISPFB1 ((GSRegDISPFB*)(g_pBasePS2Mem+0x0070)) +#define DISPLAY1 ((GSRegDISPLAY*)(g_pBasePS2Mem+0x0080)) +#define DISPFB2 ((GSRegDISPFB*)(g_pBasePS2Mem+0x0090)) +#define DISPLAY2 ((GSRegDISPLAY*)(g_pBasePS2Mem+0x00a0)) +#define EXTBUF ((GSRegEXTBUF*)(g_pBasePS2Mem+0x00b0)) +#define EXTDATA ((GSRegEXTDATA*)(g_pBasePS2Mem+0x00c0)) +#define EXTWRITE ((GSRegEXTWRITE*)(g_pBasePS2Mem+0x00d0)) +#define BGCOLOR ((GSRegBGCOLOR*)(g_pBasePS2Mem+0x00e0)) +#define CSR ((GSRegCSR*)(g_pBasePS2Mem+0x1000)) +#define IMR ((GSRegIMR*)(g_pBasePS2Mem+0x1010)) +#define BUSDIR ((GSRegBUSDIR*)(g_pBasePS2Mem+0x1040)) +#define SIGLBLID ((GSRegSIGBLID*)(g_pBasePS2Mem+0x1080)) + +// +// sps2tags.h +// +#define GET_GIF_REG(tag, reg) \ + (((tag).ai32[2 + ((reg) >> 3)] >> (((reg) & 7) << 2)) & 0xf) + +#define GET_GSFPS (((SMODE1->CMOD&1) ? 50 : 60) / (SMODE2->INT ? 1 : 2)) + extern void WriteTempRegs(); extern void SetFrameSkip(bool skip); extern void ResetRegs(); diff --git a/plugins/zzogl-pg/opengl/ZZKeyboard.cpp b/plugins/zzogl-pg/opengl/ZZKeyboard.cpp index 1066fcc998..b858e75954 100644 --- a/plugins/zzogl-pg/opengl/ZZKeyboard.cpp +++ b/plugins/zzogl-pg/opengl/ZZKeyboard.cpp @@ -23,6 +23,7 @@ #include "GS.h" #include "ZeroGSShaders/zerogsshaders.h" #include "Profile.h" +#include "GLWin.h" extern int CurrentSavestate, g_GSMultiThreaded, g_nPixelShaderVer; extern char *libraryName; @@ -355,7 +356,7 @@ void ProcessMessages() // check resizing GLWin.ResizeCheck(); - if (THR_KeyEvent) // This values was passed from GSKeyEvents which could be in another thread + if (THR_KeyEvent) // This value was passed from GSKeyEvents which could be in another thread { int my_KeyEvent = THR_KeyEvent; bool my_bShift = THR_bShift; diff --git a/plugins/zzogl-pg/opengl/ZZoglCRTC.cpp b/plugins/zzogl-pg/opengl/ZZoglCRTC.cpp index 9ff971c9ca..aa3c966340 100644 --- a/plugins/zzogl-pg/opengl/ZZoglCRTC.cpp +++ b/plugins/zzogl-pg/opengl/ZZoglCRTC.cpp @@ -22,6 +22,7 @@ //------------------ Includes #include "ZZoglCRTC.h" +#include "GLWin.h" using namespace ZeroGS; diff --git a/plugins/zzogl-pg/opengl/ZZoglCreate.cpp b/plugins/zzogl-pg/opengl/ZZoglCreate.cpp index 571fdd442b..4c29a61741 100644 --- a/plugins/zzogl-pg/opengl/ZZoglCreate.cpp +++ b/plugins/zzogl-pg/opengl/ZZoglCreate.cpp @@ -23,6 +23,7 @@ #include "GS.h" #include "Mem.h" #include "zerogs.h" +#include "GLWin.h" #include "ZeroGSShaders/zerogsshaders.h" #include "targets.h" @@ -948,20 +949,29 @@ void ZeroGS::Destroy(bool bD3D) } g_nCurVBOIndex = 0; - - for (int i = 0; i < ARRAY_SIZE(pvs); ++i) + + if (pvs != NULL) { - SAFE_RELEASE_PROG(pvs[i]); + for (int i = 0; i < ARRAY_SIZE(pvs); ++i) + { + SAFE_RELEASE_PROG(pvs[i]); + } } - for (int i = 0; i < ARRAY_SIZE(ppsRegular); ++i) + if (ppsRegular != NULL) { - SAFE_RELEASE_PROG(ppsRegular[i].prog); + for (int i = 0; i < ARRAY_SIZE(ppsRegular); ++i) + { + SAFE_RELEASE_PROG(ppsRegular[i].prog); + } } - for (int i = 0; i < ARRAY_SIZE(ppsTexture); ++i) + if (ppsTexture != NULL) { - SAFE_RELEASE_PROG(ppsTexture[i].prog); + for (int i = 0; i < ARRAY_SIZE(ppsTexture); ++i) + { + SAFE_RELEASE_PROG(ppsTexture[i].prog); + } } SAFE_RELEASE_PROG(pvsBitBlt.prog); @@ -979,7 +989,7 @@ void ZeroGS::Destroy(bool bD3D) SAFE_DELETE(font_p); - GLWin.ReleaseWindow(); + GLWin.ReleaseContext(); mapGLExtensions.clear(); } diff --git a/plugins/zzogl-pg/opengl/zerogs.cpp b/plugins/zzogl-pg/opengl/zerogs.cpp index 27831a58df..a14fbf101e 100644 --- a/plugins/zzogl-pg/opengl/zerogs.cpp +++ b/plugins/zzogl-pg/opengl/zerogs.cpp @@ -31,6 +31,7 @@ #include "zerogs.h" #include "zpipe.h" #include "targets.h" +#include "GLWin.h" //----------------------- Defines