mirror of https://github.com/PCSX2/pcsx2.git
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:
commit
5e8f776adb
|
@ -39013,12 +39013,12 @@ Compat = 5
|
||||||
Serial = SLPM-66676
|
Serial = SLPM-66676
|
||||||
Name = Kingdom Hearts Re: Chain of Memories
|
Name = Kingdom Hearts Re: Chain of Memories
|
||||||
Region = NTSC-J
|
Region = NTSC-J
|
||||||
Compat = 4
|
Compat = 5
|
||||||
---------------------------------------------
|
---------------------------------------------
|
||||||
Serial = SLUS-21799
|
Serial = SLUS-21799
|
||||||
Name = Kingdom Hearts Re: Chain of Memories
|
Name = Kingdom Hearts Re: Chain of Memories
|
||||||
Region = NTSC-U
|
Region = NTSC-U
|
||||||
Compat = 4
|
Compat = 5
|
||||||
---------------------------------------------
|
---------------------------------------------
|
||||||
Serial = SLUS-21820
|
Serial = SLUS-21820
|
||||||
Name = Legend Of Spyro - Dawn Of The Dragon
|
Name = Legend Of Spyro - Dawn Of The Dragon
|
||||||
|
|
|
@ -16,16 +16,23 @@
|
||||||
#ifndef __PCSX2TYPES_H__
|
#ifndef __PCSX2TYPES_H__
|
||||||
#define __PCSX2TYPES_H__
|
#define __PCSX2TYPES_H__
|
||||||
|
|
||||||
/*
|
// --------------------------------------------------------------------------------------
|
||||||
* Based on PS2E Definitions by
|
// Forward declarations
|
||||||
linuzappz@hotmail.com,
|
// --------------------------------------------------------------------------------------
|
||||||
* shadowpcsx2@yahoo.gr,
|
// Forward declarations for wxWidgets-supporting features.
|
||||||
* and florinsasu@hotmail.com
|
// 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)
|
#if defined(_MSC_VER)
|
||||||
|
|
||||||
|
@ -111,28 +118,41 @@ typedef s32 sptr;
|
||||||
// performing explicit conversion from 64 and 32 bit values are provided instead.
|
// performing explicit conversion from 64 and 32 bit values are provided instead.
|
||||||
//
|
//
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
struct u128
|
union u128
|
||||||
{
|
{
|
||||||
u64 lo;
|
struct
|
||||||
u64 hi;
|
{
|
||||||
|
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 )
|
static u128 From64( u64 src )
|
||||||
{
|
{
|
||||||
u128 retval = { src, 0 };
|
u128 retval;
|
||||||
|
retval.lo = src;
|
||||||
|
retval.hi = 0;
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Explicit conversion from u32
|
// Explicit conversion from u32. Zero-extends the source through 128 bits.
|
||||||
static u128 From32( u32 src )
|
static u128 From32( u32 src )
|
||||||
{
|
{
|
||||||
u128 retval = { src, 0 };
|
u128 retval;
|
||||||
|
retval._u32[0] = src;
|
||||||
|
retval._u32[1] = 0;
|
||||||
|
retval.hi = 0;
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
operator u32() const { return (u32)lo; }
|
operator u32() const { return _u32[0]; }
|
||||||
operator u16() const { return (u16)lo; }
|
operator u16() const { return _u16[0]; }
|
||||||
operator u8() const { return (u8)lo; }
|
operator u8() const { return _u8[0]; }
|
||||||
|
|
||||||
bool operator==( const u128& right ) const
|
bool operator==( const u128& right ) const
|
||||||
{
|
{
|
||||||
|
@ -143,6 +163,17 @@ struct u128
|
||||||
{
|
{
|
||||||
return (lo != right.lo) && (hi != right.hi);
|
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
|
struct s128
|
||||||
|
@ -183,13 +214,21 @@ struct s128
|
||||||
|
|
||||||
typedef union _u128_t
|
typedef union _u128_t
|
||||||
{
|
{
|
||||||
u64 lo;
|
struct
|
||||||
u64 hi;
|
{
|
||||||
|
u64 lo;
|
||||||
|
u64 hi;
|
||||||
|
};
|
||||||
|
|
||||||
|
u64 _u64[2];
|
||||||
|
u32 _u32[4];
|
||||||
|
u16 _u16[8];
|
||||||
|
u8 _u8[16];
|
||||||
} u128;
|
} u128;
|
||||||
|
|
||||||
typedef union _s128_t
|
typedef union _s128_t
|
||||||
{
|
{
|
||||||
s64 lo;
|
u64 lo;
|
||||||
s64 hi;
|
s64 hi;
|
||||||
} s128;
|
} s128;
|
||||||
|
|
||||||
|
|
|
@ -127,11 +127,13 @@ public:
|
||||||
FastFormatAscii& Write( const char* fmt, ... );
|
FastFormatAscii& Write( const char* fmt, ... );
|
||||||
FastFormatAscii& WriteV( const char* fmt, va_list argptr );
|
FastFormatAscii& WriteV( const char* fmt, va_list argptr );
|
||||||
|
|
||||||
const char* GetResult() const;
|
bool IsEmpty() const;
|
||||||
operator const char*() const;
|
|
||||||
|
const char* c_str() const { return m_dest->GetPtr(); }
|
||||||
|
operator const char*() const { return m_dest->GetPtr(); }
|
||||||
|
|
||||||
const wxString GetString() const;
|
const wxString GetString() const;
|
||||||
operator wxString() const;
|
//operator wxString() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
class FastFormatUnicode
|
class FastFormatUnicode
|
||||||
|
@ -149,18 +151,11 @@ public:
|
||||||
FastFormatUnicode& WriteV( const char* fmt, va_list argptr );
|
FastFormatUnicode& WriteV( const char* fmt, va_list argptr );
|
||||||
FastFormatUnicode& WriteV( const wxChar* fmt, va_list argptr );
|
FastFormatUnicode& WriteV( const wxChar* fmt, va_list argptr );
|
||||||
|
|
||||||
const wxChar* GetResult() const;
|
bool IsEmpty() const;
|
||||||
const wxString GetString() const;
|
|
||||||
|
|
||||||
operator const wxChar*() const
|
const wxChar* c_str() const { return (const wxChar*)m_dest->GetPtr(); }
|
||||||
{
|
operator const wxChar*() const { return (const wxChar*)m_dest->GetPtr(); }
|
||||||
return (const wxChar*)m_dest->GetPtr();
|
operator wxString() 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 );
|
extern bool pxParseAssignmentString( const wxString& src, wxString& ldest, wxString& rdest );
|
||||||
|
|
|
@ -37,7 +37,7 @@ void* __fastcall pcsx2_aligned_malloc(size_t size, size_t align)
|
||||||
uptr aligned = (pasthead + align-1) & ~(align-1);
|
uptr aligned = (pasthead + align-1) & ~(align-1);
|
||||||
|
|
||||||
AlignedMallocHeader* header = (AlignedMallocHeader*)(aligned-headsize);
|
AlignedMallocHeader* header = (AlignedMallocHeader*)(aligned-headsize);
|
||||||
jASSUME( (uptr)header >= (uptr)p );
|
pxAssume( (uptr)header >= (uptr)p );
|
||||||
|
|
||||||
header->baseptr = p;
|
header->baseptr = p;
|
||||||
header->size = size;
|
header->size = size;
|
||||||
|
|
|
@ -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
|
// (all non-virtual members that do common work and then pass the result through DoWrite
|
||||||
// or DoWriteLn)
|
// or DoWriteLn)
|
||||||
|
@ -569,14 +569,14 @@ const NullConsoleWriter NullCon = {};
|
||||||
bool ConsoleLogSource::WriteV( ConsoleColors color, const char *fmt, va_list list ) const
|
bool ConsoleLogSource::WriteV( ConsoleColors color, const char *fmt, va_list list ) const
|
||||||
{
|
{
|
||||||
ConsoleColorScope cs(color);
|
ConsoleColorScope cs(color);
|
||||||
DoWrite( pxsFmtV(fmt,list).GetResult() );
|
DoWrite( pxsFmtV(fmt,list).c_str() );
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ConsoleLogSource::WriteV( ConsoleColors color, const wxChar *fmt, va_list list ) const
|
bool ConsoleLogSource::WriteV( ConsoleColors color, const wxChar *fmt, va_list list ) const
|
||||||
{
|
{
|
||||||
ConsoleColorScope cs(color);
|
ConsoleColorScope cs(color);
|
||||||
DoWrite( pxsFmtV(fmt,list) );
|
DoWrite( pxsFmtV(fmt,list).c_str() );
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -49,21 +49,20 @@ pxDoAssertFnType* pxDoAssert = pxAssertImpl_LogIt;
|
||||||
// response times from the Output window...
|
// response times from the Output window...
|
||||||
wxString DiagnosticOrigin::ToString( const wxChar* msg ) const
|
wxString DiagnosticOrigin::ToString( const wxChar* msg ) const
|
||||||
{
|
{
|
||||||
wxString message;
|
FastFormatUnicode message;
|
||||||
message.reserve( 2048 );
|
|
||||||
|
|
||||||
message.Printf( L"%s(%d) : assertion failed:\n", srcfile, line );
|
message.Write( L"%s(%d) : assertion failed:\n", srcfile, line );
|
||||||
|
|
||||||
if( function != NULL )
|
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 )
|
if( condition != NULL )
|
||||||
message += L" Condition: " + wxString(condition) + L"\n";
|
message.Write(L" Condition: %s\n", condition);
|
||||||
|
|
||||||
if( msg != NULL )
|
if( msg != NULL )
|
||||||
message += L" Message: " + wxString(msg) + L"\n";
|
message.Write(L" Message: %s\n", msg);
|
||||||
|
|
||||||
return message;
|
return message;
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,7 +47,7 @@ class FastFormatBuffers
|
||||||
protected:
|
protected:
|
||||||
typedef SafeAlignedArray<CharType,16> BufferType;
|
typedef SafeAlignedArray<CharType,16> BufferType;
|
||||||
|
|
||||||
static const uint BufferCount = 3;
|
static const uint BufferCount = 4;
|
||||||
|
|
||||||
BufferType m_buffers[BufferCount];
|
BufferType m_buffers[BufferCount];
|
||||||
uint m_curslot;
|
uint m_curslot;
|
||||||
|
@ -64,7 +64,7 @@ public:
|
||||||
m_buffers[i].Name = wxsFormat(L"%s Formatting Buffer (slot%d)",
|
m_buffers[i].Name = wxsFormat(L"%s Formatting Buffer (slot%d)",
|
||||||
(sizeof(CharType)==1) ? L"Ascii" : L"Unicode", i);
|
(sizeof(CharType)==1) ? L"Ascii" : L"Unicode", i);
|
||||||
m_buffers[i].MakeRoomFor(1024);
|
m_buffers[i].MakeRoomFor(1024);
|
||||||
m_buffers[i].ChunkSize = 4096;
|
m_buffers[i].ChunkSize = 2048;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_curslot = 0;
|
m_curslot = 0;
|
||||||
|
@ -77,7 +77,7 @@ public:
|
||||||
|
|
||||||
bool HasFreeBuffer() const
|
bool HasFreeBuffer() const
|
||||||
{
|
{
|
||||||
return m_curslot < BufferCount;
|
return m_curslot < BufferCount-1;
|
||||||
}
|
}
|
||||||
|
|
||||||
BufferType& GrabBuffer()
|
BufferType& GrabBuffer()
|
||||||
|
@ -176,7 +176,7 @@ static __ri void format_that_unicode_mess( SafeArray<char>& buffer, uint writepo
|
||||||
while( true )
|
while( true )
|
||||||
{
|
{
|
||||||
int size = buffer.GetLength() / sizeof(wxChar);
|
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
|
// some implementations of vsnprintf() don't NUL terminate
|
||||||
|
@ -267,12 +267,11 @@ FastFormatUnicode& FastFormatUnicode::Write( const wxChar* fmt, ... )
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
const wxChar* FastFormatUnicode::GetResult() const
|
bool FastFormatUnicode::IsEmpty() const
|
||||||
{
|
{
|
||||||
return (wxChar*)m_dest->GetPtr();
|
return ((wxChar&)(*m_dest)[0]) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------
|
||||||
// FastFormatAscii (implementations)
|
// FastFormatAscii (implementations)
|
||||||
// --------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------
|
||||||
|
@ -295,10 +294,10 @@ const wxString FastFormatAscii::GetString() const
|
||||||
return fromAscii(m_dest->GetPtr());
|
return fromAscii(m_dest->GetPtr());
|
||||||
}
|
}
|
||||||
|
|
||||||
FastFormatAscii::operator wxString() const
|
/*FastFormatAscii::operator wxString() const
|
||||||
{
|
{
|
||||||
return fromAscii(m_dest->GetPtr());
|
return fromAscii(m_dest->GetPtr());
|
||||||
}
|
}*/
|
||||||
|
|
||||||
FastFormatAscii& FastFormatAscii::WriteV( const char* fmt, va_list argptr )
|
FastFormatAscii& FastFormatAscii::WriteV( const char* fmt, va_list argptr )
|
||||||
{
|
{
|
||||||
|
@ -315,13 +314,8 @@ FastFormatAscii& FastFormatAscii::Write( const char* fmt, ... )
|
||||||
return *this;
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -253,11 +253,13 @@ Threading::ScopedLock::~ScopedLock() throw()
|
||||||
|
|
||||||
Threading::ScopedLock::ScopedLock( const Mutex* locker )
|
Threading::ScopedLock::ScopedLock( const Mutex* locker )
|
||||||
{
|
{
|
||||||
|
m_IsLocked = false;
|
||||||
AssignAndLock( locker );
|
AssignAndLock( locker );
|
||||||
}
|
}
|
||||||
|
|
||||||
Threading::ScopedLock::ScopedLock( const Mutex& locker )
|
Threading::ScopedLock::ScopedLock( const Mutex& locker )
|
||||||
{
|
{
|
||||||
|
m_IsLocked = false;
|
||||||
AssignAndLock( locker );
|
AssignAndLock( locker );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -268,6 +270,8 @@ void Threading::ScopedLock::AssignAndLock( const Mutex& locker )
|
||||||
|
|
||||||
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);
|
m_lock = const_cast<Mutex*>(locker);
|
||||||
if( !m_lock ) return;
|
if( !m_lock ) return;
|
||||||
|
|
||||||
|
|
|
@ -35,6 +35,42 @@ __fi wxString fromAscii( const char* src )
|
||||||
return wxString::FromAscii( 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.
|
// 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
|
// 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.
|
// the 'default' behavior, unless you manually clear the SafeList prior to subsequent calls.
|
||||||
|
|
|
@ -1,19 +1,19 @@
|
||||||
pcsx2 for debian
|
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
|
-> documents are stored in $XDG_CONFIG_HOME instead of $HOME/pcsx2
|
||||||
-> some features was removed to compile against libsound 1.3. Pcsx2
|
-> some features were removed so it could compile against libsound 1.3.
|
||||||
needs the version 1.5
|
Pcsx2 needs at least soundtouch 1.5.
|
||||||
|
|
||||||
* This package is highly experimental.
|
* 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.
|
* -fPIC option was removed for multiple reason.
|
||||||
- Code only support x86 architecture.
|
- Code only support x86 architecture.
|
||||||
- Upstream code use ebx register so it is not compliant with PIC.
|
- Upstream code uses the ebx register so it's not compliant with PIC.
|
||||||
- Impact too much performance.
|
- Impacts the performance too much.
|
||||||
- only plugins so no others package link against us.
|
- Only plugins. No package will link to them.
|
||||||
|
|
||||||
-- Gregory Hainaut <gregory.hainaut@gmail.com> Sat, 24 Apr 2010 23:11:10 +0200
|
-- Gregory Hainaut <gregory.hainaut@gmail.com> Sat, 24 Apr 2010 23:11:10 +0200
|
||||||
|
|
|
@ -2,6 +2,7 @@ Source: pcsx2.snapshot
|
||||||
Section: games
|
Section: games
|
||||||
Priority: optional
|
Priority: optional
|
||||||
Maintainer: Gregory Hainaut <gregory.hainaut@gmail.com>
|
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),
|
Build-Depends: debhelper (>= 7.0.50), dpkg-dev (>= 1.15.5.6), cmake (>=2.8),
|
||||||
gcc-multilib [amd64], g++-multilib [amd64],
|
gcc-multilib [amd64], g++-multilib [amd64],
|
||||||
zlib1g-dev (>= 1:1.2.3.3) | lib32z1-dev (>= 1.2.3.3) [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 (>= 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],
|
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]
|
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/
|
Homepage: http://pcsx2.net/
|
||||||
|
|
||||||
Package: pcsx2-unstable
|
Package: pcsx2-unstable
|
||||||
# Warning amd64 need additional ia32libs
|
# Warning amd64 need additional ia32libs
|
||||||
Architecture: i386 amd64
|
Architecture: i386 amd64
|
||||||
Depends: ${shlibs:Depends}, ${misc:Depends}, pcsx2-data-unstable (>= ${binary:Version}), pcsx2-plugins-unstable (>= ${binary:Version})
|
Depends: ${shlibs:Depends}, ${misc:Depends},
|
||||||
Conflicts: pcsx2
|
pcsx2-data-unstable (>= ${binary:Version}),
|
||||||
|
pcsx2-plugins-unstable (>= ${binary:Version})
|
||||||
|
Conflicts: pcsx2
|
||||||
Description: Playstation 2 emulator
|
Description: Playstation 2 emulator
|
||||||
PCSX2 is a PlayStation 2 emulator for Windows and
|
PCSX2 is a PlayStation 2 emulator for Windows and Linux, started by the same
|
||||||
Linux, started by the same team that brought you PCSX
|
team that brought you PCSX (a Sony PlayStation 1 emulator).
|
||||||
(a Sony PlayStation 1 emulator).
|
|
||||||
.
|
.
|
||||||
WARNING: it requieres a CPU with sse2 instructions. If your
|
WARNING: It requires a CPU with SSE2 instructions. If your CPU does not support
|
||||||
CPU does not support this instruction set, it does not have
|
this instruction set, it does not have enough horse power to run this emulator
|
||||||
enough horse power to run this emulator anyway.
|
anyway.
|
||||||
.
|
.
|
||||||
This package includes the main binary file.
|
This package includes the main binary file.
|
||||||
|
|
||||||
|
@ -54,34 +56,33 @@ Depends: ${misc:Depends}
|
||||||
Recommends: pcsx2-unstable (>= ${binary:Version}), pcsx2-plugins-unstable (>= ${binary:Version})
|
Recommends: pcsx2-unstable (>= ${binary:Version}), pcsx2-plugins-unstable (>= ${binary:Version})
|
||||||
Conflicts: pcsx2-data
|
Conflicts: pcsx2-data
|
||||||
Description: data for pcsx2
|
Description: data for pcsx2
|
||||||
PCSX2 is a PlayStation 2 emulator for Windows and
|
PCSX2 is a PlayStation 2 emulator for Windows and Linux, started by the same
|
||||||
Linux, started by the same team that brought you PCSX
|
team that brought you PCSX (a Sony PlayStation 1 emulator).
|
||||||
(a Sony PlayStation 1 emulator).
|
|
||||||
.
|
.
|
||||||
WARNING: it requieres a CPU with sse2 instructions. If your
|
WARNING: It requires a CPU with SSE2 instructions. If your CPU does not support
|
||||||
CPU does not support this instruction set, it does not have
|
this instruction set, it does not have enough horse power to run this emulator
|
||||||
enough horse power to run this emulator anyway.
|
anyway.
|
||||||
.
|
.
|
||||||
This package includes data files.
|
This package includes data files.
|
||||||
|
|
||||||
Package: pcsx2-plugins-unstable
|
Package: pcsx2-plugins-unstable
|
||||||
# Warning amd64 need additional ia32libs
|
# Warning amd64 need additional ia32libs
|
||||||
Architecture: i386 amd64
|
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 !!!
|
# 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]
|
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
|
Conflicts: pcsx2-plugins
|
||||||
Description: Various plugins for pcsx2
|
Description: Various plugins for pcsx2
|
||||||
PCSX2 is a PlayStation 2 emulator for Windows and
|
PCSX2 is a PlayStation 2 emulator for Windows and Linux, started by the same
|
||||||
Linux, started by the same team that brought you PCSX
|
team that brought you PCSX (a Sony PlayStation 1 emulator).
|
||||||
(a Sony PlayStation 1 emulator).
|
|
||||||
.
|
.
|
||||||
WARNING: it requieres a CPU with sse2 instructions. If your
|
WARNING: It requires a CPU with SSE2 instructions. If your CPU does not support
|
||||||
CPU does not support this instruction set, it does not have
|
this instruction set, it does not have enough horse power to run this emulator
|
||||||
enough horse power to run this emulator anyway.
|
anyway.
|
||||||
.
|
.
|
||||||
This package includes the plugins of the emulator.
|
This package includes the plugins for PCSX2.
|
||||||
|
|
||||||
Package: pcsx2-unstable-dbg
|
Package: pcsx2-unstable-dbg
|
||||||
Section: debug
|
Section: debug
|
||||||
|
@ -91,9 +92,12 @@ Architecture: i386 amd64
|
||||||
Depends: ${misc:Depends}, pcsx2-unstable (= ${binary:Version})
|
Depends: ${misc:Depends}, pcsx2-unstable (= ${binary:Version})
|
||||||
Conflicts: pcsx2-dbg
|
Conflicts: pcsx2-dbg
|
||||||
Description: Debug symbols for pcsx2
|
Description: Debug symbols for pcsx2
|
||||||
PCSX2 is a PlayStation 2 emulator for Windows and
|
PCSX2 is a PlayStation 2 emulator for Windows and Linux, started by the same
|
||||||
Linux, started by the same team that brought you PCSX
|
team that brought you PCSX (a Sony PlayStation 1 emulator).
|
||||||
(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.
|
This package contains the debug symbol of pcsx2.
|
||||||
|
|
||||||
|
@ -104,9 +108,12 @@ Priority: extra
|
||||||
Architecture: i386 amd64
|
Architecture: i386 amd64
|
||||||
Depends: ${misc:Depends}, pcsx2-plugins-unstable (= ${binary:Version})
|
Depends: ${misc:Depends}, pcsx2-plugins-unstable (= ${binary:Version})
|
||||||
Conflicts: pcsx2-plugins-dbg
|
Conflicts: pcsx2-plugins-dbg
|
||||||
Description: Debug symbols for pcsx2-plugins
|
Description: Debug symbols of the pcsx2-plugins
|
||||||
PCSX2 is a PlayStation 2 emulator for Windows and
|
PCSX2 is a PlayStation 2 emulator for Windows and Linux, started by the same
|
||||||
Linux, started by the same team that brought you PCSX
|
team that brought you PCSX (a Sony PlayStation 1 emulator).
|
||||||
(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.
|
||||||
|
|
|
@ -24,21 +24,22 @@ Build-Depends: debhelper (>= 7.0.50), dpkg-dev (>= 1.15.5.6), cmake (>=2.8),
|
||||||
libgl1-mesa-dev,
|
libgl1-mesa-dev,
|
||||||
libglu1-mesa-dev,
|
libglu1-mesa-dev,
|
||||||
nvidia-cg-toolkit-pcsx2
|
nvidia-cg-toolkit-pcsx2
|
||||||
Standards-Version: 3.9.0
|
Standards-Version: 3.9.1
|
||||||
Homepage: http://pcsx2.net/
|
Homepage: http://pcsx2.net/
|
||||||
|
|
||||||
Package: pcsx2-unstable
|
Package: pcsx2-unstable
|
||||||
Architecture: i386
|
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
|
Conflicts: pcsx2
|
||||||
Description: Playstation 2 emulator
|
Description: Playstation 2 emulator
|
||||||
PCSX2 is a PlayStation 2 emulator for Windows and
|
PCSX2 is a PlayStation 2 emulator for Windows and Linux, started by the same
|
||||||
Linux, started by the same team that brought you PCSX
|
team that brought you PCSX (a Sony PlayStation 1 emulator).
|
||||||
(a Sony PlayStation 1 emulator).
|
|
||||||
.
|
.
|
||||||
WARNING: it requieres a CPU with sse2 instructions. If your
|
WARNING: It requires a CPU with SSE2 instructions. If your CPU does not support
|
||||||
CPU does not support this instruction set, it does not have
|
this instruction set, it does not have enough horse power to run this emulator
|
||||||
enough horse power to run this emulator anyway.
|
anyway.
|
||||||
.
|
.
|
||||||
This package includes the main binary file.
|
This package includes the main binary file.
|
||||||
|
|
||||||
|
@ -49,33 +50,32 @@ Depends: ${misc:Depends}
|
||||||
Recommends: pcsx2-unstable (>= ${binary:Version}), pcsx2-plugins-unstable (>= ${binary:Version})
|
Recommends: pcsx2-unstable (>= ${binary:Version}), pcsx2-plugins-unstable (>= ${binary:Version})
|
||||||
Conflicts: pcsx2-data
|
Conflicts: pcsx2-data
|
||||||
Description: data for pcsx2
|
Description: data for pcsx2
|
||||||
PCSX2 is a PlayStation 2 emulator for Windows and
|
PCSX2 is a PlayStation 2 emulator for Windows and Linux, started by the same
|
||||||
Linux, started by the same team that brought you PCSX
|
team that brought you PCSX (a Sony PlayStation 1 emulator).
|
||||||
(a Sony PlayStation 1 emulator).
|
|
||||||
.
|
.
|
||||||
WARNING: it requieres a CPU with sse2 instructions. If your
|
WARNING: It requires a CPU with SSE2 instructions. If your CPU does not support
|
||||||
CPU does not support this instruction set, it does not have
|
this instruction set, it does not have enough horse power to run this emulator
|
||||||
enough horse power to run this emulator anyway.
|
anyway.
|
||||||
.
|
.
|
||||||
This package includes data files.
|
This package includes data files.
|
||||||
|
|
||||||
Package: pcsx2-plugins-unstable
|
Package: pcsx2-plugins-unstable
|
||||||
Architecture: i386
|
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 !!!
|
# 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)
|
nvidia-cg-toolkit-pcsx2 | nvidia-cg-toolkit (>= 2.1)
|
||||||
|
Recommends: pcsx2-unstable (>= ${binary:Version}),
|
||||||
|
pcsx2-data-unstable (>= ${binary:Version})
|
||||||
Conflicts: pcsx2-plugins
|
Conflicts: pcsx2-plugins
|
||||||
Description: Various plugins for pcsx2
|
Description: Various plugins for pcsx2
|
||||||
PCSX2 is a PlayStation 2 emulator for Windows and
|
PCSX2 is a PlayStation 2 emulator for Windows and Linux, started by the same
|
||||||
Linux, started by the same team that brought you PCSX
|
team that brought you PCSX (a Sony PlayStation 1 emulator).
|
||||||
(a Sony PlayStation 1 emulator).
|
|
||||||
.
|
.
|
||||||
WARNING: it requieres a CPU with sse2 instructions. If your
|
WARNING: It requires a CPU with SSE2 instructions. If your CPU does not support
|
||||||
CPU does not support this instruction set, it does not have
|
this instruction set, it does not have enough horse power to run this emulator
|
||||||
enough horse power to run this emulator anyway.
|
anyway.
|
||||||
.
|
.
|
||||||
This package includes the plugins of the emulator.
|
This package includes the plugins for PCSX2.
|
||||||
|
|
||||||
Package: pcsx2-unstable-dbg
|
Package: pcsx2-unstable-dbg
|
||||||
Section: debug
|
Section: debug
|
||||||
|
@ -84,9 +84,12 @@ Architecture: i386
|
||||||
Depends: ${misc:Depends}, pcsx2-unstable (= ${binary:Version})
|
Depends: ${misc:Depends}, pcsx2-unstable (= ${binary:Version})
|
||||||
Conflicts: pcsx2-dbg
|
Conflicts: pcsx2-dbg
|
||||||
Description: Debug symbols for pcsx2
|
Description: Debug symbols for pcsx2
|
||||||
PCSX2 is a PlayStation 2 emulator for Windows and
|
PCSX2 is a PlayStation 2 emulator for Windows and Linux, started by the same
|
||||||
Linux, started by the same team that brought you PCSX
|
team that brought you PCSX (a Sony PlayStation 1 emulator).
|
||||||
(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.
|
This package contains the debug symbol of pcsx2.
|
||||||
|
|
||||||
|
@ -96,9 +99,12 @@ Priority: extra
|
||||||
Architecture: i386
|
Architecture: i386
|
||||||
Depends: ${misc:Depends}, pcsx2-plugins-unstable (= ${binary:Version})
|
Depends: ${misc:Depends}, pcsx2-plugins-unstable (= ${binary:Version})
|
||||||
Conflicts: pcsx2-plugins-dbg
|
Conflicts: pcsx2-plugins-dbg
|
||||||
Description: Debug symbols for pcsx2-plugins
|
Description: Debug symbols of the pcsx2-plugins
|
||||||
PCSX2 is a PlayStation 2 emulator for Windows and
|
PCSX2 is a PlayStation 2 emulator for Windows and Linux, started by the same
|
||||||
Linux, started by the same team that brought you PCSX
|
team that brought you PCSX (a Sony PlayStation 1 emulator).
|
||||||
(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.
|
||||||
|
|
|
@ -155,6 +155,8 @@ License: BSD (3 clause)
|
||||||
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
SUCH DAMAGE.
|
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:
|
The Debian packaging is:
|
||||||
|
|
|
@ -4,28 +4,34 @@
|
||||||
# it under the terms of the GNU Lesser General Public License as published by
|
# it under the terms of the GNU Lesser General Public License as published by
|
||||||
# the Free Software Foundation, either version 3 of the License, or
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
# (at your option) any later version.
|
# (at your option) any later version.
|
||||||
#
|
#
|
||||||
# This package is distributed in the hope that it will be useful,
|
# This package is distributed in the hope that it will be useful,
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
# GNU Lesser General Public License for more details.
|
# GNU Lesser General Public License for more details.
|
||||||
#
|
#
|
||||||
# You should have received a copy of the GNU Lesser General Public License
|
# You should have received a copy of the GNU Lesser General Public License
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
######################################################################
|
######################################################################
|
||||||
# Global Parameter
|
# Global Parameters
|
||||||
######################################################################
|
######################################################################
|
||||||
# Svn parameter
|
# Svn parameter
|
||||||
if [ -n "$1" ] ; then
|
if [ -n "$1" ] ; then
|
||||||
SVN_CO_VERSION=$1;
|
SVN_CO_VERSION=$1;
|
||||||
else
|
else
|
||||||
echo "Please provide the subversion version as fisrt parameter"
|
echo "Please provide the subversion revision number as the first parameter"
|
||||||
exit 1;
|
exit 1;
|
||||||
fi
|
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
|
# Debian name of package and tarball
|
||||||
PKG_NAME="pcsx2.snapshot-${SVN_CO_VERSION}"
|
PKG_NAME="pcsx2.snapshot-${SVN_CO_VERSION}"
|
||||||
|
@ -38,7 +44,7 @@ NEW_DIR=${TMP_DIR}/$PKG_NAME
|
||||||
|
|
||||||
|
|
||||||
######################################################################
|
######################################################################
|
||||||
# Basic function
|
# Basic functions
|
||||||
######################################################################
|
######################################################################
|
||||||
get_svn_dir()
|
get_svn_dir()
|
||||||
{
|
{
|
||||||
|
@ -58,8 +64,8 @@ get_svn_file()
|
||||||
{
|
{
|
||||||
for file in $* ; do
|
for file in $* ; do
|
||||||
if [ ! -e `basename ${file}` ] ; then
|
if [ ! -e `basename ${file}` ] ; then
|
||||||
# Versionning information are not support for a single file
|
# Versioning information is not supported for a single file
|
||||||
# so you can not use svn co
|
# therefore you can't use svn co
|
||||||
svn export --quiet ${SVN_TRUNK}/${file} -r $SVN_CO_VERSION;
|
svn export --quiet ${SVN_TRUNK}/${file} -r $SVN_CO_VERSION;
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
@ -69,8 +75,8 @@ get_svn_file()
|
||||||
# Main script
|
# Main script
|
||||||
######################################################################
|
######################################################################
|
||||||
|
|
||||||
## Download the svn repository (only the usefull things)
|
## Download the svn repository (only the useful things)
|
||||||
echo "Download pcsx2 source rev ${SVN_CO_VERSION}"
|
echo "Downloading pcsx2 source revision ${SVN_CO_VERSION}"
|
||||||
mkdir -p $ROOT_DIR;
|
mkdir -p $ROOT_DIR;
|
||||||
(cd $ROOT_DIR;
|
(cd $ROOT_DIR;
|
||||||
get_svn_file CMakeLists.txt;
|
get_svn_file CMakeLists.txt;
|
||||||
|
@ -78,7 +84,8 @@ mkdir -p $ROOT_DIR;
|
||||||
get_svn_dir debian-unstable-upstream;
|
get_svn_dir debian-unstable-upstream;
|
||||||
echo "Done")
|
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
|
mkdir -p $ROOT_DIR/plugins
|
||||||
(cd $ROOT_DIR/plugins;
|
(cd $ROOT_DIR/plugins;
|
||||||
get_svn_file plugins/CMakeLists.txt;
|
get_svn_file plugins/CMakeLists.txt;
|
||||||
|
@ -98,14 +105,14 @@ echo "Note: some plugins are more or less deprecated CDVDisoEFP, CDVDlinuz, Zero
|
||||||
echo "Done")
|
echo "Done")
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
echo "Copy the subversion repository in a tmp directory"
|
echo "Copy the subversion repository to a temporary directory"
|
||||||
# Copy the dir
|
# Copy the dir
|
||||||
rm -fr $NEW_DIR
|
rm -fr $NEW_DIR
|
||||||
cp -r $ROOT_DIR $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
|
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 "build.sh" -exec rm -f {} \;
|
||||||
find $NEW_DIR -name "install-sh" -exec rm -f {} \;
|
find $NEW_DIR -name "install-sh" -exec rm -f {} \;
|
||||||
find $NEW_DIR -name "depcomp" -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 "aclocal.m4" -exec rm -f {} \;
|
||||||
find $NEW_DIR -name "configure.ac" -exec rm -f {} \;
|
find $NEW_DIR -name "configure.ac" -exec rm -f {} \;
|
||||||
find $NEW_DIR -name "Makefile.am" -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
|
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)"
|
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}/plugins/zzogl-pg/opengl/Win32"
|
||||||
rm -fr "${NEW_DIR}/tools/GSDumpGUI"
|
rm -fr "${NEW_DIR}/tools/GSDumpGUI"
|
||||||
rm -fr "${NEW_DIR}/common/vsprops"
|
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}/plugins/zzogl-pg/opengl/ZeroGSShaders/zlib"
|
||||||
rm -fr "${NEW_DIR}/common/src/Utilities/x86/MemcpyFast.cpp"
|
rm -fr "${NEW_DIR}/common/src/Utilities/x86/MemcpyFast.cpp"
|
||||||
rm -fr "${NEW_DIR}/plugins/CDVDnull/Linux"
|
|
||||||
|
|
||||||
|
|
||||||
## BUILD
|
## BUILD
|
||||||
echo "Build the tar gz file"
|
echo "Build the tar.gz file"
|
||||||
tar -C ${TMP_DIR} -czf ${TAR_NAME}.gz $PKG_NAME
|
tar -C $TMP_DIR -czf ${TAR_NAME}.gz $PKG_NAME
|
||||||
|
|
||||||
## Clean
|
## Clean
|
||||||
rm -fr $NEW_DIR
|
rm -fr $NEW_DIR
|
||||||
|
rm -fr $ROOT_DIR
|
||||||
|
|
|
@ -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)
|
|
||||||
|
|
|
@ -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
|
|
|
@ -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
|
|
|
@ -2,7 +2,3 @@
|
||||||
02_update_default_path.patch
|
02_update_default_path.patch
|
||||||
05_move_data_to_config.patch
|
05_move_data_to_config.patch
|
||||||
21_use_legacy_soundtouch_13.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
|
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
# PIC code cause regression in the library and issue with the ebx register.
|
#* -fPIC option was removed for multiple reason.
|
||||||
# Morever library are plugins and the code is only compatible with x86.
|
# - 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
|
pcsx2-plugins-unstable: shlib-with-non-pic-code
|
||||||
|
|
|
@ -1 +1,3 @@
|
||||||
bin/pcsx2 usr/games
|
bin/pcsx2 usr/games
|
||||||
|
debian/pcsx2.desktop usr/share/applications
|
||||||
|
debian/pcsx2.xpm usr/share/pixmaps
|
||||||
|
|
|
@ -41,9 +41,9 @@ clean:
|
||||||
dh_testroot
|
dh_testroot
|
||||||
rm -f build-stamp
|
rm -f build-stamp
|
||||||
|
|
||||||
# Backup some orig makefile if it not already done
|
# Backup some orig makefile if it's not already done.
|
||||||
# I hope some will be delete by upstream when cmake port is over
|
# I hope that some will be delete by upstream when the cmake port is over.
|
||||||
# Note in case we do not dl all plugins the test [ -f $${makefile} ] ensure the working
|
# 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 \
|
for makefile in plugins/CDVDlinuz/Src/Linux/Makefile \
|
||||||
plugins/CDVDiso/src/Linux/Makefile \
|
plugins/CDVDiso/src/Linux/Makefile \
|
||||||
plugins/CDVDiso/src/Windows/Makefile \
|
plugins/CDVDiso/src/Windows/Makefile \
|
||||||
|
@ -53,13 +53,13 @@ clean:
|
||||||
plugins/CDVDisoEFP/src/Linux/Makefile ; do \
|
plugins/CDVDisoEFP/src/Linux/Makefile ; do \
|
||||||
[ -f $${makefile}.orig ] || ( [ -f $${makefile} ] && mv $${makefile} $${makefile}.orig ) || true ; done
|
[ -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
|
[ -f Makefile ] && $(MAKE) clean || true
|
||||||
# Remove cmake stuff
|
# Remove cmake stuff
|
||||||
rm -fr $$(find . -type d -name CMakeFiles)
|
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 CMakeCache.txt) $$(find . -type f -name cmake_install.cmake)
|
||||||
rm -f $$(find . -type f -name Makefile)
|
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
|
cd pcsx2/gui/Resources/ && rm -f App*.h Config*.h BackgroundLogo.h ButtonIcon_Camera.h Dualshock.h
|
||||||
# leftover of cmake
|
# leftover of cmake
|
||||||
rm -f bin/plugins/ps2hw.dat
|
rm -f bin/plugins/ps2hw.dat
|
||||||
|
@ -69,62 +69,15 @@ clean:
|
||||||
|
|
||||||
dh_clean
|
dh_clean
|
||||||
|
|
||||||
install:
|
## Uncomment this, if fglrx driver is installed
|
||||||
install: build
|
#override_dh_shlibdeps:
|
||||||
dh_testdir
|
# dh_shlibdeps -- --ignore-missing-info
|
||||||
dh_testroot
|
|
||||||
dh_prep
|
|
||||||
dh_installdirs
|
|
||||||
|
|
||||||
### the project build usefull thing in ./bin so directly install
|
override_dh_strip:
|
||||||
### 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
|
|
||||||
dh_strip --package=pcsx2-unstable --dbg-package=pcsx2-unstable-dbg
|
dh_strip --package=pcsx2-unstable --dbg-package=pcsx2-unstable-dbg
|
||||||
dh_strip --package=pcsx2-plugins-unstable --dbg-package=pcsx2-plugins-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
|
||||||
|
|
|
@ -41,9 +41,9 @@ clean:
|
||||||
dh_testroot
|
dh_testroot
|
||||||
rm -f build-stamp
|
rm -f build-stamp
|
||||||
|
|
||||||
# Backup some orig makefile if it not already done
|
# Backup some orig makefile if it's not already done.
|
||||||
# I hope some will be delete by upstream when cmake port is over
|
# I hope that some will be delete by upstream when the cmake port is over.
|
||||||
# Note in case we do not dl all plugins the test [ -f $${makefile} ] ensure the working
|
# 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 \
|
for makefile in plugins/CDVDlinuz/Src/Linux/Makefile \
|
||||||
plugins/CDVDiso/src/Linux/Makefile \
|
plugins/CDVDiso/src/Linux/Makefile \
|
||||||
plugins/CDVDiso/src/Windows/Makefile \
|
plugins/CDVDiso/src/Windows/Makefile \
|
||||||
|
@ -53,13 +53,13 @@ clean:
|
||||||
plugins/CDVDisoEFP/src/Linux/Makefile ; do \
|
plugins/CDVDisoEFP/src/Linux/Makefile ; do \
|
||||||
[ -f $${makefile}.orig ] || ( [ -f $${makefile} ] && mv $${makefile} $${makefile}.orig ) || true ; done
|
[ -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
|
[ -f Makefile ] && $(MAKE) clean || true
|
||||||
# Remove cmake stuff
|
# Remove cmake stuff
|
||||||
rm -fr $$(find . -type d -name CMakeFiles)
|
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 CMakeCache.txt) $$(find . -type f -name cmake_install.cmake)
|
||||||
rm -f $$(find . -type f -name Makefile)
|
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
|
cd pcsx2/gui/Resources/ && rm -f App*.h Config*.h BackgroundLogo.h ButtonIcon_Camera.h Dualshock.h
|
||||||
# leftover of cmake
|
# leftover of cmake
|
||||||
rm -f bin/plugins/ps2hw.dat
|
rm -f bin/plugins/ps2hw.dat
|
||||||
|
@ -69,65 +69,15 @@ clean:
|
||||||
|
|
||||||
dh_clean
|
dh_clean
|
||||||
|
|
||||||
install:
|
# Allow compilation when fglrx is installed
|
||||||
install: build
|
override_dh_shlibdeps:
|
||||||
dh_testdir
|
dh_shlibdeps -- --ignore-missing-info
|
||||||
dh_testroot
|
|
||||||
dh_prep
|
|
||||||
dh_installdirs
|
|
||||||
|
|
||||||
### the project build usefull thing in ./bin so directly install
|
override_dh_strip:
|
||||||
### 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
|
|
||||||
dh_strip --package=pcsx2-unstable --dbg-package=pcsx2-unstable-dbg
|
dh_strip --package=pcsx2-unstable --dbg-package=pcsx2-unstable-dbg
|
||||||
dh_strip --package=pcsx2-plugins-unstable --dbg-package=pcsx2-plugins-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
|
||||||
|
|
|
@ -6,5 +6,6 @@
|
||||||
# Compulsory line, this is a version 3 file
|
# Compulsory line, this is a version 3 file
|
||||||
version=3
|
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
|
# http://pcsx2.googlecode.com/files/Pcsx2-linux-beta-(.*).tar.gz
|
||||||
|
|
|
@ -16,10 +16,6 @@
|
||||||
#ifndef __CDVD_ISO_READER_H__
|
#ifndef __CDVD_ISO_READER_H__
|
||||||
#define __CDVD_ISO_READER_H__
|
#define __CDVD_ISO_READER_H__
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
#pragma warning(disable:4018)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#include "IopCommon.h"
|
#include "IopCommon.h"
|
||||||
|
|
|
@ -137,7 +137,8 @@ isoFile *isoOpen(const char *filename)
|
||||||
iso->handle = _openfile( iso->filename, O_RDONLY);
|
iso->handle = _openfile( iso->filename, O_RDONLY);
|
||||||
if (iso->handle == NULL)
|
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;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,10 +29,6 @@
|
||||||
|
|
||||||
#define _FILE_OFFSET_BITS 64
|
#define _FILE_OFFSET_BITS 64
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
# pragma warning(disable:4018) // disable signed/unsigned mismatch error
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "IopCommon.h"
|
#include "IopCommon.h"
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
|
@ -165,7 +165,6 @@ set(pcsx2Sources
|
||||||
Vif_Codes.cpp
|
Vif_Codes.cpp
|
||||||
Vif_Transfer.cpp
|
Vif_Transfer.cpp
|
||||||
Vif_Unpack.cpp
|
Vif_Unpack.cpp
|
||||||
Vif_Unpack.inl
|
|
||||||
vtlb.cpp
|
vtlb.cpp
|
||||||
VU0.cpp
|
VU0.cpp
|
||||||
VUmicro.cpp
|
VUmicro.cpp
|
||||||
|
@ -226,6 +225,7 @@ set(pcsx2Headers
|
||||||
Vif_Dma.h
|
Vif_Dma.h
|
||||||
Vif.h
|
Vif.h
|
||||||
Vif_Unpack.h
|
Vif_Unpack.h
|
||||||
|
Vif_Unpack.inl
|
||||||
vtlb.h
|
vtlb.h
|
||||||
VUflags.h
|
VUflags.h
|
||||||
VUmicro.h
|
VUmicro.h
|
||||||
|
@ -295,7 +295,6 @@ set(pcsx2GuiSources
|
||||||
gui/Panels/BaseApplicableConfigPanel.cpp
|
gui/Panels/BaseApplicableConfigPanel.cpp
|
||||||
gui/Panels/MemoryCardListView.cpp
|
gui/Panels/MemoryCardListView.cpp
|
||||||
gui/Dialogs/BaseConfigurationDialog.cpp
|
gui/Dialogs/BaseConfigurationDialog.cpp
|
||||||
gui/Dialogs/BaseConfigurationDialog.inl
|
|
||||||
gui/Dialogs/BiosSelectorDialog.cpp
|
gui/Dialogs/BiosSelectorDialog.cpp
|
||||||
gui/Dialogs/ConfirmationDialogs.cpp
|
gui/Dialogs/ConfirmationDialogs.cpp
|
||||||
gui/Dialogs/CreateMemoryCardDialog.cpp
|
gui/Dialogs/CreateMemoryCardDialog.cpp
|
||||||
|
@ -353,6 +352,7 @@ set(pcsx2GuiHeaders
|
||||||
gui/AppGameDatabase.h
|
gui/AppGameDatabase.h
|
||||||
gui/ConsoleLogger.h
|
gui/ConsoleLogger.h
|
||||||
gui/CpuUsageProvider.h
|
gui/CpuUsageProvider.h
|
||||||
|
gui/Dialogs/BaseConfigurationDialog.inl
|
||||||
gui/Dialogs/ConfigurationDialog.h
|
gui/Dialogs/ConfigurationDialog.h
|
||||||
gui/Dialogs/LogOptionsDialog.h
|
gui/Dialogs/LogOptionsDialog.h
|
||||||
gui/Dialogs/ModalPopups.h
|
gui/Dialogs/ModalPopups.h
|
||||||
|
@ -371,6 +371,7 @@ set(pcsx2GuiHeaders
|
||||||
set(pcsx2IPUSources
|
set(pcsx2IPUSources
|
||||||
IPU/IPU.cpp
|
IPU/IPU.cpp
|
||||||
IPU/IPU_Fifo.cpp
|
IPU/IPU_Fifo.cpp
|
||||||
|
IPU/IPUdma.cpp
|
||||||
IPU/mpeg2lib/Idct.cpp
|
IPU/mpeg2lib/Idct.cpp
|
||||||
IPU/mpeg2lib/Mpeg.cpp
|
IPU/mpeg2lib/Mpeg.cpp
|
||||||
IPU/yuv2rgb.cpp)
|
IPU/yuv2rgb.cpp)
|
||||||
|
@ -379,6 +380,7 @@ set(pcsx2IPUSources
|
||||||
set(pcsx2IPUHeaders
|
set(pcsx2IPUHeaders
|
||||||
IPU/IPU.h
|
IPU/IPU.h
|
||||||
IPU/IPU_Fifo.h
|
IPU/IPU_Fifo.h
|
||||||
|
IPU/IPUdma.h
|
||||||
IPU/yuv2rgb.h)
|
IPU/yuv2rgb.h)
|
||||||
|
|
||||||
# Linux sources
|
# Linux sources
|
||||||
|
@ -394,12 +396,15 @@ set(pcsx2LinuxHeaders
|
||||||
set(pcsx2ps2Sources
|
set(pcsx2ps2Sources
|
||||||
ps2/BiosTools.cpp
|
ps2/BiosTools.cpp
|
||||||
ps2/GIFpath.cpp
|
ps2/GIFpath.cpp
|
||||||
|
ps2/LegacyDmac.cpp
|
||||||
ps2/Iop/IopHwRead.cpp
|
ps2/Iop/IopHwRead.cpp
|
||||||
ps2/Iop/IopHwWrite.cpp)
|
ps2/Iop/IopHwWrite.cpp)
|
||||||
|
|
||||||
# ps2 headers
|
# ps2 headers
|
||||||
set(pcsx2ps2Headers
|
set(pcsx2ps2Headers
|
||||||
ps2/BiosTools.h
|
ps2/BiosTools.h
|
||||||
|
ps2/eeHwTraceLog.inl
|
||||||
|
ps2/HwInternal.h
|
||||||
ps2/Iop/IopHw_Internal.h)
|
ps2/Iop/IopHw_Internal.h)
|
||||||
|
|
||||||
# RDebug sources
|
# RDebug sources
|
||||||
|
@ -495,20 +500,6 @@ set(pcsx2x86Sources
|
||||||
x86/ix86-32/iR5900Shift.cpp
|
x86/ix86-32/iR5900Shift.cpp
|
||||||
x86/ix86-32/iR5900Templates.cpp
|
x86/ix86-32/iR5900Templates.cpp
|
||||||
x86/ix86-32/recVTLB.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_Dynarec.cpp
|
||||||
x86/newVif_Unpack.cpp
|
x86/newVif_Unpack.cpp
|
||||||
x86/newVif_UnpackSSE.cpp
|
x86/newVif_UnpackSSE.cpp
|
||||||
|
@ -538,6 +529,20 @@ set(pcsx2x86Headers
|
||||||
x86/microVU.h
|
x86/microVU.h
|
||||||
x86/microVU_IR.h
|
x86/microVU_IR.h
|
||||||
x86/microVU_Misc.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.h
|
||||||
x86/newVif_BlockBuffer.h
|
x86/newVif_BlockBuffer.h
|
||||||
x86/newVif_HashBucket.h
|
x86/newVif_HashBucket.h
|
||||||
|
|
|
@ -428,7 +428,7 @@ void MTC0()
|
||||||
}
|
}
|
||||||
|
|
||||||
int CPCOND0() {
|
int CPCOND0() {
|
||||||
return ((dmacRegs->stat.CIS | ~dmacRegs->pcr.CPC) == 0x3ff);
|
return ((dmacRegs.stat.CIS | ~dmacRegs.pcr.CPC) == 0x3ff);
|
||||||
}
|
}
|
||||||
|
|
||||||
//#define CPCOND0 1
|
//#define CPCOND0 1
|
||||||
|
|
|
@ -17,12 +17,6 @@
|
||||||
|
|
||||||
#include "Pcsx2Defs.h"
|
#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 BIAS = 2; // Bus is half of the actual ps2 speed
|
||||||
static const u32 PS2CLK = 294912000; //hz /* 294.912 mhz */
|
static const u32 PS2CLK = 294912000; //hz /* 294.912 mhz */
|
||||||
|
|
||||||
|
|
|
@ -343,11 +343,11 @@ struct Pcsx2Config
|
||||||
void LoadSave( IniInterface& conf );
|
void LoadSave( IniInterface& conf );
|
||||||
|
|
||||||
void Set( const wxString& list, bool enabled=true );
|
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;
|
bool Get( GamefixId id ) const;
|
||||||
void Set( GamefixId id, bool enabled=true );
|
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
|
bool operator ==( const GamefixOptions& right ) const
|
||||||
{
|
{
|
||||||
|
|
|
@ -15,11 +15,11 @@
|
||||||
|
|
||||||
|
|
||||||
#include "PrecompiledHeader.h"
|
#include "PrecompiledHeader.h"
|
||||||
#include "Common.h"
|
|
||||||
|
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
||||||
|
#include "Common.h"
|
||||||
#include "R3000A.h"
|
#include "R3000A.h"
|
||||||
#include "Counters.h"
|
#include "Counters.h"
|
||||||
#include "IopCounters.h"
|
#include "IopCounters.h"
|
||||||
|
@ -27,6 +27,8 @@
|
||||||
#include "GS.h"
|
#include "GS.h"
|
||||||
#include "VUmicro.h"
|
#include "VUmicro.h"
|
||||||
|
|
||||||
|
#include "ps2/HwInternal.h"
|
||||||
|
|
||||||
using namespace Threading;
|
using namespace Threading;
|
||||||
|
|
||||||
extern u8 psxhblankgate;
|
extern u8 psxhblankgate;
|
||||||
|
@ -45,6 +47,15 @@ SyncCounter vsyncCounter;
|
||||||
u32 nextsCounter; // records the cpuRegs.cycle value of the last call to rcntUpdate()
|
u32 nextsCounter; // records the cpuRegs.cycle value of the last call to rcntUpdate()
|
||||||
s32 nextCounter; // delta from nextsCounter, in cycles, until the next 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) {
|
void rcntReset(int index) {
|
||||||
counters[index].count = 0;
|
counters[index].count = 0;
|
||||||
|
@ -575,7 +586,7 @@ static __fi void _rcntSetGate( int index )
|
||||||
}
|
}
|
||||||
|
|
||||||
// mode - 0 means hblank source, 8 means vblank source.
|
// 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;
|
int i;
|
||||||
|
|
||||||
|
@ -636,7 +647,7 @@ __fi void rcntStartGate(bool isVblank, u32 sCycle)
|
||||||
}
|
}
|
||||||
|
|
||||||
// mode - 0 means hblank signal, 8 means vblank signal.
|
// 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;
|
int i;
|
||||||
|
|
||||||
|
@ -677,7 +688,15 @@ __fi void rcntEndGate(bool isVblank , u32 sCycle)
|
||||||
// rcntUpdate, since we're being called from there anyway.
|
// 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.IsCounting) {
|
||||||
if(counters[index].mode.ClockSource != 0x3) {
|
if(counters[index].mode.ClockSource != 0x3) {
|
||||||
|
@ -711,7 +730,7 @@ __fi void rcntWmode(int index, u32 value)
|
||||||
_rcntSet( index );
|
_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 );
|
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 );
|
_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);
|
EECNT_LOG("EE Counter[%d] writeTarget = %x", index, value);
|
||||||
|
|
||||||
|
@ -766,7 +785,7 @@ __fi void rcntWtarget(int index, u32 value)
|
||||||
_rcntSet( index );
|
_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);
|
EECNT_LOG("EE Counter[%d] Hold Write = %x", index, value);
|
||||||
counters[index].hold = value;
|
counters[index].hold = value;
|
||||||
|
@ -787,14 +806,76 @@ __fi u32 rcntRcount(int index)
|
||||||
return ret;
|
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))
|
// Important DevNote:
|
||||||
return counters[index].count + ((cpuRegs.cycle - counters[index].sCycleT) / counters[index].rate);
|
// Yes this uses a u16 return value on purpose! The upper bits 16 of the counter registers
|
||||||
else
|
// are all fixed to 0, so we always truncate everything in these two pages using a u16
|
||||||
return counters[index].count;
|
// 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()
|
void SaveStateBase::rcntFreeze()
|
||||||
{
|
{
|
||||||
Freeze( counters );
|
Freeze( counters );
|
||||||
|
|
|
@ -13,8 +13,7 @@
|
||||||
* If not, see <http://www.gnu.org/licenses/>.
|
* If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __COUNTERS_H__
|
#pragma once
|
||||||
#define __COUNTERS_H__
|
|
||||||
|
|
||||||
struct EECNT_MODE
|
struct EECNT_MODE
|
||||||
{
|
{
|
||||||
|
@ -137,16 +136,10 @@ extern void rcntUpdate_vSync();
|
||||||
extern void rcntUpdate();
|
extern void rcntUpdate();
|
||||||
|
|
||||||
extern void rcntInit();
|
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 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 u32 UpdateVSyncRate();
|
||||||
extern void frameLimitReset();
|
extern void frameLimitReset();
|
||||||
|
|
||||||
#endif /* __COUNTERS_H__ */
|
|
||||||
|
|
|
@ -342,17 +342,19 @@ struct SysConsoleLogPack
|
||||||
extern SysTraceLogPack SysTrace;
|
extern SysTraceLogPack SysTrace;
|
||||||
extern SysConsoleLogPack SysConsole;
|
extern SysConsoleLogPack SysConsole;
|
||||||
|
|
||||||
|
extern void __Log( const char* fmt, ... );
|
||||||
|
|
||||||
// Helper macro for cut&paste. Note that we intentionally use a top-level *inline* bitcheck
|
// 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.
|
// 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
|
// (specifically this allows debug builds to skip havingto resolve all the parameters being
|
||||||
// passed into the function)
|
// passed into the function)
|
||||||
#define macTrace(trace) SysTrace.trace.IsActive() && SysTrace.trace.Write
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef PCSX2_DEVBUILD
|
#ifdef PCSX2_DEVBUILD
|
||||||
|
# define SysTraceActive(trace) SysTrace.trace.IsActive()
|
||||||
extern void __Log( const char* fmt, ... );
|
# define macTrace(trace) SysTraceActive(trace) && SysTrace.trace.Write
|
||||||
|
#else
|
||||||
|
# define SysTraceActive(trace) (false)
|
||||||
|
# define macTrace(trace)
|
||||||
|
#endif
|
||||||
|
|
||||||
#define SIF_LOG macTrace(SIF)
|
#define SIF_LOG macTrace(SIF)
|
||||||
|
|
||||||
|
@ -385,45 +387,9 @@ extern void __Log( const char* fmt, ... );
|
||||||
#define GPU_LOG macTrace(IOP.GPU)
|
#define GPU_LOG macTrace(IOP.GPU)
|
||||||
#define CDVD_LOG macTrace(IOP.CDVD)
|
#define CDVD_LOG macTrace(IOP.CDVD)
|
||||||
|
|
||||||
#else // PCSX2_DEVBUILD
|
|
||||||
|
|
||||||
#define CPU_LOG 0&&
|
#define ELF_LOG SysConsole.ELF.IsActive() && SysConsole.ELF.Write
|
||||||
#define MEM_LOG 0&&
|
#define eeRecPerfLog SysConsole.eeRecPerf.IsActive() && SysConsole.eeRecPerf
|
||||||
#define HW_LOG 0&&
|
#define eeConLog SysConsole.eeConsole.IsActive() && SysConsole.eeConsole.Write
|
||||||
#define DMA_LOG 0&&
|
#define eeDeci2Log SysConsole.deci2.IsActive() && SysConsole.deci2.Write
|
||||||
#define BIOS_LOG 0&&
|
#define iopConLog SysConsole.iopConsole.IsActive()&& SysConsole.iopConsole.Write
|
||||||
#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
|
|
||||||
|
|
161
pcsx2/Dmac.h
161
pcsx2/Dmac.h
|
@ -171,10 +171,6 @@ union tDMA_QWC {
|
||||||
tDMA_TAG tag() const { return (tDMA_TAG)_u32; }
|
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 {
|
struct DMACh {
|
||||||
tDMA_CHCR chcr;
|
tDMA_CHCR chcr;
|
||||||
u32 _null0[3];
|
u32 _null0[3];
|
||||||
|
@ -200,63 +196,14 @@ struct DMACh {
|
||||||
qwc = ptag[0].QWC;
|
qwc = ptag[0].QWC;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool transfer(const char *s, tDMA_TAG* ptag)
|
bool transfer(const char *s, tDMA_TAG* ptag);
|
||||||
{
|
void unsafeTransfer(tDMA_TAG* ptag);
|
||||||
if (ptag == NULL) // Is ptag empty?
|
tDMA_TAG *getAddr(u32 addr, u32 num, bool write);
|
||||||
{
|
tDMA_TAG *DMAtransfer(u32 addr, u32 num);
|
||||||
throwBusError(s);
|
tDMA_TAG dma_tag();
|
||||||
return false;
|
|
||||||
}
|
|
||||||
chcrTransfer(ptag);
|
|
||||||
|
|
||||||
qwcTransfer(ptag);
|
wxString cmq_to_str() const;
|
||||||
return true;
|
wxString cmqt_to_str() const;
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
enum INTCIrqs
|
enum INTCIrqs
|
||||||
|
@ -524,7 +471,7 @@ union tDMAC_ADDR
|
||||||
|
|
||||||
wxCharBuffer ToUTF8(bool sprIsValid=true) const
|
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];
|
u32 _padding2[3];
|
||||||
};
|
};
|
||||||
|
|
||||||
#define dmacRegs ((DMACregisters*)(eeMem->HW+0xE000))
|
#define intcRegs ((INTCregisters*)(eeHw+0xF000))
|
||||||
#define intcRegs ((INTCregisters*)(eeMem->HW+0xF000))
|
|
||||||
|
|
||||||
static __fi void throwBusError(const char *s)
|
static DMACregisters& dmacRegs = (DMACregisters&)eeHw[0xE000];
|
||||||
{
|
|
||||||
Console.Error("%s BUSERR", s);
|
|
||||||
dmacRegs->stat.BEIS = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static __fi void setDmacStat(u32 num)
|
// Various useful locations
|
||||||
{
|
static DMACh& vif0ch = (DMACh&)eeHw[0x8000];
|
||||||
dmacRegs->stat.set_flags(1 << num);
|
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)
|
extern void throwBusError(const char *s);
|
||||||
static __fi tDMA_TAG *SPRdmaGetAddr(u32 addr, bool write)
|
extern void setDmacStat(u32 num);
|
||||||
{
|
extern tDMA_TAG *SPRdmaGetAddr(u32 addr, bool write);
|
||||||
// if (addr & 0xf) { DMA_LOG("*PCSX2*: DMA address not 128bit aligned: %8.8x", addr); }
|
extern tDMA_TAG *dmaGetAddr(u32 addr, bool write);
|
||||||
|
|
||||||
//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 hwIntcIrq(int n);
|
extern void hwIntcIrq(int n);
|
||||||
extern void hwDmacIrq(int n);
|
extern void hwDmacIrq(int n);
|
||||||
|
|
||||||
extern bool hwMFIFOWrite(u32 addr, const u128* data, uint size_qwc);
|
extern bool hwMFIFOWrite(u32 addr, const u128* data, uint size_qwc);
|
||||||
extern bool hwDmacSrcChainWithStack(DMACh *dma, int id);
|
extern bool hwDmacSrcChainWithStack(DMACh& dma, int id);
|
||||||
extern bool hwDmacSrcChain(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 );
|
||||||
|
|
|
@ -129,10 +129,10 @@ void iDumpRegisters(u32 startpc, u32 temp)
|
||||||
__Log("gif: %x %x %x", psHu32(0x3000), psHu32(0x3010), psHu32(0x3020));
|
__Log("gif: %x %x %x", psHu32(0x3000), psHu32(0x3010), psHu32(0x3020));
|
||||||
|
|
||||||
for(i = 0; i < ArraySize(dmacs); ++i) {
|
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("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(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));
|
__Log("sif: %x %x %x %x %x", psHu32(SBUS_F200), psHu32(SBUS_F220), psHu32(SBUS_F230), psHu32(SBUS_F240), psHu32(SBUS_F260));
|
||||||
#endif
|
#endif
|
||||||
|
|
131
pcsx2/FiFo.cpp
131
pcsx2/FiFo.cpp
|
@ -28,8 +28,6 @@
|
||||||
/////////////////////////// Quick & dirty FIFO :D ////////////////////////
|
/////////////////////////// Quick & dirty FIFO :D ////////////////////////
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
// ** NOTE: cannot use XMM/MMX regs **
|
|
||||||
|
|
||||||
// Notes on FIFO implementation
|
// Notes on FIFO implementation
|
||||||
//
|
//
|
||||||
// The FIFO consists of four separate pages of HW register memory, each mapped to a
|
// 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)
|
// 0x6000 - 0x7000 : GS (all registers map to 0x6000)
|
||||||
// 0x7000 - 0x8000 : IPU (registers map to 0x7000 and 0x7010, respectively)
|
// 0x7000 - 0x8000 : IPU (registers map to 0x7000 and 0x7010, respectively)
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
void __fastcall ReadFIFO_VIF1(mem128_t* out)
|
||||||
// ReadFIFO Pages
|
|
||||||
|
|
||||||
void __fastcall ReadFIFO_page_4(u32 mem, mem128_t* out)
|
|
||||||
{
|
{
|
||||||
pxAssert( (mem >= VIF0_FIFO) && (mem < VIF1_FIFO) );
|
if (vif1Regs.stat.test(VIF1_STAT_INT | VIF1_STAT_VSS | VIF1_STAT_VIS | VIF1_STAT_VFS) )
|
||||||
|
|
||||||
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) )
|
|
||||||
DevCon.Warning( "Reading from vif1 fifo when stalled" );
|
DevCon.Warning( "Reading from vif1 fifo when stalled" );
|
||||||
|
|
||||||
if(vif1Regs->stat.FQC == 0) Console.Warning("FQC = 0 on VIF FIFO READ!");
|
pxAssertRel(vif1Regs.stat.FQC != 0, "FQC = 0 on VIF FIFO READ!");
|
||||||
if (vif1Regs->stat.FDR)
|
if (vif1Regs.stat.FDR)
|
||||||
{
|
{
|
||||||
if(vif1Regs->stat.FQC > vif1.GSLastDownloadSize)
|
if(vif1Regs.stat.FQC > vif1.GSLastDownloadSize)
|
||||||
{
|
{
|
||||||
DevCon.Warning("Warning! GS Download size < FIFO count!");
|
DevCon.Warning("Warning! GS Download size < FIFO count!");
|
||||||
}
|
}
|
||||||
if (vif1Regs->stat.FQC > 0)
|
if (vif1Regs.stat.FQC > 0)
|
||||||
{
|
{
|
||||||
GetMTGS().WaitGS();
|
GetMTGS().WaitGS();
|
||||||
GSreadFIFO(&psHu64(VIF1_FIFO));
|
GSreadFIFO(&psHu64(VIF1_FIFO));
|
||||||
vif1.GSLastDownloadSize--;
|
vif1.GSLastDownloadSize--;
|
||||||
if (vif1.GSLastDownloadSize <= 16)
|
if (vif1.GSLastDownloadSize <= 16)
|
||||||
gifRegs->stat.OPH = false;
|
gifRegs.stat.OPH = false;
|
||||||
vif1Regs->stat.FQC = min((u32)16, vif1.GSLastDownloadSize);
|
vif1Regs.stat.FQC = min((u32)16, vif1.GSLastDownloadSize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CopyQWC( out, &psHu128(VIF1_FIFO) );
|
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
|
// 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 <- %ls", value->ToString().c_str());
|
||||||
|
|
||||||
VIF_LOG("WriteFIFO/VIF0, addr=0x%08X", mem);
|
|
||||||
|
|
||||||
CopyQWC(&psHu128(VIF0_FIFO), value);
|
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!");
|
if(vif0.irqoffset != 0 && vif0.vifstalled == true) DevCon.Warning("Offset on VIF0 FIFO start!");
|
||||||
bool ret = VIF0transfer((u32*)value, 4);
|
bool ret = VIF0transfer((u32*)value, 4);
|
||||||
|
|
||||||
if (vif0.cmd)
|
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
|
else
|
||||||
{
|
{
|
||||||
vif0Regs->stat.VPS = VPS_IDLE;
|
vif0Regs.stat.VPS = VPS_IDLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
pxAssertDev( ret, "vif stall code not implemented" );
|
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 <- %ls", value->ToString().c_str());
|
||||||
|
|
||||||
VIF_LOG("WriteFIFO/VIF1, addr=0x%08X", mem);
|
|
||||||
|
|
||||||
CopyQWC(&psHu128(VIF1_FIFO), value);
|
CopyQWC(&psHu128(VIF1_FIFO), value);
|
||||||
|
|
||||||
if (vif1Regs->stat.FDR)
|
if (vif1Regs.stat.FDR)
|
||||||
DevCon.Warning("writing to fifo when fdr is set!");
|
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");
|
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!");
|
if(vif1.irqoffset != 0 && vif1.vifstalled == true) DevCon.Warning("Offset on VIF1 FIFO start!");
|
||||||
bool ret = VIF1transfer((u32*)value, 4);
|
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;
|
if(gifRegs.stat.DIR == 0)gifRegs.stat.OPH = false;
|
||||||
gifRegs->stat.APATH = GIF_APATH_IDLE;
|
gifRegs.stat.APATH = GIF_APATH_IDLE;
|
||||||
if(gifRegs->stat.P1Q) gsPath1Interrupt();
|
if(gifRegs.stat.P1Q) gsPath1Interrupt();
|
||||||
}
|
}
|
||||||
if (vif1.cmd)
|
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
|
else
|
||||||
{
|
{
|
||||||
vif1Regs->stat.VPS = VPS_IDLE;
|
vif1Regs.stat.VPS = VPS_IDLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
pxAssertDev( ret, "vif stall code not implemented" );
|
pxAssertDev( ret, "vif stall code not implemented" );
|
||||||
}
|
}
|
||||||
|
|
||||||
// Dummy GIF-TAG Packet to Guarantee Count = 1
|
// 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 <- %ls", value->ToString().c_str());
|
||||||
GIF_LOG("WriteFIFO/GIF, addr=0x%08X", mem);
|
|
||||||
|
|
||||||
CopyQWC(&psHu128(GIF_FIFO), value);
|
CopyQWC(&psHu128(GIF_FIFO), value);
|
||||||
CopyQWC(nloop0_packet, value);
|
CopyQWC(&nloop0_packet, value);
|
||||||
|
|
||||||
GetMTGS().PrepDataPacket(GIF_PATH_3, 1);
|
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();
|
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;
|
if(gifRegs.stat.DIR == 0)gifRegs.stat.OPH = false;
|
||||||
gifRegs->stat.APATH = GIF_APATH_IDLE;
|
gifRegs.stat.APATH = GIF_APATH_IDLE;
|
||||||
if(gifRegs->stat.P1Q) gsPath1Interrupt();
|
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();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
16
pcsx2/GS.cpp
16
pcsx2/GS.cpp
|
@ -56,9 +56,9 @@ extern u32 SIGNAL_Data_Pending[2];
|
||||||
|
|
||||||
void gsGIFReset()
|
void gsGIFReset()
|
||||||
{
|
{
|
||||||
gifRegs->stat.reset();
|
gifRegs.stat.reset();
|
||||||
gifRegs->ctrl.reset();
|
gifRegs.ctrl.reset();
|
||||||
gifRegs->mode.reset();
|
gifRegs.mode.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
void gsReset()
|
void gsReset()
|
||||||
|
@ -128,7 +128,7 @@ static __fi void gsCSRwrite( const tGS_CSR& csr )
|
||||||
|
|
||||||
SIGNAL_IMR_Pending = false;
|
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;
|
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 :(.
|
//Only problem is it kills killzone :(.
|
||||||
// (yes it *is* a complete hack; both lines here in fact --air)
|
// (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
|
// BUSDIR INSANITY !! MTGS FLUSH NEEDED
|
||||||
//
|
//
|
||||||
|
@ -459,9 +459,7 @@ void SaveStateBase::gsFreeze()
|
||||||
{
|
{
|
||||||
FreezeMem(PS2MEM_GS, 0x2000);
|
FreezeMem(PS2MEM_GS, 0x2000);
|
||||||
Freeze(SIGNAL_IMR_Pending);
|
Freeze(SIGNAL_IMR_Pending);
|
||||||
|
Freeze(gsRegionMode);
|
||||||
if( GetVersion() > 0 )
|
|
||||||
Freeze(gsRegionMode);
|
|
||||||
|
|
||||||
gifPathFreeze();
|
gifPathFreeze();
|
||||||
}
|
}
|
||||||
|
|
268
pcsx2/Gif.cpp
268
pcsx2/Gif.cpp
|
@ -54,9 +54,9 @@ void gsPath1Interrupt()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if((gifRegs->stat.APATH <= GIF_APATH1 || (gifRegs->stat.IP3 == true && gifRegs->stat.APATH == GIF_APATH3)) && Path1WritePos > 0 && !gifRegs->stat.PSE)
|
if((gifRegs.stat.APATH <= GIF_APATH1 || (gifRegs.stat.IP3 == true && gifRegs.stat.APATH == GIF_APATH3)) && Path1WritePos > 0 && !gifRegs.stat.PSE)
|
||||||
{
|
{
|
||||||
gifRegs->stat.P1Q = false;
|
gifRegs.stat.P1Q = false;
|
||||||
|
|
||||||
if (uint size = (Path1WritePos - Path1ReadPos))
|
if (uint size = (Path1WritePos - Path1ReadPos))
|
||||||
{
|
{
|
||||||
|
@ -70,8 +70,8 @@ void gsPath1Interrupt()
|
||||||
|
|
||||||
if(GSTransferStatus.PTH1 == STOPPED_MODE)
|
if(GSTransferStatus.PTH1 == STOPPED_MODE)
|
||||||
{
|
{
|
||||||
gifRegs->stat.OPH = false;
|
gifRegs.stat.OPH = false;
|
||||||
gifRegs->stat.APATH = GIF_APATH_IDLE;
|
gifRegs.stat.APATH = GIF_APATH_IDLE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
GetMTGS().SendDataPacket();
|
GetMTGS().SendDataPacket();
|
||||||
|
@ -84,8 +84,8 @@ void gsPath1Interrupt()
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if(gifRegs->stat.PSE) DevCon.Warning("Path1 paused by GIF_CTRL");
|
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);
|
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);
|
//if(!(cpuRegs.interrupt & (1<<28)) && Path1WritePos > 0)CPU_INT(28, 128);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -104,25 +104,25 @@ __fi void gsInterrupt()
|
||||||
return;
|
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;
|
GSTransferStatus.PTH3 = STOPPED_MODE;
|
||||||
gifRegs->stat.APATH = GIF_APATH_IDLE;
|
gifRegs.stat.APATH = GIF_APATH_IDLE;
|
||||||
if(gifRegs->stat.P1Q) gsPath1Interrupt();
|
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;
|
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...");
|
Console.Warning("gs dma masked, re-scheduling...");
|
||||||
// re-raise the int shortly in the future
|
// re-raise the int shortly in the future
|
||||||
|
@ -136,14 +136,14 @@ __fi void gsInterrupt()
|
||||||
|
|
||||||
gspath3done = false;
|
gspath3done = false;
|
||||||
gscycles = 0;
|
gscycles = 0;
|
||||||
gif->chcr.STR = false;
|
gifch.chcr.STR = false;
|
||||||
|
|
||||||
////
|
////
|
||||||
/*gifRegs->stat.OPH = false;
|
/*gifRegs.stat.OPH = false;
|
||||||
GSTransferStatus.PTH3 = STOPPED_MODE;
|
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);
|
clearFIFOstuff(false);
|
||||||
hwDmacIrq(DMAC_GIF);
|
hwDmacIrq(DMAC_GIF);
|
||||||
//DevCon.Warning("GIF DMA end");
|
//DevCon.Warning("GIF DMA end");
|
||||||
|
@ -166,20 +166,20 @@ int _GIFchain()
|
||||||
{
|
{
|
||||||
tDMA_TAG *pMem;
|
tDMA_TAG *pMem;
|
||||||
|
|
||||||
pMem = dmaGetAddr(gif->madr, false);
|
pMem = dmaGetAddr(gifch.madr, false);
|
||||||
if (pMem == NULL)
|
if (pMem == NULL)
|
||||||
{
|
{
|
||||||
// reset path3, fixes dark cloud 2
|
// reset path3, fixes dark cloud 2
|
||||||
GIFPath_Clear( GIF_PATH_3 );
|
GIFPath_Clear( GIF_PATH_3 );
|
||||||
|
|
||||||
//must increment madr and clear qwc, else it loops
|
//must increment madr and clear qwc, else it loops
|
||||||
gif->madr += gif->qwc * 16;
|
gifch.madr += gifch.qwc * 16;
|
||||||
gif->qwc = 0;
|
gifch.qwc = 0;
|
||||||
Console.Warning( "Hackfix - NULL GIFchain" );
|
Console.Warning( "Hackfix - NULL GIFchain" );
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return WRITERING_DMA(pMem, gif->qwc);
|
return WRITERING_DMA(pMem, gifch.qwc);
|
||||||
}
|
}
|
||||||
|
|
||||||
static __fi void GIFchain()
|
static __fi void GIFchain()
|
||||||
|
@ -187,12 +187,12 @@ static __fi void GIFchain()
|
||||||
// qwc check now done outside this function
|
// qwc check now done outside this function
|
||||||
// Voodoocycles
|
// Voodoocycles
|
||||||
// >> 2 so Drakan and Tekken 5 don't mess up in some PATH3 transfer. Cycles to interrupt were getting huge..
|
// >> 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)
|
static __fi bool checkTieBit(tDMA_TAG* &ptag)
|
||||||
{
|
{
|
||||||
if (gif->chcr.TIE && ptag->IRQ)
|
if (gifch.chcr.TIE && ptag->IRQ)
|
||||||
{
|
{
|
||||||
GIF_LOG("dmaIrq Set");
|
GIF_LOG("dmaIrq Set");
|
||||||
gspath3done = true;
|
gspath3done = true;
|
||||||
|
@ -204,38 +204,38 @@ static __fi bool checkTieBit(tDMA_TAG* &ptag)
|
||||||
|
|
||||||
static __fi tDMA_TAG* ReadTag()
|
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
|
gscycles += 2; // Add 1 cycles from the QW read for the tag
|
||||||
|
|
||||||
gspath3done = hwDmacSrcChainWithStack(gif, ptag->ID);
|
gspath3done = hwDmacSrcChainWithStack(gifch, ptag->ID);
|
||||||
return ptag;
|
return ptag;
|
||||||
}
|
}
|
||||||
|
|
||||||
static __fi tDMA_TAG* ReadTag2()
|
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);
|
gifch.unsafeTransfer(ptag);
|
||||||
gif->madr = ptag[1]._u32;
|
gifch.madr = ptag[1]._u32;
|
||||||
|
|
||||||
gspath3done = hwDmacSrcChainWithStack(gif, ptag->ID);
|
gspath3done = hwDmacSrcChainWithStack(gifch, ptag->ID);
|
||||||
return ptag;
|
return ptag;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CheckPaths(int Channel)
|
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;
|
gifRegs.stat.IP3 = true;
|
||||||
if(gifRegs->stat.P1Q) gsPath1Interrupt();
|
if(gifRegs.stat.P1Q) gsPath1Interrupt();
|
||||||
CPU_INT(DMAC_GIF, 16);
|
CPU_INT(DMAC_GIF, 16);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -244,15 +244,15 @@ bool CheckPaths(int Channel)
|
||||||
else if((GSTransferStatus.PTH3 == IDLE_MODE)|| (GSTransferStatus.PTH3 == STOPPED_MODE))
|
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).
|
//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);
|
CPU_INT(DMAC_GIF, 16);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
gifRegs->stat.IP3 = false;
|
gifRegs.stat.IP3 = false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -262,18 +262,18 @@ void GIFdma()
|
||||||
|
|
||||||
gscycles = prevcycles;
|
gscycles = prevcycles;
|
||||||
|
|
||||||
if (gifRegs->ctrl.PSE) // temporarily stop
|
if (gifRegs.ctrl.PSE) // temporarily stop
|
||||||
{
|
{
|
||||||
Console.WriteLn("Gif dma temp paused? (non MFIFO GIF)");
|
Console.WriteLn("Gif dma temp paused? (non MFIFO GIF)");
|
||||||
CPU_INT(DMAC_GIF, 16);
|
CPU_INT(DMAC_GIF, 16);
|
||||||
return;
|
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);
|
CPU_INT(DMAC_GIF, 4);
|
||||||
gscycles = 0;
|
gscycles = 0;
|
||||||
|
@ -281,24 +281,24 @@ void GIFdma()
|
||||||
}
|
}
|
||||||
|
|
||||||
prevcycles = 0;
|
prevcycles = 0;
|
||||||
gif->qwc = 0;
|
gifch.qwc = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
clearFIFOstuff(true);
|
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();
|
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;
|
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
|
//Check TIE bit of CHCR and IRQ bit of tag
|
||||||
if (checkTieBit(ptag)) GIF_LOG("PATH3 MSK dmaIrq Set");
|
if (checkTieBit(ptag)) GIF_LOG("PATH3 MSK dmaIrq Set");
|
||||||
|
@ -308,26 +308,26 @@ void GIFdma()
|
||||||
|
|
||||||
if (GSTransferStatus.PTH3 == IDLE_MODE)
|
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();
|
if(gifch.qwc == 0) gsInterrupt();
|
||||||
else gifRegs->stat.set_flags(GIF_STAT_P3Q);
|
else gifRegs.stat.set_flags(GIF_STAT_P3Q);
|
||||||
return;
|
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
|
//Check with Path3 masking games
|
||||||
if (gif->qwc > 0) {
|
if (gifch.qwc > 0) {
|
||||||
gifRegs->stat.set_flags(GIF_STAT_P3Q);
|
gifRegs.stat.set_flags(GIF_STAT_P3Q);
|
||||||
if(CheckPaths(DMAC_GIF) == false) return;
|
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");
|
GIF_LOG("PTH3 MASK Transferring");
|
||||||
GIFchain();
|
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;
|
GSTransferStatus.PTH3 = STOPPED_MODE;
|
||||||
}*/
|
}*/
|
||||||
|
@ -338,54 +338,54 @@ void GIFdma()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Transfer Dn_QWC from Dn_MADR to GIF
|
// 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");
|
//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
|
//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) {
|
if (gifch.qwc > 0) {
|
||||||
gifRegs->stat.set_flags(GIF_STAT_P3Q);
|
gifRegs.stat.set_flags(GIF_STAT_P3Q);
|
||||||
if(CheckPaths(DMAC_GIF) == false) return;
|
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
|
GIFchain(); //Transfers the data set by the switch
|
||||||
CPU_INT(DMAC_GIF, gscycles);
|
CPU_INT(DMAC_GIF, gscycles);
|
||||||
return;
|
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
|
//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();
|
ptag = ReadTag();
|
||||||
if (ptag == NULL) return;
|
if (ptag == NULL) return;
|
||||||
//DevCon.Warning("GIF Reading Tag MSK = %x", vif1Regs->mskpath3);
|
//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);
|
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, 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 (dmacRegs->ctrl.STD == STD_GIF)
|
if (dmacRegs.ctrl.STD == STD_GIF)
|
||||||
{
|
{
|
||||||
// there are still bugs, need to also check if gif->madr +16*qwc >= stadr, if not, stall
|
// there are still bugs, need to also check if gifch.madr +16*qwc >= stadr, if not, stall
|
||||||
if (!gspath3done && ((gif->madr + (gif->qwc * 16)) > dmacRegs->stadr.ADDR) && (ptag->ID == TAG_REFS))
|
if (!gspath3done && ((gifch.madr + (gifch.qwc * 16)) > dmacRegs.stadr.ADDR) && (ptag->ID == TAG_REFS))
|
||||||
{
|
{
|
||||||
// stalled.
|
// stalled.
|
||||||
// We really need to test this. Pay attention to prevcycles, as it used to trigger GIFchains in the code above. (rama)
|
// 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;
|
prevcycles = gscycles;
|
||||||
//gif->tadr -= 16;
|
//gifch.tadr -= 16;
|
||||||
// Quake III revolution wants to see tadr move.
|
// Quake III revolution wants to see tadr move.
|
||||||
// Simple Media System (homebrew) as well.
|
// Simple Media System (homebrew) as well.
|
||||||
// -16 also seems right (it shifts the bg image right if anything else).
|
// -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
|
// Next line also needs to be here, according to ref
|
||||||
gif->qwc = 0;
|
gifch.qwc = 0;
|
||||||
hwDmacIrq(DMAC_STALL_SIS);
|
hwDmacIrq(DMAC_STALL_SIS);
|
||||||
CPU_INT(DMAC_GIF, gscycles);
|
CPU_INT(DMAC_GIF, gscycles);
|
||||||
gscycles = 0;
|
gscycles = 0;
|
||||||
|
@ -394,7 +394,7 @@ void GIFdma()
|
||||||
}
|
}
|
||||||
|
|
||||||
checkTieBit(ptag);
|
checkTieBit(ptag);
|
||||||
/*if(gif->qwc == 0)
|
/*if(gifch.qwc == 0)
|
||||||
{
|
{
|
||||||
gsInterrupt();
|
gsInterrupt();
|
||||||
return;
|
return;
|
||||||
|
@ -403,34 +403,34 @@ void GIFdma()
|
||||||
|
|
||||||
prevcycles = 0;
|
prevcycles = 0;
|
||||||
CPU_INT(DMAC_GIF, gscycles);
|
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()
|
void dmaGIF()
|
||||||
{
|
{
|
||||||
//We used to add wait time for the buffer to fill here, fixing some timing problems in path 3 masking
|
//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
|
//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 :)
|
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;
|
gspath3done = true;
|
||||||
}
|
}
|
||||||
clearFIFOstuff(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());
|
//DevCon.Warning(L"GIF QWC on Chain " + gifch.chcr.desc());
|
||||||
if ((gif->chcr.tag().ID == TAG_REFE) || (gif->chcr.tag().ID == TAG_END))
|
if ((gifch.chcr.tag().ID == TAG_REFE) || (gifch.chcr.tag().ID == TAG_END))
|
||||||
{
|
{
|
||||||
gspath3done = true;
|
gspath3done = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dmacRegs->ctrl.MFD == MFD_GIF) // GIF MFIFO
|
if (dmacRegs.ctrl.MFD == MFD_GIF) // GIF MFIFO
|
||||||
{
|
{
|
||||||
//Console.WriteLn("GIF MFIFO");
|
//Console.WriteLn("GIF MFIFO");
|
||||||
gifMFIFOInterrupt();
|
gifMFIFOInterrupt();
|
||||||
|
@ -443,7 +443,7 @@ void dmaGIF()
|
||||||
// called from only one location, so forceinline it:
|
// called from only one location, so forceinline it:
|
||||||
static __fi bool mfifoGIFrbTransfer()
|
static __fi bool mfifoGIFrbTransfer()
|
||||||
{
|
{
|
||||||
u32 mfifoqwc = min(gifqwc, (u32)gif->qwc);
|
u32 mfifoqwc = min(gifqwc, (u32)gifch.qwc);
|
||||||
u32 *src;
|
u32 *src;
|
||||||
|
|
||||||
GetMTGS().PrepDataPacket(GIF_PATH_3, mfifoqwc);
|
GetMTGS().PrepDataPacket(GIF_PATH_3, mfifoqwc);
|
||||||
|
@ -453,21 +453,21 @@ static __fi bool mfifoGIFrbTransfer()
|
||||||
// memory similarly to how it wraps VU1 memory on PATH1.
|
// memory similarly to how it wraps VU1 memory on PATH1.
|
||||||
|
|
||||||
/* Check if the transfer should wrap around the ring buffer */
|
/* 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);
|
uint s2 = (mfifoqwc - s1);
|
||||||
|
|
||||||
/* it does (wrap around), so first copy 's1' bytes from 'addr' to 'data' */
|
/* it does (wrap around), so first copy 's1' bytes from 'addr' to 'data' */
|
||||||
/* and second copy 's2' bytes from 'maddr' to '&data[s1]' */
|
/* 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;
|
if (src == NULL) return false;
|
||||||
uint copied = GIFPath_CopyTag(GIF_PATH_3, (u128*)src, s1);
|
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.
|
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;
|
if (src == NULL) return false;
|
||||||
copied += GIFPath_CopyTag(GIF_PATH_3, (u128*)src, s2);
|
copied += GIFPath_CopyTag(GIF_PATH_3, (u128*)src, s2);
|
||||||
}
|
}
|
||||||
|
@ -476,11 +476,11 @@ static __fi bool mfifoGIFrbTransfer()
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* it doesn't, so just transfer 'qwc*16' words from 'gif->madr' to GS */
|
/* it doesn't, so just transfer 'qwc*16' words from 'gifch.madr' to GS */
|
||||||
src = (u32*)PSM(gif->madr);
|
src = (u32*)PSM(gifch.madr);
|
||||||
if (src == NULL) return false;
|
if (src == NULL) return false;
|
||||||
mfifoqwc = GIFPath_CopyTag(GIF_PATH_3, (u128*)src, mfifoqwc);
|
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();
|
GetMTGS().SendDataPacket();
|
||||||
|
@ -493,10 +493,10 @@ static __fi bool mfifoGIFrbTransfer()
|
||||||
static __fi bool mfifoGIFchain()
|
static __fi bool mfifoGIFchain()
|
||||||
{
|
{
|
||||||
/* Is QWC = 0? if so there is nothing to transfer */
|
/* 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 &&
|
if (gifch.madr >= dmacRegs.rbor.ADDR &&
|
||||||
gif->madr <= (dmacRegs->rbor.ADDR + dmacRegs->rbsr.RMSK))
|
gifch.madr <= (dmacRegs.rbor.ADDR + dmacRegs.rbsr.RMSK))
|
||||||
{
|
{
|
||||||
if (!mfifoGIFrbTransfer()) return false;
|
if (!mfifoGIFrbTransfer()) return false;
|
||||||
}
|
}
|
||||||
|
@ -504,10 +504,10 @@ static __fi bool mfifoGIFchain()
|
||||||
{
|
{
|
||||||
int mfifoqwc;
|
int mfifoqwc;
|
||||||
|
|
||||||
tDMA_TAG *pMem = dmaGetAddr(gif->madr, false);
|
tDMA_TAG *pMem = dmaGetAddr(gifch.madr, false);
|
||||||
if (pMem == NULL) return false;
|
if (pMem == NULL) return false;
|
||||||
|
|
||||||
mfifoqwc = WRITERING_DMA(pMem, gif->qwc);
|
mfifoqwc = WRITERING_DMA(pMem, gifch.qwc);
|
||||||
mfifocycles += (mfifoqwc) * 2; /* guessing */
|
mfifocycles += (mfifoqwc) * 2; /* guessing */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -516,7 +516,7 @@ static __fi bool mfifoGIFchain()
|
||||||
|
|
||||||
static u32 qwctag(u32 mask)
|
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)
|
void mfifoGIFtransfer(int qwc)
|
||||||
|
@ -536,16 +536,16 @@ void mfifoGIFtransfer(int qwc)
|
||||||
gifempty = false;
|
gifempty = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gifRegs->ctrl.PSE) // temporarily stop
|
if (gifRegs.ctrl.PSE) // temporarily stop
|
||||||
{
|
{
|
||||||
Console.WriteLn("Gif dma temp paused?");
|
Console.WriteLn("Gif dma temp paused?");
|
||||||
CPU_INT(DMAC_MFIFO_GIF, 16);
|
CPU_INT(DMAC_MFIFO_GIF, 16);
|
||||||
return;
|
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);
|
//if( gifqwc > 1 ) DevCon.WriteLn("gif mfifo tadr==madr but qwc = %d", gifqwc);
|
||||||
hwDmacIrq(DMAC_MFIFO_EMPTY);
|
hwDmacIrq(DMAC_MFIFO_EMPTY);
|
||||||
|
@ -554,55 +554,55 @@ void mfifoGIFtransfer(int qwc)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
gif->tadr = qwctag(gif->tadr);
|
gifch.tadr = qwctag(gifch.tadr);
|
||||||
|
|
||||||
ptag = dmaGetAddr(gif->tadr, false);
|
ptag = dmaGetAddr(gifch.tadr, false);
|
||||||
gif->unsafeTransfer(ptag);
|
gifch.unsafeTransfer(ptag);
|
||||||
gif->madr = ptag[1]._u32;
|
gifch.madr = ptag[1]._u32;
|
||||||
|
|
||||||
mfifocycles += 2;
|
mfifocycles += 2;
|
||||||
|
|
||||||
GIF_LOG("dmaChain %8.8x_%8.8x size=%d, id=%d, madr=%lx, tadr=%lx mfifo qwc = %x spr0 madr = %x",
|
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--;
|
gifqwc--;
|
||||||
|
|
||||||
switch (ptag->ID)
|
switch (ptag->ID)
|
||||||
{
|
{
|
||||||
case TAG_REFE: // Refe - Transfer Packet According to ADDR field
|
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
|
gifstate = GIF_STATE_DONE; //End Transfer
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TAG_CNT: // CNT - Transfer QWC following the tag.
|
case TAG_CNT: // CNT - Transfer QWC following the tag.
|
||||||
gif->madr = qwctag(gif->tadr + 16); //Set MADR to QW after Tag
|
gifch.madr = qwctag(gifch.tadr + 16); //Set MADR to QW after Tag
|
||||||
gif->tadr = qwctag(gif->madr + (gif->qwc << 4)); //Set TADR to QW following the data
|
gifch.tadr = qwctag(gifch.madr + (gifch.qwc << 4)); //Set TADR to QW following the data
|
||||||
gifstate = GIF_STATE_READY;
|
gifstate = GIF_STATE_READY;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TAG_NEXT: // Next - Transfer QWC following tag. TADR = ADDR
|
case TAG_NEXT: // Next - Transfer QWC following tag. TADR = ADDR
|
||||||
{
|
{
|
||||||
u32 temp = gif->madr; //Temporarily Store ADDR
|
u32 temp = gifch.madr; //Temporarily Store ADDR
|
||||||
gif->madr = qwctag(gif->tadr + 16); //Set MADR to QW following the tag
|
gifch.madr = qwctag(gifch.tadr + 16); //Set MADR to QW following the tag
|
||||||
gif->tadr = temp; //Copy temporarily stored ADDR to Tag
|
gifch.tadr = temp; //Copy temporarily stored ADDR to Tag
|
||||||
gifstate = GIF_STATE_READY;
|
gifstate = GIF_STATE_READY;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case TAG_REF: // Ref - Transfer QWC from ADDR field
|
case TAG_REF: // Ref - Transfer QWC from ADDR field
|
||||||
case TAG_REFS: // Refs - Transfer QWC from ADDR field (Stall Control)
|
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;
|
gifstate = GIF_STATE_READY;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TAG_END: // End - Transfer QWC following the tag
|
case TAG_END: // End - Transfer QWC following the tag
|
||||||
gif->madr = qwctag(gif->tadr + 16); //Set MADR to data following the tag
|
gifch.madr = qwctag(gifch.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.tadr = qwctag(gifch.madr + (gifch.qwc << 4)); //Set TADR to QW following the data
|
||||||
gifstate = GIF_STATE_DONE; //End Transfer
|
gifstate = GIF_STATE_DONE; //End Transfer
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((gif->chcr.TIE) && (ptag->IRQ))
|
if ((gifch.chcr.TIE) && (ptag->IRQ))
|
||||||
{
|
{
|
||||||
SPR_LOG("dmaIrq Set");
|
SPR_LOG("dmaIrq Set");
|
||||||
gifstate = GIF_STATE_DONE;
|
gifstate = GIF_STATE_DONE;
|
||||||
|
@ -612,14 +612,14 @@ void mfifoGIFtransfer(int qwc)
|
||||||
|
|
||||||
if (!mfifoGIFchain())
|
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;
|
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);
|
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()
|
void gifMFIFOInterrupt()
|
||||||
|
@ -634,16 +634,16 @@ void gifMFIFOInterrupt()
|
||||||
return;
|
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.OPH = false;
|
||||||
gifRegs->stat.APATH = GIF_APATH_IDLE;
|
gifRegs.stat.APATH = GIF_APATH_IDLE;
|
||||||
if(gifRegs->stat.P1Q) gsPath1Interrupt();
|
if(gifRegs.stat.P1Q) gsPath1Interrupt();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(CheckPaths(11) == false) return;
|
if(CheckPaths(11) == false) return;
|
||||||
|
|
||||||
if (!(gif->chcr.STR))
|
if (!(gifch.chcr.STR))
|
||||||
{
|
{
|
||||||
Console.WriteLn("WTF GIFMFIFO");
|
Console.WriteLn("WTF GIFMFIFO");
|
||||||
cpuRegs.interrupt &= ~(1 << 11);
|
cpuRegs.interrupt &= ~(1 << 11);
|
||||||
|
@ -659,7 +659,7 @@ void gifMFIFOInterrupt()
|
||||||
gifstate |= GIF_STATE_EMPTY;
|
gifstate |= GIF_STATE_EMPTY;
|
||||||
gifempty = true;
|
gifempty = true;
|
||||||
|
|
||||||
gifRegs->stat.IMT = false;
|
gifRegs.stat.IMT = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
mfifoGIFtransfer(0);
|
mfifoGIFtransfer(0);
|
||||||
|
@ -667,7 +667,7 @@ void gifMFIFOInterrupt()
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef PCSX2_DEVBUILD
|
#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!");
|
Console.Error("gifMFIFO Panic > Shouldn't go here!");
|
||||||
return;
|
return;
|
||||||
|
@ -679,10 +679,10 @@ void gifMFIFOInterrupt()
|
||||||
gspath3done = false;
|
gspath3done = false;
|
||||||
gscycles = 0;
|
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;
|
vif1Regs.stat.VGW = false;
|
||||||
gif->chcr.STR = false;
|
gifch.chcr.STR = false;
|
||||||
gifstate = GIF_STATE_READY;
|
gifstate = GIF_STATE_READY;
|
||||||
hwDmacIrq(DMAC_GIF);
|
hwDmacIrq(DMAC_GIF);
|
||||||
clearFIFOstuff(false);
|
clearFIFOstuff(false);
|
||||||
|
|
|
@ -277,7 +277,7 @@ struct GIFregisters
|
||||||
u32 padding9[3];
|
u32 padding9[3];
|
||||||
};
|
};
|
||||||
|
|
||||||
#define gifRegs ((GIFregisters*)(eeMem->HW+0x3000))
|
static GIFregisters& gifRegs = (GIFregisters&)eeHw[0x3000];
|
||||||
|
|
||||||
extern tGSTransferStatus GSTransferStatus;
|
extern tGSTransferStatus GSTransferStatus;
|
||||||
|
|
||||||
|
|
99
pcsx2/Hw.cpp
99
pcsx2/Hw.cpp
|
@ -18,6 +18,7 @@
|
||||||
|
|
||||||
#include "Hardware.h"
|
#include "Hardware.h"
|
||||||
#include "newVif.h"
|
#include "newVif.h"
|
||||||
|
#include "IPU/IPUdma.h"
|
||||||
|
|
||||||
using namespace R5900;
|
using namespace R5900;
|
||||||
|
|
||||||
|
@ -45,17 +46,12 @@ void hwInit()
|
||||||
hwInitialized = true;
|
hwInitialized = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*void hwShutdown()
|
|
||||||
{
|
|
||||||
ipuShutdown();
|
|
||||||
}*/
|
|
||||||
|
|
||||||
void hwReset()
|
void hwReset()
|
||||||
{
|
{
|
||||||
hwInit();
|
hwInit();
|
||||||
|
|
||||||
memzero_ptr<Ps2MemSize::Hardware>( eeMem->HW );
|
memzero_ptr<Ps2MemSize::Hardware>( eeHw );
|
||||||
//memset(eeMem->HW+0x2000, 0, 0x0000e000);
|
//memset(eeHw+0x2000, 0, 0x0000e000);
|
||||||
|
|
||||||
psHu32(SBUS_F260) = 0x1D000060;
|
psHu32(SBUS_F260) = 0x1D000060;
|
||||||
|
|
||||||
|
@ -72,6 +68,9 @@ void hwReset()
|
||||||
ipuReset();
|
ipuReset();
|
||||||
vif0Reset();
|
vif0Reset();
|
||||||
vif1Reset();
|
vif1Reset();
|
||||||
|
|
||||||
|
// needed for legacy DMAC
|
||||||
|
ipuDmaReset();
|
||||||
}
|
}
|
||||||
|
|
||||||
__fi void intcInterrupt()
|
__fi void intcInterrupt()
|
||||||
|
@ -104,7 +103,7 @@ __fi void dmacInterrupt()
|
||||||
return;
|
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");
|
//DevCon.Warning("DMAC Suspended or Disabled on interrupt");
|
||||||
return;
|
return;
|
||||||
|
@ -131,7 +130,7 @@ void hwDmacIrq(int n)
|
||||||
__ri bool hwMFIFOWrite(u32 addr, const u128* data, uint qwc)
|
__ri bool hwMFIFOWrite(u32 addr, const u128* data, uint qwc)
|
||||||
{
|
{
|
||||||
// all FIFO addresses should always be QWC-aligned.
|
// all FIFO addresses should always be QWC-aligned.
|
||||||
pxAssume((dmacRegs->rbor.ADDR & 15) == 0);
|
pxAssume((dmacRegs.rbor.ADDR & 15) == 0);
|
||||||
pxAssume((addr & 15) == 0);
|
pxAssume((addr & 15) == 0);
|
||||||
|
|
||||||
// DMAC Address resolution: FIFO can be placed anywhere in the *physical* memory map
|
// 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
|
// valid/invalid page areas of ram, so realistically we only need to test the base address
|
||||||
// of the FIFO for address validity.
|
// 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;
|
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!" );
|
pxAssertMsg( PSM(dmacRegs.rbor.ADDR+ringsize-1) != NULL, "Scratchpad/MFIFO ringbuffer spans into invalid (unmapped) physical memory!" );
|
||||||
uint startpos = (addr & dmacRegs->rbsr.RMSK)/16;
|
uint startpos = (addr & dmacRegs.rbsr.RMSK)/16;
|
||||||
MemCopy_WrappedDest( data, dst, startpos, ringsize, qwc );
|
MemCopy_WrappedDest( data, dst, startpos, ringsize, qwc );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
SPR_LOG( "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) );
|
pxFailDev( wxsFormat( L"Scratchpad/MFIFO: Invalid base physical address: 0x%08x", dmacRegs.rbor.ADDR) );
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
__ri bool hwDmacSrcChainWithStack(DMACh *dma, int id) {
|
__ri bool hwDmacSrcChainWithStack(DMACh& dma, int id) {
|
||||||
switch (id) {
|
switch (id) {
|
||||||
case TAG_REFE: // Refe - Transfer Packet According to ADDR field
|
case TAG_REFE: // Refe - Transfer Packet According to ADDR field
|
||||||
//End Transfer
|
//End Transfer
|
||||||
|
@ -164,49 +163,49 @@ __ri bool hwDmacSrcChainWithStack(DMACh *dma, int id) {
|
||||||
|
|
||||||
case TAG_CNT: // CNT - Transfer QWC following the tag.
|
case TAG_CNT: // CNT - Transfer QWC following the tag.
|
||||||
// Set MADR to QW afer tag, and set TADR to QW following the data.
|
// Set MADR to QW afer tag, and set TADR to QW following the data.
|
||||||
dma->madr = dma->tadr + 16;
|
dma.madr = dma.tadr + 16;
|
||||||
dma->tadr = dma->madr + (dma->qwc << 4);
|
dma.tadr = dma.madr + (dma.qwc << 4);
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
case TAG_NEXT: // Next - Transfer QWC following tag. TADR = ADDR
|
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.
|
// Set MADR to QW following the tag, and set TADR to the address formerly in MADR.
|
||||||
u32 temp = dma->madr;
|
u32 temp = dma.madr;
|
||||||
dma->madr = dma->tadr + 16;
|
dma.madr = dma.tadr + 16;
|
||||||
dma->tadr = temp;
|
dma.tadr = temp;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
case TAG_REF: // Ref - Transfer QWC from ADDR field
|
case TAG_REF: // Ref - Transfer QWC from ADDR field
|
||||||
case TAG_REFS: // Refs - Transfer QWC from ADDR field (Stall Control)
|
case TAG_REFS: // Refs - Transfer QWC from ADDR field (Stall Control)
|
||||||
//Set TADR to next tag
|
//Set TADR to next tag
|
||||||
dma->tadr += 16;
|
dma.tadr += 16;
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
case TAG_CALL: // Call - Transfer QWC following the tag, save succeeding tag
|
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.
|
// Store the address in MADR in temp, and set MADR to the data following the tag.
|
||||||
u32 temp = dma->madr;
|
u32 temp = dma.madr;
|
||||||
dma->madr = dma->tadr + 16;
|
dma.madr = dma.tadr + 16;
|
||||||
|
|
||||||
if(temp == 0)
|
if(temp == 0)
|
||||||
{
|
{
|
||||||
DevCon.Warning("DMA Chain CALL next tag error. Tag Addr = 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;
|
return false;
|
||||||
}
|
}
|
||||||
// Stash an address on the address stack pointer.
|
// Stash an address on the address stack pointer.
|
||||||
switch(dma->chcr.ASP)
|
switch(dma.chcr.ASP)
|
||||||
{
|
{
|
||||||
case 0: //Check if ASR0 is empty
|
case 0: //Check if ASR0 is empty
|
||||||
// Store the succeeding tag in asr0, and mark chcr as having 1 address.
|
// Store the succeeding tag in asr0, and mark chcr as having 1 address.
|
||||||
dma->asr0 = dma->madr + (dma->qwc << 4);
|
dma.asr0 = dma.madr + (dma.qwc << 4);
|
||||||
dma->chcr.ASP++;
|
dma.chcr.ASP++;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 1:
|
case 1:
|
||||||
// Store the succeeding tag in asr1, and mark chcr as having 2 addresses.
|
// Store the succeeding tag in asr1, and mark chcr as having 2 addresses.
|
||||||
dma->asr1 = dma->madr + (dma->qwc << 4);
|
dma.asr1 = dma.madr + (dma.qwc << 4);
|
||||||
dma->chcr.ASP++;
|
dma.chcr.ASP++;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -215,48 +214,48 @@ __ri bool hwDmacSrcChainWithStack(DMACh *dma, int id) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set TADR to the address from MADR we stored in temp.
|
// Set TADR to the address from MADR we stored in temp.
|
||||||
dma->tadr = temp;
|
dma.tadr = temp;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
case TAG_RET: // Ret - Transfer QWC following the tag, load next tag
|
case TAG_RET: // Ret - Transfer QWC following the tag, load next tag
|
||||||
//Set MADR to data following the 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.
|
// Snag an address from the address stack pointer.
|
||||||
switch(dma->chcr.ASP)
|
switch(dma.chcr.ASP)
|
||||||
{
|
{
|
||||||
case 2:
|
case 2:
|
||||||
// Pull asr1 from the stack, give it to TADR, and decrease the # of addresses.
|
// Pull asr1 from the stack, give it to TADR, and decrease the # of addresses.
|
||||||
dma->tadr = dma->asr1;
|
dma.tadr = dma.asr1;
|
||||||
dma->asr1 = 0;
|
dma.asr1 = 0;
|
||||||
dma->chcr.ASP--;
|
dma.chcr.ASP--;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 1:
|
case 1:
|
||||||
// Pull asr0 from the stack, give it to TADR, and decrease the # of addresses.
|
// Pull asr0 from the stack, give it to TADR, and decrease the # of addresses.
|
||||||
dma->tadr = dma->asr0;
|
dma.tadr = dma.asr0;
|
||||||
dma->asr0 = 0;
|
dma.asr0 = 0;
|
||||||
dma->chcr.ASP--;
|
dma.chcr.ASP--;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0:
|
case 0:
|
||||||
// There aren't any addresses to pull, so end the transfer.
|
// 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;
|
return true;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
// If ASR1 and ASR0 are messed up, end the transfer.
|
// If ASR1 and ASR0 are messed up, end the transfer.
|
||||||
//Console.Error("TAG_RET: ASR 1 & 0 == 1. This shouldn't happen!");
|
//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 true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
case TAG_END: // End - Transfer QWC following the tag
|
case TAG_END: // End - Transfer QWC following the tag
|
||||||
//Set MADR to data following the tag, and end the transfer.
|
//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
|
//Don't Increment tadr; breaks Soul Calibur II and III
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -264,7 +263,7 @@ __ri bool hwDmacSrcChainWithStack(DMACh *dma, int id) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool hwDmacSrcChain(DMACh *dma, int id)
|
bool hwDmacSrcChain(DMACh& dma, int id)
|
||||||
{
|
{
|
||||||
u32 temp;
|
u32 temp;
|
||||||
|
|
||||||
|
@ -276,26 +275,26 @@ bool hwDmacSrcChain(DMACh *dma, int id)
|
||||||
|
|
||||||
case TAG_CNT: // CNT - Transfer QWC following the tag.
|
case TAG_CNT: // CNT - Transfer QWC following the tag.
|
||||||
// Set MADR to QW after the tag, and TADR to QW following the data.
|
// Set MADR to QW after the tag, and TADR to QW following the data.
|
||||||
dma->madr = dma->tadr + 16;
|
dma.madr = dma.tadr + 16;
|
||||||
dma->tadr = dma->madr + (dma->qwc << 4);
|
dma.tadr = dma.madr + (dma.qwc << 4);
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
case TAG_NEXT: // Next - Transfer QWC following tag. TADR = ADDR
|
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.
|
// Set MADR to QW following the tag, and set TADR to the address formerly in MADR.
|
||||||
temp = dma->madr;
|
temp = dma.madr;
|
||||||
dma->madr = dma->tadr + 16;
|
dma.madr = dma.tadr + 16;
|
||||||
dma->tadr = temp;
|
dma.tadr = temp;
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
case TAG_REF: // Ref - Transfer QWC from ADDR field
|
case TAG_REF: // Ref - Transfer QWC from ADDR field
|
||||||
case TAG_REFS: // Refs - Transfer QWC from ADDR field (Stall Control)
|
case TAG_REFS: // Refs - Transfer QWC from ADDR field (Stall Control)
|
||||||
//Set TADR to next tag
|
//Set TADR to next tag
|
||||||
dma->tadr += 16;
|
dma.tadr += 16;
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
case TAG_END: // End - Transfer QWC following the tag
|
case TAG_END: // End - Transfer QWC following the tag
|
||||||
//Set MADR to data following the tag, and end the transfer.
|
//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
|
//Don't Increment tadr; breaks Soul Calibur II and III
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
235
pcsx2/Hw.h
235
pcsx2/Hw.h
|
@ -13,28 +13,84 @@
|
||||||
* If not, see <http://www.gnu.org/licenses/>.
|
* If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
#ifndef __HW_H__
|
namespace EEMemoryMap
|
||||||
#define __HW_H__
|
{
|
||||||
|
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;
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
static const uint IPU_Start = 0x10002000;
|
||||||
// Hardware FIFOs (128 bit access only!)
|
static const uint IPU_End = 0x10003000;
|
||||||
//
|
|
||||||
// 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]
|
|
||||||
|
|
||||||
void __fastcall ReadFIFO_page_4(u32 mem, mem128_t *out);
|
static const uint GIF_Start = 0x10003000;
|
||||||
void __fastcall ReadFIFO_page_5(u32 mem, mem128_t *out);
|
static const uint GIF_End = 0x10003800;
|
||||||
void __fastcall ReadFIFO_page_6(u32 mem, mem128_t *out);
|
|
||||||
void __fastcall ReadFIFO_page_7(u32 mem, mem128_t *out);
|
|
||||||
|
|
||||||
void __fastcall WriteFIFO_page_4(u32 mem, const mem128_t *value);
|
static const uint VIF0_Start = 0x10003800;
|
||||||
void __fastcall WriteFIFO_page_5(u32 mem, const mem128_t *value);
|
static const uint VIF0_End = 0x10003C00;
|
||||||
void __fastcall WriteFIFO_page_6(u32 mem, const mem128_t *value);
|
static const uint VIF1_Start = 0x10003C00;
|
||||||
void __fastcall WriteFIFO_page_7(u32 mem, const mem128_t *value);
|
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
|
// HW defines
|
||||||
enum EERegisterAddresses
|
enum EERegisterAddresses
|
||||||
|
@ -86,14 +142,14 @@ enum EERegisterAddresses
|
||||||
VIF0_ITOPS = 0x10003890,
|
VIF0_ITOPS = 0x10003890,
|
||||||
VIF0_ITOP = 0x100038d0,
|
VIF0_ITOP = 0x100038d0,
|
||||||
VIF0_TOP = 0x100038e0,
|
VIF0_TOP = 0x100038e0,
|
||||||
VIF0_R0 = 0x10003900,
|
VIF0_ROW0 = 0x10003900,
|
||||||
VIF0_R1 = 0x10003910,
|
VIF0_ROW1 = 0x10003910,
|
||||||
VIF0_R2 = 0x10003920,
|
VIF0_ROW2 = 0x10003920,
|
||||||
VIF0_R3 = 0x10003930,
|
VIF0_ROW3 = 0x10003930,
|
||||||
VIF0_C0 = 0x10003940,
|
VIF0_COL0 = 0x10003940,
|
||||||
VIF0_C1 = 0x10003950,
|
VIF0_COL1 = 0x10003950,
|
||||||
VIF0_C2 = 0x10003960,
|
VIF0_COL2 = 0x10003960,
|
||||||
VIF0_C3 = 0x10003970,
|
VIF0_COL3 = 0x10003970,
|
||||||
|
|
||||||
VIF1_STAT = 0x10003c00,
|
VIF1_STAT = 0x10003c00,
|
||||||
VIF1_FBRST = 0x10003c10,
|
VIF1_FBRST = 0x10003c10,
|
||||||
|
@ -110,14 +166,14 @@ enum EERegisterAddresses
|
||||||
VIF1_TOPS = 0x10003cc0,
|
VIF1_TOPS = 0x10003cc0,
|
||||||
VIF1_ITOP = 0x10003cd0,
|
VIF1_ITOP = 0x10003cd0,
|
||||||
VIF1_TOP = 0x10003ce0,
|
VIF1_TOP = 0x10003ce0,
|
||||||
VIF1_R0 = 0x10003d00,
|
VIF1_ROW0 = 0x10003d00,
|
||||||
VIF1_R1 = 0x10003d10,
|
VIF1_ROW1 = 0x10003d10,
|
||||||
VIF1_R2 = 0x10003d20,
|
VIF1_ROW2 = 0x10003d20,
|
||||||
VIF1_R3 = 0x10003d30,
|
VIF1_ROW3 = 0x10003d30,
|
||||||
VIF1_C0 = 0x10003d40,
|
VIF1_COL0 = 0x10003d40,
|
||||||
VIF1_C1 = 0x10003d50,
|
VIF1_COL1 = 0x10003d50,
|
||||||
VIF1_C2 = 0x10003d60,
|
VIF1_COL2 = 0x10003d60,
|
||||||
VIF1_C3 = 0x10003d70,
|
VIF1_COL3 = 0x10003d70,
|
||||||
|
|
||||||
VIF0_FIFO = 0x10004000,
|
VIF0_FIFO = 0x10004000,
|
||||||
VIF1_FIFO = 0x10005000,
|
VIF1_FIFO = 0x10005000,
|
||||||
|
@ -134,6 +190,13 @@ enum EERegisterAddresses
|
||||||
D0_ASR0 = 0x10008040,
|
D0_ASR0 = 0x10008040,
|
||||||
D0_ASR1 = 0x10008050,
|
D0_ASR1 = 0x10008050,
|
||||||
|
|
||||||
|
VIF0_CHCR = 0x10008000,
|
||||||
|
VIF0_MADR = 0x10008010,
|
||||||
|
VIF0_QWC = 0x10008020,
|
||||||
|
VIF0_TADR = 0x10008030,
|
||||||
|
VIF0_ASR0 = 0x10008040,
|
||||||
|
VIF0_ASR1 = 0x10008050,
|
||||||
|
|
||||||
//VIF1
|
//VIF1
|
||||||
D1_CHCR = 0x10009000,
|
D1_CHCR = 0x10009000,
|
||||||
D1_MADR = 0x10009010,
|
D1_MADR = 0x10009010,
|
||||||
|
@ -141,7 +204,13 @@ enum EERegisterAddresses
|
||||||
D1_TADR = 0x10009030,
|
D1_TADR = 0x10009030,
|
||||||
D1_ASR0 = 0x10009040,
|
D1_ASR0 = 0x10009040,
|
||||||
D1_ASR1 = 0x10009050,
|
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
|
//GS
|
||||||
D2_CHCR = 0x1000A000,
|
D2_CHCR = 0x1000A000,
|
||||||
|
@ -150,44 +219,82 @@ enum EERegisterAddresses
|
||||||
D2_TADR = 0x1000A030,
|
D2_TADR = 0x1000A030,
|
||||||
D2_ASR0 = 0x1000A040,
|
D2_ASR0 = 0x1000A040,
|
||||||
D2_ASR1 = 0x1000A050,
|
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
|
//fromIPU
|
||||||
D3_CHCR = 0x1000B000,
|
D3_CHCR = 0x1000B000,
|
||||||
D3_MADR = 0x1000B010,
|
D3_MADR = 0x1000B010,
|
||||||
D3_QWC = 0x1000B020,
|
D3_QWC = 0x1000B020,
|
||||||
D3_TADR = 0x1000B030,
|
D3_TADR = 0x1000B030,
|
||||||
D3_SADR = 0x1000B080,
|
|
||||||
|
fromIPU_CHCR = 0x1000B000,
|
||||||
|
fromIPU_MADR = 0x1000B010,
|
||||||
|
fromIPU_QWC = 0x1000B020,
|
||||||
|
fromIPU_TADR = 0x1000B030,
|
||||||
|
|
||||||
//toIPU
|
//toIPU
|
||||||
D4_CHCR = 0x1000B400,
|
D4_CHCR = 0x1000B400,
|
||||||
D4_MADR = 0x1000B410,
|
D4_MADR = 0x1000B410,
|
||||||
D4_QWC = 0x1000B420,
|
D4_QWC = 0x1000B420,
|
||||||
D4_TADR = 0x1000B430,
|
D4_TADR = 0x1000B430,
|
||||||
D4_SADR = 0x1000B480,
|
|
||||||
|
toIPU_CHCR = 0x1000B400,
|
||||||
|
toIPU_MADR = 0x1000B410,
|
||||||
|
toIPU_QWC = 0x1000B420,
|
||||||
|
toIPU_TADR = 0x1000B430,
|
||||||
|
|
||||||
//SIF0
|
//SIF0
|
||||||
D5_CHCR = 0x1000C000,
|
D5_CHCR = 0x1000C000,
|
||||||
D5_MADR = 0x1000C010,
|
D5_MADR = 0x1000C010,
|
||||||
D5_QWC = 0x1000C020,
|
D5_QWC = 0x1000C020,
|
||||||
|
|
||||||
|
SIF0_CHCR = 0x1000C000,
|
||||||
|
SIF0_MADR = 0x1000C010,
|
||||||
|
SIF0_QWC = 0x1000C020,
|
||||||
|
|
||||||
//SIF1
|
//SIF1
|
||||||
D6_CHCR = 0x1000C400,
|
D6_CHCR = 0x1000C400,
|
||||||
D6_MADR = 0x1000C410,
|
D6_MADR = 0x1000C410,
|
||||||
D6_QWC = 0x1000C420,
|
D6_QWC = 0x1000C420,
|
||||||
D6_TADR = 0x1000C430,
|
D6_TADR = 0x1000C430,
|
||||||
|
|
||||||
|
SIF1_CHCR = 0x1000C400,
|
||||||
|
SIF1_MADR = 0x1000C410,
|
||||||
|
SIF1_QWC = 0x1000C420,
|
||||||
|
SIF1_TADR = 0x1000C430,
|
||||||
|
|
||||||
//SIF2
|
//SIF2
|
||||||
D7_CHCR = 0x1000C800,
|
D7_CHCR = 0x1000C800,
|
||||||
D7_MADR = 0x1000C810,
|
D7_MADR = 0x1000C810,
|
||||||
D7_QWC = 0x1000C820,
|
D7_QWC = 0x1000C820,
|
||||||
|
|
||||||
|
SIF2_CHCR = 0x1000C800,
|
||||||
|
SIF2_MADR = 0x1000C810,
|
||||||
|
SIF2_QWC = 0x1000C820,
|
||||||
|
|
||||||
//fromSPR
|
//fromSPR
|
||||||
D8_CHCR = 0x1000D000,
|
D8_CHCR = 0x1000D000,
|
||||||
D8_MADR = 0x1000D010,
|
D8_MADR = 0x1000D010,
|
||||||
D8_QWC = 0x1000D020,
|
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_CTRL = 0x1000E000,
|
||||||
DMAC_STAT = 0x1000E010,
|
DMAC_STAT = 0x1000E010,
|
||||||
|
@ -264,53 +371,7 @@ union tGS_SMODE2
|
||||||
bool IsInterlaced() const { return INT; }
|
bool IsInterlaced() const { return INT; }
|
||||||
};
|
};
|
||||||
|
|
||||||
void hwReset();
|
extern 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 const int rdram_devices;
|
extern const int rdram_devices;
|
||||||
extern int rdram_sdevid;
|
extern int rdram_sdevid;
|
||||||
|
|
||||||
#endif /* __HW_H__ */
|
|
||||||
|
|
618
pcsx2/HwRead.cpp
618
pcsx2/HwRead.cpp
|
@ -16,9 +16,11 @@
|
||||||
|
|
||||||
#include "PrecompiledHeader.h"
|
#include "PrecompiledHeader.h"
|
||||||
#include "Common.h"
|
#include "Common.h"
|
||||||
|
|
||||||
#include "Hardware.h"
|
#include "Hardware.h"
|
||||||
|
|
||||||
|
#include "ps2/HwInternal.h"
|
||||||
|
#include "ps2/eeHwTraceLog.inl"
|
||||||
|
|
||||||
using namespace R5900;
|
using namespace R5900;
|
||||||
|
|
||||||
static __fi void IntCHackCheck()
|
static __fi void IntCHackCheck()
|
||||||
|
@ -29,470 +31,270 @@ static __fi void IntCHackCheck()
|
||||||
if( diff > 0 ) cpuRegs.cycle = g_nextBranchCycle;
|
if( diff > 0 ) cpuRegs.cycle = g_nextBranchCycle;
|
||||||
}
|
}
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////
|
static const uint HwF_VerboseConLog = 1<<0;
|
||||||
// Hardware READ 8 bit
|
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;
|
switch( page )
|
||||||
// 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 )
|
|
||||||
{
|
{
|
||||||
#ifdef PCSX2_DEVBUILD
|
case 0x00: return rcntRead32<0x00>( mem );
|
||||||
HW_LOG("8bit Hardware IPU Read at 0x%x, value=0x%x", mem, psHu8(mem) );
|
case 0x01: return rcntRead32<0x01>( mem );
|
||||||
#endif
|
|
||||||
return psHu8(mem);
|
case 0x02: return ipuRead32( mem );
|
||||||
}
|
|
||||||
// DevCon.Warning("Unexpected hwRead8 from 0x%x", mem);
|
case 0x03: return dmacRead32<0x03>( 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 0x04:
|
||||||
case 0x05:
|
case 0x05:
|
||||||
case 0x06:
|
case 0x06:
|
||||||
case 0x07:
|
case 0x07:
|
||||||
case 0x08:
|
|
||||||
case 0x09:
|
|
||||||
case 0x0a:
|
|
||||||
case 0x0b:
|
|
||||||
case 0x0c:
|
|
||||||
case 0x0d:
|
|
||||||
{
|
{
|
||||||
const char* regName = "Unknown";
|
// [Ps2Confirm] Reading from FIFOs using non-128 bit reads is a complete mystery.
|
||||||
|
// No game is known to attempt such a thing (yay!), so probably nothing for us to
|
||||||
|
// worry about. Chances are, though, doing so is "legal" and yields some sort
|
||||||
|
// of reproducible behavior. Candidate for real hardware testing.
|
||||||
|
|
||||||
|
// Current assumption: Reads 128 bits and discards the unused portion.
|
||||||
|
|
||||||
switch( mem & 0xf0)
|
DevCon.WriteLn( Color_Cyan, "Reading 32-bit FIFO data" );
|
||||||
{
|
|
||||||
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 Read 8 at 0x%x (%ls %s), value=0x%x", mem, ChcrName(mem & ~0xff), regName, psHu8(mem) );
|
u128 out128;
|
||||||
ret = psHu8(mem);
|
_hwRead128<page>(mem, &out128);
|
||||||
return ret;
|
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;
|
break;
|
||||||
|
|
||||||
case 0xf130: // SIO_ISR
|
case 0x0f:
|
||||||
case 0xf260: // SBUS_F260
|
{
|
||||||
case 0xf410: // 0x1000f410
|
// INTC_STAT shortcut for heavy spinning.
|
||||||
case 0xf430: // MCH_RICM
|
// Performance Note: Visual Studio handles this best if we just manually check for it here,
|
||||||
return 0;
|
// 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
|
if (mem == INTC_STAT)
|
||||||
return psHu32(0xf240) | 0xF0000102;
|
|
||||||
|
|
||||||
case 0xf440: // MCH_DRD
|
|
||||||
if( !((psHu32(0xf430) >> 6) & 0xF) )
|
|
||||||
{
|
{
|
||||||
switch ((psHu32(0xf430)>>16) & 0xFFF)
|
if (intcstathack) IntCHackCheck();
|
||||||
{
|
return psHu32(INTC_STAT);
|
||||||
//MCH_RICM: x:4|SA:12|x:5|SDEV:1|SOP:4|SBC:1|SDEV:5
|
}
|
||||||
|
|
||||||
case 0x21://INIT
|
//if ((mem & 0x1000f200) == 0x1000f200)
|
||||||
if(rdram_sdevid < rdram_devices)
|
// Console.Error("SBUS");
|
||||||
{
|
|
||||||
rdram_sdevid++;
|
switch( mem )
|
||||||
return 0x1F;
|
{
|
||||||
}
|
case SIO_ISR:
|
||||||
|
case SBUS_F260:
|
||||||
|
case 0x1000f410:
|
||||||
|
case MCH_RICM:
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
case 0x23://CNFGA
|
case SBUS_F240:
|
||||||
return 0x0D0D; //PVER=3 | MVER=16 | DBL=1 | REFBIT=5
|
return psHu32(SBUS_F240) | 0xF0000102;
|
||||||
|
|
||||||
case 0x24://CNFGB
|
case MCH_DRD:
|
||||||
//0x0110 for PSX SVER=0 | CORG=8(5x9x7) | SPT=1 | DEVTYP=0 | BYTE=0
|
if( !((psHu32(MCH_RICM) >> 6) & 0xF) )
|
||||||
return 0x0090; //SVER=0 | CORG=4(5x9x6) | SPT=1 | DEVTYP=0 | BYTE=0
|
{
|
||||||
|
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
|
case 0x21://INIT
|
||||||
return psHu32(0xf430) & 0x1F; // =SDEV
|
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)
|
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.
|
template< uint page >
|
||||||
mem32_t __fastcall hwRead32_generic(u32 mem)
|
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:
|
case 0x02:
|
||||||
if(masked_mem >= 0x3800) HW_LOG("VIF%x Register Read32 at 0x%x, value=0x%x", (masked_mem < 0x3c00) ? 0 : 1, mem, psHu32(mem) );
|
*result = ipuRead64(mem);
|
||||||
else HW_LOG("GIF Register Read32 at 0x%x, value=0x%x", mem, psHu32(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 0x04:
|
||||||
case 0x05:
|
case 0x05:
|
||||||
case 0x06:
|
case 0x06:
|
||||||
case 0x07:
|
case 0x07:
|
||||||
case 0x08:
|
|
||||||
case 0x09:
|
|
||||||
case 0x0a:
|
|
||||||
case 0x0b:
|
|
||||||
case 0x0c:
|
|
||||||
case 0x0d:
|
|
||||||
{
|
{
|
||||||
const char* regName = "Unknown";
|
// [Ps2Confirm] Reading from FIFOs using non-128 bit reads is a complete mystery.
|
||||||
|
// No game is known to attempt such a thing (yay!), so probably nothing for us to
|
||||||
|
// worry about. Chances are, though, doing so is "legal" and yields some sort
|
||||||
|
// of reproducible behavior. Candidate for real hardware testing.
|
||||||
|
|
||||||
|
// Current assumption: Reads 128 bits and discards the unused portion.
|
||||||
|
|
||||||
switch( mem & 0xf0)
|
uint wordpart = (mem >> 3) & 0x1;
|
||||||
{
|
DevCon.WriteLn( Color_Cyan, "Reading 64-bit FIFO data (%s 64 bits discarded)", wordpart ? "upper" : "lower" );
|
||||||
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 Read32 at 0x%x (%ls %s), value=0x%x", mem, ChcrName(mem & ~0xff), regName, psHu32(mem) );
|
u128 out128;
|
||||||
|
_hwRead128<page>(mem, &out128);
|
||||||
|
*result = out128._u64[wordpart];
|
||||||
}
|
}
|
||||||
break;
|
return;
|
||||||
#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 *((u32*)&eeMem->HW[masked_mem]);
|
*result = _hwRead32<page,false>( mem );
|
||||||
}
|
}
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////
|
template< uint page >
|
||||||
// Hardware READ 64 bit
|
void __fastcall hwRead64(u32 mem, mem64_t* result )
|
||||||
|
|
||||||
void __fastcall hwRead64_page_00(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 )
|
#define InstantizeHwRead(pageidx) \
|
||||||
{
|
template mem8_t __fastcall hwRead8<pageidx>(u32 mem); \
|
||||||
if (mem == INTC_STAT) IntCHackCheck();
|
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);
|
InstantizeHwRead(0x00); InstantizeHwRead(0x08);
|
||||||
UnknownHW_LOG("Hardware Read 64 at %x",mem);
|
InstantizeHwRead(0x01); InstantizeHwRead(0x09);
|
||||||
}
|
InstantizeHwRead(0x02); InstantizeHwRead(0x0a);
|
||||||
|
InstantizeHwRead(0x03); InstantizeHwRead(0x0b);
|
||||||
void __fastcall hwRead64_generic(u32 mem, mem64_t* result )
|
InstantizeHwRead(0x04); InstantizeHwRead(0x0c);
|
||||||
{
|
InstantizeHwRead(0x05); InstantizeHwRead(0x0d);
|
||||||
*result = psHu64(mem);
|
InstantizeHwRead(0x06); InstantizeHwRead(0x0e);
|
||||||
UnknownHW_LOG("Hardware Read 64 at %x",mem);
|
InstantizeHwRead(0x07); InstantizeHwRead(0x0f);
|
||||||
}
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////
|
|
||||||
// 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);
|
|
||||||
}
|
|
||||||
|
|
1536
pcsx2/HwWrite.cpp
1536
pcsx2/HwWrite.cpp
File diff suppressed because it is too large
Load Diff
1211
pcsx2/IPU/IPU.cpp
1211
pcsx2/IPU/IPU.cpp
File diff suppressed because it is too large
Load Diff
|
@ -17,10 +17,6 @@
|
||||||
|
|
||||||
#include "IPU_Fifo.h"
|
#include "IPU_Fifo.h"
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
//#pragma pack(1)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define ipumsk( src ) ( (src) & 0xff )
|
#define ipumsk( src ) ( (src) & 0xff )
|
||||||
#define ipucase( src ) case ipumsk(src)
|
#define ipucase( src ) case ipumsk(src)
|
||||||
|
|
||||||
|
@ -29,26 +25,6 @@
|
||||||
|
|
||||||
#define IPU_FORCEINLINE __fi
|
#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
|
// Bitfield Structures
|
||||||
//
|
//
|
||||||
|
@ -102,10 +78,6 @@ struct tIPU_BP {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
//#pragma pack()
|
|
||||||
#endif
|
|
||||||
|
|
||||||
union tIPU_CMD_IDEC
|
union tIPU_CMD_IDEC
|
||||||
{
|
{
|
||||||
struct
|
struct
|
||||||
|
@ -178,47 +150,6 @@ union tIPU_CMD_CSC
|
||||||
void log_from_RGB32() const;
|
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
|
enum SCE_IPU
|
||||||
{
|
{
|
||||||
SCE_IPU_BCLR = 0x0
|
SCE_IPU_BCLR = 0x0
|
||||||
|
@ -245,8 +176,6 @@ struct IPUregisters {
|
||||||
u32 dummy3[2];
|
u32 dummy3[2];
|
||||||
};
|
};
|
||||||
|
|
||||||
#define ipuRegs ((IPUregisters*)(&eeMem->HW[0x2000]))
|
|
||||||
|
|
||||||
struct tIPU_cmd
|
struct tIPU_cmd
|
||||||
{
|
{
|
||||||
int index;
|
int index;
|
||||||
|
@ -271,32 +200,22 @@ struct tIPU_cmd
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static IPUregisters& ipuRegs = (IPUregisters&)eeHw[0x2000];
|
||||||
|
|
||||||
extern tIPU_cmd ipu_cmd;
|
extern tIPU_cmd ipu_cmd;
|
||||||
extern int coded_block_pattern;
|
extern int coded_block_pattern;
|
||||||
extern IPUStatus IPU1Status;
|
|
||||||
extern tIPU_DMA g_nDMATransfer;
|
|
||||||
|
|
||||||
extern int ipuInit();
|
extern int ipuInit();
|
||||||
extern void ipuReset();
|
extern void ipuReset();
|
||||||
extern void ipuShutdown();
|
|
||||||
extern int ipuFreeze(gzFile f, int Mode);
|
|
||||||
extern bool ipuCanFreeze();
|
|
||||||
|
|
||||||
extern u32 ipuRead32(u32 mem);
|
extern u32 ipuRead32(u32 mem);
|
||||||
extern u64 ipuRead64(u32 mem);
|
extern u64 ipuRead64(u32 mem);
|
||||||
extern void ipuWrite32(u32 mem,u32 value);
|
extern bool ipuWrite32(u32 mem,u32 value);
|
||||||
extern void ipuWrite64(u32 mem,u64 value);
|
extern bool ipuWrite64(u32 mem,u64 value);
|
||||||
|
|
||||||
extern void IPUCMD_WRITE(u32 val);
|
extern void IPUCMD_WRITE(u32 val);
|
||||||
extern void ipuSoftReset();
|
extern void ipuSoftReset();
|
||||||
extern void IPUProcessInterrupt();
|
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 u16 __fastcall FillInternalBuffer(u32 * pointer, u32 advance, u32 size);
|
||||||
extern u8 __fastcall getBits128(u8 *address, u32 advance);
|
extern u8 __fastcall getBits128(u8 *address, u32 advance);
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
#include "PrecompiledHeader.h"
|
#include "PrecompiledHeader.h"
|
||||||
#include "Common.h"
|
#include "Common.h"
|
||||||
#include "IPU.h"
|
#include "IPU.h"
|
||||||
|
#include "IPU/IPUdma.h"
|
||||||
#include "mpeg2lib/Mpeg.h"
|
#include "mpeg2lib/Mpeg.h"
|
||||||
|
|
||||||
|
|
||||||
|
@ -35,7 +36,7 @@ void IPU_Fifo_Input::clear()
|
||||||
{
|
{
|
||||||
memzero(data);
|
memzero(data);
|
||||||
g_BP.IFC = 0;
|
g_BP.IFC = 0;
|
||||||
ipuRegs->ctrl.IFC = 0;
|
ipuRegs.ctrl.IFC = 0;
|
||||||
readpos = 0;
|
readpos = 0;
|
||||||
writepos = 0;
|
writepos = 0;
|
||||||
}
|
}
|
||||||
|
@ -43,7 +44,7 @@ void IPU_Fifo_Input::clear()
|
||||||
void IPU_Fifo_Output::clear()
|
void IPU_Fifo_Output::clear()
|
||||||
{
|
{
|
||||||
memzero(data);
|
memzero(data);
|
||||||
ipuRegs->ctrl.OFC = 0;
|
ipuRegs.ctrl.OFC = 0;
|
||||||
readpos = 0;
|
readpos = 0;
|
||||||
writepos = 0;
|
writepos = 0;
|
||||||
}
|
}
|
||||||
|
@ -89,9 +90,9 @@ int IPU_Fifo_Output::write(const u32 *value, int size)
|
||||||
{
|
{
|
||||||
int transsize, firsttrans;
|
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;
|
firsttrans = transsize;
|
||||||
|
|
||||||
while (transsize-- > 0)
|
while (transsize-- > 0)
|
||||||
|
@ -104,7 +105,7 @@ int IPU_Fifo_Output::write(const u32 *value, int size)
|
||||||
value += 4;
|
value += 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
ipuRegs->ctrl.OFC += firsttrans;
|
ipuRegs.ctrl.OFC += firsttrans;
|
||||||
IPU0dma();
|
IPU0dma();
|
||||||
|
|
||||||
return firsttrans;
|
return firsttrans;
|
||||||
|
@ -150,7 +151,7 @@ void IPU_Fifo_Output::_readsingle(void *value)
|
||||||
|
|
||||||
void IPU_Fifo_Output::read(void *value, int size)
|
void IPU_Fifo_Output::read(void *value, int size)
|
||||||
{
|
{
|
||||||
ipuRegs->ctrl.OFC -= size;
|
ipuRegs.ctrl.OFC -= size;
|
||||||
while (size > 0)
|
while (size > 0)
|
||||||
{
|
{
|
||||||
_readsingle(value);
|
_readsingle(value);
|
||||||
|
@ -161,38 +162,51 @@ void IPU_Fifo_Output::read(void *value, int size)
|
||||||
|
|
||||||
void IPU_Fifo_Output::readsingle(void *value)
|
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);
|
_readsingle(value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
__fi bool decoder_t::ReadIpuData(u128* out)
|
__fi bool decoder_t::ReadIpuData(u128* out)
|
||||||
{
|
{
|
||||||
if(decoder.ipu0_data == 0) return false;
|
if(ipu0_data == 0)
|
||||||
_mm_store_ps((float*)out, _mm_load_ps((float*)GetIpuDataPtr()));
|
{
|
||||||
|
IPU_LOG( "ReadFIFO/IPUout -> (fifo empty/no data available)" );
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
CopyQWC(out, GetIpuDataPtr());
|
||||||
|
|
||||||
--ipu0_data;
|
--ipu0_data;
|
||||||
++ipu0_idx;
|
++ipu0_idx;
|
||||||
|
|
||||||
|
IPU_LOG( "ReadFIFO/IPUout -> %ls", out->ToString().c_str() );
|
||||||
|
|
||||||
return true;
|
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:
|
if (decoder.ReadIpuData(out))
|
||||||
mem &= 0x10;
|
|
||||||
|
|
||||||
if (mem == 0) // IPUout_FIFO
|
|
||||||
{
|
{
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
|
@ -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();
|
|
@ -680,7 +680,7 @@ static __fi bool slice_non_intra_DCT(s16 * const dest, const int stride, const b
|
||||||
|
|
||||||
void __fi finishmpeg2sliceIDEC()
|
void __fi finishmpeg2sliceIDEC()
|
||||||
{
|
{
|
||||||
ipuRegs->ctrl.SCD = 0;
|
ipuRegs.ctrl.SCD = 0;
|
||||||
coded_block_pattern = decoder.coded_block_pattern;
|
coded_block_pattern = decoder.coded_block_pattern;
|
||||||
|
|
||||||
g_BP.BP += decoder.bitstream_bits - 16;
|
g_BP.BP += decoder.bitstream_bits - 16;
|
||||||
|
@ -710,8 +710,8 @@ bool mpeg2sliceIDEC()
|
||||||
decoder.dc_dct_pred[2] = 128 << decoder.intra_dc_precision;
|
decoder.dc_dct_pred[2] = 128 << decoder.intra_dc_precision;
|
||||||
|
|
||||||
decoder.mbc = 0;
|
decoder.mbc = 0;
|
||||||
ipuRegs->top = 0;
|
ipuRegs.top = 0;
|
||||||
ipuRegs->ctrl.ECD = 0;
|
ipuRegs.ctrl.ECD = 0;
|
||||||
|
|
||||||
case 1:
|
case 1:
|
||||||
ipu_cmd.pos[0] = 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);
|
if (g_BP.BP & 7) g_BP.BP += 8 - (g_BP.BP & 7);
|
||||||
|
|
||||||
ipuRegs->ctrl.SCD = 1;
|
ipuRegs.ctrl.SCD = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
case 4:
|
case 4:
|
||||||
if (!getBits32((u8*)&ipuRegs->top, 0))
|
if (!getBits32((u8*)&ipuRegs.top, 0))
|
||||||
{
|
{
|
||||||
ipu_cmd.pos[0] = 4;
|
ipu_cmd.pos[0] = 4;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
BigEndian(ipuRegs->top, ipuRegs->top);
|
BigEndian(ipuRegs.top, ipuRegs.top);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -942,8 +942,8 @@ bool mpeg2_slice()
|
||||||
decoder.dc_dct_pred[2] = 128 << decoder.intra_dc_precision;
|
decoder.dc_dct_pred[2] = 128 << decoder.intra_dc_precision;
|
||||||
}
|
}
|
||||||
|
|
||||||
ipuRegs->ctrl.ECD = 0;
|
ipuRegs.ctrl.ECD = 0;
|
||||||
ipuRegs->top = 0;
|
ipuRegs.top = 0;
|
||||||
memzero_sse_a(mb8);
|
memzero_sse_a(mb8);
|
||||||
memzero_sse_a(mb16);
|
memzero_sse_a(mb16);
|
||||||
case 1:
|
case 1:
|
||||||
|
@ -1082,7 +1082,7 @@ bool mpeg2_slice()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send The MacroBlock via DmaIpuFrom
|
// Send The MacroBlock via DmaIpuFrom
|
||||||
ipuRegs->ctrl.SCD = 0;
|
ipuRegs.ctrl.SCD = 0;
|
||||||
coded_block_pattern = decoder.coded_block_pattern;
|
coded_block_pattern = decoder.coded_block_pattern;
|
||||||
g_BP.BP += (int)decoder.bitstream_bits - 16;
|
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);
|
if (g_BP.BP & 7) g_BP.BP += 8 - (g_BP.BP & 7);
|
||||||
|
|
||||||
ipuRegs->ctrl.SCD = 1;
|
ipuRegs.ctrl.SCD = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
case 5:
|
case 5:
|
||||||
if (!getBits32((u8*)&ipuRegs->top, 0))
|
if (!getBits32((u8*)&ipuRegs.top, 0))
|
||||||
{
|
{
|
||||||
ipu_cmd.pos[0] = 5;
|
ipu_cmd.pos[0] = 5;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
BigEndian(ipuRegs->top, ipuRegs->top);
|
BigEndian(ipuRegs.top, ipuRegs.top);
|
||||||
decoder.bitstream_bits = 0;
|
decoder.bitstream_bits = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
// 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
|
// 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;
|
return;
|
||||||
}
|
}
|
||||||
else if (t == 0x1000)
|
else if (t == 0x1000)
|
||||||
|
|
|
@ -137,6 +137,60 @@
|
||||||
<Add library="$(SvnRootDir)/deps/release/libUtilities.a" />
|
<Add library="$(SvnRootDir)/deps/release/libUtilities.a" />
|
||||||
</Linker>
|
</Linker>
|
||||||
</Target>
|
</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>
|
<Environment>
|
||||||
<Variable name="SvnRootDir" value="../../" />
|
<Variable name="SvnRootDir" value="../../" />
|
||||||
<Variable name="ProjectRootDir" value='"$(SvnRootDir)/pcsx2/"' />
|
<Variable name="ProjectRootDir" value='"$(SvnRootDir)/pcsx2/"' />
|
||||||
|
@ -240,6 +294,8 @@
|
||||||
<Unit filename="../IPU/IPU.h" />
|
<Unit filename="../IPU/IPU.h" />
|
||||||
<Unit filename="../IPU/IPU_Fifo.cpp" />
|
<Unit filename="../IPU/IPU_Fifo.cpp" />
|
||||||
<Unit filename="../IPU/IPU_Fifo.h" />
|
<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/Idct.cpp" />
|
||||||
<Unit filename="../IPU/mpeg2lib/Mpeg.cpp" />
|
<Unit filename="../IPU/mpeg2lib/Mpeg.cpp" />
|
||||||
<Unit filename="../IPU/mpeg2lib/Mpeg.h" />
|
<Unit filename="../IPU/mpeg2lib/Mpeg.h" />
|
||||||
|
@ -522,9 +578,11 @@
|
||||||
<Unit filename="../ps2/BiosTools.cpp" />
|
<Unit filename="../ps2/BiosTools.cpp" />
|
||||||
<Unit filename="../ps2/BiosTools.h" />
|
<Unit filename="../ps2/BiosTools.h" />
|
||||||
<Unit filename="../ps2/GIFpath.cpp" />
|
<Unit filename="../ps2/GIFpath.cpp" />
|
||||||
|
<Unit filename="../ps2/HwInternal.h" />
|
||||||
<Unit filename="../ps2/Iop/IopHwRead.cpp" />
|
<Unit filename="../ps2/Iop/IopHwRead.cpp" />
|
||||||
<Unit filename="../ps2/Iop/IopHwWrite.cpp" />
|
<Unit filename="../ps2/Iop/IopHwWrite.cpp" />
|
||||||
<Unit filename="../ps2/Iop/IopHw_Internal.h" />
|
<Unit filename="../ps2/Iop/IopHw_Internal.h" />
|
||||||
|
<Unit filename="../ps2/LegacyDmac.cpp" />
|
||||||
<Unit filename="../vtlb.cpp" />
|
<Unit filename="../vtlb.cpp" />
|
||||||
<Unit filename="../vtlb.h" />
|
<Unit filename="../vtlb.h" />
|
||||||
<Unit filename="../x86/BaseblockEx.cpp" />
|
<Unit filename="../x86/BaseblockEx.cpp" />
|
||||||
|
|
|
@ -171,14 +171,11 @@ void PLZCW() {
|
||||||
_PLZCW (1);
|
_PLZCW (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
__fi void PMFHL_CLAMP(u16 dst, u16 src)
|
__fi void PMFHL_CLAMP(u16& dst, s32 src)
|
||||||
{
|
{
|
||||||
if ((int)src > (int)0x00007fff)
|
if (src > 0x7fff) dst = 0x7fff;
|
||||||
dst = 0x7fff;
|
else if (src < -0x8000) dst = 0x8000;
|
||||||
else if ((int)src < (int)0xffff8000) // Ints only go up to 0x7FFFFFFF. Something's not right here. --arcum42
|
else dst = (u16)src;
|
||||||
dst = 0x8000;
|
|
||||||
else
|
|
||||||
dst = (u16)src;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PMFHL() {
|
void PMFHL() {
|
||||||
|
|
143
pcsx2/Memory.cpp
143
pcsx2/Memory.cpp
|
@ -35,15 +35,14 @@ BIOS
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "PrecompiledHeader.h"
|
#include "PrecompiledHeader.h"
|
||||||
#include "IopCommon.h"
|
|
||||||
|
|
||||||
#pragma warning(disable:4799) // No EMMS at end of function
|
|
||||||
|
|
||||||
#include <wx/file.h>
|
#include <wx/file.h>
|
||||||
|
|
||||||
|
#include "IopCommon.h"
|
||||||
#include "VUmicro.h"
|
#include "VUmicro.h"
|
||||||
#include "GS.h"
|
#include "GS.h"
|
||||||
#include "System/PageFaultSource.h"
|
#include "System/PageFaultSource.h"
|
||||||
|
|
||||||
|
#include "ps2/HwInternal.h"
|
||||||
#include "ps2/BiosTools.h"
|
#include "ps2/BiosTools.h"
|
||||||
|
|
||||||
#ifdef ENABLECACHE
|
#ifdef ENABLECACHE
|
||||||
|
@ -154,7 +153,6 @@ void memMapPhy()
|
||||||
vtlb_MapBlock(psxM,0x1c000000,0x00800000);
|
vtlb_MapBlock(psxM,0x1c000000,0x00800000);
|
||||||
|
|
||||||
// Generic Handlers; These fallback to mem* stuff...
|
// 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_7,0x14000000,0x10000);
|
||||||
vtlb_MapHandler(tlb_fallback_4,0x18000000,0x10000);
|
vtlb_MapHandler(tlb_fallback_4,0x18000000,0x10000);
|
||||||
vtlb_MapHandler(tlb_fallback_5,0x1a000000,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
|
// 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)
|
// (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);
|
for( uint i=0; i<16; ++i)
|
||||||
vtlb_MapHandler(hw_by_page[0x2], 0x10002000, 0x01000);
|
vtlb_MapHandler(hw_by_page[i], 0x10000000 + (0x01000 * i), 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);
|
|
||||||
|
|
||||||
vtlb_MapHandler(gs_page_0, 0x12000000, 0x01000);
|
vtlb_MapHandler(gs_page_0, 0x12000000, 0x01000);
|
||||||
vtlb_MapHandler(gs_page_1, 0x12001000, 0x01000);
|
vtlb_MapHandler(gs_page_1, 0x12001000, 0x01000);
|
||||||
|
@ -256,8 +246,6 @@ static mem8_t __fastcall _ext_memRead8 (u32 mem)
|
||||||
{
|
{
|
||||||
switch (p)
|
switch (p)
|
||||||
{
|
{
|
||||||
case 1: // hwm
|
|
||||||
return hwRead8(mem);
|
|
||||||
case 3: // psh4
|
case 3: // psh4
|
||||||
return psxHw4Read8(mem);
|
return psxHw4Read8(mem);
|
||||||
case 6: // gsm
|
case 6: // gsm
|
||||||
|
@ -280,8 +268,6 @@ static mem16_t __fastcall _ext_memRead16(u32 mem)
|
||||||
{
|
{
|
||||||
switch (p)
|
switch (p)
|
||||||
{
|
{
|
||||||
case 1: // hwm
|
|
||||||
return hwRead16(mem);
|
|
||||||
case 4: // b80
|
case 4: // b80
|
||||||
MEM_LOG("b800000 Memory read16 address %x", mem);
|
MEM_LOG("b800000 Memory read16 address %x", mem);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -358,9 +344,6 @@ template<int p>
|
||||||
static void __fastcall _ext_memWrite8 (u32 mem, mem8_t value)
|
static void __fastcall _ext_memWrite8 (u32 mem, mem8_t value)
|
||||||
{
|
{
|
||||||
switch (p) {
|
switch (p) {
|
||||||
case 1: // hwm
|
|
||||||
hwWrite8(mem, value);
|
|
||||||
return;
|
|
||||||
case 3: // psh4
|
case 3: // psh4
|
||||||
psxHw4Write8(mem, value); return;
|
psxHw4Write8(mem, value); return;
|
||||||
case 6: // gsm
|
case 6: // gsm
|
||||||
|
@ -379,9 +362,6 @@ template<int p>
|
||||||
static void __fastcall _ext_memWrite16(u32 mem, mem16_t value)
|
static void __fastcall _ext_memWrite16(u32 mem, mem16_t value)
|
||||||
{
|
{
|
||||||
switch (p) {
|
switch (p) {
|
||||||
case 1: // hwm
|
|
||||||
hwWrite16(mem, value);
|
|
||||||
return;
|
|
||||||
case 5: // ba0
|
case 5: // ba0
|
||||||
MEM_LOG("ba00000 Memory write16 to address %x with data %x", mem, value);
|
MEM_LOG("ba00000 Memory write16 to address %x with data %x", mem, value);
|
||||||
return;
|
return;
|
||||||
|
@ -602,10 +582,12 @@ protected:
|
||||||
void OnPageFaultEvent( const PageFaultInfo& info, bool& handled );
|
void OnPageFaultEvent( const PageFaultInfo& info, bool& handled );
|
||||||
};
|
};
|
||||||
|
|
||||||
mmap_PageFaultHandler mmap_faultHandler;
|
static mmap_PageFaultHandler mmap_faultHandler;
|
||||||
|
|
||||||
EEVM_MemoryAllocMess* eeMem = NULL;
|
EEVM_MemoryAllocMess* eeMem = NULL;
|
||||||
|
|
||||||
|
__pagealigned u8 eeHw[Ps2MemSize::Hardware];
|
||||||
|
|
||||||
void memAlloc()
|
void memAlloc()
|
||||||
{
|
{
|
||||||
if( eeMem == NULL )
|
if( eeMem == NULL )
|
||||||
|
@ -630,13 +612,28 @@ void memBindConditionalHandlers()
|
||||||
{
|
{
|
||||||
if( hw_by_page[0xf] == -1 ) return;
|
if( hw_by_page[0xf] == -1 ) return;
|
||||||
|
|
||||||
vtlbMemR32FP* page0F32( EmuConfig.Speedhacks.IntcStat ? hwRead32_page_0F_INTC_HACK : hwRead32_page_0F );
|
if (EmuConfig.Speedhacks.IntcStat)
|
||||||
vtlbMemR64FP* page0F64( EmuConfig.Speedhacks.IntcStat ? hwRead64_generic_INTC_HACK : hwRead64_generic );
|
{
|
||||||
|
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],
|
vtlb_ReassignHandler( hw_by_page[0xf],
|
||||||
_ext_memRead8<1>, _ext_memRead16<1>, page0F32, page0F64, hwRead128_generic,
|
hwRead8<0x0f>, page0F16, page0F32, hwRead64<0x0f>, hwRead128<0x0f>,
|
||||||
_ext_memWrite8<1>, _ext_memWrite16<1>, hwWrite32_page_0F, hwWrite64_generic, hwWrite128_generic
|
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.
|
// 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_3 = vtlb_RegisterHandlerTempl1(_ext_mem,3);
|
||||||
tlb_fallback_4 = vtlb_RegisterHandlerTempl1(_ext_mem,4);
|
tlb_fallback_4 = vtlb_RegisterHandlerTempl1(_ext_mem,4);
|
||||||
tlb_fallback_5 = vtlb_RegisterHandlerTempl1(_ext_mem,5);
|
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_7 = vtlb_RegisterHandlerTempl1(_ext_mem,7);
|
||||||
tlb_fallback_8 = vtlb_RegisterHandlerTempl1(_ext_mem,8);
|
tlb_fallback_8 = vtlb_RegisterHandlerTempl1(_ext_mem,8);
|
||||||
|
|
||||||
|
@ -701,68 +697,29 @@ void memReset()
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// psHw Optimized Mappings
|
// psHw Optimized Mappings
|
||||||
// The HW Registers have been split into pages to improve optimization.
|
// The HW Registers have been split into pages to improve optimization.
|
||||||
// Anything not explicitly mapped into one of the hw_by_page handlers will be handled
|
|
||||||
// by the default/generic tlb_fallback_1 handler.
|
#define hwHandlerTmpl(page) \
|
||||||
|
hwRead8<page>, hwRead16<page>, hwRead32<page>, hwRead64<page>, hwRead128<page>, \
|
||||||
|
hwWrite8<page>, hwWrite16<page>,hwWrite32<page>,hwWrite64<page>,hwWrite128<page>
|
||||||
|
|
||||||
tlb_fallback_1 = vtlb_RegisterHandler(
|
hw_by_page[0x0] = vtlb_RegisterHandler( hwHandlerTmpl(0x00) );
|
||||||
_ext_memRead8<1>, _ext_memRead16<1>, hwRead32_generic, hwRead64_generic, hwRead128_generic,
|
hw_by_page[0x1] = vtlb_RegisterHandler( hwHandlerTmpl(0x01) );
|
||||||
_ext_memWrite8<1>, _ext_memWrite16<1>, hwWrite32_generic, hwWrite64_generic, hwWrite128_generic
|
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[0x0] = vtlb_RegisterHandler(
|
hw_by_page[0x5] = vtlb_RegisterHandler( hwHandlerTmpl(0x05) );
|
||||||
_ext_memRead8<1>, _ext_memRead16<1>, hwRead32_page_00, hwRead64_page_00, hwRead128_page_00,
|
hw_by_page[0x6] = vtlb_RegisterHandler( hwHandlerTmpl(0x06) );
|
||||||
_ext_memWrite8<1>, _ext_memWrite16<1>, hwWrite32_page_00, hwWrite64_page_00, hwWrite128_generic
|
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[0x1] = vtlb_RegisterHandler(
|
hw_by_page[0xa] = vtlb_RegisterHandler( hwHandlerTmpl(0x0a) );
|
||||||
_ext_memRead8<1>, _ext_memRead16<1>, hwRead32_page_01, hwRead64_page_01, hwRead128_page_01,
|
hw_by_page[0xb] = vtlb_RegisterHandler( hwHandlerTmpl(0x0b) );
|
||||||
_ext_memWrite8<1>, _ext_memWrite16<1>, hwWrite32_page_01, hwWrite64_page_01, hwWrite128_generic
|
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[0x2] = vtlb_RegisterHandler(
|
hw_by_page[0xf] = vtlb_NewHandler(); // redefined later based on speedhacking prefs
|
||||||
_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();
|
|
||||||
memBindConditionalHandlers();
|
memBindConditionalHandlers();
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -34,33 +34,22 @@ static __fi void ZeroQWC( void* dest )
|
||||||
_mm_store_ps( (float*)dest, _mm_setzero_ps() );
|
_mm_store_ps( (float*)dest, _mm_setzero_ps() );
|
||||||
}
|
}
|
||||||
|
|
||||||
// Various useful locations
|
static __fi void ZeroQWC( u128& dest )
|
||||||
#define spr0 ((DMACh*)&eeMem->HW[0xD000])
|
{
|
||||||
#define spr1 ((DMACh*)&eeMem->HW[0xD400])
|
_mm_store_ps( (float*)&dest, _mm_setzero_ps() );
|
||||||
|
}
|
||||||
#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])
|
|
||||||
|
|
||||||
#define PSM(mem) (vtlb_GetPhyPtr((mem)&0x1fffffff)) //pcsx2 is a competition.The one with most hacks wins :D
|
#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 psHs8(mem) (*(s8 *)&eeHw[(mem) & 0xffff])
|
||||||
#define psHs16(mem) (*(s16*)&eeMem->HW[(mem) & 0xffff])
|
#define psHs16(mem) (*(s16*)&eeHw[(mem) & 0xffff])
|
||||||
#define psHs32(mem) (*(s32*)&eeMem->HW[(mem) & 0xffff])
|
#define psHs32(mem) (*(s32*)&eeHw[(mem) & 0xffff])
|
||||||
#define psHs64(mem) (*(s64*)&eeMem->HW[(mem) & 0xffff])
|
#define psHs64(mem) (*(s64*)&eeHw[(mem) & 0xffff])
|
||||||
#define psHu8(mem) (*(u8 *)&eeMem->HW[(mem) & 0xffff])
|
#define psHu8(mem) (*(u8 *)&eeHw[(mem) & 0xffff])
|
||||||
#define psHu16(mem) (*(u16*)&eeMem->HW[(mem) & 0xffff])
|
#define psHu16(mem) (*(u16*)&eeHw[(mem) & 0xffff])
|
||||||
#define psHu32(mem) (*(u32*)&eeMem->HW[(mem) & 0xffff])
|
#define psHu32(mem) (*(u32*)&eeHw[(mem) & 0xffff])
|
||||||
#define psHu64(mem) (*(u64*)&eeMem->HW[(mem) & 0xffff])
|
#define psHu64(mem) (*(u64*)&eeHw[(mem) & 0xffff])
|
||||||
#define psHu128(mem)(*(u128*)&eeMem->HW[(mem) & 0xffff])
|
#define psHu128(mem)(*(u128*)&eeHw[(mem) & 0xffff])
|
||||||
|
|
||||||
#define psMs8(mem) (*(s8 *)&eeMem->Main[(mem) & 0x1ffffff])
|
#define psMs8(mem) (*(s8 *)&eeMem->Main[(mem) & 0x1ffffff])
|
||||||
#define psMs16(mem) (*(s16*)&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 psSu64(mem) (*(u64 *)&eeMem->Scratch[(mem) & 0x3fff])
|
||||||
#define psSu128(mem) (*(u128*)&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 memAlloc();
|
||||||
extern void memReset(); // clears PS2 ram and loads the bios. Throws Exception::FileNotFound on error.
|
extern void memReset(); // clears PS2 ram and loads the bios. Throws Exception::FileNotFound on error.
|
||||||
extern void memShutdown();
|
extern void memShutdown();
|
||||||
|
@ -135,13 +122,21 @@ extern void mmap_ResetBlockTracking();
|
||||||
#define memRead8 vtlb_memRead<mem8_t>
|
#define memRead8 vtlb_memRead<mem8_t>
|
||||||
#define memRead16 vtlb_memRead<mem16_t>
|
#define memRead16 vtlb_memRead<mem16_t>
|
||||||
#define memRead32 vtlb_memRead<mem32_t>
|
#define memRead32 vtlb_memRead<mem32_t>
|
||||||
#define memRead64 vtlb_memRead64
|
|
||||||
#define memRead128 vtlb_memRead128
|
|
||||||
|
|
||||||
#define memWrite8 vtlb_memWrite<mem8_t>
|
#define memWrite8 vtlb_memWrite<mem8_t>
|
||||||
#define memWrite16 vtlb_memWrite<mem16_t>
|
#define memWrite16 vtlb_memWrite<mem16_t>
|
||||||
#define memWrite32 vtlb_memWrite<mem32_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);
|
extern u16 ba0R16(u32 mem);
|
||||||
|
|
|
@ -37,15 +37,55 @@ typedef u32 mem32_t;
|
||||||
typedef u64 mem64_t;
|
typedef u64 mem64_t;
|
||||||
typedef u128 mem128_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
|
struct EEVM_MemoryAllocMess
|
||||||
{
|
{
|
||||||
u8 Scratch[Ps2MemSize::Scratch]; // Scratchpad!
|
u8 Scratch[Ps2MemSize::Scratch]; // Scratchpad!
|
||||||
u8 Main[Ps2MemSize::Base]; // Main memory (hard-wired to 32MB)
|
u8 Main[Ps2MemSize::Base]; // Main memory (hard-wired to 32MB)
|
||||||
u8 HW[Ps2MemSize::Hardware]; // Hardware registers
|
|
||||||
u8 ROM[Ps2MemSize::Rom]; // Boot rom (4MB)
|
u8 ROM[Ps2MemSize::Rom]; // Boot rom (4MB)
|
||||||
u8 ROM1[Ps2MemSize::Rom1]; // DVD player
|
u8 ROM1[Ps2MemSize::Rom1]; // DVD player
|
||||||
u8 ROM2[Ps2MemSize::Rom2]; // Chinese extensions (?)
|
u8 ROM2[Ps2MemSize::Rom2]; // Chinese extensions
|
||||||
u8 EROM[Ps2MemSize::ERom]; // DVD player extensions (?)
|
u8 EROM[Ps2MemSize::ERom]; // DVD player extensions
|
||||||
|
|
||||||
// Two 1 megabyte (max DMA) buffers for reading and writing to high memory (>32MB).
|
// 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
|
// Such accesses are not documented as causing bus errors but as the memory does
|
||||||
|
@ -56,4 +96,13 @@ struct EEVM_MemoryAllocMess
|
||||||
u8 ZeroWrite[_1mb];
|
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;
|
extern EEVM_MemoryAllocMess* eeMem;
|
||||||
|
|
|
@ -78,6 +78,7 @@ typedef int BOOL;
|
||||||
#define TRUE 1
|
#define TRUE 1
|
||||||
#define FALSE 0
|
#define FALSE 0
|
||||||
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// Begin Pcsx2 Includes: Add items here that are local to Pcsx2 but stay relatively
|
// 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
|
// 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"
|
#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.
|
// Linux isn't set up for svn version numbers yet.
|
||||||
#ifdef __LINUX__
|
#ifdef __LINUX__
|
||||||
# define SVN_REV 0
|
# define SVN_REV 0
|
||||||
# define SVN_MODS 0
|
# define SVN_MODS 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// Compiler/OS specific macros and defines -- Begin Section
|
|
||||||
|
|
||||||
#if defined(_MSC_VER)
|
#if defined(_MSC_VER)
|
||||||
|
|
||||||
# define strnicmp _strnicmp
|
# define strnicmp _strnicmp
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
#include "R5900Exceptions.h"
|
#include "R5900Exceptions.h"
|
||||||
|
|
||||||
#include "Hardware.h"
|
#include "Hardware.h"
|
||||||
|
#include "IPU/IPUdma.h"
|
||||||
|
|
||||||
#include "Elfheader.h"
|
#include "Elfheader.h"
|
||||||
#include "CDVD/CDVD.h"
|
#include "CDVD/CDVD.h"
|
||||||
|
@ -287,9 +288,11 @@ static __fi void TESTINT( u8 n, void (*callback)() )
|
||||||
cpuSetNextBranch( cpuRegs.sCycle[n], cpuRegs.eCycle[n] );
|
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()
|
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");
|
//Console.Write("DMAC Disabled or suspended");
|
||||||
return;
|
return;
|
||||||
|
@ -415,7 +418,7 @@ __fi void _cpuBranchTest_Shared()
|
||||||
//if( EEsCycle < -450 )
|
//if( EEsCycle < -450 )
|
||||||
// Console.WriteLn( " IOP ahead by: %d cycles", -EEsCycle );
|
// 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
|
// 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
|
// 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
|
// 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.sCycle[30] = cpuRegs.cycle;
|
||||||
cpuRegs.eCycle[30] = 4; //Needs to be 4 to account for bus delays/pipelines etc
|
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
|
cpuSetNextBranchDelta( 4 );
|
||||||
// the current branch...
|
if(eeEventTestIsActive && (psxCycleEE > 0))
|
||||||
if( !eeEventTestIsActive )
|
|
||||||
cpuSetNextBranchDelta( 4 );
|
|
||||||
else if(psxCycleEE > 0)
|
|
||||||
{
|
{
|
||||||
psxBreak += psxCycleEE; // record the number of cycles the IOP didn't run.
|
psxBreak += psxCycleEE; // record the number of cycles the IOP didn't run.
|
||||||
psxCycleEE = 0;
|
psxCycleEE = 0;
|
||||||
|
@ -529,11 +529,8 @@ __fi void cpuTestDMACInts()
|
||||||
cpuRegs.sCycle[31] = cpuRegs.cycle;
|
cpuRegs.sCycle[31] = cpuRegs.cycle;
|
||||||
cpuRegs.eCycle[31] = 4; //Needs to be 4 to account for bus delays/pipelines etc
|
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
|
cpuSetNextBranchDelta( 4 );
|
||||||
// the current branch...
|
if(eeEventTestIsActive && (psxCycleEE > 0))
|
||||||
if( !eeEventTestIsActive )
|
|
||||||
cpuSetNextBranchDelta( 4 );
|
|
||||||
else if(psxCycleEE > 0)
|
|
||||||
{
|
{
|
||||||
psxBreak += psxCycleEE; // record the number of cycles the IOP didn't run.
|
psxBreak += psxCycleEE; // record the number of cycles the IOP didn't run.
|
||||||
psxCycleEE = 0;
|
psxCycleEE = 0;
|
||||||
|
|
|
@ -816,7 +816,7 @@ void SQ()
|
||||||
// an address error due to unaligned access isn't possible like it is on other loads/stores.
|
// 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_;
|
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.
|
// 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 (SysTraceActive(EE.Bios) && (call == 0x77))
|
||||||
if (SysTrace.EE.Bios.IsActive() && (call == 0x77))
|
|
||||||
{
|
{
|
||||||
t_sif_dma_transfer *dmat;
|
t_sif_dma_transfer *dmat;
|
||||||
//struct t_sif_cmd_header *hdr;
|
//struct t_sif_cmd_header *hdr;
|
||||||
|
@ -891,7 +890,6 @@ void SYSCALL()
|
||||||
dmat->dest, dmat->src);
|
dmat->dest, dmat->src);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
cpuRegs.pc -= 4;
|
cpuRegs.pc -= 4;
|
||||||
cpuException(0x20, cpuRegs.branch);
|
cpuException(0x20, cpuRegs.branch);
|
||||||
|
|
180
pcsx2/SPR.cpp
180
pcsx2/SPR.cpp
|
@ -51,96 +51,96 @@ int _SPR0chain()
|
||||||
{
|
{
|
||||||
tDMA_TAG *pMem;
|
tDMA_TAG *pMem;
|
||||||
|
|
||||||
if (spr0->qwc == 0) return 0;
|
if (spr0ch.qwc == 0) return 0;
|
||||||
pMem = SPRdmaGetAddr(spr0->madr, true);
|
pMem = SPRdmaGetAddr(spr0ch.madr, true);
|
||||||
if (pMem == NULL) return -1;
|
if (pMem == NULL) return -1;
|
||||||
|
|
||||||
switch (dmacRegs->ctrl.MFD)
|
switch (dmacRegs.ctrl.MFD)
|
||||||
{
|
{
|
||||||
case MFD_VIF1:
|
case MFD_VIF1:
|
||||||
case MFD_GIF:
|
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");
|
Console.WriteLn("SPR MFIFO Write outside MFIFO area");
|
||||||
else
|
else
|
||||||
mfifotransferred += spr0->qwc;
|
mfifotransferred += spr0ch.qwc;
|
||||||
|
|
||||||
hwMFIFOWrite(spr0->madr, &psSu128(spr0->sadr), spr0->qwc);
|
hwMFIFOWrite(spr0ch.madr, &psSu128(spr0ch.sadr), spr0ch.qwc);
|
||||||
spr0->madr += spr0->qwc << 4;
|
spr0ch.madr += spr0ch.qwc << 4;
|
||||||
spr0->madr = dmacRegs->rbor.ADDR + (spr0->madr & dmacRegs->rbsr.RMSK);
|
spr0ch.madr = dmacRegs.rbor.ADDR + (spr0ch.madr & dmacRegs.rbsr.RMSK);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NO_MFD:
|
case NO_MFD:
|
||||||
case MFD_RESERVED:
|
case MFD_RESERVED:
|
||||||
memcpy_qwc(pMem, &psSu128(spr0->sadr), spr0->qwc);
|
memcpy_qwc(pMem, &psSu128(spr0ch.sadr), spr0ch.qwc);
|
||||||
|
|
||||||
// clear VU mem also!
|
// clear VU mem also!
|
||||||
TestClearVUs(spr0->madr, spr0->qwc << 2); // Wtf is going on here? AFAIK, only VIF should affect VU micromem (cottonvibes)
|
TestClearVUs(spr0ch.madr, spr0ch.qwc << 2); // Wtf is going on here? AFAIK, only VIF should affect VU micromem (cottonvibes)
|
||||||
spr0->madr += spr0->qwc << 4;
|
spr0ch.madr += spr0ch.qwc << 4;
|
||||||
break;
|
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()
|
__fi void SPR0chain()
|
||||||
{
|
{
|
||||||
CPU_INT(DMAC_FROM_SPR, _SPR0chain() / BIAS);
|
CPU_INT(DMAC_FROM_SPR, _SPR0chain() / BIAS);
|
||||||
spr0->qwc = 0;
|
spr0ch.qwc = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void _SPR0interleave()
|
void _SPR0interleave()
|
||||||
{
|
{
|
||||||
int qwc = spr0->qwc;
|
int qwc = spr0ch.qwc;
|
||||||
int sqwc = dmacRegs->sqwc.SQWC;
|
int sqwc = dmacRegs.sqwc.SQWC;
|
||||||
int tqwc = dmacRegs->sqwc.TQWC;
|
int tqwc = dmacRegs.sqwc.TQWC;
|
||||||
tDMA_TAG *pMem;
|
tDMA_TAG *pMem;
|
||||||
|
|
||||||
if (tqwc == 0) tqwc = qwc;
|
if (tqwc == 0) tqwc = qwc;
|
||||||
//Console.WriteLn("dmaSPR0 interleave");
|
//Console.WriteLn("dmaSPR0 interleave");
|
||||||
SPR_LOG("SPR0 interleave size=%d, tqwc=%d, sqwc=%d, addr=%lx sadr=%lx",
|
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);
|
CPU_INT(DMAC_FROM_SPR, qwc / BIAS);
|
||||||
|
|
||||||
while (qwc > 0)
|
while (qwc > 0)
|
||||||
{
|
{
|
||||||
spr0->qwc = std::min(tqwc, qwc);
|
spr0ch.qwc = std::min(tqwc, qwc);
|
||||||
qwc -= spr0->qwc;
|
qwc -= spr0ch.qwc;
|
||||||
pMem = SPRdmaGetAddr(spr0->madr, true);
|
pMem = SPRdmaGetAddr(spr0ch.madr, true);
|
||||||
|
|
||||||
switch (dmacRegs->ctrl.MFD)
|
switch (dmacRegs.ctrl.MFD)
|
||||||
{
|
{
|
||||||
case MFD_VIF1:
|
case MFD_VIF1:
|
||||||
case MFD_GIF:
|
case MFD_GIF:
|
||||||
hwMFIFOWrite(spr0->madr, &psSu128(spr0->sadr), spr0->qwc);
|
hwMFIFOWrite(spr0ch.madr, &psSu128(spr0ch.sadr), spr0ch.qwc);
|
||||||
mfifotransferred += spr0->qwc;
|
mfifotransferred += spr0ch.qwc;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NO_MFD:
|
case NO_MFD:
|
||||||
case MFD_RESERVED:
|
case MFD_RESERVED:
|
||||||
// clear VU mem also!
|
// clear VU mem also!
|
||||||
TestClearVUs(spr0->madr, spr0->qwc << 2);
|
TestClearVUs(spr0ch.madr, spr0ch.qwc << 2);
|
||||||
memcpy_qwc(pMem, &psSu128(spr0->sadr), spr0->qwc);
|
memcpy_qwc(pMem, &psSu128(spr0ch.sadr), spr0ch.qwc);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
spr0->sadr += spr0->qwc * 16;
|
spr0ch.sadr += spr0ch.qwc * 16;
|
||||||
spr0->madr += (sqwc + spr0->qwc) * 16;
|
spr0ch.madr += (sqwc + spr0ch.qwc) * 16;
|
||||||
}
|
}
|
||||||
|
|
||||||
spr0->qwc = 0;
|
spr0ch.qwc = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static __fi void _dmaSPR0()
|
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
|
// Transfer Dn_QWC from SPR to Dn_MADR
|
||||||
switch(spr0->chcr.MOD)
|
switch(spr0ch.chcr.MOD)
|
||||||
{
|
{
|
||||||
case NORMAL_MODE:
|
case NORMAL_MODE:
|
||||||
{
|
{
|
||||||
|
@ -153,23 +153,23 @@ static __fi void _dmaSPR0()
|
||||||
tDMA_TAG *ptag;
|
tDMA_TAG *ptag;
|
||||||
bool done = false;
|
bool done = false;
|
||||||
|
|
||||||
if (spr0->qwc > 0)
|
if (spr0ch.qwc > 0)
|
||||||
{
|
{
|
||||||
SPR0chain();
|
SPR0chain();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Destination Chain Mode
|
// Destination Chain Mode
|
||||||
ptag = (tDMA_TAG*)&psSu32(spr0->sadr);
|
ptag = (tDMA_TAG*)&psSu32(spr0ch.sadr);
|
||||||
spr0->sadr += 16;
|
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",
|
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");
|
Console.WriteLn("SPR stall control");
|
||||||
}
|
}
|
||||||
|
@ -177,7 +177,7 @@ static __fi void _dmaSPR0()
|
||||||
switch (ptag->ID)
|
switch (ptag->ID)
|
||||||
{
|
{
|
||||||
case TAG_CNTS: // CNTS - Transfer QWC following the tag (Stall Control)
|
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;
|
break;
|
||||||
|
|
||||||
case TAG_CNT: // CNT - Transfer QWC following the tag.
|
case TAG_CNT: // CNT - Transfer QWC following the tag.
|
||||||
|
@ -191,7 +191,7 @@ static __fi void _dmaSPR0()
|
||||||
|
|
||||||
SPR0chain();
|
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");
|
//Console.WriteLn("SPR0 TIE");
|
||||||
done = true;
|
done = true;
|
||||||
|
@ -199,7 +199,7 @@ static __fi void _dmaSPR0()
|
||||||
|
|
||||||
spr0finished = done;
|
spr0finished = done;
|
||||||
SPR_LOG("spr0 dmaChain complete %8.8x_%8.8x size=%d, id=%d, addr=%lx spr=%lx",
|
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;
|
break;
|
||||||
}
|
}
|
||||||
//case INTERLEAVE_MODE:
|
//case INTERLEAVE_MODE:
|
||||||
|
@ -215,27 +215,27 @@ static __fi void _dmaSPR0()
|
||||||
void SPRFROMinterrupt()
|
void SPRFROMinterrupt()
|
||||||
{
|
{
|
||||||
|
|
||||||
if (!spr0finished || spr0->qwc > 0)
|
if (!spr0finished || spr0ch.qwc > 0)
|
||||||
{
|
{
|
||||||
_dmaSPR0();
|
_dmaSPR0();
|
||||||
|
|
||||||
if(mfifotransferred != 0)
|
if(mfifotransferred != 0)
|
||||||
{
|
{
|
||||||
switch (dmacRegs->ctrl.MFD)
|
switch (dmacRegs.ctrl.MFD)
|
||||||
{
|
{
|
||||||
case MFD_VIF1: // Most common case.
|
case MFD_VIF1: // Most common case.
|
||||||
{
|
{
|
||||||
if ((spr0->madr & ~dmacRegs->rbsr.RMSK) != dmacRegs->rbor.ADDR) Console.WriteLn("VIF MFIFO Write outside MFIFO area");
|
if ((spr0ch.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);
|
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);
|
//Console.WriteLn("mfifoVIF1transfer %x madr %x, tadr %x", vif1ch.chcr._u32, vif1ch.madr, vif1ch.tadr);
|
||||||
mfifoVIF1transfer(mfifotransferred);
|
mfifoVIF1transfer(mfifotransferred);
|
||||||
mfifotransferred = 0;
|
mfifotransferred = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case MFD_GIF:
|
case MFD_GIF:
|
||||||
{
|
{
|
||||||
if ((spr0->madr & ~dmacRegs->rbsr.RMSK) != dmacRegs->rbor.ADDR) Console.WriteLn("GIF MFIFO Write outside MFIFO area");
|
if ((spr0ch.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);
|
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);
|
//Console.WriteLn("mfifoGIFtransfer %x madr %x, tadr %x", gif->chcr._u32, gif->madr, gif->tadr);
|
||||||
mfifoGIFtransfer(mfifotransferred);
|
mfifoGIFtransfer(mfifotransferred);
|
||||||
mfifotransferred = 0;
|
mfifotransferred = 0;
|
||||||
|
@ -249,22 +249,22 @@ void SPRFROMinterrupt()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
spr0->chcr.STR = false;
|
spr0ch.chcr.STR = false;
|
||||||
hwDmacIrq(DMAC_FROM_SPR);
|
hwDmacIrq(DMAC_FROM_SPR);
|
||||||
}
|
}
|
||||||
|
|
||||||
void dmaSPR0() // fromSPR
|
void dmaSPR0() // fromSPR
|
||||||
{
|
{
|
||||||
SPR_LOG("dmaSPR0 chcr = %lx, madr = %lx, qwc = %lx, sadr = %lx",
|
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
|
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());
|
//DevCon.Warning(L"SPR0 QWC on Chain " + spr0ch.chcr.desc());
|
||||||
if (spr0->chcr.tag().ID == TAG_END) // but not TAG_REFE?
|
if (spr0ch.chcr.tag().ID == TAG_END) // but not TAG_REFE?
|
||||||
{
|
{
|
||||||
spr0finished = true;
|
spr0finished = true;
|
||||||
}
|
}
|
||||||
|
@ -275,58 +275,58 @@ void dmaSPR0() // fromSPR
|
||||||
|
|
||||||
__fi static void SPR1transfer(const void* data, int qwc)
|
__fi static void SPR1transfer(const void* data, int qwc)
|
||||||
{
|
{
|
||||||
memcpy_qwc(&psSu128(spr1->sadr), data, qwc);
|
memcpy_qwc(&psSu128(spr1ch.sadr), data, qwc);
|
||||||
spr1->sadr += qwc * 16;
|
spr1ch.sadr += qwc * 16;
|
||||||
}
|
}
|
||||||
|
|
||||||
int _SPR1chain()
|
int _SPR1chain()
|
||||||
{
|
{
|
||||||
tDMA_TAG *pMem;
|
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;
|
if (pMem == NULL) return -1;
|
||||||
|
|
||||||
SPR1transfer(pMem, spr1->qwc);
|
SPR1transfer(pMem, spr1ch.qwc);
|
||||||
spr1->madr += spr1->qwc * 16;
|
spr1ch.madr += spr1ch.qwc * 16;
|
||||||
|
|
||||||
return (spr1->qwc);
|
return (spr1ch.qwc);
|
||||||
}
|
}
|
||||||
|
|
||||||
__fi void SPR1chain()
|
__fi void SPR1chain()
|
||||||
{
|
{
|
||||||
CPU_INT(DMAC_TO_SPR, _SPR1chain() / BIAS);
|
CPU_INT(DMAC_TO_SPR, _SPR1chain() / BIAS);
|
||||||
spr1->qwc = 0;
|
spr1ch.qwc = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void _SPR1interleave()
|
void _SPR1interleave()
|
||||||
{
|
{
|
||||||
int qwc = spr1->qwc;
|
int qwc = spr1ch.qwc;
|
||||||
int sqwc = dmacRegs->sqwc.SQWC;
|
int sqwc = dmacRegs.sqwc.SQWC;
|
||||||
int tqwc = dmacRegs->sqwc.TQWC;
|
int tqwc = dmacRegs.sqwc.TQWC;
|
||||||
tDMA_TAG *pMem;
|
tDMA_TAG *pMem;
|
||||||
|
|
||||||
if (tqwc == 0) tqwc = qwc;
|
if (tqwc == 0) tqwc = qwc;
|
||||||
SPR_LOG("SPR1 interleave size=%d, tqwc=%d, sqwc=%d, addr=%lx sadr=%lx",
|
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);
|
CPU_INT(DMAC_TO_SPR, qwc / BIAS);
|
||||||
while (qwc > 0)
|
while (qwc > 0)
|
||||||
{
|
{
|
||||||
spr1->qwc = std::min(tqwc, qwc);
|
spr1ch.qwc = std::min(tqwc, qwc);
|
||||||
qwc -= spr1->qwc;
|
qwc -= spr1ch.qwc;
|
||||||
pMem = SPRdmaGetAddr(spr1->madr, false);
|
pMem = SPRdmaGetAddr(spr1ch.madr, false);
|
||||||
memcpy_qwc(&psSu128(spr1->sadr), pMem, spr1->qwc);
|
memcpy_qwc(&psSu128(spr1ch.sadr), pMem, spr1ch.qwc);
|
||||||
spr1->sadr += spr1->qwc * 16;
|
spr1ch.sadr += spr1ch.qwc * 16;
|
||||||
spr1->madr += (sqwc + spr1->qwc) * 16;
|
spr1ch.madr += (sqwc + spr1ch.qwc) * 16;
|
||||||
}
|
}
|
||||||
|
|
||||||
spr1->qwc = 0;
|
spr1ch.qwc = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void _dmaSPR1() // toSPR work function
|
void _dmaSPR1() // toSPR work function
|
||||||
{
|
{
|
||||||
switch(spr1->chcr.MOD)
|
switch(spr1ch.chcr.MOD)
|
||||||
{
|
{
|
||||||
case NORMAL_MODE:
|
case NORMAL_MODE:
|
||||||
{
|
{
|
||||||
|
@ -341,39 +341,39 @@ void _dmaSPR1() // toSPR work function
|
||||||
tDMA_TAG *ptag;
|
tDMA_TAG *ptag;
|
||||||
bool done = false;
|
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
|
// Transfer Dn_QWC from Dn_MADR to SPR1
|
||||||
SPR1chain();
|
SPR1chain();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Chain Mode
|
// 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;
|
done = true;
|
||||||
spr1finished = done;
|
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
|
// 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);
|
SPR_LOG("SPR TTE: %x_%x\n", ptag[3]._u32, ptag[2]._u32);
|
||||||
SPR1transfer(ptag, 1); //Transfer Tag
|
SPR1transfer(ptag, 1); //Transfer Tag
|
||||||
}
|
}
|
||||||
|
|
||||||
SPR_LOG("spr1 dmaChain %8.8x_%8.8x size=%d, id=%d, addr=%lx taddr=%lx saddr=%lx",
|
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
|
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");
|
SPR_LOG("dmaIrq Set");
|
||||||
|
|
||||||
|
@ -398,15 +398,15 @@ void dmaSPR1() // toSPR
|
||||||
{
|
{
|
||||||
SPR_LOG("dmaSPR1 chcr = 0x%x, madr = 0x%x, qwc = 0x%x\n"
|
SPR_LOG("dmaSPR1 chcr = 0x%x, madr = 0x%x, qwc = 0x%x\n"
|
||||||
" tadr = 0x%x, sadr = 0x%x",
|
" tadr = 0x%x, sadr = 0x%x",
|
||||||
spr1->chcr._u32, spr1->madr, spr1->qwc,
|
spr1ch.chcr._u32, spr1ch.madr, spr1ch.qwc,
|
||||||
spr1->tadr, spr1->sadr);
|
spr1ch.tadr, spr1ch.sadr);
|
||||||
|
|
||||||
spr1finished = false; //Init
|
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());
|
//DevCon.Warning(L"SPR1 QWC on Chain " + spr1ch.chcr.desc());
|
||||||
if ((spr1->chcr.tag().ID == TAG_END) || (spr1->chcr.tag().ID == TAG_REFE))
|
if ((spr1ch.chcr.tag().ID == TAG_END) || (spr1ch.chcr.tag().ID == TAG_REFE))
|
||||||
{
|
{
|
||||||
spr1finished = true;
|
spr1finished = true;
|
||||||
}
|
}
|
||||||
|
@ -418,14 +418,14 @@ void dmaSPR1() // toSPR
|
||||||
void SPRTOinterrupt()
|
void SPRTOinterrupt()
|
||||||
{
|
{
|
||||||
SPR_LOG("SPR1 Interrupt");
|
SPR_LOG("SPR1 Interrupt");
|
||||||
if (!spr1finished || spr1->qwc > 0)
|
if (!spr1finished || spr1ch.qwc > 0)
|
||||||
{
|
{
|
||||||
_dmaSPR1();
|
_dmaSPR1();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
SPR_LOG("SPR1 End");
|
SPR_LOG("SPR1 End");
|
||||||
spr1->chcr.STR = false;
|
spr1ch.chcr.STR = false;
|
||||||
hwDmacIrq(DMAC_TO_SPR);
|
hwDmacIrq(DMAC_TO_SPR);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -154,7 +154,7 @@ void SaveStateBase::FreezeMainMemory()
|
||||||
// ---------------------------
|
// ---------------------------
|
||||||
FreezeMem(eeMem->Main, Ps2MemSize::Base); // 32 MB main memory
|
FreezeMem(eeMem->Main, Ps2MemSize::Base); // 32 MB main memory
|
||||||
FreezeMem(eeMem->Scratch, Ps2MemSize::Scratch); // scratch pad
|
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(psxM, Ps2MemSize::IopRam); // 2 MB main memory
|
||||||
FreezeMem(psxH, Ps2MemSize::IopHardware); // hardware memory
|
FreezeMem(psxH, Ps2MemSize::IopHardware); // hardware memory
|
||||||
|
@ -194,6 +194,7 @@ void SaveStateBase::FreezeRegisters()
|
||||||
vif1Freeze();
|
vif1Freeze();
|
||||||
sifFreeze();
|
sifFreeze();
|
||||||
ipuFreeze();
|
ipuFreeze();
|
||||||
|
ipuDmaFreeze();
|
||||||
gifFreeze();
|
gifFreeze();
|
||||||
sprFreeze();
|
sprFreeze();
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
// the lower 16 bit value. IF the change is breaking of all compatibility with old
|
// 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.
|
// 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
|
// 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. :)
|
// between the GS saving function and the MTGS's needs. :)
|
||||||
|
@ -214,6 +214,7 @@ protected:
|
||||||
#endif
|
#endif
|
||||||
void sifFreeze();
|
void sifFreeze();
|
||||||
void ipuFreeze();
|
void ipuFreeze();
|
||||||
|
void ipuDmaFreeze();
|
||||||
void gifFreeze();
|
void gifFreeze();
|
||||||
void sprFreeze();
|
void sprFreeze();
|
||||||
|
|
||||||
|
|
|
@ -28,9 +28,9 @@ void sifInit()
|
||||||
|
|
||||||
__fi void dmaSIF2()
|
__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);
|
hwDmacIrq(DMAC_SIF2);
|
||||||
Console.WriteLn("*PCSX2*: dmaSIF2");
|
Console.WriteLn("*PCSX2*: dmaSIF2");
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,12 @@
|
||||||
#ifndef __SIF_H__
|
#ifndef __SIF_H__
|
||||||
#define __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
|
struct sifData
|
||||||
{
|
{
|
||||||
|
|
|
@ -35,14 +35,14 @@ static __fi void Sif0Init()
|
||||||
// Write from Fifo to EE.
|
// Write from Fifo to EE.
|
||||||
static __fi bool WriteFifoToEE()
|
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;
|
tDMA_TAG *ptag;
|
||||||
|
|
||||||
//SIF_LOG(" EE SIF doing transfer %04Xqw to %08X", readSize, sif0dma->madr);
|
//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("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)
|
if (ptag == NULL)
|
||||||
{
|
{
|
||||||
DevCon.Warning("Write Fifo to EE: 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);
|
sif0.fifo.read((u32*)ptag, readSize << 2);
|
||||||
|
|
||||||
// Clearing handled by vtlb memory protection and manual blocks.
|
// 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
|
sif0.ee.cycles += readSize; // fixme : BIAS is factored in above
|
||||||
sif0dma->qwc -= readSize;
|
sif0dma.qwc -= readSize;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -87,14 +87,14 @@ static __fi bool ProcessEETag()
|
||||||
sif0.fifo.read((u32*)&tag[0], 4); // Tag
|
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]);
|
SIF_LOG("SIF0 EE read tag: %x %x %x %x", tag[0], tag[1], tag[2], tag[3]);
|
||||||
|
|
||||||
sif0dma->unsafeTransfer(((tDMA_TAG*)(tag)));
|
sif0dma.unsafeTransfer(((tDMA_TAG*)(tag)));
|
||||||
sif0dma->madr = tag[1];
|
sif0dma.madr = tag[1];
|
||||||
tDMA_TAG ptag(tag[0]);
|
tDMA_TAG ptag(tag[0]);
|
||||||
|
|
||||||
SIF_LOG("SIF0 EE dest chain tag madr:%08X qwc:%04X id:%X irq:%d(%08X_%08X)",
|
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");
|
//Console.WriteLn("SIF0 TIE");
|
||||||
sif0.ee.end = true;
|
sif0.ee.end = true;
|
||||||
|
@ -104,13 +104,13 @@ static __fi bool ProcessEETag()
|
||||||
{
|
{
|
||||||
case TAG_REFE:
|
case TAG_REFE:
|
||||||
sif0.ee.end = true;
|
sif0.ee.end = true;
|
||||||
if (dmacRegs->ctrl.STS != NO_STS)
|
if (dmacRegs.ctrl.STS != NO_STS)
|
||||||
dmacRegs->stadr.ADDR = sif0dma->madr + (sif0dma->qwc * 16);
|
dmacRegs.stadr.ADDR = sif0dma.madr + (sif0dma.qwc * 16);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TAG_REFS:
|
case TAG_REFS:
|
||||||
if (dmacRegs->ctrl.STS != NO_STS)
|
if (dmacRegs.ctrl.STS != NO_STS)
|
||||||
dmacRegs->stadr.ADDR = sif0dma->madr + (sif0dma->qwc * 16);
|
dmacRegs.stadr.ADDR = sif0dma.madr + (sif0dma.qwc * 16);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TAG_END:
|
case TAG_END:
|
||||||
|
@ -177,7 +177,7 @@ static __fi void EndIOP()
|
||||||
// Handle the EE transfer.
|
// Handle the EE transfer.
|
||||||
static __fi void HandleEETransfer()
|
static __fi void HandleEETransfer()
|
||||||
{
|
{
|
||||||
if(sif0dma->chcr.STR == false)
|
if(sif0dma.chcr.STR == false)
|
||||||
{
|
{
|
||||||
DevCon.Warning("Replacement for irq prevention hack EE SIF0");
|
DevCon.Warning("Replacement for irq prevention hack EE SIF0");
|
||||||
sif0.ee.end = false;
|
sif0.ee.end = false;
|
||||||
|
@ -185,22 +185,22 @@ static __fi void HandleEETransfer()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dmacRegs->ctrl.STS == STS_SIF0)
|
if (dmacRegs.ctrl.STS == STS_SIF0)
|
||||||
{
|
{
|
||||||
DevCon.Warning("SIF0 stall control");
|
DevCon.Warning("SIF0 stall control");
|
||||||
}
|
}
|
||||||
|
|
||||||
/*if (sif0dma->qwc == 0)
|
/*if (sif0dma.qwc == 0)
|
||||||
if (sif0dma->chcr.MOD == NORMAL_MODE)
|
if (sif0dma.chcr.MOD == NORMAL_MODE)
|
||||||
if (!sif0.ee.end){
|
if (!sif0.ee.end){
|
||||||
DevCon.Warning("sif0 irq prevented");
|
DevCon.Warning("sif0 irq prevented");
|
||||||
done = true;
|
done = true;
|
||||||
return;
|
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.
|
// Stop transferring ee, and signal an interrupt.
|
||||||
done = true;
|
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.
|
// Write from Fifo to EE.
|
||||||
if (sif0.fifo.size > 0)
|
if (sif0.fifo.size > 0)
|
||||||
|
@ -306,7 +306,7 @@ __fi void SIF0Dma()
|
||||||
}
|
}
|
||||||
if (sif0.ee.busy)
|
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++;
|
BusyCheck++;
|
||||||
HandleEETransfer();
|
HandleEETransfer();
|
||||||
|
@ -326,19 +326,19 @@ __fi void sif0Interrupt()
|
||||||
__fi void EEsif0Interrupt()
|
__fi void EEsif0Interrupt()
|
||||||
{
|
{
|
||||||
hwDmacIrq(DMAC_SIF0);
|
hwDmacIrq(DMAC_SIF0);
|
||||||
sif0dma->chcr.STR = false;
|
sif0dma.chcr.STR = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
__fi void dmaSIF0()
|
__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)
|
if (sif0.fifo.readPos != sif0.fifo.writePos)
|
||||||
{
|
{
|
||||||
SIF_LOG("warning, sif0.fifoReadPos != sif0.fifoWritePos");
|
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;
|
psHu32(SBUS_F240) |= 0x2000;
|
||||||
sif0.ee.busy = true;
|
sif0.ee.busy = true;
|
||||||
|
|
||||||
|
|
|
@ -38,11 +38,11 @@ static __fi bool WriteEEtoFifo()
|
||||||
// There's some data ready to transfer into the fifo..
|
// There's some data ready to transfer into the fifo..
|
||||||
|
|
||||||
SIF_LOG("Sif 1: Write EE to 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;
|
tDMA_TAG *ptag;
|
||||||
|
|
||||||
ptag = sif1dma->getAddr(sif1dma->madr, DMAC_SIF1, false);
|
ptag = sif1dma.getAddr(sif1dma.madr, DMAC_SIF1, false);
|
||||||
if (ptag == NULL)
|
if (ptag == NULL)
|
||||||
{
|
{
|
||||||
DevCon.Warning("Write EE to Fifo: 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);
|
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
|
sif1.ee.cycles += writeSize; // fixme : BIAS is factored in above
|
||||||
sif1dma->qwc -= writeSize;
|
sif1dma.qwc -= writeSize;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -84,21 +84,21 @@ static __fi bool ProcessEETag()
|
||||||
tDMA_TAG *ptag;
|
tDMA_TAG *ptag;
|
||||||
SIF_LOG("Sif1: ProcessEETag");
|
SIF_LOG("Sif1: ProcessEETag");
|
||||||
|
|
||||||
// Process DMA tag at sif1dma->tadr
|
// Process DMA tag at sif1dma.tadr
|
||||||
ptag = sif1dma->DMAtransfer(sif1dma->tadr, DMAC_SIF1);
|
ptag = sif1dma.DMAtransfer(sif1dma.tadr, DMAC_SIF1);
|
||||||
if (ptag == NULL)
|
if (ptag == NULL)
|
||||||
{
|
{
|
||||||
Console.WriteLn("Sif1 ProcessEETag: ptag = NULL");
|
Console.WriteLn("Sif1 ProcessEETag: ptag = NULL");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sif1dma->chcr.TTE)
|
if (sif1dma.chcr.TTE)
|
||||||
{
|
{
|
||||||
Console.WriteLn("SIF1 TTE");
|
Console.WriteLn("SIF1 TTE");
|
||||||
sif1.fifo.write((u32*)ptag + 2, 2);
|
sif1.fifo.write((u32*)ptag + 2, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sif1dma->chcr.TIE && ptag->IRQ)
|
if (sif1dma.chcr.TIE && ptag->IRQ)
|
||||||
{
|
{
|
||||||
Console.WriteLn("SIF1 TIE");
|
Console.WriteLn("SIF1 TIE");
|
||||||
sif1.ee.end = true;
|
sif1.ee.end = true;
|
||||||
|
@ -109,30 +109,30 @@ static __fi bool ProcessEETag()
|
||||||
{
|
{
|
||||||
case TAG_REFE:
|
case TAG_REFE:
|
||||||
sif1.ee.end = true;
|
sif1.ee.end = true;
|
||||||
sif1dma->madr = ptag[1]._u32;
|
sif1dma.madr = ptag[1]._u32;
|
||||||
sif1dma->tadr += 16;
|
sif1dma.tadr += 16;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TAG_CNT:
|
case TAG_CNT:
|
||||||
sif1dma->madr = sif1dma->tadr + 16;
|
sif1dma.madr = sif1dma.tadr + 16;
|
||||||
sif1dma->tadr = sif1dma->madr + (sif1dma->qwc << 4);
|
sif1dma.tadr = sif1dma.madr + (sif1dma.qwc << 4);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TAG_NEXT:
|
case TAG_NEXT:
|
||||||
sif1dma->madr = sif1dma->tadr + 16;
|
sif1dma.madr = sif1dma.tadr + 16;
|
||||||
sif1dma->tadr = ptag[1]._u32;
|
sif1dma.tadr = ptag[1]._u32;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TAG_REF:
|
case TAG_REF:
|
||||||
case TAG_REFS:
|
case TAG_REFS:
|
||||||
sif1dma->madr = ptag[1]._u32;
|
sif1dma.madr = ptag[1]._u32;
|
||||||
sif1dma->tadr += 16;
|
sif1dma.tadr += 16;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TAG_END:
|
case TAG_END:
|
||||||
sif1.ee.end = true;
|
sif1.ee.end = true;
|
||||||
sif1dma->madr = sif1dma->tadr + 16;
|
sif1dma.madr = sif1dma.tadr + 16;
|
||||||
sif1dma->tadr = sif1dma->madr + (sif1dma->qwc << 4);
|
sif1dma.tadr = sif1dma.madr + (sif1dma.qwc << 4);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -203,31 +203,31 @@ static __fi void EndIOP()
|
||||||
// Handle the EE transfer.
|
// Handle the EE transfer.
|
||||||
static __fi void HandleEETransfer()
|
static __fi void HandleEETransfer()
|
||||||
{
|
{
|
||||||
if(sif1dma->chcr.STR == false)
|
if(sif1dma.chcr.STR == false)
|
||||||
{
|
{
|
||||||
DevCon.Warning("Replacement for irq prevention hack EE SIF1");
|
DevCon.Warning("Replacement for irq prevention hack EE SIF1");
|
||||||
sif1.ee.end = false;
|
sif1.ee.end = false;
|
||||||
sif1.ee.busy = false;
|
sif1.ee.busy = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (dmacRegs->ctrl.STD == STD_SIF1)
|
if (dmacRegs.ctrl.STD == STD_SIF1)
|
||||||
{
|
{
|
||||||
DevCon.Warning("SIF1 stall control"); // STD == fromSIF1
|
DevCon.Warning("SIF1 stall control"); // STD == fromSIF1
|
||||||
}
|
}
|
||||||
|
|
||||||
/*if (sif1dma->qwc == 0)
|
/*if (sif1dma.qwc == 0)
|
||||||
if (sif1dma->chcr.MOD == NORMAL_MODE)
|
if (sif1dma.chcr.MOD == NORMAL_MODE)
|
||||||
if (!sif1.ee.end){
|
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;
|
done = true;
|
||||||
return;
|
return;
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
// If there's no more to transfer.
|
// 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 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;
|
done = true;
|
||||||
EndEE();
|
EndEE();
|
||||||
|
@ -292,7 +292,7 @@ __fi void SIF1Dma()
|
||||||
|
|
||||||
if (sif1.ee.busy)
|
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++;
|
BusyCheck++;
|
||||||
HandleEETransfer();
|
HandleEETransfer();
|
||||||
|
@ -322,21 +322,21 @@ __fi void sif1Interrupt()
|
||||||
__fi void EEsif1Interrupt()
|
__fi void EEsif1Interrupt()
|
||||||
{
|
{
|
||||||
hwDmacIrq(DMAC_SIF1);
|
hwDmacIrq(DMAC_SIF1);
|
||||||
sif1dma->chcr.STR = false;
|
sif1dma.chcr.STR = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Do almost exactly the same thing as psxDma10 in IopDma.cpp.
|
// Do almost exactly the same thing as psxDma10 in IopDma.cpp.
|
||||||
// Main difference is this checks for iop, where psxDma10 checks for ee.
|
// Main difference is this checks for iop, where psxDma10 checks for ee.
|
||||||
__fi void dmaSIF1()
|
__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)
|
if (sif1.fifo.readPos != sif1.fifo.writePos)
|
||||||
{
|
{
|
||||||
SIF_LOG("warning, sif1.fifoReadPos != sif1.fifoWritePos");
|
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;
|
psHu32(SBUS_F240) |= 0x4000;
|
||||||
sif1.ee.busy = true;
|
sif1.ee.busy = true;
|
||||||
|
|
87
pcsx2/VU.h
87
pcsx2/VU.h
|
@ -16,10 +16,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "Vif.h"
|
#include "Vif.h"
|
||||||
|
|
||||||
#ifdef _MSC_VER // Most of the structs here should be packed
|
|
||||||
# pragma pack(1)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
enum VURegFlags
|
enum VURegFlags
|
||||||
{
|
{
|
||||||
REG_STATUS_FLAG = 16,
|
REG_STATUS_FLAG = 16,
|
||||||
|
@ -68,7 +64,7 @@ union VECTOR {
|
||||||
s16 SS[8];
|
s16 SS[8];
|
||||||
u8 UC[16];
|
u8 UC[16];
|
||||||
s8 SC[16];
|
s8 SC[16];
|
||||||
} __packed;
|
};
|
||||||
|
|
||||||
struct REG_VI {
|
struct REG_VI {
|
||||||
union {
|
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
|
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)
|
// VU0 mem, with only lower 16 bits valid, and the upper 112bits are hardwired to 0 (cottonvibes)
|
||||||
} __packed;
|
};
|
||||||
|
|
||||||
//#define VUFLAG_BREAKONMFLAG 0x00000001
|
//#define VUFLAG_BREAKONMFLAG 0x00000001
|
||||||
#define VUFLAG_MFLAGSET 0x00000002
|
#define VUFLAG_MFLAGSET 0x00000002
|
||||||
|
@ -120,45 +116,61 @@ struct ialuPipe {
|
||||||
u32 Cycle;
|
u32 Cycle;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct VURegs {
|
struct __aligned16 VURegs {
|
||||||
VECTOR VF[32]; // VF and VI need to be first in this struct for proper mapping
|
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)
|
REG_VI VI[32]; // needs to be 128bit x 32 (cottonvibes)
|
||||||
|
|
||||||
VECTOR ACC;
|
VECTOR ACC;
|
||||||
REG_VI q;
|
REG_VI q;
|
||||||
REG_VI p;
|
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 macflag;
|
||||||
u32 statusflag;
|
u32 statusflag;
|
||||||
u32 clipflag;
|
u32 clipflag;
|
||||||
|
|
||||||
u32 cycle;
|
|
||||||
u32 flags;
|
|
||||||
|
|
||||||
void (*vuExec)(VURegs*);
|
|
||||||
VIFregisters *vifRegs;
|
|
||||||
|
|
||||||
u8 *Mem;
|
u8 *Mem;
|
||||||
u8 *Micro;
|
u8 *Micro;
|
||||||
|
|
||||||
u32 code;
|
u32 ebit;
|
||||||
u32 maxmem;
|
|
||||||
u32 maxmicro;
|
|
||||||
|
|
||||||
u16 branch;
|
|
||||||
u16 ebit;
|
|
||||||
u32 branchpc;
|
|
||||||
|
|
||||||
fmacPipe fmac[8];
|
fmacPipe fmac[8];
|
||||||
fdivPipe fdiv;
|
fdivPipe fdiv;
|
||||||
efuPipe efu;
|
efuPipe efu;
|
||||||
ialuPipe ialu[8];
|
ialuPipe ialu[8];
|
||||||
|
|
||||||
VURegs() :
|
VURegs()
|
||||||
Mem( NULL )
|
|
||||||
, Micro( NULL )
|
|
||||||
{
|
{
|
||||||
|
Mem = NULL;
|
||||||
|
Micro = NULL;
|
||||||
}
|
}
|
||||||
} __packed;
|
|
||||||
|
bool IsVU1() const;
|
||||||
|
bool IsVU0() const;
|
||||||
|
|
||||||
|
VIFregisters& GetVifRegs() const
|
||||||
|
{
|
||||||
|
return IsVU1() ? vif1Regs : vif0Regs;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
enum VUPipeState
|
enum VUPipeState
|
||||||
{
|
{
|
||||||
|
@ -171,27 +183,16 @@ enum VUPipeState
|
||||||
VUPIPE_XGKICK
|
VUPIPE_XGKICK
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _VURegsNum {
|
extern __aligned16 VURegs vuRegs[2];
|
||||||
u8 pipe; // if 0xff, COP2
|
|
||||||
u8 VFwrite;
|
|
||||||
u8 VFwxyzw;
|
|
||||||
u8 VFr0xyzw;
|
|
||||||
u8 VFr1xyzw;
|
|
||||||
u8 VFread0;
|
|
||||||
u8 VFread1;
|
|
||||||
u32 VIwrite;
|
|
||||||
u32 VIread;
|
|
||||||
int cycles;
|
|
||||||
};
|
|
||||||
|
|
||||||
#ifdef _MSC_VER // Restore to default pack alignment
|
// Obsolete(?) -- I think I'd rather use vu0Regs/vu1Regs or actually have these explicit to any
|
||||||
# pragma pack()
|
// CPP file that needs them only. --air
|
||||||
#endif
|
static VURegs& VU0 = vuRegs[0];
|
||||||
|
static VURegs& VU1 = vuRegs[1];
|
||||||
|
|
||||||
extern VURegs* g_pVU1;
|
// Do not use __fi here because it fires 'multiple definition' error in GCC
|
||||||
extern __aligned16 VURegs VU0;
|
inline bool VURegs::IsVU1() const { return this == &vuRegs[1]; }
|
||||||
|
inline bool VURegs::IsVU0() const { return this == &vuRegs[0]; }
|
||||||
#define VU1 (*g_pVU1)
|
|
||||||
|
|
||||||
extern u32* GET_VU_MEM(VURegs* VU, u32 addr);
|
extern u32* GET_VU_MEM(VURegs* VU, u32 addr);
|
||||||
|
|
||||||
|
|
172
pcsx2/VU0.cpp
172
pcsx2/VU0.cpp
|
@ -44,8 +44,6 @@
|
||||||
|
|
||||||
using namespace R5900;
|
using namespace R5900;
|
||||||
|
|
||||||
__aligned16 VURegs VU0;
|
|
||||||
|
|
||||||
void COP2_BC2() { Int_COP2BC2PrintTable[_Rt_]();}
|
void COP2_BC2() { Int_COP2BC2PrintTable[_Rt_]();}
|
||||||
void COP2_SPECIAL() { Int_COP2SPECIAL1PrintTable[_Funct_]();}
|
void COP2_SPECIAL() { Int_COP2SPECIAL1PrintTable[_Funct_]();}
|
||||||
|
|
||||||
|
@ -88,15 +86,10 @@ namespace OpcodeImpl
|
||||||
void LQC2() {
|
void LQC2() {
|
||||||
u32 addr = cpuRegs.GPR.r[_Rs_].UL[0] + (s16)cpuRegs.code;
|
u32 addr = cpuRegs.GPR.r[_Rs_].UL[0] + (s16)cpuRegs.code;
|
||||||
if (_Ft_) {
|
if (_Ft_) {
|
||||||
#ifdef __LINUX__
|
memRead128(addr, VU0.VF[_Ft_].UQ);
|
||||||
// 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
|
|
||||||
} else {
|
} else {
|
||||||
u64 val[2];
|
u128 val;
|
||||||
memRead128(addr, val);
|
memRead128(addr, val);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -105,9 +98,7 @@ namespace OpcodeImpl
|
||||||
// HUH why ? doesn't make any sense ...
|
// HUH why ? doesn't make any sense ...
|
||||||
void SQC2() {
|
void SQC2() {
|
||||||
u32 addr = _Imm_ + cpuRegs.GPR.r[_Rs_].UL[0];
|
u32 addr = _Imm_ + cpuRegs.GPR.r[_Rs_].UL[0];
|
||||||
//memWrite64(addr, VU0.VF[_Ft_].UD[0]);
|
memWrite128(addr, VU0.VF[_Ft_].UQ);
|
||||||
//memWrite64(addr+8,VU0.VF[_Ft_].UD[1]);
|
|
||||||
memWrite128(addr, VU0.VF[_Ft_].UD);
|
|
||||||
}
|
}
|
||||||
}}}
|
}}}
|
||||||
|
|
||||||
|
@ -180,158 +171,3 @@ void CTC2() {
|
||||||
break;
|
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); }
|
|
||||||
|
|
||||||
|
|
|
@ -20,11 +20,10 @@
|
||||||
|
|
||||||
#include "PrecompiledHeader.h"
|
#include "PrecompiledHeader.h"
|
||||||
#include "Common.h"
|
#include "Common.h"
|
||||||
|
#include "VUmicro.h"
|
||||||
|
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
||||||
#include "VUmicro.h"
|
|
||||||
|
|
||||||
using namespace R5900;
|
using namespace R5900;
|
||||||
|
|
||||||
#define VF_VAL(x) ((x==0x80000000)?0:(x))
|
#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_VPU_STAT].UL &= ~0xff; // stop vu0
|
||||||
VU0.VI[REG_FBRST].UL &= ~0xff; // stop vu0
|
VU0.VI[REG_FBRST].UL &= ~0xff; // stop vu0
|
||||||
vif0Regs->stat.VEW = false;
|
vif0Regs.stat.VEW = false;
|
||||||
}
|
|
||||||
|
|
||||||
void VU0MI_XGKICK() {
|
|
||||||
}
|
|
||||||
|
|
||||||
void VU0MI_XTOP() {
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void __fastcall vu0ExecMicro(u32 addr) {
|
void __fastcall vu0ExecMicro(u32 addr) {
|
||||||
|
@ -58,362 +51,3 @@ void __fastcall vu0ExecMicro(u32 addr) {
|
||||||
_vuExecMicroDebug(VU0);
|
_vuExecMicroDebug(VU0);
|
||||||
CpuVU0->ExecuteBlock(1);
|
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); }
|
|
||||||
|
|
|
@ -21,15 +21,13 @@
|
||||||
|
|
||||||
extern void _vuFlushAll(VURegs* VU);
|
extern void _vuFlushAll(VURegs* VU);
|
||||||
|
|
||||||
_vuTables(VU0, VU0);
|
static void _vu0ExecUpper(VURegs* VU, u32 *ptr) {
|
||||||
|
|
||||||
void _vu0ExecUpper(VURegs* VU, u32 *ptr) {
|
|
||||||
VU->code = ptr[1];
|
VU->code = ptr[1];
|
||||||
IdebugUPPER(VU0);
|
IdebugUPPER(VU0);
|
||||||
VU0_UPPER_OPCODE[VU->code & 0x3f]();
|
VU0_UPPER_OPCODE[VU->code & 0x3f]();
|
||||||
}
|
}
|
||||||
|
|
||||||
void _vu0ExecLower(VURegs* VU, u32 *ptr) {
|
static void _vu0ExecLower(VURegs* VU, u32 *ptr) {
|
||||||
VU->code = ptr[0];
|
VU->code = ptr[0];
|
||||||
IdebugLOWER(VU0);
|
IdebugLOWER(VU0);
|
||||||
VU0_LOWER_OPCODE[VU->code >> 25]();
|
VU0_LOWER_OPCODE[VU->code >> 25]();
|
||||||
|
@ -49,15 +47,6 @@ static void _vu0Exec(VURegs* VU)
|
||||||
int vireg;
|
int vireg;
|
||||||
int discard=0;
|
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];
|
ptr = (u32*)&VU->Micro[VU->VI[REG_TPC].UL];
|
||||||
VU->VI[REG_TPC].UL+=8;
|
VU->VI[REG_TPC].UL+=8;
|
||||||
|
|
||||||
|
@ -166,21 +155,15 @@ static void _vu0Exec(VURegs* VU)
|
||||||
if( VU->ebit-- == 1 ) {
|
if( VU->ebit-- == 1 ) {
|
||||||
_vuFlushAll(VU);
|
_vuFlushAll(VU);
|
||||||
VU0.VI[REG_VPU_STAT].UL&= ~0x1; /* E flag */
|
VU0.VI[REG_VPU_STAT].UL&= ~0x1; /* E flag */
|
||||||
vif0Regs->stat.VEW = false;
|
vif0Regs.stat.VEW = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void vu0Exec(VURegs* VU)
|
void vu0Exec(VURegs* VU)
|
||||||
{
|
{
|
||||||
if (VU->VI[REG_TPC].UL >= VU->maxmicro) {
|
VU0.VI[REG_TPC].UL &= VU0_PROGMASK;
|
||||||
#ifdef CPU_LOG
|
_vu0Exec(VU);
|
||||||
Console.Warning("VU0 memory overflow!!: %x", VU->VI[REG_TPC].UL);
|
|
||||||
#endif
|
|
||||||
VU0.VI[REG_VPU_STAT].UL&= ~0x1;
|
|
||||||
} else {
|
|
||||||
_vu0Exec(VU);
|
|
||||||
}
|
|
||||||
VU->cycle++;
|
VU->cycle++;
|
||||||
|
|
||||||
if (VU->VI[0].UL != 0) DbgCon.Error("VI[0] != 0!!!!\n");
|
if (VU->VI[0].UL != 0) DbgCon.Error("VI[0] != 0!!!!\n");
|
||||||
|
|
|
@ -24,8 +24,6 @@
|
||||||
|
|
||||||
#include "VUmicro.h"
|
#include "VUmicro.h"
|
||||||
|
|
||||||
VURegs* g_pVU1;
|
|
||||||
|
|
||||||
#ifdef PCSX2_DEBUG
|
#ifdef PCSX2_DEBUG
|
||||||
u32 vudump = 0;
|
u32 vudump = 0;
|
||||||
#endif
|
#endif
|
||||||
|
@ -37,7 +35,7 @@ void vu1ResetRegs()
|
||||||
{
|
{
|
||||||
VU0.VI[REG_VPU_STAT].UL &= ~0xff00; // stop vu1
|
VU0.VI[REG_VPU_STAT].UL &= ~0xff00; // stop vu1
|
||||||
VU0.VI[REG_FBRST].UL &= ~0xff00; // stop vu1
|
VU0.VI[REG_FBRST].UL &= ~0xff00; // stop vu1
|
||||||
vif1Regs->stat.VEW = false;
|
vif1Regs.stat.VEW = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void vu1Finish() {
|
void vu1Finish() {
|
||||||
|
@ -58,373 +56,9 @@ void __fastcall vu1ExecMicro(u32 addr)
|
||||||
VU0.VI[REG_VPU_STAT].UL &= ~0xFF00;
|
VU0.VI[REG_VPU_STAT].UL &= ~0xFF00;
|
||||||
VU0.VI[REG_VPU_STAT].UL |= 0x0100;
|
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;
|
if ((s32)addr != -1) VU1.VI[REG_TPC].UL = addr;
|
||||||
_vuExecMicroDebug(VU1);
|
_vuExecMicroDebug(VU1);
|
||||||
|
|
||||||
CpuVU1->Execute(vu1RunCycles);
|
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); }
|
|
||||||
|
|
|
@ -21,8 +21,6 @@
|
||||||
|
|
||||||
extern void _vuFlushAll(VURegs* VU);
|
extern void _vuFlushAll(VURegs* VU);
|
||||||
|
|
||||||
_vuTables(VU1, VU1);
|
|
||||||
|
|
||||||
void _vu1ExecUpper(VURegs* VU, u32 *ptr) {
|
void _vu1ExecUpper(VURegs* VU, u32 *ptr) {
|
||||||
VU->code = ptr[1];
|
VU->code = ptr[1];
|
||||||
IdebugUPPER(VU1);
|
IdebugUPPER(VU1);
|
||||||
|
@ -50,13 +48,6 @@ static void _vu1Exec(VURegs* VU)
|
||||||
int vireg;
|
int vireg;
|
||||||
int discard=0;
|
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];
|
ptr = (u32*)&VU->Micro[VU->VI[REG_TPC].UL];
|
||||||
VU->VI[REG_TPC].UL+=8;
|
VU->VI[REG_TPC].UL+=8;
|
||||||
|
|
||||||
|
@ -159,7 +150,7 @@ static void _vu1Exec(VURegs* VU)
|
||||||
if( VU->ebit-- == 1 ) {
|
if( VU->ebit-- == 1 ) {
|
||||||
_vuFlushAll(VU);
|
_vuFlushAll(VU);
|
||||||
VU0.VI[REG_VPU_STAT].UL &= ~0x100;
|
VU0.VI[REG_VPU_STAT].UL &= ~0x100;
|
||||||
vif1Regs->stat.VEW = false;
|
vif1Regs.stat.VEW = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -184,6 +175,7 @@ InterpVU1::InterpVU1()
|
||||||
|
|
||||||
void InterpVU1::Step()
|
void InterpVU1::Step()
|
||||||
{
|
{
|
||||||
|
VU1.VI[REG_TPC].UL &= VU1_PROGMASK;
|
||||||
vu1Exec( &VU1 );
|
vu1Exec( &VU1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -192,11 +184,11 @@ void InterpVU1::Execute(u32 cycles)
|
||||||
for (int i = (int)cycles; i > 0 ; i--) {
|
for (int i = (int)cycles; i > 0 ; i--) {
|
||||||
if (!(VU0.VI[REG_VPU_STAT].UL & 0x100)) {
|
if (!(VU0.VI[REG_VPU_STAT].UL & 0x100)) {
|
||||||
if (VU1.branch || VU1.ebit) {
|
if (VU1.branch || VU1.ebit) {
|
||||||
vu1Exec(&VU1); // run branch delay slot?
|
Step(); // run branch delay slot?
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
vu1Exec(&VU1);
|
Step();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
1205
pcsx2/VUmicro.h
1205
pcsx2/VUmicro.h
File diff suppressed because it is too large
Load Diff
|
@ -18,10 +18,12 @@
|
||||||
#include "Common.h"
|
#include "Common.h"
|
||||||
#include "VUmicro.h"
|
#include "VUmicro.h"
|
||||||
|
|
||||||
|
__aligned16 VURegs vuRegs[2];
|
||||||
|
|
||||||
static u8* m_vuAllMem = NULL;
|
static u8* m_vuAllMem = NULL;
|
||||||
static const uint m_vuMemSize =
|
static const uint m_vuMemSize =
|
||||||
0x1000 + // VU0micro memory
|
0x1000 + // VU0micro memory
|
||||||
0x4000+0x800 + // VU0 memory and VU1 registers
|
0x4000 + // VU0 memory
|
||||||
0x4000 + // VU1 memory
|
0x4000 + // VU1 memory
|
||||||
0x4000;
|
0x4000;
|
||||||
|
|
||||||
|
@ -33,12 +35,9 @@ void vuMicroMemAlloc()
|
||||||
if( m_vuAllMem == NULL )
|
if( m_vuAllMem == NULL )
|
||||||
throw Exception::OutOfMemory( L"VU0 and VU1 on-chip memory" );
|
throw Exception::OutOfMemory( L"VU0 and VU1 on-chip memory" );
|
||||||
|
|
||||||
pxAssume( sizeof( VURegs ) <= 0x800 );
|
|
||||||
|
|
||||||
u8* curpos = m_vuAllMem;
|
u8* curpos = m_vuAllMem;
|
||||||
VU0.Micro = curpos; curpos += 0x1000;
|
VU0.Micro = curpos; curpos += 0x1000;
|
||||||
VU0.Mem = curpos; curpos += 0x4000;
|
VU0.Mem = curpos; curpos += 0x4000;
|
||||||
g_pVU1 = (VURegs*)curpos; curpos += 0x800;
|
|
||||||
VU1.Micro = curpos; curpos += 0x4000;
|
VU1.Micro = curpos; curpos += 0x4000;
|
||||||
VU1.Mem = curpos;
|
VU1.Mem = curpos;
|
||||||
//curpos += 0x4000;
|
//curpos += 0x4000;
|
||||||
|
@ -50,7 +49,6 @@ void vuMicroMemShutdown()
|
||||||
|
|
||||||
vtlb_free( m_vuAllMem, m_vuMemSize );
|
vtlb_free( m_vuAllMem, m_vuMemSize );
|
||||||
m_vuAllMem = NULL;
|
m_vuAllMem = NULL;
|
||||||
g_pVU1 = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void vuMicroMemReset()
|
void vuMicroMemReset()
|
||||||
|
@ -72,17 +70,6 @@ void vuMicroMemReset()
|
||||||
memzero_ptr<4*1024>(VU0.Mem);
|
memzero_ptr<4*1024>(VU0.Mem);
|
||||||
memzero_ptr<4*1024>(VU0.Micro);
|
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 ===
|
// === VU1 Initialization ===
|
||||||
memzero(VU1.ACC);
|
memzero(VU1.ACC);
|
||||||
memzero(VU1.VF);
|
memzero(VU1.VF);
|
||||||
|
@ -94,13 +81,6 @@ void vuMicroMemReset()
|
||||||
VU1.VI[0].UL = 0;
|
VU1.VI[0].UL = 0;
|
||||||
memzero_ptr<16*1024>(VU1.Mem);
|
memzero_ptr<16*1024>(VU1.Mem);
|
||||||
memzero_ptr<16*1024>(VU1.Micro);
|
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()
|
void SaveStateBase::vuMicroFreeze()
|
||||||
|
|
1740
pcsx2/VUops.cpp
1740
pcsx2/VUops.cpp
File diff suppressed because it is too large
Load Diff
373
pcsx2/VUops.h
373
pcsx2/VUops.h
|
@ -27,354 +27,35 @@
|
||||||
|
|
||||||
#define MAC_Reset( VU ) VU->VI[REG_MAC_FLAG].UL = VU->VI[REG_MAC_FLAG].UL & (~0xFFFF)
|
#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 _vuTestPipes(VURegs * VU);
|
||||||
extern void _vuTestUpperStalls(VURegs * VU, _VURegsNum *VUregsn);
|
extern void _vuTestUpperStalls(VURegs * VU, _VURegsNum *VUregsn);
|
||||||
extern void _vuTestLowerStalls(VURegs * VU, _VURegsNum *VUregsn);
|
extern void _vuTestLowerStalls(VURegs * VU, _VURegsNum *VUregsn);
|
||||||
extern void _vuAddUpperStalls(VURegs * VU, _VURegsNum *VUregsn);
|
extern void _vuAddUpperStalls(VURegs * VU, _VURegsNum *VUregsn);
|
||||||
extern void _vuAddLowerStalls(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);
|
|
||||||
|
|
168
pcsx2/Vif.cpp
168
pcsx2/Vif.cpp
|
@ -29,13 +29,13 @@ void vif0Reset()
|
||||||
{
|
{
|
||||||
/* Reset the whole VIF, meaning the internal pcsx2 vars and all the registers */
|
/* Reset the whole VIF, meaning the internal pcsx2 vars and all the registers */
|
||||||
memzero(vif0);
|
memzero(vif0);
|
||||||
memzero(*vif0Regs);
|
memzero(vif0Regs);
|
||||||
|
|
||||||
psHu64(VIF0_FIFO) = 0;
|
psHu64(VIF0_FIFO) = 0;
|
||||||
psHu64(VIF0_FIFO + 8) = 0;
|
psHu64(VIF0_FIFO + 8) = 0;
|
||||||
|
|
||||||
vif0Regs->stat.VPS = VPS_IDLE;
|
vif0Regs.stat.VPS = VPS_IDLE;
|
||||||
vif0Regs->stat.FQC = 0;
|
vif0Regs.stat.FQC = 0;
|
||||||
|
|
||||||
vif0.done = false;
|
vif0.done = false;
|
||||||
|
|
||||||
|
@ -46,13 +46,13 @@ void vif1Reset()
|
||||||
{
|
{
|
||||||
/* Reset the whole VIF, meaning the internal pcsx2 vars, and all the registers */
|
/* Reset the whole VIF, meaning the internal pcsx2 vars, and all the registers */
|
||||||
memzero(vif1);
|
memzero(vif1);
|
||||||
memzero(*vif1Regs);
|
memzero(vif1Regs);
|
||||||
|
|
||||||
psHu64(VIF1_FIFO) = 0;
|
psHu64(VIF1_FIFO) = 0;
|
||||||
psHu64(VIF1_FIFO + 8) = 0;
|
psHu64(VIF1_FIFO + 8) = 0;
|
||||||
|
|
||||||
vif1Regs->stat.VPS = VPS_IDLE;
|
vif1Regs.stat.VPS = VPS_IDLE;
|
||||||
vif1Regs->stat.FQC = 0; // FQC=0
|
vif1Regs.stat.FQC = 0; // FQC=0
|
||||||
|
|
||||||
vif1.done = false;
|
vif1.done = false;
|
||||||
cpuRegs.interrupt &= ~((1 << 1) | (1 << 10)); //Stop all vif1 DMA's
|
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.
|
if (value & 0x1) // Reset Vif.
|
||||||
{
|
{
|
||||||
//Console.WriteLn("Vif0 Reset %x", vif0Regs->stat._u32);
|
//Console.WriteLn("Vif0 Reset %x", vif0Regs.stat._u32);
|
||||||
|
|
||||||
memzero(vif0);
|
memzero(vif0);
|
||||||
vif0ch->qwc = 0; //?
|
vif0ch.qwc = 0; //?
|
||||||
cpuRegs.interrupt &= ~1; //Stop all vif0 DMA's
|
cpuRegs.interrupt &= ~1; //Stop all vif0 DMA's
|
||||||
psHu64(VIF0_FIFO) = 0;
|
psHu64(VIF0_FIFO) = 0;
|
||||||
psHu64(VIF0_FIFO + 8) = 0;
|
psHu64(VIF0_FIFO + 8) = 0;
|
||||||
vif0.done = false;
|
vif0.done = false;
|
||||||
vif0Regs->err.reset();
|
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.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
|
/* 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) */
|
/* I guess we should stop the VIF dma here, but not 100% sure (linuz) */
|
||||||
cpuRegs.interrupt &= ~1; //Stop all vif0 DMA's
|
cpuRegs.interrupt &= ~1; //Stop all vif0 DMA's
|
||||||
vif0Regs->stat.VFS = true;
|
vif0Regs.stat.VFS = true;
|
||||||
vif0Regs->stat.VPS = VPS_IDLE;
|
vif0Regs.stat.VPS = VPS_IDLE;
|
||||||
Console.WriteLn("vif0 force break");
|
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
|
// 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).
|
// just stoppin the VIF (linuz).
|
||||||
vif0Regs->stat.VSS = true;
|
vif0Regs.stat.VSS = true;
|
||||||
vif0Regs->stat.VPS = VPS_IDLE;
|
vif0Regs.stat.VPS = VPS_IDLE;
|
||||||
vif0.vifstalled = true;
|
vif0.vifstalled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -128,10 +128,10 @@ __fi void vif0FBRST(u32 value) {
|
||||||
bool cancel = false;
|
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 */
|
/* 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;
|
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);
|
VIF0_STAT_INT | VIF0_STAT_ER0 | VIF0_STAT_ER1);
|
||||||
if (cancel)
|
if (cancel)
|
||||||
{
|
{
|
||||||
|
@ -140,8 +140,8 @@ __fi void vif0FBRST(u32 value) {
|
||||||
g_vifCycles = 0;
|
g_vifCycles = 0;
|
||||||
|
|
||||||
// loop necessary for spiderman
|
// loop necessary for spiderman
|
||||||
//vif0ch->chcr.STR = true;
|
//vif0ch.chcr.STR = true;
|
||||||
if(vif0ch->chcr.STR) CPU_INT(DMAC_VIF0, 0); // Gets the timing right - Flatout
|
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);
|
memzero(vif1);
|
||||||
//cpuRegs.interrupt &= ~((1 << 1) | (1 << 10)); //Stop all vif1 DMA's
|
//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) = 0;
|
||||||
psHu64(VIF1_FIFO + 8) = 0;
|
psHu64(VIF1_FIFO + 8) = 0;
|
||||||
//vif1.done = false;
|
//vif1.done = false;
|
||||||
|
|
||||||
|
|
||||||
//DevCon.Warning("VIF FBRST Reset MSK = %x", vif1Regs->mskpath3);
|
//DevCon.Warning("VIF FBRST Reset MSK = %x", vif1Regs.mskpath3);
|
||||||
if(vif1Regs->mskpath3 == 1 && GSTransferStatus.PTH3 == STOPPED_MODE && gif->chcr.STR == true)
|
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();
|
gsInterrupt();
|
||||||
vif1Regs->mskpath3 = false;
|
vif1Regs.mskpath3 = false;
|
||||||
gifRegs->stat.M3P = 0;
|
gifRegs.stat.M3P = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
vif1Regs->mskpath3 = false;
|
vif1Regs.mskpath3 = false;
|
||||||
gifRegs->stat.M3P = 0;
|
gifRegs.stat.M3P = 0;
|
||||||
vif1Regs->err.reset();
|
vif1Regs.err.reset();
|
||||||
vif1.inprogress = 0;
|
vif1.inprogress = 0;
|
||||||
vif1.cmd = 0;
|
vif1.cmd = 0;
|
||||||
vif1.vifstalled = false;
|
vif1.vifstalled = false;
|
||||||
vif1Regs->stat.FQC = 0;
|
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.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
|
/* 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.
|
if (FBRST(value).FBK) // Forcebreak Vif.
|
||||||
{
|
{
|
||||||
/* I guess we should stop the VIF dma here, but not 100% sure (linuz) */
|
/* I guess we should stop the VIF dma here, but not 100% sure (linuz) */
|
||||||
vif1Regs->stat.VFS = true;
|
vif1Regs.stat.VFS = true;
|
||||||
vif1Regs->stat.VPS = VPS_IDLE;
|
vif1Regs.stat.VPS = VPS_IDLE;
|
||||||
cpuRegs.interrupt &= ~((1 << 1) | (1 << 10)); //Stop all vif1 DMA's
|
cpuRegs.interrupt &= ~((1 << 1) | (1 << 10)); //Stop all vif1 DMA's
|
||||||
Console.WriteLn("vif1 force break");
|
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
|
// 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).
|
// just stoppin the VIF (linuz).
|
||||||
vif1Regs->stat.VSS = true;
|
vif1Regs.stat.VSS = true;
|
||||||
vif1Regs->stat.VPS = VPS_IDLE;
|
vif1Regs.stat.VPS = VPS_IDLE;
|
||||||
cpuRegs.interrupt &= ~((1 << 1) | (1 << 10)); //Stop all vif1 DMA's
|
cpuRegs.interrupt &= ~((1 << 1) | (1 << 10)); //Stop all vif1 DMA's
|
||||||
vif1.vifstalled = true;
|
vif1.vifstalled = true;
|
||||||
}
|
}
|
||||||
|
@ -206,12 +206,12 @@ __fi void vif1FBRST(u32 value) {
|
||||||
bool cancel = false;
|
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 */
|
/* 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;
|
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);
|
VIF1_STAT_INT | VIF1_STAT_ER0 | VIF1_STAT_ER1);
|
||||||
|
|
||||||
if (cancel)
|
if (cancel)
|
||||||
|
@ -220,22 +220,22 @@ __fi void vif1FBRST(u32 value) {
|
||||||
{
|
{
|
||||||
g_vifCycles = 0;
|
g_vifCycles = 0;
|
||||||
// loop necessary for spiderman
|
// loop necessary for spiderman
|
||||||
switch(dmacRegs->ctrl.MFD)
|
switch(dmacRegs.ctrl.MFD)
|
||||||
{
|
{
|
||||||
case MFD_VIF1:
|
case MFD_VIF1:
|
||||||
//Console.WriteLn("MFIFO Stall");
|
//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;
|
break;
|
||||||
|
|
||||||
case NO_MFD:
|
case NO_MFD:
|
||||||
case MFD_RESERVED:
|
case MFD_RESERVED:
|
||||||
case MFD_GIF: // Wonder if this should be with VIF?
|
case MFD_GIF: // Wonder if this should be with VIF?
|
||||||
// Gets the timing right - Flatout
|
// 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;
|
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);
|
VIF_LOG("VIF1_STAT write32 0x%8.8x", value);
|
||||||
|
|
||||||
/* Only FDR bit is writable, so mask the rest */
|
/* 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
|
// 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");
|
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)
|
// Hack but it checks this is true before transfer? (fatal frame)
|
||||||
// Update Refraction: Use of this function has been investigated and understood.
|
// 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
|
// 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)
|
// 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);
|
//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.
|
//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 ;)
|
//Other times it can read it off ;)
|
||||||
vif1Regs->stat.FQC = 0;
|
vif1Regs.stat.FQC = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#define caseVif(x) (idx ? VIF1_##x : VIF0_##x)
|
#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) {
|
switch (mem) {
|
||||||
case caseVif(MARK):
|
case caseVif(MARK):
|
||||||
VIF_LOG("VIF%d_MARK write32 0x%8.8x", idx, value);
|
VIF_LOG("VIF%d_MARK write32 0x%8.8x", idx, value);
|
||||||
vifXRegs->stat.MRK = false;
|
vifXRegs.stat.MRK = false;
|
||||||
vifXRegs->mark = value;
|
//vifXRegs.mark = value;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case caseVif(FBRST):
|
case caseVif(FBRST):
|
||||||
if (!idx) vif0FBRST(value);
|
if (!idx) vif0FBRST(value);
|
||||||
else vif1FBRST(value);
|
else vif1FBRST(value);
|
||||||
break;
|
return false;
|
||||||
|
|
||||||
case caseVif(ERR):
|
|
||||||
VIF_LOG("VIF%d_ERR write32 0x%8.8x", idx, value);
|
|
||||||
vifXRegs->err.write(value);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case caseVif(STAT):
|
case caseVif(STAT):
|
||||||
if (idx) { // Only Vif1 does this stuff?
|
if (idx) { // Only Vif1 does this stuff?
|
||||||
vif1STAT(value);
|
vif1STAT(value);
|
||||||
}
|
}
|
||||||
else {
|
return false;
|
||||||
Console.WriteLn("Unknown Vif%d write to %x", idx, mem);
|
|
||||||
psHu32(mem) = value;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
|
case caseVif(ERR):
|
||||||
case caseVif(MODE):
|
case caseVif(MODE):
|
||||||
vifXRegs->mode = value;
|
// standard register writes -- handled by caller.
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case caseVif(R0):
|
case caseVif(ROW0):
|
||||||
case caseVif(R1):
|
case caseVif(ROW1):
|
||||||
case caseVif(R2):
|
case caseVif(ROW2):
|
||||||
case caseVif(R3):
|
case caseVif(ROW3):
|
||||||
if (!idx) g_vifmask.Row0[ (mem>>4)&3 ] = value;
|
// Here's a neat way to obfuscate code. This is a super-fancy-complicated version
|
||||||
else g_vifmask.Row1[ (mem>>4)&3 ] = value;
|
// of a standard psHu32(mem) = value; writeback. Handled by caller for us, thanks! --air
|
||||||
((u32*)&vifXRegs->r0) [((mem>>4)&3)*4] = value;
|
//if (!idx) g_vifmask.Row0[ (mem>>4)&3 ] = value;
|
||||||
break;
|
//else g_vifmask.Row1[ (mem>>4)&3 ] = value;
|
||||||
|
//((u32*)&vifXRegs.r0) [((mem>>4)&3)*4] = value;
|
||||||
|
break;
|
||||||
|
|
||||||
case caseVif(C0):
|
case caseVif(COL0):
|
||||||
case caseVif(C1):
|
case caseVif(COL1):
|
||||||
case caseVif(C2):
|
case caseVif(COL2):
|
||||||
case caseVif(C3):
|
case caseVif(COL3):
|
||||||
if (!idx) g_vifmask.Col0[ (mem>>4)&3 ] = value;
|
// Here's a neat way to obfuscate code. This is a super-fancy-complicated version
|
||||||
else g_vifmask.Col1[ (mem>>4)&3 ] = value;
|
// of a standard psHu32(mem) = value; writeback. Handled by caller for us, thanks! --air
|
||||||
((u32*)&vifXRegs->c0) [((mem>>4)&3)*4] = value;
|
//if (!idx) g_vifmask.Col0[ (mem>>4)&3 ] = value;
|
||||||
break;
|
//else g_vifmask.Col1[ (mem>>4)&3 ] = value;
|
||||||
|
//((u32*)&vifXRegs.c0) [((mem>>4)&3)*4] = value;
|
||||||
default:
|
break;
|
||||||
Console.WriteLn("Unknown Vif%d write to %x", idx, mem);
|
|
||||||
psHu32(mem) = 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);
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "MemoryTypes.h"
|
||||||
#include "R5900.h"
|
#include "R5900.h"
|
||||||
|
|
||||||
enum vif0_stat_flags
|
enum vif0_stat_flags
|
||||||
|
@ -214,10 +215,8 @@ struct VIFregisters {
|
||||||
|
|
||||||
extern VIFregisters *vifRegs;
|
extern VIFregisters *vifRegs;
|
||||||
|
|
||||||
#define vif0RegsRef ((VIFregisters&)eeMem->HW[0x3800])
|
static VIFregisters& vif0Regs = (VIFregisters&)eeHw[0x3800];
|
||||||
#define vif1RegsRef ((VIFregisters&)eeMem->HW[0x3c00])
|
static VIFregisters& vif1Regs = (VIFregisters&)eeHw[0x3C00];
|
||||||
#define vif0Regs (&vif0RegsRef)
|
|
||||||
#define vif1Regs (&vif1RegsRef)
|
|
||||||
|
|
||||||
#define _vifT template <int idx>
|
#define _vifT template <int idx>
|
||||||
#define GetVifX (idx ? (vif1) : (vif0))
|
#define GetVifX (idx ? (vif1) : (vif0))
|
||||||
|
|
|
@ -54,28 +54,28 @@ bool _VIF0chain()
|
||||||
{
|
{
|
||||||
u32 *pMem;
|
u32 *pMem;
|
||||||
|
|
||||||
if (vif0ch->qwc == 0)
|
if (vif0ch.qwc == 0)
|
||||||
{
|
{
|
||||||
vif0.inprogress = 0;
|
vif0.inprogress = 0;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
pMem = (u32*)dmaGetAddr(vif0ch->madr, false);
|
pMem = (u32*)dmaGetAddr(vif0ch.madr, false);
|
||||||
if (pMem == NULL)
|
if (pMem == NULL)
|
||||||
{
|
{
|
||||||
vif0.cmd = 0;
|
vif0.cmd = 0;
|
||||||
vif0.tag.size = 0;
|
vif0.tag.size = 0;
|
||||||
vif0ch->qwc = 0;
|
vif0ch.qwc = 0;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
VIF_LOG("VIF0chain size=%d, madr=%lx, tadr=%lx",
|
VIF_LOG("VIF0chain size=%d, madr=%lx, tadr=%lx",
|
||||||
vif0ch->qwc, vif0ch->madr, vif0ch->tadr);
|
vif0ch.qwc, vif0ch.madr, vif0ch.tadr);
|
||||||
|
|
||||||
if (vif0.vifstalled)
|
if (vif0.vifstalled)
|
||||||
return VIF0transfer(pMem + vif0.irqoffset, vif0ch->qwc * 4 - vif0.irqoffset);
|
return VIF0transfer(pMem + vif0.irqoffset, vif0ch.qwc * 4 - vif0.irqoffset);
|
||||||
else
|
else
|
||||||
return VIF0transfer(pMem, vif0ch->qwc * 4);
|
return VIF0transfer(pMem, vif0ch.qwc * 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
__fi void vif0SetupTransfer()
|
__fi void vif0SetupTransfer()
|
||||||
|
@ -91,21 +91,21 @@ __fi void vif0SetupTransfer()
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case VIF_CHAIN_MODE:
|
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
|
g_vifCycles += 1; // Add 1 g_vifCycles from the QW read for the tag
|
||||||
|
|
||||||
// Transfer dma tag if tte is set
|
// Transfer dma tag if tte is set
|
||||||
|
|
||||||
VIF_LOG("vif0 Tag %8.8x_%8.8x size=%d, id=%d, madr=%lx, tadr=%lx",
|
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;
|
vif0.inprogress = 0;
|
||||||
|
|
||||||
if (vif0ch->chcr.TTE)
|
if (vif0ch.chcr.TTE)
|
||||||
{
|
{
|
||||||
bool ret;
|
bool ret;
|
||||||
|
|
||||||
|
@ -124,9 +124,9 @@ __fi void vif0SetupTransfer()
|
||||||
vif0.irqoffset = 0;
|
vif0.irqoffset = 0;
|
||||||
vif0.done |= hwDmacSrcChainWithStack(vif0ch, ptag->ID);
|
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
|
//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");
|
VIF_LOG("dmaIrq Set");
|
||||||
|
|
||||||
|
@ -144,29 +144,29 @@ __fi void vif0Interrupt()
|
||||||
|
|
||||||
g_vifCycles = 0;
|
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.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
|
else
|
||||||
{
|
{
|
||||||
vif0Regs->stat.VPS = VPS_IDLE;
|
vif0Regs.stat.VPS = VPS_IDLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (vif0.irq && vif0.tag.size == 0)
|
if (vif0.irq && vif0.tag.size == 0)
|
||||||
{
|
{
|
||||||
vif0Regs->stat.INT = true;
|
vif0Regs.stat.INT = true;
|
||||||
hwIntcIrq(VIF0intc);
|
hwIntcIrq(VIF0intc);
|
||||||
--vif0.irq;
|
--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
|
// One game doesn't like vif stalling at end, can't remember what. Spiderman isn't keen on it tho
|
||||||
//vif0ch->chcr.STR = false;
|
//vif0ch.chcr.STR = false;
|
||||||
if(vif0ch->qwc > 0 || !vif0.done) return;
|
if(vif0ch.qwc > 0 || !vif0.done) return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -180,7 +180,7 @@ __fi void vif0Interrupt()
|
||||||
if (!vif0.done)
|
if (!vif0.done)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (!(dmacRegs->ctrl.DMAE))
|
if (!(dmacRegs.ctrl.DMAE))
|
||||||
{
|
{
|
||||||
Console.WriteLn("vif0 dma masked");
|
Console.WriteLn("vif0 dma masked");
|
||||||
return;
|
return;
|
||||||
|
@ -199,22 +199,22 @@ __fi void vif0Interrupt()
|
||||||
return; //Dont want to end if vif is stalled.
|
return; //Dont want to end if vif is stalled.
|
||||||
}
|
}
|
||||||
#ifdef PCSX2_DEVBUILD
|
#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);
|
if (vif0.cmd != 0) Console.WriteLn("vif0.cmd still set %x tag size %x", vif0.cmd, vif0.tag.size);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
vif0ch->chcr.STR = false;
|
vif0ch.chcr.STR = false;
|
||||||
g_vifCycles = 0;
|
g_vifCycles = 0;
|
||||||
hwDmacIrq(DMAC_VIF0);
|
hwDmacIrq(DMAC_VIF0);
|
||||||
vif0Regs->stat.FQC = 0;
|
vif0Regs.stat.FQC = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void dmaVIF0()
|
void dmaVIF0()
|
||||||
{
|
{
|
||||||
VIF_LOG("dmaVIF0 chcr = %lx, madr = %lx, qwc = %lx\n"
|
VIF_LOG("dmaVIF0 chcr = %lx, madr = %lx, qwc = %lx\n"
|
||||||
" tadr = %lx, asr0 = %lx, asr1 = %lx",
|
" tadr = %lx, asr0 = %lx, asr1 = %lx",
|
||||||
vif0ch->chcr._u32, vif0ch->madr, vif0ch->qwc,
|
vif0ch.chcr._u32, vif0ch.madr, vif0ch.qwc,
|
||||||
vif0ch->tadr, vif0ch->asr0, vif0ch->asr1);
|
vif0ch.tadr, vif0ch.asr0, vif0ch.asr1);
|
||||||
|
|
||||||
g_vifCycles = 0;
|
g_vifCycles = 0;
|
||||||
g_vu0Cycles = 0;
|
g_vu0Cycles = 0;
|
||||||
|
@ -224,18 +224,18 @@ void dmaVIF0()
|
||||||
vif0.inprogress = 0;
|
vif0.inprogress = 0;
|
||||||
vif0.done = false;*/
|
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.dmamode = VIF_NORMAL_TO_MEM_MODE;
|
||||||
|
|
||||||
vif0.done = false;
|
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;
|
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;
|
vif0.done = true;
|
||||||
}
|
}
|
||||||
|
@ -247,7 +247,7 @@ void dmaVIF0()
|
||||||
vif0.done = false;
|
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),
|
//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.
|
//the first bit it sends isnt required for it to work.
|
||||||
|
|
|
@ -46,10 +46,10 @@ __fi void vif1FLUSH()
|
||||||
//DevCon.Warning("VIF1 adding %x cycles", (VU1.cycle - _cycles) * BIAS);
|
//DevCon.Warning("VIF1 adding %x cycles", (VU1.cycle - _cycles) * BIAS);
|
||||||
g_vifCycles += (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;
|
vif1.vifstalled = true;
|
||||||
vif1Regs->stat.VGW = true;
|
vif1Regs.stat.VGW = true;
|
||||||
vif1.GifWaitState = 2;
|
vif1.GifWaitState = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,16 +58,16 @@ __fi void vif1FLUSH()
|
||||||
void vif1TransferToMemory()
|
void vif1TransferToMemory()
|
||||||
{
|
{
|
||||||
u32 size;
|
u32 size;
|
||||||
u64* pMem = (u64*)dmaGetAddr(vif1ch->madr, false);
|
u64* pMem = (u64*)dmaGetAddr(vif1ch.madr, false);
|
||||||
|
|
||||||
// VIF from gsMemory
|
// VIF from gsMemory
|
||||||
if (pMem == NULL) //Is vif0ptag empty?
|
if (pMem == NULL) //Is vif0ptag empty?
|
||||||
{
|
{
|
||||||
Console.WriteLn("Vif1 Tag BUSERR");
|
Console.WriteLn("Vif1 Tag BUSERR");
|
||||||
dmacRegs->stat.BEIS = true; //Bus Error
|
dmacRegs.stat.BEIS = true; //Bus Error
|
||||||
vif1Regs->stat.FQC = 0;
|
vif1Regs.stat.FQC = 0;
|
||||||
|
|
||||||
vif1ch->qwc = 0;
|
vif1ch.qwc = 0;
|
||||||
vif1.done = true;
|
vif1.done = true;
|
||||||
CPU_INT(DMAC_VIF1, 0);
|
CPU_INT(DMAC_VIF1, 0);
|
||||||
return; //An error has occurred.
|
return; //An error has occurred.
|
||||||
|
@ -76,8 +76,8 @@ void vif1TransferToMemory()
|
||||||
// MTGS concerns: The MTGS is inherently disagreeable with the idea of downloading
|
// 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
|
// stuff from the GS. The *only* way to handle this case safely is to flush the GS
|
||||||
// completely and execute the transfer there-after.
|
// completely and execute the transfer there-after.
|
||||||
//Console.Warning("Real QWC %x", vif1ch->qwc);
|
//Console.Warning("Real QWC %x", vif1ch.qwc);
|
||||||
size = min((u32)vif1ch->qwc, vif1.GSLastDownloadSize);
|
size = min((u32)vif1ch.qwc, vif1.GSLastDownloadSize);
|
||||||
|
|
||||||
if (GSreadFIFO2 == NULL)
|
if (GSreadFIFO2 == NULL)
|
||||||
{
|
{
|
||||||
|
@ -90,10 +90,10 @@ void vif1TransferToMemory()
|
||||||
pMem[1] = psHu64(VIF1_FIFO + 8);
|
pMem[1] = psHu64(VIF1_FIFO + 8);
|
||||||
pMem += 2;
|
pMem += 2;
|
||||||
}
|
}
|
||||||
if(vif1ch->qwc > vif1.GSLastDownloadSize)
|
if(vif1ch.qwc > vif1.GSLastDownloadSize)
|
||||||
{
|
{
|
||||||
DevCon.Warning("GS Transfer < VIF QWC, Clearing end of space");
|
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) = 0;
|
||||||
psHu64(VIF1_FIFO + 8) = 0;
|
psHu64(VIF1_FIFO + 8) = 0;
|
||||||
|
@ -112,10 +112,10 @@ void vif1TransferToMemory()
|
||||||
psHu64(VIF1_FIFO) = pMem[2*size-2];
|
psHu64(VIF1_FIFO) = pMem[2*size-2];
|
||||||
psHu64(VIF1_FIFO + 8) = pMem[2*size-1];
|
psHu64(VIF1_FIFO + 8) = pMem[2*size-1];
|
||||||
pMem += size * 2;
|
pMem += size * 2;
|
||||||
if(vif1ch->qwc > vif1.GSLastDownloadSize)
|
if(vif1ch.qwc > vif1.GSLastDownloadSize)
|
||||||
{
|
{
|
||||||
DevCon.Warning("GS Transfer < VIF QWC, Clearing end of space");
|
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) = 0;
|
||||||
psHu64(VIF1_FIFO + 8) = 0;
|
psHu64(VIF1_FIFO + 8) = 0;
|
||||||
|
@ -127,27 +127,27 @@ void vif1TransferToMemory()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
g_vifCycles += vif1ch->qwc * 2;
|
g_vifCycles += vif1ch.qwc * 2;
|
||||||
vif1ch->madr += vif1ch->qwc * 16; // mgs3 scene changes
|
vif1ch.madr += vif1ch.qwc * 16; // mgs3 scene changes
|
||||||
if(vif1.GSLastDownloadSize >= vif1ch->qwc)
|
if(vif1.GSLastDownloadSize >= vif1ch.qwc)
|
||||||
{
|
{
|
||||||
vif1.GSLastDownloadSize -= vif1ch->qwc;
|
vif1.GSLastDownloadSize -= vif1ch.qwc;
|
||||||
vif1Regs->stat.FQC = min((u32)16, vif1.GSLastDownloadSize);
|
vif1Regs.stat.FQC = min((u32)16, vif1.GSLastDownloadSize);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
vif1Regs->stat.FQC = 0;
|
vif1Regs.stat.FQC = 0;
|
||||||
vif1.GSLastDownloadSize = 0;
|
vif1.GSLastDownloadSize = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
vif1ch->qwc = 0;
|
vif1ch.qwc = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool _VIF1chain()
|
bool _VIF1chain()
|
||||||
{
|
{
|
||||||
u32 *pMem;
|
u32 *pMem;
|
||||||
|
|
||||||
if (vif1ch->qwc == 0)
|
if (vif1ch.qwc == 0)
|
||||||
{
|
{
|
||||||
vif1.inprogress &= ~1;
|
vif1.inprogress &= ~1;
|
||||||
vif1.irqoffset = 0;
|
vif1.irqoffset = 0;
|
||||||
|
@ -162,28 +162,27 @@ bool _VIF1chain()
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
pMem = (u32*)dmaGetAddr(vif1ch->madr, !vif1ch->chcr.DIR);
|
pMem = (u32*)dmaGetAddr(vif1ch.madr, !vif1ch.chcr.DIR);
|
||||||
if (pMem == NULL)
|
if (pMem == NULL)
|
||||||
{
|
{
|
||||||
vif1.cmd = 0;
|
vif1.cmd = 0;
|
||||||
vif1.tag.size = 0;
|
vif1.tag.size = 0;
|
||||||
vif1ch->qwc = 0;
|
vif1ch.qwc = 0;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
VIF_LOG("VIF1chain size=%d, madr=%lx, tadr=%lx",
|
VIF_LOG("VIF1chain size=%d, madr=%lx, tadr=%lx",
|
||||||
vif1ch->qwc, vif1ch->madr, vif1ch->tadr);
|
vif1ch.qwc, vif1ch.madr, vif1ch.tadr);
|
||||||
|
|
||||||
if (vif1.vifstalled)
|
if (vif1.vifstalled)
|
||||||
return VIF1transfer(pMem + vif1.irqoffset, vif1ch->qwc * 4 - vif1.irqoffset);
|
return VIF1transfer(pMem + vif1.irqoffset, vif1ch.qwc * 4 - vif1.irqoffset);
|
||||||
else
|
else
|
||||||
return VIF1transfer(pMem, vif1ch->qwc * 4);
|
return VIF1transfer(pMem, vif1ch.qwc * 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
__fi void vif1SetupTransfer()
|
__fi void vif1SetupTransfer()
|
||||||
{
|
{
|
||||||
tDMA_TAG *ptag;
|
tDMA_TAG *ptag;
|
||||||
DMACh& vif1c = (DMACh&)eeMem->HW[0x9000];
|
|
||||||
|
|
||||||
switch (vif1.dmamode)
|
switch (vif1.dmamode)
|
||||||
{
|
{
|
||||||
|
@ -195,20 +194,20 @@ __fi void vif1SetupTransfer()
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case VIF_CHAIN_MODE:
|
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
|
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",
|
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
|
// 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
|
// stalled
|
||||||
hwDmacIrq(DMAC_STALL_SIS);
|
hwDmacIrq(DMAC_STALL_SIS);
|
||||||
|
@ -219,7 +218,7 @@ __fi void vif1SetupTransfer()
|
||||||
|
|
||||||
vif1.inprogress &= ~1;
|
vif1.inprogress &= ~1;
|
||||||
|
|
||||||
if (vif1c.chcr.TTE)
|
if (vif1ch.chcr.TTE)
|
||||||
{
|
{
|
||||||
// Transfer dma tag if tte is set
|
// Transfer dma tag if tte is set
|
||||||
|
|
||||||
|
@ -243,10 +242,10 @@ __fi void vif1SetupTransfer()
|
||||||
|
|
||||||
vif1.done |= hwDmacSrcChainWithStack(vif1ch, ptag->ID);
|
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
|
//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");
|
VIF_LOG("dmaIrq Set");
|
||||||
|
|
||||||
|
@ -262,73 +261,73 @@ extern bool SIGNAL_IMR_Pending;
|
||||||
|
|
||||||
bool CheckPath2GIF(EE_EventType channel)
|
bool CheckPath2GIF(EE_EventType channel)
|
||||||
{
|
{
|
||||||
if ((vif1Regs->stat.VGW))
|
if ((vif1Regs.stat.VGW))
|
||||||
{
|
{
|
||||||
if( vif1.GifWaitState == 0 ) //DIRECT/HL Check
|
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
|
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);
|
CPU_INT(channel, 128);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
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
|
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);
|
CPU_INT(channel, 128);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (GSTransferStatus.PTH3 < IDLE_MODE)
|
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("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("PTH3 %x P1Q %x P3Q %x IP3 %x", GSTransferStatus.PTH3, gifRegs.stat.P1Q, gifRegs.stat.P3Q, gifRegs.stat.IP3 );
|
||||||
CPU_INT(channel, 8);
|
CPU_INT(channel, 8);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else
|
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
|
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);
|
CPU_INT(channel, 128);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
vif1Regs->stat.VGW = false;
|
vif1Regs.stat.VGW = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else //Normal Flush
|
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);
|
CPU_INT(channel, 128);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
vif1Regs->stat.VGW = false;
|
vif1Regs.stat.VGW = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -346,11 +345,11 @@ __fi void vif1Interrupt()
|
||||||
|
|
||||||
g_vifCycles = 0;
|
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.OPH = false;
|
||||||
gifRegs->stat.APATH = GIF_APATH_IDLE;
|
gifRegs.stat.APATH = GIF_APATH_IDLE;
|
||||||
if(gifRegs->stat.P1Q) gsPath1Interrupt();
|
if(gifRegs.stat.P1Q) gsPath1Interrupt();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (schedulepath3msk & 0x10)
|
if (schedulepath3msk & 0x10)
|
||||||
|
@ -360,48 +359,48 @@ __fi void vif1Interrupt()
|
||||||
return;
|
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.
|
//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");
|
//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.
|
// 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);
|
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);
|
vif1Regs.stat.FQC = min((u16)0x10, vif1ch.qwc);
|
||||||
vifMFIFOInterrupt();
|
vifMFIFOInterrupt();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//We need to check the direction, if it is downloading from the GS, we handle that separately (KH2 for testing)
|
//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;
|
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
|
//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.cmd)
|
||||||
{
|
{
|
||||||
if (vif1.done && (vif1ch->qwc == 0)) vif1Regs->stat.VPS = VPS_WAITING;
|
if (vif1.done && (vif1ch.qwc == 0)) vif1Regs.stat.VPS = VPS_WAITING;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
vif1Regs->stat.VPS = VPS_IDLE;
|
vif1Regs.stat.VPS = VPS_IDLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (vif1.irq && vif1.tag.size == 0)
|
if (vif1.irq && vif1.tag.size == 0)
|
||||||
{
|
{
|
||||||
vif1Regs->stat.INT = true;
|
vif1Regs.stat.INT = true;
|
||||||
hwIntcIrq(VIF1intc);
|
hwIntcIrq(VIF1intc);
|
||||||
--vif1.irq;
|
--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)
|
//NFSHPS stalls when the whole packet has gone across (it stalls in the last 32bit cmd)
|
||||||
//In this case VIF will end
|
//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();
|
_VIF1chain();
|
||||||
// VIF_NORMAL_FROM_MEM_MODE is a very slow operation.
|
// VIF_NORMAL_FROM_MEM_MODE is a very slow operation.
|
||||||
// Timesplitters 2 depends on this beeing a bit higher than 128.
|
// 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.
|
// 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);
|
/*if (vif1.dmamode == VIF_NORMAL_FROM_MEM_MODE ) CPU_INT(DMAC_VIF1, 1024);
|
||||||
else */CPU_INT(DMAC_VIF1, g_vifCycles /*VifCycleVoodoo*/);
|
else */CPU_INT(DMAC_VIF1, g_vifCycles /*VifCycleVoodoo*/);
|
||||||
|
@ -420,14 +419,14 @@ __fi void vif1Interrupt()
|
||||||
if (!vif1.done)
|
if (!vif1.done)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (!(dmacRegs->ctrl.DMAE))
|
if (!(dmacRegs.ctrl.DMAE))
|
||||||
{
|
{
|
||||||
Console.WriteLn("vif1 dma masked");
|
Console.WriteLn("vif1 dma masked");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((vif1.inprogress & 0x1) == 0) vif1SetupTransfer();
|
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);
|
CPU_INT(DMAC_VIF1, g_vifCycles);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -439,17 +438,17 @@ __fi void vif1Interrupt()
|
||||||
return; //Dont want to end if vif is stalled.
|
return; //Dont want to end if vif is stalled.
|
||||||
}
|
}
|
||||||
#ifdef PCSX2_DEVBUILD
|
#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);
|
if (vif1.cmd != 0) Console.WriteLn("vif1.cmd still set %x tag size %x", vif1.cmd, vif1.tag.size);
|
||||||
#endif
|
#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
|
//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;
|
vif1.vifstalled = false;
|
||||||
g_vifCycles = 0;
|
g_vifCycles = 0;
|
||||||
g_vu1Cycles = 0;
|
g_vu1Cycles = 0;
|
||||||
|
@ -462,8 +461,8 @@ void dmaVIF1()
|
||||||
{
|
{
|
||||||
VIF_LOG("dmaVIF1 chcr = %lx, madr = %lx, qwc = %lx\n"
|
VIF_LOG("dmaVIF1 chcr = %lx, madr = %lx, qwc = %lx\n"
|
||||||
" tadr = %lx, asr0 = %lx, asr1 = %lx",
|
" tadr = %lx, asr0 = %lx, asr1 = %lx",
|
||||||
vif1ch->chcr._u32, vif1ch->madr, vif1ch->qwc,
|
vif1ch.chcr._u32, vif1ch.madr, vif1ch.qwc,
|
||||||
vif1ch->tadr, vif1ch->asr0, vif1ch->asr1);
|
vif1ch.tadr, vif1ch.asr0, vif1ch.asr1);
|
||||||
|
|
||||||
// vif1.done = false;
|
// vif1.done = false;
|
||||||
|
|
||||||
|
@ -475,19 +474,19 @@ void dmaVIF1()
|
||||||
g_vu1Cycles = 0;
|
g_vu1Cycles = 0;
|
||||||
|
|
||||||
#ifdef PCSX2_DEVBUILD
|
#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);
|
//DevCon.WriteLn("VIF Stall Control Source = %x, Drain = %x", (psHu32(0xe000) >> 4) & 0x3, (psHu32(0xe000) >> 6) & 0x3);
|
||||||
}
|
}
|
||||||
#endif
|
#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");
|
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;
|
vif1.dmamode = VIF_NORMAL_FROM_MEM_MODE;
|
||||||
else
|
else
|
||||||
vif1.dmamode = VIF_NORMAL_TO_MEM_MODE;
|
vif1.dmamode = VIF_NORMAL_TO_MEM_MODE;
|
||||||
|
@ -495,12 +494,12 @@ void dmaVIF1()
|
||||||
vif1.done = false;
|
vif1.done = false;
|
||||||
|
|
||||||
// ignore tag if it's a GS download (Def Jam Fight for NY)
|
// 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;
|
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;
|
vif1.done = true;
|
||||||
}
|
}
|
||||||
|
@ -512,7 +511,7 @@ void dmaVIF1()
|
||||||
vif1.done = false;
|
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
|
// Chain Mode
|
||||||
CPU_INT(DMAC_VIF1, 4);
|
CPU_INT(DMAC_VIF1, 4);
|
||||||
|
|
|
@ -33,26 +33,26 @@ extern u32 g_vifCycles;
|
||||||
|
|
||||||
static u32 qwctag(u32 mask)
|
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()
|
static __fi bool mfifoVIF1rbTransfer()
|
||||||
{
|
{
|
||||||
u32 maddr = dmacRegs->rbor.ADDR;
|
u32 maddr = dmacRegs.rbor.ADDR;
|
||||||
u32 msize = dmacRegs->rbor.ADDR + dmacRegs->rbsr.RMSK + 16;
|
u32 msize = dmacRegs.rbor.ADDR + dmacRegs.rbsr.RMSK + 16;
|
||||||
u16 mfifoqwc = std::min(vif1ch->qwc, vifqwc);
|
u16 mfifoqwc = std::min(vif1ch.qwc, vifqwc);
|
||||||
u32 *src;
|
u32 *src;
|
||||||
bool ret;
|
bool ret;
|
||||||
|
|
||||||
/* Check if the transfer should wrap around the ring buffer */
|
/* 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");
|
SPR_LOG("Split MFIFO");
|
||||||
|
|
||||||
/* it does, so first copy 's1' bytes from 'addr' to 'data' */
|
/* 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 (src == NULL) return false;
|
||||||
|
|
||||||
if (vif1.vifstalled)
|
if (vif1.vifstalled)
|
||||||
|
@ -60,18 +60,18 @@ static __fi bool mfifoVIF1rbTransfer()
|
||||||
else
|
else
|
||||||
ret = VIF1transfer(src, s1);
|
ret = VIF1transfer(src, s1);
|
||||||
|
|
||||||
vif1ch->madr = qwctag(vif1ch->madr);
|
vif1ch.madr = qwctag(vif1ch.madr);
|
||||||
|
|
||||||
if (ret)
|
if (ret)
|
||||||
{
|
{
|
||||||
/* and second copy 's2' bytes from 'maddr' to '&data[s1]' */
|
/* and second copy 's2' bytes from 'maddr' to '&data[s1]' */
|
||||||
vif1ch->madr = maddr;
|
vif1ch.madr = maddr;
|
||||||
|
|
||||||
src = (u32*)PSM(maddr);
|
src = (u32*)PSM(maddr);
|
||||||
if (src == NULL) return false;
|
if (src == NULL) return false;
|
||||||
VIF1transfer(src, ((mfifoqwc << 2) - s1));
|
VIF1transfer(src, ((mfifoqwc << 2) - s1));
|
||||||
}
|
}
|
||||||
vif1ch->madr = qwctag(vif1ch->madr);
|
vif1ch.madr = qwctag(vif1ch.madr);
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -79,7 +79,7 @@ static __fi bool mfifoVIF1rbTransfer()
|
||||||
SPR_LOG("Direct MFIFO");
|
SPR_LOG("Direct MFIFO");
|
||||||
|
|
||||||
/* it doesn't, so just transfer 'qwc*4' words */
|
/* 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 (src == NULL) return false;
|
||||||
|
|
||||||
if (vif1.vifstalled)
|
if (vif1.vifstalled)
|
||||||
|
@ -87,7 +87,7 @@ static __fi bool mfifoVIF1rbTransfer()
|
||||||
else
|
else
|
||||||
ret = VIF1transfer(src, mfifoqwc << 2);
|
ret = VIF1transfer(src, mfifoqwc << 2);
|
||||||
|
|
||||||
vif1ch->madr = qwctag(vif1ch->madr);
|
vif1ch.madr = qwctag(vif1ch.madr);
|
||||||
|
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -96,25 +96,25 @@ static __fi bool mfifoVIF1rbTransfer()
|
||||||
static __fi void mfifo_VIF1chain()
|
static __fi void mfifo_VIF1chain()
|
||||||
{
|
{
|
||||||
/* Is QWC = 0? if so there is nothing to transfer */
|
/* Is QWC = 0? if so there is nothing to transfer */
|
||||||
if ((vif1ch->qwc == 0))
|
if ((vif1ch.qwc == 0))
|
||||||
{
|
{
|
||||||
vif1.inprogress &= ~1;
|
vif1.inprogress &= ~1;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (vif1ch->madr >= dmacRegs->rbor.ADDR &&
|
if (vif1ch.madr >= dmacRegs.rbor.ADDR &&
|
||||||
vif1ch->madr <= (dmacRegs->rbor.ADDR + dmacRegs->rbsr.RMSK))
|
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 :(
|
//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();
|
mfifoVIF1rbTransfer();
|
||||||
vifqwc -= startqwc - vif1ch->qwc;
|
vifqwc -= startqwc - vif1ch.qwc;
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
tDMA_TAG *pMem = dmaGetAddr(vif1ch->madr, !vif1ch->chcr.DIR);
|
tDMA_TAG *pMem = dmaGetAddr(vif1ch.madr, !vif1ch.chcr.DIR);
|
||||||
SPR_LOG("Non-MFIFO Location");
|
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
|
//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 (pMem == NULL) return;
|
||||||
|
|
||||||
if (vif1.vifstalled)
|
if (vif1.vifstalled)
|
||||||
VIF1transfer((u32*)pMem + vif1.irqoffset, vif1ch->qwc * 4 - vif1.irqoffset);
|
VIF1transfer((u32*)pMem + vif1.irqoffset, vif1ch.qwc * 4 - vif1.irqoffset);
|
||||||
else
|
else
|
||||||
VIF1transfer((u32*)pMem, vif1ch->qwc << 2);
|
VIF1transfer((u32*)pMem, vif1ch.qwc << 2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -139,23 +139,23 @@ void mfifoVIF1transfer(int qwc)
|
||||||
if (qwc > 0)
|
if (qwc > 0)
|
||||||
{
|
{
|
||||||
vifqwc += qwc;
|
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 (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;
|
vif1.inprogress &= ~0x10;
|
||||||
|
|
||||||
return;
|
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;
|
bool ret;
|
||||||
|
|
||||||
|
@ -173,62 +173,62 @@ void mfifoVIF1transfer(int qwc)
|
||||||
|
|
||||||
vif1.irqoffset = 0;
|
vif1.irqoffset = 0;
|
||||||
|
|
||||||
vif1ch->unsafeTransfer(ptag);
|
vif1ch.unsafeTransfer(ptag);
|
||||||
|
|
||||||
vif1ch->madr = ptag[1]._u32;
|
vif1ch.madr = ptag[1]._u32;
|
||||||
vifqwc--;
|
vifqwc--;
|
||||||
|
|
||||||
SPR_LOG("dmaChain %8.8x_%8.8x size=%d, id=%d, madr=%lx, tadr=%lx mfifo qwc = %x spr0 madr = %x",
|
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)
|
switch (ptag->ID)
|
||||||
{
|
{
|
||||||
case TAG_REFE: // Refe - Transfer Packet According to ADDR field
|
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
|
vif1.done = true; //End Transfer
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TAG_CNT: // CNT - Transfer QWC following the tag.
|
case TAG_CNT: // CNT - Transfer QWC following the tag.
|
||||||
vif1ch->madr = qwctag(vif1ch->tadr + 16); //Set MADR to QW after 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.tadr = qwctag(vif1ch.madr + (vif1ch.qwc << 4)); //Set TADR to QW following the data
|
||||||
vif1.done = false;
|
vif1.done = false;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TAG_NEXT: // Next - Transfer QWC following tag. TADR = ADDR
|
case TAG_NEXT: // Next - Transfer QWC following tag. TADR = ADDR
|
||||||
{
|
{
|
||||||
int temp = vif1ch->madr; //Temporarily Store ADDR
|
int temp = vif1ch.madr; //Temporarily Store ADDR
|
||||||
vif1ch->madr = qwctag(vif1ch->tadr + 16); //Set MADR to QW following the tag
|
vif1ch.madr = qwctag(vif1ch.tadr + 16); //Set MADR to QW following the tag
|
||||||
vif1ch->tadr = temp; //Copy temporarily stored ADDR to 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));
|
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;
|
vif1.done = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case TAG_REF: // Ref - Transfer QWC from ADDR field
|
case TAG_REF: // Ref - Transfer QWC from ADDR field
|
||||||
case TAG_REFS: // Refs - Transfer QWC from ADDR field (Stall Control)
|
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;
|
vif1.done = false;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TAG_END: // End - Transfer QWC following the tag
|
case TAG_END: // End - Transfer QWC following the tag
|
||||||
vif1ch->madr = qwctag(vif1ch->tadr + 16); //Set MADR to data 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.tadr = qwctag(vif1ch.madr + (vif1ch.qwc << 4)); //Set TADR to QW following the data
|
||||||
vif1.done = true; //End Transfer
|
vif1.done = true; //End Transfer
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (vif1ch->chcr.TIE && ptag->IRQ)
|
if (vif1ch.chcr.TIE && ptag->IRQ)
|
||||||
{
|
{
|
||||||
VIF_LOG("dmaIrq Set");
|
VIF_LOG("dmaIrq Set");
|
||||||
vif1.done = true;
|
vif1.done = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
vif1Regs->stat.FQC = min(vif1ch->qwc, (u16)16);
|
vif1Regs.stat.FQC = min(vif1ch.qwc, (u16)16);
|
||||||
vif1.inprogress |= 1;
|
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()
|
void vifMFIFOInterrupt()
|
||||||
|
@ -236,52 +236,52 @@ void vifMFIFOInterrupt()
|
||||||
g_vifCycles = 0;
|
g_vifCycles = 0;
|
||||||
VIF_LOG("vif mfifo interrupt");
|
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;
|
GSTransferStatus.PTH2 = STOPPED_MODE;
|
||||||
if(gifRegs->stat.DIR == 0)gifRegs->stat.OPH = false;
|
if(gifRegs.stat.DIR == 0)gifRegs.stat.OPH = false;
|
||||||
gifRegs->stat.APATH = GIF_APATH_IDLE;
|
gifRegs.stat.APATH = GIF_APATH_IDLE;
|
||||||
if(gifRegs->stat.P1Q) gsPath1Interrupt();
|
if(gifRegs.stat.P1Q) gsPath1Interrupt();
|
||||||
/*gifRegs->stat.APATH = GIF_APATH_IDLE;
|
/*gifRegs.stat.APATH = GIF_APATH_IDLE;
|
||||||
if(gifRegs->stat.DIR == 0)gifRegs->stat.OPH = false;*/
|
if(gifRegs.stat.DIR == 0)gifRegs.stat.OPH = false;*/
|
||||||
}
|
}
|
||||||
|
|
||||||
if (schedulepath3msk & 0x10) Vif1MskPath3();
|
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)
|
//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
|
//Simulated GS transfer time done, clear the flags
|
||||||
|
|
||||||
if (vif1.cmd)
|
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
|
else
|
||||||
{
|
{
|
||||||
vif1Regs->stat.VPS = VPS_IDLE;
|
vif1Regs.stat.VPS = VPS_IDLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (vif1.irq && vif1.tag.size == 0)
|
if (vif1.irq && vif1.tag.size == 0)
|
||||||
{
|
{
|
||||||
vif1Regs->stat.INT = true;
|
vif1Regs.stat.INT = true;
|
||||||
hwIntcIrq(INTC_VIF1);
|
hwIntcIrq(INTC_VIF1);
|
||||||
--vif1.irq;
|
--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
|
/*vif1Regs.stat.FQC = 0; // FQC=0
|
||||||
vif1ch->chcr.STR = false;*/
|
vif1ch.chcr.STR = false;*/
|
||||||
if(vif1ch->qwc > 0 || !vif1.done) return;
|
if(vif1ch.qwc > 0 || !vif1.done) return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (vif1.done == false || vif1ch->qwc)
|
if (vif1.done == false || vif1ch.qwc)
|
||||||
{
|
{
|
||||||
switch(vif1.inprogress & 1)
|
switch(vif1.inprogress & 1)
|
||||||
{
|
{
|
||||||
case 0: //Set up transfer
|
case 0: //Set up transfer
|
||||||
if (vif1ch->tadr == spr0->madr)
|
if (vif1ch.tadr == spr0ch.madr)
|
||||||
{
|
{
|
||||||
// Console.WriteLn("Empty 1");
|
// Console.WriteLn("Empty 1");
|
||||||
vifqwc = 0;
|
vifqwc = 0;
|
||||||
|
@ -290,7 +290,7 @@ void vifMFIFOInterrupt()
|
||||||
hwDmacIrq(DMAC_MFIFO_EMPTY);
|
hwDmacIrq(DMAC_MFIFO_EMPTY);
|
||||||
vif1.inprogress |= 0x10;
|
vif1.inprogress |= 0x10;
|
||||||
}
|
}
|
||||||
vif1Regs->stat.FQC = 0;
|
vif1Regs.stat.FQC = 0;
|
||||||
return;
|
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.
|
//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?)
|
//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;
|
vifqwc = 0;
|
||||||
if((vif1.inprogress & 0x10) == 0)
|
if((vif1.inprogress & 0x10) == 0)
|
||||||
|
@ -322,9 +322,9 @@ void vifMFIFOInterrupt()
|
||||||
vif1.vifstalled = false;
|
vif1.vifstalled = false;
|
||||||
vif1.done = 1;
|
vif1.done = 1;
|
||||||
g_vifCycles = 0;
|
g_vifCycles = 0;
|
||||||
vif1ch->chcr.STR = false;
|
vif1ch.chcr.STR = false;
|
||||||
hwDmacIrq(DMAC_VIF1);
|
hwDmacIrq(DMAC_VIF1);
|
||||||
VIF_LOG("vif mfifo dma end");
|
VIF_LOG("vif mfifo dma end");
|
||||||
|
|
||||||
vif1Regs->stat.FQC = 0;
|
vif1Regs.stat.FQC = 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,32 +39,33 @@ static __fi void vifFlush(int idx) {
|
||||||
|
|
||||||
static __fi void vuExecMicro(int idx, u32 addr) {
|
static __fi void vuExecMicro(int idx, u32 addr) {
|
||||||
VURegs* VU = nVif[idx].VU;
|
VURegs* VU = nVif[idx].VU;
|
||||||
|
VIFregisters& vifRegs = VU->GetVifRegs();
|
||||||
int startcycles = 0;
|
int startcycles = 0;
|
||||||
//vifFlush(idx);
|
//vifFlush(idx);
|
||||||
|
|
||||||
//if(vifX.vifstalled == true) return;
|
//if(vifX.vifstalled == true) return;
|
||||||
|
|
||||||
if (VU->vifRegs->itops > (idx ? 0x3ffu : 0xffu)) {
|
if (vifRegs.itops > (idx ? 0x3ffu : 0xffu)) {
|
||||||
Console.WriteLn("VIF%d ITOP overrun! %x", idx, VU->vifRegs->itops);
|
Console.WriteLn("VIF%d ITOP overrun! %x", idx, vifRegs.itops);
|
||||||
VU->vifRegs->itops &= (idx ? 0x3ffu : 0xffu);
|
vifRegs.itops &= (idx ? 0x3ffu : 0xffu);
|
||||||
}
|
}
|
||||||
|
|
||||||
VU->vifRegs->itop = VU->vifRegs->itops;
|
vifRegs.itop = vifRegs.itops;
|
||||||
|
|
||||||
if (idx) {
|
if (idx) {
|
||||||
// in case we're handling a VIF1 execMicro, set the top with the tops value
|
// 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?
|
// 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
|
// it is, so set tops with base, and clear the stat DBF flag
|
||||||
VU->vifRegs->tops = VU->vifRegs->base;
|
vifRegs.tops = vifRegs.base;
|
||||||
VU->vifRegs->stat.DBF = false;
|
vifRegs.stat.DBF = false;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// it is not, so set tops with base + offset, and set stat DBF flag
|
// it is not, so set tops with base + offset, and set stat DBF flag
|
||||||
VU->vifRegs->tops = VU->vifRegs->base + VU->vifRegs->ofst;
|
vifRegs.tops = vifRegs.base + vifRegs.ofst;
|
||||||
VU->vifRegs->stat.DBF = true;
|
vifRegs.stat.DBF = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -84,16 +85,16 @@ u8 schedulepath3msk = 0;
|
||||||
|
|
||||||
void Vif1MskPath3() {
|
void Vif1MskPath3() {
|
||||||
|
|
||||||
vif1Regs->mskpath3 = schedulepath3msk & 0x1;
|
vif1Regs.mskpath3 = schedulepath3msk & 0x1;
|
||||||
GIF_LOG("VIF MSKPATH3 %x gif str %x path3 status %x", vif1Regs->mskpath3, gif->chcr.STR, GSTransferStatus.PTH3);
|
GIF_LOG("VIF MSKPATH3 %x gif str %x path3 status %x", vif1Regs.mskpath3, gifch.chcr.STR, GSTransferStatus.PTH3);
|
||||||
gifRegs->stat.M3P = vif1Regs->mskpath3;
|
gifRegs.stat.M3P = vif1Regs.mskpath3;
|
||||||
|
|
||||||
if (!vif1Regs->mskpath3)
|
if (!vif1Regs.mskpath3)
|
||||||
{
|
{
|
||||||
//if(GSTransferStatus.PTH3 > TRANSFER_MODE && gif->chcr.STR) GSTransferStatus.PTH3 = TRANSFER_MODE;
|
//if(GSTransferStatus.PTH3 > TRANSFER_MODE && gif->chcr.STR) GSTransferStatus.PTH3 = TRANSFER_MODE;
|
||||||
//DevCon.Warning("Mask off");
|
//DevCon.Warning("Mask off");
|
||||||
//if(GSTransferStatus.PTH3 >= PENDINGSTOP_MODE) GSTransferStatus.PTH3 = IDLE_MODE;
|
//if(GSTransferStatus.PTH3 >= PENDINGSTOP_MODE) GSTransferStatus.PTH3 = IDLE_MODE;
|
||||||
if(gifRegs->stat.P3Q)
|
if(gifRegs.stat.P3Q)
|
||||||
{
|
{
|
||||||
gsInterrupt();//gsInterrupt();
|
gsInterrupt();//gsInterrupt();
|
||||||
}
|
}
|
||||||
|
@ -109,7 +110,7 @@ void Vif1MskPath3() {
|
||||||
|
|
||||||
vifOp(vifCode_Base) {
|
vifOp(vifCode_Base) {
|
||||||
vif1Only();
|
vif1Only();
|
||||||
pass1 { vif1Regs->base = vif1Regs->code & 0x3ff; vif1.cmd = 0; }
|
pass1 { vif1Regs.base = vif1Regs.code & 0x3ff; vif1.cmd = 0; }
|
||||||
pass3 { VifCodeLog("Base"); }
|
pass3 { VifCodeLog("Base"); }
|
||||||
return 0;
|
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) {
|
template<int idx> __fi int _vifCode_Direct(int pass, const u8* data, bool isDirectHL) {
|
||||||
pass1 {
|
pass1 {
|
||||||
vif1Only();
|
vif1Only();
|
||||||
int vifImm = (u16)vif1Regs->code;
|
int vifImm = (u16)vif1Regs.code;
|
||||||
vif1.tag.size = vifImm ? (vifImm*4) : (65536*4);
|
vif1.tag.size = vifImm ? (vifImm*4) : (65536*4);
|
||||||
vif1.vifstalled = true;
|
vif1.vifstalled = true;
|
||||||
gifRegs->stat.P2Q = true;
|
gifRegs.stat.P2Q = true;
|
||||||
if (gifRegs->stat.PSE) // temporarily stop
|
if (gifRegs.stat.PSE) // temporarily stop
|
||||||
{
|
{
|
||||||
Console.WriteLn("Gif dma temp paused? VIF DIRECT");
|
Console.WriteLn("Gif dma temp paused? VIF DIRECT");
|
||||||
vif1.GifWaitState = 3;
|
vif1.GifWaitState = 3;
|
||||||
vif1Regs->stat.VGW = true;
|
vif1Regs.stat.VGW = true;
|
||||||
}
|
}
|
||||||
//Should cause this to split here to try and time PATH3 right.
|
//Should cause this to split here to try and time PATH3 right.
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -135,18 +136,18 @@ template<int idx> __fi int _vifCode_Direct(int pass, const u8* data, bool isDire
|
||||||
pass2 {
|
pass2 {
|
||||||
vif1Only();
|
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
|
//Do nothing, allow it
|
||||||
vif1Regs->stat.VGW = false;
|
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);
|
//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
|
else
|
||||||
{
|
{
|
||||||
//DevCon.Warning("Stall DIRECT/HL %x P3 %x APATH %x P1Q %x", vif1.cmd, GSTransferStatus.PTH3, gifRegs->stat.APATH, gifRegs->stat.P1Q);
|
//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)
|
vif1Regs.stat.VGW = true; // PATH3 is in image mode (DIRECTHL), or busy (BOTH no IMT)
|
||||||
vif1.GifWaitState = 0;
|
vif1.GifWaitState = 0;
|
||||||
vif1.vifstalled = true;
|
vif1.vifstalled = true;
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -158,19 +159,19 @@ template<int idx> __fi int _vifCode_Direct(int pass, const u8* data, bool isDire
|
||||||
vif1.vifstalled = true;
|
vif1.vifstalled = true;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (gifRegs->stat.PSE) // temporarily stop
|
if (gifRegs.stat.PSE) // temporarily stop
|
||||||
{
|
{
|
||||||
Console.WriteLn("Gif dma temp paused? VIF DIRECT");
|
Console.WriteLn("Gif dma temp paused? VIF DIRECT");
|
||||||
vif1.GifWaitState = 3;
|
vif1.GifWaitState = 3;
|
||||||
vif1.vifstalled = true;
|
vif1.vifstalled = true;
|
||||||
vif1Regs->stat.VGW = true;
|
vif1Regs.stat.VGW = true;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// HACK ATTACK!
|
// HACK ATTACK!
|
||||||
// we shouldn't be clearing the queue flag here at all. Ideally, the queue statuses
|
// 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
|
// 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 minSize = aMin(vif1.vifpacketsize, vif1.tag.size);
|
||||||
uint ret;
|
uint ret;
|
||||||
|
@ -259,12 +260,12 @@ vifOp(vifCode_FlushA) {
|
||||||
pass1 {
|
pass1 {
|
||||||
vifFlush(idx);
|
vifFlush(idx);
|
||||||
// Gif is already transferring so wait for it.
|
// Gif is already transferring so wait for it.
|
||||||
if (gifRegs->stat.P1Q || GSTransferStatus.PTH3 <= PENDINGSTOP_MODE) {
|
if (gifRegs.stat.P1Q || GSTransferStatus.PTH3 <= PENDINGSTOP_MODE) {
|
||||||
//DevCon.Warning("VIF FlushA Wait MSK = %x", vif1Regs->mskpath3);
|
//DevCon.Warning("VIF FlushA Wait MSK = %x", vif1Regs.mskpath3);
|
||||||
//
|
//
|
||||||
|
|
||||||
//DevCon.WriteLn("FlushA path3 Wait! PTH3 MD %x STR %x", GSTransferStatus.PTH3, gif->chcr.STR);
|
//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.GifWaitState = 1;
|
||||||
vifX.vifstalled = true;
|
vifX.vifstalled = true;
|
||||||
} // else DevCon.WriteLn("FlushA path3 no Wait! PTH3 MD %x STR %x", GSTransferStatus.PTH3, gif->chcr.STR);
|
} // 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) {
|
vifOp(vifCode_ITop) {
|
||||||
pass1 { vifXRegs->itops = vifXRegs->code & 0x3ff; GetVifX.cmd = 0; }
|
pass1 { vifXRegs.itops = vifXRegs.code & 0x3ff; GetVifX.cmd = 0; }
|
||||||
pass3 { VifCodeLog("ITop"); }
|
pass3 { VifCodeLog("ITop"); }
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -292,8 +293,8 @@ vifOp(vifCode_ITop) {
|
||||||
vifOp(vifCode_Mark) {
|
vifOp(vifCode_Mark) {
|
||||||
vifStruct& vifX = GetVifX;
|
vifStruct& vifX = GetVifX;
|
||||||
pass1 {
|
pass1 {
|
||||||
vifXRegs->mark = (u16)vifXRegs->code;
|
vifXRegs.mark = (u16)vifXRegs.code;
|
||||||
vifXRegs->stat.MRK = true;
|
vifXRegs.stat.MRK = true;
|
||||||
vifX.cmd = 0;
|
vifX.cmd = 0;
|
||||||
}
|
}
|
||||||
pass3 { VifCodeLog("Mark"); }
|
pass3 { VifCodeLog("Mark"); }
|
||||||
|
@ -316,8 +317,8 @@ static __fi void _vifCode_MPG(int idx, u32 addr, const u32 *data, int size) {
|
||||||
vifOp(vifCode_MPG) {
|
vifOp(vifCode_MPG) {
|
||||||
vifStruct& vifX = GetVifX;
|
vifStruct& vifX = GetVifX;
|
||||||
pass1 {
|
pass1 {
|
||||||
int vifNum = (u8)(vifXRegs->code >> 16);
|
int vifNum = (u8)(vifXRegs.code >> 16);
|
||||||
vifX.tag.addr = (u16)(vifXRegs->code << 3) & (idx ? 0x3fff : 0xfff);
|
vifX.tag.addr = (u16)(vifXRegs.code << 3) & (idx ? 0x3fff : 0xfff);
|
||||||
vifX.tag.size = vifNum ? (vifNum*2) : 512;
|
vifX.tag.size = vifNum ? (vifNum*2) : 512;
|
||||||
//vifFlush(idx);
|
//vifFlush(idx);
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -349,14 +350,14 @@ vifOp(vifCode_MPG) {
|
||||||
|
|
||||||
vifOp(vifCode_MSCAL) {
|
vifOp(vifCode_MSCAL) {
|
||||||
vifStruct& vifX = GetVifX;
|
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"); }
|
pass3 { VifCodeLog("MSCAL"); }
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
vifOp(vifCode_MSCALF) {
|
vifOp(vifCode_MSCALF) {
|
||||||
vifStruct& vifX = GetVifX;
|
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"); }
|
pass3 { VifCodeLog("MSCALF"); }
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -372,12 +373,12 @@ vifOp(vifCode_MSCNT) {
|
||||||
vifOp(vifCode_MskPath3) {
|
vifOp(vifCode_MskPath3) {
|
||||||
vif1Only();
|
vif1Only();
|
||||||
pass1 {
|
pass1 {
|
||||||
if (vif1ch->chcr.STR && vif1.lastcmd != 0x13) {
|
if (vif1ch.chcr.STR && vif1.lastcmd != 0x13) {
|
||||||
schedulepath3msk = 0x10 | ((vif1Regs->code >> 15) & 0x1);
|
schedulepath3msk = 0x10 | ((vif1Regs.code >> 15) & 0x1);
|
||||||
vif1.vifstalled = true;
|
vif1.vifstalled = true;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
schedulepath3msk = (vif1Regs->code >> 15) & 0x1;
|
schedulepath3msk = (vif1Regs.code >> 15) & 0x1;
|
||||||
Vif1MskPath3();
|
Vif1MskPath3();
|
||||||
}
|
}
|
||||||
vif1.cmd = 0;
|
vif1.cmd = 0;
|
||||||
|
@ -397,9 +398,9 @@ vifOp(vifCode_Null) {
|
||||||
vifStruct& vifX = GetVifX;
|
vifStruct& vifX = GetVifX;
|
||||||
pass1 {
|
pass1 {
|
||||||
// if ME1, then force the vif to interrupt
|
// 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);
|
Console.WriteLn("Vif%d: Unknown VifCmd! [%x]", idx, vifX.cmd);
|
||||||
vifXRegs->stat.ER1 = true;
|
vifXRegs.stat.ER1 = true;
|
||||||
vifX.vifstalled = true;
|
vifX.vifstalled = true;
|
||||||
//vifX.irq++;
|
//vifX.irq++;
|
||||||
}
|
}
|
||||||
|
@ -413,9 +414,9 @@ vifOp(vifCode_Null) {
|
||||||
vifOp(vifCode_Offset) {
|
vifOp(vifCode_Offset) {
|
||||||
vif1Only();
|
vif1Only();
|
||||||
pass1 {
|
pass1 {
|
||||||
vif1Regs->stat.DBF = false;
|
vif1Regs.stat.DBF = false;
|
||||||
vif1Regs->ofst = vif1Regs->code & 0x3ff;
|
vif1Regs.ofst = vif1Regs.code & 0x3ff;
|
||||||
vif1Regs->tops = vif1Regs->base;
|
vif1Regs.tops = vif1Regs.base;
|
||||||
vif1.cmd = 0;
|
vif1.cmd = 0;
|
||||||
}
|
}
|
||||||
pass3 { VifCodeLog("Offset"); }
|
pass3 { VifCodeLog("Offset"); }
|
||||||
|
@ -462,7 +463,7 @@ vifOp(vifCode_STCol) {
|
||||||
}
|
}
|
||||||
pass2 {
|
pass2 {
|
||||||
u32* cols = idx ? g_vifmask.Col1 : g_vifmask.Col0;
|
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;
|
u32* pmem2 = cols + vifX.tag.addr;
|
||||||
return _vifCode_STColRow<idx>(data, pmem1, pmem2);
|
return _vifCode_STColRow<idx>(data, pmem1, pmem2);
|
||||||
}
|
}
|
||||||
|
@ -480,7 +481,7 @@ vifOp(vifCode_STRow) {
|
||||||
}
|
}
|
||||||
pass2 {
|
pass2 {
|
||||||
u32* rows = idx ? g_vifmask.Row1 : g_vifmask.Row0;
|
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;
|
u32* pmem2 = rows + vifX.tag.addr;
|
||||||
return _vifCode_STColRow<idx>(data, pmem1, pmem2);
|
return _vifCode_STColRow<idx>(data, pmem1, pmem2);
|
||||||
}
|
}
|
||||||
|
@ -491,8 +492,8 @@ vifOp(vifCode_STRow) {
|
||||||
vifOp(vifCode_STCycl) {
|
vifOp(vifCode_STCycl) {
|
||||||
vifStruct& vifX = GetVifX;
|
vifStruct& vifX = GetVifX;
|
||||||
pass1 {
|
pass1 {
|
||||||
vifXRegs->cycle.cl = (u8)(vifXRegs->code);
|
vifXRegs.cycle.cl = (u8)(vifXRegs.code);
|
||||||
vifXRegs->cycle.wl = (u8)(vifXRegs->code >> 8);
|
vifXRegs.cycle.wl = (u8)(vifXRegs.code >> 8);
|
||||||
vifX.cmd = 0;
|
vifX.cmd = 0;
|
||||||
}
|
}
|
||||||
pass3 { VifCodeLog("STCycl"); }
|
pass3 { VifCodeLog("STCycl"); }
|
||||||
|
@ -502,13 +503,13 @@ vifOp(vifCode_STCycl) {
|
||||||
vifOp(vifCode_STMask) {
|
vifOp(vifCode_STMask) {
|
||||||
vifStruct& vifX = GetVifX;
|
vifStruct& vifX = GetVifX;
|
||||||
pass1 { vifX.tag.size = 1; }
|
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"); }
|
pass3 { VifCodeLog("STMask"); }
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
vifOp(vifCode_STMod) {
|
vifOp(vifCode_STMod) {
|
||||||
pass1 { vifXRegs->mode = vifXRegs->code & 0x3; GetVifX.cmd = 0; }
|
pass1 { vifXRegs.mode = vifXRegs.code & 0x3; GetVifX.cmd = 0; }
|
||||||
pass3 { VifCodeLog("STMod"); }
|
pass3 { VifCodeLog("STMod"); }
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,8 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "Vif.h"
|
||||||
#include "Vif_Unpack.h"
|
#include "Vif_Unpack.h"
|
||||||
|
|
||||||
struct vifCode {
|
struct vifCode {
|
||||||
|
@ -84,13 +86,13 @@ extern vifStruct* vif;
|
||||||
extern vifStruct vif0, vif1;
|
extern vifStruct vif0, vif1;
|
||||||
extern u8 schedulepath3msk;
|
extern u8 schedulepath3msk;
|
||||||
|
|
||||||
|
_vifT extern bool vifWrite32(u32 mem, u32 value);
|
||||||
|
|
||||||
extern void vif0Interrupt();
|
extern void vif0Interrupt();
|
||||||
extern void vif0Write32(u32 mem, u32 value);
|
|
||||||
extern void vif0Reset();
|
extern void vif0Reset();
|
||||||
|
|
||||||
extern void vif1Interrupt();
|
extern void vif1Interrupt();
|
||||||
extern void Vif1MskPath3();
|
extern void Vif1MskPath3();
|
||||||
extern void vif1Write32(u32 mem, u32 value);
|
|
||||||
extern void vif1Reset();
|
extern void vif1Reset();
|
||||||
|
|
||||||
typedef int __fastcall FnType_VifCmdHandler(int pass, const u32 *data);
|
typedef int __fastcall FnType_VifCmdHandler(int pass, const u32 *data);
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
|
|
||||||
// Doesn't stall if the next vifCode is the Mark command
|
// Doesn't stall if the next vifCode is the Mark command
|
||||||
_vifT bool runMark(u32* &data) {
|
_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);
|
Console.WriteLn("Vif%d: Running Mark with I-bit", idx);
|
||||||
return 1; // No Stall?
|
return 1; // No Stall?
|
||||||
}
|
}
|
||||||
|
@ -34,7 +34,7 @@ _vifT bool runMark(u32* &data) {
|
||||||
// Returns 1 if i-bit && finished vifcode && i-bit not masked
|
// Returns 1 if i-bit && finished vifcode && i-bit not masked
|
||||||
_vifT bool analyzeIbit(u32* &data, int iBit) {
|
_vifT bool analyzeIbit(u32* &data, int iBit) {
|
||||||
vifStruct& vifX = GetVifX;
|
vifStruct& vifX = GetVifX;
|
||||||
if (iBit && !vifX.cmd && !vifXRegs->err.MII) {
|
if (iBit && !vifX.cmd && !vifXRegs.err.MII) {
|
||||||
//DevCon.WriteLn("Vif I-Bit IRQ");
|
//DevCon.WriteLn("Vif I-Bit IRQ");
|
||||||
vifX.irq++;
|
vifX.irq++;
|
||||||
|
|
||||||
|
@ -75,14 +75,14 @@ _vifT void vifTransferLoop(u32* &data) {
|
||||||
u32& pSize = vifX.vifpacketsize;
|
u32& pSize = vifX.vifpacketsize;
|
||||||
int iBit = vifX.cmd >> 7;
|
int iBit = vifX.cmd >> 7;
|
||||||
|
|
||||||
vifXRegs->stat.VPS |= VPS_TRANSFERRING;
|
vifXRegs.stat.VPS |= VPS_TRANSFERRING;
|
||||||
vifXRegs->stat.ER1 = false;
|
vifXRegs.stat.ER1 = false;
|
||||||
|
|
||||||
while (pSize > 0 && !vifX.vifstalled) {
|
while (pSize > 0 && !vifX.vifstalled) {
|
||||||
|
|
||||||
if(!vifX.cmd) { // Get new VifCode
|
if(!vifX.cmd) { // Get new VifCode
|
||||||
vifX.lastcmd = (vifXRegs->code >> 24) & 0x7f;
|
vifX.lastcmd = (vifXRegs.code >> 24) & 0x7f;
|
||||||
vifXRegs->code = data[0];
|
vifXRegs.code = data[0];
|
||||||
vifX.cmd = data[0] >> 24;
|
vifX.cmd = data[0] >> 24;
|
||||||
iBit = data[0] >> 31;
|
iBit = data[0] >> 31;
|
||||||
|
|
||||||
|
@ -135,20 +135,20 @@ _vifT static __fi bool vifTransfer(u32 *data, int size) {
|
||||||
|
|
||||||
transferred = transferred >> 2;
|
transferred = transferred >> 2;
|
||||||
|
|
||||||
vifXch->madr +=(transferred << 4);
|
vifXch.madr +=(transferred << 4);
|
||||||
vifXch->qwc -= transferred;
|
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) {
|
if (vifX.irq && vifX.cmd == 0) {
|
||||||
//DevCon.WriteLn("Vif IRQ!");
|
//DevCon.WriteLn("Vif IRQ!");
|
||||||
if(((vifXRegs->code >> 24) & 0x7f) != 0x7)
|
if(((vifXRegs.code >> 24) & 0x7f) != 0x7)
|
||||||
{
|
{
|
||||||
vifX.vifstalled = true;
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -302,8 +302,8 @@ _vifT void vifUnpackSetup(const u32 *data) {
|
||||||
|
|
||||||
vifStruct& vifX = GetVifX;
|
vifStruct& vifX = GetVifX;
|
||||||
|
|
||||||
if ((vifXRegs->cycle.wl == 0) && (vifXRegs->cycle.wl < vifXRegs->cycle.cl)) {
|
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);
|
Console.WriteLn("Vif%d CL %d, WL %d", idx, vifXRegs.cycle.cl, vifXRegs.cycle.wl);
|
||||||
vifX.cmd = 0;
|
vifX.cmd = 0;
|
||||||
return; // Skipping write and 0 write-cycles, so do nothing!
|
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?
|
//if (!idx) vif0FLUSH(); // Only VU0?
|
||||||
|
|
||||||
vifX.usn = (vifXRegs->code >> 14) & 0x01;
|
vifX.usn = (vifXRegs.code >> 14) & 0x01;
|
||||||
int vifNum = (vifXRegs->code >> 16) & 0xff;
|
int vifNum = (vifXRegs.code >> 16) & 0xff;
|
||||||
|
|
||||||
if (vifNum == 0) vifNum = 256;
|
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;
|
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 vif1.tag.size = ((vifNum * VIFfuncTable[ vif1.cmd & 0xf ].gsize) + 3) >> 2;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
int n = vifXRegs->cycle.cl * (vifNum / vifXRegs->cycle.wl) +
|
int n = vifXRegs.cycle.cl * (vifNum / vifXRegs.cycle.wl) +
|
||||||
_limit(vifNum % vifXRegs->cycle.wl, vifXRegs->cycle.cl);
|
_limit(vifNum % vifXRegs.cycle.wl, vifXRegs.cycle.cl);
|
||||||
|
|
||||||
if (!idx) vif0.tag.size = ((n * VIFfuncTable[ vif0.cmd & 0xf ].gsize) + 3) >> 2;
|
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;
|
else vif1.tag.size = ((n * VIFfuncTable[ vif1.cmd & 0xf ].gsize) + 3) >> 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 addr = vifXRegs->code;
|
u32 addr = vifXRegs.code;
|
||||||
if (idx && ((addr>>15)&1)) addr += vif1Regs->tops;
|
if (idx && ((addr>>15)&1)) addr += vif1Regs.tops;
|
||||||
vifX.tag.addr = (addr<<4) & (idx ? 0x3ff0 : 0xff0);
|
vifX.tag.addr = (addr<<4) & (idx ? 0x3ff0 : 0xff0);
|
||||||
|
|
||||||
VIF_LOG("Unpack VIF%x, QWC %x tagsize %x", idx, vifNum, vif0.tag.size);
|
VIF_LOG("Unpack VIF%x, QWC %x tagsize %x", idx, vifNum, vif0.tag.size);
|
||||||
|
|
||||||
vifX.cl = 0;
|
vifX.cl = 0;
|
||||||
vifX.tag.cmd = vifX.cmd;
|
vifX.tag.cmd = vifX.cmd;
|
||||||
vifXRegs->offset = 0;
|
vifXRegs.offset = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
template void vifUnpackSetup<0>(const u32 *data);
|
template void vifUnpackSetup<0>(const u32 *data);
|
||||||
|
|
|
@ -26,12 +26,12 @@ template<const u32 VIFdmanum> void VIFunpack(u32 *data, vifCode *v, u32 size) {
|
||||||
|
|
||||||
if (VIFdmanum == 0) {
|
if (VIFdmanum == 0) {
|
||||||
VU = &VU0;
|
VU = &VU0;
|
||||||
vifRegs = vif0Regs;
|
vifRegs = &vif0Regs;
|
||||||
vif = &vif0;
|
vif = &vif0;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
VU = &VU1;
|
VU = &VU1;
|
||||||
vifRegs = vif1Regs;
|
vifRegs = &vif1Regs;
|
||||||
vif = &vif1;
|
vif = &vif1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -993,7 +993,7 @@ void Pcsx2App::ProgramLog_PostEvent( wxEvent& evt )
|
||||||
static void __concall ConsoleToFile_Newline()
|
static void __concall ConsoleToFile_Newline()
|
||||||
{
|
{
|
||||||
#ifdef __LINUX__
|
#ifdef __LINUX__
|
||||||
if (g_Conf->EmuOptions.ConsoleToStdio) ConsoleWriter_Stdout.Newline();
|
if ((g_Conf) && (g_Conf->EmuOptions.ConsoleToStdio)) ConsoleWriter_Stdout.Newline();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __LINUX__
|
#ifdef __LINUX__
|
||||||
|
@ -1006,7 +1006,7 @@ static void __concall ConsoleToFile_Newline()
|
||||||
static void __concall ConsoleToFile_DoWrite( const wxString& fmt )
|
static void __concall ConsoleToFile_DoWrite( const wxString& fmt )
|
||||||
{
|
{
|
||||||
#ifdef __LINUX__
|
#ifdef __LINUX__
|
||||||
if (g_Conf->EmuOptions.ConsoleToStdio) ConsoleWriter_Stdout.WriteRaw(fmt);
|
if ((g_Conf) && (g_Conf->EmuOptions.ConsoleToStdio)) ConsoleWriter_Stdout.WriteRaw(fmt);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
px_fputs( emuLog, fmt.ToUTF8() );
|
px_fputs( emuLog, fmt.ToUTF8() );
|
||||||
|
|
|
@ -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
|
// games must take care to ensure transfer rectangles are exact multiples of a qword
|
||||||
vif1.GSLastDownloadSize = vif1.TRXREG.RRW * vif1.TRXREG.RRH * bpp >> 7;
|
vif1.GSLastDownloadSize = vif1.TRXREG.RRW * vif1.TRXREG.RRH * bpp >> 7;
|
||||||
//DevCon.Warning("GS download in progress");
|
//DevCon.Warning("GS download in progress");
|
||||||
gifRegs->stat.OPH = true;
|
gifRegs.stat.OPH = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (reg >= 0x60)
|
if (reg >= 0x60)
|
||||||
|
@ -602,7 +602,7 @@ __fi int GIFPath::CopyTag(const u128* pMem128, u32 size)
|
||||||
else GSTransferStatus.PTH2 = TRANSFER_MODE;
|
else GSTransferStatus.PTH2 = TRANSFER_MODE;
|
||||||
break;
|
break;
|
||||||
case GIF_PATH_3:
|
case GIF_PATH_3:
|
||||||
if(vif1Regs->mskpath3 == 1 && GSTransferStatus.PTH3 == STOPPED_MODE)
|
if(vif1Regs.mskpath3 == 1 && GSTransferStatus.PTH3 == STOPPED_MODE)
|
||||||
{
|
{
|
||||||
GSTransferStatus.PTH3 = IDLE_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)
|
if(GSTransferStatus.PTH3 < PENDINGSTOP_MODE || pathidx != 2)
|
||||||
{
|
{
|
||||||
gifRegs->stat.OPH = true;
|
gifRegs.stat.OPH = true;
|
||||||
gifRegs->stat.APATH = pathidx + 1;
|
gifRegs.stat.APATH = pathidx + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(pathidx == GIF_PATH_3)
|
if(pathidx == GIF_PATH_3)
|
||||||
|
@ -645,8 +645,8 @@ __fi int GIFPath::CopyTag(const u128* pMem128, u32 size)
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
gifRegs->stat.APATH = pathidx + 1;
|
gifRegs.stat.APATH = pathidx + 1;
|
||||||
gifRegs->stat.OPH = true;
|
gifRegs.stat.OPH = true;
|
||||||
|
|
||||||
switch(tag.FLG) {
|
switch(tag.FLG) {
|
||||||
case GIF_FLG_PACKED:
|
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
|
// 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.
|
// 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
|
//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())
|
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 (tag.EOP && nloop == 0) {
|
||||||
|
|
||||||
/*if(gifRegs->stat.DIR == 0)gifRegs->stat.OPH = false;
|
/*if(gifRegs.stat.DIR == 0)gifRegs.stat.OPH = false;
|
||||||
gifRegs->stat.APATH = GIF_APATH_IDLE;*/
|
gifRegs.stat.APATH = GIF_APATH_IDLE;*/
|
||||||
switch(pathidx)
|
switch(pathidx)
|
||||||
{
|
{
|
||||||
case GIF_PATH_1:
|
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)
|
//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;
|
if(size > 8) GSTransferStatus.PTH3 = PENDINGSTOP_MODE;
|
||||||
else GSTransferStatus.PTH3 = STOPPED_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_LOG("Path3 end EOP %x NLOOP %x Status %x", tag.EOP, nloop, GSTransferStatus.PTH3);
|
||||||
gif->madr += size * 16;
|
gifch.madr += size * 16;
|
||||||
gif->qwc -= size;
|
gifch.qwc -= size;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -860,10 +860,10 @@ __fi int GIFPath::CopyTag(const u128* pMem128, u32 size)
|
||||||
else if(pathidx == 2)
|
else if(pathidx == 2)
|
||||||
{
|
{
|
||||||
//if(nloop <= 16 && GSTransferStatus.PTH3 == IMAGE_MODE)GSTransferStatus.PTH3 = PENDINGIMAGE_MODE;
|
//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_LOG("Path3 end EOP %x NLOOP %x Status %x", tag.EOP, nloop, GSTransferStatus.PTH3);
|
||||||
gif->madr += size * 16;
|
gifch.madr += size * 16;
|
||||||
gif->qwc -= size;
|
gifch.qwc -= size;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
|
@ -51,28 +51,28 @@ mem8_t __fastcall iopHwRead8_Page1( u32 addr )
|
||||||
default:
|
default:
|
||||||
if( masked_addr >= 0x100 && masked_addr < 0x130 )
|
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 );
|
ret = psxHu8( addr );
|
||||||
}
|
}
|
||||||
else if( masked_addr >= 0x480 && masked_addr < 0x4a0 )
|
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 );
|
ret = psxHu8( addr );
|
||||||
}
|
}
|
||||||
else if( (masked_addr >= pgmsk(HW_USB_START)) && (masked_addr < pgmsk(HW_USB_END)) )
|
else if( (masked_addr >= pgmsk(HW_USB_START)) && (masked_addr < pgmsk(HW_USB_END)) )
|
||||||
{
|
{
|
||||||
ret = USBread8( addr );
|
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
|
else
|
||||||
{
|
{
|
||||||
ret = psxHu8(addr);
|
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;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
IopHwTraceLog<mem8_t>( addr, ret, "Read" );
|
IopHwTraceLog<mem8_t>( addr, ret, true );
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -89,7 +89,7 @@ mem8_t __fastcall iopHwRead8_Page3( u32 addr )
|
||||||
else
|
else
|
||||||
ret = psxHu8( addr );
|
ret = psxHu8( addr );
|
||||||
|
|
||||||
IopHwTraceLog<mem8_t>( addr, ret, "Read" );
|
IopHwTraceLog<mem8_t>( addr, ret, true );
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -107,7 +107,7 @@ mem8_t __fastcall iopHwRead8_Page8( u32 addr )
|
||||||
else
|
else
|
||||||
ret = psxHu8( addr );
|
ret = psxHu8( addr );
|
||||||
|
|
||||||
IopHwTraceLog<mem8_t>( addr, ret, "Read" );
|
IopHwTraceLog<mem8_t>( addr, ret, true );
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -216,7 +216,7 @@ static __fi T _HwRead_16or32_Page1( u32 addr )
|
||||||
ret = SPU2read( addr );
|
ret = SPU2read( addr );
|
||||||
else
|
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);
|
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;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -343,7 +343,7 @@ mem16_t __fastcall iopHwRead16_Page3( u32 addr )
|
||||||
jASSUME( (addr >> 12) == 0x1f803 );
|
jASSUME( (addr >> 12) == 0x1f803 );
|
||||||
|
|
||||||
mem16_t ret = psxHu16(addr);
|
mem16_t ret = psxHu16(addr);
|
||||||
IopHwTraceLog<mem16_t>( addr, ret, "Read" );
|
IopHwTraceLog<mem16_t>( addr, ret, true );
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -355,7 +355,7 @@ mem16_t __fastcall iopHwRead16_Page8( u32 addr )
|
||||||
jASSUME( (addr >> 12) == 0x1f808 );
|
jASSUME( (addr >> 12) == 0x1f808 );
|
||||||
|
|
||||||
mem16_t ret = psxHu16(addr);
|
mem16_t ret = psxHu16(addr);
|
||||||
IopHwTraceLog<mem16_t>( addr, ret, "Read" );
|
IopHwTraceLog<mem16_t>( addr, ret, true );
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -373,7 +373,7 @@ mem32_t __fastcall iopHwRead32_Page3( u32 addr )
|
||||||
// all addresses are assumed to be prefixed with 0x1f803xxx:
|
// all addresses are assumed to be prefixed with 0x1f803xxx:
|
||||||
jASSUME( (addr >> 12) == 0x1f803 );
|
jASSUME( (addr >> 12) == 0x1f803 );
|
||||||
const mem32_t ret = psxHu32(addr);
|
const mem32_t ret = psxHu32(addr);
|
||||||
IopHwTraceLog<mem32_t>( addr, ret, "Read" );
|
IopHwTraceLog<mem32_t>( addr, ret, true );
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -437,7 +437,7 @@ mem32_t __fastcall iopHwRead32_Page8( u32 addr )
|
||||||
}
|
}
|
||||||
else ret = psxHu32(addr);
|
else ret = psxHu32(addr);
|
||||||
|
|
||||||
IopHwTraceLog<mem32_t>( addr, ret, "Read" );
|
IopHwTraceLog<mem32_t>( addr, ret, true );
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -33,7 +33,7 @@ template< typename T >
|
||||||
static __fi void _generic_write( u32 addr, T val )
|
static __fi void _generic_write( u32 addr, T val )
|
||||||
{
|
{
|
||||||
//int bitsize = (sizeof(T) == 1) ? 8 : ( (sizeof(T) == 2) ? 16 : 32 );
|
//int bitsize = (sizeof(T) == 1) ? 8 : ( (sizeof(T) == 2) ? 16 : 32 );
|
||||||
IopHwTraceLog<T>( addr, val, "Write" );
|
IopHwTraceLog<T>( addr, val, false );
|
||||||
psxHu(addr) = val;
|
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 );
|
//int bitsize = (sizeof(T) == 1) ? 8 : ( (sizeof(T) == 2) ? 16 : 32 );
|
||||||
|
|
||||||
T ret = psxHu(addr);
|
T ret = psxHu(addr);
|
||||||
IopHwTraceLog<T>( addr, ret, "Read" );
|
IopHwTraceLog<T>( addr, ret, true );
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -84,12 +84,12 @@ void __fastcall iopHwWrite8_Page1( u32 addr, mem8_t val )
|
||||||
default:
|
default:
|
||||||
if( masked_addr >= 0x100 && masked_addr < 0x130 )
|
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;
|
psxHu8( addr ) = val;
|
||||||
}
|
}
|
||||||
else if( masked_addr >= 0x480 && masked_addr < 0x4a0 )
|
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;
|
psxHu8( addr ) = val;
|
||||||
}
|
}
|
||||||
else if( (masked_addr >= pgmsk(HW_USB_START)) && (masked_addr < pgmsk(HW_USB_END)) )
|
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;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
IopHwTraceLog<mem8_t>( addr, val, "Write" );
|
IopHwTraceLog<mem8_t>( addr, val, false );
|
||||||
}
|
}
|
||||||
|
|
||||||
void __fastcall iopHwWrite8_Page3( u32 addr, mem8_t val )
|
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;
|
psxHu8( addr ) = val;
|
||||||
IopHwTraceLog<mem8_t>( addr, val, "Write" );
|
IopHwTraceLog<mem8_t>( addr, val, false );
|
||||||
}
|
}
|
||||||
|
|
||||||
void __fastcall iopHwWrite8_Page8( u32 addr, mem8_t val )
|
void __fastcall iopHwWrite8_Page8( u32 addr, mem8_t val )
|
||||||
|
@ -150,7 +150,7 @@ void __fastcall iopHwWrite8_Page8( u32 addr, mem8_t val )
|
||||||
else
|
else
|
||||||
psxHu8( addr ) = val;
|
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 );
|
SPU2write( addr, val );
|
||||||
else
|
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;
|
//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:
|
// all addresses are assumed to be prefixed with 0x1f803xxx:
|
||||||
pxAssert( (addr >> 12) == 0x1f803 );
|
pxAssert( (addr >> 12) == 0x1f803 );
|
||||||
psxHu16(addr) = val;
|
psxHu16(addr) = val;
|
||||||
IopHwTraceLog<mem16_t>( addr, val, "Write" );
|
IopHwTraceLog<mem16_t>( addr, val, false );
|
||||||
}
|
}
|
||||||
|
|
||||||
void __fastcall iopHwWrite16_Page8( u32 addr, mem16_t val )
|
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:
|
// all addresses are assumed to be prefixed with 0x1f808xxx:
|
||||||
pxAssert( (addr >> 12) == 0x1f808 );
|
pxAssert( (addr >> 12) == 0x1f808 );
|
||||||
psxHu16(addr) = val;
|
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:
|
// all addresses are assumed to be prefixed with 0x1f803xxx:
|
||||||
pxAssert( (addr >> 12) == 0x1f803 );
|
pxAssert( (addr >> 12) == 0x1f803 );
|
||||||
psxHu16(addr) = val;
|
psxHu16(addr) = val;
|
||||||
IopHwTraceLog<mem32_t>( addr, val, "Write" );
|
IopHwTraceLog<mem32_t>( addr, val, false );
|
||||||
}
|
}
|
||||||
|
|
||||||
void __fastcall iopHwWrite32_Page8( u32 addr, mem32_t val )
|
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;
|
else psxHu32(addr) = val;
|
||||||
|
|
||||||
IopHwTraceLog<mem32_t>( addr, val, "Write" );
|
IopHwTraceLog<mem32_t>( addr, val, false );
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,7 +38,7 @@ namespace Internal {
|
||||||
//
|
//
|
||||||
|
|
||||||
template< typename T>
|
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 )
|
switch( addr )
|
||||||
{
|
{
|
||||||
|
@ -200,20 +200,31 @@ static __ri const char* _log_GetIopHwName( u32 addr, T val )
|
||||||
}
|
}
|
||||||
|
|
||||||
template< typename T>
|
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
|
switch( sizeof (T) )
|
||||||
// zero-fill hex values):
|
{
|
||||||
temp[(sizeof temp)-3] = '0' + (sizeof(T)*2);
|
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 ) )
|
case 8: valStr.Write("0x%08x.%08x", ((u32*)&val)[1], ((u32*)&val)[0]); break;
|
||||||
PSXHW_LOG( temp, modestr, (sizeof (T)) * 8, regname, addr, val );
|
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
|
else
|
||||||
PSXUnkHW_LOG( temp, modestr, (sizeof (T)) * 8, "Unknown", addr, val );
|
PSXUnkHW_LOG( temp, labelStr.c_str(), addr, "Unknown", mode ? "->" : "<-", valStr.c_str() );
|
||||||
}
|
}
|
||||||
|
|
||||||
} };
|
} };
|
||||||
|
|
|
@ -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 );
|
|
@ -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() );
|
||||||
|
}
|
|
@ -126,10 +126,6 @@ void __fastcall vtlb_memRead128(u32 mem, mem128_t *out)
|
||||||
((vtlbMemR128FP*)vtlbdata.RWFT[4][0][hand])(paddr, 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 >
|
template< typename DataType >
|
||||||
void __fastcall vtlb_memWrite(u32 addr, DataType data)
|
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)
|
void __fastcall vtlb_memWrite64(u32 mem, const mem64_t* value)
|
||||||
{
|
{
|
||||||
u32 vmv=vtlbdata.vmap[mem>>VTLB_PAGE_BITS];
|
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 mem8_t vtlb_memRead<mem8_t>(u32 mem);
|
||||||
template mem16_t vtlb_memRead<mem16_t>(u32 mem);
|
template mem16_t vtlb_memRead<mem16_t>(u32 mem);
|
||||||
template mem32_t vtlb_memRead<mem32_t>(u32 mem);
|
template mem32_t vtlb_memRead<mem32_t>(u32 mem);
|
||||||
|
|
|
@ -71,13 +71,11 @@ template< typename DataType >
|
||||||
extern DataType __fastcall vtlb_memRead(u32 mem);
|
extern DataType __fastcall vtlb_memRead(u32 mem);
|
||||||
extern void __fastcall vtlb_memRead64(u32 mem, mem64_t *out);
|
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, mem128_t *out);
|
||||||
extern void __fastcall vtlb_memRead128(u32 mem, u64 (&out)[2]);
|
|
||||||
|
|
||||||
template< typename DataType >
|
template< typename DataType >
|
||||||
extern void __fastcall vtlb_memWrite(u32 mem, DataType value);
|
extern void __fastcall vtlb_memWrite(u32 mem, DataType value);
|
||||||
extern void __fastcall vtlb_memWrite64(u32 mem, const mem64_t* 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 mem128_t* value);
|
||||||
extern void __fastcall vtlb_memWrite128(u32 mem, const u64 (&value)[2]);
|
|
||||||
|
|
||||||
extern void vtlb_DynGenWrite(u32 sz);
|
extern void vtlb_DynGenWrite(u32 sz);
|
||||||
extern void vtlb_DynGenRead32(u32 bits, bool sign);
|
extern void vtlb_DynGenRead32(u32 bits, bool sign);
|
||||||
|
|
|
@ -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,
|
"\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]);
|
tag[0], tag[1], tag[2], tag[3]);
|
||||||
|
|
||||||
sif0dma->unsafeTransfer(((tDMA_TAG*)(tag)));
|
sif0dma.unsafeTransfer(((tDMA_TAG*)(tag)));
|
||||||
sif0dma->madr = tag[1];
|
sif0dma.madr = tag[1];
|
||||||
tDMA_TAG ptag(tag[0]);
|
tDMA_TAG ptag(tag[0]);
|
||||||
|
|
||||||
SIF_LOG("SIF0 EE dest chain tag madr:%08X qwc:%04X id:%X irq:%d(%08X_%08X)",
|
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");
|
//Console.WriteLn("SIF0 TIE");
|
||||||
sif0.ee.end = true;
|
sif0.ee.end = true;
|
||||||
|
@ -50,13 +50,13 @@ s32 PrepareEERead()
|
||||||
{
|
{
|
||||||
case TAG_REFE:
|
case TAG_REFE:
|
||||||
sif0.ee.end = true;
|
sif0.ee.end = true;
|
||||||
if (dmacRegs->ctrl.STS != NO_STS)
|
if (dmacRegs.ctrl.STS != NO_STS)
|
||||||
dmacRegs->stadr.ADDR = sif0dma->madr + (sif0dma->qwc * 16);
|
dmacRegs.stadr.ADDR = sif0dma.madr + (sif0dma.qwc * 16);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TAG_REFS:
|
case TAG_REFS:
|
||||||
if (dmacRegs->ctrl.STS != NO_STS)
|
if (dmacRegs.ctrl.STS != NO_STS)
|
||||||
dmacRegs->stadr.ADDR = sif0dma->madr + (sif0dma->qwc * 16);
|
dmacRegs.stadr.ADDR = sif0dma.madr + (sif0dma.qwc * 16);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TAG_END:
|
case TAG_END:
|
||||||
|
@ -91,7 +91,7 @@ s32 DoSifRead(u32 iopAvailable)
|
||||||
|
|
||||||
SIF_LOG("Write IOP to EE: +++++++++++ %lX of %lX", transferSizeWords, sif0.iop.counter);
|
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)
|
if (ptag == NULL)
|
||||||
{
|
{
|
||||||
DevCon.Warning("Write IOP to EE: 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);
|
memcpy((u32*)ptag, (u32*)iopPhysMem(hw_dma(9).madr), transferSizeBytes);
|
||||||
|
|
||||||
// Clearing handled by vtlb memory protection and manual blocks.
|
// 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;
|
sif0.ee.cycles += transferSizeQWords * 2;
|
||||||
sif0dma->qwc -= transferSizeQWords;
|
sif0dma.qwc -= transferSizeQWords;
|
||||||
|
|
||||||
return transferSizeBytes;
|
return transferSizeBytes;
|
||||||
}
|
}
|
||||||
|
|
|
@ -513,6 +513,10 @@
|
||||||
RelativePath="..\..\Dmac.h"
|
RelativePath="..\..\Dmac.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\ps2\eeHwTraceLog.inl"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\FiFo.cpp"
|
RelativePath="..\..\FiFo.cpp"
|
||||||
>
|
>
|
||||||
|
@ -529,6 +533,10 @@
|
||||||
RelativePath="..\..\Hw.h"
|
RelativePath="..\..\Hw.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\ps2\HwInternal.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\HwRead.cpp"
|
RelativePath="..\..\HwRead.cpp"
|
||||||
>
|
>
|
||||||
|
@ -749,6 +757,10 @@
|
||||||
<Filter
|
<Filter
|
||||||
Name="DMAC"
|
Name="DMAC"
|
||||||
>
|
>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\ps2\LegacyDmac.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<Filter
|
<Filter
|
||||||
Name="Sif"
|
Name="Sif"
|
||||||
>
|
>
|
||||||
|
@ -1318,6 +1330,14 @@
|
||||||
RelativePath="..\..\Ipu\IPU_Fifo.h"
|
RelativePath="..\..\Ipu\IPU_Fifo.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\IPU\IPUdma.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\IPU\IPUdma.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\Ipu\yuv2rgb.cpp"
|
RelativePath="..\..\Ipu\yuv2rgb.cpp"
|
||||||
>
|
>
|
||||||
|
|
|
@ -670,7 +670,7 @@ void psxRecompileCodeConst1(R3000AFNPTR constcode, R3000AFNPTR_INFO noconstcode)
|
||||||
const char *funcname = irxImportFuncname(libname, index);
|
const char *funcname = irxImportFuncname(libname, index);
|
||||||
irxDEBUG debug = irxImportDebug(libname, index);
|
irxDEBUG debug = irxImportDebug(libname, index);
|
||||||
|
|
||||||
if (SysTrace.IOP.Bios.IsActive()) {
|
if (SysTraceActive(IOP.Bios)) {
|
||||||
xMOV(ecx, (uptr)libname);
|
xMOV(ecx, (uptr)libname);
|
||||||
xMOV(edx, index);
|
xMOV(edx, index);
|
||||||
xPUSH((uptr)funcname);
|
xPUSH((uptr)funcname);
|
||||||
|
|
|
@ -21,11 +21,6 @@
|
||||||
#include "iR5900.h"
|
#include "iR5900.h"
|
||||||
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
//#pragma warning(disable:4244)
|
|
||||||
//#pragma warning(disable:4761)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace R5900 {
|
namespace R5900 {
|
||||||
namespace Dynarec {
|
namespace Dynarec {
|
||||||
namespace OpcodeImpl
|
namespace OpcodeImpl
|
||||||
|
|
|
@ -19,6 +19,21 @@
|
||||||
#include "Common.h"
|
#include "Common.h"
|
||||||
#include "microVU.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
|
// Micro VU - Global Variables
|
||||||
//------------------------------------------------------------------
|
//------------------------------------------------------------------
|
||||||
|
@ -70,107 +85,93 @@ static __fi void mVUthrowHardwareDeficiency(const wxChar* extFail, int vuIndex)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Only run this once per VU! ;)
|
// 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.hasMultimediaExtensions) mVUthrowHardwareDeficiency( L"MMX", vuIndex );
|
||||||
if(!x86caps.hasStreamingSIMDExtensions) mVUthrowHardwareDeficiency( L"SSE", vuIndex );
|
if(!x86caps.hasStreamingSIMDExtensions) mVUthrowHardwareDeficiency( L"SSE", vuIndex );
|
||||||
if(!x86caps.hasStreamingSIMD2Extensions) mVUthrowHardwareDeficiency( L"SSE2", vuIndex );
|
if(!x86caps.hasStreamingSIMD2Extensions) mVUthrowHardwareDeficiency( L"SSE2", vuIndex );
|
||||||
|
|
||||||
microVU* mVU = mVUx;
|
memzero(prog);
|
||||||
memzero(mVU->prog);
|
|
||||||
|
|
||||||
mVU->index = vuIndex;
|
index = vuIndex;
|
||||||
mVU->cop2 = 0;
|
cop2 = 0;
|
||||||
mVU->vuMemSize = (vuIndex ? 0x4000 : 0x1000);
|
vuMemSize = (index ? 0x4000 : 0x1000);
|
||||||
mVU->microMemSize = (vuIndex ? 0x4000 : 0x1000);
|
microMemSize = (index ? 0x4000 : 0x1000);
|
||||||
mVU->progSize = (vuIndex ? 0x4000 : 0x1000) / 4;
|
progSize = (index ? 0x4000 : 0x1000) / 4;
|
||||||
mVU->progMemMask = mVU->progSize-1;
|
progMemMask = progSize-1;
|
||||||
mVU->dispCache = NULL;
|
dispCache = NULL;
|
||||||
mVU->cache = NULL;
|
cache = NULL;
|
||||||
mVU->cacheSize = mVUcacheSize;
|
cacheSize = mVUcacheSize;
|
||||||
mVU->regAlloc = new microRegAlloc();
|
regAlloc = new microRegAlloc(index);
|
||||||
|
|
||||||
for (u32 i = 0; i < (mVU->progSize / 2); i++) {
|
for (u32 i = 0; i < (progSize / 2); i++) {
|
||||||
mVU->prog.prog[i] = new deque<microProgram*>();
|
prog.prog[i] = new deque<microProgram*>();
|
||||||
}
|
}
|
||||||
|
|
||||||
mVU->dispCache = SysMmapEx(0, mVUdispCacheSize, 0, (mVU->index ? "Micro VU1 Dispatcher" : "Micro VU0 Dispatcher"));
|
dispCache = SysMmapEx(0, mVUdispCacheSize, 0, (index ? "Micro VU1 Dispatcher" : "Micro VU0 Dispatcher"));
|
||||||
if (!mVU->dispCache) throw Exception::OutOfMemory( mVU->index ? L"Micro VU1 Dispatcher" : L"Micro VU0 Dispatcher" );
|
if (!dispCache) throw Exception::OutOfMemory( index ? L"Micro VU1 Dispatcher" : L"Micro VU0 Dispatcher" );
|
||||||
memset(mVU->dispCache, 0xcc, mVUdispCacheSize);
|
memset(dispCache, 0xcc, mVUdispCacheSize);
|
||||||
|
|
||||||
// Allocates rec-cache and calls mVUreset()
|
// Allocates rec-cache and calls mVUreset()
|
||||||
mVUresizeCache(mVU, mVU->cacheSize + mVUcacheSafeZone);
|
mVUresizeCache(this, cacheSize + mVUcacheSafeZone);
|
||||||
//if (vuIndex) gen_memcpy_vibes();
|
//if (vuIndex) gen_memcpy_vibes();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Resets Rec Data
|
// Resets Rec Data
|
||||||
// If vuRegsPtr is NUL, the current regs pointer assigned to the VU compiler is assumed.
|
void microVU::reset() {
|
||||||
static __fi void mVUreset(mV, VURegs* vuRegsPtr) {
|
|
||||||
|
|
||||||
static bool dispatchersGenerated = false;
|
x86SetPtr(dispCache);
|
||||||
|
mVUdispatcherA(this);
|
||||||
if (!vuRegsPtr) vuRegsPtr = mVU->regs;
|
mVUdispatcherB(this);
|
||||||
if (!dispatchersGenerated || (mVU->regs != vuRegsPtr))
|
mVUemitSearch();
|
||||||
{
|
|
||||||
// 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();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Clear All Program Data
|
// Clear All Program Data
|
||||||
//memset(&mVU->prog, 0, sizeof(mVU->prog));
|
//memset(&prog, 0, sizeof(prog));
|
||||||
memset(&mVU->prog.lpState, 0, sizeof(mVU->prog.lpState));
|
memset(&prog.lpState, 0, sizeof(prog.lpState));
|
||||||
|
|
||||||
if (IsDevBuild) { // Release builds shouldn't need this
|
if (IsDevBuild) { // Release builds shouldn't need this
|
||||||
memset(mVU->cache, 0xcc, mVU->cacheSize);
|
memset(cache, 0xcc, cacheSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Program Variables
|
// Program Variables
|
||||||
mVU->prog.cleared = 1;
|
prog.cleared = 1;
|
||||||
mVU->prog.isSame = -1;
|
prog.isSame = -1;
|
||||||
mVU->prog.cur = NULL;
|
prog.cur = NULL;
|
||||||
mVU->prog.total = 0;
|
prog.total = 0;
|
||||||
mVU->prog.curFrame = 0;
|
prog.curFrame = 0;
|
||||||
|
|
||||||
// Setup Dynarec Cache Limits for Each Program
|
// Setup Dynarec Cache Limits for Each Program
|
||||||
u8* z = mVU->cache;
|
u8* z = cache;
|
||||||
mVU->prog.x86start = z;
|
prog.x86start = z;
|
||||||
mVU->prog.x86ptr = z;
|
prog.x86ptr = z;
|
||||||
mVU->prog.x86end = (u8*)((uptr)z + (uptr)(mVU->cacheSize - mVUcacheSafeZone)); // "Safe Zone"
|
prog.x86end = (u8*)((uptr)z + (uptr)(cacheSize - mVUcacheSafeZone)); // "Safe Zone"
|
||||||
|
|
||||||
for (u32 i = 0; i < (mVU->progSize / 2); i++) {
|
for (u32 i = 0; i < (progSize / 2); i++) {
|
||||||
deque<microProgram*>::iterator it(mVU->prog.prog[i]->begin());
|
deque<microProgram*>::iterator it(prog.prog[i]->begin());
|
||||||
for ( ; it != mVU->prog.prog[i]->end(); ++it) {
|
for ( ; it != prog.prog[i]->end(); ++it) {
|
||||||
if (!isVU1) mVUdeleteProg<0>(it[0]);
|
if (index) mVUdeleteProg<1>(it[0]);
|
||||||
else mVUdeleteProg<1>(it[0]);
|
else mVUdeleteProg<0>(it[0]);
|
||||||
}
|
}
|
||||||
mVU->prog.prog[i]->clear();
|
prog.prog[i]->clear();
|
||||||
mVU->prog.quick[i].block = NULL;
|
prog.quick[i].block = NULL;
|
||||||
mVU->prog.quick[i].prog = NULL;
|
prog.quick[i].prog = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Free Allocated Resources
|
// Free Allocated Resources
|
||||||
static __fi void mVUclose(mV) {
|
void microVU::close() {
|
||||||
|
|
||||||
if (mVU->dispCache) { HostSys::Munmap(mVU->dispCache, mVUdispCacheSize); mVU->dispCache = NULL; }
|
if (dispCache) { HostSys::Munmap(dispCache, mVUdispCacheSize); dispCache = NULL; }
|
||||||
if (mVU->cache) { HostSys::Munmap(mVU->cache, mVU->cacheSize); mVU->cache = NULL; }
|
if (cache) { HostSys::Munmap(cache, cacheSize); cache = NULL; }
|
||||||
|
|
||||||
// Delete Programs and Block Managers
|
// Delete Programs and Block Managers
|
||||||
for (u32 i = 0; i < (mVU->progSize / 2); i++) {
|
for (u32 i = 0; i < (progSize / 2); i++) {
|
||||||
deque<microProgram*>::iterator it(mVU->prog.prog[i]->begin());
|
deque<microProgram*>::iterator it(prog.prog[i]->begin());
|
||||||
for ( ; it != mVU->prog.prog[i]->end(); ++it) {
|
for ( ; it != prog.prog[i]->end(); ++it) {
|
||||||
if (!isVU1) mVUdeleteProg<0>(it[0]);
|
if (index) mVUdeleteProg<1>(it[0]);
|
||||||
else 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.
|
// 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)
|
//(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);
|
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;
|
return;
|
||||||
}
|
}
|
||||||
size = mVUcacheMaxSize;
|
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"));
|
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 && !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) {
|
if (mVU->cache) {
|
||||||
HostSys::Munmap(mVU->cache, mVU->cacheSize);
|
HostSys::Munmap(mVU->cache, mVU->cacheSize);
|
||||||
ProfilerTerminateSource(isVU1?"mVU1 Rec":"mVU0 Rec");
|
ProfilerTerminateSource(isVU1?"mVU1 Rec":"mVU0 Rec");
|
||||||
|
@ -200,7 +201,7 @@ static void mVUresizeCache(mV, u32 size) {
|
||||||
mVU->cache = cache;
|
mVU->cache = cache;
|
||||||
mVU->cacheSize = size;
|
mVU->cacheSize = size;
|
||||||
ProfilerRegisterSource(isVU1?"mVU1 Rec":"mVU0 Rec", mVU->cache, mVU->cacheSize);
|
ProfilerRegisterSource(isVU1?"mVU1 Rec":"mVU0 Rec", mVU->cache, mVU->cacheSize);
|
||||||
mVUreset(mVU);
|
mVU->reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clears Block Data in specified range
|
// Clears Block Data in specified range
|
||||||
|
@ -254,8 +255,8 @@ _mVUt __fi microProgram* mVUcreateProg(int startPC) {
|
||||||
// Caches Micro Program
|
// Caches Micro Program
|
||||||
_mVUt __fi void mVUcacheProg(microProgram& prog) {
|
_mVUt __fi void mVUcacheProg(microProgram& prog) {
|
||||||
microVU* mVU = mVUx;
|
microVU* mVU = mVUx;
|
||||||
if (!vuIndex) memcpy_const(prog.data, mVU->regs->Micro, 0x1000);
|
if (!vuIndex) memcpy_const(prog.data, mVU->regs().Micro, 0x1000);
|
||||||
else memcpy_const(prog.data, mVU->regs->Micro, 0x4000);
|
else memcpy_const(prog.data, mVU->regs().Micro, 0x4000);
|
||||||
mVUdumpProg(prog);
|
mVUdumpProg(prog);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -265,17 +266,17 @@ _mVUt __fi bool mVUcmpPartial(microProgram& prog) {
|
||||||
deque<microRange>::const_iterator it(prog.ranges->begin());
|
deque<microRange>::const_iterator it(prog.ranges->begin());
|
||||||
for ( ; it != prog.ranges->end(); ++it) {
|
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((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 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 1;
|
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) {
|
_mVUt __fi bool mVUcmpProg(microProgram& prog, const bool cmpWholeProg) {
|
||||||
microVU* mVU = mVUx;
|
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))) {
|
|| (!cmpWholeProg && mVUcmpPartial<vuIndex>(prog))) {
|
||||||
mVU->prog.cleared = 0;
|
mVU->prog.cleared = 0;
|
||||||
mVU->prog.cur = &prog;
|
mVU->prog.cur = &prog;
|
||||||
|
@ -334,14 +335,14 @@ void recMicroVU0::Allocate() {
|
||||||
if(!m_AllocCount) {
|
if(!m_AllocCount) {
|
||||||
m_AllocCount++;
|
m_AllocCount++;
|
||||||
if (AtomicExchange(mvu0_allocated, 1) == 0)
|
if (AtomicExchange(mvu0_allocated, 1) == 0)
|
||||||
mVUinit(0);
|
microVU0.init(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void recMicroVU1::Allocate() {
|
void recMicroVU1::Allocate() {
|
||||||
if(!m_AllocCount) {
|
if(!m_AllocCount) {
|
||||||
m_AllocCount++;
|
m_AllocCount++;
|
||||||
if (AtomicExchange(mvu1_allocated, 1) == 0)
|
if (AtomicExchange(mvu1_allocated, 1) == 0)
|
||||||
mVUinit(1);
|
microVU1.init(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -349,24 +350,24 @@ void recMicroVU0::Shutdown() throw() {
|
||||||
if (m_AllocCount > 0) {
|
if (m_AllocCount > 0) {
|
||||||
m_AllocCount--;
|
m_AllocCount--;
|
||||||
if (AtomicExchange(mvu0_allocated, 0) == 1)
|
if (AtomicExchange(mvu0_allocated, 0) == 1)
|
||||||
mVUclose(µVU0);
|
microVU0.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void recMicroVU1::Shutdown() throw() {
|
void recMicroVU1::Shutdown() throw() {
|
||||||
if (m_AllocCount > 0) {
|
if (m_AllocCount > 0) {
|
||||||
m_AllocCount--;
|
m_AllocCount--;
|
||||||
if (AtomicExchange(mvu1_allocated, 0) == 1)
|
if (AtomicExchange(mvu1_allocated, 0) == 1)
|
||||||
mVUclose(µVU1);
|
microVU1.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void recMicroVU0::Reset() {
|
void recMicroVU0::Reset() {
|
||||||
if(!pxAssertDev(m_AllocCount, "MicroVU0 CPU Provider has not been allocated prior to reset!")) return;
|
if(!pxAssertDev(m_AllocCount, "MicroVU0 CPU Provider has not been allocated prior to reset!")) return;
|
||||||
mVUreset(µVU0, &VU0);
|
microVU0.reset();
|
||||||
}
|
}
|
||||||
void recMicroVU1::Reset() {
|
void recMicroVU1::Reset() {
|
||||||
if(!pxAssertDev(m_AllocCount, "MicroVU1 CPU Provider has not been allocated prior to reset!")) return;
|
if(!pxAssertDev(m_AllocCount, "MicroVU1 CPU Provider has not been allocated prior to reset!")) return;
|
||||||
mVUreset(µVU1, &VU1);
|
microVU1.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
void recMicroVU0::Execute(u32 cycles) {
|
void recMicroVU0::Execute(u32 cycles) {
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue