GregMiscellaneous: sync from trunk (3679:3727)

git-svn-id: http://pcsx2.googlecode.com/svn/branches/GregMiscellaneous@3729 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
gregory.hainaut@gmail.com 2010-09-05 15:33:08 +00:00
commit 5e8f776adb
146 changed files with 6586 additions and 8521 deletions

View File

@ -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

View File

@ -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;

View File

@ -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 );

View File

@ -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;

View File

@ -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;
}

View File

@ -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;
}

View File

@ -47,7 +47,7 @@ class FastFormatBuffers
protected:
typedef SafeAlignedArray<CharType,16> 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<char>& 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;
}

View File

@ -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<Mutex*>(locker);
if( !m_lock ) return;

View File

@ -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.

View File

@ -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 <gregory.hainaut@gmail.com> Sat, 24 Apr 2010 23:11:10 +0200

View File

@ -2,6 +2,7 @@ Source: pcsx2.snapshot
Section: games
Priority: optional
Maintainer: Gregory Hainaut <gregory.hainaut@gmail.com>
# 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.

View File

@ -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.

View File

@ -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:

View File

@ -16,16 +16,22 @@
######################################################################
# 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

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -1 +1,3 @@
bin/pcsx2 usr/games
debian/pcsx2.desktop usr/share/applications
debian/pcsx2.xpm usr/share/pixmaps

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -16,10 +16,6 @@
#ifndef __CDVD_ISO_READER_H__
#define __CDVD_ISO_READER_H__
#ifdef _MSC_VER
#pragma warning(disable:4018)
#endif
#include <stdio.h>
#include "IopCommon.h"

View File

@ -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;
}

View File

@ -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 <stdio.h>

View File

@ -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

View File

@ -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

View File

@ -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 */

View File

@ -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
{

View File

@ -15,11 +15,11 @@
#include "PrecompiledHeader.h"
#include "Common.h"
#include <time.h>
#include <cmath>
#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 );

View File

@ -13,8 +13,7 @@
* If not, see <http://www.gnu.org/licenses/>.
*/
#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__ */

View File

@ -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

View File

@ -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 );

View File

@ -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

View File

@ -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();
}
}

View File

@ -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();
}

View File

@ -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);

View File

@ -277,7 +277,7 @@ struct GIFregisters
u32 padding9[3];
};
#define gifRegs ((GIFregisters*)(eeMem->HW+0x3000))
static GIFregisters& gifRegs = (GIFregisters&)eeHw[0x3000];
extern tGSTransferStatus GSTransferStatus;

View File

@ -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<Ps2MemSize::Hardware>( eeMem->HW );
//memset(eeMem->HW+0x2000, 0, 0x0000e000);
memzero_ptr<Ps2MemSize::Hardware>( 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;
}

View File

@ -13,28 +13,84 @@
* If not, see <http://www.gnu.org/licenses/>.
*/
#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__ */

View File

@ -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.
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;
}
// Current assumption: Reads 128 bits and discards the unused portion.
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;
DevCon.WriteLn( Color_Cyan, "Reading 32-bit FIFO data" );
u128 out128;
_hwRead128<page>(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<page,false>(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<page, false>(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<page, false>(mem & ~0x03);
return ((u16*)&ret32)[(mem>>1) & 0x01];
}
template< uint page >
mem16_t __fastcall hwRead16(u32 mem)
{
u16 ret16 = _hwRead16<page>(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) );
case 0x02:
*result = ipuRead64(mem);
return;
// 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 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.
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;
}
// Current assumption: Reads 128 bits and discards the unused portion.
HW_LOG("Hardware Read32 at 0x%x (%ls %s), value=0x%x", mem, ChcrName(mem & ~0xff), regName, psHu32(mem) );
uint wordpart = (mem >> 3) & 0x1;
DevCon.WriteLn( Color_Cyan, "Reading 64-bit FIFO data (%s 64 bits discarded)", wordpart ? "upper" : "lower" );
u128 out128;
_hwRead128<page>(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<page,false>( 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<page>( 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<page>( 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<page>( 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<pageidx>(u32 mem); \
template mem16_t __fastcall hwRead16<pageidx>(u32 mem); \
template mem32_t __fastcall hwRead32<pageidx>(u32 mem); \
template void __fastcall hwRead64<pageidx>(u32 mem, mem64_t* result ); \
template void __fastcall hwRead128<pageidx>(u32 mem, mem128_t* result ); \
template mem32_t __fastcall _hwRead32<pageidx, false>(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);

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -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);

View File

@ -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);
}

509
pcsx2/IPU/IPUdma.cpp Normal file
View File

@ -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 <http://www.gnu.org/licenses/>.
*/
#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);
}

93
pcsx2/IPU/IPUdma.h Normal file
View File

@ -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 <http://www.gnu.org/licenses/>.
*/
#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();

View File

@ -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;
}

View File

@ -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)

View File

@ -137,6 +137,60 @@
<Add library="$(SvnRootDir)/deps/release/libUtilities.a" />
</Linker>
</Target>
<Target title="Devel-Debug">
<Option platforms="Windows;Unix;" />
<Option output="$(SvnRootDir)/bin/pcsx2-deb" prefix_auto="1" extension_auto="1" />
<Option working_dir="$(SvnRootDir)/bin/" />
<Option object_output="./.objs/devel" />
<Option external_deps="../../tools/bin/bin2cpp;" />
<Option type="0" />
<Option compiler="gcc" />
<Compiler>
<Add option="-fdefer-pop" />
<Add option="-fcprop-registers" />
<Add option="-fif-conversion" />
<Add option="-fif-conversion2" />
<Add option="-ftree-ccp" />
<Add option="-ftree-dce" />
<Add option="-ftree-dominator-opts" />
<Add option="-ftree-ter" />
<Add option="-ftree-lrs" />
<Add option="-ftree-sra" />
<Add option="-ftree-copyrename" />
<Add option="-ftree-fre" />
<Add option="-ftree-ch" />
<Add option="-funit-at-a-time" />
<Add option="-fmerge-constants" />
<Add option="-fthread-jumps" />
<Add option="-fcrossjumping" />
<Add option="-foptimize-sibling-calls" />
<Add option="-fcse-follow-jumps" />
<Add option="-fcse-skip-blocks" />
<Add option="-fgcse -fgcse-lm" />
<Add option="-frerun-cse-after-loop" />
<Add option="-fcaller-saves" />
<Add option="-fpeephole2" />
<Add option="-fsched-interblock -fsched-spec" />
<Add option="-fregmove" />
<Add option="-fstrict-overflow" />
<Add option="-fdelete-null-pointer-checks" />
<Add option="-freorder-blocks -freorder-functions" />
<Add option="-falign-functions -falign-jumps" />
<Add option="-falign-loops -falign-labels" />
<Add option="-ftree-vrp" />
<Add option="-ftree-pre" />
<Add option="-DPCSX2_DEVBUILD" />
<Add option="-DPCSX2_DEVEL" />
<Add option="-DNDEBUG" />
</Compiler>
<ResourceCompiler>
<Add directory="$(ProjectRootDir)/gui" />
</ResourceCompiler>
<Linker>
<Add library="$(SvnRootDir)/deps/devel/libx86emitter.a" />
<Add library="$(SvnRootDir)/deps/devel/libUtilities.a" />
</Linker>
</Target>
<Environment>
<Variable name="SvnRootDir" value="../../" />
<Variable name="ProjectRootDir" value='&quot;$(SvnRootDir)/pcsx2/&quot;' />
@ -240,6 +294,8 @@
<Unit filename="../IPU/IPU.h" />
<Unit filename="../IPU/IPU_Fifo.cpp" />
<Unit filename="../IPU/IPU_Fifo.h" />
<Unit filename="../IPU/IPUdma.cpp" />
<Unit filename="../IPU/IPUdma.h" />
<Unit filename="../IPU/mpeg2lib/Idct.cpp" />
<Unit filename="../IPU/mpeg2lib/Mpeg.cpp" />
<Unit filename="../IPU/mpeg2lib/Mpeg.h" />
@ -522,9 +578,11 @@
<Unit filename="../ps2/BiosTools.cpp" />
<Unit filename="../ps2/BiosTools.h" />
<Unit filename="../ps2/GIFpath.cpp" />
<Unit filename="../ps2/HwInternal.h" />
<Unit filename="../ps2/Iop/IopHwRead.cpp" />
<Unit filename="../ps2/Iop/IopHwWrite.cpp" />
<Unit filename="../ps2/Iop/IopHw_Internal.h" />
<Unit filename="../ps2/LegacyDmac.cpp" />
<Unit filename="../vtlb.cpp" />
<Unit filename="../vtlb.h" />
<Unit filename="../x86/BaseblockEx.cpp" />

View File

@ -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() {

View File

@ -35,15 +35,14 @@ BIOS
*/
#include "PrecompiledHeader.h"
#include "IopCommon.h"
#pragma warning(disable:4799) // No EMMS at end of function
#include <wx/file.h>
#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<int p>
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<int p>
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.
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
);
#define hwHandlerTmpl(page) \
hwRead8<page>, hwRead16<page>, hwRead32<page>, hwRead64<page>, hwRead128<page>, \
hwWrite8<page>, hwWrite16<page>,hwWrite32<page>,hwWrite64<page>,hwWrite128<page>
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();
//////////////////////////////////////////////////////////////////////

View File

@ -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<mem8_t>
#define memRead16 vtlb_memRead<mem16_t>
#define memRead32 vtlb_memRead<mem32_t>
#define memRead64 vtlb_memRead64
#define memRead128 vtlb_memRead128
#define memWrite8 vtlb_memWrite<mem8_t>
#define memWrite16 vtlb_memWrite<mem16_t>
#define memWrite32 vtlb_memWrite<mem32_t>
#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);

View File

@ -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;

View File

@ -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

View File

@ -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;

View File

@ -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);

View File

@ -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);
}

View File

@ -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();

View File

@ -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();

View File

@ -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");
}

View File

@ -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
{

View File

@ -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;

View File

@ -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;

View File

@ -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);

View File

@ -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); }

View File

@ -20,11 +20,10 @@
#include "PrecompiledHeader.h"
#include "Common.h"
#include "VUmicro.h"
#include <cmath>
#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); }

View File

@ -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");

View File

@ -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); }

View File

@ -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();
}
}

File diff suppressed because it is too large Load Diff

View File

@ -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()

File diff suppressed because it is too large Load Diff

View File

@ -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);

View File

@ -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);

View File

@ -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 <int idx>
#define GetVifX (idx ? (vif1) : (vif0))

View File

@ -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.

View File

@ -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);

View File

@ -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;
}

View File

@ -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<int idx> __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<int idx> __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<int idx> __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<idx>(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<idx>(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;
}

View File

@ -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);

View File

@ -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;
}

View File

@ -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);

View File

@ -26,12 +26,12 @@ template<const u32 VIFdmanum> 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;
}

View File

@ -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() );

View File

@ -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;
}
}

79
pcsx2/ps2/HwInternal.h Normal file
View File

@ -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 <http://www.gnu.org/licenses/>.
*/
#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<uint page> extern void __fastcall hwWrite8 (u32 mem, u8 value);
template<uint page> extern void __fastcall hwWrite16 (u32 mem, u16 value);
template<uint page> extern void __fastcall hwWrite32 (u32 mem, mem32_t value);
template<uint page> extern void __fastcall hwWrite64 (u32 mem, const mem64_t* srcval);
template<uint page> 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);

View File

@ -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<mem8_t>( addr, ret, "Read" );
IopHwTraceLog<mem8_t>( addr, ret, true );
return ret;
}
@ -89,7 +89,7 @@ mem8_t __fastcall iopHwRead8_Page3( u32 addr )
else
ret = psxHu8( addr );
IopHwTraceLog<mem8_t>( addr, ret, "Read" );
IopHwTraceLog<mem8_t>( addr, ret, true );
return ret;
}
@ -107,7 +107,7 @@ mem8_t __fastcall iopHwRead8_Page8( u32 addr )
else
ret = psxHu8( addr );
IopHwTraceLog<mem8_t>( addr, ret, "Read" );
IopHwTraceLog<mem8_t>( 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<T>( addr, ret, "Read" );
IopHwTraceLog<T>( 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<mem16_t>( addr, ret, "Read" );
IopHwTraceLog<mem16_t>( 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<mem16_t>( addr, ret, "Read" );
IopHwTraceLog<mem16_t>( 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<mem32_t>( addr, ret, "Read" );
IopHwTraceLog<mem32_t>( addr, ret, true );
return ret;
}
@ -437,7 +437,7 @@ mem32_t __fastcall iopHwRead32_Page8( u32 addr )
}
else ret = psxHu32(addr);
IopHwTraceLog<mem32_t>( addr, ret, "Read" );
IopHwTraceLog<mem32_t>( addr, ret, true );
return ret;
}

View File

@ -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<T>( addr, val, "Write" );
IopHwTraceLog<T>( 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<T>( addr, ret, "Read" );
IopHwTraceLog<T>( 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<mem8_t>( addr, val, "Write" );
IopHwTraceLog<mem8_t>( 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<mem8_t>( addr, val, "Write" );
IopHwTraceLog<mem8_t>( 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<mem8_t>( addr, val, "Write" );
IopHwTraceLog<mem8_t>( 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<T>( addr, val, "Write" );
IopHwTraceLog<T>( 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<mem16_t>( addr, val, "Write" );
IopHwTraceLog<mem16_t>( 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<mem16_t>( addr, val, "Write" );
IopHwTraceLog<mem16_t>( 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<mem32_t>( addr, val, "Write" );
IopHwTraceLog<mem32_t>( 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<mem32_t>( addr, val, "Write" );
IopHwTraceLog<mem32_t>( addr, val, false );
}
}

View File

@ -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<T>( 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<T>( 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() );
}
} };

437
pcsx2/ps2/LegacyDmac.cpp Normal file
View File

@ -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 <http://www.gnu.org/licenses/>.
*/
#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 );

268
pcsx2/ps2/eeHwTraceLog.inl Normal file
View File

@ -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 <http://www.gnu.org/licenses/>.
*/
#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<T>( 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() );
}

View File

@ -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<mem8_t>(u32 mem);
template mem16_t vtlb_memRead<mem16_t>(u32 mem);
template mem32_t vtlb_memRead<mem32_t>(u32 mem);

View File

@ -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);

View File

@ -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;
}

View File

@ -513,6 +513,10 @@
RelativePath="..\..\Dmac.h"
>
</File>
<File
RelativePath="..\..\ps2\eeHwTraceLog.inl"
>
</File>
<File
RelativePath="..\..\FiFo.cpp"
>
@ -529,6 +533,10 @@
RelativePath="..\..\Hw.h"
>
</File>
<File
RelativePath="..\..\ps2\HwInternal.h"
>
</File>
<File
RelativePath="..\..\HwRead.cpp"
>
@ -749,6 +757,10 @@
<Filter
Name="DMAC"
>
<File
RelativePath="..\..\ps2\LegacyDmac.cpp"
>
</File>
<Filter
Name="Sif"
>
@ -1318,6 +1330,14 @@
RelativePath="..\..\Ipu\IPU_Fifo.h"
>
</File>
<File
RelativePath="..\..\IPU\IPUdma.cpp"
>
</File>
<File
RelativePath="..\..\IPU\IPUdma.h"
>
</File>
<File
RelativePath="..\..\Ipu\yuv2rgb.cpp"
>

View File

@ -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);

View File

@ -21,11 +21,6 @@
#include "iR5900.h"
#ifdef _WIN32
//#pragma warning(disable:4244)
//#pragma warning(disable:4761)
#endif
namespace R5900 {
namespace Dynarec {
namespace OpcodeImpl

View File

@ -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<microProgram*>();
for (u32 i = 0; i < (progSize / 2); i++) {
prog.prog[i] = new deque<microProgram*>();
}
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<microProgram*>::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<microProgram*>::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<microProgram*>::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<microProgram*>::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<microRange>::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<vuIndex>(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(&microVU0);
microVU0.close();
}
}
void recMicroVU1::Shutdown() throw() {
if (m_AllocCount > 0) {
m_AllocCount--;
if (AtomicExchange(mvu1_allocated, 0) == 1)
mVUclose(&microVU1);
microVU1.close();
}
}
void recMicroVU0::Reset() {
if(!pxAssertDev(m_AllocCount, "MicroVU0 CPU Provider has not been allocated prior to reset!")) return;
mVUreset(&microVU0, &VU0);
microVU0.reset();
}
void recMicroVU1::Reset() {
if(!pxAssertDev(m_AllocCount, "MicroVU1 CPU Provider has not been allocated prior to reset!")) return;
mVUreset(&microVU1, &VU1);
microVU1.reset();
}
void recMicroVU0::Execute(u32 cycles) {

Some files were not shown because too many files have changed in this diff Show More