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
|
||||
Name = Kingdom Hearts Re: Chain of Memories
|
||||
Region = NTSC-J
|
||||
Compat = 4
|
||||
Compat = 5
|
||||
---------------------------------------------
|
||||
Serial = SLUS-21799
|
||||
Name = Kingdom Hearts Re: Chain of Memories
|
||||
Region = NTSC-U
|
||||
Compat = 4
|
||||
Compat = 5
|
||||
---------------------------------------------
|
||||
Serial = SLUS-21820
|
||||
Name = Legend Of Spyro - Dawn Of The Dragon
|
||||
|
|
|
@ -16,16 +16,23 @@
|
|||
#ifndef __PCSX2TYPES_H__
|
||||
#define __PCSX2TYPES_H__
|
||||
|
||||
/*
|
||||
* Based on PS2E Definitions by
|
||||
linuzappz@hotmail.com,
|
||||
* shadowpcsx2@yahoo.gr,
|
||||
* and florinsasu@hotmail.com
|
||||
*/
|
||||
// --------------------------------------------------------------------------------------
|
||||
// Forward declarations
|
||||
// --------------------------------------------------------------------------------------
|
||||
// Forward declarations for wxWidgets-supporting features.
|
||||
// If you aren't linking against wxWidgets libraries, then functions that
|
||||
// depend on these types will not be usable (they will yield linker errors).
|
||||
|
||||
#ifdef __cplusplus
|
||||
class wxString;
|
||||
class FastFormatAscii;
|
||||
class FastFormatUnicode;
|
||||
#endif
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Basic Atomic Types
|
||||
// --------------------------------------------------------------------------------------
|
||||
// Basic Atomic Types
|
||||
// --------------------------------------------------------------------------------------
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
|
||||
|
@ -111,28 +118,41 @@ typedef s32 sptr;
|
|||
// performing explicit conversion from 64 and 32 bit values are provided instead.
|
||||
//
|
||||
#ifdef __cplusplus
|
||||
struct u128
|
||||
union u128
|
||||
{
|
||||
u64 lo;
|
||||
u64 hi;
|
||||
struct
|
||||
{
|
||||
u64 lo;
|
||||
u64 hi;
|
||||
};
|
||||
|
||||
// Explicit conversion from u64
|
||||
u64 _u64[2];
|
||||
u32 _u32[4];
|
||||
u16 _u16[8];
|
||||
u8 _u8[16];
|
||||
|
||||
// Explicit conversion from u64. Zero-extends the source through 128 bits.
|
||||
static u128 From64( u64 src )
|
||||
{
|
||||
u128 retval = { src, 0 };
|
||||
u128 retval;
|
||||
retval.lo = src;
|
||||
retval.hi = 0;
|
||||
return retval;
|
||||
}
|
||||
|
||||
// Explicit conversion from u32
|
||||
// Explicit conversion from u32. Zero-extends the source through 128 bits.
|
||||
static u128 From32( u32 src )
|
||||
{
|
||||
u128 retval = { src, 0 };
|
||||
u128 retval;
|
||||
retval._u32[0] = src;
|
||||
retval._u32[1] = 0;
|
||||
retval.hi = 0;
|
||||
return retval;
|
||||
}
|
||||
|
||||
operator u32() const { return (u32)lo; }
|
||||
operator u16() const { return (u16)lo; }
|
||||
operator u8() const { return (u8)lo; }
|
||||
operator u32() const { return _u32[0]; }
|
||||
operator u16() const { return _u16[0]; }
|
||||
operator u8() const { return _u8[0]; }
|
||||
|
||||
bool operator==( const u128& right ) const
|
||||
{
|
||||
|
@ -143,6 +163,17 @@ struct u128
|
|||
{
|
||||
return (lo != right.lo) && (hi != right.hi);
|
||||
}
|
||||
|
||||
// In order for the following ToString() and WriteTo methods to be available, you must
|
||||
// be linking to both wxWidgets and the pxWidgets extension library. If you are not
|
||||
// using them, then you will need to provide your own implementations of these methods.
|
||||
wxString ToString() const;
|
||||
wxString ToString64() const;
|
||||
wxString ToString8() const;
|
||||
|
||||
void WriteTo( FastFormatAscii& dest ) const;
|
||||
void WriteTo8( FastFormatAscii& dest ) const;
|
||||
void WriteTo64( FastFormatAscii& dest ) const;
|
||||
};
|
||||
|
||||
struct s128
|
||||
|
@ -183,13 +214,21 @@ struct s128
|
|||
|
||||
typedef union _u128_t
|
||||
{
|
||||
u64 lo;
|
||||
u64 hi;
|
||||
struct
|
||||
{
|
||||
u64 lo;
|
||||
u64 hi;
|
||||
};
|
||||
|
||||
u64 _u64[2];
|
||||
u32 _u32[4];
|
||||
u16 _u16[8];
|
||||
u8 _u8[16];
|
||||
} u128;
|
||||
|
||||
typedef union _s128_t
|
||||
{
|
||||
s64 lo;
|
||||
u64 lo;
|
||||
s64 hi;
|
||||
} s128;
|
||||
|
||||
|
|
|
@ -127,11 +127,13 @@ public:
|
|||
FastFormatAscii& Write( const char* fmt, ... );
|
||||
FastFormatAscii& WriteV( const char* fmt, va_list argptr );
|
||||
|
||||
const char* GetResult() const;
|
||||
operator const char*() const;
|
||||
bool IsEmpty() const;
|
||||
|
||||
const char* c_str() const { return m_dest->GetPtr(); }
|
||||
operator const char*() const { return m_dest->GetPtr(); }
|
||||
|
||||
const wxString GetString() const;
|
||||
operator wxString() const;
|
||||
//operator wxString() const;
|
||||
};
|
||||
|
||||
class FastFormatUnicode
|
||||
|
@ -149,18 +151,11 @@ public:
|
|||
FastFormatUnicode& WriteV( const char* fmt, va_list argptr );
|
||||
FastFormatUnicode& WriteV( const wxChar* fmt, va_list argptr );
|
||||
|
||||
const wxChar* GetResult() const;
|
||||
const wxString GetString() const;
|
||||
bool IsEmpty() const;
|
||||
|
||||
operator const wxChar*() const
|
||||
{
|
||||
return (const wxChar*)m_dest->GetPtr();
|
||||
}
|
||||
|
||||
operator wxString() const
|
||||
{
|
||||
return (const wxChar*)m_dest->GetPtr();
|
||||
}
|
||||
const wxChar* c_str() const { return (const wxChar*)m_dest->GetPtr(); }
|
||||
operator const wxChar*() const { return (const wxChar*)m_dest->GetPtr(); }
|
||||
operator wxString() const { return (const wxChar*)m_dest->GetPtr(); }
|
||||
};
|
||||
|
||||
extern bool pxParseAssignmentString( const wxString& src, wxString& ldest, wxString& rdest );
|
||||
|
|
|
@ -37,7 +37,7 @@ void* __fastcall pcsx2_aligned_malloc(size_t size, size_t align)
|
|||
uptr aligned = (pasthead + align-1) & ~(align-1);
|
||||
|
||||
AlignedMallocHeader* header = (AlignedMallocHeader*)(aligned-headsize);
|
||||
jASSUME( (uptr)header >= (uptr)p );
|
||||
pxAssume( (uptr)header >= (uptr)p );
|
||||
|
||||
header->baseptr = p;
|
||||
header->size = size;
|
||||
|
|
|
@ -298,7 +298,7 @@ const IConsoleWriter ConsoleWriter_wxError =
|
|||
};
|
||||
|
||||
// =====================================================================================================
|
||||
// IConsoleWriter Implementations
|
||||
// IConsoleWriter (implementations)
|
||||
// =====================================================================================================
|
||||
// (all non-virtual members that do common work and then pass the result through DoWrite
|
||||
// or DoWriteLn)
|
||||
|
@ -569,14 +569,14 @@ const NullConsoleWriter NullCon = {};
|
|||
bool ConsoleLogSource::WriteV( ConsoleColors color, const char *fmt, va_list list ) const
|
||||
{
|
||||
ConsoleColorScope cs(color);
|
||||
DoWrite( pxsFmtV(fmt,list).GetResult() );
|
||||
DoWrite( pxsFmtV(fmt,list).c_str() );
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ConsoleLogSource::WriteV( ConsoleColors color, const wxChar *fmt, va_list list ) const
|
||||
{
|
||||
ConsoleColorScope cs(color);
|
||||
DoWrite( pxsFmtV(fmt,list) );
|
||||
DoWrite( pxsFmtV(fmt,list).c_str() );
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -49,21 +49,20 @@ pxDoAssertFnType* pxDoAssert = pxAssertImpl_LogIt;
|
|||
// response times from the Output window...
|
||||
wxString DiagnosticOrigin::ToString( const wxChar* msg ) const
|
||||
{
|
||||
wxString message;
|
||||
message.reserve( 2048 );
|
||||
FastFormatUnicode message;
|
||||
|
||||
message.Printf( L"%s(%d) : assertion failed:\n", srcfile, line );
|
||||
message.Write( L"%s(%d) : assertion failed:\n", srcfile, line );
|
||||
|
||||
if( function != NULL )
|
||||
message += L" Function: " + fromUTF8(function) + L"\n";
|
||||
message.Write( " Function: %s\n", function );
|
||||
|
||||
message += L" Thread: " + Threading::pxGetCurrentThreadName() + L"\n";
|
||||
message.Write(L" Thread: %s\n", Threading::pxGetCurrentThreadName().c_str() );
|
||||
|
||||
if( condition != NULL )
|
||||
message += L" Condition: " + wxString(condition) + L"\n";
|
||||
message.Write(L" Condition: %s\n", condition);
|
||||
|
||||
if( msg != NULL )
|
||||
message += L" Message: " + wxString(msg) + L"\n";
|
||||
message.Write(L" Message: %s\n", msg);
|
||||
|
||||
return message;
|
||||
}
|
||||
|
|
|
@ -47,7 +47,7 @@ class FastFormatBuffers
|
|||
protected:
|
||||
typedef SafeAlignedArray<CharType,16> BufferType;
|
||||
|
||||
static const uint BufferCount = 3;
|
||||
static const uint BufferCount = 4;
|
||||
|
||||
BufferType m_buffers[BufferCount];
|
||||
uint m_curslot;
|
||||
|
@ -64,7 +64,7 @@ public:
|
|||
m_buffers[i].Name = wxsFormat(L"%s Formatting Buffer (slot%d)",
|
||||
(sizeof(CharType)==1) ? L"Ascii" : L"Unicode", i);
|
||||
m_buffers[i].MakeRoomFor(1024);
|
||||
m_buffers[i].ChunkSize = 4096;
|
||||
m_buffers[i].ChunkSize = 2048;
|
||||
}
|
||||
|
||||
m_curslot = 0;
|
||||
|
@ -77,7 +77,7 @@ public:
|
|||
|
||||
bool HasFreeBuffer() const
|
||||
{
|
||||
return m_curslot < BufferCount;
|
||||
return m_curslot < BufferCount-1;
|
||||
}
|
||||
|
||||
BufferType& GrabBuffer()
|
||||
|
@ -176,7 +176,7 @@ static __ri void format_that_unicode_mess( SafeArray<char>& buffer, uint writepo
|
|||
while( true )
|
||||
{
|
||||
int size = buffer.GetLength() / sizeof(wxChar);
|
||||
int len = wxVsnprintf((wxChar*)buffer.GetPtr(writepos), size-writepos, fmt, argptr);
|
||||
int len = wxVsnprintf((wxChar*)buffer.GetPtr(writepos*2), size-writepos, fmt, argptr);
|
||||
|
||||
|
||||
// some implementations of vsnprintf() don't NUL terminate
|
||||
|
@ -267,12 +267,11 @@ FastFormatUnicode& FastFormatUnicode::Write( const wxChar* fmt, ... )
|
|||
return *this;
|
||||
}
|
||||
|
||||
const wxChar* FastFormatUnicode::GetResult() const
|
||||
bool FastFormatUnicode::IsEmpty() const
|
||||
{
|
||||
return (wxChar*)m_dest->GetPtr();
|
||||
return ((wxChar&)(*m_dest)[0]) == 0;
|
||||
}
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// FastFormatAscii (implementations)
|
||||
// --------------------------------------------------------------------------------------
|
||||
|
@ -295,10 +294,10 @@ const wxString FastFormatAscii::GetString() const
|
|||
return fromAscii(m_dest->GetPtr());
|
||||
}
|
||||
|
||||
FastFormatAscii::operator wxString() const
|
||||
/*FastFormatAscii::operator wxString() const
|
||||
{
|
||||
return fromAscii(m_dest->GetPtr());
|
||||
}
|
||||
}*/
|
||||
|
||||
FastFormatAscii& FastFormatAscii::WriteV( const char* fmt, va_list argptr )
|
||||
{
|
||||
|
@ -315,13 +314,8 @@ FastFormatAscii& FastFormatAscii::Write( const char* fmt, ... )
|
|||
return *this;
|
||||
}
|
||||
|
||||
const char* FastFormatAscii::GetResult() const
|
||||
{
|
||||
return m_dest->GetPtr();
|
||||
}
|
||||
|
||||
FastFormatAscii::operator const char*() const
|
||||
bool FastFormatAscii::IsEmpty() const
|
||||
{
|
||||
return m_dest->GetPtr();
|
||||
return (*m_dest)[0] == 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -253,11 +253,13 @@ Threading::ScopedLock::~ScopedLock() throw()
|
|||
|
||||
Threading::ScopedLock::ScopedLock( const Mutex* locker )
|
||||
{
|
||||
m_IsLocked = false;
|
||||
AssignAndLock( locker );
|
||||
}
|
||||
|
||||
Threading::ScopedLock::ScopedLock( const Mutex& locker )
|
||||
{
|
||||
m_IsLocked = false;
|
||||
AssignAndLock( locker );
|
||||
}
|
||||
|
||||
|
@ -268,6 +270,8 @@ void Threading::ScopedLock::AssignAndLock( const Mutex& locker )
|
|||
|
||||
void Threading::ScopedLock::AssignAndLock( const Mutex* locker )
|
||||
{
|
||||
pxAssume(!m_IsLocked); // if we're already locked, changing the lock is bad mojo.
|
||||
|
||||
m_lock = const_cast<Mutex*>(locker);
|
||||
if( !m_lock ) return;
|
||||
|
||||
|
|
|
@ -35,6 +35,42 @@ __fi wxString fromAscii( const char* src )
|
|||
return wxString::FromAscii( src );
|
||||
}
|
||||
|
||||
wxString u128::ToString() const
|
||||
{
|
||||
return pxsFmt( L"0x%08X.%08X.%08X.%08X", _u32[0], _u32[1], _u32[2], _u32[3] );
|
||||
}
|
||||
|
||||
wxString u128::ToString64() const
|
||||
{
|
||||
return pxsFmt( L"0x%08X%08X.%08X%08X", _u32[0], _u32[1], _u32[2], _u32[3] );
|
||||
}
|
||||
|
||||
wxString u128::ToString8() const
|
||||
{
|
||||
FastFormatUnicode result;
|
||||
result.Write( L"0x%02X.%02X", _u8[0], _u8[1] );
|
||||
for (uint i=2; i<16; i+=2)
|
||||
result.Write( L".%02X.%02X", _u8[i], _u8[i+1] );
|
||||
return result;
|
||||
}
|
||||
|
||||
void u128::WriteTo( FastFormatAscii& dest ) const
|
||||
{
|
||||
dest.Write( "0x%08X.%08X.%08X.%08X", _u32[0], _u32[1], _u32[2], _u32[3] );
|
||||
}
|
||||
|
||||
void u128::WriteTo64( FastFormatAscii& dest ) const
|
||||
{
|
||||
dest.Write( "0x%08X%08X.%08X%08X", _u32[0], _u32[1], _u32[2], _u32[3] );
|
||||
}
|
||||
|
||||
void u128::WriteTo8( FastFormatAscii& dest ) const
|
||||
{
|
||||
dest.Write( "0x%02X.%02X", _u8[0], _u8[1] );
|
||||
for (uint i=2; i<16; i+=2)
|
||||
dest.Write( ".%02X.%02X", _u8[i], _u8[i+1] );
|
||||
}
|
||||
|
||||
// Splits a string into parts and adds the parts into the given SafeList.
|
||||
// This list is not cleared, so concatenating many splits into a single large list is
|
||||
// the 'default' behavior, unless you manually clear the SafeList prior to subsequent calls.
|
||||
|
|
|
@ -1,19 +1,19 @@
|
|||
pcsx2 for debian
|
||||
=========================
|
||||
|
||||
* This version have some majors modification against default upstream
|
||||
* This version has some major modifications against the default upstream version.
|
||||
-> documents are stored in $XDG_CONFIG_HOME instead of $HOME/pcsx2
|
||||
-> some features was removed to compile against libsound 1.3. Pcsx2
|
||||
needs the version 1.5
|
||||
-> some features were removed so it could compile against libsound 1.3.
|
||||
Pcsx2 needs at least soundtouch 1.5.
|
||||
|
||||
* This package is highly experimental.
|
||||
|
||||
* Documentation needs some loves. Feel free to help.
|
||||
* Documentation needs some love. Feel free to help.
|
||||
|
||||
* -fPIC option was removed for multiple reason.
|
||||
- Code only support x86 architecture.
|
||||
- Upstream code use ebx register so it is not compliant with PIC.
|
||||
- Impact too much performance.
|
||||
- only plugins so no others package link against us.
|
||||
- Upstream code uses the ebx register so it's not compliant with PIC.
|
||||
- Impacts the performance too much.
|
||||
- Only plugins. No package will link to them.
|
||||
|
||||
-- Gregory Hainaut <gregory.hainaut@gmail.com> Sat, 24 Apr 2010 23:11:10 +0200
|
||||
|
|
|
@ -2,6 +2,7 @@ Source: pcsx2.snapshot
|
|||
Section: games
|
||||
Priority: optional
|
||||
Maintainer: Gregory Hainaut <gregory.hainaut@gmail.com>
|
||||
# WARNING we need dpkg-dev 1.15.7 to support dpkg-buildflags but ubunutu 10.04 have only 1.15.5.6...
|
||||
Build-Depends: debhelper (>= 7.0.50), dpkg-dev (>= 1.15.5.6), cmake (>=2.8),
|
||||
gcc-multilib [amd64], g++-multilib [amd64],
|
||||
zlib1g-dev (>= 1:1.2.3.3) | lib32z1-dev (>= 1.2.3.3) [amd64],
|
||||
|
@ -28,22 +29,23 @@ Build-Depends: debhelper (>= 7.0.50), dpkg-dev (>= 1.15.5.6), cmake (>=2.8),
|
|||
# nvidia-cg-toolkit (>= 2.1.0017.deb1) | nvidia-cg-toolkit (>= 2.1.0017.deb1+nmu2) [amd64],
|
||||
nvidia-cg-toolkit-pcsx2 | nvidia-cg-toolkit (>= 2.1), ia32-nvidia-cg-toolkit-pcsx2 [amd64],
|
||||
ia32-libs (>= 20090808+nmu7) [amd64], ia32-libs-gtk (= 20100503+local1) [amd64]
|
||||
Standards-Version: 3.9.0
|
||||
Standards-Version: 3.9.1
|
||||
Homepage: http://pcsx2.net/
|
||||
|
||||
Package: pcsx2-unstable
|
||||
# Warning amd64 need additional ia32libs
|
||||
Architecture: i386 amd64
|
||||
Depends: ${shlibs:Depends}, ${misc:Depends}, pcsx2-data-unstable (>= ${binary:Version}), pcsx2-plugins-unstable (>= ${binary:Version})
|
||||
Conflicts: pcsx2
|
||||
Depends: ${shlibs:Depends}, ${misc:Depends},
|
||||
pcsx2-data-unstable (>= ${binary:Version}),
|
||||
pcsx2-plugins-unstable (>= ${binary:Version})
|
||||
Conflicts: pcsx2
|
||||
Description: Playstation 2 emulator
|
||||
PCSX2 is a PlayStation 2 emulator for Windows and
|
||||
Linux, started by the same team that brought you PCSX
|
||||
(a Sony PlayStation 1 emulator).
|
||||
PCSX2 is a PlayStation 2 emulator for Windows and Linux, started by the same
|
||||
team that brought you PCSX (a Sony PlayStation 1 emulator).
|
||||
.
|
||||
WARNING: it requieres a CPU with sse2 instructions. If your
|
||||
CPU does not support this instruction set, it does not have
|
||||
enough horse power to run this emulator anyway.
|
||||
WARNING: It requires a CPU with SSE2 instructions. If your CPU does not support
|
||||
this instruction set, it does not have enough horse power to run this emulator
|
||||
anyway.
|
||||
.
|
||||
This package includes the main binary file.
|
||||
|
||||
|
@ -54,34 +56,33 @@ Depends: ${misc:Depends}
|
|||
Recommends: pcsx2-unstable (>= ${binary:Version}), pcsx2-plugins-unstable (>= ${binary:Version})
|
||||
Conflicts: pcsx2-data
|
||||
Description: data for pcsx2
|
||||
PCSX2 is a PlayStation 2 emulator for Windows and
|
||||
Linux, started by the same team that brought you PCSX
|
||||
(a Sony PlayStation 1 emulator).
|
||||
PCSX2 is a PlayStation 2 emulator for Windows and Linux, started by the same
|
||||
team that brought you PCSX (a Sony PlayStation 1 emulator).
|
||||
.
|
||||
WARNING: it requieres a CPU with sse2 instructions. If your
|
||||
CPU does not support this instruction set, it does not have
|
||||
enough horse power to run this emulator anyway.
|
||||
WARNING: It requires a CPU with SSE2 instructions. If your CPU does not support
|
||||
this instruction set, it does not have enough horse power to run this emulator
|
||||
anyway.
|
||||
.
|
||||
This package includes data files.
|
||||
|
||||
Package: pcsx2-plugins-unstable
|
||||
# Warning amd64 need additional ia32libs
|
||||
Architecture: i386 amd64
|
||||
Depends: ${shlibs:Depends}, ${misc:Depends}
|
||||
Recommends: pcsx2-unstable (>= ${binary:Version}), pcsx2-data-unstable (>= ${binary:Version}),
|
||||
# manually add nvidia-cg-toolkit for zzogl. Do not why is not found by shlibs !!!
|
||||
Depends: ${shlibs:Depends}, ${misc:Depends},
|
||||
nvidia-cg-toolkit-pcsx2 | nvidia-cg-toolkit (>= 2.1), ia32-nvidia-cg-toolkit-pcsx2 [amd64]
|
||||
Recommends: pcsx2-unstable (>= ${binary:Version}),
|
||||
pcsx2-data-unstable (>= ${binary:Version})
|
||||
Conflicts: pcsx2-plugins
|
||||
Description: Various plugins for pcsx2
|
||||
PCSX2 is a PlayStation 2 emulator for Windows and
|
||||
Linux, started by the same team that brought you PCSX
|
||||
(a Sony PlayStation 1 emulator).
|
||||
PCSX2 is a PlayStation 2 emulator for Windows and Linux, started by the same
|
||||
team that brought you PCSX (a Sony PlayStation 1 emulator).
|
||||
.
|
||||
WARNING: it requieres a CPU with sse2 instructions. If your
|
||||
CPU does not support this instruction set, it does not have
|
||||
enough horse power to run this emulator anyway.
|
||||
WARNING: It requires a CPU with SSE2 instructions. If your CPU does not support
|
||||
this instruction set, it does not have enough horse power to run this emulator
|
||||
anyway.
|
||||
.
|
||||
This package includes the plugins of the emulator.
|
||||
This package includes the plugins for PCSX2.
|
||||
|
||||
Package: pcsx2-unstable-dbg
|
||||
Section: debug
|
||||
|
@ -91,9 +92,12 @@ Architecture: i386 amd64
|
|||
Depends: ${misc:Depends}, pcsx2-unstable (= ${binary:Version})
|
||||
Conflicts: pcsx2-dbg
|
||||
Description: Debug symbols for pcsx2
|
||||
PCSX2 is a PlayStation 2 emulator for Windows and
|
||||
Linux, started by the same team that brought you PCSX
|
||||
(a Sony PlayStation 1 emulator).
|
||||
PCSX2 is a PlayStation 2 emulator for Windows and Linux, started by the same
|
||||
team that brought you PCSX (a Sony PlayStation 1 emulator).
|
||||
.
|
||||
WARNING: It requires a CPU with SSE2 instructions. If your CPU does not support
|
||||
this instruction set, it does not have enough horse power to run this emulator
|
||||
anyway.
|
||||
.
|
||||
This package contains the debug symbol of pcsx2.
|
||||
|
||||
|
@ -104,9 +108,12 @@ Priority: extra
|
|||
Architecture: i386 amd64
|
||||
Depends: ${misc:Depends}, pcsx2-plugins-unstable (= ${binary:Version})
|
||||
Conflicts: pcsx2-plugins-dbg
|
||||
Description: Debug symbols for pcsx2-plugins
|
||||
PCSX2 is a PlayStation 2 emulator for Windows and
|
||||
Linux, started by the same team that brought you PCSX
|
||||
(a Sony PlayStation 1 emulator).
|
||||
Description: Debug symbols of the pcsx2-plugins
|
||||
PCSX2 is a PlayStation 2 emulator for Windows and Linux, started by the same
|
||||
team that brought you PCSX (a Sony PlayStation 1 emulator).
|
||||
.
|
||||
This package contains the debug symbol of pcsx2 plugins.
|
||||
WARNING: It requires a CPU with SSE2 instructions. If your CPU does not support
|
||||
this instruction set, it does not have enough horse power to run this emulator
|
||||
anyway.
|
||||
.
|
||||
This package contains the debug symbols of the pcsx2 plugins.
|
||||
|
|
|
@ -24,21 +24,22 @@ Build-Depends: debhelper (>= 7.0.50), dpkg-dev (>= 1.15.5.6), cmake (>=2.8),
|
|||
libgl1-mesa-dev,
|
||||
libglu1-mesa-dev,
|
||||
nvidia-cg-toolkit-pcsx2
|
||||
Standards-Version: 3.9.0
|
||||
Standards-Version: 3.9.1
|
||||
Homepage: http://pcsx2.net/
|
||||
|
||||
Package: pcsx2-unstable
|
||||
Architecture: i386
|
||||
Depends: ${shlibs:Depends}, ${misc:Depends}, pcsx2-data-unstable (>= ${binary:Version}), pcsx2-plugins-unstable (>= ${binary:Version})
|
||||
Depends: ${shlibs:Depends}, ${misc:Depends},
|
||||
pcsx2-data-unstable (>= ${binary:Version}),
|
||||
pcsx2-plugins-unstable (>= ${binary:Version})
|
||||
Conflicts: pcsx2
|
||||
Description: Playstation 2 emulator
|
||||
PCSX2 is a PlayStation 2 emulator for Windows and
|
||||
Linux, started by the same team that brought you PCSX
|
||||
(a Sony PlayStation 1 emulator).
|
||||
PCSX2 is a PlayStation 2 emulator for Windows and Linux, started by the same
|
||||
team that brought you PCSX (a Sony PlayStation 1 emulator).
|
||||
.
|
||||
WARNING: it requieres a CPU with sse2 instructions. If your
|
||||
CPU does not support this instruction set, it does not have
|
||||
enough horse power to run this emulator anyway.
|
||||
WARNING: It requires a CPU with SSE2 instructions. If your CPU does not support
|
||||
this instruction set, it does not have enough horse power to run this emulator
|
||||
anyway.
|
||||
.
|
||||
This package includes the main binary file.
|
||||
|
||||
|
@ -49,33 +50,32 @@ Depends: ${misc:Depends}
|
|||
Recommends: pcsx2-unstable (>= ${binary:Version}), pcsx2-plugins-unstable (>= ${binary:Version})
|
||||
Conflicts: pcsx2-data
|
||||
Description: data for pcsx2
|
||||
PCSX2 is a PlayStation 2 emulator for Windows and
|
||||
Linux, started by the same team that brought you PCSX
|
||||
(a Sony PlayStation 1 emulator).
|
||||
PCSX2 is a PlayStation 2 emulator for Windows and Linux, started by the same
|
||||
team that brought you PCSX (a Sony PlayStation 1 emulator).
|
||||
.
|
||||
WARNING: it requieres a CPU with sse2 instructions. If your
|
||||
CPU does not support this instruction set, it does not have
|
||||
enough horse power to run this emulator anyway.
|
||||
WARNING: It requires a CPU with SSE2 instructions. If your CPU does not support
|
||||
this instruction set, it does not have enough horse power to run this emulator
|
||||
anyway.
|
||||
.
|
||||
This package includes data files.
|
||||
|
||||
Package: pcsx2-plugins-unstable
|
||||
Architecture: i386
|
||||
Depends: ${shlibs:Depends}, ${misc:Depends}
|
||||
Recommends: pcsx2-unstable (>= ${binary:Version}), pcsx2-data-unstable (>= ${binary:Version}),
|
||||
# manually add nvidia-cg-toolkit for zzogl. Do not why is not found by shlibs !!!
|
||||
Depends: ${shlibs:Depends}, ${misc:Depends},
|
||||
nvidia-cg-toolkit-pcsx2 | nvidia-cg-toolkit (>= 2.1)
|
||||
Recommends: pcsx2-unstable (>= ${binary:Version}),
|
||||
pcsx2-data-unstable (>= ${binary:Version})
|
||||
Conflicts: pcsx2-plugins
|
||||
Description: Various plugins for pcsx2
|
||||
PCSX2 is a PlayStation 2 emulator for Windows and
|
||||
Linux, started by the same team that brought you PCSX
|
||||
(a Sony PlayStation 1 emulator).
|
||||
PCSX2 is a PlayStation 2 emulator for Windows and Linux, started by the same
|
||||
team that brought you PCSX (a Sony PlayStation 1 emulator).
|
||||
.
|
||||
WARNING: it requieres a CPU with sse2 instructions. If your
|
||||
CPU does not support this instruction set, it does not have
|
||||
enough horse power to run this emulator anyway.
|
||||
WARNING: It requires a CPU with SSE2 instructions. If your CPU does not support
|
||||
this instruction set, it does not have enough horse power to run this emulator
|
||||
anyway.
|
||||
.
|
||||
This package includes the plugins of the emulator.
|
||||
This package includes the plugins for PCSX2.
|
||||
|
||||
Package: pcsx2-unstable-dbg
|
||||
Section: debug
|
||||
|
@ -84,9 +84,12 @@ Architecture: i386
|
|||
Depends: ${misc:Depends}, pcsx2-unstable (= ${binary:Version})
|
||||
Conflicts: pcsx2-dbg
|
||||
Description: Debug symbols for pcsx2
|
||||
PCSX2 is a PlayStation 2 emulator for Windows and
|
||||
Linux, started by the same team that brought you PCSX
|
||||
(a Sony PlayStation 1 emulator).
|
||||
PCSX2 is a PlayStation 2 emulator for Windows and Linux, started by the same
|
||||
team that brought you PCSX (a Sony PlayStation 1 emulator).
|
||||
.
|
||||
WARNING: It requires a CPU with SSE2 instructions. If your CPU does not support
|
||||
this instruction set, it does not have enough horse power to run this emulator
|
||||
anyway.
|
||||
.
|
||||
This package contains the debug symbol of pcsx2.
|
||||
|
||||
|
@ -96,9 +99,12 @@ Priority: extra
|
|||
Architecture: i386
|
||||
Depends: ${misc:Depends}, pcsx2-plugins-unstable (= ${binary:Version})
|
||||
Conflicts: pcsx2-plugins-dbg
|
||||
Description: Debug symbols for pcsx2-plugins
|
||||
PCSX2 is a PlayStation 2 emulator for Windows and
|
||||
Linux, started by the same team that brought you PCSX
|
||||
(a Sony PlayStation 1 emulator).
|
||||
Description: Debug symbols of the pcsx2-plugins
|
||||
PCSX2 is a PlayStation 2 emulator for Windows and Linux, started by the same
|
||||
team that brought you PCSX (a Sony PlayStation 1 emulator).
|
||||
.
|
||||
This package contains the debug symbol of pcsx2 plugins.
|
||||
WARNING: It requires a CPU with SSE2 instructions. If your CPU does not support
|
||||
this instruction set, it does not have enough horse power to run this emulator
|
||||
anyway.
|
||||
.
|
||||
This package contains the debug symbols of the pcsx2 plugins.
|
||||
|
|
|
@ -155,6 +155,8 @@ License: BSD (3 clause)
|
|||
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGE.
|
||||
|
||||
Files: plugins/zzogl-pg/opengl/ZeroGSShaders/* plugins/zzogl-pg/opengl/zpipe* plugins/zzogl-pg/opengl/zerogsmath.h plugins/zzogl-pg/opengl/memcpy_amd.cpp
|
||||
Copyright: Unknown
|
||||
|
||||
|
||||
The Debian packaging is:
|
||||
|
|
|
@ -4,28 +4,34 @@
|
|||
# it under the terms of the GNU Lesser General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
#
|
||||
# This package is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Lesser General Public License for more details.
|
||||
#
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
|
||||
######################################################################
|
||||
# Global Parameter
|
||||
# Global Parameters
|
||||
######################################################################
|
||||
# Svn parameter
|
||||
if [ -n "$1" ] ; then
|
||||
SVN_CO_VERSION=$1;
|
||||
else
|
||||
echo "Please provide the subversion version as fisrt parameter"
|
||||
echo "Please provide the subversion revision number as the first parameter"
|
||||
exit 1;
|
||||
fi
|
||||
SVN_TRUNK="http://pcsx2.googlecode.com/svn/trunk"
|
||||
if [ -n "$2" ] ; then
|
||||
# Use branch argument
|
||||
SVN_TRUNK="http://pcsx2.googlecode.com/svn/branches/$2"
|
||||
else
|
||||
# by default take the trunk
|
||||
SVN_TRUNK="http://pcsx2.googlecode.com/svn/trunk"
|
||||
fi
|
||||
|
||||
# Debian name of package and tarball
|
||||
PKG_NAME="pcsx2.snapshot-${SVN_CO_VERSION}"
|
||||
|
@ -38,7 +44,7 @@ NEW_DIR=${TMP_DIR}/$PKG_NAME
|
|||
|
||||
|
||||
######################################################################
|
||||
# Basic function
|
||||
# Basic functions
|
||||
######################################################################
|
||||
get_svn_dir()
|
||||
{
|
||||
|
@ -58,8 +64,8 @@ get_svn_file()
|
|||
{
|
||||
for file in $* ; do
|
||||
if [ ! -e `basename ${file}` ] ; then
|
||||
# Versionning information are not support for a single file
|
||||
# so you can not use svn co
|
||||
# Versioning information is not supported for a single file
|
||||
# therefore you can't use svn co
|
||||
svn export --quiet ${SVN_TRUNK}/${file} -r $SVN_CO_VERSION;
|
||||
fi
|
||||
done
|
||||
|
@ -69,8 +75,8 @@ get_svn_file()
|
|||
# Main script
|
||||
######################################################################
|
||||
|
||||
## Download the svn repository (only the usefull things)
|
||||
echo "Download pcsx2 source rev ${SVN_CO_VERSION}"
|
||||
## Download the svn repository (only the useful things)
|
||||
echo "Downloading pcsx2 source revision ${SVN_CO_VERSION}"
|
||||
mkdir -p $ROOT_DIR;
|
||||
(cd $ROOT_DIR;
|
||||
get_svn_file CMakeLists.txt;
|
||||
|
@ -78,7 +84,8 @@ mkdir -p $ROOT_DIR;
|
|||
get_svn_dir debian-unstable-upstream;
|
||||
echo "Done")
|
||||
|
||||
echo "Donwload Linux compatible plugins ${SVN_CO_VERSION}"
|
||||
echo "Downloading Linux compatible plugins for revision ${SVN_CO_VERSION}"
|
||||
# Note: Other plugins exist but they are not 100% copyright free.
|
||||
mkdir -p $ROOT_DIR/plugins
|
||||
(cd $ROOT_DIR/plugins;
|
||||
get_svn_file plugins/CMakeLists.txt;
|
||||
|
@ -98,14 +105,14 @@ echo "Note: some plugins are more or less deprecated CDVDisoEFP, CDVDlinuz, Zero
|
|||
echo "Done")
|
||||
|
||||
## Installation
|
||||
echo "Copy the subversion repository in a tmp directory"
|
||||
echo "Copy the subversion repository to a temporary directory"
|
||||
# Copy the dir
|
||||
rm -fr $NEW_DIR
|
||||
cp -r $ROOT_DIR $NEW_DIR
|
||||
|
||||
echo "Remove .svn file"
|
||||
echo "Remove .svn directories"
|
||||
find $NEW_DIR -name ".svn" -type d -exec rm -fr {} \; 2> /dev/null
|
||||
echo "Remove old build system (script and autotools)"
|
||||
echo "Remove old build system (scripts and autotools)"
|
||||
find $NEW_DIR -name "build.sh" -exec rm -f {} \;
|
||||
find $NEW_DIR -name "install-sh" -exec rm -f {} \;
|
||||
find $NEW_DIR -name "depcomp" -exec rm -f {} \;
|
||||
|
@ -113,22 +120,25 @@ find $NEW_DIR -name "missing" -exec rm -f {} \;
|
|||
find $NEW_DIR -name "aclocal.m4" -exec rm -f {} \;
|
||||
find $NEW_DIR -name "configure.ac" -exec rm -f {} \;
|
||||
find $NEW_DIR -name "Makefile.am" -exec rm -f {} \;
|
||||
echo "Remove 3rd party directory"
|
||||
echo "Remove 3rd party directories"
|
||||
find $NEW_DIR -name "3rdparty" -exec rm -fr {} \; 2> /dev/null
|
||||
# I really need to clean this mess one day
|
||||
# echo "Remove plugins/zzogl-pg/opengl/ZeroGSShaders (some zlib source in the middle)"
|
||||
# rm -fr $NEW_DIR/plugins/zzogl-pg/opengl/ZeroGSShaders
|
||||
echo "Remove windows file (useless & copyright issue)"
|
||||
find $NEW_DIR -iname "windows" -exec rm -fr {} \; 2> /dev/null
|
||||
find $NEW_DIR -iname "windows" -type d -exec rm -fr {} \; 2> /dev/null
|
||||
find $NEW_DIR -name "Win32" -type d -exec rm -fr {} \; 2> /dev/null
|
||||
rm -fr "${NEW_DIR}/plugins/zzogl-pg/opengl/Win32"
|
||||
rm -fr "${NEW_DIR}/tools/GSDumpGUI"
|
||||
rm -fr "${NEW_DIR}/common/vsprops"
|
||||
echo "Remove useless file (copyright issue)"
|
||||
echo "Remove useless files (copyright issues)"
|
||||
rm -fr "${NEW_DIR}/plugins/zzogl-pg/opengl/ZeroGSShaders/zlib"
|
||||
rm -fr "${NEW_DIR}/common/src/Utilities/x86/MemcpyFast.cpp"
|
||||
rm -fr "${NEW_DIR}/plugins/CDVDnull/Linux"
|
||||
|
||||
|
||||
## BUILD
|
||||
echo "Build the tar gz file"
|
||||
tar -C ${TMP_DIR} -czf ${TAR_NAME}.gz $PKG_NAME
|
||||
echo "Build the tar.gz file"
|
||||
tar -C $TMP_DIR -czf ${TAR_NAME}.gz $PKG_NAME
|
||||
|
||||
## Clean
|
||||
rm -fr $NEW_DIR
|
||||
rm -fr $ROOT_DIR
|
||||
|
|
|
@ -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
|
||||
05_move_data_to_config.patch
|
||||
21_use_legacy_soundtouch_13.patch
|
||||
# Personnal patch that need advance testing
|
||||
#55_cmake_opt_clean.patch
|
||||
#56_cmake_enable_opt1.patch
|
||||
#57_cmake_enable_opt2.patch
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
# PIC code cause regression in the library and issue with the ebx register.
|
||||
# Morever library are plugins and the code is only compatible with x86.
|
||||
#* -fPIC option was removed for multiple reason.
|
||||
# - Code only support x86 architecture.
|
||||
# - Upstream code uses the ebx register so it's not compliant with PIC.
|
||||
# - Impacts the performance too much.
|
||||
# - Only plugins. No package will link to them.
|
||||
pcsx2-plugins-unstable: shlib-with-non-pic-code
|
||||
|
|
|
@ -1 +1,3 @@
|
|||
bin/pcsx2 usr/games
|
||||
debian/pcsx2.desktop usr/share/applications
|
||||
debian/pcsx2.xpm usr/share/pixmaps
|
||||
|
|
|
@ -41,9 +41,9 @@ clean:
|
|||
dh_testroot
|
||||
rm -f build-stamp
|
||||
|
||||
# Backup some orig makefile if it not already done
|
||||
# I hope some will be delete by upstream when cmake port is over
|
||||
# Note in case we do not dl all plugins the test [ -f $${makefile} ] ensure the working
|
||||
# Backup some orig makefile if it's not already done.
|
||||
# I hope that some will be delete by upstream when the cmake port is over.
|
||||
# Note: In case that we do not dl all the plugins, the test [ -f $${makefile} ] ensures it works
|
||||
for makefile in plugins/CDVDlinuz/Src/Linux/Makefile \
|
||||
plugins/CDVDiso/src/Linux/Makefile \
|
||||
plugins/CDVDiso/src/Windows/Makefile \
|
||||
|
@ -53,13 +53,13 @@ clean:
|
|||
plugins/CDVDisoEFP/src/Linux/Makefile ; do \
|
||||
[ -f $${makefile}.orig ] || ( [ -f $${makefile} ] && mv $${makefile} $${makefile}.orig ) || true ; done
|
||||
|
||||
# Add here commands to clean up after the build process.
|
||||
# Add here the commands to clean up after the build process.
|
||||
[ -f Makefile ] && $(MAKE) clean || true
|
||||
# Remove cmake stuff
|
||||
rm -fr $$(find . -type d -name CMakeFiles)
|
||||
rm -f $$(find . -type f -name CMakeCache.txt) $$(find . -type f -name cmake_install.cmake)
|
||||
rm -f $$(find . -type f -name Makefile)
|
||||
# File generated by bin2cpp
|
||||
# Files generated by bin2cpp
|
||||
cd pcsx2/gui/Resources/ && rm -f App*.h Config*.h BackgroundLogo.h ButtonIcon_Camera.h Dualshock.h
|
||||
# leftover of cmake
|
||||
rm -f bin/plugins/ps2hw.dat
|
||||
|
@ -69,62 +69,15 @@ clean:
|
|||
|
||||
dh_clean
|
||||
|
||||
install:
|
||||
install: build
|
||||
dh_testdir
|
||||
dh_testroot
|
||||
dh_prep
|
||||
dh_installdirs
|
||||
## Uncomment this, if fglrx driver is installed
|
||||
#override_dh_shlibdeps:
|
||||
# dh_shlibdeps -- --ignore-missing-info
|
||||
|
||||
### the project build usefull thing in ./bin so directly install
|
||||
### from this directory to the debian pkg directory (skip debian/tmp)
|
||||
# Ubuntu use debian/tmp as default sourcedir...
|
||||
# copy bin into debian tmp
|
||||
mkdir -p debian/tmp
|
||||
cp -fr bin debian/tmp
|
||||
dh_install --sourcedir=debian/tmp
|
||||
|
||||
# install menu and icon
|
||||
cp debian/pcsx2.desktop debian/pcsx2-unstable/usr/share/applications
|
||||
cp debian/pcsx2.xpm debian/pcsx2-unstable/usr/share/pixmaps
|
||||
|
||||
# lintian override
|
||||
dh_lintian
|
||||
|
||||
# Build architecture-independent files here.
|
||||
binary-indep: build install
|
||||
dh_testdir -i
|
||||
dh_testroot -i
|
||||
dh_installchangelogs -i
|
||||
dh_installdocs -i
|
||||
dh_installman -i
|
||||
dh_link -i
|
||||
dh_compress -i
|
||||
dh_fixperms -i
|
||||
dh_installdeb -i
|
||||
dh_gencontrol -i
|
||||
dh_md5sums -i
|
||||
dh_builddeb -i
|
||||
|
||||
# Build architecture-dependent files here.
|
||||
binary-arch: build install
|
||||
dh_testdir -a
|
||||
dh_testroot -a
|
||||
dh_installchangelogs -a
|
||||
dh_installdocs -a
|
||||
dh_installmenu -a
|
||||
dh_installman -a
|
||||
override_dh_strip:
|
||||
dh_strip --package=pcsx2-unstable --dbg-package=pcsx2-unstable-dbg
|
||||
dh_strip --package=pcsx2-plugins-unstable --dbg-package=pcsx2-plugins-unstable-dbg
|
||||
dh_link -a
|
||||
dh_compress -a
|
||||
dh_fixperms -a
|
||||
dh_makeshlibs -a
|
||||
dh_installdeb -a
|
||||
dh_shlibdeps -a
|
||||
dh_gencontrol -a
|
||||
dh_md5sums -a
|
||||
dh_builddeb -a
|
||||
|
||||
binary: binary-indep binary-arch
|
||||
.PHONY: build clean binary-indep binary-arch binary install
|
||||
%:
|
||||
dh $@ --parallel
|
||||
|
||||
.PHONY: build clean install
|
||||
|
|
|
@ -41,9 +41,9 @@ clean:
|
|||
dh_testroot
|
||||
rm -f build-stamp
|
||||
|
||||
# Backup some orig makefile if it not already done
|
||||
# I hope some will be delete by upstream when cmake port is over
|
||||
# Note in case we do not dl all plugins the test [ -f $${makefile} ] ensure the working
|
||||
# Backup some orig makefile if it's not already done.
|
||||
# I hope that some will be delete by upstream when the cmake port is over.
|
||||
# Note: In case that we do not dl all the plugins, the test [ -f $${makefile} ] ensures it works
|
||||
for makefile in plugins/CDVDlinuz/Src/Linux/Makefile \
|
||||
plugins/CDVDiso/src/Linux/Makefile \
|
||||
plugins/CDVDiso/src/Windows/Makefile \
|
||||
|
@ -53,13 +53,13 @@ clean:
|
|||
plugins/CDVDisoEFP/src/Linux/Makefile ; do \
|
||||
[ -f $${makefile}.orig ] || ( [ -f $${makefile} ] && mv $${makefile} $${makefile}.orig ) || true ; done
|
||||
|
||||
# Add here commands to clean up after the build process.
|
||||
# Add here the commands to clean up after the build process.
|
||||
[ -f Makefile ] && $(MAKE) clean || true
|
||||
# Remove cmake stuff
|
||||
rm -fr $$(find . -type d -name CMakeFiles)
|
||||
rm -f $$(find . -type f -name CMakeCache.txt) $$(find . -type f -name cmake_install.cmake)
|
||||
rm -f $$(find . -type f -name Makefile)
|
||||
# File generated by bin2cpp
|
||||
# Files generated by bin2cpp
|
||||
cd pcsx2/gui/Resources/ && rm -f App*.h Config*.h BackgroundLogo.h ButtonIcon_Camera.h Dualshock.h
|
||||
# leftover of cmake
|
||||
rm -f bin/plugins/ps2hw.dat
|
||||
|
@ -69,65 +69,15 @@ clean:
|
|||
|
||||
dh_clean
|
||||
|
||||
install:
|
||||
install: build
|
||||
dh_testdir
|
||||
dh_testroot
|
||||
dh_prep
|
||||
dh_installdirs
|
||||
# Allow compilation when fglrx is installed
|
||||
override_dh_shlibdeps:
|
||||
dh_shlibdeps -- --ignore-missing-info
|
||||
|
||||
### the project build usefull thing in ./bin so directly install
|
||||
### from this directory to the debian pkg directory (skip debian/tmp)
|
||||
# Ubuntu use debian/tmp as default sourcedir...
|
||||
# copy bin into debian tmp
|
||||
mkdir -p debian/tmp
|
||||
cp -fr bin debian/tmp
|
||||
dh_install --sourcedir=debian/tmp
|
||||
|
||||
# install menu and icon
|
||||
cp debian/pcsx2.desktop debian/pcsx2-unstable/usr/share/applications
|
||||
cp debian/pcsx2.xpm debian/pcsx2-unstable/usr/share/pixmaps
|
||||
|
||||
# lintian override
|
||||
dh_lintian
|
||||
|
||||
# Build architecture-independent files here.
|
||||
binary-indep: build install
|
||||
dh_testdir -i
|
||||
dh_testroot -i
|
||||
dh_installchangelogs -i
|
||||
dh_installdocs -i
|
||||
dh_installman -i
|
||||
dh_link -i
|
||||
dh_compress -i
|
||||
dh_fixperms -i
|
||||
dh_installdeb -i
|
||||
dh_gencontrol -i
|
||||
dh_md5sums -i
|
||||
dh_builddeb -i
|
||||
|
||||
# Build architecture-dependent files here.
|
||||
binary-arch: build install
|
||||
dh_testdir -a
|
||||
dh_testroot -a
|
||||
dh_installchangelogs -a
|
||||
dh_installdocs -a
|
||||
dh_installmenu -a
|
||||
dh_installman -a
|
||||
override_dh_strip:
|
||||
dh_strip --package=pcsx2-unstable --dbg-package=pcsx2-unstable-dbg
|
||||
dh_strip --package=pcsx2-plugins-unstable --dbg-package=pcsx2-plugins-unstable-dbg
|
||||
dh_link -a
|
||||
dh_compress -a
|
||||
dh_fixperms -a
|
||||
dh_makeshlibs -a
|
||||
dh_installdeb -a
|
||||
# XXX: WARNING to test the package on my system I must add the option (--exclude)
|
||||
# due to fglrx drivers modify libGL. It must be re-enable for final packaging
|
||||
# dh_shlibdeps -a
|
||||
dh_shlibdeps -a --exclude=libzzogl
|
||||
dh_gencontrol -a
|
||||
dh_md5sums -a
|
||||
dh_builddeb -a
|
||||
|
||||
binary: binary-indep binary-arch
|
||||
.PHONY: build clean binary-indep binary-arch binary install
|
||||
%:
|
||||
dh $@ --parallel
|
||||
|
||||
.PHONY: build clean install
|
||||
|
|
|
@ -6,5 +6,6 @@
|
|||
# Compulsory line, this is a version 3 file
|
||||
version=3
|
||||
|
||||
# Note upstream do not release source files. It advices to pick them from subversion
|
||||
# Note: Upstream does not release prepackaged source files.
|
||||
# It's adviced to get them from their subversion repository.
|
||||
# http://pcsx2.googlecode.com/files/Pcsx2-linux-beta-(.*).tar.gz
|
||||
|
|
|
@ -16,10 +16,6 @@
|
|||
#ifndef __CDVD_ISO_READER_H__
|
||||
#define __CDVD_ISO_READER_H__
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable:4018)
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "IopCommon.h"
|
||||
|
|
|
@ -137,7 +137,8 @@ isoFile *isoOpen(const char *filename)
|
|||
iso->handle = _openfile( iso->filename, O_RDONLY);
|
||||
if (iso->handle == NULL)
|
||||
{
|
||||
Console.Error("error loading %s", iso->filename);
|
||||
Console.Error("ISO loader: Cannot access %s", iso->filename);
|
||||
Console.Error(">> Make sure the iso file is not mounted in any disk emulation software! <<");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
|
@ -29,10 +29,6 @@
|
|||
|
||||
#define _FILE_OFFSET_BITS 64
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# pragma warning(disable:4018) // disable signed/unsigned mismatch error
|
||||
#endif
|
||||
|
||||
#include "IopCommon.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
|
|
@ -165,7 +165,6 @@ set(pcsx2Sources
|
|||
Vif_Codes.cpp
|
||||
Vif_Transfer.cpp
|
||||
Vif_Unpack.cpp
|
||||
Vif_Unpack.inl
|
||||
vtlb.cpp
|
||||
VU0.cpp
|
||||
VUmicro.cpp
|
||||
|
@ -226,6 +225,7 @@ set(pcsx2Headers
|
|||
Vif_Dma.h
|
||||
Vif.h
|
||||
Vif_Unpack.h
|
||||
Vif_Unpack.inl
|
||||
vtlb.h
|
||||
VUflags.h
|
||||
VUmicro.h
|
||||
|
@ -295,7 +295,6 @@ set(pcsx2GuiSources
|
|||
gui/Panels/BaseApplicableConfigPanel.cpp
|
||||
gui/Panels/MemoryCardListView.cpp
|
||||
gui/Dialogs/BaseConfigurationDialog.cpp
|
||||
gui/Dialogs/BaseConfigurationDialog.inl
|
||||
gui/Dialogs/BiosSelectorDialog.cpp
|
||||
gui/Dialogs/ConfirmationDialogs.cpp
|
||||
gui/Dialogs/CreateMemoryCardDialog.cpp
|
||||
|
@ -353,6 +352,7 @@ set(pcsx2GuiHeaders
|
|||
gui/AppGameDatabase.h
|
||||
gui/ConsoleLogger.h
|
||||
gui/CpuUsageProvider.h
|
||||
gui/Dialogs/BaseConfigurationDialog.inl
|
||||
gui/Dialogs/ConfigurationDialog.h
|
||||
gui/Dialogs/LogOptionsDialog.h
|
||||
gui/Dialogs/ModalPopups.h
|
||||
|
@ -371,6 +371,7 @@ set(pcsx2GuiHeaders
|
|||
set(pcsx2IPUSources
|
||||
IPU/IPU.cpp
|
||||
IPU/IPU_Fifo.cpp
|
||||
IPU/IPUdma.cpp
|
||||
IPU/mpeg2lib/Idct.cpp
|
||||
IPU/mpeg2lib/Mpeg.cpp
|
||||
IPU/yuv2rgb.cpp)
|
||||
|
@ -379,6 +380,7 @@ set(pcsx2IPUSources
|
|||
set(pcsx2IPUHeaders
|
||||
IPU/IPU.h
|
||||
IPU/IPU_Fifo.h
|
||||
IPU/IPUdma.h
|
||||
IPU/yuv2rgb.h)
|
||||
|
||||
# Linux sources
|
||||
|
@ -394,12 +396,15 @@ set(pcsx2LinuxHeaders
|
|||
set(pcsx2ps2Sources
|
||||
ps2/BiosTools.cpp
|
||||
ps2/GIFpath.cpp
|
||||
ps2/LegacyDmac.cpp
|
||||
ps2/Iop/IopHwRead.cpp
|
||||
ps2/Iop/IopHwWrite.cpp)
|
||||
|
||||
# ps2 headers
|
||||
set(pcsx2ps2Headers
|
||||
ps2/BiosTools.h
|
||||
ps2/eeHwTraceLog.inl
|
||||
ps2/HwInternal.h
|
||||
ps2/Iop/IopHw_Internal.h)
|
||||
|
||||
# RDebug sources
|
||||
|
@ -495,20 +500,6 @@ set(pcsx2x86Sources
|
|||
x86/ix86-32/iR5900Shift.cpp
|
||||
x86/ix86-32/iR5900Templates.cpp
|
||||
x86/ix86-32/recVTLB.cpp
|
||||
x86/microVU_Alloc.inl
|
||||
x86/microVU_Analyze.inl
|
||||
x86/microVU_Branch.inl
|
||||
x86/microVU_Clamp.inl
|
||||
x86/microVU_Compile.inl
|
||||
x86/microVU.cpp
|
||||
x86/microVU_Execute.inl
|
||||
x86/microVU_Flags.inl
|
||||
x86/microVU_Log.inl
|
||||
x86/microVU_Lower.inl
|
||||
x86/microVU_Macro.inl
|
||||
x86/microVU_Misc.inl
|
||||
x86/microVU_Tables.inl
|
||||
x86/microVU_Upper.inl
|
||||
x86/newVif_Dynarec.cpp
|
||||
x86/newVif_Unpack.cpp
|
||||
x86/newVif_UnpackSSE.cpp
|
||||
|
@ -538,6 +529,20 @@ set(pcsx2x86Headers
|
|||
x86/microVU.h
|
||||
x86/microVU_IR.h
|
||||
x86/microVU_Misc.h
|
||||
x86/microVU_Alloc.inl
|
||||
x86/microVU_Analyze.inl
|
||||
x86/microVU_Branch.inl
|
||||
x86/microVU_Clamp.inl
|
||||
x86/microVU_Compile.inl
|
||||
x86/microVU.cpp
|
||||
x86/microVU_Execute.inl
|
||||
x86/microVU_Flags.inl
|
||||
x86/microVU_Log.inl
|
||||
x86/microVU_Lower.inl
|
||||
x86/microVU_Macro.inl
|
||||
x86/microVU_Misc.inl
|
||||
x86/microVU_Tables.inl
|
||||
x86/microVU_Upper.inl
|
||||
x86/newVif.h
|
||||
x86/newVif_BlockBuffer.h
|
||||
x86/newVif_HashBucket.h
|
||||
|
|
|
@ -428,7 +428,7 @@ void MTC0()
|
|||
}
|
||||
|
||||
int CPCOND0() {
|
||||
return ((dmacRegs->stat.CIS | ~dmacRegs->pcr.CPC) == 0x3ff);
|
||||
return ((dmacRegs.stat.CIS | ~dmacRegs.pcr.CPC) == 0x3ff);
|
||||
}
|
||||
|
||||
//#define CPCOND0 1
|
||||
|
|
|
@ -17,12 +17,6 @@
|
|||
|
||||
#include "Pcsx2Defs.h"
|
||||
|
||||
static const s64 _1mb = 0x100000;
|
||||
static const s64 _8mb = _1mb * 8;
|
||||
static const s64 _16mb = _1mb * 16;
|
||||
static const s64 _256mb = _1mb * 256;
|
||||
static const s64 _1gb = _256mb * 4;
|
||||
|
||||
static const u32 BIAS = 2; // Bus is half of the actual ps2 speed
|
||||
static const u32 PS2CLK = 294912000; //hz /* 294.912 mhz */
|
||||
|
||||
|
|
|
@ -343,11 +343,11 @@ struct Pcsx2Config
|
|||
void LoadSave( IniInterface& conf );
|
||||
|
||||
void Set( const wxString& list, bool enabled=true );
|
||||
bool Clear( const wxString& list ) { Set( list, false ); }
|
||||
void Clear( const wxString& list ) { Set( list, false ); }
|
||||
|
||||
bool Get( GamefixId id ) const;
|
||||
void Set( GamefixId id, bool enabled=true );
|
||||
bool Clear( GamefixId id ) { Set( id, false ); }
|
||||
void Clear( GamefixId id ) { Set( id, false ); }
|
||||
|
||||
bool operator ==( const GamefixOptions& right ) const
|
||||
{
|
||||
|
|
|
@ -15,11 +15,11 @@
|
|||
|
||||
|
||||
#include "PrecompiledHeader.h"
|
||||
#include "Common.h"
|
||||
|
||||
#include <time.h>
|
||||
#include <cmath>
|
||||
|
||||
#include "Common.h"
|
||||
#include "R3000A.h"
|
||||
#include "Counters.h"
|
||||
#include "IopCounters.h"
|
||||
|
@ -27,6 +27,8 @@
|
|||
#include "GS.h"
|
||||
#include "VUmicro.h"
|
||||
|
||||
#include "ps2/HwInternal.h"
|
||||
|
||||
using namespace Threading;
|
||||
|
||||
extern u8 psxhblankgate;
|
||||
|
@ -45,6 +47,15 @@ SyncCounter vsyncCounter;
|
|||
u32 nextsCounter; // records the cpuRegs.cycle value of the last call to rcntUpdate()
|
||||
s32 nextCounter; // delta from nextsCounter, in cycles, until the next rcntUpdate()
|
||||
|
||||
// Forward declarations needed because C/C++ both are wimpy single-pass compilers.
|
||||
|
||||
static void rcntStartGate(bool mode, u32 sCycle);
|
||||
static void rcntEndGate(bool mode, u32 sCycle);
|
||||
static void rcntWcount(int index, u32 value);
|
||||
static void rcntWmode(int index, u32 value);
|
||||
static void rcntWtarget(int index, u32 value);
|
||||
static void rcntWhold(int index, u32 value);
|
||||
|
||||
|
||||
void rcntReset(int index) {
|
||||
counters[index].count = 0;
|
||||
|
@ -575,7 +586,7 @@ static __fi void _rcntSetGate( int index )
|
|||
}
|
||||
|
||||
// mode - 0 means hblank source, 8 means vblank source.
|
||||
__fi void rcntStartGate(bool isVblank, u32 sCycle)
|
||||
static __fi void rcntStartGate(bool isVblank, u32 sCycle)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
@ -636,7 +647,7 @@ __fi void rcntStartGate(bool isVblank, u32 sCycle)
|
|||
}
|
||||
|
||||
// mode - 0 means hblank signal, 8 means vblank signal.
|
||||
__fi void rcntEndGate(bool isVblank , u32 sCycle)
|
||||
static __fi void rcntEndGate(bool isVblank , u32 sCycle)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
@ -677,7 +688,15 @@ __fi void rcntEndGate(bool isVblank , u32 sCycle)
|
|||
// rcntUpdate, since we're being called from there anyway.
|
||||
}
|
||||
|
||||
__fi void rcntWmode(int index, u32 value)
|
||||
static __fi u32 rcntCycle(int index)
|
||||
{
|
||||
if (counters[index].mode.IsCounting && (counters[index].mode.ClockSource != 0x3))
|
||||
return counters[index].count + ((cpuRegs.cycle - counters[index].sCycleT) / counters[index].rate);
|
||||
else
|
||||
return counters[index].count;
|
||||
}
|
||||
|
||||
static __fi void rcntWmode(int index, u32 value)
|
||||
{
|
||||
if(counters[index].mode.IsCounting) {
|
||||
if(counters[index].mode.ClockSource != 0x3) {
|
||||
|
@ -711,7 +730,7 @@ __fi void rcntWmode(int index, u32 value)
|
|||
_rcntSet( index );
|
||||
}
|
||||
|
||||
__fi void rcntWcount(int index, u32 value)
|
||||
static __fi void rcntWcount(int index, u32 value)
|
||||
{
|
||||
EECNT_LOG("EE Counter[%d] writeCount = %x, oldcount=%x, target=%x", index, value, counters[index].count, counters[index].target );
|
||||
|
||||
|
@ -737,7 +756,7 @@ __fi void rcntWcount(int index, u32 value)
|
|||
_rcntSet( index );
|
||||
}
|
||||
|
||||
__fi void rcntWtarget(int index, u32 value)
|
||||
static __fi void rcntWtarget(int index, u32 value)
|
||||
{
|
||||
EECNT_LOG("EE Counter[%d] writeTarget = %x", index, value);
|
||||
|
||||
|
@ -766,7 +785,7 @@ __fi void rcntWtarget(int index, u32 value)
|
|||
_rcntSet( index );
|
||||
}
|
||||
|
||||
__fi void rcntWhold(int index, u32 value)
|
||||
static __fi void rcntWhold(int index, u32 value)
|
||||
{
|
||||
EECNT_LOG("EE Counter[%d] Hold Write = %x", index, value);
|
||||
counters[index].hold = value;
|
||||
|
@ -787,14 +806,76 @@ __fi u32 rcntRcount(int index)
|
|||
return ret;
|
||||
}
|
||||
|
||||
__fi u32 rcntCycle(int index)
|
||||
template< uint page >
|
||||
__fi u16 rcntRead32( u32 mem )
|
||||
{
|
||||
if (counters[index].mode.IsCounting && (counters[index].mode.ClockSource != 0x3))
|
||||
return counters[index].count + ((cpuRegs.cycle - counters[index].sCycleT) / counters[index].rate);
|
||||
else
|
||||
return counters[index].count;
|
||||
// Important DevNote:
|
||||
// Yes this uses a u16 return value on purpose! The upper bits 16 of the counter registers
|
||||
// are all fixed to 0, so we always truncate everything in these two pages using a u16
|
||||
// return value! --air
|
||||
|
||||
iswitch( mem ) {
|
||||
icase(RCNT0_COUNT) return (u16)rcntRcount(0);
|
||||
icase(RCNT0_MODE) return (u16)counters[0].modeval;
|
||||
icase(RCNT0_TARGET) return (u16)counters[0].target;
|
||||
icase(RCNT0_HOLD) return (u16)counters[0].hold;
|
||||
|
||||
icase(RCNT1_COUNT) return (u16)rcntRcount(1);
|
||||
icase(RCNT1_MODE) return (u16)counters[1].modeval;
|
||||
icase(RCNT1_TARGET) return (u16)counters[1].target;
|
||||
icase(RCNT1_HOLD) return (u16)counters[1].hold;
|
||||
|
||||
icase(RCNT2_COUNT) return (u16)rcntRcount(2);
|
||||
icase(RCNT2_MODE) return (u16)counters[2].modeval;
|
||||
icase(RCNT2_TARGET) return (u16)counters[2].target;
|
||||
|
||||
icase(RCNT3_COUNT) return (u16)rcntRcount(3);
|
||||
icase(RCNT3_MODE) return (u16)counters[3].modeval;
|
||||
icase(RCNT3_TARGET) return (u16)counters[3].target;
|
||||
}
|
||||
|
||||
return psHu16(mem);
|
||||
}
|
||||
|
||||
template< uint page >
|
||||
__fi bool rcntWrite32( u32 mem, mem32_t& value )
|
||||
{
|
||||
pxAssume( mem >= RCNT0_COUNT && mem < 0x10002000 );
|
||||
|
||||
// [TODO] : counters should actually just use the EE's hw register space for storing
|
||||
// count, mode, target, and hold. This will allow for a simplified handler for register
|
||||
// reads.
|
||||
|
||||
iswitch( mem ) {
|
||||
icase(RCNT0_COUNT) return rcntWcount(0, value), false;
|
||||
icase(RCNT0_MODE) return rcntWmode(0, value), false;
|
||||
icase(RCNT0_TARGET) return rcntWtarget(0, value), false;
|
||||
icase(RCNT0_HOLD) return rcntWhold(0, value), false;
|
||||
|
||||
icase(RCNT1_COUNT) return rcntWcount(1, value), false;
|
||||
icase(RCNT1_MODE) return rcntWmode(1, value), false;
|
||||
icase(RCNT1_TARGET) return rcntWtarget(1, value), false;
|
||||
icase(RCNT1_HOLD) return rcntWhold(1, value), false;
|
||||
|
||||
icase(RCNT2_COUNT) return rcntWcount(2, value), false;
|
||||
icase(RCNT2_MODE) return rcntWmode(2, value), false;
|
||||
icase(RCNT2_TARGET) return rcntWtarget(2, value), false;
|
||||
|
||||
icase(RCNT3_COUNT) return rcntWcount(3, value), false;
|
||||
icase(RCNT3_MODE) return rcntWmode(3, value), false;
|
||||
icase(RCNT3_TARGET) return rcntWtarget(3, value), false;
|
||||
}
|
||||
|
||||
// unhandled .. do memory writeback.
|
||||
return true;
|
||||
}
|
||||
|
||||
template u16 rcntRead32<0x00>( u32 mem );
|
||||
template u16 rcntRead32<0x01>( u32 mem );
|
||||
|
||||
template bool rcntWrite32<0x00>( u32 mem, mem32_t& value );
|
||||
template bool rcntWrite32<0x01>( u32 mem, mem32_t& value );
|
||||
|
||||
void SaveStateBase::rcntFreeze()
|
||||
{
|
||||
Freeze( counters );
|
||||
|
|
|
@ -13,8 +13,7 @@
|
|||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __COUNTERS_H__
|
||||
#define __COUNTERS_H__
|
||||
#pragma once
|
||||
|
||||
struct EECNT_MODE
|
||||
{
|
||||
|
@ -137,16 +136,10 @@ extern void rcntUpdate_vSync();
|
|||
extern void rcntUpdate();
|
||||
|
||||
extern void rcntInit();
|
||||
extern void rcntStartGate(bool mode, u32 sCycle);
|
||||
extern void rcntEndGate(bool mode, u32 sCycle);
|
||||
extern void rcntWcount(int index, u32 value);
|
||||
extern void rcntWmode(int index, u32 value);
|
||||
extern void rcntWtarget(int index, u32 value);
|
||||
extern void rcntWhold(int index, u32 value);
|
||||
extern u32 rcntRcount(int index);
|
||||
extern u32 rcntCycle(int index);
|
||||
template< uint page > extern bool rcntWrite32( u32 mem, mem32_t& value );
|
||||
template< uint page > extern u16 rcntRead32( u32 mem ); // returns u16 by design! (see implementation for details)
|
||||
|
||||
extern u32 UpdateVSyncRate();
|
||||
extern void frameLimitReset();
|
||||
|
||||
#endif /* __COUNTERS_H__ */
|
||||
|
|
|
@ -342,17 +342,19 @@ struct SysConsoleLogPack
|
|||
extern SysTraceLogPack SysTrace;
|
||||
extern SysConsoleLogPack SysConsole;
|
||||
|
||||
extern void __Log( const char* fmt, ... );
|
||||
|
||||
// Helper macro for cut&paste. Note that we intentionally use a top-level *inline* bitcheck
|
||||
// against Trace.Enabled, to avoid extra overhead in Debug builds when logging is disabled.
|
||||
// (specifically this allows debug builds to skip havingto resolve all the parameters being
|
||||
// passed into the function)
|
||||
#define macTrace(trace) SysTrace.trace.IsActive() && SysTrace.trace.Write
|
||||
|
||||
|
||||
#ifdef PCSX2_DEVBUILD
|
||||
|
||||
extern void __Log( const char* fmt, ... );
|
||||
# define SysTraceActive(trace) SysTrace.trace.IsActive()
|
||||
# define macTrace(trace) SysTraceActive(trace) && SysTrace.trace.Write
|
||||
#else
|
||||
# define SysTraceActive(trace) (false)
|
||||
# define macTrace(trace)
|
||||
#endif
|
||||
|
||||
#define SIF_LOG macTrace(SIF)
|
||||
|
||||
|
@ -385,45 +387,9 @@ extern void __Log( const char* fmt, ... );
|
|||
#define GPU_LOG macTrace(IOP.GPU)
|
||||
#define CDVD_LOG macTrace(IOP.CDVD)
|
||||
|
||||
#else // PCSX2_DEVBUILD
|
||||
|
||||
#define CPU_LOG 0&&
|
||||
#define MEM_LOG 0&&
|
||||
#define HW_LOG 0&&
|
||||
#define DMA_LOG 0&&
|
||||
#define BIOS_LOG 0&&
|
||||
#define VU0_LOG 0&&
|
||||
#define COP0_LOG 0&&
|
||||
#define UnknownHW_LOG 0&&
|
||||
#define VIF_LOG 0&&
|
||||
#define SPR_LOG 0&&
|
||||
#define GIF_LOG 0&&
|
||||
#define SIF_LOG 0&&
|
||||
#define IPU_LOG 0&&
|
||||
#define VUM_LOG 0&&
|
||||
#define VifCodeLog 0&&
|
||||
|
||||
#define PSXCPU_LOG 0&&
|
||||
#define PSXMEM_LOG 0&&
|
||||
#define PSXHW_LOG 0&&
|
||||
#define PSXUnkHW_LOG 0&&
|
||||
#define PSXBIOS_LOG 0&&
|
||||
#define PSXDMA_LOG 0&&
|
||||
|
||||
#define PAD_LOG 0&&
|
||||
#define CDR_LOG 0&&
|
||||
#define CDVD_LOG 0&&
|
||||
#define GPU_LOG 0&&
|
||||
#define PSXCNT_LOG 0&&
|
||||
#define EECNT_LOG 0&&
|
||||
|
||||
#define EMU_LOG 0&&
|
||||
#define CACHE_LOG 0&&
|
||||
#define MEMCARDS_LOG 0&&
|
||||
#endif
|
||||
|
||||
#define ELF_LOG SysConsole.ELF.IsActive() && SysConsole.ELF.Write
|
||||
#define eeRecPerfLog SysConsole.eeRecPerf.IsActive() && SysConsole.eeRecPerf
|
||||
#define eeConLog SysConsole.eeConsole.IsActive() && SysConsole.eeConsole.Write
|
||||
#define eeDeci2Log SysConsole.deci2.IsActive() && SysConsole.deci2.Write
|
||||
#define iopConLog SysConsole.iopConsole.IsActive() && SysConsole.iopConsole.Write
|
||||
#define ELF_LOG SysConsole.ELF.IsActive() && SysConsole.ELF.Write
|
||||
#define eeRecPerfLog SysConsole.eeRecPerf.IsActive() && SysConsole.eeRecPerf
|
||||
#define eeConLog SysConsole.eeConsole.IsActive() && SysConsole.eeConsole.Write
|
||||
#define eeDeci2Log SysConsole.deci2.IsActive() && SysConsole.deci2.Write
|
||||
#define iopConLog SysConsole.iopConsole.IsActive()&& SysConsole.iopConsole.Write
|
||||
|
|
161
pcsx2/Dmac.h
161
pcsx2/Dmac.h
|
@ -171,10 +171,6 @@ union tDMA_QWC {
|
|||
tDMA_TAG tag() const { return (tDMA_TAG)_u32; }
|
||||
};
|
||||
|
||||
static void setDmacStat(u32 num);
|
||||
static tDMA_TAG *dmaGetAddr(u32 addr, bool write);
|
||||
static void throwBusError(const char *s);
|
||||
|
||||
struct DMACh {
|
||||
tDMA_CHCR chcr;
|
||||
u32 _null0[3];
|
||||
|
@ -200,63 +196,14 @@ struct DMACh {
|
|||
qwc = ptag[0].QWC;
|
||||
}
|
||||
|
||||
bool transfer(const char *s, tDMA_TAG* ptag)
|
||||
{
|
||||
if (ptag == NULL) // Is ptag empty?
|
||||
{
|
||||
throwBusError(s);
|
||||
return false;
|
||||
}
|
||||
chcrTransfer(ptag);
|
||||
bool transfer(const char *s, tDMA_TAG* ptag);
|
||||
void unsafeTransfer(tDMA_TAG* ptag);
|
||||
tDMA_TAG *getAddr(u32 addr, u32 num, bool write);
|
||||
tDMA_TAG *DMAtransfer(u32 addr, u32 num);
|
||||
tDMA_TAG dma_tag();
|
||||
|
||||
qwcTransfer(ptag);
|
||||
return true;
|
||||
}
|
||||
|
||||
void unsafeTransfer(tDMA_TAG* ptag)
|
||||
{
|
||||
chcrTransfer(ptag);
|
||||
qwcTransfer(ptag);
|
||||
}
|
||||
|
||||
tDMA_TAG *getAddr(u32 addr, u32 num, bool write)
|
||||
{
|
||||
tDMA_TAG *ptr = dmaGetAddr(addr, write);
|
||||
if (ptr == NULL)
|
||||
{
|
||||
throwBusError("dmaGetAddr");
|
||||
setDmacStat(num);
|
||||
chcr.STR = false;
|
||||
}
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
tDMA_TAG *DMAtransfer(u32 addr, u32 num)
|
||||
{
|
||||
tDMA_TAG *tag = getAddr(addr, num, false);
|
||||
|
||||
if (tag == NULL) return NULL;
|
||||
|
||||
chcrTransfer(tag);
|
||||
qwcTransfer(tag);
|
||||
return tag;
|
||||
}
|
||||
|
||||
tDMA_TAG dma_tag()
|
||||
{
|
||||
return chcr.tag();
|
||||
}
|
||||
|
||||
wxString cmq_to_str() const
|
||||
{
|
||||
return wxsFormat(L"chcr = %lx, madr = %lx, qwc = %lx", chcr._u32, madr, qwc);
|
||||
}
|
||||
|
||||
wxString cmqt_to_str() const
|
||||
{
|
||||
return wxsFormat(L"chcr = %lx, madr = %lx, qwc = %lx, tadr = %1x", chcr._u32, madr, qwc, tadr);
|
||||
}
|
||||
wxString cmq_to_str() const;
|
||||
wxString cmqt_to_str() const;
|
||||
};
|
||||
|
||||
enum INTCIrqs
|
||||
|
@ -524,7 +471,7 @@ union tDMAC_ADDR
|
|||
|
||||
wxCharBuffer ToUTF8(bool sprIsValid=true) const
|
||||
{
|
||||
return FastFormatAscii().Write((sprIsValid && SPR) ? "0x%04X(SPR)" : "0x%08X", ADDR).GetResult();
|
||||
return FastFormatAscii().Write((sprIsValid && SPR) ? "0x%04X(SPR)" : "0x%08X", ADDR).c_str();
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -588,88 +535,28 @@ struct INTCregisters
|
|||
u32 _padding2[3];
|
||||
};
|
||||
|
||||
#define dmacRegs ((DMACregisters*)(eeMem->HW+0xE000))
|
||||
#define intcRegs ((INTCregisters*)(eeMem->HW+0xF000))
|
||||
#define intcRegs ((INTCregisters*)(eeHw+0xF000))
|
||||
|
||||
static __fi void throwBusError(const char *s)
|
||||
{
|
||||
Console.Error("%s BUSERR", s);
|
||||
dmacRegs->stat.BEIS = true;
|
||||
}
|
||||
static DMACregisters& dmacRegs = (DMACregisters&)eeHw[0xE000];
|
||||
|
||||
static __fi void setDmacStat(u32 num)
|
||||
{
|
||||
dmacRegs->stat.set_flags(1 << num);
|
||||
}
|
||||
// Various useful locations
|
||||
static DMACh& vif0ch = (DMACh&)eeHw[0x8000];
|
||||
static DMACh& vif1ch = (DMACh&)eeHw[0x9000];
|
||||
static DMACh& gifch = (DMACh&)eeHw[0xA000];
|
||||
static DMACh& spr0ch = (DMACh&)eeHw[0xD000];
|
||||
static DMACh& spr1ch = (DMACh&)eeHw[0xD400];
|
||||
|
||||
// Note: Dma addresses are guaranteed to be aligned to 16 bytes (128 bits)
|
||||
static __fi tDMA_TAG *SPRdmaGetAddr(u32 addr, bool write)
|
||||
{
|
||||
// if (addr & 0xf) { DMA_LOG("*PCSX2*: DMA address not 128bit aligned: %8.8x", addr); }
|
||||
|
||||
//For some reason Getaway references SPR Memory from itself using SPR0, oh well, let it i guess...
|
||||
if((addr & 0x70000000) == 0x70000000)
|
||||
{
|
||||
return (tDMA_TAG*)&eeMem->Scratch[addr & 0x3ff0];
|
||||
}
|
||||
|
||||
// FIXME: Why??? DMA uses physical addresses
|
||||
addr &= 0x1ffffff0;
|
||||
|
||||
if (addr < Ps2MemSize::Base)
|
||||
{
|
||||
return (tDMA_TAG*)&eeMem->Main[addr];
|
||||
}
|
||||
else if (addr < 0x10000000)
|
||||
{
|
||||
return (tDMA_TAG*)(write ? eeMem->ZeroWrite : eeMem->ZeroRead);
|
||||
}
|
||||
else if ((addr >= 0x11004000) && (addr < 0x11010000))
|
||||
{
|
||||
//Access for VU Memory
|
||||
return (tDMA_TAG*)vtlb_GetPhyPtr(addr & 0x1FFFFFF0);
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.Error( "*PCSX2*: DMA error: %8.8x", addr);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// Note: Dma addresses are guaranteed to be aligned to 16 bytes (128 bits)
|
||||
static __ri tDMA_TAG *dmaGetAddr(u32 addr, bool write)
|
||||
{
|
||||
// if (addr & 0xf) { DMA_LOG("*PCSX2*: DMA address not 128bit aligned: %8.8x", addr); }
|
||||
if (DMA_TAG(addr).SPR) return (tDMA_TAG*)&eeMem->Scratch[addr & 0x3ff0];
|
||||
|
||||
// FIXME: Why??? DMA uses physical addresses
|
||||
addr &= 0x1ffffff0;
|
||||
|
||||
if (addr < Ps2MemSize::Base)
|
||||
{
|
||||
return (tDMA_TAG*)&eeMem->Main[addr];
|
||||
}
|
||||
else if (addr < 0x10000000)
|
||||
{
|
||||
return (tDMA_TAG*)(write ? eeMem->ZeroWrite : eeMem->ZeroRead);
|
||||
}
|
||||
else if (addr < 0x10004000)
|
||||
{
|
||||
// Secret scratchpad address for DMA = end of maximum main memory?
|
||||
//Console.Warning("Writing to the scratchpad without the SPR flag set!");
|
||||
return (tDMA_TAG*)&eeMem->Scratch[addr & 0x3ff0];
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.Error( "*PCSX2*: DMA error: %8.8x", addr);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
extern void throwBusError(const char *s);
|
||||
extern void setDmacStat(u32 num);
|
||||
extern tDMA_TAG *SPRdmaGetAddr(u32 addr, bool write);
|
||||
extern tDMA_TAG *dmaGetAddr(u32 addr, bool write);
|
||||
|
||||
extern void hwIntcIrq(int n);
|
||||
extern void hwDmacIrq(int n);
|
||||
|
||||
extern bool hwMFIFOWrite(u32 addr, const u128* data, uint size_qwc);
|
||||
extern bool hwDmacSrcChainWithStack(DMACh *dma, int id);
|
||||
extern bool hwDmacSrcChain(DMACh *dma, int id);
|
||||
extern bool hwDmacSrcChainWithStack(DMACh& dma, int id);
|
||||
extern bool hwDmacSrcChain(DMACh& dma, int id);
|
||||
|
||||
template< uint page > u32 dmacRead32( u32 mem );
|
||||
template< uint page > extern bool dmacWrite32( u32 mem, mem32_t& value );
|
||||
|
|
|
@ -129,10 +129,10 @@ void iDumpRegisters(u32 startpc, u32 temp)
|
|||
__Log("gif: %x %x %x", psHu32(0x3000), psHu32(0x3010), psHu32(0x3020));
|
||||
|
||||
for(i = 0; i < ArraySize(dmacs); ++i) {
|
||||
DMACh* p = (DMACh*)(&eeMem->HW[dmacs[i]]);
|
||||
DMACh* p = (DMACh*)(&eeHw[dmacs[i]]);
|
||||
__Log("dma%d c%x m%x q%x t%x s%x", i, p->chcr._u32, p->madr, p->qwc, p->tadr, p->sadr);
|
||||
}
|
||||
__Log(L"dmac " + dmacRegs->ctrl.desc() + L" " + dmacRegs->stat.desc() + L" " + dmacRegs->rbsr.desc() + L" " + dmacRegs->rbor.desc());
|
||||
__Log(L"dmac " + dmacRegs.ctrl.desc() + L" " + dmacRegs.stat.desc() + L" " + dmacRegs.rbsr.desc() + L" " + dmacRegs.rbor.desc());
|
||||
__Log(L"intc " + intcRegs->stat.desc() + L" " + intcRegs->mask.desc());
|
||||
__Log("sif: %x %x %x %x %x", psHu32(SBUS_F200), psHu32(SBUS_F220), psHu32(SBUS_F230), psHu32(SBUS_F240), psHu32(SBUS_F260));
|
||||
#endif
|
||||
|
|
131
pcsx2/FiFo.cpp
131
pcsx2/FiFo.cpp
|
@ -28,8 +28,6 @@
|
|||
/////////////////////////// Quick & dirty FIFO :D ////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// ** NOTE: cannot use XMM/MMX regs **
|
||||
|
||||
// Notes on FIFO implementation
|
||||
//
|
||||
// The FIFO consists of four separate pages of HW register memory, each mapped to a
|
||||
|
@ -40,167 +38,108 @@
|
|||
// 0x6000 - 0x7000 : GS (all registers map to 0x6000)
|
||||
// 0x7000 - 0x8000 : IPU (registers map to 0x7000 and 0x7010, respectively)
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// ReadFIFO Pages
|
||||
|
||||
void __fastcall ReadFIFO_page_4(u32 mem, mem128_t* out)
|
||||
void __fastcall ReadFIFO_VIF1(mem128_t* out)
|
||||
{
|
||||
pxAssert( (mem >= VIF0_FIFO) && (mem < VIF1_FIFO) );
|
||||
|
||||
VIF_LOG("ReadFIFO/VIF0 0x%08X", mem);
|
||||
|
||||
CopyQWC( out, &psHu128(VIF0_FIFO) );
|
||||
}
|
||||
|
||||
void __fastcall ReadFIFO_page_5(u32 mem, mem128_t* out)
|
||||
{
|
||||
pxAssert( (mem >= VIF1_FIFO) && (mem < GIF_FIFO) );
|
||||
|
||||
VIF_LOG("ReadFIFO/VIF1, addr=0x%08X", mem);
|
||||
|
||||
if (vif1Regs->stat.test(VIF1_STAT_INT | VIF1_STAT_VSS | VIF1_STAT_VIS | VIF1_STAT_VFS) )
|
||||
if (vif1Regs.stat.test(VIF1_STAT_INT | VIF1_STAT_VSS | VIF1_STAT_VIS | VIF1_STAT_VFS) )
|
||||
DevCon.Warning( "Reading from vif1 fifo when stalled" );
|
||||
|
||||
if(vif1Regs->stat.FQC == 0) Console.Warning("FQC = 0 on VIF FIFO READ!");
|
||||
if (vif1Regs->stat.FDR)
|
||||
pxAssertRel(vif1Regs.stat.FQC != 0, "FQC = 0 on VIF FIFO READ!");
|
||||
if (vif1Regs.stat.FDR)
|
||||
{
|
||||
if(vif1Regs->stat.FQC > vif1.GSLastDownloadSize)
|
||||
if(vif1Regs.stat.FQC > vif1.GSLastDownloadSize)
|
||||
{
|
||||
DevCon.Warning("Warning! GS Download size < FIFO count!");
|
||||
}
|
||||
if (vif1Regs->stat.FQC > 0)
|
||||
if (vif1Regs.stat.FQC > 0)
|
||||
{
|
||||
GetMTGS().WaitGS();
|
||||
GSreadFIFO(&psHu64(VIF1_FIFO));
|
||||
vif1.GSLastDownloadSize--;
|
||||
if (vif1.GSLastDownloadSize <= 16)
|
||||
gifRegs->stat.OPH = false;
|
||||
vif1Regs->stat.FQC = min((u32)16, vif1.GSLastDownloadSize);
|
||||
gifRegs.stat.OPH = false;
|
||||
vif1Regs.stat.FQC = min((u32)16, vif1.GSLastDownloadSize);
|
||||
}
|
||||
}
|
||||
|
||||
CopyQWC( out, &psHu128(VIF1_FIFO) );
|
||||
VIF_LOG("ReadFIFO/VIF1 -> %ls", out->ToString().c_str());
|
||||
}
|
||||
|
||||
void __fastcall ReadFIFO_page_6(u32 mem, mem128_t* out)
|
||||
{
|
||||
pxAssert( (mem >= GIF_FIFO) && (mem < IPUout_FIFO) );
|
||||
|
||||
DevCon.Warning( "ReadFIFO/GIF, addr=0x%x", mem );
|
||||
|
||||
CopyQWC( out, &psHu128(GIF_FIFO) );
|
||||
}
|
||||
|
||||
// ReadFIFO_page_7 is contained in IPU_Fifo.cpp
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// WriteFIFO Pages
|
||||
|
||||
void __fastcall WriteFIFO_page_4(u32 mem, const mem128_t *value)
|
||||
//
|
||||
void __fastcall WriteFIFO_VIF0(const mem128_t *value)
|
||||
{
|
||||
pxAssert( (mem >= VIF0_FIFO) && (mem < VIF1_FIFO) );
|
||||
|
||||
VIF_LOG("WriteFIFO/VIF0, addr=0x%08X", mem);
|
||||
VIF_LOG("WriteFIFO/VIF0 <- %ls", value->ToString().c_str());
|
||||
|
||||
CopyQWC(&psHu128(VIF0_FIFO), value);
|
||||
|
||||
vif0ch->qwc += 1;
|
||||
vif0ch.qwc += 1;
|
||||
if(vif0.irqoffset != 0 && vif0.vifstalled == true) DevCon.Warning("Offset on VIF0 FIFO start!");
|
||||
bool ret = VIF0transfer((u32*)value, 4);
|
||||
|
||||
if (vif0.cmd)
|
||||
{
|
||||
if(vif0.done == true && vif0ch->qwc == 0) vif0Regs->stat.VPS = VPS_WAITING;
|
||||
if(vif0.done && vif0ch.qwc == 0) vif0Regs.stat.VPS = VPS_WAITING;
|
||||
}
|
||||
else
|
||||
{
|
||||
vif0Regs->stat.VPS = VPS_IDLE;
|
||||
vif0Regs.stat.VPS = VPS_IDLE;
|
||||
}
|
||||
|
||||
pxAssertDev( ret, "vif stall code not implemented" );
|
||||
}
|
||||
|
||||
void __fastcall WriteFIFO_page_5(u32 mem, const mem128_t *value)
|
||||
void __fastcall WriteFIFO_VIF1(const mem128_t *value)
|
||||
{
|
||||
pxAssert( (mem >= VIF1_FIFO) && (mem < GIF_FIFO) );
|
||||
|
||||
VIF_LOG("WriteFIFO/VIF1, addr=0x%08X", mem);
|
||||
VIF_LOG("WriteFIFO/VIF1 <- %ls", value->ToString().c_str());
|
||||
|
||||
CopyQWC(&psHu128(VIF1_FIFO), value);
|
||||
|
||||
if (vif1Regs->stat.FDR)
|
||||
if (vif1Regs.stat.FDR)
|
||||
DevCon.Warning("writing to fifo when fdr is set!");
|
||||
if (vif1Regs->stat.test(VIF1_STAT_INT | VIF1_STAT_VSS | VIF1_STAT_VIS | VIF1_STAT_VFS) )
|
||||
if (vif1Regs.stat.test(VIF1_STAT_INT | VIF1_STAT_VSS | VIF1_STAT_VIS | VIF1_STAT_VFS) )
|
||||
DevCon.Warning("writing to vif1 fifo when stalled");
|
||||
|
||||
vif1ch->qwc += 1;
|
||||
vif1ch.qwc += 1;
|
||||
if(vif1.irqoffset != 0 && vif1.vifstalled == true) DevCon.Warning("Offset on VIF1 FIFO start!");
|
||||
bool ret = VIF1transfer((u32*)value, 4);
|
||||
|
||||
if(GSTransferStatus.PTH2 == STOPPED_MODE && gifRegs->stat.APATH == GIF_APATH2)
|
||||
if(GSTransferStatus.PTH2 == STOPPED_MODE && gifRegs.stat.APATH == GIF_APATH2)
|
||||
{
|
||||
if(gifRegs->stat.DIR == 0)gifRegs->stat.OPH = false;
|
||||
gifRegs->stat.APATH = GIF_APATH_IDLE;
|
||||
if(gifRegs->stat.P1Q) gsPath1Interrupt();
|
||||
if(gifRegs.stat.DIR == 0)gifRegs.stat.OPH = false;
|
||||
gifRegs.stat.APATH = GIF_APATH_IDLE;
|
||||
if(gifRegs.stat.P1Q) gsPath1Interrupt();
|
||||
}
|
||||
if (vif1.cmd)
|
||||
{
|
||||
if(vif1.done == true && vif1ch->qwc == 0) vif1Regs->stat.VPS = VPS_WAITING;
|
||||
if(vif1.done == true && vif1ch.qwc == 0) vif1Regs.stat.VPS = VPS_WAITING;
|
||||
}
|
||||
else
|
||||
{
|
||||
vif1Regs->stat.VPS = VPS_IDLE;
|
||||
vif1Regs.stat.VPS = VPS_IDLE;
|
||||
}
|
||||
|
||||
pxAssertDev( ret, "vif stall code not implemented" );
|
||||
}
|
||||
|
||||
// Dummy GIF-TAG Packet to Guarantee Count = 1
|
||||
__aligned16 u32 nloop0_packet[4] = {0, 0, 0, 0};
|
||||
__aligned16 u128 nloop0_packet;
|
||||
|
||||
void __fastcall WriteFIFO_page_6(u32 mem, const mem128_t *value)
|
||||
void __fastcall WriteFIFO_GIF(const mem128_t *value)
|
||||
{
|
||||
pxAssert( (mem >= GIF_FIFO) && (mem < IPUout_FIFO) );
|
||||
GIF_LOG("WriteFIFO/GIF, addr=0x%08X", mem);
|
||||
GIF_LOG("WriteFIFO/GIF <- %ls", value->ToString().c_str());
|
||||
|
||||
CopyQWC(&psHu128(GIF_FIFO), value);
|
||||
CopyQWC(nloop0_packet, value);
|
||||
CopyQWC(&nloop0_packet, value);
|
||||
|
||||
GetMTGS().PrepDataPacket(GIF_PATH_3, 1);
|
||||
GIFPath_CopyTag( GIF_PATH_3, (u128*)nloop0_packet, 1 );
|
||||
GIFPath_CopyTag( GIF_PATH_3, &nloop0_packet, 1 );
|
||||
GetMTGS().SendDataPacket();
|
||||
if(GSTransferStatus.PTH3 == STOPPED_MODE && gifRegs->stat.APATH == GIF_APATH3 )
|
||||
if(GSTransferStatus.PTH3 == STOPPED_MODE && gifRegs.stat.APATH == GIF_APATH3 )
|
||||
{
|
||||
if(gifRegs->stat.DIR == 0)gifRegs->stat.OPH = false;
|
||||
gifRegs->stat.APATH = GIF_APATH_IDLE;
|
||||
if(gifRegs->stat.P1Q) gsPath1Interrupt();
|
||||
}
|
||||
}
|
||||
|
||||
void __fastcall WriteFIFO_page_7(u32 mem, const mem128_t *value)
|
||||
{
|
||||
pxAssert( (mem >= IPUout_FIFO) && (mem < D0_CHCR) );
|
||||
|
||||
// All addresses in this page map to 0x7000 and 0x7010:
|
||||
mem &= 0x10;
|
||||
|
||||
IPU_LOG( "WriteFIFO, addr=0x%x", mem );
|
||||
|
||||
if( mem == 0 )
|
||||
{
|
||||
// Should this raise a PS2 exception or just ignore silently?
|
||||
Console.Warning( "WriteFIFO/IPUout (ignored)" );
|
||||
}
|
||||
else
|
||||
{
|
||||
IPU_LOG("WriteFIFO in[%d] <- %8.8X_%8.8X_%8.8X_%8.8X",
|
||||
mem/16, ((u32*)value)[3], ((u32*)value)[2], ((u32*)value)[1], ((u32*)value)[0]);
|
||||
|
||||
//committing every 16 bytes
|
||||
while( ipu_fifo.in.write((u32*)value, 1) == 0 )
|
||||
{
|
||||
Console.WriteLn("IPU sleeping");
|
||||
Threading::Timeslice();
|
||||
}
|
||||
if(gifRegs.stat.DIR == 0)gifRegs.stat.OPH = false;
|
||||
gifRegs.stat.APATH = GIF_APATH_IDLE;
|
||||
if(gifRegs.stat.P1Q) gsPath1Interrupt();
|
||||
}
|
||||
}
|
||||
|
|
16
pcsx2/GS.cpp
16
pcsx2/GS.cpp
|
@ -56,9 +56,9 @@ extern u32 SIGNAL_Data_Pending[2];
|
|||
|
||||
void gsGIFReset()
|
||||
{
|
||||
gifRegs->stat.reset();
|
||||
gifRegs->ctrl.reset();
|
||||
gifRegs->mode.reset();
|
||||
gifRegs.stat.reset();
|
||||
gifRegs.ctrl.reset();
|
||||
gifRegs.mode.reset();
|
||||
}
|
||||
|
||||
void gsReset()
|
||||
|
@ -128,7 +128,7 @@ static __fi void gsCSRwrite( const tGS_CSR& csr )
|
|||
|
||||
SIGNAL_IMR_Pending = false;
|
||||
|
||||
if(gifRegs->stat.P1Q && gifRegs->stat.APATH <= GIF_APATH1) gsPath1Interrupt();
|
||||
if(gifRegs.stat.P1Q && gifRegs.stat.APATH <= GIF_APATH1) gsPath1Interrupt();
|
||||
}
|
||||
|
||||
if(csr.FINISH) CSRreg.FINISH = false;
|
||||
|
@ -286,9 +286,9 @@ void __fastcall gsWrite64_page_01( u32 mem, const mem64_t* value )
|
|||
//Only problem is it kills killzone :(.
|
||||
// (yes it *is* a complete hack; both lines here in fact --air)
|
||||
//=========================================================================
|
||||
//gifRegs->stat.OPH = true; // Bleach wants it, Killzone hates it.
|
||||
//gifRegs.stat.OPH = true; // Bleach wants it, Killzone hates it.
|
||||
|
||||
gifRegs->stat.DIR = (u32)value[0];
|
||||
gifRegs.stat.DIR = (u32)value[0];
|
||||
//=========================================================================
|
||||
// BUSDIR INSANITY !! MTGS FLUSH NEEDED
|
||||
//
|
||||
|
@ -459,9 +459,7 @@ void SaveStateBase::gsFreeze()
|
|||
{
|
||||
FreezeMem(PS2MEM_GS, 0x2000);
|
||||
Freeze(SIGNAL_IMR_Pending);
|
||||
|
||||
if( GetVersion() > 0 )
|
||||
Freeze(gsRegionMode);
|
||||
Freeze(gsRegionMode);
|
||||
|
||||
gifPathFreeze();
|
||||
}
|
||||
|
|
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))
|
||||
{
|
||||
|
@ -70,8 +70,8 @@ void gsPath1Interrupt()
|
|||
|
||||
if(GSTransferStatus.PTH1 == STOPPED_MODE)
|
||||
{
|
||||
gifRegs->stat.OPH = false;
|
||||
gifRegs->stat.APATH = GIF_APATH_IDLE;
|
||||
gifRegs.stat.OPH = false;
|
||||
gifRegs.stat.APATH = GIF_APATH_IDLE;
|
||||
}
|
||||
}
|
||||
GetMTGS().SendDataPacket();
|
||||
|
@ -84,8 +84,8 @@ void gsPath1Interrupt()
|
|||
}
|
||||
else
|
||||
{
|
||||
if(gifRegs->stat.PSE) DevCon.Warning("Path1 paused by GIF_CTRL");
|
||||
DevCon.Warning("Looping??? IP3 %x APATH %x OPH %x", gifRegs->stat.IP3, gifRegs->stat.APATH, gifRegs->stat.OPH);
|
||||
if(gifRegs.stat.PSE) DevCon.Warning("Path1 paused by GIF_CTRL");
|
||||
DevCon.Warning("Looping??? IP3 %x APATH %x OPH %x", gifRegs.stat.IP3, gifRegs.stat.APATH, gifRegs.stat.OPH);
|
||||
//if(!(cpuRegs.interrupt & (1<<28)) && Path1WritePos > 0)CPU_INT(28, 128);
|
||||
}
|
||||
|
||||
|
@ -104,25 +104,25 @@ __fi void gsInterrupt()
|
|||
return;
|
||||
}
|
||||
|
||||
if(GSTransferStatus.PTH3 >= PENDINGSTOP_MODE && gifRegs->stat.APATH == GIF_APATH3 )
|
||||
if(GSTransferStatus.PTH3 >= PENDINGSTOP_MODE && gifRegs.stat.APATH == GIF_APATH3 )
|
||||
{
|
||||
gifRegs->stat.OPH = false;
|
||||
gifRegs.stat.OPH = false;
|
||||
GSTransferStatus.PTH3 = STOPPED_MODE;
|
||||
gifRegs->stat.APATH = GIF_APATH_IDLE;
|
||||
if(gifRegs->stat.P1Q) gsPath1Interrupt();
|
||||
gifRegs.stat.APATH = GIF_APATH_IDLE;
|
||||
if(gifRegs.stat.P1Q) gsPath1Interrupt();
|
||||
}
|
||||
|
||||
|
||||
if (!(gif->chcr.STR))
|
||||
if (!(gifch.chcr.STR))
|
||||
{
|
||||
//Console.WriteLn("Eh? why are you still interrupting! chcr %x, qwc %x, done = %x", gif->chcr._u32, gif->qwc, done);
|
||||
//Console.WriteLn("Eh? why are you still interrupting! chcr %x, qwc %x, done = %x", gifch.chcr._u32, gifch.qwc, done);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if ((gif->qwc > 0) || (!gspath3done))
|
||||
if ((gifch.qwc > 0) || (!gspath3done))
|
||||
{
|
||||
if (!dmacRegs->ctrl.DMAE)
|
||||
if (!dmacRegs.ctrl.DMAE)
|
||||
{
|
||||
Console.Warning("gs dma masked, re-scheduling...");
|
||||
// re-raise the int shortly in the future
|
||||
|
@ -136,14 +136,14 @@ __fi void gsInterrupt()
|
|||
|
||||
gspath3done = false;
|
||||
gscycles = 0;
|
||||
gif->chcr.STR = false;
|
||||
gifch.chcr.STR = false;
|
||||
|
||||
////
|
||||
/*gifRegs->stat.OPH = false;
|
||||
/*gifRegs.stat.OPH = false;
|
||||
GSTransferStatus.PTH3 = STOPPED_MODE;
|
||||
gifRegs->stat.APATH = GIF_APATH_IDLE;*/
|
||||
gifRegs.stat.APATH = GIF_APATH_IDLE;*/
|
||||
////
|
||||
gifRegs->stat.clear_flags(GIF_STAT_FQC);
|
||||
gifRegs.stat.clear_flags(GIF_STAT_FQC);
|
||||
clearFIFOstuff(false);
|
||||
hwDmacIrq(DMAC_GIF);
|
||||
//DevCon.Warning("GIF DMA end");
|
||||
|
@ -166,20 +166,20 @@ int _GIFchain()
|
|||
{
|
||||
tDMA_TAG *pMem;
|
||||
|
||||
pMem = dmaGetAddr(gif->madr, false);
|
||||
pMem = dmaGetAddr(gifch.madr, false);
|
||||
if (pMem == NULL)
|
||||
{
|
||||
// reset path3, fixes dark cloud 2
|
||||
GIFPath_Clear( GIF_PATH_3 );
|
||||
|
||||
//must increment madr and clear qwc, else it loops
|
||||
gif->madr += gif->qwc * 16;
|
||||
gif->qwc = 0;
|
||||
gifch.madr += gifch.qwc * 16;
|
||||
gifch.qwc = 0;
|
||||
Console.Warning( "Hackfix - NULL GIFchain" );
|
||||
return -1;
|
||||
}
|
||||
|
||||
return WRITERING_DMA(pMem, gif->qwc);
|
||||
return WRITERING_DMA(pMem, gifch.qwc);
|
||||
}
|
||||
|
||||
static __fi void GIFchain()
|
||||
|
@ -187,12 +187,12 @@ static __fi void GIFchain()
|
|||
// qwc check now done outside this function
|
||||
// Voodoocycles
|
||||
// >> 2 so Drakan and Tekken 5 don't mess up in some PATH3 transfer. Cycles to interrupt were getting huge..
|
||||
/*if (gif->qwc)*/ gscycles+= ( _GIFchain() * BIAS); /* guessing */
|
||||
/*if (gifch.qwc)*/ gscycles+= ( _GIFchain() * BIAS); /* guessing */
|
||||
}
|
||||
|
||||
static __fi bool checkTieBit(tDMA_TAG* &ptag)
|
||||
{
|
||||
if (gif->chcr.TIE && ptag->IRQ)
|
||||
if (gifch.chcr.TIE && ptag->IRQ)
|
||||
{
|
||||
GIF_LOG("dmaIrq Set");
|
||||
gspath3done = true;
|
||||
|
@ -204,38 +204,38 @@ static __fi bool checkTieBit(tDMA_TAG* &ptag)
|
|||
|
||||
static __fi tDMA_TAG* ReadTag()
|
||||
{
|
||||
tDMA_TAG* ptag = dmaGetAddr(gif->tadr, false); //Set memory pointer to TADR
|
||||
tDMA_TAG* ptag = dmaGetAddr(gifch.tadr, false); //Set memory pointer to TADR
|
||||
|
||||
if (!(gif->transfer("Gif", ptag))) return NULL;
|
||||
if (!(gifch.transfer("Gif", ptag))) return NULL;
|
||||
|
||||
gif->madr = ptag[1]._u32; //MADR = ADDR field + SPR
|
||||
gifch.madr = ptag[1]._u32; //MADR = ADDR field + SPR
|
||||
gscycles += 2; // Add 1 cycles from the QW read for the tag
|
||||
|
||||
gspath3done = hwDmacSrcChainWithStack(gif, ptag->ID);
|
||||
gspath3done = hwDmacSrcChainWithStack(gifch, ptag->ID);
|
||||
return ptag;
|
||||
}
|
||||
|
||||
static __fi tDMA_TAG* ReadTag2()
|
||||
{
|
||||
tDMA_TAG* ptag = dmaGetAddr(gif->tadr, false); //Set memory pointer to TADR
|
||||
tDMA_TAG* ptag = dmaGetAddr(gifch.tadr, false); //Set memory pointer to TADR
|
||||
|
||||
gif->unsafeTransfer(ptag);
|
||||
gif->madr = ptag[1]._u32;
|
||||
gifch.unsafeTransfer(ptag);
|
||||
gifch.madr = ptag[1]._u32;
|
||||
|
||||
gspath3done = hwDmacSrcChainWithStack(gif, ptag->ID);
|
||||
gspath3done = hwDmacSrcChainWithStack(gifch, ptag->ID);
|
||||
return ptag;
|
||||
}
|
||||
|
||||
bool CheckPaths(int Channel)
|
||||
{
|
||||
if(GSTransferStatus.PTH3 <= IMAGE_MODE && gifRegs->mode.IMT)
|
||||
if(GSTransferStatus.PTH3 <= IMAGE_MODE && gifRegs.mode.IMT)
|
||||
{
|
||||
if((gifRegs->stat.P1Q == true || gifRegs->stat.P2Q == true) || (gifRegs->stat.APATH > GIF_APATH_IDLE && gifRegs->stat.APATH < GIF_APATH3))
|
||||
if((gifRegs.stat.P1Q == true || gifRegs.stat.P2Q == true) || (gifRegs.stat.APATH > GIF_APATH_IDLE && gifRegs.stat.APATH < GIF_APATH3))
|
||||
{
|
||||
if((vif1.cmd & 0x7f) != 0x51 || gifRegs->stat.P1Q == true)
|
||||
if((vif1.cmd & 0x7f) != 0x51 || gifRegs.stat.P1Q == true)
|
||||
{
|
||||
gifRegs->stat.IP3 = true;
|
||||
if(gifRegs->stat.P1Q) gsPath1Interrupt();
|
||||
gifRegs.stat.IP3 = true;
|
||||
if(gifRegs.stat.P1Q) gsPath1Interrupt();
|
||||
CPU_INT(DMAC_GIF, 16);
|
||||
return false;
|
||||
}
|
||||
|
@ -244,15 +244,15 @@ bool CheckPaths(int Channel)
|
|||
else if((GSTransferStatus.PTH3 == IDLE_MODE)|| (GSTransferStatus.PTH3 == STOPPED_MODE))
|
||||
{
|
||||
//This should cover both scenarios, as DIRECTHL doesn't gain priority when image mode is running (PENDINGIMAGE_MODE == fininshed).
|
||||
if((gifRegs->stat.P1Q == true || gifRegs->stat.P2Q == true) || (gifRegs->stat.APATH > GIF_APATH_IDLE && gifRegs->stat.APATH < GIF_APATH3))
|
||||
if((gifRegs.stat.P1Q == true || gifRegs.stat.P2Q == true) || (gifRegs.stat.APATH > GIF_APATH_IDLE && gifRegs.stat.APATH < GIF_APATH3))
|
||||
{
|
||||
gifRegs->stat.IP3 = true;
|
||||
gifRegs.stat.IP3 = true;
|
||||
CPU_INT(DMAC_GIF, 16);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
gifRegs->stat.IP3 = false;
|
||||
gifRegs.stat.IP3 = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -262,18 +262,18 @@ void GIFdma()
|
|||
|
||||
gscycles = prevcycles;
|
||||
|
||||
if (gifRegs->ctrl.PSE) // temporarily stop
|
||||
if (gifRegs.ctrl.PSE) // temporarily stop
|
||||
{
|
||||
Console.WriteLn("Gif dma temp paused? (non MFIFO GIF)");
|
||||
CPU_INT(DMAC_GIF, 16);
|
||||
return;
|
||||
}
|
||||
|
||||
if ((dmacRegs->ctrl.STD == STD_GIF) && (prevcycles != 0))
|
||||
if ((dmacRegs.ctrl.STD == STD_GIF) && (prevcycles != 0))
|
||||
{
|
||||
//Console.WriteLn("GS Stall Control Source = %x, Drain = %x\n MADR = %x, STADR = %x", (psHu32(0xe000) >> 4) & 0x3, (psHu32(0xe000) >> 6) & 0x3, gif->madr, psHu32(DMAC_STADR));
|
||||
//Console.WriteLn("GS Stall Control Source = %x, Drain = %x\n MADR = %x, STADR = %x", (psHu32(0xe000) >> 4) & 0x3, (psHu32(0xe000) >> 6) & 0x3, gifch.madr, psHu32(DMAC_STADR));
|
||||
|
||||
if ((gif->madr + (gif->qwc * 16)) > dmacRegs->stadr.ADDR)
|
||||
if ((gifch.madr + (gifch.qwc * 16)) > dmacRegs.stadr.ADDR)
|
||||
{
|
||||
CPU_INT(DMAC_GIF, 4);
|
||||
gscycles = 0;
|
||||
|
@ -281,24 +281,24 @@ void GIFdma()
|
|||
}
|
||||
|
||||
prevcycles = 0;
|
||||
gif->qwc = 0;
|
||||
gifch.qwc = 0;
|
||||
}
|
||||
|
||||
clearFIFOstuff(true);
|
||||
gifRegs->stat.FQC = min((u16)0x10, gif->qwc);// FQC=31, hack ;) (for values of 31 that equal 16) [ used to be 0xE00; // APATH=3]
|
||||
gifRegs.stat.FQC = min((u16)0x10, gifch.qwc);// FQC=31, hack ;) (for values of 31 that equal 16) [ used to be 0xE00; // APATH=3]
|
||||
|
||||
|
||||
if (vif1Regs->mskpath3 || gifRegs->mode.M3R)
|
||||
if (vif1Regs.mskpath3 || gifRegs.mode.M3R)
|
||||
{
|
||||
if (gif->qwc == 0)
|
||||
if (gifch.qwc == 0)
|
||||
{
|
||||
if ((gif->chcr.MOD == CHAIN_MODE) && gif->chcr.STR)
|
||||
if ((gifch.chcr.MOD == CHAIN_MODE) && gifch.chcr.STR)
|
||||
{
|
||||
//DevCon.Warning("GIF Reading Tag Masked MSK = %x", vif1Regs->mskpath3);
|
||||
//DevCon.Warning("GIF Reading Tag Masked MSK = %x", vif1Regs.mskpath3);
|
||||
ptag = ReadTag();
|
||||
gifRegs->stat.FQC = min((u16)0x10, gif->qwc);// FQC=31, hack ;) (for values of 31 that equal 16) [ used to be 0xE00; // APATH=3]
|
||||
gifRegs.stat.FQC = min((u16)0x10, gifch.qwc);// FQC=31, hack ;) (for values of 31 that equal 16) [ used to be 0xE00; // APATH=3]
|
||||
if (ptag == NULL) return;
|
||||
GIF_LOG("PTH3 MASK gifdmaChain %8.8x_%8.8x size=%d, id=%d, addr=%lx tadr=%lx", ptag[1]._u32, ptag[0]._u32, gif->qwc, ptag->ID, gif->madr, gif->tadr);
|
||||
GIF_LOG("PTH3 MASK gifdmaChain %8.8x_%8.8x size=%d, id=%d, addr=%lx tadr=%lx", ptag[1]._u32, ptag[0]._u32, gifch.qwc, ptag->ID, gifch.madr, gifch.tadr);
|
||||
|
||||
//Check TIE bit of CHCR and IRQ bit of tag
|
||||
if (checkTieBit(ptag)) GIF_LOG("PATH3 MSK dmaIrq Set");
|
||||
|
@ -308,26 +308,26 @@ void GIFdma()
|
|||
|
||||
if (GSTransferStatus.PTH3 == IDLE_MODE)
|
||||
{
|
||||
GIF_LOG("PTH3 MASK Paused by VIF QWC %x", gif->qwc);
|
||||
GIF_LOG("PTH3 MASK Paused by VIF QWC %x", gifch.qwc);
|
||||
|
||||
//DevCon.Warning("GIF Paused by Mask MSK = %x", vif1Regs->mskpath3);
|
||||
//DevCon.Warning("GIF Paused by Mask MSK = %x", vif1Regs.mskpath3);
|
||||
|
||||
if(gif->qwc == 0) gsInterrupt();
|
||||
else gifRegs->stat.set_flags(GIF_STAT_P3Q);
|
||||
if(gifch.qwc == 0) gsInterrupt();
|
||||
else gifRegs.stat.set_flags(GIF_STAT_P3Q);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
gifRegs->stat.FQC = min((u16)0x10, gif->qwc);// FQC=31, hack ;) (for values of 31 that equal 16) [ used to be 0xE00; // APATH=3]
|
||||
gifRegs.stat.FQC = min((u16)0x10, gifch.qwc);// FQC=31, hack ;) (for values of 31 that equal 16) [ used to be 0xE00; // APATH=3]
|
||||
//Check with Path3 masking games
|
||||
if (gif->qwc > 0) {
|
||||
gifRegs->stat.set_flags(GIF_STAT_P3Q);
|
||||
if (gifch.qwc > 0) {
|
||||
gifRegs.stat.set_flags(GIF_STAT_P3Q);
|
||||
if(CheckPaths(DMAC_GIF) == false) return;
|
||||
gifRegs->stat.clear_flags(GIF_STAT_P3Q);
|
||||
gifRegs.stat.clear_flags(GIF_STAT_P3Q);
|
||||
GIF_LOG("PTH3 MASK Transferring");
|
||||
GIFchain();
|
||||
/*if(GSTransferStatus.PTH3 == PENDINGSTOP_MODE && gifRegs->stat.APATH == GIF_APATH_IDLE)
|
||||
/*if(GSTransferStatus.PTH3 == PENDINGSTOP_MODE && gifRegs.stat.APATH == GIF_APATH_IDLE)
|
||||
{
|
||||
GSTransferStatus.PTH3 = STOPPED_MODE;
|
||||
}*/
|
||||
|
@ -338,54 +338,54 @@ void GIFdma()
|
|||
}
|
||||
|
||||
// Transfer Dn_QWC from Dn_MADR to GIF
|
||||
if ((gif->chcr.MOD == NORMAL_MODE) || (gif->qwc > 0)) // Normal Mode
|
||||
if ((gifch.chcr.MOD == NORMAL_MODE) || (gifch.qwc > 0)) // Normal Mode
|
||||
{
|
||||
|
||||
if ((dmacRegs->ctrl.STD == STD_GIF) && (gif->chcr.MOD == NORMAL_MODE))
|
||||
if ((dmacRegs.ctrl.STD == STD_GIF) && (gifch.chcr.MOD == NORMAL_MODE))
|
||||
{
|
||||
//Console.WriteLn("DMA Stall Control on GIF normal");
|
||||
}
|
||||
gifRegs->stat.FQC = min((u16)0x10, gif->qwc);// FQC=31, hack ;) (for values of 31 that equal 16) [ used to be 0xE00; // APATH=3]
|
||||
gifRegs.stat.FQC = min((u16)0x10, gifch.qwc);// FQC=31, hack ;) (for values of 31 that equal 16) [ used to be 0xE00; // APATH=3]
|
||||
//Check with Path3 masking games
|
||||
//DevCon.Warning("GIF Transferring Normal/ChainQWC MSK = %x", vif1Regs->mskpath3);
|
||||
//DevCon.Warning("GIF Transferring Normal/ChainQWC MSK = %x", vif1Regs.mskpath3);
|
||||
|
||||
|
||||
|
||||
if (gif->qwc > 0) {
|
||||
gifRegs->stat.set_flags(GIF_STAT_P3Q);
|
||||
if (gifch.qwc > 0) {
|
||||
gifRegs.stat.set_flags(GIF_STAT_P3Q);
|
||||
if(CheckPaths(DMAC_GIF) == false) return;
|
||||
gifRegs->stat.clear_flags(GIF_STAT_P3Q);
|
||||
gifRegs.stat.clear_flags(GIF_STAT_P3Q);
|
||||
GIFchain(); //Transfers the data set by the switch
|
||||
CPU_INT(DMAC_GIF, gscycles);
|
||||
return;
|
||||
} else DevCon.Warning("GIF Normalmode or QWC going to invalid case? CHCR %x", gif->chcr._u32);
|
||||
} else DevCon.Warning("GIF Normalmode or QWC going to invalid case? CHCR %x", gifch.chcr._u32);
|
||||
|
||||
//else DevCon.WriteLn("GIFdma() case 2, but qwc = 0!"); //Don't do 0 GIFchain and then return, fixes Dual Hearts
|
||||
}
|
||||
|
||||
if ((gif->chcr.MOD == CHAIN_MODE) && (!gspath3done)) // Chain Mode
|
||||
if ((gifch.chcr.MOD == CHAIN_MODE) && (!gspath3done)) // Chain Mode
|
||||
{
|
||||
ptag = ReadTag();
|
||||
if (ptag == NULL) return;
|
||||
//DevCon.Warning("GIF Reading Tag MSK = %x", vif1Regs->mskpath3);
|
||||
GIF_LOG("gifdmaChain %8.8x_%8.8x size=%d, id=%d, addr=%lx tadr=%lx", ptag[1]._u32, ptag[0]._u32, gif->qwc, ptag->ID, gif->madr, gif->tadr);
|
||||
gifRegs->stat.FQC = min((u16)0x10, gif->qwc);// FQC=31, hack ;) (for values of 31 that equal 16) [ used to be 0xE00; // APATH=3]
|
||||
if (dmacRegs->ctrl.STD == STD_GIF)
|
||||
//DevCon.Warning("GIF Reading Tag MSK = %x", vif1Regs.mskpath3);
|
||||
GIF_LOG("gifdmaChain %8.8x_%8.8x size=%d, id=%d, addr=%lx tadr=%lx", ptag[1]._u32, ptag[0]._u32, gifch.qwc, ptag->ID, gifch.madr, gifch.tadr);
|
||||
gifRegs.stat.FQC = min((u16)0x10, gifch.qwc);// FQC=31, hack ;) (for values of 31 that equal 16) [ used to be 0xE00; // APATH=3]
|
||||
if (dmacRegs.ctrl.STD == STD_GIF)
|
||||
{
|
||||
// there are still bugs, need to also check if gif->madr +16*qwc >= stadr, if not, stall
|
||||
if (!gspath3done && ((gif->madr + (gif->qwc * 16)) > dmacRegs->stadr.ADDR) && (ptag->ID == TAG_REFS))
|
||||
// there are still bugs, need to also check if gifch.madr +16*qwc >= stadr, if not, stall
|
||||
if (!gspath3done && ((gifch.madr + (gifch.qwc * 16)) > dmacRegs.stadr.ADDR) && (ptag->ID == TAG_REFS))
|
||||
{
|
||||
// stalled.
|
||||
// We really need to test this. Pay attention to prevcycles, as it used to trigger GIFchains in the code above. (rama)
|
||||
//Console.WriteLn("GS Stall Control start Source = %x, Drain = %x\n MADR = %x, STADR = %x", (psHu32(0xe000) >> 4) & 0x3, (psHu32(0xe000) >> 6) & 0x3,gif->madr, psHu32(DMAC_STADR));
|
||||
//Console.WriteLn("GS Stall Control start Source = %x, Drain = %x\n MADR = %x, STADR = %x", (psHu32(0xe000) >> 4) & 0x3, (psHu32(0xe000) >> 6) & 0x3,gifch.madr, psHu32(DMAC_STADR));
|
||||
prevcycles = gscycles;
|
||||
//gif->tadr -= 16;
|
||||
//gifch.tadr -= 16;
|
||||
// Quake III revolution wants to see tadr move.
|
||||
// Simple Media System (homebrew) as well.
|
||||
// -16 also seems right (it shifts the bg image right if anything else).
|
||||
gif->tadr -= 16;
|
||||
gifch.tadr -= 16;
|
||||
// Next line also needs to be here, according to ref
|
||||
gif->qwc = 0;
|
||||
gifch.qwc = 0;
|
||||
hwDmacIrq(DMAC_STALL_SIS);
|
||||
CPU_INT(DMAC_GIF, gscycles);
|
||||
gscycles = 0;
|
||||
|
@ -394,7 +394,7 @@ void GIFdma()
|
|||
}
|
||||
|
||||
checkTieBit(ptag);
|
||||
/*if(gif->qwc == 0)
|
||||
/*if(gifch.qwc == 0)
|
||||
{
|
||||
gsInterrupt();
|
||||
return;
|
||||
|
@ -403,34 +403,34 @@ void GIFdma()
|
|||
|
||||
prevcycles = 0;
|
||||
CPU_INT(DMAC_GIF, gscycles);
|
||||
gifRegs->stat.FQC = min((u16)0x10, gif->qwc);// FQC=31, hack ;) (for values of 31 that equal 16) [ used to be 0xE00; // OPH=1 | APATH=3]
|
||||
gifRegs.stat.FQC = min((u16)0x10, gifch.qwc);// FQC=31, hack ;) (for values of 31 that equal 16) [ used to be 0xE00; // OPH=1 | APATH=3]
|
||||
}
|
||||
|
||||
void dmaGIF()
|
||||
{
|
||||
//We used to add wait time for the buffer to fill here, fixing some timing problems in path 3 masking
|
||||
//It takes the time of 24 QW for the BUS to become ready - The Punisher And Streetball
|
||||
//DevCon.Warning("dmaGIFstart chcr = %lx, madr = %lx, qwc = %lx\n tadr = %lx, asr0 = %lx, asr1 = %lx", gif->chcr._u32, gif->madr, gif->qwc, gif->tadr, gif->asr0, gif->asr1);
|
||||
//DevCon.Warning("dmaGIFstart chcr = %lx, madr = %lx, qwc = %lx\n tadr = %lx, asr0 = %lx, asr1 = %lx", gifch.chcr._u32, gifch.madr, gifch.qwc, gifch.tadr, gifch.asr0, gifch.asr1);
|
||||
|
||||
gspath3done = false; // For some reason this doesn't clear? So when the system starts the thread, we will clear it :)
|
||||
|
||||
gifRegs->stat.FQC |= 0x10; // hack ;)
|
||||
gifRegs.stat.FQC |= 0x10; // hack ;)
|
||||
|
||||
if (gif->chcr.MOD == NORMAL_MODE) { //Else it really is a normal transfer and we want to quit, else it gets confused with chains
|
||||
if (gifch.chcr.MOD == NORMAL_MODE) { //Else it really is a normal transfer and we want to quit, else it gets confused with chains
|
||||
gspath3done = true;
|
||||
}
|
||||
clearFIFOstuff(true);
|
||||
|
||||
if(gif->chcr.MOD == CHAIN_MODE && gif->qwc > 0)
|
||||
if(gifch.chcr.MOD == CHAIN_MODE && gifch.qwc > 0)
|
||||
{
|
||||
//DevCon.Warning(L"GIF QWC on Chain " + gif->chcr.desc());
|
||||
if ((gif->chcr.tag().ID == TAG_REFE) || (gif->chcr.tag().ID == TAG_END))
|
||||
//DevCon.Warning(L"GIF QWC on Chain " + gifch.chcr.desc());
|
||||
if ((gifch.chcr.tag().ID == TAG_REFE) || (gifch.chcr.tag().ID == TAG_END))
|
||||
{
|
||||
gspath3done = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (dmacRegs->ctrl.MFD == MFD_GIF) // GIF MFIFO
|
||||
if (dmacRegs.ctrl.MFD == MFD_GIF) // GIF MFIFO
|
||||
{
|
||||
//Console.WriteLn("GIF MFIFO");
|
||||
gifMFIFOInterrupt();
|
||||
|
@ -443,7 +443,7 @@ void dmaGIF()
|
|||
// called from only one location, so forceinline it:
|
||||
static __fi bool mfifoGIFrbTransfer()
|
||||
{
|
||||
u32 mfifoqwc = min(gifqwc, (u32)gif->qwc);
|
||||
u32 mfifoqwc = min(gifqwc, (u32)gifch.qwc);
|
||||
u32 *src;
|
||||
|
||||
GetMTGS().PrepDataPacket(GIF_PATH_3, mfifoqwc);
|
||||
|
@ -453,21 +453,21 @@ static __fi bool mfifoGIFrbTransfer()
|
|||
// memory similarly to how it wraps VU1 memory on PATH1.
|
||||
|
||||
/* Check if the transfer should wrap around the ring buffer */
|
||||
if ((gif->madr + mfifoqwc * 16) > (dmacRegs->rbor.ADDR + dmacRegs->rbsr.RMSK + 16))
|
||||
if ((gifch.madr + mfifoqwc * 16) > (dmacRegs.rbor.ADDR + dmacRegs.rbsr.RMSK + 16))
|
||||
{
|
||||
uint s1 = ((dmacRegs->rbor.ADDR + dmacRegs->rbsr.RMSK + 16) - gif->madr) >> 4;
|
||||
uint s1 = ((dmacRegs.rbor.ADDR + dmacRegs.rbsr.RMSK + 16) - gifch.madr) >> 4;
|
||||
uint s2 = (mfifoqwc - s1);
|
||||
|
||||
/* it does (wrap around), so first copy 's1' bytes from 'addr' to 'data' */
|
||||
/* and second copy 's2' bytes from 'maddr' to '&data[s1]' */
|
||||
|
||||
src = (u32*)PSM(gif->madr);
|
||||
src = (u32*)PSM(gifch.madr);
|
||||
if (src == NULL) return false;
|
||||
uint copied = GIFPath_CopyTag(GIF_PATH_3, (u128*)src, s1);
|
||||
|
||||
if (copied == s1) // but only copy second if first didn't abort prematurely for some reason.
|
||||
{
|
||||
src = (u32*)PSM(dmacRegs->rbor.ADDR);
|
||||
src = (u32*)PSM(dmacRegs.rbor.ADDR);
|
||||
if (src == NULL) return false;
|
||||
copied += GIFPath_CopyTag(GIF_PATH_3, (u128*)src, s2);
|
||||
}
|
||||
|
@ -476,11 +476,11 @@ static __fi bool mfifoGIFrbTransfer()
|
|||
}
|
||||
else
|
||||
{
|
||||
/* it doesn't, so just transfer 'qwc*16' words from 'gif->madr' to GS */
|
||||
src = (u32*)PSM(gif->madr);
|
||||
/* it doesn't, so just transfer 'qwc*16' words from 'gifch.madr' to GS */
|
||||
src = (u32*)PSM(gifch.madr);
|
||||
if (src == NULL) return false;
|
||||
mfifoqwc = GIFPath_CopyTag(GIF_PATH_3, (u128*)src, mfifoqwc);
|
||||
gif->madr = dmacRegs->rbor.ADDR + (gif->madr & dmacRegs->rbsr.RMSK);
|
||||
gifch.madr = dmacRegs.rbor.ADDR + (gifch.madr & dmacRegs.rbsr.RMSK);
|
||||
}
|
||||
|
||||
GetMTGS().SendDataPacket();
|
||||
|
@ -493,10 +493,10 @@ static __fi bool mfifoGIFrbTransfer()
|
|||
static __fi bool mfifoGIFchain()
|
||||
{
|
||||
/* Is QWC = 0? if so there is nothing to transfer */
|
||||
if (gif->qwc == 0) return true;
|
||||
if (gifch.qwc == 0) return true;
|
||||
|
||||
if (gif->madr >= dmacRegs->rbor.ADDR &&
|
||||
gif->madr <= (dmacRegs->rbor.ADDR + dmacRegs->rbsr.RMSK))
|
||||
if (gifch.madr >= dmacRegs.rbor.ADDR &&
|
||||
gifch.madr <= (dmacRegs.rbor.ADDR + dmacRegs.rbsr.RMSK))
|
||||
{
|
||||
if (!mfifoGIFrbTransfer()) return false;
|
||||
}
|
||||
|
@ -504,10 +504,10 @@ static __fi bool mfifoGIFchain()
|
|||
{
|
||||
int mfifoqwc;
|
||||
|
||||
tDMA_TAG *pMem = dmaGetAddr(gif->madr, false);
|
||||
tDMA_TAG *pMem = dmaGetAddr(gifch.madr, false);
|
||||
if (pMem == NULL) return false;
|
||||
|
||||
mfifoqwc = WRITERING_DMA(pMem, gif->qwc);
|
||||
mfifoqwc = WRITERING_DMA(pMem, gifch.qwc);
|
||||
mfifocycles += (mfifoqwc) * 2; /* guessing */
|
||||
}
|
||||
|
||||
|
@ -516,7 +516,7 @@ static __fi bool mfifoGIFchain()
|
|||
|
||||
static u32 qwctag(u32 mask)
|
||||
{
|
||||
return (dmacRegs->rbor.ADDR + (mask & dmacRegs->rbsr.RMSK));
|
||||
return (dmacRegs.rbor.ADDR + (mask & dmacRegs.rbsr.RMSK));
|
||||
}
|
||||
|
||||
void mfifoGIFtransfer(int qwc)
|
||||
|
@ -536,16 +536,16 @@ void mfifoGIFtransfer(int qwc)
|
|||
gifempty = false;
|
||||
}
|
||||
|
||||
if (gifRegs->ctrl.PSE) // temporarily stop
|
||||
if (gifRegs.ctrl.PSE) // temporarily stop
|
||||
{
|
||||
Console.WriteLn("Gif dma temp paused?");
|
||||
CPU_INT(DMAC_MFIFO_GIF, 16);
|
||||
return;
|
||||
}
|
||||
|
||||
if (gif->qwc == 0)
|
||||
if (gifch.qwc == 0)
|
||||
{
|
||||
if (gif->tadr == spr0->madr)
|
||||
if (gifch.tadr == spr0ch.madr)
|
||||
{
|
||||
//if( gifqwc > 1 ) DevCon.WriteLn("gif mfifo tadr==madr but qwc = %d", gifqwc);
|
||||
hwDmacIrq(DMAC_MFIFO_EMPTY);
|
||||
|
@ -554,55 +554,55 @@ void mfifoGIFtransfer(int qwc)
|
|||
return;
|
||||
}
|
||||
|
||||
gif->tadr = qwctag(gif->tadr);
|
||||
gifch.tadr = qwctag(gifch.tadr);
|
||||
|
||||
ptag = dmaGetAddr(gif->tadr, false);
|
||||
gif->unsafeTransfer(ptag);
|
||||
gif->madr = ptag[1]._u32;
|
||||
ptag = dmaGetAddr(gifch.tadr, false);
|
||||
gifch.unsafeTransfer(ptag);
|
||||
gifch.madr = ptag[1]._u32;
|
||||
|
||||
mfifocycles += 2;
|
||||
|
||||
GIF_LOG("dmaChain %8.8x_%8.8x size=%d, id=%d, madr=%lx, tadr=%lx mfifo qwc = %x spr0 madr = %x",
|
||||
ptag[1]._u32, ptag[0]._u32, gif->qwc, ptag->ID, gif->madr, gif->tadr, gifqwc, spr0->madr);
|
||||
ptag[1]._u32, ptag[0]._u32, gifch.qwc, ptag->ID, gifch.madr, gifch.tadr, gifqwc, spr0ch.madr);
|
||||
|
||||
gifqwc--;
|
||||
|
||||
switch (ptag->ID)
|
||||
{
|
||||
case TAG_REFE: // Refe - Transfer Packet According to ADDR field
|
||||
gif->tadr = qwctag(gif->tadr + 16);
|
||||
gifch.tadr = qwctag(gifch.tadr + 16);
|
||||
gifstate = GIF_STATE_DONE; //End Transfer
|
||||
break;
|
||||
|
||||
case TAG_CNT: // CNT - Transfer QWC following the tag.
|
||||
gif->madr = qwctag(gif->tadr + 16); //Set MADR to QW after Tag
|
||||
gif->tadr = qwctag(gif->madr + (gif->qwc << 4)); //Set TADR to QW following the data
|
||||
gifch.madr = qwctag(gifch.tadr + 16); //Set MADR to QW after Tag
|
||||
gifch.tadr = qwctag(gifch.madr + (gifch.qwc << 4)); //Set TADR to QW following the data
|
||||
gifstate = GIF_STATE_READY;
|
||||
break;
|
||||
|
||||
case TAG_NEXT: // Next - Transfer QWC following tag. TADR = ADDR
|
||||
{
|
||||
u32 temp = gif->madr; //Temporarily Store ADDR
|
||||
gif->madr = qwctag(gif->tadr + 16); //Set MADR to QW following the tag
|
||||
gif->tadr = temp; //Copy temporarily stored ADDR to Tag
|
||||
u32 temp = gifch.madr; //Temporarily Store ADDR
|
||||
gifch.madr = qwctag(gifch.tadr + 16); //Set MADR to QW following the tag
|
||||
gifch.tadr = temp; //Copy temporarily stored ADDR to Tag
|
||||
gifstate = GIF_STATE_READY;
|
||||
break;
|
||||
}
|
||||
|
||||
case TAG_REF: // Ref - Transfer QWC from ADDR field
|
||||
case TAG_REFS: // Refs - Transfer QWC from ADDR field (Stall Control)
|
||||
gif->tadr = qwctag(gif->tadr + 16); //Set TADR to next tag
|
||||
gifch.tadr = qwctag(gifch.tadr + 16); //Set TADR to next tag
|
||||
gifstate = GIF_STATE_READY;
|
||||
break;
|
||||
|
||||
case TAG_END: // End - Transfer QWC following the tag
|
||||
gif->madr = qwctag(gif->tadr + 16); //Set MADR to data following the tag
|
||||
gif->tadr = qwctag(gif->madr + (gif->qwc << 4)); //Set TADR to QW following the data
|
||||
gifch.madr = qwctag(gifch.tadr + 16); //Set MADR to data following the tag
|
||||
gifch.tadr = qwctag(gifch.madr + (gifch.qwc << 4)); //Set TADR to QW following the data
|
||||
gifstate = GIF_STATE_DONE; //End Transfer
|
||||
break;
|
||||
}
|
||||
|
||||
if ((gif->chcr.TIE) && (ptag->IRQ))
|
||||
if ((gifch.chcr.TIE) && (ptag->IRQ))
|
||||
{
|
||||
SPR_LOG("dmaIrq Set");
|
||||
gifstate = GIF_STATE_DONE;
|
||||
|
@ -612,14 +612,14 @@ void mfifoGIFtransfer(int qwc)
|
|||
|
||||
if (!mfifoGIFchain())
|
||||
{
|
||||
Console.WriteLn("GIF dmaChain error size=%d, madr=%lx, tadr=%lx", gif->qwc, gif->madr, gif->tadr);
|
||||
Console.WriteLn("GIF dmaChain error size=%d, madr=%lx, tadr=%lx", gifch.qwc, gifch.madr, gifch.tadr);
|
||||
gifstate = GIF_STATE_STALL;
|
||||
}
|
||||
|
||||
if ((gif->qwc == 0) && (gifstate & GIF_STATE_DONE)) gifstate = GIF_STATE_STALL;
|
||||
if ((gifch.qwc == 0) && (gifstate & GIF_STATE_DONE)) gifstate = GIF_STATE_STALL;
|
||||
CPU_INT(DMAC_MFIFO_GIF,mfifocycles);
|
||||
|
||||
SPR_LOG("mfifoGIFtransfer end %x madr %x, tadr %x", gif->chcr._u32, gif->madr, gif->tadr);
|
||||
SPR_LOG("mfifoGIFtransfer end %x madr %x, tadr %x", gifch.chcr._u32, gifch.madr, gifch.tadr);
|
||||
}
|
||||
|
||||
void gifMFIFOInterrupt()
|
||||
|
@ -634,16 +634,16 @@ void gifMFIFOInterrupt()
|
|||
return;
|
||||
}
|
||||
|
||||
if(GSTransferStatus.PTH3 == STOPPED_MODE && gifRegs->stat.APATH == GIF_APATH3 )
|
||||
if(GSTransferStatus.PTH3 == STOPPED_MODE && gifRegs.stat.APATH == GIF_APATH3 )
|
||||
{
|
||||
gifRegs->stat.OPH = false;
|
||||
gifRegs->stat.APATH = GIF_APATH_IDLE;
|
||||
if(gifRegs->stat.P1Q) gsPath1Interrupt();
|
||||
gifRegs.stat.OPH = false;
|
||||
gifRegs.stat.APATH = GIF_APATH_IDLE;
|
||||
if(gifRegs.stat.P1Q) gsPath1Interrupt();
|
||||
}
|
||||
|
||||
if(CheckPaths(11) == false) return;
|
||||
|
||||
if (!(gif->chcr.STR))
|
||||
if (!(gifch.chcr.STR))
|
||||
{
|
||||
Console.WriteLn("WTF GIFMFIFO");
|
||||
cpuRegs.interrupt &= ~(1 << 11);
|
||||
|
@ -659,7 +659,7 @@ void gifMFIFOInterrupt()
|
|||
gifstate |= GIF_STATE_EMPTY;
|
||||
gifempty = true;
|
||||
|
||||
gifRegs->stat.IMT = false;
|
||||
gifRegs.stat.IMT = false;
|
||||
return;
|
||||
}
|
||||
mfifoGIFtransfer(0);
|
||||
|
@ -667,7 +667,7 @@ void gifMFIFOInterrupt()
|
|||
}
|
||||
|
||||
#ifdef PCSX2_DEVBUILD
|
||||
if ((gifstate & GIF_STATE_READY) || (gif->qwc > 0))
|
||||
if ((gifstate & GIF_STATE_READY) || (gifch.qwc > 0))
|
||||
{
|
||||
Console.Error("gifMFIFO Panic > Shouldn't go here!");
|
||||
return;
|
||||
|
@ -679,10 +679,10 @@ void gifMFIFOInterrupt()
|
|||
gspath3done = false;
|
||||
gscycles = 0;
|
||||
|
||||
gifRegs->stat.clear_flags(GIF_STAT_APATH3 | GIF_STAT_P3Q | GIF_STAT_FQC); // APATH, P3Q, FQC = 0
|
||||
gifRegs.stat.clear_flags(GIF_STAT_APATH3 | GIF_STAT_P3Q | GIF_STAT_FQC); // APATH, P3Q, FQC = 0
|
||||
|
||||
vif1Regs->stat.VGW = false;
|
||||
gif->chcr.STR = false;
|
||||
vif1Regs.stat.VGW = false;
|
||||
gifch.chcr.STR = false;
|
||||
gifstate = GIF_STATE_READY;
|
||||
hwDmacIrq(DMAC_GIF);
|
||||
clearFIFOstuff(false);
|
||||
|
|
|
@ -277,7 +277,7 @@ struct GIFregisters
|
|||
u32 padding9[3];
|
||||
};
|
||||
|
||||
#define gifRegs ((GIFregisters*)(eeMem->HW+0x3000))
|
||||
static GIFregisters& gifRegs = (GIFregisters&)eeHw[0x3000];
|
||||
|
||||
extern tGSTransferStatus GSTransferStatus;
|
||||
|
||||
|
|
99
pcsx2/Hw.cpp
99
pcsx2/Hw.cpp
|
@ -18,6 +18,7 @@
|
|||
|
||||
#include "Hardware.h"
|
||||
#include "newVif.h"
|
||||
#include "IPU/IPUdma.h"
|
||||
|
||||
using namespace R5900;
|
||||
|
||||
|
@ -45,17 +46,12 @@ void hwInit()
|
|||
hwInitialized = true;
|
||||
}
|
||||
|
||||
/*void hwShutdown()
|
||||
{
|
||||
ipuShutdown();
|
||||
}*/
|
||||
|
||||
void hwReset()
|
||||
{
|
||||
hwInit();
|
||||
|
||||
memzero_ptr<Ps2MemSize::Hardware>( eeMem->HW );
|
||||
//memset(eeMem->HW+0x2000, 0, 0x0000e000);
|
||||
memzero_ptr<Ps2MemSize::Hardware>( eeHw );
|
||||
//memset(eeHw+0x2000, 0, 0x0000e000);
|
||||
|
||||
psHu32(SBUS_F260) = 0x1D000060;
|
||||
|
||||
|
@ -72,6 +68,9 @@ void hwReset()
|
|||
ipuReset();
|
||||
vif0Reset();
|
||||
vif1Reset();
|
||||
|
||||
// needed for legacy DMAC
|
||||
ipuDmaReset();
|
||||
}
|
||||
|
||||
__fi void intcInterrupt()
|
||||
|
@ -104,7 +103,7 @@ __fi void dmacInterrupt()
|
|||
return;
|
||||
}
|
||||
|
||||
if (!(dmacRegs->ctrl.DMAE) || psHu8(DMAC_ENABLER+2) == 1)
|
||||
if (!(dmacRegs.ctrl.DMAE) || psHu8(DMAC_ENABLER+2) == 1)
|
||||
{
|
||||
//DevCon.Warning("DMAC Suspended or Disabled on interrupt");
|
||||
return;
|
||||
|
@ -131,7 +130,7 @@ void hwDmacIrq(int n)
|
|||
__ri bool hwMFIFOWrite(u32 addr, const u128* data, uint qwc)
|
||||
{
|
||||
// all FIFO addresses should always be QWC-aligned.
|
||||
pxAssume((dmacRegs->rbor.ADDR & 15) == 0);
|
||||
pxAssume((dmacRegs.rbor.ADDR & 15) == 0);
|
||||
pxAssume((addr & 15) == 0);
|
||||
|
||||
// DMAC Address resolution: FIFO can be placed anywhere in the *physical* memory map
|
||||
|
@ -139,24 +138,24 @@ __ri bool hwMFIFOWrite(u32 addr, const u128* data, uint qwc)
|
|||
// valid/invalid page areas of ram, so realistically we only need to test the base address
|
||||
// of the FIFO for address validity.
|
||||
|
||||
if (u128* dst = (u128*)PSM(dmacRegs->rbor.ADDR))
|
||||
if (u128* dst = (u128*)PSM(dmacRegs.rbor.ADDR))
|
||||
{
|
||||
const u32 ringsize = (dmacRegs->rbsr.RMSK / 16) + 1;
|
||||
pxAssertMsg( PSM(dmacRegs->rbor.ADDR+ringsize-1) != NULL, "Scratchpad/MFIFO ringbuffer spans into invalid (unmapped) physical memory!" );
|
||||
uint startpos = (addr & dmacRegs->rbsr.RMSK)/16;
|
||||
const u32 ringsize = (dmacRegs.rbsr.RMSK / 16) + 1;
|
||||
pxAssertMsg( PSM(dmacRegs.rbor.ADDR+ringsize-1) != NULL, "Scratchpad/MFIFO ringbuffer spans into invalid (unmapped) physical memory!" );
|
||||
uint startpos = (addr & dmacRegs.rbsr.RMSK)/16;
|
||||
MemCopy_WrappedDest( data, dst, startpos, ringsize, qwc );
|
||||
}
|
||||
else
|
||||
{
|
||||
SPR_LOG( "Scratchpad/MFIFO: invalid base physical address: 0x%08x", dmacRegs->rbor.ADDR );
|
||||
pxFailDev( wxsFormat( L"Scratchpad/MFIFO: Invalid base physical address: 0x%08x", dmacRegs->rbor.ADDR) );
|
||||
SPR_LOG( "Scratchpad/MFIFO: invalid base physical address: 0x%08x", dmacRegs.rbor.ADDR );
|
||||
pxFailDev( wxsFormat( L"Scratchpad/MFIFO: Invalid base physical address: 0x%08x", dmacRegs.rbor.ADDR) );
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
__ri bool hwDmacSrcChainWithStack(DMACh *dma, int id) {
|
||||
__ri bool hwDmacSrcChainWithStack(DMACh& dma, int id) {
|
||||
switch (id) {
|
||||
case TAG_REFE: // Refe - Transfer Packet According to ADDR field
|
||||
//End Transfer
|
||||
|
@ -164,49 +163,49 @@ __ri bool hwDmacSrcChainWithStack(DMACh *dma, int id) {
|
|||
|
||||
case TAG_CNT: // CNT - Transfer QWC following the tag.
|
||||
// Set MADR to QW afer tag, and set TADR to QW following the data.
|
||||
dma->madr = dma->tadr + 16;
|
||||
dma->tadr = dma->madr + (dma->qwc << 4);
|
||||
dma.madr = dma.tadr + 16;
|
||||
dma.tadr = dma.madr + (dma.qwc << 4);
|
||||
return false;
|
||||
|
||||
case TAG_NEXT: // Next - Transfer QWC following tag. TADR = ADDR
|
||||
{
|
||||
// Set MADR to QW following the tag, and set TADR to the address formerly in MADR.
|
||||
u32 temp = dma->madr;
|
||||
dma->madr = dma->tadr + 16;
|
||||
dma->tadr = temp;
|
||||
u32 temp = dma.madr;
|
||||
dma.madr = dma.tadr + 16;
|
||||
dma.tadr = temp;
|
||||
return false;
|
||||
}
|
||||
case TAG_REF: // Ref - Transfer QWC from ADDR field
|
||||
case TAG_REFS: // Refs - Transfer QWC from ADDR field (Stall Control)
|
||||
//Set TADR to next tag
|
||||
dma->tadr += 16;
|
||||
dma.tadr += 16;
|
||||
return false;
|
||||
|
||||
case TAG_CALL: // Call - Transfer QWC following the tag, save succeeding tag
|
||||
{
|
||||
// Store the address in MADR in temp, and set MADR to the data following the tag.
|
||||
u32 temp = dma->madr;
|
||||
dma->madr = dma->tadr + 16;
|
||||
u32 temp = dma.madr;
|
||||
dma.madr = dma.tadr + 16;
|
||||
|
||||
if(temp == 0)
|
||||
{
|
||||
DevCon.Warning("DMA Chain CALL next tag error. Tag Addr = 0");
|
||||
dma->tadr = dma->madr + (dma->qwc << 4);
|
||||
dma.tadr = dma.madr + (dma.qwc << 4);
|
||||
return false;
|
||||
}
|
||||
// Stash an address on the address stack pointer.
|
||||
switch(dma->chcr.ASP)
|
||||
switch(dma.chcr.ASP)
|
||||
{
|
||||
case 0: //Check if ASR0 is empty
|
||||
// Store the succeeding tag in asr0, and mark chcr as having 1 address.
|
||||
dma->asr0 = dma->madr + (dma->qwc << 4);
|
||||
dma->chcr.ASP++;
|
||||
dma.asr0 = dma.madr + (dma.qwc << 4);
|
||||
dma.chcr.ASP++;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
// Store the succeeding tag in asr1, and mark chcr as having 2 addresses.
|
||||
dma->asr1 = dma->madr + (dma->qwc << 4);
|
||||
dma->chcr.ASP++;
|
||||
dma.asr1 = dma.madr + (dma.qwc << 4);
|
||||
dma.chcr.ASP++;
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -215,48 +214,48 @@ __ri bool hwDmacSrcChainWithStack(DMACh *dma, int id) {
|
|||
}
|
||||
|
||||
// Set TADR to the address from MADR we stored in temp.
|
||||
dma->tadr = temp;
|
||||
dma.tadr = temp;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
case TAG_RET: // Ret - Transfer QWC following the tag, load next tag
|
||||
//Set MADR to data following the tag.
|
||||
dma->madr = dma->tadr + 16;
|
||||
dma.madr = dma.tadr + 16;
|
||||
|
||||
// Snag an address from the address stack pointer.
|
||||
switch(dma->chcr.ASP)
|
||||
switch(dma.chcr.ASP)
|
||||
{
|
||||
case 2:
|
||||
// Pull asr1 from the stack, give it to TADR, and decrease the # of addresses.
|
||||
dma->tadr = dma->asr1;
|
||||
dma->asr1 = 0;
|
||||
dma->chcr.ASP--;
|
||||
dma.tadr = dma.asr1;
|
||||
dma.asr1 = 0;
|
||||
dma.chcr.ASP--;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
// Pull asr0 from the stack, give it to TADR, and decrease the # of addresses.
|
||||
dma->tadr = dma->asr0;
|
||||
dma->asr0 = 0;
|
||||
dma->chcr.ASP--;
|
||||
dma.tadr = dma.asr0;
|
||||
dma.asr0 = 0;
|
||||
dma.chcr.ASP--;
|
||||
break;
|
||||
|
||||
case 0:
|
||||
// There aren't any addresses to pull, so end the transfer.
|
||||
//dma->tadr += 16; //Clear tag address - Kills Klonoa 2
|
||||
//dma.tadr += 16; //Clear tag address - Kills Klonoa 2
|
||||
return true;
|
||||
|
||||
default:
|
||||
// If ASR1 and ASR0 are messed up, end the transfer.
|
||||
//Console.Error("TAG_RET: ASR 1 & 0 == 1. This shouldn't happen!");
|
||||
//dma->tadr += 16; //Clear tag address - Kills Klonoa 2
|
||||
//dma.tadr += 16; //Clear tag address - Kills Klonoa 2
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
||||
case TAG_END: // End - Transfer QWC following the tag
|
||||
//Set MADR to data following the tag, and end the transfer.
|
||||
dma->madr = dma->tadr + 16;
|
||||
dma.madr = dma.tadr + 16;
|
||||
//Don't Increment tadr; breaks Soul Calibur II and III
|
||||
return true;
|
||||
}
|
||||
|
@ -264,7 +263,7 @@ __ri bool hwDmacSrcChainWithStack(DMACh *dma, int id) {
|
|||
return false;
|
||||
}
|
||||
|
||||
bool hwDmacSrcChain(DMACh *dma, int id)
|
||||
bool hwDmacSrcChain(DMACh& dma, int id)
|
||||
{
|
||||
u32 temp;
|
||||
|
||||
|
@ -276,26 +275,26 @@ bool hwDmacSrcChain(DMACh *dma, int id)
|
|||
|
||||
case TAG_CNT: // CNT - Transfer QWC following the tag.
|
||||
// Set MADR to QW after the tag, and TADR to QW following the data.
|
||||
dma->madr = dma->tadr + 16;
|
||||
dma->tadr = dma->madr + (dma->qwc << 4);
|
||||
dma.madr = dma.tadr + 16;
|
||||
dma.tadr = dma.madr + (dma.qwc << 4);
|
||||
return false;
|
||||
|
||||
case TAG_NEXT: // Next - Transfer QWC following tag. TADR = ADDR
|
||||
// Set MADR to QW following the tag, and set TADR to the address formerly in MADR.
|
||||
temp = dma->madr;
|
||||
dma->madr = dma->tadr + 16;
|
||||
dma->tadr = temp;
|
||||
temp = dma.madr;
|
||||
dma.madr = dma.tadr + 16;
|
||||
dma.tadr = temp;
|
||||
return false;
|
||||
|
||||
case TAG_REF: // Ref - Transfer QWC from ADDR field
|
||||
case TAG_REFS: // Refs - Transfer QWC from ADDR field (Stall Control)
|
||||
//Set TADR to next tag
|
||||
dma->tadr += 16;
|
||||
dma.tadr += 16;
|
||||
return false;
|
||||
|
||||
case TAG_END: // End - Transfer QWC following the tag
|
||||
//Set MADR to data following the tag, and end the transfer.
|
||||
dma->madr = dma->tadr + 16;
|
||||
dma.madr = dma.tadr + 16;
|
||||
//Don't Increment tadr; breaks Soul Calibur II and III
|
||||
return true;
|
||||
}
|
||||
|
|
235
pcsx2/Hw.h
235
pcsx2/Hw.h
|
@ -13,28 +13,84 @@
|
|||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __HW_H__
|
||||
#define __HW_H__
|
||||
namespace EEMemoryMap
|
||||
{
|
||||
static const uint RCNT0_Start = 0x10000000;
|
||||
static const uint RCNT0_End = 0x10000800;
|
||||
static const uint RCNT1_Start = 0x10000800;
|
||||
static const uint RCNT1_End = 0x10001000;
|
||||
static const uint RCNT2_Start = 0x10001000;
|
||||
static const uint RCNT2_End = 0x10001800;
|
||||
static const uint RCNT3_Start = 0x10001800;
|
||||
static const uint RCNT3_End = 0x10002000;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Hardware FIFOs (128 bit access only!)
|
||||
//
|
||||
// VIF0 -- 0x10004000 -- eeMem->HW[0x4000]
|
||||
// VIF1 -- 0x10005000 -- eeMem->HW[0x5000]
|
||||
// GIF -- 0x10006000 -- eeMem->HW[0x6000]
|
||||
// IPUout -- 0x10007000 -- eeMem->HW[0x7000]
|
||||
// IPUin -- 0x10007010 -- eeMem->HW[0x7010]
|
||||
static const uint IPU_Start = 0x10002000;
|
||||
static const uint IPU_End = 0x10003000;
|
||||
|
||||
void __fastcall ReadFIFO_page_4(u32 mem, mem128_t *out);
|
||||
void __fastcall ReadFIFO_page_5(u32 mem, mem128_t *out);
|
||||
void __fastcall ReadFIFO_page_6(u32 mem, mem128_t *out);
|
||||
void __fastcall ReadFIFO_page_7(u32 mem, mem128_t *out);
|
||||
static const uint GIF_Start = 0x10003000;
|
||||
static const uint GIF_End = 0x10003800;
|
||||
|
||||
void __fastcall WriteFIFO_page_4(u32 mem, const mem128_t *value);
|
||||
void __fastcall WriteFIFO_page_5(u32 mem, const mem128_t *value);
|
||||
void __fastcall WriteFIFO_page_6(u32 mem, const mem128_t *value);
|
||||
void __fastcall WriteFIFO_page_7(u32 mem, const mem128_t *value);
|
||||
static const uint VIF0_Start = 0x10003800;
|
||||
static const uint VIF0_End = 0x10003C00;
|
||||
static const uint VIF1_Start = 0x10003C00;
|
||||
static const uint VIF1_End = 0x10004000;
|
||||
|
||||
static const uint VIF0_FIFO_Start = 0x10004000;
|
||||
static const uint VIF0_FIFO_End = 0x10005000;
|
||||
static const uint VIF1_FIFO_Start = 0x10005000;
|
||||
static const uint VIF1_FIFO_End = 0x10006000;
|
||||
static const uint GIF_FIFO_Start = 0x10006000;
|
||||
static const uint GIF_FIFO_End = 0x10007000;
|
||||
static const uint IPU_FIFO_Start = 0x10007000;
|
||||
static const uint IPU_FIFO_End = 0x10008000;
|
||||
|
||||
static const uint VIF0dma_Start = 0x10008000;
|
||||
static const uint VIF0dma_End = 0x10009000;
|
||||
static const uint VIF1dma_Start = 0x10009000;
|
||||
static const uint VIF1dma_End = 0x1000A000;
|
||||
|
||||
static const uint GIFdma_Start = 0x1000A000;
|
||||
static const uint GIFdma_End = 0x1000B000;
|
||||
|
||||
static const uint fromIPU_Start = 0x1000B000;
|
||||
static const uint fromIPU_End = 0x1000B400;
|
||||
static const uint toIPU_Start = 0x1000B400;
|
||||
static const uint toIPU_End = 0x1000C000;
|
||||
|
||||
static const uint SIF0dma_Start = 0x1000C000;
|
||||
static const uint SIF0dma_End = 0x1000C400;
|
||||
static const uint SIF1dma_Start = 0x1000C400;
|
||||
static const uint SIF1dma_End = 0x1000C800;
|
||||
static const uint SIF2dma_Start = 0x1000C800;
|
||||
static const uint SIF2dma_End = 0x1000D000;
|
||||
|
||||
static const uint fromSPR_Start = 0x1000D000;
|
||||
static const uint fromSPR_End = 0x1000D400;
|
||||
static const uint toSPR_Start = 0x1000D400;
|
||||
static const uint toSPR_End = 0x1000E000;
|
||||
|
||||
static const uint DMAC_Start = 0x1000E000;
|
||||
static const uint DMAC_End = 0x1000F000;
|
||||
|
||||
static const uint INTC_Start = 0x1000F000;
|
||||
static const uint INTC_End = 0x1000F100;
|
||||
|
||||
static const uint SIO_Start = 0x1000F100;
|
||||
static const uint SIO_End = 0x1000F200;
|
||||
static const uint SBUS_Start = 0x1000F200;
|
||||
static const uint SBUS_End = 0x1000F400;
|
||||
|
||||
// MCH area -- Really not sure what this area is. Information is lacking.
|
||||
static const uint MCH_Start = 0x1000F400;
|
||||
static const uint MCH_End = 0x1000F500;
|
||||
|
||||
// Extended master control register area for DMAC.
|
||||
static const uint DMACext_Start = 0x1000F500;
|
||||
static const uint DMACext_End = 0x1000F600;
|
||||
|
||||
};
|
||||
|
||||
// HW defines
|
||||
enum EERegisterAddresses
|
||||
|
@ -86,14 +142,14 @@ enum EERegisterAddresses
|
|||
VIF0_ITOPS = 0x10003890,
|
||||
VIF0_ITOP = 0x100038d0,
|
||||
VIF0_TOP = 0x100038e0,
|
||||
VIF0_R0 = 0x10003900,
|
||||
VIF0_R1 = 0x10003910,
|
||||
VIF0_R2 = 0x10003920,
|
||||
VIF0_R3 = 0x10003930,
|
||||
VIF0_C0 = 0x10003940,
|
||||
VIF0_C1 = 0x10003950,
|
||||
VIF0_C2 = 0x10003960,
|
||||
VIF0_C3 = 0x10003970,
|
||||
VIF0_ROW0 = 0x10003900,
|
||||
VIF0_ROW1 = 0x10003910,
|
||||
VIF0_ROW2 = 0x10003920,
|
||||
VIF0_ROW3 = 0x10003930,
|
||||
VIF0_COL0 = 0x10003940,
|
||||
VIF0_COL1 = 0x10003950,
|
||||
VIF0_COL2 = 0x10003960,
|
||||
VIF0_COL3 = 0x10003970,
|
||||
|
||||
VIF1_STAT = 0x10003c00,
|
||||
VIF1_FBRST = 0x10003c10,
|
||||
|
@ -110,14 +166,14 @@ enum EERegisterAddresses
|
|||
VIF1_TOPS = 0x10003cc0,
|
||||
VIF1_ITOP = 0x10003cd0,
|
||||
VIF1_TOP = 0x10003ce0,
|
||||
VIF1_R0 = 0x10003d00,
|
||||
VIF1_R1 = 0x10003d10,
|
||||
VIF1_R2 = 0x10003d20,
|
||||
VIF1_R3 = 0x10003d30,
|
||||
VIF1_C0 = 0x10003d40,
|
||||
VIF1_C1 = 0x10003d50,
|
||||
VIF1_C2 = 0x10003d60,
|
||||
VIF1_C3 = 0x10003d70,
|
||||
VIF1_ROW0 = 0x10003d00,
|
||||
VIF1_ROW1 = 0x10003d10,
|
||||
VIF1_ROW2 = 0x10003d20,
|
||||
VIF1_ROW3 = 0x10003d30,
|
||||
VIF1_COL0 = 0x10003d40,
|
||||
VIF1_COL1 = 0x10003d50,
|
||||
VIF1_COL2 = 0x10003d60,
|
||||
VIF1_COL3 = 0x10003d70,
|
||||
|
||||
VIF0_FIFO = 0x10004000,
|
||||
VIF1_FIFO = 0x10005000,
|
||||
|
@ -134,6 +190,13 @@ enum EERegisterAddresses
|
|||
D0_ASR0 = 0x10008040,
|
||||
D0_ASR1 = 0x10008050,
|
||||
|
||||
VIF0_CHCR = 0x10008000,
|
||||
VIF0_MADR = 0x10008010,
|
||||
VIF0_QWC = 0x10008020,
|
||||
VIF0_TADR = 0x10008030,
|
||||
VIF0_ASR0 = 0x10008040,
|
||||
VIF0_ASR1 = 0x10008050,
|
||||
|
||||
//VIF1
|
||||
D1_CHCR = 0x10009000,
|
||||
D1_MADR = 0x10009010,
|
||||
|
@ -141,7 +204,13 @@ enum EERegisterAddresses
|
|||
D1_TADR = 0x10009030,
|
||||
D1_ASR0 = 0x10009040,
|
||||
D1_ASR1 = 0x10009050,
|
||||
D1_SADR = 0x10009080,
|
||||
|
||||
VIF1_CHCR = 0x10009000,
|
||||
VIF1_MADR = 0x10009010,
|
||||
VIF1_QWC = 0x10009020,
|
||||
VIF1_TADR = 0x10009030,
|
||||
VIF1_ASR0 = 0x10009040,
|
||||
VIF1_ASR1 = 0x10009050,
|
||||
|
||||
//GS
|
||||
D2_CHCR = 0x1000A000,
|
||||
|
@ -150,44 +219,82 @@ enum EERegisterAddresses
|
|||
D2_TADR = 0x1000A030,
|
||||
D2_ASR0 = 0x1000A040,
|
||||
D2_ASR1 = 0x1000A050,
|
||||
D2_SADR = 0x1000A080,
|
||||
|
||||
GIF_CHCR = 0x1000A000,
|
||||
GIF_MADR = 0x1000A010,
|
||||
GIF_QWC = 0x1000A020,
|
||||
GIF_TADR = 0x1000A030,
|
||||
GIF_ASR0 = 0x1000A040,
|
||||
GIF_ASR1 = 0x1000A050,
|
||||
|
||||
//fromIPU
|
||||
D3_CHCR = 0x1000B000,
|
||||
D3_MADR = 0x1000B010,
|
||||
D3_QWC = 0x1000B020,
|
||||
D3_TADR = 0x1000B030,
|
||||
D3_SADR = 0x1000B080,
|
||||
|
||||
fromIPU_CHCR = 0x1000B000,
|
||||
fromIPU_MADR = 0x1000B010,
|
||||
fromIPU_QWC = 0x1000B020,
|
||||
fromIPU_TADR = 0x1000B030,
|
||||
|
||||
//toIPU
|
||||
D4_CHCR = 0x1000B400,
|
||||
D4_MADR = 0x1000B410,
|
||||
D4_QWC = 0x1000B420,
|
||||
D4_TADR = 0x1000B430,
|
||||
D4_SADR = 0x1000B480,
|
||||
|
||||
toIPU_CHCR = 0x1000B400,
|
||||
toIPU_MADR = 0x1000B410,
|
||||
toIPU_QWC = 0x1000B420,
|
||||
toIPU_TADR = 0x1000B430,
|
||||
|
||||
//SIF0
|
||||
D5_CHCR = 0x1000C000,
|
||||
D5_MADR = 0x1000C010,
|
||||
D5_QWC = 0x1000C020,
|
||||
|
||||
SIF0_CHCR = 0x1000C000,
|
||||
SIF0_MADR = 0x1000C010,
|
||||
SIF0_QWC = 0x1000C020,
|
||||
|
||||
//SIF1
|
||||
D6_CHCR = 0x1000C400,
|
||||
D6_MADR = 0x1000C410,
|
||||
D6_QWC = 0x1000C420,
|
||||
D6_TADR = 0x1000C430,
|
||||
|
||||
SIF1_CHCR = 0x1000C400,
|
||||
SIF1_MADR = 0x1000C410,
|
||||
SIF1_QWC = 0x1000C420,
|
||||
SIF1_TADR = 0x1000C430,
|
||||
|
||||
//SIF2
|
||||
D7_CHCR = 0x1000C800,
|
||||
D7_MADR = 0x1000C810,
|
||||
D7_QWC = 0x1000C820,
|
||||
|
||||
SIF2_CHCR = 0x1000C800,
|
||||
SIF2_MADR = 0x1000C810,
|
||||
SIF2_QWC = 0x1000C820,
|
||||
|
||||
//fromSPR
|
||||
D8_CHCR = 0x1000D000,
|
||||
D8_MADR = 0x1000D010,
|
||||
D8_QWC = 0x1000D020,
|
||||
D8_SADR = 0x1000D080,
|
||||
D9_CHCR = 0x1000D400,
|
||||
|
||||
fromSPR_CHCR = 0x1000D000,
|
||||
fromSPR_MADR = 0x1000D010,
|
||||
fromSPR_QWC = 0x1000D020,
|
||||
|
||||
//toSPR
|
||||
D9_CHCR = 0x1000D400,
|
||||
D9_MADR = 0x1000D010,
|
||||
D9_QWC = 0x1000D020,
|
||||
|
||||
toSPR_CHCR = 0x1000D400,
|
||||
toSPR_MADR = 0x1000D410,
|
||||
toSPR_QWC = 0x1000D420,
|
||||
|
||||
DMAC_CTRL = 0x1000E000,
|
||||
DMAC_STAT = 0x1000E010,
|
||||
|
@ -264,53 +371,7 @@ union tGS_SMODE2
|
|||
bool IsInterlaced() const { return INT; }
|
||||
};
|
||||
|
||||
void hwReset();
|
||||
|
||||
// hw read functions
|
||||
extern mem8_t hwRead8 (u32 mem);
|
||||
extern mem16_t hwRead16(u32 mem);
|
||||
|
||||
extern mem32_t __fastcall hwRead32_page_00(u32 mem);
|
||||
extern mem32_t __fastcall hwRead32_page_01(u32 mem);
|
||||
extern mem32_t __fastcall hwRead32_page_02(u32 mem);
|
||||
extern mem32_t __fastcall hwRead32_page_0F(u32 mem);
|
||||
extern mem32_t __fastcall hwRead32_page_0F_INTC_HACK(u32 mem);
|
||||
extern mem32_t __fastcall hwRead32_generic(u32 mem);
|
||||
|
||||
extern void __fastcall hwRead64_page_00(u32 mem, mem64_t* result );
|
||||
extern void __fastcall hwRead64_page_01(u32 mem, mem64_t* result );
|
||||
extern void __fastcall hwRead64_page_02(u32 mem, mem64_t* result );
|
||||
extern void __fastcall hwRead64_generic_INTC_HACK(u32 mem, mem64_t *out);
|
||||
extern void __fastcall hwRead64_generic(u32 mem, mem64_t* result );
|
||||
|
||||
extern void __fastcall hwRead128_page_00(u32 mem, mem128_t* result );
|
||||
extern void __fastcall hwRead128_page_01(u32 mem, mem128_t* result );
|
||||
extern void __fastcall hwRead128_page_02(u32 mem, mem128_t* result );
|
||||
extern void __fastcall hwRead128_generic(u32 mem, mem128_t *out);
|
||||
|
||||
// hw write functions
|
||||
extern void hwWrite8 (u32 mem, u8 value);
|
||||
extern void hwWrite16(u32 mem, u16 value);
|
||||
|
||||
extern void __fastcall hwWrite32_page_00( u32 mem, mem32_t value );
|
||||
extern void __fastcall hwWrite32_page_01( u32 mem, mem32_t value );
|
||||
extern void __fastcall hwWrite32_page_02( u32 mem, mem32_t value );
|
||||
extern void __fastcall hwWrite32_page_03( u32 mem, mem32_t value );
|
||||
extern void __fastcall hwWrite32_page_0B( u32 mem, mem32_t value );
|
||||
extern void __fastcall hwWrite32_page_0E( u32 mem, mem32_t value );
|
||||
extern void __fastcall hwWrite32_page_0F( u32 mem, mem32_t value );
|
||||
extern void __fastcall hwWrite32_generic( u32 mem, mem32_t value );
|
||||
|
||||
extern void __fastcall hwWrite64_page_00( u32 mem, const mem64_t* srcval );
|
||||
extern void __fastcall hwWrite64_page_01( u32 mem, const mem64_t* srcval );
|
||||
extern void __fastcall hwWrite64_page_02( u32 mem, const mem64_t* srcval );
|
||||
extern void __fastcall hwWrite64_page_03( u32 mem, const mem64_t* srcval );
|
||||
extern void __fastcall hwWrite64_page_0E( u32 mem, const mem64_t* srcval );
|
||||
extern void __fastcall hwWrite64_generic( u32 mem, const mem64_t* srcval );
|
||||
|
||||
extern void __fastcall hwWrite128_generic(u32 mem, const mem128_t *srcval);
|
||||
extern void hwReset();
|
||||
|
||||
extern const int rdram_devices;
|
||||
extern int rdram_sdevid;
|
||||
|
||||
#endif /* __HW_H__ */
|
||||
|
|
618
pcsx2/HwRead.cpp
618
pcsx2/HwRead.cpp
|
@ -16,9 +16,11 @@
|
|||
|
||||
#include "PrecompiledHeader.h"
|
||||
#include "Common.h"
|
||||
|
||||
#include "Hardware.h"
|
||||
|
||||
#include "ps2/HwInternal.h"
|
||||
#include "ps2/eeHwTraceLog.inl"
|
||||
|
||||
using namespace R5900;
|
||||
|
||||
static __fi void IntCHackCheck()
|
||||
|
@ -29,470 +31,270 @@ static __fi void IntCHackCheck()
|
|||
if( diff > 0 ) cpuRegs.cycle = g_nextBranchCycle;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// Hardware READ 8 bit
|
||||
static const uint HwF_VerboseConLog = 1<<0;
|
||||
static const uint HwF_IntcStatHack = 1<<1; // used for Reads only.
|
||||
|
||||
__fi mem8_t hwRead8(u32 mem)
|
||||
template< uint page > void __fastcall _hwRead128(u32 mem, mem128_t* result );
|
||||
|
||||
template< uint page, bool intcstathack >
|
||||
mem32_t __fastcall _hwRead32(u32 mem)
|
||||
{
|
||||
u8 ret;
|
||||
pxAssume( (mem & 0x03) == 0 );
|
||||
|
||||
const u16 masked_mem = mem & 0xffff;
|
||||
// TODO re-implement this warning along with a *complete* logging of all hw activity.
|
||||
// (implementation should be modelled after thee iopHWRead/iopHwWrite files)
|
||||
if( mem >= IPU_CMD && mem < D0_CHCR )
|
||||
switch( page )
|
||||
{
|
||||
#ifdef PCSX2_DEVBUILD
|
||||
HW_LOG("8bit Hardware IPU Read at 0x%x, value=0x%x", mem, psHu8(mem) );
|
||||
#endif
|
||||
return psHu8(mem);
|
||||
}
|
||||
// DevCon.Warning("Unexpected hwRead8 from 0x%x", mem);
|
||||
#ifdef PCSX2_DEVBUILD
|
||||
switch((mem >> 12) & 0xf)
|
||||
{
|
||||
case 0x03:
|
||||
if(masked_mem >= 0x3800) HW_LOG("VIF%x Register Read8 at 0x%x, value=0x%x", (masked_mem < 0x3c00) ? 0 : 1, mem, psHu32(mem) );
|
||||
else HW_LOG("GIF Register Read8 at 0x%x, value=0x%x", mem, psHu32(mem) );
|
||||
case 0x00: return rcntRead32<0x00>( mem );
|
||||
case 0x01: return rcntRead32<0x01>( mem );
|
||||
|
||||
case 0x02: return ipuRead32( mem );
|
||||
|
||||
case 0x03: return dmacRead32<0x03>( mem );
|
||||
|
||||
case 0x04:
|
||||
case 0x05:
|
||||
case 0x06:
|
||||
case 0x07:
|
||||
case 0x08:
|
||||
case 0x09:
|
||||
case 0x0a:
|
||||
case 0x0b:
|
||||
case 0x0c:
|
||||
case 0x0d:
|
||||
{
|
||||
const char* regName = "Unknown";
|
||||
// [Ps2Confirm] Reading from FIFOs using non-128 bit reads is a complete mystery.
|
||||
// No game is known to attempt such a thing (yay!), so probably nothing for us to
|
||||
// worry about. Chances are, though, doing so is "legal" and yields some sort
|
||||
// of reproducible behavior. Candidate for real hardware testing.
|
||||
|
||||
// Current assumption: Reads 128 bits and discards the unused portion.
|
||||
|
||||
switch( mem & 0xf0)
|
||||
{
|
||||
case 0x00: regName = "CHCR"; break;
|
||||
case 0x10: regName = "MADR"; break;
|
||||
case 0x20: regName = "QWC"; break;
|
||||
case 0x30: regName = "TADR"; break;
|
||||
case 0x40: regName = "ASR0"; break;
|
||||
case 0x50: regName = "ASR1"; break;
|
||||
case 0x80: regName = "SADDR"; break;
|
||||
}
|
||||
DevCon.WriteLn( Color_Cyan, "Reading 32-bit FIFO data" );
|
||||
|
||||
HW_LOG("Hardware Read 8 at 0x%x (%ls %s), value=0x%x", mem, ChcrName(mem & ~0xff), regName, psHu8(mem) );
|
||||
ret = psHu8(mem);
|
||||
return ret;
|
||||
u128 out128;
|
||||
_hwRead128<page>(mem, &out128);
|
||||
return out128._u32[(mem >> 2) & 0x3];
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
switch (mem)
|
||||
{
|
||||
case RCNT0_COUNT: ret = (u8)rcntRcount(0); break;
|
||||
case RCNT0_MODE: ret = (u8)counters[0].modeval; break;
|
||||
case RCNT0_TARGET: ret = (u8)counters[0].target; break;
|
||||
case RCNT0_HOLD: ret = (u8)counters[0].hold; break;
|
||||
case RCNT0_COUNT + 1: ret = (u8)(rcntRcount(0)>>8); break;
|
||||
case RCNT0_MODE + 1: ret = (u8)(counters[0].modeval>>8); break;
|
||||
case RCNT0_TARGET + 1: ret = (u8)(counters[0].target>>8); break;
|
||||
case RCNT0_HOLD + 1: ret = (u8)(counters[0].hold>>8); break;
|
||||
|
||||
case RCNT1_COUNT: ret = (u8)rcntRcount(1); break;
|
||||
case RCNT1_MODE: ret = (u8)counters[1].modeval; break;
|
||||
case RCNT1_TARGET: ret = (u8)counters[1].target; break;
|
||||
case RCNT1_HOLD: ret = (u8)counters[1].hold; break;
|
||||
case RCNT1_COUNT + 1: ret = (u8)(rcntRcount(1)>>8); break;
|
||||
case RCNT1_MODE + 1: ret = (u8)(counters[1].modeval>>8); break;
|
||||
case RCNT1_TARGET + 1: ret = (u8)(counters[1].target>>8); break;
|
||||
case RCNT1_HOLD + 1: ret = (u8)(counters[1].hold>>8); break;
|
||||
|
||||
case RCNT2_COUNT: ret = (u8)rcntRcount(2); break;
|
||||
case RCNT2_MODE: ret = (u8)counters[2].modeval; break;
|
||||
case RCNT2_TARGET: ret = (u8)counters[2].target; break;
|
||||
case RCNT2_COUNT + 1: ret = (u8)(rcntRcount(2)>>8); break;
|
||||
case RCNT2_MODE + 1: ret = (u8)(counters[2].modeval>>8); break;
|
||||
case RCNT2_TARGET + 1: ret = (u8)(counters[2].target>>8); break;
|
||||
|
||||
case RCNT3_COUNT: ret = (u8)rcntRcount(3); break;
|
||||
case RCNT3_MODE: ret = (u8)counters[3].modeval; break;
|
||||
case RCNT3_TARGET: ret = (u8)counters[3].target; break;
|
||||
case RCNT3_COUNT + 1: ret = (u8)(rcntRcount(3)>>8); break;
|
||||
case RCNT3_MODE + 1: ret = (u8)(counters[3].modeval>>8); break;
|
||||
case RCNT3_TARGET + 1: ret = (u8)(counters[3].target>>8); break;
|
||||
|
||||
default:
|
||||
if ((mem & 0xffffff0f) == SBUS_F200)
|
||||
{
|
||||
switch (mem)
|
||||
{
|
||||
case SBUS_F240:
|
||||
ret = psHu32(mem);
|
||||
//psHu32(mem) &= ~0x4000;
|
||||
break;
|
||||
|
||||
case SBUS_F260:
|
||||
ret = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
ret = psHu32(mem);
|
||||
break;
|
||||
}
|
||||
return (u8)ret;
|
||||
}
|
||||
|
||||
ret = psHu8(mem);
|
||||
UnknownHW_LOG("Hardware Read 8 from 0x%x = 0x%x", mem, ret);
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// Hardware READ 16 bit
|
||||
|
||||
__fi mem16_t hwRead16(u32 mem)
|
||||
{
|
||||
u16 ret;
|
||||
const u16 masked_mem = mem & 0xffff;
|
||||
|
||||
// TODO re-implement this warning along with a *complete* logging of all hw activity.
|
||||
// (implementation should be modelled after the iopHWRead/iopHwWrite files)
|
||||
if( mem >= IPU_CMD && mem < D0_CHCR )
|
||||
{
|
||||
#ifdef PCSX2_DEVBUILD
|
||||
HW_LOG("16 bit Hardware IPU Read at 0x%x, value=0x%x", mem, psHu16(mem) );
|
||||
#endif
|
||||
return psHu16(mem);
|
||||
}
|
||||
// Console.Warning("Unexpected hwRead16 from 0x%x", mem);
|
||||
|
||||
#ifdef PCSX2_DEVBUILD
|
||||
switch((mem >> 12) & 0xf)
|
||||
{
|
||||
case 0x03:
|
||||
if(masked_mem >= 0x3800) HW_LOG("VIF%x Register Read8 at 0x%x, value=0x%x", (masked_mem < 0x3c00) ? 0 : 1, mem, psHu32(mem) );
|
||||
else HW_LOG("GIF Register Read8 at 0x%x, value=0x%x", mem, psHu32(mem) );
|
||||
case 0x04:
|
||||
case 0x05:
|
||||
case 0x06:
|
||||
case 0x07:
|
||||
case 0x08:
|
||||
case 0x09:
|
||||
case 0x0a:
|
||||
case 0x0b:
|
||||
case 0x0c:
|
||||
case 0x0d:
|
||||
{
|
||||
const char* regName = "Unknown";
|
||||
|
||||
switch( mem & 0xf0)
|
||||
{
|
||||
case 0x00: regName = "CHCR"; break;
|
||||
case 0x10: regName = "MADR"; break;
|
||||
case 0x20: regName = "QWC"; break;
|
||||
case 0x30: regName = "TADR"; break;
|
||||
case 0x40: regName = "ASR0"; break;
|
||||
case 0x50: regName = "ASR1"; break;
|
||||
case 0x80: regName = "SADDR"; break;
|
||||
}
|
||||
|
||||
HW_LOG("Hardware Read16 at 0x%x (%ls %s), value=0x%x", mem, ChcrName(mem & ~0xff), regName, psHu16(mem) );
|
||||
ret = psHu16(mem);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
switch (mem)
|
||||
{
|
||||
case RCNT0_COUNT: ret = (u16)rcntRcount(0); break;
|
||||
case RCNT0_MODE: ret = (u16)counters[0].modeval; break;
|
||||
case RCNT0_TARGET: ret = (u16)counters[0].target; break;
|
||||
case RCNT0_HOLD: ret = (u16)counters[0].hold; break;
|
||||
|
||||
case RCNT1_COUNT: ret = (u16)rcntRcount(1); break;
|
||||
case RCNT1_MODE: ret = (u16)counters[1].modeval; break;
|
||||
case RCNT1_TARGET: ret = (u16)counters[1].target; break;
|
||||
case RCNT1_HOLD: ret = (u16)counters[1].hold; break;
|
||||
|
||||
case RCNT2_COUNT: ret = (u16)rcntRcount(2); break;
|
||||
case RCNT2_MODE: ret = (u16)counters[2].modeval; break;
|
||||
case RCNT2_TARGET: ret = (u16)counters[2].target; break;
|
||||
|
||||
case RCNT3_COUNT: ret = (u16)rcntRcount(3); break;
|
||||
case RCNT3_MODE: ret = (u16)counters[3].modeval; break;
|
||||
case RCNT3_TARGET: ret = (u16)counters[3].target; break;
|
||||
|
||||
default:
|
||||
if ((mem & 0xffffff0f) == SBUS_F200)
|
||||
{
|
||||
switch (mem)
|
||||
{
|
||||
case SBUS_F240:
|
||||
ret = psHu16(mem) | 0x0102;
|
||||
psHu32(mem) &= ~0x4000; // not commented out like in bit mode?
|
||||
break;
|
||||
|
||||
case SBUS_F260:
|
||||
ret = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
ret = psHu32(mem);
|
||||
break;
|
||||
}
|
||||
return (u16)ret;
|
||||
}
|
||||
ret = psHu16(mem);
|
||||
UnknownHW_LOG("Hardware Read16 at 0x%x, value= 0x%x", ret, mem);
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// Hardware READ 32 bit
|
||||
|
||||
// Reads hardware registers for page 0 (counters 0 and 1)
|
||||
mem32_t __fastcall hwRead32_page_00(u32 mem)
|
||||
{
|
||||
mem &= 0xffff;
|
||||
switch( mem )
|
||||
{
|
||||
case 0x00: return (u16)rcntRcount(0);
|
||||
case 0x10: return (u16)counters[0].modeval;
|
||||
case 0x20: return (u16)counters[0].target;
|
||||
case 0x30: return (u16)counters[0].hold;
|
||||
|
||||
case 0x800: return (u16)rcntRcount(1);
|
||||
case 0x810: return (u16)counters[1].modeval;
|
||||
case 0x820: return (u16)counters[1].target;
|
||||
case 0x830: return (u16)counters[1].hold;
|
||||
}
|
||||
|
||||
return *((u32*)&eeMem->HW[mem]);
|
||||
}
|
||||
|
||||
// Reads hardware registers for page 1 (counters 2 and 3)
|
||||
mem32_t __fastcall hwRead32_page_01(u32 mem)
|
||||
{
|
||||
mem &= 0xffff;
|
||||
switch( mem )
|
||||
{
|
||||
case 0x1000: return (u16)rcntRcount(2);
|
||||
case 0x1010: return (u16)counters[2].modeval;
|
||||
case 0x1020: return (u16)counters[2].target;
|
||||
|
||||
case 0x1800: return (u16)rcntRcount(3);
|
||||
case 0x1810: return (u16)counters[3].modeval;
|
||||
case 0x1820: return (u16)counters[3].target;
|
||||
}
|
||||
|
||||
return *((u32*)&eeMem->HW[mem]);
|
||||
}
|
||||
|
||||
// Reads hardware registers for page 15 (0x0F).
|
||||
// This is used internally to produce two inline versions, one with INTC_HACK, and one without.
|
||||
static __fi mem32_t __hwRead32_page_0F( u32 mem, bool intchack )
|
||||
{
|
||||
// *Performance Warning* This function is called -A-LOT. Be wary when making changes. It
|
||||
// could impact FPS significantly.
|
||||
|
||||
mem &= 0xffff;
|
||||
|
||||
// INTC_STAT shortcut for heavy spinning.
|
||||
// Performance Note: Visual Studio handles this best if we just manually check for it here,
|
||||
// outside the context of the switch statement below. This is likely fixed by PGO also,
|
||||
// but it's an easy enough conditional to account for anyways.
|
||||
|
||||
static const uint ics = INTC_STAT & 0xffff;
|
||||
if( mem == ics ) // INTC_STAT
|
||||
{
|
||||
if( intchack ) IntCHackCheck();
|
||||
return *((u32*)&eeMem->HW[ics]);
|
||||
}
|
||||
|
||||
switch( mem )
|
||||
{
|
||||
case 0xf010:
|
||||
HW_LOG("INTC_MASK Read32, value=0x%x", psHu32(INTC_MASK));
|
||||
break;
|
||||
|
||||
case 0xf130: // SIO_ISR
|
||||
case 0xf260: // SBUS_F260
|
||||
case 0xf410: // 0x1000f410
|
||||
case 0xf430: // MCH_RICM
|
||||
return 0;
|
||||
case 0x0f:
|
||||
{
|
||||
// INTC_STAT shortcut for heavy spinning.
|
||||
// Performance Note: Visual Studio handles this best if we just manually check for it here,
|
||||
// outside the context of the switch statement below. This is likely fixed by PGO also,
|
||||
// but it's an easy enough conditional to account for anyways.
|
||||
|
||||
case 0xf240: // SBUS_F240
|
||||
return psHu32(0xf240) | 0xF0000102;
|
||||
|
||||
case 0xf440: // MCH_DRD
|
||||
if( !((psHu32(0xf430) >> 6) & 0xF) )
|
||||
if (mem == INTC_STAT)
|
||||
{
|
||||
switch ((psHu32(0xf430)>>16) & 0xFFF)
|
||||
{
|
||||
//MCH_RICM: x:4|SA:12|x:5|SDEV:1|SOP:4|SBC:1|SDEV:5
|
||||
if (intcstathack) IntCHackCheck();
|
||||
return psHu32(INTC_STAT);
|
||||
}
|
||||
|
||||
case 0x21://INIT
|
||||
if(rdram_sdevid < rdram_devices)
|
||||
{
|
||||
rdram_sdevid++;
|
||||
return 0x1F;
|
||||
}
|
||||
//if ((mem & 0x1000f200) == 0x1000f200)
|
||||
// Console.Error("SBUS");
|
||||
|
||||
switch( mem )
|
||||
{
|
||||
case SIO_ISR:
|
||||
case SBUS_F260:
|
||||
case 0x1000f410:
|
||||
case MCH_RICM:
|
||||
return 0;
|
||||
|
||||
case 0x23://CNFGA
|
||||
return 0x0D0D; //PVER=3 | MVER=16 | DBL=1 | REFBIT=5
|
||||
case SBUS_F240:
|
||||
return psHu32(SBUS_F240) | 0xF0000102;
|
||||
|
||||
case 0x24://CNFGB
|
||||
//0x0110 for PSX SVER=0 | CORG=8(5x9x7) | SPT=1 | DEVTYP=0 | BYTE=0
|
||||
return 0x0090; //SVER=0 | CORG=4(5x9x6) | SPT=1 | DEVTYP=0 | BYTE=0
|
||||
case MCH_DRD:
|
||||
if( !((psHu32(MCH_RICM) >> 6) & 0xF) )
|
||||
{
|
||||
switch ((psHu32(MCH_RICM)>>16) & 0xFFF)
|
||||
{
|
||||
//MCH_RICM: x:4|SA:12|x:5|SDEV:1|SOP:4|SBC:1|SDEV:5
|
||||
|
||||
case 0x40://DEVID
|
||||
return psHu32(0xf430) & 0x1F; // =SDEV
|
||||
}
|
||||
case 0x21://INIT
|
||||
if(rdram_sdevid < rdram_devices)
|
||||
{
|
||||
rdram_sdevid++;
|
||||
return 0x1F;
|
||||
}
|
||||
return 0;
|
||||
|
||||
case 0x23://CNFGA
|
||||
return 0x0D0D; //PVER=3 | MVER=16 | DBL=1 | REFBIT=5
|
||||
|
||||
case 0x24://CNFGB
|
||||
//0x0110 for PSX SVER=0 | CORG=8(5x9x7) | SPT=1 | DEVTYP=0 | BYTE=0
|
||||
return 0x0090; //SVER=0 | CORG=4(5x9x6) | SPT=1 | DEVTYP=0 | BYTE=0
|
||||
|
||||
case 0x40://DEVID
|
||||
return psHu32(MCH_RICM) & 0x1F; // =SDEV
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return *((u32*)&eeMem->HW[mem]);
|
||||
|
||||
return psHu32(mem);
|
||||
}
|
||||
|
||||
mem32_t __fastcall hwRead32_page_0F(u32 mem)
|
||||
template< uint page >
|
||||
mem32_t __fastcall hwRead32(u32 mem)
|
||||
{
|
||||
return __hwRead32_page_0F( mem, false );
|
||||
mem32_t retval = _hwRead32<page,false>(mem);
|
||||
eeHwTraceLog( mem, retval, true );
|
||||
return retval;
|
||||
}
|
||||
|
||||
mem32_t __fastcall hwRead32_page_0F_INTC_HACK(u32 mem)
|
||||
{
|
||||
return __hwRead32_page_0F( mem, true );
|
||||
mem32_t retval = _hwRead32<0x0f,true>(mem);
|
||||
eeHwTraceLog( mem, retval, true );
|
||||
return retval;
|
||||
}
|
||||
|
||||
mem32_t __fastcall hwRead32_page_02(u32 mem)
|
||||
// --------------------------------------------------------------------------------------
|
||||
// hwRead8 / hwRead16 / hwRead64 / hwRead128
|
||||
// --------------------------------------------------------------------------------------
|
||||
|
||||
template< uint page >
|
||||
mem8_t __fastcall _hwRead8(u32 mem)
|
||||
{
|
||||
return ipuRead32( mem );
|
||||
u32 ret32 = _hwRead32<page, false>(mem & ~0x03);
|
||||
return ((u8*)&ret32)[mem & 0x03];
|
||||
}
|
||||
|
||||
// Used for all pages not explicitly specified above.
|
||||
mem32_t __fastcall hwRead32_generic(u32 mem)
|
||||
template< uint page >
|
||||
mem8_t __fastcall hwRead8(u32 mem)
|
||||
{
|
||||
const u16 masked_mem = mem & 0xffff;
|
||||
mem8_t ret8 = _hwRead8<0x0f>(mem);
|
||||
eeHwTraceLog( mem, ret8, true );
|
||||
return ret8;
|
||||
}
|
||||
|
||||
switch( masked_mem>>12 ) // switch out as according to the 4k page of the access.
|
||||
template< uint page >
|
||||
mem16_t __fastcall _hwRead16(u32 mem)
|
||||
{
|
||||
pxAssume( (mem & 0x01) == 0 );
|
||||
|
||||
u32 ret32 = _hwRead32<page, false>(mem & ~0x03);
|
||||
return ((u16*)&ret32)[(mem>>1) & 0x01];
|
||||
}
|
||||
|
||||
template< uint page >
|
||||
mem16_t __fastcall hwRead16(u32 mem)
|
||||
{
|
||||
u16 ret16 = _hwRead16<page>(mem);
|
||||
eeHwTraceLog( mem, ret16, true );
|
||||
return ret16;
|
||||
}
|
||||
|
||||
mem16_t __fastcall hwRead16_page_0F_INTC_HACK(u32 mem)
|
||||
{
|
||||
pxAssume( (mem & 0x01) == 0 );
|
||||
|
||||
u32 ret32 = _hwRead32<0x0f, true>(mem & ~0x03);
|
||||
u16 ret16 = ((u16*)&ret32)[(mem>>1) & 0x01];
|
||||
|
||||
eeHwTraceLog( mem, ret16, "Read" );
|
||||
return ret16;
|
||||
}
|
||||
|
||||
template< uint page >
|
||||
static void _hwRead64(u32 mem, mem64_t* result )
|
||||
{
|
||||
pxAssume( (mem & 0x07) == 0 );
|
||||
|
||||
switch (page)
|
||||
{
|
||||
case 0x03:
|
||||
if(masked_mem >= 0x3800) HW_LOG("VIF%x Register Read32 at 0x%x, value=0x%x", (masked_mem < 0x3c00) ? 0 : 1, mem, psHu32(mem) );
|
||||
else HW_LOG("GIF Register Read32 at 0x%x, value=0x%x", mem, psHu32(mem) );
|
||||
|
||||
// Fixme: OPH hack. Toggle the flag on each GIF_STAT access. (rama)
|
||||
if (CHECK_OPHFLAGHACK)
|
||||
{
|
||||
if (masked_mem == 0x3020)
|
||||
gifRegs->stat.OPH = !gifRegs->stat.OPH;
|
||||
}
|
||||
break;
|
||||
///////////////////////////////////////////////////////
|
||||
// Most of the following case handlers are for developer builds only (logging).
|
||||
// It'll all optimize to ziltch in public release builds.
|
||||
#ifdef PCSX2_DEVBUILD
|
||||
case 0x02:
|
||||
*result = ipuRead64(mem);
|
||||
return;
|
||||
|
||||
case 0x04:
|
||||
case 0x05:
|
||||
case 0x06:
|
||||
case 0x07:
|
||||
case 0x08:
|
||||
case 0x09:
|
||||
case 0x0a:
|
||||
case 0x0b:
|
||||
case 0x0c:
|
||||
case 0x0d:
|
||||
{
|
||||
const char* regName = "Unknown";
|
||||
// [Ps2Confirm] Reading from FIFOs using non-128 bit reads is a complete mystery.
|
||||
// No game is known to attempt such a thing (yay!), so probably nothing for us to
|
||||
// worry about. Chances are, though, doing so is "legal" and yields some sort
|
||||
// of reproducible behavior. Candidate for real hardware testing.
|
||||
|
||||
// Current assumption: Reads 128 bits and discards the unused portion.
|
||||
|
||||
switch( mem & 0xf0)
|
||||
{
|
||||
case 0x00: regName = "CHCR"; break;
|
||||
case 0x10: regName = "MADR"; break;
|
||||
case 0x20: regName = "QWC"; break;
|
||||
case 0x30: regName = "TADR"; break;
|
||||
case 0x40: regName = "ASR0"; break;
|
||||
case 0x50: regName = "ASR1"; break;
|
||||
case 0x80: regName = "SADDR"; break;
|
||||
}
|
||||
uint wordpart = (mem >> 3) & 0x1;
|
||||
DevCon.WriteLn( Color_Cyan, "Reading 64-bit FIFO data (%s 64 bits discarded)", wordpart ? "upper" : "lower" );
|
||||
|
||||
HW_LOG("Hardware Read32 at 0x%x (%ls %s), value=0x%x", mem, ChcrName(mem & ~0xff), regName, psHu32(mem) );
|
||||
u128 out128;
|
||||
_hwRead128<page>(mem, &out128);
|
||||
*result = out128._u64[wordpart];
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
case 0x0e:
|
||||
#ifdef PCSX2_DEVBUILD
|
||||
HW_LOG("DMAC Control Regs addr=0x%x Read32, value=0x%x", mem, psHu32(mem));
|
||||
#else
|
||||
if( mem == DMAC_STAT)
|
||||
HW_LOG("DMAC_STAT Read32, value=0x%x", psHu32(DMAC_STAT));
|
||||
#endif
|
||||
break;
|
||||
|
||||
jNO_DEFAULT;
|
||||
return;
|
||||
}
|
||||
|
||||
return *((u32*)&eeMem->HW[masked_mem]);
|
||||
*result = _hwRead32<page,false>( mem );
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// Hardware READ 64 bit
|
||||
|
||||
void __fastcall hwRead64_page_00(u32 mem, mem64_t* result )
|
||||
template< uint page >
|
||||
void __fastcall hwRead64(u32 mem, mem64_t* result )
|
||||
{
|
||||
*result = hwRead32_page_00( mem );
|
||||
_hwRead64<page>( mem, result );
|
||||
eeHwTraceLog( mem, *result, true );
|
||||
}
|
||||
|
||||
void __fastcall hwRead64_page_01(u32 mem, mem64_t* result )
|
||||
template< uint page >
|
||||
void __fastcall _hwRead128(u32 mem, mem128_t* result )
|
||||
{
|
||||
*result = hwRead32_page_01( mem );
|
||||
pxAssume( (mem & 0x0f) == 0 );
|
||||
|
||||
// FIFOs are the only "legal" 128 bit registers, so we Handle them first.
|
||||
// All other registers fall back on the 64-bit handler (and from there
|
||||
// all non-IPU reads fall back to the 32-bit handler).
|
||||
|
||||
switch (page)
|
||||
{
|
||||
case 0x05:
|
||||
ReadFIFO_VIF1( result );
|
||||
break;
|
||||
|
||||
case 0x07:
|
||||
if (mem & 0x10)
|
||||
ZeroQWC( result ); // IPUin is write-only
|
||||
else
|
||||
ReadFIFO_IPUout( result );
|
||||
break;
|
||||
|
||||
case 0x04:
|
||||
case 0x06:
|
||||
// VIF0 and GIF are write-only.
|
||||
// [Ps2Confirm] Reads from these FIFOs (and IPUin) do one of the following:
|
||||
// return zero, leave contents of the dest register unchanged, or in some
|
||||
// indeterminate state. The actual behavior probably isn't important.
|
||||
ZeroQWC( result );
|
||||
break;
|
||||
|
||||
default:
|
||||
_hwRead64<page>( mem, &result->lo );
|
||||
result->hi = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void __fastcall hwRead64_page_02(u32 mem, mem64_t* result )
|
||||
template< uint page >
|
||||
void __fastcall hwRead128(u32 mem, mem128_t* result )
|
||||
{
|
||||
*result = ipuRead64(mem);
|
||||
_hwRead128<page>( mem, result );
|
||||
eeHwTraceLog( mem, *result, true );
|
||||
}
|
||||
|
||||
void __fastcall hwRead64_generic_INTC_HACK(u32 mem, mem64_t* result )
|
||||
{
|
||||
if (mem == INTC_STAT) IntCHackCheck();
|
||||
#define InstantizeHwRead(pageidx) \
|
||||
template mem8_t __fastcall hwRead8<pageidx>(u32 mem); \
|
||||
template mem16_t __fastcall hwRead16<pageidx>(u32 mem); \
|
||||
template mem32_t __fastcall hwRead32<pageidx>(u32 mem); \
|
||||
template void __fastcall hwRead64<pageidx>(u32 mem, mem64_t* result ); \
|
||||
template void __fastcall hwRead128<pageidx>(u32 mem, mem128_t* result ); \
|
||||
template mem32_t __fastcall _hwRead32<pageidx, false>(u32 mem);
|
||||
|
||||
*result = psHu64(mem);
|
||||
UnknownHW_LOG("Hardware Read 64 at %x",mem);
|
||||
}
|
||||
|
||||
void __fastcall hwRead64_generic(u32 mem, mem64_t* result )
|
||||
{
|
||||
*result = psHu64(mem);
|
||||
UnknownHW_LOG("Hardware Read 64 at %x",mem);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// Hardware READ 128 bit
|
||||
|
||||
void __fastcall hwRead128_page_00(u32 mem, mem128_t* result )
|
||||
{
|
||||
result->lo = hwRead32_page_00( mem );
|
||||
result->hi = 0;
|
||||
}
|
||||
|
||||
void __fastcall hwRead128_page_01(u32 mem, mem128_t* result )
|
||||
{
|
||||
result->lo = hwRead32_page_01( mem );
|
||||
result->hi = 0;
|
||||
}
|
||||
|
||||
void __fastcall hwRead128_page_02(u32 mem, mem128_t* result )
|
||||
{
|
||||
// IPU is currently unhandled in 128 bit mode.
|
||||
HW_LOG("Hardware Read 128 at %x (IPU)",mem);
|
||||
}
|
||||
|
||||
void __fastcall hwRead128_generic(u32 mem, mem128_t* out)
|
||||
{
|
||||
CopyQWC(out, &psHu128(mem));
|
||||
UnknownHW_LOG("Hardware Read 128 at %x",mem);
|
||||
}
|
||||
InstantizeHwRead(0x00); InstantizeHwRead(0x08);
|
||||
InstantizeHwRead(0x01); InstantizeHwRead(0x09);
|
||||
InstantizeHwRead(0x02); InstantizeHwRead(0x0a);
|
||||
InstantizeHwRead(0x03); InstantizeHwRead(0x0b);
|
||||
InstantizeHwRead(0x04); InstantizeHwRead(0x0c);
|
||||
InstantizeHwRead(0x05); InstantizeHwRead(0x0d);
|
||||
InstantizeHwRead(0x06); InstantizeHwRead(0x0e);
|
||||
InstantizeHwRead(0x07); InstantizeHwRead(0x0f);
|
||||
|
|
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"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
//#pragma pack(1)
|
||||
#endif
|
||||
|
||||
#define ipumsk( src ) ( (src) & 0xff )
|
||||
#define ipucase( src ) case ipumsk(src)
|
||||
|
||||
|
@ -29,26 +25,6 @@
|
|||
|
||||
#define IPU_FORCEINLINE __fi
|
||||
|
||||
struct IPUStatus {
|
||||
bool InProgress;
|
||||
u8 DMAMode;
|
||||
bool DMAFinished;
|
||||
bool IRQTriggered;
|
||||
u8 TagFollow;
|
||||
u32 TagAddr;
|
||||
bool stalled;
|
||||
u8 ChainMode;
|
||||
u32 NextMem;
|
||||
};
|
||||
|
||||
#define DMA_MODE_NORMAL 0
|
||||
#define DMA_MODE_CHAIN 1
|
||||
|
||||
#define IPU1_TAG_FOLLOW 0
|
||||
#define IPU1_TAG_QWC 1
|
||||
#define IPU1_TAG_ADDR 2
|
||||
#define IPU1_TAG_NONE 3
|
||||
|
||||
//
|
||||
// Bitfield Structures
|
||||
//
|
||||
|
@ -102,10 +78,6 @@ struct tIPU_BP {
|
|||
}
|
||||
};
|
||||
|
||||
#ifdef _WIN32
|
||||
//#pragma pack()
|
||||
#endif
|
||||
|
||||
union tIPU_CMD_IDEC
|
||||
{
|
||||
struct
|
||||
|
@ -178,47 +150,6 @@ union tIPU_CMD_CSC
|
|||
void log_from_RGB32() const;
|
||||
};
|
||||
|
||||
union tIPU_DMA
|
||||
{
|
||||
struct
|
||||
{
|
||||
bool GIFSTALL : 1;
|
||||
bool TIE0 :1;
|
||||
bool TIE1 : 1;
|
||||
bool ACTV1 : 1;
|
||||
bool DOTIE1 : 1;
|
||||
bool FIREINT0 : 1;
|
||||
bool FIREINT1 : 1;
|
||||
bool VIFSTALL : 1;
|
||||
bool SIFSTALL : 1;
|
||||
};
|
||||
u32 _u32;
|
||||
|
||||
tIPU_DMA( u32 val ){ _u32 = val; }
|
||||
|
||||
bool test(u32 flags) const { return !!(_u32 & flags); }
|
||||
void set_flags(u32 flags) { _u32 |= flags; }
|
||||
void clear_flags(u32 flags) { _u32 &= ~flags; }
|
||||
void reset() { _u32 = 0; }
|
||||
wxString desc() const
|
||||
{
|
||||
wxString temp(L"g_nDMATransfer[");
|
||||
|
||||
if (GIFSTALL) temp += L" GIFSTALL ";
|
||||
if (TIE0) temp += L" TIE0 ";
|
||||
if (TIE1) temp += L" TIE1 ";
|
||||
if (ACTV1) temp += L" ACTV1 ";
|
||||
if (DOTIE1) temp += L" DOTIE1 ";
|
||||
if (FIREINT0) temp += L" FIREINT0 ";
|
||||
if (FIREINT1) temp += L" FIREINT1 ";
|
||||
if (VIFSTALL) temp += L" VIFSTALL ";
|
||||
if (SIFSTALL) temp += L" SIFSTALL ";
|
||||
|
||||
temp += L"]";
|
||||
return temp;
|
||||
}
|
||||
};
|
||||
|
||||
enum SCE_IPU
|
||||
{
|
||||
SCE_IPU_BCLR = 0x0
|
||||
|
@ -245,8 +176,6 @@ struct IPUregisters {
|
|||
u32 dummy3[2];
|
||||
};
|
||||
|
||||
#define ipuRegs ((IPUregisters*)(&eeMem->HW[0x2000]))
|
||||
|
||||
struct tIPU_cmd
|
||||
{
|
||||
int index;
|
||||
|
@ -271,32 +200,22 @@ struct tIPU_cmd
|
|||
}
|
||||
};
|
||||
|
||||
static IPUregisters& ipuRegs = (IPUregisters&)eeHw[0x2000];
|
||||
|
||||
extern tIPU_cmd ipu_cmd;
|
||||
extern int coded_block_pattern;
|
||||
extern IPUStatus IPU1Status;
|
||||
extern tIPU_DMA g_nDMATransfer;
|
||||
|
||||
extern int ipuInit();
|
||||
extern void ipuReset();
|
||||
extern void ipuShutdown();
|
||||
extern int ipuFreeze(gzFile f, int Mode);
|
||||
extern bool ipuCanFreeze();
|
||||
|
||||
extern u32 ipuRead32(u32 mem);
|
||||
extern u64 ipuRead64(u32 mem);
|
||||
extern void ipuWrite32(u32 mem,u32 value);
|
||||
extern void ipuWrite64(u32 mem,u64 value);
|
||||
extern bool ipuWrite32(u32 mem,u32 value);
|
||||
extern bool ipuWrite64(u32 mem,u64 value);
|
||||
|
||||
extern void IPUCMD_WRITE(u32 val);
|
||||
extern void ipuSoftReset();
|
||||
extern void IPUProcessInterrupt();
|
||||
extern void ipu0Interrupt();
|
||||
extern void ipu1Interrupt();
|
||||
|
||||
extern void dmaIPU0();
|
||||
extern void dmaIPU1();
|
||||
extern int IPU0dma();
|
||||
extern int IPU1dma();
|
||||
|
||||
extern u16 __fastcall FillInternalBuffer(u32 * pointer, u32 advance, u32 size);
|
||||
extern u8 __fastcall getBits128(u8 *address, u32 advance);
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include "PrecompiledHeader.h"
|
||||
#include "Common.h"
|
||||
#include "IPU.h"
|
||||
#include "IPU/IPUdma.h"
|
||||
#include "mpeg2lib/Mpeg.h"
|
||||
|
||||
|
||||
|
@ -35,7 +36,7 @@ void IPU_Fifo_Input::clear()
|
|||
{
|
||||
memzero(data);
|
||||
g_BP.IFC = 0;
|
||||
ipuRegs->ctrl.IFC = 0;
|
||||
ipuRegs.ctrl.IFC = 0;
|
||||
readpos = 0;
|
||||
writepos = 0;
|
||||
}
|
||||
|
@ -43,7 +44,7 @@ void IPU_Fifo_Input::clear()
|
|||
void IPU_Fifo_Output::clear()
|
||||
{
|
||||
memzero(data);
|
||||
ipuRegs->ctrl.OFC = 0;
|
||||
ipuRegs.ctrl.OFC = 0;
|
||||
readpos = 0;
|
||||
writepos = 0;
|
||||
}
|
||||
|
@ -89,9 +90,9 @@ int IPU_Fifo_Output::write(const u32 *value, int size)
|
|||
{
|
||||
int transsize, firsttrans;
|
||||
|
||||
if ((int)ipuRegs->ctrl.OFC >= 8) IPU0dma();
|
||||
if ((int)ipuRegs.ctrl.OFC >= 8) IPU0dma();
|
||||
|
||||
transsize = min(size, 8 - (int)ipuRegs->ctrl.OFC);
|
||||
transsize = min(size, 8 - (int)ipuRegs.ctrl.OFC);
|
||||
firsttrans = transsize;
|
||||
|
||||
while (transsize-- > 0)
|
||||
|
@ -104,7 +105,7 @@ int IPU_Fifo_Output::write(const u32 *value, int size)
|
|||
value += 4;
|
||||
}
|
||||
|
||||
ipuRegs->ctrl.OFC += firsttrans;
|
||||
ipuRegs.ctrl.OFC += firsttrans;
|
||||
IPU0dma();
|
||||
|
||||
return firsttrans;
|
||||
|
@ -150,7 +151,7 @@ void IPU_Fifo_Output::_readsingle(void *value)
|
|||
|
||||
void IPU_Fifo_Output::read(void *value, int size)
|
||||
{
|
||||
ipuRegs->ctrl.OFC -= size;
|
||||
ipuRegs.ctrl.OFC -= size;
|
||||
while (size > 0)
|
||||
{
|
||||
_readsingle(value);
|
||||
|
@ -161,38 +162,51 @@ void IPU_Fifo_Output::read(void *value, int size)
|
|||
|
||||
void IPU_Fifo_Output::readsingle(void *value)
|
||||
{
|
||||
if (ipuRegs->ctrl.OFC > 0)
|
||||
if (ipuRegs.ctrl.OFC > 0)
|
||||
{
|
||||
ipuRegs->ctrl.OFC--;
|
||||
ipuRegs.ctrl.OFC--;
|
||||
_readsingle(value);
|
||||
}
|
||||
}
|
||||
|
||||
__fi bool decoder_t::ReadIpuData(u128* out)
|
||||
{
|
||||
if(decoder.ipu0_data == 0) return false;
|
||||
_mm_store_ps((float*)out, _mm_load_ps((float*)GetIpuDataPtr()));
|
||||
if(ipu0_data == 0)
|
||||
{
|
||||
IPU_LOG( "ReadFIFO/IPUout -> (fifo empty/no data available)" );
|
||||
return false;
|
||||
}
|
||||
|
||||
CopyQWC(out, GetIpuDataPtr());
|
||||
|
||||
--ipu0_data;
|
||||
++ipu0_idx;
|
||||
|
||||
IPU_LOG( "ReadFIFO/IPUout -> %ls", out->ToString().c_str() );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void __fastcall ReadFIFO_page_7(u32 mem, mem128_t* out)
|
||||
void __fastcall ReadFIFO_IPUout(mem128_t* out)
|
||||
{
|
||||
pxAssert( (mem >= IPUout_FIFO) && (mem < D0_CHCR) );
|
||||
// FIXME! When ReadIpuData() doesn't succeed (returns false), the EE should probably stall
|
||||
// until a value becomes available. This isn't exactly easy to do since the virtualized EE
|
||||
// in PCSX2 *has* to be running in order for the IPU DMA to upload new input data to allow
|
||||
// IPUout's FIFO to fill. Thus if we implement an EE stall, PCSX2 deadlocks. Grr. --air
|
||||
|
||||
// All addresses in this page map to 0x7000 and 0x7010:
|
||||
mem &= 0x10;
|
||||
|
||||
if (mem == 0) // IPUout_FIFO
|
||||
if (decoder.ReadIpuData(out))
|
||||
{
|
||||
if (decoder.ReadIpuData(out))
|
||||
{
|
||||
ipu_fifo.out.readpos = (ipu_fifo.out.readpos + 4) & 31;
|
||||
}
|
||||
ipu_fifo.out.readpos = (ipu_fifo.out.readpos + 4) & 31;
|
||||
}
|
||||
}
|
||||
|
||||
void __fastcall WriteFIFO_IPUin(const mem128_t* value)
|
||||
{
|
||||
IPU_LOG( "WriteFIFO/IPUin <- %ls", value->ToString().c_str() );
|
||||
|
||||
//committing every 16 bytes
|
||||
if( ipu_fifo.in.write((u32*)value, 1) == 0 )
|
||||
{
|
||||
IPUProcessInterrupt();
|
||||
}
|
||||
else // IPUin_FIFO
|
||||
ipu_fifo.out.readsingle((void*)out);
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
{
|
||||
ipuRegs->ctrl.SCD = 0;
|
||||
ipuRegs.ctrl.SCD = 0;
|
||||
coded_block_pattern = decoder.coded_block_pattern;
|
||||
|
||||
g_BP.BP += decoder.bitstream_bits - 16;
|
||||
|
@ -710,8 +710,8 @@ bool mpeg2sliceIDEC()
|
|||
decoder.dc_dct_pred[2] = 128 << decoder.intra_dc_precision;
|
||||
|
||||
decoder.mbc = 0;
|
||||
ipuRegs->top = 0;
|
||||
ipuRegs->ctrl.ECD = 0;
|
||||
ipuRegs.top = 0;
|
||||
ipuRegs.ctrl.ECD = 0;
|
||||
|
||||
case 1:
|
||||
ipu_cmd.pos[0] = 1;
|
||||
|
@ -907,17 +907,17 @@ finish_idec:
|
|||
{
|
||||
if (g_BP.BP & 7) g_BP.BP += 8 - (g_BP.BP & 7);
|
||||
|
||||
ipuRegs->ctrl.SCD = 1;
|
||||
ipuRegs.ctrl.SCD = 1;
|
||||
}
|
||||
|
||||
case 4:
|
||||
if (!getBits32((u8*)&ipuRegs->top, 0))
|
||||
if (!getBits32((u8*)&ipuRegs.top, 0))
|
||||
{
|
||||
ipu_cmd.pos[0] = 4;
|
||||
return false;
|
||||
}
|
||||
|
||||
BigEndian(ipuRegs->top, ipuRegs->top);
|
||||
BigEndian(ipuRegs.top, ipuRegs.top);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -942,8 +942,8 @@ bool mpeg2_slice()
|
|||
decoder.dc_dct_pred[2] = 128 << decoder.intra_dc_precision;
|
||||
}
|
||||
|
||||
ipuRegs->ctrl.ECD = 0;
|
||||
ipuRegs->top = 0;
|
||||
ipuRegs.ctrl.ECD = 0;
|
||||
ipuRegs.top = 0;
|
||||
memzero_sse_a(mb8);
|
||||
memzero_sse_a(mb16);
|
||||
case 1:
|
||||
|
@ -1082,7 +1082,7 @@ bool mpeg2_slice()
|
|||
}
|
||||
|
||||
// Send The MacroBlock via DmaIpuFrom
|
||||
ipuRegs->ctrl.SCD = 0;
|
||||
ipuRegs.ctrl.SCD = 0;
|
||||
coded_block_pattern = decoder.coded_block_pattern;
|
||||
g_BP.BP += (int)decoder.bitstream_bits - 16;
|
||||
|
||||
|
@ -1128,17 +1128,17 @@ bool mpeg2_slice()
|
|||
{
|
||||
if (g_BP.BP & 7) g_BP.BP += 8 - (g_BP.BP & 7);
|
||||
|
||||
ipuRegs->ctrl.SCD = 1;
|
||||
ipuRegs.ctrl.SCD = 1;
|
||||
}
|
||||
|
||||
case 5:
|
||||
if (!getBits32((u8*)&ipuRegs->top, 0))
|
||||
if (!getBits32((u8*)&ipuRegs.top, 0))
|
||||
{
|
||||
ipu_cmd.pos[0] = 5;
|
||||
return false;
|
||||
}
|
||||
|
||||
BigEndian(ipuRegs->top, ipuRegs->top);
|
||||
BigEndian(ipuRegs.top, ipuRegs.top);
|
||||
decoder.bitstream_bits = 0;
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -468,7 +468,7 @@ void __fastcall iopMemWrite32(u32 mem, u32 value)
|
|||
|
||||
// wtf? why were we writing to the EE's sif space? Commenting this out doesn't
|
||||
// break any of my games, and should be more correct, but I guess we'll see. --air
|
||||
//*(u32*)(eeMem->HW+0xf200+(mem&0xf0)) = value;
|
||||
//*(u32*)(eeHw+0xf200+(mem&0xf0)) = value;
|
||||
return;
|
||||
}
|
||||
else if (t == 0x1000)
|
||||
|
|
|
@ -137,6 +137,60 @@
|
|||
<Add library="$(SvnRootDir)/deps/release/libUtilities.a" />
|
||||
</Linker>
|
||||
</Target>
|
||||
<Target title="Devel-Debug">
|
||||
<Option platforms="Windows;Unix;" />
|
||||
<Option output="$(SvnRootDir)/bin/pcsx2-deb" prefix_auto="1" extension_auto="1" />
|
||||
<Option working_dir="$(SvnRootDir)/bin/" />
|
||||
<Option object_output="./.objs/devel" />
|
||||
<Option external_deps="../../tools/bin/bin2cpp;" />
|
||||
<Option type="0" />
|
||||
<Option compiler="gcc" />
|
||||
<Compiler>
|
||||
<Add option="-fdefer-pop" />
|
||||
<Add option="-fcprop-registers" />
|
||||
<Add option="-fif-conversion" />
|
||||
<Add option="-fif-conversion2" />
|
||||
<Add option="-ftree-ccp" />
|
||||
<Add option="-ftree-dce" />
|
||||
<Add option="-ftree-dominator-opts" />
|
||||
<Add option="-ftree-ter" />
|
||||
<Add option="-ftree-lrs" />
|
||||
<Add option="-ftree-sra" />
|
||||
<Add option="-ftree-copyrename" />
|
||||
<Add option="-ftree-fre" />
|
||||
<Add option="-ftree-ch" />
|
||||
<Add option="-funit-at-a-time" />
|
||||
<Add option="-fmerge-constants" />
|
||||
<Add option="-fthread-jumps" />
|
||||
<Add option="-fcrossjumping" />
|
||||
<Add option="-foptimize-sibling-calls" />
|
||||
<Add option="-fcse-follow-jumps" />
|
||||
<Add option="-fcse-skip-blocks" />
|
||||
<Add option="-fgcse -fgcse-lm" />
|
||||
<Add option="-frerun-cse-after-loop" />
|
||||
<Add option="-fcaller-saves" />
|
||||
<Add option="-fpeephole2" />
|
||||
<Add option="-fsched-interblock -fsched-spec" />
|
||||
<Add option="-fregmove" />
|
||||
<Add option="-fstrict-overflow" />
|
||||
<Add option="-fdelete-null-pointer-checks" />
|
||||
<Add option="-freorder-blocks -freorder-functions" />
|
||||
<Add option="-falign-functions -falign-jumps" />
|
||||
<Add option="-falign-loops -falign-labels" />
|
||||
<Add option="-ftree-vrp" />
|
||||
<Add option="-ftree-pre" />
|
||||
<Add option="-DPCSX2_DEVBUILD" />
|
||||
<Add option="-DPCSX2_DEVEL" />
|
||||
<Add option="-DNDEBUG" />
|
||||
</Compiler>
|
||||
<ResourceCompiler>
|
||||
<Add directory="$(ProjectRootDir)/gui" />
|
||||
</ResourceCompiler>
|
||||
<Linker>
|
||||
<Add library="$(SvnRootDir)/deps/devel/libx86emitter.a" />
|
||||
<Add library="$(SvnRootDir)/deps/devel/libUtilities.a" />
|
||||
</Linker>
|
||||
</Target>
|
||||
<Environment>
|
||||
<Variable name="SvnRootDir" value="../../" />
|
||||
<Variable name="ProjectRootDir" value='"$(SvnRootDir)/pcsx2/"' />
|
||||
|
@ -240,6 +294,8 @@
|
|||
<Unit filename="../IPU/IPU.h" />
|
||||
<Unit filename="../IPU/IPU_Fifo.cpp" />
|
||||
<Unit filename="../IPU/IPU_Fifo.h" />
|
||||
<Unit filename="../IPU/IPUdma.cpp" />
|
||||
<Unit filename="../IPU/IPUdma.h" />
|
||||
<Unit filename="../IPU/mpeg2lib/Idct.cpp" />
|
||||
<Unit filename="../IPU/mpeg2lib/Mpeg.cpp" />
|
||||
<Unit filename="../IPU/mpeg2lib/Mpeg.h" />
|
||||
|
@ -522,9 +578,11 @@
|
|||
<Unit filename="../ps2/BiosTools.cpp" />
|
||||
<Unit filename="../ps2/BiosTools.h" />
|
||||
<Unit filename="../ps2/GIFpath.cpp" />
|
||||
<Unit filename="../ps2/HwInternal.h" />
|
||||
<Unit filename="../ps2/Iop/IopHwRead.cpp" />
|
||||
<Unit filename="../ps2/Iop/IopHwWrite.cpp" />
|
||||
<Unit filename="../ps2/Iop/IopHw_Internal.h" />
|
||||
<Unit filename="../ps2/LegacyDmac.cpp" />
|
||||
<Unit filename="../vtlb.cpp" />
|
||||
<Unit filename="../vtlb.h" />
|
||||
<Unit filename="../x86/BaseblockEx.cpp" />
|
||||
|
|
|
@ -171,14 +171,11 @@ void PLZCW() {
|
|||
_PLZCW (1);
|
||||
}
|
||||
|
||||
__fi void PMFHL_CLAMP(u16 dst, u16 src)
|
||||
__fi void PMFHL_CLAMP(u16& dst, s32 src)
|
||||
{
|
||||
if ((int)src > (int)0x00007fff)
|
||||
dst = 0x7fff;
|
||||
else if ((int)src < (int)0xffff8000) // Ints only go up to 0x7FFFFFFF. Something's not right here. --arcum42
|
||||
dst = 0x8000;
|
||||
else
|
||||
dst = (u16)src;
|
||||
if (src > 0x7fff) dst = 0x7fff;
|
||||
else if (src < -0x8000) dst = 0x8000;
|
||||
else dst = (u16)src;
|
||||
}
|
||||
|
||||
void PMFHL() {
|
||||
|
|
143
pcsx2/Memory.cpp
143
pcsx2/Memory.cpp
|
@ -35,15 +35,14 @@ BIOS
|
|||
*/
|
||||
|
||||
#include "PrecompiledHeader.h"
|
||||
#include "IopCommon.h"
|
||||
|
||||
#pragma warning(disable:4799) // No EMMS at end of function
|
||||
|
||||
#include <wx/file.h>
|
||||
|
||||
#include "IopCommon.h"
|
||||
#include "VUmicro.h"
|
||||
#include "GS.h"
|
||||
#include "System/PageFaultSource.h"
|
||||
|
||||
#include "ps2/HwInternal.h"
|
||||
#include "ps2/BiosTools.h"
|
||||
|
||||
#ifdef ENABLECACHE
|
||||
|
@ -154,7 +153,6 @@ void memMapPhy()
|
|||
vtlb_MapBlock(psxM,0x1c000000,0x00800000);
|
||||
|
||||
// Generic Handlers; These fallback to mem* stuff...
|
||||
vtlb_MapHandler(tlb_fallback_1,0x10000000,0x10000);
|
||||
vtlb_MapHandler(tlb_fallback_7,0x14000000,0x10000);
|
||||
vtlb_MapHandler(tlb_fallback_4,0x18000000,0x10000);
|
||||
vtlb_MapHandler(tlb_fallback_5,0x1a000000,0x10000);
|
||||
|
@ -166,17 +164,9 @@ void memMapPhy()
|
|||
|
||||
// Hardware Register Handlers : specialized/optimized per-page handling of HW register accesses
|
||||
// (note that hw_by_page handles are assigned in memReset prior to calling this function)
|
||||
vtlb_MapHandler(hw_by_page[0x0], 0x10000000, 0x01000);
|
||||
vtlb_MapHandler(hw_by_page[0x1], 0x10001000, 0x01000);
|
||||
vtlb_MapHandler(hw_by_page[0x2], 0x10002000, 0x01000);
|
||||
vtlb_MapHandler(hw_by_page[0x3], 0x10003000, 0x01000);
|
||||
vtlb_MapHandler(hw_by_page[0x4], 0x10004000, 0x01000);
|
||||
vtlb_MapHandler(hw_by_page[0x5], 0x10005000, 0x01000);
|
||||
vtlb_MapHandler(hw_by_page[0x6], 0x10006000, 0x01000);
|
||||
vtlb_MapHandler(hw_by_page[0x7], 0x10007000, 0x01000);
|
||||
vtlb_MapHandler(hw_by_page[0xb], 0x1000b000, 0x01000);
|
||||
vtlb_MapHandler(hw_by_page[0xe], 0x1000e000, 0x01000);
|
||||
vtlb_MapHandler(hw_by_page[0xf], 0x1000f000, 0x01000);
|
||||
|
||||
for( uint i=0; i<16; ++i)
|
||||
vtlb_MapHandler(hw_by_page[i], 0x10000000 + (0x01000 * i), 0x01000);
|
||||
|
||||
vtlb_MapHandler(gs_page_0, 0x12000000, 0x01000);
|
||||
vtlb_MapHandler(gs_page_1, 0x12001000, 0x01000);
|
||||
|
@ -256,8 +246,6 @@ static mem8_t __fastcall _ext_memRead8 (u32 mem)
|
|||
{
|
||||
switch (p)
|
||||
{
|
||||
case 1: // hwm
|
||||
return hwRead8(mem);
|
||||
case 3: // psh4
|
||||
return psxHw4Read8(mem);
|
||||
case 6: // gsm
|
||||
|
@ -280,8 +268,6 @@ static mem16_t __fastcall _ext_memRead16(u32 mem)
|
|||
{
|
||||
switch (p)
|
||||
{
|
||||
case 1: // hwm
|
||||
return hwRead16(mem);
|
||||
case 4: // b80
|
||||
MEM_LOG("b800000 Memory read16 address %x", mem);
|
||||
return 0;
|
||||
|
@ -358,9 +344,6 @@ template<int p>
|
|||
static void __fastcall _ext_memWrite8 (u32 mem, mem8_t value)
|
||||
{
|
||||
switch (p) {
|
||||
case 1: // hwm
|
||||
hwWrite8(mem, value);
|
||||
return;
|
||||
case 3: // psh4
|
||||
psxHw4Write8(mem, value); return;
|
||||
case 6: // gsm
|
||||
|
@ -379,9 +362,6 @@ template<int p>
|
|||
static void __fastcall _ext_memWrite16(u32 mem, mem16_t value)
|
||||
{
|
||||
switch (p) {
|
||||
case 1: // hwm
|
||||
hwWrite16(mem, value);
|
||||
return;
|
||||
case 5: // ba0
|
||||
MEM_LOG("ba00000 Memory write16 to address %x with data %x", mem, value);
|
||||
return;
|
||||
|
@ -602,10 +582,12 @@ protected:
|
|||
void OnPageFaultEvent( const PageFaultInfo& info, bool& handled );
|
||||
};
|
||||
|
||||
mmap_PageFaultHandler mmap_faultHandler;
|
||||
static mmap_PageFaultHandler mmap_faultHandler;
|
||||
|
||||
EEVM_MemoryAllocMess* eeMem = NULL;
|
||||
|
||||
__pagealigned u8 eeHw[Ps2MemSize::Hardware];
|
||||
|
||||
void memAlloc()
|
||||
{
|
||||
if( eeMem == NULL )
|
||||
|
@ -630,13 +612,28 @@ void memBindConditionalHandlers()
|
|||
{
|
||||
if( hw_by_page[0xf] == -1 ) return;
|
||||
|
||||
vtlbMemR32FP* page0F32( EmuConfig.Speedhacks.IntcStat ? hwRead32_page_0F_INTC_HACK : hwRead32_page_0F );
|
||||
vtlbMemR64FP* page0F64( EmuConfig.Speedhacks.IntcStat ? hwRead64_generic_INTC_HACK : hwRead64_generic );
|
||||
if (EmuConfig.Speedhacks.IntcStat)
|
||||
{
|
||||
vtlbMemR16FP* page0F16(hwRead16_page_0F_INTC_HACK);
|
||||
vtlbMemR32FP* page0F32(hwRead32_page_0F_INTC_HACK);
|
||||
//vtlbMemR64FP* page0F64(hwRead64_generic_INTC_HACK);
|
||||
|
||||
vtlb_ReassignHandler( hw_by_page[0xf],
|
||||
_ext_memRead8<1>, _ext_memRead16<1>, page0F32, page0F64, hwRead128_generic,
|
||||
_ext_memWrite8<1>, _ext_memWrite16<1>, hwWrite32_page_0F, hwWrite64_generic, hwWrite128_generic
|
||||
);
|
||||
vtlb_ReassignHandler( hw_by_page[0xf],
|
||||
hwRead8<0x0f>, page0F16, page0F32, hwRead64<0x0f>, hwRead128<0x0f>,
|
||||
hwWrite8<0x0f>, hwWrite16<0x0f>, hwWrite32<0x0f>, hwWrite64<0x0f>, hwWrite128<0x0f>
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
vtlbMemR16FP* page0F16(hwRead16<0x0f>);
|
||||
vtlbMemR32FP* page0F32(hwRead32<0x0f>);
|
||||
//vtlbMemR64FP* page0F64(hwRead64<0x0f>);
|
||||
|
||||
vtlb_ReassignHandler( hw_by_page[0xf],
|
||||
hwRead8<0x0f>, page0F16, page0F32, hwRead64<0x0f>, hwRead128<0x0f>,
|
||||
hwWrite8<0x0f>, hwWrite16<0x0f>, hwWrite32<0x0f>, hwWrite64<0x0f>, hwWrite128<0x0f>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Resets memory mappings, unmaps TLBs, reloads bios roms, etc.
|
||||
|
@ -664,7 +661,6 @@ void memReset()
|
|||
tlb_fallback_3 = vtlb_RegisterHandlerTempl1(_ext_mem,3);
|
||||
tlb_fallback_4 = vtlb_RegisterHandlerTempl1(_ext_mem,4);
|
||||
tlb_fallback_5 = vtlb_RegisterHandlerTempl1(_ext_mem,5);
|
||||
//tlb_fallback_6 = vtlb_RegisterHandlerTempl1(_ext_mem,6);
|
||||
tlb_fallback_7 = vtlb_RegisterHandlerTempl1(_ext_mem,7);
|
||||
tlb_fallback_8 = vtlb_RegisterHandlerTempl1(_ext_mem,8);
|
||||
|
||||
|
@ -701,68 +697,29 @@ void memReset()
|
|||
);
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// psHw Optimized Mappings
|
||||
// The HW Registers have been split into pages to improve optimization.
|
||||
// Anything not explicitly mapped into one of the hw_by_page handlers will be handled
|
||||
// by the default/generic tlb_fallback_1 handler.
|
||||
|
||||
#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(
|
||||
_ext_memRead8<1>, _ext_memRead16<1>, hwRead32_generic, hwRead64_generic, hwRead128_generic,
|
||||
_ext_memWrite8<1>, _ext_memWrite16<1>, hwWrite32_generic, hwWrite64_generic, hwWrite128_generic
|
||||
);
|
||||
|
||||
hw_by_page[0x0] = vtlb_RegisterHandler(
|
||||
_ext_memRead8<1>, _ext_memRead16<1>, hwRead32_page_00, hwRead64_page_00, hwRead128_page_00,
|
||||
_ext_memWrite8<1>, _ext_memWrite16<1>, hwWrite32_page_00, hwWrite64_page_00, hwWrite128_generic
|
||||
);
|
||||
|
||||
hw_by_page[0x1] = vtlb_RegisterHandler(
|
||||
_ext_memRead8<1>, _ext_memRead16<1>, hwRead32_page_01, hwRead64_page_01, hwRead128_page_01,
|
||||
_ext_memWrite8<1>, _ext_memWrite16<1>, hwWrite32_page_01, hwWrite64_page_01, hwWrite128_generic
|
||||
);
|
||||
|
||||
hw_by_page[0x2] = vtlb_RegisterHandler(
|
||||
_ext_memRead8<1>, _ext_memRead16<1>, hwRead32_page_02, hwRead64_page_02, hwRead128_page_02,
|
||||
_ext_memWrite8<1>, _ext_memWrite16<1>, hwWrite32_page_02, hwWrite64_page_02, hwWrite128_generic
|
||||
);
|
||||
|
||||
hw_by_page[0x3] = vtlb_RegisterHandler(
|
||||
_ext_memRead8<1>, _ext_memRead16<1>, hwRead32_generic, hwRead64_generic, hwRead128_generic,
|
||||
_ext_memWrite8<1>, _ext_memWrite16<1>, hwWrite32_page_03, hwWrite64_page_03, hwWrite128_generic
|
||||
);
|
||||
|
||||
hw_by_page[0x4] = vtlb_RegisterHandler(
|
||||
_ext_memRead8<1>, _ext_memRead16<1>, hwRead32_generic, hwRead64_generic, ReadFIFO_page_4,
|
||||
_ext_memWrite8<1>, _ext_memWrite16<1>, hwWrite32_generic, hwWrite64_generic, WriteFIFO_page_4
|
||||
);
|
||||
|
||||
hw_by_page[0x5] = vtlb_RegisterHandler(
|
||||
_ext_memRead8<1>, _ext_memRead16<1>, hwRead32_generic, hwRead64_generic, ReadFIFO_page_5,
|
||||
_ext_memWrite8<1>, _ext_memWrite16<1>, hwWrite32_generic, hwWrite64_generic, WriteFIFO_page_5
|
||||
);
|
||||
|
||||
hw_by_page[0x6] = vtlb_RegisterHandler(
|
||||
_ext_memRead8<1>, _ext_memRead16<1>, hwRead32_generic, hwRead64_generic, ReadFIFO_page_6,
|
||||
_ext_memWrite8<1>, _ext_memWrite16<1>, hwWrite32_generic, hwWrite64_generic, WriteFIFO_page_6
|
||||
);
|
||||
|
||||
hw_by_page[0x7] = vtlb_RegisterHandler(
|
||||
_ext_memRead8<1>, _ext_memRead16<1>, hwRead32_generic, hwRead64_generic, ReadFIFO_page_7,
|
||||
_ext_memWrite8<1>, _ext_memWrite16<1>, hwWrite32_generic, hwWrite64_generic, WriteFIFO_page_7
|
||||
);
|
||||
|
||||
hw_by_page[0xb] = vtlb_RegisterHandler(
|
||||
_ext_memRead8<1>, _ext_memRead16<1>, hwRead32_generic, hwRead64_generic, hwRead128_generic,
|
||||
_ext_memWrite8<1>, _ext_memWrite16<1>, hwWrite32_page_0B, hwWrite64_generic, hwWrite128_generic
|
||||
);
|
||||
|
||||
hw_by_page[0xe] = vtlb_RegisterHandler(
|
||||
_ext_memRead8<1>, _ext_memRead16<1>, hwRead32_generic, hwRead64_generic, hwRead128_generic,
|
||||
_ext_memWrite8<1>, _ext_memWrite16<1>, hwWrite32_page_0E, hwWrite64_page_0E, hwWrite128_generic
|
||||
);
|
||||
|
||||
hw_by_page[0xf] = vtlb_NewHandler();
|
||||
hw_by_page[0x0] = vtlb_RegisterHandler( hwHandlerTmpl(0x00) );
|
||||
hw_by_page[0x1] = vtlb_RegisterHandler( hwHandlerTmpl(0x01) );
|
||||
hw_by_page[0x2] = vtlb_RegisterHandler( hwHandlerTmpl(0x02) );
|
||||
hw_by_page[0x3] = vtlb_RegisterHandler( hwHandlerTmpl(0x03) );
|
||||
hw_by_page[0x4] = vtlb_RegisterHandler( hwHandlerTmpl(0x04) );
|
||||
hw_by_page[0x5] = vtlb_RegisterHandler( hwHandlerTmpl(0x05) );
|
||||
hw_by_page[0x6] = vtlb_RegisterHandler( hwHandlerTmpl(0x06) );
|
||||
hw_by_page[0x7] = vtlb_RegisterHandler( hwHandlerTmpl(0x07) );
|
||||
hw_by_page[0x8] = vtlb_RegisterHandler( hwHandlerTmpl(0x08) );
|
||||
hw_by_page[0x9] = vtlb_RegisterHandler( hwHandlerTmpl(0x09) );
|
||||
hw_by_page[0xa] = vtlb_RegisterHandler( hwHandlerTmpl(0x0a) );
|
||||
hw_by_page[0xb] = vtlb_RegisterHandler( hwHandlerTmpl(0x0b) );
|
||||
hw_by_page[0xc] = vtlb_RegisterHandler( hwHandlerTmpl(0x0c) );
|
||||
hw_by_page[0xd] = vtlb_RegisterHandler( hwHandlerTmpl(0x0d) );
|
||||
hw_by_page[0xe] = vtlb_RegisterHandler( hwHandlerTmpl(0x0e) );
|
||||
hw_by_page[0xf] = vtlb_NewHandler(); // redefined later based on speedhacking prefs
|
||||
memBindConditionalHandlers();
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -34,33 +34,22 @@ static __fi void ZeroQWC( void* dest )
|
|||
_mm_store_ps( (float*)dest, _mm_setzero_ps() );
|
||||
}
|
||||
|
||||
// Various useful locations
|
||||
#define spr0 ((DMACh*)&eeMem->HW[0xD000])
|
||||
#define spr1 ((DMACh*)&eeMem->HW[0xD400])
|
||||
|
||||
#define gif ((DMACh*)&eeMem->HW[0xA000])
|
||||
|
||||
#define vif0ch ((DMACh*)&eeMem->HW[0x8000])
|
||||
#define vif1ch ((DMACh*)&eeMem->HW[0x9000])
|
||||
|
||||
#define sif0dma ((DMACh*)&eeMem->HW[0xc000])
|
||||
#define sif1dma ((DMACh*)&eeMem->HW[0xc400])
|
||||
#define sif2dma ((DMACh*)&eeMem->HW[0xc800])
|
||||
|
||||
#define ipu0dma ((DMACh *)&eeMem->HW[0xb000])
|
||||
#define ipu1dma ((DMACh *)&eeMem->HW[0xb400])
|
||||
static __fi void ZeroQWC( u128& dest )
|
||||
{
|
||||
_mm_store_ps( (float*)&dest, _mm_setzero_ps() );
|
||||
}
|
||||
|
||||
#define PSM(mem) (vtlb_GetPhyPtr((mem)&0x1fffffff)) //pcsx2 is a competition.The one with most hacks wins :D
|
||||
|
||||
#define psHs8(mem) (*(s8 *)&eeMem->HW[(mem) & 0xffff])
|
||||
#define psHs16(mem) (*(s16*)&eeMem->HW[(mem) & 0xffff])
|
||||
#define psHs32(mem) (*(s32*)&eeMem->HW[(mem) & 0xffff])
|
||||
#define psHs64(mem) (*(s64*)&eeMem->HW[(mem) & 0xffff])
|
||||
#define psHu8(mem) (*(u8 *)&eeMem->HW[(mem) & 0xffff])
|
||||
#define psHu16(mem) (*(u16*)&eeMem->HW[(mem) & 0xffff])
|
||||
#define psHu32(mem) (*(u32*)&eeMem->HW[(mem) & 0xffff])
|
||||
#define psHu64(mem) (*(u64*)&eeMem->HW[(mem) & 0xffff])
|
||||
#define psHu128(mem)(*(u128*)&eeMem->HW[(mem) & 0xffff])
|
||||
#define psHs8(mem) (*(s8 *)&eeHw[(mem) & 0xffff])
|
||||
#define psHs16(mem) (*(s16*)&eeHw[(mem) & 0xffff])
|
||||
#define psHs32(mem) (*(s32*)&eeHw[(mem) & 0xffff])
|
||||
#define psHs64(mem) (*(s64*)&eeHw[(mem) & 0xffff])
|
||||
#define psHu8(mem) (*(u8 *)&eeHw[(mem) & 0xffff])
|
||||
#define psHu16(mem) (*(u16*)&eeHw[(mem) & 0xffff])
|
||||
#define psHu32(mem) (*(u32*)&eeHw[(mem) & 0xffff])
|
||||
#define psHu64(mem) (*(u64*)&eeHw[(mem) & 0xffff])
|
||||
#define psHu128(mem)(*(u128*)&eeHw[(mem) & 0xffff])
|
||||
|
||||
#define psMs8(mem) (*(s8 *)&eeMem->Main[(mem) & 0x1ffffff])
|
||||
#define psMs16(mem) (*(s16*)&eeMem->Main[(mem) & 0x1ffffff])
|
||||
|
@ -114,8 +103,6 @@ static __fi void ZeroQWC( void* dest )
|
|||
#define psSu64(mem) (*(u64 *)&eeMem->Scratch[(mem) & 0x3fff])
|
||||
#define psSu128(mem) (*(u128*)&eeMem->Scratch[(mem) & 0x3fff])
|
||||
|
||||
#define psH_DMACh(mem) (*(DMACh*)&eeMem->HW[(mem) & 0xffff])
|
||||
|
||||
extern void memAlloc();
|
||||
extern void memReset(); // clears PS2 ram and loads the bios. Throws Exception::FileNotFound on error.
|
||||
extern void memShutdown();
|
||||
|
@ -135,13 +122,21 @@ extern void mmap_ResetBlockTracking();
|
|||
#define memRead8 vtlb_memRead<mem8_t>
|
||||
#define memRead16 vtlb_memRead<mem16_t>
|
||||
#define memRead32 vtlb_memRead<mem32_t>
|
||||
#define memRead64 vtlb_memRead64
|
||||
#define memRead128 vtlb_memRead128
|
||||
|
||||
#define memWrite8 vtlb_memWrite<mem8_t>
|
||||
#define memWrite16 vtlb_memWrite<mem16_t>
|
||||
#define memWrite32 vtlb_memWrite<mem32_t>
|
||||
#define memWrite64 vtlb_memWrite64
|
||||
#define memWrite128 vtlb_memWrite128
|
||||
|
||||
static __fi void memRead64(u32 mem, mem64_t* out) { vtlb_memRead64(mem, out); }
|
||||
static __fi void memRead64(u32 mem, mem64_t& out) { vtlb_memRead64(mem, &out); }
|
||||
|
||||
static __fi void memRead128(u32 mem, mem128_t* out) { vtlb_memRead128(mem, out); }
|
||||
static __fi void memRead128(u32 mem, mem128_t& out) { vtlb_memRead128(mem, &out); }
|
||||
|
||||
static __fi void memWrite64(u32 mem, const mem64_t* val) { vtlb_memWrite64(mem, val); }
|
||||
static __fi void memWrite64(u32 mem, const mem64_t& val) { vtlb_memWrite64(mem, &val); }
|
||||
static __fi void memWrite128(u32 mem, const mem128_t* val) { vtlb_memWrite128(mem, val); }
|
||||
static __fi void memWrite128(u32 mem, const mem128_t& val) { vtlb_memWrite128(mem, &val); }
|
||||
|
||||
|
||||
extern u16 ba0R16(u32 mem);
|
||||
|
|
|
@ -37,15 +37,55 @@ typedef u32 mem32_t;
|
|||
typedef u64 mem64_t;
|
||||
typedef u128 mem128_t;
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// Future-Planned VTLB pagefault scheme!
|
||||
// --------------------------------------------------------------------------------------
|
||||
// When enabled, the VTLB will use a large-area reserved memory range of 512megs for EE
|
||||
// physical ram/rom access. The base ram will be committed at 0x00000000, and ROMs will be
|
||||
// at 0x1fc00000, etc. All memory ranges in between will be uncommitted memory -- which
|
||||
// means that the memory will *not* count against the operating system's physical memory
|
||||
// pool.
|
||||
//
|
||||
// When the VTLB generates memory operations (loads/stores), it will assume that the op
|
||||
// is addressing either RAM or ROM, and by assuming that it can generate a completely efficient
|
||||
// direct memory access (one AND and one MOV instruction). If the access is to another area of
|
||||
// memory, such as hardware registers or scratchpad, the access will generate a page fault, the
|
||||
// compiled block will be cleared and re-compiled using "full" VTLB translation logic.
|
||||
//
|
||||
#define VTLB_UsePageFaulting 0
|
||||
|
||||
#if VTLB_UsePageFaulting
|
||||
|
||||
// The order of the components in this struct *matter* -- it has been laid out so that the
|
||||
// full breadth of PS2 RAM and ROM mappings are directly supported.
|
||||
struct EEVM_MemoryAllocMess
|
||||
{
|
||||
u8 (&Main)[Ps2MemSize::Base]; // Main memory (hard-wired to 32MB)
|
||||
|
||||
u8 _padding1[0x1e000000-Ps2MemSize::Base]
|
||||
u8 (&ROM1)[Ps2MemSize::Rom1]; // DVD player
|
||||
|
||||
u8 _padding2[0x1e040000-(0x1e000000+Ps2MemSize::Rom1)]
|
||||
u8 (&EROM)[Ps2MemSize::ERom]; // DVD player extensions
|
||||
|
||||
u8 _padding3[0x1e400000-(0x1e040000+Ps2MemSize::EROM)]
|
||||
u8 (&ROM2)[Ps2MemSize::Rom2]; // Chinese extensions
|
||||
|
||||
u8 _padding4[0x1fc00000-(0x1e040000+Ps2MemSize::Rom2)];
|
||||
u8 (&ROM)[Ps2MemSize::Rom]; // Boot rom (4MB)
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
struct EEVM_MemoryAllocMess
|
||||
{
|
||||
u8 Scratch[Ps2MemSize::Scratch]; // Scratchpad!
|
||||
u8 Main[Ps2MemSize::Base]; // Main memory (hard-wired to 32MB)
|
||||
u8 HW[Ps2MemSize::Hardware]; // Hardware registers
|
||||
u8 ROM[Ps2MemSize::Rom]; // Boot rom (4MB)
|
||||
u8 ROM1[Ps2MemSize::Rom1]; // DVD player
|
||||
u8 ROM2[Ps2MemSize::Rom2]; // Chinese extensions (?)
|
||||
u8 EROM[Ps2MemSize::ERom]; // DVD player extensions (?)
|
||||
u8 ROM2[Ps2MemSize::Rom2]; // Chinese extensions
|
||||
u8 EROM[Ps2MemSize::ERom]; // DVD player extensions
|
||||
|
||||
// Two 1 megabyte (max DMA) buffers for reading and writing to high memory (>32MB).
|
||||
// Such accesses are not documented as causing bus errors but as the memory does
|
||||
|
@ -56,4 +96,13 @@ struct EEVM_MemoryAllocMess
|
|||
u8 ZeroWrite[_1mb];
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
// EE Hardware registers.
|
||||
// DevNote: These are done as a static array instead of a pointer in order to allow for simpler
|
||||
// macros and reference handles to be defined (we can safely use compile-time references to
|
||||
// registers instead of having to use instance variables).
|
||||
extern __pagealigned u8 eeHw[Ps2MemSize::Hardware];
|
||||
|
||||
|
||||
extern EEVM_MemoryAllocMess* eeMem;
|
||||
|
|
|
@ -78,6 +78,7 @@ typedef int BOOL;
|
|||
#define TRUE 1
|
||||
#define FALSE 0
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Begin Pcsx2 Includes: Add items here that are local to Pcsx2 but stay relatively
|
||||
// unchanged for long periods of time, or happen to be used by almost everything, so they
|
||||
|
@ -100,15 +101,24 @@ typedef int BOOL;
|
|||
|
||||
#include "Config.h"
|
||||
|
||||
typedef void FnType_Void();
|
||||
typedef FnType_Void* Fnptr_Void;
|
||||
|
||||
static const s64 _1mb = 0x100000;
|
||||
static const s64 _8mb = _1mb * 8;
|
||||
static const s64 _16mb = _1mb * 16;
|
||||
static const s64 _256mb = _1mb * 256;
|
||||
static const s64 _1gb = _256mb * 4;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Compiler/OS specific macros and defines -- Begin Section
|
||||
|
||||
// Linux isn't set up for svn version numbers yet.
|
||||
#ifdef __LINUX__
|
||||
# define SVN_REV 0
|
||||
# define SVN_MODS 0
|
||||
#endif
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Compiler/OS specific macros and defines -- Begin Section
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
|
||||
# define strnicmp _strnicmp
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include "R5900Exceptions.h"
|
||||
|
||||
#include "Hardware.h"
|
||||
#include "IPU/IPUdma.h"
|
||||
|
||||
#include "Elfheader.h"
|
||||
#include "CDVD/CDVD.h"
|
||||
|
@ -287,9 +288,11 @@ static __fi void TESTINT( u8 n, void (*callback)() )
|
|||
cpuSetNextBranch( cpuRegs.sCycle[n], cpuRegs.eCycle[n] );
|
||||
}
|
||||
|
||||
// [TODO] move this function to LegacyDmac.cpp, and remove most of the DMAC-related headers from
|
||||
// being included into R5900.cpp.
|
||||
static __fi void _cpuTestInterrupts()
|
||||
{
|
||||
if (!dmacRegs->ctrl.DMAE || psHu8(DMAC_ENABLER+2) == 1)
|
||||
if (!dmacRegs.ctrl.DMAE || (psHu8(DMAC_ENABLER+2) & 1))
|
||||
{
|
||||
//Console.Write("DMAC Disabled or suspended");
|
||||
return;
|
||||
|
@ -415,7 +418,7 @@ __fi void _cpuBranchTest_Shared()
|
|||
//if( EEsCycle < -450 )
|
||||
// Console.WriteLn( " IOP ahead by: %d cycles", -EEsCycle );
|
||||
|
||||
// Experimental and Probably Unnecessry Logic -->
|
||||
// Experimental and Probably Unnecessary Logic -->
|
||||
// Check if the EE already has an exception pending, and if so we shouldn't
|
||||
// waste too much time updating the IOP. Theory being that the EE and IOP should
|
||||
// run closely in sync during raised exception events. But in practice it didn't
|
||||
|
@ -502,11 +505,8 @@ __ri void cpuTestINTCInts()
|
|||
cpuRegs.sCycle[30] = cpuRegs.cycle;
|
||||
cpuRegs.eCycle[30] = 4; //Needs to be 4 to account for bus delays/pipelines etc
|
||||
|
||||
// only set the next branch delta if the exception won't be handled for
|
||||
// the current branch...
|
||||
if( !eeEventTestIsActive )
|
||||
cpuSetNextBranchDelta( 4 );
|
||||
else if(psxCycleEE > 0)
|
||||
cpuSetNextBranchDelta( 4 );
|
||||
if(eeEventTestIsActive && (psxCycleEE > 0))
|
||||
{
|
||||
psxBreak += psxCycleEE; // record the number of cycles the IOP didn't run.
|
||||
psxCycleEE = 0;
|
||||
|
@ -529,11 +529,8 @@ __fi void cpuTestDMACInts()
|
|||
cpuRegs.sCycle[31] = cpuRegs.cycle;
|
||||
cpuRegs.eCycle[31] = 4; //Needs to be 4 to account for bus delays/pipelines etc
|
||||
|
||||
// only set the next branch delta if the exception won't be handled for
|
||||
// the current branch...
|
||||
if( !eeEventTestIsActive )
|
||||
cpuSetNextBranchDelta( 4 );
|
||||
else if(psxCycleEE > 0)
|
||||
cpuSetNextBranchDelta( 4 );
|
||||
if(eeEventTestIsActive && (psxCycleEE > 0))
|
||||
{
|
||||
psxBreak += psxCycleEE; // record the number of cycles the IOP didn't run.
|
||||
psxCycleEE = 0;
|
||||
|
|
|
@ -816,7 +816,7 @@ void SQ()
|
|||
// an address error due to unaligned access isn't possible like it is on other loads/stores.
|
||||
|
||||
u32 addr = cpuRegs.GPR.r[_Rs_].UL[0] + _Imm_;
|
||||
memWrite128(addr & ~0xf, cpuRegs.GPR.r[_Rt_].UD);
|
||||
memWrite128(addr & ~0xf, cpuRegs.GPR.r[_Rt_].UQ);
|
||||
}
|
||||
|
||||
/*********************************************************
|
||||
|
@ -868,8 +868,7 @@ void SYSCALL()
|
|||
}
|
||||
|
||||
// The only thing this code is used for is the one log message, so don't execute it if we aren't logging bios messages.
|
||||
#ifdef PCSX2_DEVBUILD
|
||||
if (SysTrace.EE.Bios.IsActive() && (call == 0x77))
|
||||
if (SysTraceActive(EE.Bios) && (call == 0x77))
|
||||
{
|
||||
t_sif_dma_transfer *dmat;
|
||||
//struct t_sif_cmd_header *hdr;
|
||||
|
@ -891,7 +890,6 @@ void SYSCALL()
|
|||
dmat->dest, dmat->src);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
cpuRegs.pc -= 4;
|
||||
cpuException(0x20, cpuRegs.branch);
|
||||
|
|
180
pcsx2/SPR.cpp
180
pcsx2/SPR.cpp
|
@ -51,96 +51,96 @@ int _SPR0chain()
|
|||
{
|
||||
tDMA_TAG *pMem;
|
||||
|
||||
if (spr0->qwc == 0) return 0;
|
||||
pMem = SPRdmaGetAddr(spr0->madr, true);
|
||||
if (spr0ch.qwc == 0) return 0;
|
||||
pMem = SPRdmaGetAddr(spr0ch.madr, true);
|
||||
if (pMem == NULL) return -1;
|
||||
|
||||
switch (dmacRegs->ctrl.MFD)
|
||||
switch (dmacRegs.ctrl.MFD)
|
||||
{
|
||||
case MFD_VIF1:
|
||||
case MFD_GIF:
|
||||
if ((spr0->madr & ~dmacRegs->rbsr.RMSK) != dmacRegs->rbor.ADDR)
|
||||
if ((spr0ch.madr & ~dmacRegs.rbsr.RMSK) != dmacRegs.rbor.ADDR)
|
||||
Console.WriteLn("SPR MFIFO Write outside MFIFO area");
|
||||
else
|
||||
mfifotransferred += spr0->qwc;
|
||||
mfifotransferred += spr0ch.qwc;
|
||||
|
||||
hwMFIFOWrite(spr0->madr, &psSu128(spr0->sadr), spr0->qwc);
|
||||
spr0->madr += spr0->qwc << 4;
|
||||
spr0->madr = dmacRegs->rbor.ADDR + (spr0->madr & dmacRegs->rbsr.RMSK);
|
||||
hwMFIFOWrite(spr0ch.madr, &psSu128(spr0ch.sadr), spr0ch.qwc);
|
||||
spr0ch.madr += spr0ch.qwc << 4;
|
||||
spr0ch.madr = dmacRegs.rbor.ADDR + (spr0ch.madr & dmacRegs.rbsr.RMSK);
|
||||
break;
|
||||
|
||||
case NO_MFD:
|
||||
case MFD_RESERVED:
|
||||
memcpy_qwc(pMem, &psSu128(spr0->sadr), spr0->qwc);
|
||||
memcpy_qwc(pMem, &psSu128(spr0ch.sadr), spr0ch.qwc);
|
||||
|
||||
// clear VU mem also!
|
||||
TestClearVUs(spr0->madr, spr0->qwc << 2); // Wtf is going on here? AFAIK, only VIF should affect VU micromem (cottonvibes)
|
||||
spr0->madr += spr0->qwc << 4;
|
||||
TestClearVUs(spr0ch.madr, spr0ch.qwc << 2); // Wtf is going on here? AFAIK, only VIF should affect VU micromem (cottonvibes)
|
||||
spr0ch.madr += spr0ch.qwc << 4;
|
||||
break;
|
||||
}
|
||||
|
||||
spr0->sadr += spr0->qwc << 4;
|
||||
spr0ch.sadr += spr0ch.qwc << 4;
|
||||
|
||||
return (spr0->qwc); // bus is 1/2 the ee speed
|
||||
return (spr0ch.qwc); // bus is 1/2 the ee speed
|
||||
}
|
||||
|
||||
__fi void SPR0chain()
|
||||
{
|
||||
CPU_INT(DMAC_FROM_SPR, _SPR0chain() / BIAS);
|
||||
spr0->qwc = 0;
|
||||
spr0ch.qwc = 0;
|
||||
}
|
||||
|
||||
void _SPR0interleave()
|
||||
{
|
||||
int qwc = spr0->qwc;
|
||||
int sqwc = dmacRegs->sqwc.SQWC;
|
||||
int tqwc = dmacRegs->sqwc.TQWC;
|
||||
int qwc = spr0ch.qwc;
|
||||
int sqwc = dmacRegs.sqwc.SQWC;
|
||||
int tqwc = dmacRegs.sqwc.TQWC;
|
||||
tDMA_TAG *pMem;
|
||||
|
||||
if (tqwc == 0) tqwc = qwc;
|
||||
//Console.WriteLn("dmaSPR0 interleave");
|
||||
SPR_LOG("SPR0 interleave size=%d, tqwc=%d, sqwc=%d, addr=%lx sadr=%lx",
|
||||
spr0->qwc, tqwc, sqwc, spr0->madr, spr0->sadr);
|
||||
spr0ch.qwc, tqwc, sqwc, spr0ch.madr, spr0ch.sadr);
|
||||
|
||||
CPU_INT(DMAC_FROM_SPR, qwc / BIAS);
|
||||
|
||||
while (qwc > 0)
|
||||
{
|
||||
spr0->qwc = std::min(tqwc, qwc);
|
||||
qwc -= spr0->qwc;
|
||||
pMem = SPRdmaGetAddr(spr0->madr, true);
|
||||
spr0ch.qwc = std::min(tqwc, qwc);
|
||||
qwc -= spr0ch.qwc;
|
||||
pMem = SPRdmaGetAddr(spr0ch.madr, true);
|
||||
|
||||
switch (dmacRegs->ctrl.MFD)
|
||||
switch (dmacRegs.ctrl.MFD)
|
||||
{
|
||||
case MFD_VIF1:
|
||||
case MFD_GIF:
|
||||
hwMFIFOWrite(spr0->madr, &psSu128(spr0->sadr), spr0->qwc);
|
||||
mfifotransferred += spr0->qwc;
|
||||
hwMFIFOWrite(spr0ch.madr, &psSu128(spr0ch.sadr), spr0ch.qwc);
|
||||
mfifotransferred += spr0ch.qwc;
|
||||
break;
|
||||
|
||||
case NO_MFD:
|
||||
case MFD_RESERVED:
|
||||
// clear VU mem also!
|
||||
TestClearVUs(spr0->madr, spr0->qwc << 2);
|
||||
memcpy_qwc(pMem, &psSu128(spr0->sadr), spr0->qwc);
|
||||
TestClearVUs(spr0ch.madr, spr0ch.qwc << 2);
|
||||
memcpy_qwc(pMem, &psSu128(spr0ch.sadr), spr0ch.qwc);
|
||||
break;
|
||||
}
|
||||
spr0->sadr += spr0->qwc * 16;
|
||||
spr0->madr += (sqwc + spr0->qwc) * 16;
|
||||
spr0ch.sadr += spr0ch.qwc * 16;
|
||||
spr0ch.madr += (sqwc + spr0ch.qwc) * 16;
|
||||
}
|
||||
|
||||
spr0->qwc = 0;
|
||||
spr0ch.qwc = 0;
|
||||
}
|
||||
|
||||
static __fi void _dmaSPR0()
|
||||
{
|
||||
if (dmacRegs->ctrl.STS == STS_fromSPR)
|
||||
if (dmacRegs.ctrl.STS == STS_fromSPR)
|
||||
{
|
||||
Console.WriteLn("SPR0 stall %d", dmacRegs->ctrl.STS);
|
||||
Console.WriteLn("SPR0 stall %d", dmacRegs.ctrl.STS);
|
||||
}
|
||||
|
||||
// Transfer Dn_QWC from SPR to Dn_MADR
|
||||
switch(spr0->chcr.MOD)
|
||||
switch(spr0ch.chcr.MOD)
|
||||
{
|
||||
case NORMAL_MODE:
|
||||
{
|
||||
|
@ -153,23 +153,23 @@ static __fi void _dmaSPR0()
|
|||
tDMA_TAG *ptag;
|
||||
bool done = false;
|
||||
|
||||
if (spr0->qwc > 0)
|
||||
if (spr0ch.qwc > 0)
|
||||
{
|
||||
SPR0chain();
|
||||
return;
|
||||
}
|
||||
// Destination Chain Mode
|
||||
ptag = (tDMA_TAG*)&psSu32(spr0->sadr);
|
||||
spr0->sadr += 16;
|
||||
ptag = (tDMA_TAG*)&psSu32(spr0ch.sadr);
|
||||
spr0ch.sadr += 16;
|
||||
|
||||
spr0->unsafeTransfer(ptag);
|
||||
spr0ch.unsafeTransfer(ptag);
|
||||
|
||||
spr0->madr = ptag[1]._u32; //MADR = ADDR field + SPR
|
||||
spr0ch.madr = ptag[1]._u32; //MADR = ADDR field + SPR
|
||||
|
||||
SPR_LOG("spr0 dmaChain %8.8x_%8.8x size=%d, id=%d, addr=%lx spr=%lx",
|
||||
ptag[1]._u32, ptag[0]._u32, spr0->qwc, ptag->ID, spr0->madr, spr0->sadr);
|
||||
ptag[1]._u32, ptag[0]._u32, spr0ch.qwc, ptag->ID, spr0ch.madr, spr0ch.sadr);
|
||||
|
||||
if (dmacRegs->ctrl.STS == STS_fromSPR) // STS == fromSPR
|
||||
if (dmacRegs.ctrl.STS == STS_fromSPR) // STS == fromSPR
|
||||
{
|
||||
Console.WriteLn("SPR stall control");
|
||||
}
|
||||
|
@ -177,7 +177,7 @@ static __fi void _dmaSPR0()
|
|||
switch (ptag->ID)
|
||||
{
|
||||
case TAG_CNTS: // CNTS - Transfer QWC following the tag (Stall Control)
|
||||
if (dmacRegs->ctrl.STS == STS_fromSPR) dmacRegs->stadr.ADDR = spr0->madr + (spr0->qwc * 16); //Copy MADR to DMAC_STADR stall addr register
|
||||
if (dmacRegs.ctrl.STS == STS_fromSPR) dmacRegs.stadr.ADDR = spr0ch.madr + (spr0ch.qwc * 16); //Copy MADR to DMAC_STADR stall addr register
|
||||
break;
|
||||
|
||||
case TAG_CNT: // CNT - Transfer QWC following the tag.
|
||||
|
@ -191,7 +191,7 @@ static __fi void _dmaSPR0()
|
|||
|
||||
SPR0chain();
|
||||
|
||||
if (spr0->chcr.TIE && ptag->IRQ) //Check TIE bit of CHCR and IRQ bit of tag
|
||||
if (spr0ch.chcr.TIE && ptag->IRQ) //Check TIE bit of CHCR and IRQ bit of tag
|
||||
{
|
||||
//Console.WriteLn("SPR0 TIE");
|
||||
done = true;
|
||||
|
@ -199,7 +199,7 @@ static __fi void _dmaSPR0()
|
|||
|
||||
spr0finished = done;
|
||||
SPR_LOG("spr0 dmaChain complete %8.8x_%8.8x size=%d, id=%d, addr=%lx spr=%lx",
|
||||
ptag[1]._u32, ptag[0]._u32, spr0->qwc, ptag->ID, spr0->madr);
|
||||
ptag[1]._u32, ptag[0]._u32, spr0ch.qwc, ptag->ID, spr0ch.madr);
|
||||
break;
|
||||
}
|
||||
//case INTERLEAVE_MODE:
|
||||
|
@ -215,27 +215,27 @@ static __fi void _dmaSPR0()
|
|||
void SPRFROMinterrupt()
|
||||
{
|
||||
|
||||
if (!spr0finished || spr0->qwc > 0)
|
||||
if (!spr0finished || spr0ch.qwc > 0)
|
||||
{
|
||||
_dmaSPR0();
|
||||
|
||||
if(mfifotransferred != 0)
|
||||
{
|
||||
switch (dmacRegs->ctrl.MFD)
|
||||
switch (dmacRegs.ctrl.MFD)
|
||||
{
|
||||
case MFD_VIF1: // Most common case.
|
||||
{
|
||||
if ((spr0->madr & ~dmacRegs->rbsr.RMSK) != dmacRegs->rbor.ADDR) Console.WriteLn("VIF MFIFO Write outside MFIFO area");
|
||||
spr0->madr = dmacRegs->rbor.ADDR + (spr0->madr & dmacRegs->rbsr.RMSK);
|
||||
//Console.WriteLn("mfifoVIF1transfer %x madr %x, tadr %x", vif1ch->chcr._u32, vif1ch->madr, vif1ch->tadr);
|
||||
if ((spr0ch.madr & ~dmacRegs.rbsr.RMSK) != dmacRegs.rbor.ADDR) Console.WriteLn("VIF MFIFO Write outside MFIFO area");
|
||||
spr0ch.madr = dmacRegs.rbor.ADDR + (spr0ch.madr & dmacRegs.rbsr.RMSK);
|
||||
//Console.WriteLn("mfifoVIF1transfer %x madr %x, tadr %x", vif1ch.chcr._u32, vif1ch.madr, vif1ch.tadr);
|
||||
mfifoVIF1transfer(mfifotransferred);
|
||||
mfifotransferred = 0;
|
||||
break;
|
||||
}
|
||||
case MFD_GIF:
|
||||
{
|
||||
if ((spr0->madr & ~dmacRegs->rbsr.RMSK) != dmacRegs->rbor.ADDR) Console.WriteLn("GIF MFIFO Write outside MFIFO area");
|
||||
spr0->madr = dmacRegs->rbor.ADDR + (spr0->madr & dmacRegs->rbsr.RMSK);
|
||||
if ((spr0ch.madr & ~dmacRegs.rbsr.RMSK) != dmacRegs.rbor.ADDR) Console.WriteLn("GIF MFIFO Write outside MFIFO area");
|
||||
spr0ch.madr = dmacRegs.rbor.ADDR + (spr0ch.madr & dmacRegs.rbsr.RMSK);
|
||||
//Console.WriteLn("mfifoGIFtransfer %x madr %x, tadr %x", gif->chcr._u32, gif->madr, gif->tadr);
|
||||
mfifoGIFtransfer(mfifotransferred);
|
||||
mfifotransferred = 0;
|
||||
|
@ -249,22 +249,22 @@ void SPRFROMinterrupt()
|
|||
}
|
||||
|
||||
|
||||
spr0->chcr.STR = false;
|
||||
spr0ch.chcr.STR = false;
|
||||
hwDmacIrq(DMAC_FROM_SPR);
|
||||
}
|
||||
|
||||
void dmaSPR0() // fromSPR
|
||||
{
|
||||
SPR_LOG("dmaSPR0 chcr = %lx, madr = %lx, qwc = %lx, sadr = %lx",
|
||||
spr0->chcr._u32, spr0->madr, spr0->qwc, spr0->sadr);
|
||||
spr0ch.chcr._u32, spr0ch.madr, spr0ch.qwc, spr0ch.sadr);
|
||||
|
||||
|
||||
spr0finished = false; //Init
|
||||
|
||||
if(spr0->chcr.MOD == CHAIN_MODE && spr0->qwc > 0)
|
||||
if(spr0ch.chcr.MOD == CHAIN_MODE && spr0ch.qwc > 0)
|
||||
{
|
||||
//DevCon.Warning(L"SPR0 QWC on Chain " + spr0->chcr.desc());
|
||||
if (spr0->chcr.tag().ID == TAG_END) // but not TAG_REFE?
|
||||
//DevCon.Warning(L"SPR0 QWC on Chain " + spr0ch.chcr.desc());
|
||||
if (spr0ch.chcr.tag().ID == TAG_END) // but not TAG_REFE?
|
||||
{
|
||||
spr0finished = true;
|
||||
}
|
||||
|
@ -275,58 +275,58 @@ void dmaSPR0() // fromSPR
|
|||
|
||||
__fi static void SPR1transfer(const void* data, int qwc)
|
||||
{
|
||||
memcpy_qwc(&psSu128(spr1->sadr), data, qwc);
|
||||
spr1->sadr += qwc * 16;
|
||||
memcpy_qwc(&psSu128(spr1ch.sadr), data, qwc);
|
||||
spr1ch.sadr += qwc * 16;
|
||||
}
|
||||
|
||||
int _SPR1chain()
|
||||
{
|
||||
tDMA_TAG *pMem;
|
||||
|
||||
if (spr1->qwc == 0) return 0;
|
||||
if (spr1ch.qwc == 0) return 0;
|
||||
|
||||
pMem = SPRdmaGetAddr(spr1->madr, false);
|
||||
pMem = SPRdmaGetAddr(spr1ch.madr, false);
|
||||
if (pMem == NULL) return -1;
|
||||
|
||||
SPR1transfer(pMem, spr1->qwc);
|
||||
spr1->madr += spr1->qwc * 16;
|
||||
SPR1transfer(pMem, spr1ch.qwc);
|
||||
spr1ch.madr += spr1ch.qwc * 16;
|
||||
|
||||
return (spr1->qwc);
|
||||
return (spr1ch.qwc);
|
||||
}
|
||||
|
||||
__fi void SPR1chain()
|
||||
{
|
||||
CPU_INT(DMAC_TO_SPR, _SPR1chain() / BIAS);
|
||||
spr1->qwc = 0;
|
||||
spr1ch.qwc = 0;
|
||||
}
|
||||
|
||||
void _SPR1interleave()
|
||||
{
|
||||
int qwc = spr1->qwc;
|
||||
int sqwc = dmacRegs->sqwc.SQWC;
|
||||
int tqwc = dmacRegs->sqwc.TQWC;
|
||||
int qwc = spr1ch.qwc;
|
||||
int sqwc = dmacRegs.sqwc.SQWC;
|
||||
int tqwc = dmacRegs.sqwc.TQWC;
|
||||
tDMA_TAG *pMem;
|
||||
|
||||
if (tqwc == 0) tqwc = qwc;
|
||||
SPR_LOG("SPR1 interleave size=%d, tqwc=%d, sqwc=%d, addr=%lx sadr=%lx",
|
||||
spr1->qwc, tqwc, sqwc, spr1->madr, spr1->sadr);
|
||||
spr1ch.qwc, tqwc, sqwc, spr1ch.madr, spr1ch.sadr);
|
||||
CPU_INT(DMAC_TO_SPR, qwc / BIAS);
|
||||
while (qwc > 0)
|
||||
{
|
||||
spr1->qwc = std::min(tqwc, qwc);
|
||||
qwc -= spr1->qwc;
|
||||
pMem = SPRdmaGetAddr(spr1->madr, false);
|
||||
memcpy_qwc(&psSu128(spr1->sadr), pMem, spr1->qwc);
|
||||
spr1->sadr += spr1->qwc * 16;
|
||||
spr1->madr += (sqwc + spr1->qwc) * 16;
|
||||
spr1ch.qwc = std::min(tqwc, qwc);
|
||||
qwc -= spr1ch.qwc;
|
||||
pMem = SPRdmaGetAddr(spr1ch.madr, false);
|
||||
memcpy_qwc(&psSu128(spr1ch.sadr), pMem, spr1ch.qwc);
|
||||
spr1ch.sadr += spr1ch.qwc * 16;
|
||||
spr1ch.madr += (sqwc + spr1ch.qwc) * 16;
|
||||
}
|
||||
|
||||
spr1->qwc = 0;
|
||||
spr1ch.qwc = 0;
|
||||
}
|
||||
|
||||
void _dmaSPR1() // toSPR work function
|
||||
{
|
||||
switch(spr1->chcr.MOD)
|
||||
switch(spr1ch.chcr.MOD)
|
||||
{
|
||||
case NORMAL_MODE:
|
||||
{
|
||||
|
@ -341,39 +341,39 @@ void _dmaSPR1() // toSPR work function
|
|||
tDMA_TAG *ptag;
|
||||
bool done = false;
|
||||
|
||||
if (spr1->qwc > 0)
|
||||
if (spr1ch.qwc > 0)
|
||||
{
|
||||
SPR_LOG("spr1 Normal or in Progress size=%d, addr=%lx taddr=%lx saddr=%lx", spr1->qwc, spr1->madr, spr1->tadr, spr1->sadr);
|
||||
SPR_LOG("spr1 Normal or in Progress size=%d, addr=%lx taddr=%lx saddr=%lx", spr1ch.qwc, spr1ch.madr, spr1ch.tadr, spr1ch.sadr);
|
||||
// Transfer Dn_QWC from Dn_MADR to SPR1
|
||||
SPR1chain();
|
||||
return;
|
||||
}
|
||||
// Chain Mode
|
||||
|
||||
ptag = SPRdmaGetAddr(spr1->tadr, false); //Set memory pointer to TADR
|
||||
ptag = SPRdmaGetAddr(spr1ch.tadr, false); //Set memory pointer to TADR
|
||||
|
||||
if (!spr1->transfer("SPR1 Tag", ptag))
|
||||
if (!spr1ch.transfer("SPR1 Tag", ptag))
|
||||
{
|
||||
done = true;
|
||||
spr1finished = done;
|
||||
}
|
||||
|
||||
spr1->madr = ptag[1]._u32; //MADR = ADDR field + SPR
|
||||
spr1ch.madr = ptag[1]._u32; //MADR = ADDR field + SPR
|
||||
|
||||
// Transfer dma tag if tte is set
|
||||
if (spr1->chcr.TTE)
|
||||
if (spr1ch.chcr.TTE)
|
||||
{
|
||||
SPR_LOG("SPR TTE: %x_%x\n", ptag[3]._u32, ptag[2]._u32);
|
||||
SPR1transfer(ptag, 1); //Transfer Tag
|
||||
}
|
||||
|
||||
SPR_LOG("spr1 dmaChain %8.8x_%8.8x size=%d, id=%d, addr=%lx taddr=%lx saddr=%lx",
|
||||
ptag[1]._u32, ptag[0]._u32, spr1->qwc, ptag->ID, spr1->madr, spr1->tadr, spr1->sadr);
|
||||
ptag[1]._u32, ptag[0]._u32, spr1ch.qwc, ptag->ID, spr1ch.madr, spr1ch.tadr, spr1ch.sadr);
|
||||
|
||||
done = (hwDmacSrcChain(spr1, ptag->ID));
|
||||
done = (hwDmacSrcChain(spr1ch, ptag->ID));
|
||||
SPR1chain(); //Transfers the data set by the switch
|
||||
|
||||
if (spr1->chcr.TIE && ptag->IRQ) //Check TIE bit of CHCR and IRQ bit of tag
|
||||
if (spr1ch.chcr.TIE && ptag->IRQ) //Check TIE bit of CHCR and IRQ bit of tag
|
||||
{
|
||||
SPR_LOG("dmaIrq Set");
|
||||
|
||||
|
@ -398,15 +398,15 @@ void dmaSPR1() // toSPR
|
|||
{
|
||||
SPR_LOG("dmaSPR1 chcr = 0x%x, madr = 0x%x, qwc = 0x%x\n"
|
||||
" tadr = 0x%x, sadr = 0x%x",
|
||||
spr1->chcr._u32, spr1->madr, spr1->qwc,
|
||||
spr1->tadr, spr1->sadr);
|
||||
spr1ch.chcr._u32, spr1ch.madr, spr1ch.qwc,
|
||||
spr1ch.tadr, spr1ch.sadr);
|
||||
|
||||
spr1finished = false; //Init
|
||||
|
||||
if(spr1->chcr.MOD == CHAIN_MODE && spr1->qwc > 0)
|
||||
if(spr1ch.chcr.MOD == CHAIN_MODE && spr1ch.qwc > 0)
|
||||
{
|
||||
//DevCon.Warning(L"SPR1 QWC on Chain " + spr1->chcr.desc());
|
||||
if ((spr1->chcr.tag().ID == TAG_END) || (spr1->chcr.tag().ID == TAG_REFE))
|
||||
//DevCon.Warning(L"SPR1 QWC on Chain " + spr1ch.chcr.desc());
|
||||
if ((spr1ch.chcr.tag().ID == TAG_END) || (spr1ch.chcr.tag().ID == TAG_REFE))
|
||||
{
|
||||
spr1finished = true;
|
||||
}
|
||||
|
@ -418,14 +418,14 @@ void dmaSPR1() // toSPR
|
|||
void SPRTOinterrupt()
|
||||
{
|
||||
SPR_LOG("SPR1 Interrupt");
|
||||
if (!spr1finished || spr1->qwc > 0)
|
||||
if (!spr1finished || spr1ch.qwc > 0)
|
||||
{
|
||||
_dmaSPR1();
|
||||
return;
|
||||
}
|
||||
|
||||
SPR_LOG("SPR1 End");
|
||||
spr1->chcr.STR = false;
|
||||
spr1ch.chcr.STR = false;
|
||||
hwDmacIrq(DMAC_TO_SPR);
|
||||
}
|
||||
|
||||
|
|
|
@ -154,7 +154,7 @@ void SaveStateBase::FreezeMainMemory()
|
|||
// ---------------------------
|
||||
FreezeMem(eeMem->Main, Ps2MemSize::Base); // 32 MB main memory
|
||||
FreezeMem(eeMem->Scratch, Ps2MemSize::Scratch); // scratch pad
|
||||
FreezeMem(eeMem->HW, Ps2MemSize::Hardware); // hardware memory
|
||||
FreezeMem(eeHw, Ps2MemSize::Hardware); // hardware memory
|
||||
|
||||
FreezeMem(psxM, Ps2MemSize::IopRam); // 2 MB main memory
|
||||
FreezeMem(psxH, Ps2MemSize::IopHardware); // hardware memory
|
||||
|
@ -194,6 +194,7 @@ void SaveStateBase::FreezeRegisters()
|
|||
vif1Freeze();
|
||||
sifFreeze();
|
||||
ipuFreeze();
|
||||
ipuDmaFreeze();
|
||||
gifFreeze();
|
||||
sprFreeze();
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
// the lower 16 bit value. IF the change is breaking of all compatibility with old
|
||||
// states, increment the upper 16 bit value, and clear the lower 16 bits to 0.
|
||||
|
||||
static const u32 g_SaveVersion = 0x8b480000;
|
||||
static const u32 g_SaveVersion = 0x8b490000;
|
||||
|
||||
// this function is meant to be used in the place of GSfreeze, and provides a safe layer
|
||||
// between the GS saving function and the MTGS's needs. :)
|
||||
|
@ -214,6 +214,7 @@ protected:
|
|||
#endif
|
||||
void sifFreeze();
|
||||
void ipuFreeze();
|
||||
void ipuDmaFreeze();
|
||||
void gifFreeze();
|
||||
void sprFreeze();
|
||||
|
||||
|
|
|
@ -28,9 +28,9 @@ void sifInit()
|
|||
|
||||
__fi void dmaSIF2()
|
||||
{
|
||||
SIF_LOG(wxString(L"dmaSIF2" + sif2dma->cmq_to_str()).To8BitData());
|
||||
SIF_LOG(wxString(L"dmaSIF2" + sif2dma.cmq_to_str()).To8BitData());
|
||||
|
||||
sif2dma->chcr.STR = false;
|
||||
sif2dma.chcr.STR = false;
|
||||
hwDmacIrq(DMAC_SIF2);
|
||||
Console.WriteLn("*PCSX2*: dmaSIF2");
|
||||
}
|
||||
|
|
|
@ -16,7 +16,12 @@
|
|||
#ifndef __SIF_H__
|
||||
#define __SIF_H__
|
||||
|
||||
#define FIFO_SIF_W 128
|
||||
static const int FIFO_SIF_W = 128;
|
||||
|
||||
static DMACh& sif0dma = (DMACh&)eeHw[0xc000];
|
||||
static DMACh& sif1dma = (DMACh&)eeHw[0xc400];
|
||||
static DMACh& sif2dma = (DMACh&)eeHw[0xc800];
|
||||
|
||||
|
||||
struct sifData
|
||||
{
|
||||
|
|
|
@ -35,14 +35,14 @@ static __fi void Sif0Init()
|
|||
// Write from Fifo to EE.
|
||||
static __fi bool WriteFifoToEE()
|
||||
{
|
||||
const int readSize = min((s32)sif0dma->qwc, sif0.fifo.size >> 2);
|
||||
const int readSize = min((s32)sif0dma.qwc, sif0.fifo.size >> 2);
|
||||
|
||||
tDMA_TAG *ptag;
|
||||
|
||||
//SIF_LOG(" EE SIF doing transfer %04Xqw to %08X", readSize, sif0dma->madr);
|
||||
SIF_LOG("Write Fifo to EE: ----------- %lX of %lX", readSize << 2, sif0dma->qwc << 2);
|
||||
//SIF_LOG(" EE SIF doing transfer %04Xqw to %08X", readSize, sif0dma.madr);
|
||||
SIF_LOG("Write Fifo to EE: ----------- %lX of %lX", readSize << 2, sif0dma.qwc << 2);
|
||||
|
||||
ptag = sif0dma->getAddr(sif0dma->madr, DMAC_SIF0, true);
|
||||
ptag = sif0dma.getAddr(sif0dma.madr, DMAC_SIF0, true);
|
||||
if (ptag == NULL)
|
||||
{
|
||||
DevCon.Warning("Write Fifo to EE: ptag == NULL");
|
||||
|
@ -52,11 +52,11 @@ static __fi bool WriteFifoToEE()
|
|||
sif0.fifo.read((u32*)ptag, readSize << 2);
|
||||
|
||||
// Clearing handled by vtlb memory protection and manual blocks.
|
||||
//Cpu->Clear(sif0dma->madr, readSize*4);
|
||||
//Cpu->Clear(sif0dma.madr, readSize*4);
|
||||
|
||||
sif0dma->madr += readSize << 4;
|
||||
sif0dma.madr += readSize << 4;
|
||||
sif0.ee.cycles += readSize; // fixme : BIAS is factored in above
|
||||
sif0dma->qwc -= readSize;
|
||||
sif0dma.qwc -= readSize;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -87,14 +87,14 @@ static __fi bool ProcessEETag()
|
|||
sif0.fifo.read((u32*)&tag[0], 4); // Tag
|
||||
SIF_LOG("SIF0 EE read tag: %x %x %x %x", tag[0], tag[1], tag[2], tag[3]);
|
||||
|
||||
sif0dma->unsafeTransfer(((tDMA_TAG*)(tag)));
|
||||
sif0dma->madr = tag[1];
|
||||
sif0dma.unsafeTransfer(((tDMA_TAG*)(tag)));
|
||||
sif0dma.madr = tag[1];
|
||||
tDMA_TAG ptag(tag[0]);
|
||||
|
||||
SIF_LOG("SIF0 EE dest chain tag madr:%08X qwc:%04X id:%X irq:%d(%08X_%08X)",
|
||||
sif0dma->madr, sif0dma->qwc, ptag.ID, ptag.IRQ, tag[1], tag[0]);
|
||||
sif0dma.madr, sif0dma.qwc, ptag.ID, ptag.IRQ, tag[1], tag[0]);
|
||||
|
||||
if (sif0dma->chcr.TIE && ptag.IRQ)
|
||||
if (sif0dma.chcr.TIE && ptag.IRQ)
|
||||
{
|
||||
//Console.WriteLn("SIF0 TIE");
|
||||
sif0.ee.end = true;
|
||||
|
@ -104,13 +104,13 @@ static __fi bool ProcessEETag()
|
|||
{
|
||||
case TAG_REFE:
|
||||
sif0.ee.end = true;
|
||||
if (dmacRegs->ctrl.STS != NO_STS)
|
||||
dmacRegs->stadr.ADDR = sif0dma->madr + (sif0dma->qwc * 16);
|
||||
if (dmacRegs.ctrl.STS != NO_STS)
|
||||
dmacRegs.stadr.ADDR = sif0dma.madr + (sif0dma.qwc * 16);
|
||||
break;
|
||||
|
||||
case TAG_REFS:
|
||||
if (dmacRegs->ctrl.STS != NO_STS)
|
||||
dmacRegs->stadr.ADDR = sif0dma->madr + (sif0dma->qwc * 16);
|
||||
if (dmacRegs.ctrl.STS != NO_STS)
|
||||
dmacRegs.stadr.ADDR = sif0dma.madr + (sif0dma.qwc * 16);
|
||||
break;
|
||||
|
||||
case TAG_END:
|
||||
|
@ -177,7 +177,7 @@ static __fi void EndIOP()
|
|||
// Handle the EE transfer.
|
||||
static __fi void HandleEETransfer()
|
||||
{
|
||||
if(sif0dma->chcr.STR == false)
|
||||
if(sif0dma.chcr.STR == false)
|
||||
{
|
||||
DevCon.Warning("Replacement for irq prevention hack EE SIF0");
|
||||
sif0.ee.end = false;
|
||||
|
@ -185,22 +185,22 @@ static __fi void HandleEETransfer()
|
|||
return;
|
||||
}
|
||||
|
||||
if (dmacRegs->ctrl.STS == STS_SIF0)
|
||||
if (dmacRegs.ctrl.STS == STS_SIF0)
|
||||
{
|
||||
DevCon.Warning("SIF0 stall control");
|
||||
}
|
||||
|
||||
/*if (sif0dma->qwc == 0)
|
||||
if (sif0dma->chcr.MOD == NORMAL_MODE)
|
||||
/*if (sif0dma.qwc == 0)
|
||||
if (sif0dma.chcr.MOD == NORMAL_MODE)
|
||||
if (!sif0.ee.end){
|
||||
DevCon.Warning("sif0 irq prevented");
|
||||
done = true;
|
||||
return;
|
||||
}*/
|
||||
|
||||
if (sif0dma->qwc <= 0)
|
||||
if (sif0dma.qwc <= 0)
|
||||
{
|
||||
if ((sif0dma->chcr.MOD == NORMAL_MODE) || sif0.ee.end)
|
||||
if ((sif0dma.chcr.MOD == NORMAL_MODE) || sif0.ee.end)
|
||||
{
|
||||
// Stop transferring ee, and signal an interrupt.
|
||||
done = true;
|
||||
|
@ -214,7 +214,7 @@ static __fi void HandleEETransfer()
|
|||
}
|
||||
}
|
||||
|
||||
if (sif0dma->qwc > 0) // If we're writing something, continue to do so.
|
||||
if (sif0dma.qwc > 0) // If we're writing something, continue to do so.
|
||||
{
|
||||
// Write from Fifo to EE.
|
||||
if (sif0.fifo.size > 0)
|
||||
|
@ -306,7 +306,7 @@ __fi void SIF0Dma()
|
|||
}
|
||||
if (sif0.ee.busy)
|
||||
{
|
||||
if(sif0.fifo.size >= 4 || (sif0.ee.end == true && sif0dma->qwc == 0))
|
||||
if(sif0.fifo.size >= 4 || (sif0.ee.end == true && sif0dma.qwc == 0))
|
||||
{
|
||||
BusyCheck++;
|
||||
HandleEETransfer();
|
||||
|
@ -326,19 +326,19 @@ __fi void sif0Interrupt()
|
|||
__fi void EEsif0Interrupt()
|
||||
{
|
||||
hwDmacIrq(DMAC_SIF0);
|
||||
sif0dma->chcr.STR = false;
|
||||
sif0dma.chcr.STR = false;
|
||||
}
|
||||
|
||||
__fi void dmaSIF0()
|
||||
{
|
||||
SIF_LOG(wxString(L"dmaSIF0" + sif0dma->cmqt_to_str()).To8BitData());
|
||||
SIF_LOG(wxString(L"dmaSIF0" + sif0dma.cmqt_to_str()).To8BitData());
|
||||
|
||||
if (sif0.fifo.readPos != sif0.fifo.writePos)
|
||||
{
|
||||
SIF_LOG("warning, sif0.fifoReadPos != sif0.fifoWritePos");
|
||||
}
|
||||
|
||||
//if(sif0dma->chcr.MOD == CHAIN_MODE && sif0dma->qwc > 0) DevCon.Warning(L"SIF0 QWC on Chain CHCR " + sif0dma->chcr.desc());
|
||||
//if(sif0dma.chcr.MOD == CHAIN_MODE && sif0dma.qwc > 0) DevCon.Warning(L"SIF0 QWC on Chain CHCR " + sif0dma.chcr.desc());
|
||||
psHu32(SBUS_F240) |= 0x2000;
|
||||
sif0.ee.busy = true;
|
||||
|
||||
|
|
|
@ -38,11 +38,11 @@ static __fi bool WriteEEtoFifo()
|
|||
// There's some data ready to transfer into the fifo..
|
||||
|
||||
SIF_LOG("Sif 1: Write EE to Fifo");
|
||||
const int writeSize = min((s32)sif1dma->qwc, sif1.fifo.free() >> 2);
|
||||
const int writeSize = min((s32)sif1dma.qwc, sif1.fifo.free() >> 2);
|
||||
|
||||
tDMA_TAG *ptag;
|
||||
|
||||
ptag = sif1dma->getAddr(sif1dma->madr, DMAC_SIF1, false);
|
||||
ptag = sif1dma.getAddr(sif1dma.madr, DMAC_SIF1, false);
|
||||
if (ptag == NULL)
|
||||
{
|
||||
DevCon.Warning("Write EE to Fifo: ptag == NULL");
|
||||
|
@ -51,9 +51,9 @@ static __fi bool WriteEEtoFifo()
|
|||
|
||||
sif1.fifo.write((u32*)ptag, writeSize << 2);
|
||||
|
||||
sif1dma->madr += writeSize << 4;
|
||||
sif1dma.madr += writeSize << 4;
|
||||
sif1.ee.cycles += writeSize; // fixme : BIAS is factored in above
|
||||
sif1dma->qwc -= writeSize;
|
||||
sif1dma.qwc -= writeSize;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -84,21 +84,21 @@ static __fi bool ProcessEETag()
|
|||
tDMA_TAG *ptag;
|
||||
SIF_LOG("Sif1: ProcessEETag");
|
||||
|
||||
// Process DMA tag at sif1dma->tadr
|
||||
ptag = sif1dma->DMAtransfer(sif1dma->tadr, DMAC_SIF1);
|
||||
// Process DMA tag at sif1dma.tadr
|
||||
ptag = sif1dma.DMAtransfer(sif1dma.tadr, DMAC_SIF1);
|
||||
if (ptag == NULL)
|
||||
{
|
||||
Console.WriteLn("Sif1 ProcessEETag: ptag = NULL");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (sif1dma->chcr.TTE)
|
||||
if (sif1dma.chcr.TTE)
|
||||
{
|
||||
Console.WriteLn("SIF1 TTE");
|
||||
sif1.fifo.write((u32*)ptag + 2, 2);
|
||||
}
|
||||
|
||||
if (sif1dma->chcr.TIE && ptag->IRQ)
|
||||
if (sif1dma.chcr.TIE && ptag->IRQ)
|
||||
{
|
||||
Console.WriteLn("SIF1 TIE");
|
||||
sif1.ee.end = true;
|
||||
|
@ -109,30 +109,30 @@ static __fi bool ProcessEETag()
|
|||
{
|
||||
case TAG_REFE:
|
||||
sif1.ee.end = true;
|
||||
sif1dma->madr = ptag[1]._u32;
|
||||
sif1dma->tadr += 16;
|
||||
sif1dma.madr = ptag[1]._u32;
|
||||
sif1dma.tadr += 16;
|
||||
break;
|
||||
|
||||
case TAG_CNT:
|
||||
sif1dma->madr = sif1dma->tadr + 16;
|
||||
sif1dma->tadr = sif1dma->madr + (sif1dma->qwc << 4);
|
||||
sif1dma.madr = sif1dma.tadr + 16;
|
||||
sif1dma.tadr = sif1dma.madr + (sif1dma.qwc << 4);
|
||||
break;
|
||||
|
||||
case TAG_NEXT:
|
||||
sif1dma->madr = sif1dma->tadr + 16;
|
||||
sif1dma->tadr = ptag[1]._u32;
|
||||
sif1dma.madr = sif1dma.tadr + 16;
|
||||
sif1dma.tadr = ptag[1]._u32;
|
||||
break;
|
||||
|
||||
case TAG_REF:
|
||||
case TAG_REFS:
|
||||
sif1dma->madr = ptag[1]._u32;
|
||||
sif1dma->tadr += 16;
|
||||
sif1dma.madr = ptag[1]._u32;
|
||||
sif1dma.tadr += 16;
|
||||
break;
|
||||
|
||||
case TAG_END:
|
||||
sif1.ee.end = true;
|
||||
sif1dma->madr = sif1dma->tadr + 16;
|
||||
sif1dma->tadr = sif1dma->madr + (sif1dma->qwc << 4);
|
||||
sif1dma.madr = sif1dma.tadr + 16;
|
||||
sif1dma.tadr = sif1dma.madr + (sif1dma.qwc << 4);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -203,31 +203,31 @@ static __fi void EndIOP()
|
|||
// Handle the EE transfer.
|
||||
static __fi void HandleEETransfer()
|
||||
{
|
||||
if(sif1dma->chcr.STR == false)
|
||||
if(sif1dma.chcr.STR == false)
|
||||
{
|
||||
DevCon.Warning("Replacement for irq prevention hack EE SIF1");
|
||||
sif1.ee.end = false;
|
||||
sif1.ee.busy = false;
|
||||
return;
|
||||
}
|
||||
if (dmacRegs->ctrl.STD == STD_SIF1)
|
||||
if (dmacRegs.ctrl.STD == STD_SIF1)
|
||||
{
|
||||
DevCon.Warning("SIF1 stall control"); // STD == fromSIF1
|
||||
}
|
||||
|
||||
/*if (sif1dma->qwc == 0)
|
||||
if (sif1dma->chcr.MOD == NORMAL_MODE)
|
||||
/*if (sif1dma.qwc == 0)
|
||||
if (sif1dma.chcr.MOD == NORMAL_MODE)
|
||||
if (!sif1.ee.end){
|
||||
DevCon.Warning("sif1 irq prevented CHCR %x QWC %x", sif1dma->chcr, sif1dma->qwc);
|
||||
DevCon.Warning("sif1 irq prevented CHCR %x QWC %x", sif1dma.chcr, sif1dma.qwc);
|
||||
done = true;
|
||||
return;
|
||||
}*/
|
||||
|
||||
// If there's no more to transfer.
|
||||
if (sif1dma->qwc <= 0)
|
||||
if (sif1dma.qwc <= 0)
|
||||
{
|
||||
// If NORMAL mode or end of CHAIN then stop DMA.
|
||||
if ((sif1dma->chcr.MOD == NORMAL_MODE) || sif1.ee.end)
|
||||
if ((sif1dma.chcr.MOD == NORMAL_MODE) || sif1.ee.end)
|
||||
{
|
||||
done = true;
|
||||
EndEE();
|
||||
|
@ -292,7 +292,7 @@ __fi void SIF1Dma()
|
|||
|
||||
if (sif1.ee.busy)
|
||||
{
|
||||
if(sif1.fifo.free() > 0 || (sif1.ee.end == true && sif1dma->qwc == 0))
|
||||
if(sif1.fifo.free() > 0 || (sif1.ee.end == true && sif1dma.qwc == 0))
|
||||
{
|
||||
BusyCheck++;
|
||||
HandleEETransfer();
|
||||
|
@ -322,21 +322,21 @@ __fi void sif1Interrupt()
|
|||
__fi void EEsif1Interrupt()
|
||||
{
|
||||
hwDmacIrq(DMAC_SIF1);
|
||||
sif1dma->chcr.STR = false;
|
||||
sif1dma.chcr.STR = false;
|
||||
}
|
||||
|
||||
// Do almost exactly the same thing as psxDma10 in IopDma.cpp.
|
||||
// Main difference is this checks for iop, where psxDma10 checks for ee.
|
||||
__fi void dmaSIF1()
|
||||
{
|
||||
SIF_LOG(wxString(L"dmaSIF1" + sif1dma->cmqt_to_str()).To8BitData());
|
||||
SIF_LOG(wxString(L"dmaSIF1" + sif1dma.cmqt_to_str()).To8BitData());
|
||||
|
||||
if (sif1.fifo.readPos != sif1.fifo.writePos)
|
||||
{
|
||||
SIF_LOG("warning, sif1.fifoReadPos != sif1.fifoWritePos");
|
||||
}
|
||||
|
||||
//if(sif1dma->chcr.MOD == CHAIN_MODE && sif1dma->qwc > 0) DevCon.Warning(L"SIF1 QWC on Chain CHCR " + sif1dma->chcr.desc());
|
||||
//if(sif1dma.chcr.MOD == CHAIN_MODE && sif1dma.qwc > 0) DevCon.Warning(L"SIF1 QWC on Chain CHCR " + sif1dma.chcr.desc());
|
||||
|
||||
psHu32(SBUS_F240) |= 0x4000;
|
||||
sif1.ee.busy = true;
|
||||
|
|
87
pcsx2/VU.h
87
pcsx2/VU.h
|
@ -16,10 +16,6 @@
|
|||
#pragma once
|
||||
#include "Vif.h"
|
||||
|
||||
#ifdef _MSC_VER // Most of the structs here should be packed
|
||||
# pragma pack(1)
|
||||
#endif
|
||||
|
||||
enum VURegFlags
|
||||
{
|
||||
REG_STATUS_FLAG = 16,
|
||||
|
@ -68,7 +64,7 @@ union VECTOR {
|
|||
s16 SS[8];
|
||||
u8 UC[16];
|
||||
s8 SC[16];
|
||||
} __packed;
|
||||
};
|
||||
|
||||
struct REG_VI {
|
||||
union {
|
||||
|
@ -82,7 +78,7 @@ struct REG_VI {
|
|||
};
|
||||
u32 padding[3]; // needs padding to make them 128bit; VU0 maps VU1's VI regs as 128bits to addr 0x4xx0 in
|
||||
// VU0 mem, with only lower 16 bits valid, and the upper 112bits are hardwired to 0 (cottonvibes)
|
||||
} __packed;
|
||||
};
|
||||
|
||||
//#define VUFLAG_BREAKONMFLAG 0x00000001
|
||||
#define VUFLAG_MFLAGSET 0x00000002
|
||||
|
@ -120,45 +116,61 @@ struct ialuPipe {
|
|||
u32 Cycle;
|
||||
};
|
||||
|
||||
struct VURegs {
|
||||
struct __aligned16 VURegs {
|
||||
VECTOR VF[32]; // VF and VI need to be first in this struct for proper mapping
|
||||
REG_VI VI[32]; // needs to be 128bit x 32 (cottonvibes)
|
||||
|
||||
VECTOR ACC;
|
||||
REG_VI q;
|
||||
REG_VI p;
|
||||
|
||||
uint idx; // VU index (0 or 1)
|
||||
|
||||
// flags/cycle are needed by VIF dma code, so they have to be here (for now)
|
||||
// We may replace these by accessors in the future, if merited.
|
||||
u32 cycle;
|
||||
u32 flags;
|
||||
|
||||
// Current opcode being interpreted or recompiled (this var is used by Interps and superVU
|
||||
// but not microVU. Would like to have it local to their respective classes... someday)
|
||||
u32 code;
|
||||
|
||||
// branch/branchpc are used by interpreter only, but making them local to the interpreter
|
||||
// classes requires considerable code refactoring. Maybe later. >_<
|
||||
u32 branch;
|
||||
u32 branchpc;
|
||||
|
||||
// MAC/Status flags -- these are used by interpreters and superVU, but are kind of hacky
|
||||
// and shouldn't be relied on for any useful/valid info. Would like to move them out of
|
||||
// this struct eventually.
|
||||
u32 macflag;
|
||||
u32 statusflag;
|
||||
u32 clipflag;
|
||||
|
||||
u32 cycle;
|
||||
u32 flags;
|
||||
|
||||
void (*vuExec)(VURegs*);
|
||||
VIFregisters *vifRegs;
|
||||
|
||||
u8 *Mem;
|
||||
u8 *Micro;
|
||||
|
||||
u32 code;
|
||||
u32 maxmem;
|
||||
u32 maxmicro;
|
||||
|
||||
u16 branch;
|
||||
u16 ebit;
|
||||
u32 branchpc;
|
||||
u32 ebit;
|
||||
|
||||
fmacPipe fmac[8];
|
||||
fdivPipe fdiv;
|
||||
efuPipe efu;
|
||||
ialuPipe ialu[8];
|
||||
|
||||
VURegs() :
|
||||
Mem( NULL )
|
||||
, Micro( NULL )
|
||||
VURegs()
|
||||
{
|
||||
Mem = NULL;
|
||||
Micro = NULL;
|
||||
}
|
||||
} __packed;
|
||||
|
||||
bool IsVU1() const;
|
||||
bool IsVU0() const;
|
||||
|
||||
VIFregisters& GetVifRegs() const
|
||||
{
|
||||
return IsVU1() ? vif1Regs : vif0Regs;
|
||||
}
|
||||
};
|
||||
|
||||
enum VUPipeState
|
||||
{
|
||||
|
@ -171,27 +183,16 @@ enum VUPipeState
|
|||
VUPIPE_XGKICK
|
||||
};
|
||||
|
||||
struct _VURegsNum {
|
||||
u8 pipe; // if 0xff, COP2
|
||||
u8 VFwrite;
|
||||
u8 VFwxyzw;
|
||||
u8 VFr0xyzw;
|
||||
u8 VFr1xyzw;
|
||||
u8 VFread0;
|
||||
u8 VFread1;
|
||||
u32 VIwrite;
|
||||
u32 VIread;
|
||||
int cycles;
|
||||
};
|
||||
extern __aligned16 VURegs vuRegs[2];
|
||||
|
||||
#ifdef _MSC_VER // Restore to default pack alignment
|
||||
# pragma pack()
|
||||
#endif
|
||||
// Obsolete(?) -- I think I'd rather use vu0Regs/vu1Regs or actually have these explicit to any
|
||||
// CPP file that needs them only. --air
|
||||
static VURegs& VU0 = vuRegs[0];
|
||||
static VURegs& VU1 = vuRegs[1];
|
||||
|
||||
extern VURegs* g_pVU1;
|
||||
extern __aligned16 VURegs VU0;
|
||||
|
||||
#define VU1 (*g_pVU1)
|
||||
// Do not use __fi here because it fires 'multiple definition' error in GCC
|
||||
inline bool VURegs::IsVU1() const { return this == &vuRegs[1]; }
|
||||
inline bool VURegs::IsVU0() const { return this == &vuRegs[0]; }
|
||||
|
||||
extern u32* GET_VU_MEM(VURegs* VU, u32 addr);
|
||||
|
||||
|
|
172
pcsx2/VU0.cpp
172
pcsx2/VU0.cpp
|
@ -44,8 +44,6 @@
|
|||
|
||||
using namespace R5900;
|
||||
|
||||
__aligned16 VURegs VU0;
|
||||
|
||||
void COP2_BC2() { Int_COP2BC2PrintTable[_Rt_]();}
|
||||
void COP2_SPECIAL() { Int_COP2SPECIAL1PrintTable[_Funct_]();}
|
||||
|
||||
|
@ -88,15 +86,10 @@ namespace OpcodeImpl
|
|||
void LQC2() {
|
||||
u32 addr = cpuRegs.GPR.r[_Rs_].UL[0] + (s16)cpuRegs.code;
|
||||
if (_Ft_) {
|
||||
#ifdef __LINUX__
|
||||
// Ifdeffing mainly because I haven't gotten around to checking it in Windows yet.
|
||||
memRead128(addr, &VU0.VF[_Ft_].UQ);
|
||||
#else
|
||||
memRead128(addr, VU0.VF[_Ft_].UD);
|
||||
#endif
|
||||
memRead128(addr, VU0.VF[_Ft_].UQ);
|
||||
} else {
|
||||
u64 val[2];
|
||||
memRead128(addr, val);
|
||||
u128 val;
|
||||
memRead128(addr, val);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -105,9 +98,7 @@ namespace OpcodeImpl
|
|||
// HUH why ? doesn't make any sense ...
|
||||
void SQC2() {
|
||||
u32 addr = _Imm_ + cpuRegs.GPR.r[_Rs_].UL[0];
|
||||
//memWrite64(addr, VU0.VF[_Ft_].UD[0]);
|
||||
//memWrite64(addr+8,VU0.VF[_Ft_].UD[1]);
|
||||
memWrite128(addr, VU0.VF[_Ft_].UD);
|
||||
memWrite128(addr, VU0.VF[_Ft_].UQ);
|
||||
}
|
||||
}}}
|
||||
|
||||
|
@ -180,158 +171,3 @@ void CTC2() {
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
__fi void SYNCMSFLAGS()
|
||||
{
|
||||
VU0.VI[REG_STATUS_FLAG].UL = VU0.statusflag;
|
||||
VU0.VI[REG_MAC_FLAG].UL = VU0.macflag;
|
||||
}
|
||||
|
||||
__fi void SYNCFDIV()
|
||||
{
|
||||
VU0.VI[REG_Q].UL = VU0.q.UL;
|
||||
VU0.VI[REG_STATUS_FLAG].UL = VU0.statusflag;
|
||||
}
|
||||
|
||||
void VABS() { VU0.code = cpuRegs.code; _vuABS(&VU0); }
|
||||
void VADD() { VU0.code = cpuRegs.code; _vuADD(&VU0); SYNCMSFLAGS(); }
|
||||
void VADDi() { VU0.code = cpuRegs.code; _vuADDi(&VU0); SYNCMSFLAGS(); }
|
||||
void VADDq() { VU0.code = cpuRegs.code; _vuADDq(&VU0); SYNCMSFLAGS(); }
|
||||
void VADDx() { VU0.code = cpuRegs.code; _vuADDx(&VU0); SYNCMSFLAGS(); }
|
||||
void VADDy() { VU0.code = cpuRegs.code; _vuADDy(&VU0); SYNCMSFLAGS(); }
|
||||
void VADDz() { VU0.code = cpuRegs.code; _vuADDz(&VU0); SYNCMSFLAGS(); }
|
||||
void VADDw() { VU0.code = cpuRegs.code; _vuADDw(&VU0); SYNCMSFLAGS(); }
|
||||
void VADDA() { VU0.code = cpuRegs.code; _vuADDA(&VU0); SYNCMSFLAGS(); }
|
||||
void VADDAi() { VU0.code = cpuRegs.code; _vuADDAi(&VU0); SYNCMSFLAGS(); }
|
||||
void VADDAq() { VU0.code = cpuRegs.code; _vuADDAq(&VU0); SYNCMSFLAGS(); }
|
||||
void VADDAx() { VU0.code = cpuRegs.code; _vuADDAx(&VU0); SYNCMSFLAGS(); }
|
||||
void VADDAy() { VU0.code = cpuRegs.code; _vuADDAy(&VU0); SYNCMSFLAGS(); }
|
||||
void VADDAz() { VU0.code = cpuRegs.code; _vuADDAz(&VU0); SYNCMSFLAGS(); }
|
||||
void VADDAw() { VU0.code = cpuRegs.code; _vuADDAw(&VU0); SYNCMSFLAGS(); }
|
||||
void VSUB() { VU0.code = cpuRegs.code; _vuSUB(&VU0); SYNCMSFLAGS(); }
|
||||
void VSUBi() { VU0.code = cpuRegs.code; _vuSUBi(&VU0); SYNCMSFLAGS(); }
|
||||
void VSUBq() { VU0.code = cpuRegs.code; _vuSUBq(&VU0); SYNCMSFLAGS(); }
|
||||
void VSUBx() { VU0.code = cpuRegs.code; _vuSUBx(&VU0); SYNCMSFLAGS(); }
|
||||
void VSUBy() { VU0.code = cpuRegs.code; _vuSUBy(&VU0); SYNCMSFLAGS(); }
|
||||
void VSUBz() { VU0.code = cpuRegs.code; _vuSUBz(&VU0); SYNCMSFLAGS(); }
|
||||
void VSUBw() { VU0.code = cpuRegs.code; _vuSUBw(&VU0); SYNCMSFLAGS(); }
|
||||
void VSUBA() { VU0.code = cpuRegs.code; _vuSUBA(&VU0); SYNCMSFLAGS(); }
|
||||
void VSUBAi() { VU0.code = cpuRegs.code; _vuSUBAi(&VU0); SYNCMSFLAGS(); }
|
||||
void VSUBAq() { VU0.code = cpuRegs.code; _vuSUBAq(&VU0); SYNCMSFLAGS(); }
|
||||
void VSUBAx() { VU0.code = cpuRegs.code; _vuSUBAx(&VU0); SYNCMSFLAGS(); }
|
||||
void VSUBAy() { VU0.code = cpuRegs.code; _vuSUBAy(&VU0); SYNCMSFLAGS(); }
|
||||
void VSUBAz() { VU0.code = cpuRegs.code; _vuSUBAz(&VU0); SYNCMSFLAGS(); }
|
||||
void VSUBAw() { VU0.code = cpuRegs.code; _vuSUBAw(&VU0); SYNCMSFLAGS(); }
|
||||
void VMUL() { VU0.code = cpuRegs.code; _vuMUL(&VU0); SYNCMSFLAGS(); }
|
||||
void VMULi() { VU0.code = cpuRegs.code; _vuMULi(&VU0); SYNCMSFLAGS(); }
|
||||
void VMULq() { VU0.code = cpuRegs.code; _vuMULq(&VU0); SYNCMSFLAGS(); }
|
||||
void VMULx() { VU0.code = cpuRegs.code; _vuMULx(&VU0); SYNCMSFLAGS(); }
|
||||
void VMULy() { VU0.code = cpuRegs.code; _vuMULy(&VU0); SYNCMSFLAGS(); }
|
||||
void VMULz() { VU0.code = cpuRegs.code; _vuMULz(&VU0); SYNCMSFLAGS(); }
|
||||
void VMULw() { VU0.code = cpuRegs.code; _vuMULw(&VU0); SYNCMSFLAGS(); }
|
||||
void VMULA() { VU0.code = cpuRegs.code; _vuMULA(&VU0); SYNCMSFLAGS(); }
|
||||
void VMULAi() { VU0.code = cpuRegs.code; _vuMULAi(&VU0); SYNCMSFLAGS(); }
|
||||
void VMULAq() { VU0.code = cpuRegs.code; _vuMULAq(&VU0); SYNCMSFLAGS(); }
|
||||
void VMULAx() { VU0.code = cpuRegs.code; _vuMULAx(&VU0); SYNCMSFLAGS(); }
|
||||
void VMULAy() { VU0.code = cpuRegs.code; _vuMULAy(&VU0); SYNCMSFLAGS(); }
|
||||
void VMULAz() { VU0.code = cpuRegs.code; _vuMULAz(&VU0); SYNCMSFLAGS(); }
|
||||
void VMULAw() { VU0.code = cpuRegs.code; _vuMULAw(&VU0); SYNCMSFLAGS(); }
|
||||
void VMADD() { VU0.code = cpuRegs.code; _vuMADD(&VU0); SYNCMSFLAGS(); }
|
||||
void VMADDi() { VU0.code = cpuRegs.code; _vuMADDi(&VU0); SYNCMSFLAGS(); }
|
||||
void VMADDq() { VU0.code = cpuRegs.code; _vuMADDq(&VU0); SYNCMSFLAGS(); }
|
||||
void VMADDx() { VU0.code = cpuRegs.code; _vuMADDx(&VU0); SYNCMSFLAGS(); }
|
||||
void VMADDy() { VU0.code = cpuRegs.code; _vuMADDy(&VU0); SYNCMSFLAGS(); }
|
||||
void VMADDz() { VU0.code = cpuRegs.code; _vuMADDz(&VU0); SYNCMSFLAGS(); }
|
||||
void VMADDw() { VU0.code = cpuRegs.code; _vuMADDw(&VU0); SYNCMSFLAGS(); }
|
||||
void VMADDA() { VU0.code = cpuRegs.code; _vuMADDA(&VU0); SYNCMSFLAGS(); }
|
||||
void VMADDAi() { VU0.code = cpuRegs.code; _vuMADDAi(&VU0); SYNCMSFLAGS(); }
|
||||
void VMADDAq() { VU0.code = cpuRegs.code; _vuMADDAq(&VU0); SYNCMSFLAGS(); }
|
||||
void VMADDAx() { VU0.code = cpuRegs.code; _vuMADDAx(&VU0); SYNCMSFLAGS(); }
|
||||
void VMADDAy() { VU0.code = cpuRegs.code; _vuMADDAy(&VU0); SYNCMSFLAGS(); }
|
||||
void VMADDAz() { VU0.code = cpuRegs.code; _vuMADDAz(&VU0); SYNCMSFLAGS(); }
|
||||
void VMADDAw() { VU0.code = cpuRegs.code; _vuMADDAw(&VU0); SYNCMSFLAGS(); }
|
||||
void VMSUB() { VU0.code = cpuRegs.code; _vuMSUB(&VU0); SYNCMSFLAGS(); }
|
||||
void VMSUBi() { VU0.code = cpuRegs.code; _vuMSUBi(&VU0); SYNCMSFLAGS(); }
|
||||
void VMSUBq() { VU0.code = cpuRegs.code; _vuMSUBq(&VU0); SYNCMSFLAGS(); }
|
||||
void VMSUBx() { VU0.code = cpuRegs.code; _vuMSUBx(&VU0); SYNCMSFLAGS(); }
|
||||
void VMSUBy() { VU0.code = cpuRegs.code; _vuMSUBy(&VU0); SYNCMSFLAGS(); }
|
||||
void VMSUBz() { VU0.code = cpuRegs.code; _vuMSUBz(&VU0); SYNCMSFLAGS(); }
|
||||
void VMSUBw() { VU0.code = cpuRegs.code; _vuMSUBw(&VU0); SYNCMSFLAGS(); }
|
||||
void VMSUBA() { VU0.code = cpuRegs.code; _vuMSUBA(&VU0); SYNCMSFLAGS(); }
|
||||
void VMSUBAi() { VU0.code = cpuRegs.code; _vuMSUBAi(&VU0); SYNCMSFLAGS(); }
|
||||
void VMSUBAq() { VU0.code = cpuRegs.code; _vuMSUBAq(&VU0); SYNCMSFLAGS(); }
|
||||
void VMSUBAx() { VU0.code = cpuRegs.code; _vuMSUBAx(&VU0); SYNCMSFLAGS(); }
|
||||
void VMSUBAy() { VU0.code = cpuRegs.code; _vuMSUBAy(&VU0); SYNCMSFLAGS(); }
|
||||
void VMSUBAz() { VU0.code = cpuRegs.code; _vuMSUBAz(&VU0); SYNCMSFLAGS(); }
|
||||
void VMSUBAw() { VU0.code = cpuRegs.code; _vuMSUBAw(&VU0); SYNCMSFLAGS(); }
|
||||
void VMAX() { VU0.code = cpuRegs.code; _vuMAX(&VU0); }
|
||||
void VMAXi() { VU0.code = cpuRegs.code; _vuMAXi(&VU0); }
|
||||
void VMAXx() { VU0.code = cpuRegs.code; _vuMAXx(&VU0); }
|
||||
void VMAXy() { VU0.code = cpuRegs.code; _vuMAXy(&VU0); }
|
||||
void VMAXz() { VU0.code = cpuRegs.code; _vuMAXz(&VU0); }
|
||||
void VMAXw() { VU0.code = cpuRegs.code; _vuMAXw(&VU0); }
|
||||
void VMINI() { VU0.code = cpuRegs.code; _vuMINI(&VU0); }
|
||||
void VMINIi() { VU0.code = cpuRegs.code; _vuMINIi(&VU0); }
|
||||
void VMINIx() { VU0.code = cpuRegs.code; _vuMINIx(&VU0); }
|
||||
void VMINIy() { VU0.code = cpuRegs.code; _vuMINIy(&VU0); }
|
||||
void VMINIz() { VU0.code = cpuRegs.code; _vuMINIz(&VU0); }
|
||||
void VMINIw() { VU0.code = cpuRegs.code; _vuMINIw(&VU0); }
|
||||
void VOPMULA() { VU0.code = cpuRegs.code; _vuOPMULA(&VU0); SYNCMSFLAGS(); }
|
||||
void VOPMSUB() { VU0.code = cpuRegs.code; _vuOPMSUB(&VU0); SYNCMSFLAGS(); }
|
||||
void VNOP() { VU0.code = cpuRegs.code; _vuNOP(&VU0); }
|
||||
void VFTOI0() { VU0.code = cpuRegs.code; _vuFTOI0(&VU0); }
|
||||
void VFTOI4() { VU0.code = cpuRegs.code; _vuFTOI4(&VU0); }
|
||||
void VFTOI12() { VU0.code = cpuRegs.code; _vuFTOI12(&VU0); }
|
||||
void VFTOI15() { VU0.code = cpuRegs.code; _vuFTOI15(&VU0); }
|
||||
void VITOF0() { VU0.code = cpuRegs.code; _vuITOF0(&VU0); }
|
||||
void VITOF4() { VU0.code = cpuRegs.code; _vuITOF4(&VU0); }
|
||||
void VITOF12() { VU0.code = cpuRegs.code; _vuITOF12(&VU0); }
|
||||
void VITOF15() { VU0.code = cpuRegs.code; _vuITOF15(&VU0); }
|
||||
void VCLIPw() { VU0.code = cpuRegs.code; _vuCLIP(&VU0); VU0.VI[REG_CLIP_FLAG].UL = VU0.clipflag; }
|
||||
|
||||
void VDIV() { VU0.code = cpuRegs.code; _vuDIV(&VU0); SYNCFDIV(); }
|
||||
void VSQRT() { VU0.code = cpuRegs.code; _vuSQRT(&VU0); SYNCFDIV(); }
|
||||
void VRSQRT() { VU0.code = cpuRegs.code; _vuRSQRT(&VU0); SYNCFDIV(); }
|
||||
void VIADD() { VU0.code = cpuRegs.code; _vuIADD(&VU0); }
|
||||
void VIADDI() { VU0.code = cpuRegs.code; _vuIADDI(&VU0); }
|
||||
void VIADDIU() { VU0.code = cpuRegs.code; _vuIADDIU(&VU0); }
|
||||
void VIAND() { VU0.code = cpuRegs.code; _vuIAND(&VU0); }
|
||||
void VIOR() { VU0.code = cpuRegs.code; _vuIOR(&VU0); }
|
||||
void VISUB() { VU0.code = cpuRegs.code; _vuISUB(&VU0); }
|
||||
void VISUBIU() { VU0.code = cpuRegs.code; _vuISUBIU(&VU0); }
|
||||
void VMOVE() { VU0.code = cpuRegs.code; _vuMOVE(&VU0); }
|
||||
void VMFIR() { VU0.code = cpuRegs.code; _vuMFIR(&VU0); }
|
||||
void VMTIR() { VU0.code = cpuRegs.code; _vuMTIR(&VU0); }
|
||||
void VMR32() { VU0.code = cpuRegs.code; _vuMR32(&VU0); }
|
||||
void VLQ() { VU0.code = cpuRegs.code; _vuLQ(&VU0); }
|
||||
void VLQD() { VU0.code = cpuRegs.code; _vuLQD(&VU0); }
|
||||
void VLQI() { VU0.code = cpuRegs.code; _vuLQI(&VU0); }
|
||||
void VSQ() { VU0.code = cpuRegs.code; _vuSQ(&VU0); }
|
||||
void VSQD() { VU0.code = cpuRegs.code; _vuSQD(&VU0); }
|
||||
void VSQI() { VU0.code = cpuRegs.code; _vuSQI(&VU0); }
|
||||
void VILW() { VU0.code = cpuRegs.code; _vuILW(&VU0); }
|
||||
void VISW() { VU0.code = cpuRegs.code; _vuISW(&VU0); }
|
||||
void VILWR() { VU0.code = cpuRegs.code; _vuILWR(&VU0); }
|
||||
void VISWR() { VU0.code = cpuRegs.code; _vuISWR(&VU0); }
|
||||
void VRINIT() { VU0.code = cpuRegs.code; _vuRINIT(&VU0); }
|
||||
void VRGET() { VU0.code = cpuRegs.code; _vuRGET(&VU0); }
|
||||
void VRNEXT() { VU0.code = cpuRegs.code; _vuRNEXT(&VU0); }
|
||||
void VRXOR() { VU0.code = cpuRegs.code; _vuRXOR(&VU0); }
|
||||
void VWAITQ() { VU0.code = cpuRegs.code; _vuWAITQ(&VU0); }
|
||||
void VFSAND() { VU0.code = cpuRegs.code; _vuFSAND(&VU0); }
|
||||
void VFSEQ() { VU0.code = cpuRegs.code; _vuFSEQ(&VU0); }
|
||||
void VFSOR() { VU0.code = cpuRegs.code; _vuFSOR(&VU0); }
|
||||
void VFSSET() { VU0.code = cpuRegs.code; _vuFSSET(&VU0); }
|
||||
void VFMAND() { VU0.code = cpuRegs.code; _vuFMAND(&VU0); }
|
||||
void VFMEQ() { VU0.code = cpuRegs.code; _vuFMEQ(&VU0); }
|
||||
void VFMOR() { VU0.code = cpuRegs.code; _vuFMOR(&VU0); }
|
||||
void VFCAND() { VU0.code = cpuRegs.code; _vuFCAND(&VU0); }
|
||||
void VFCEQ() { VU0.code = cpuRegs.code; _vuFCEQ(&VU0); }
|
||||
void VFCOR() { VU0.code = cpuRegs.code; _vuFCOR(&VU0); }
|
||||
void VFCSET() { VU0.code = cpuRegs.code; _vuFCSET(&VU0); }
|
||||
void VFCGET() { VU0.code = cpuRegs.code; _vuFCGET(&VU0); }
|
||||
void VXITOP() { VU0.code = cpuRegs.code; _vuXITOP(&VU0); }
|
||||
|
||||
|
|
|
@ -20,11 +20,10 @@
|
|||
|
||||
#include "PrecompiledHeader.h"
|
||||
#include "Common.h"
|
||||
#include "VUmicro.h"
|
||||
|
||||
#include <cmath>
|
||||
|
||||
#include "VUmicro.h"
|
||||
|
||||
using namespace R5900;
|
||||
|
||||
#define VF_VAL(x) ((x==0x80000000)?0:(x))
|
||||
|
@ -34,13 +33,7 @@ void vu0ResetRegs()
|
|||
{
|
||||
VU0.VI[REG_VPU_STAT].UL &= ~0xff; // stop vu0
|
||||
VU0.VI[REG_FBRST].UL &= ~0xff; // stop vu0
|
||||
vif0Regs->stat.VEW = false;
|
||||
}
|
||||
|
||||
void VU0MI_XGKICK() {
|
||||
}
|
||||
|
||||
void VU0MI_XTOP() {
|
||||
vif0Regs.stat.VEW = false;
|
||||
}
|
||||
|
||||
void __fastcall vu0ExecMicro(u32 addr) {
|
||||
|
@ -58,362 +51,3 @@ void __fastcall vu0ExecMicro(u32 addr) {
|
|||
_vuExecMicroDebug(VU0);
|
||||
CpuVU0->ExecuteBlock(1);
|
||||
}
|
||||
|
||||
void VU0unknown() {
|
||||
pxFailDev("Unknown VU micromode opcode called");
|
||||
CPU_LOG("Unknown VU micromode opcode called");
|
||||
}
|
||||
|
||||
void VU0regsunknown(_VURegsNum *VUregsn) {
|
||||
pxFailDev("Unknown VU micromode opcode called");
|
||||
CPU_LOG("Unknown VU micromode opcode called");
|
||||
}
|
||||
|
||||
_vuRegsTables(VU0, VU0regs);
|
||||
|
||||
|
||||
/****************************************/
|
||||
/* VU Micromode Upper instructions */
|
||||
/****************************************/
|
||||
|
||||
void VU0MI_ABS() { _vuABS(&VU0); }
|
||||
void VU0MI_ADD() { _vuADD(&VU0); }
|
||||
void VU0MI_ADDi() { _vuADDi(&VU0); }
|
||||
void VU0MI_ADDq() { _vuADDq(&VU0); }
|
||||
void VU0MI_ADDx() { _vuADDx(&VU0); }
|
||||
void VU0MI_ADDy() { _vuADDy(&VU0); }
|
||||
void VU0MI_ADDz() { _vuADDz(&VU0); }
|
||||
void VU0MI_ADDw() { _vuADDw(&VU0); }
|
||||
void VU0MI_ADDA() { _vuADDA(&VU0); }
|
||||
void VU0MI_ADDAi() { _vuADDAi(&VU0); }
|
||||
void VU0MI_ADDAq() { _vuADDAq(&VU0); }
|
||||
void VU0MI_ADDAx() { _vuADDAx(&VU0); }
|
||||
void VU0MI_ADDAy() { _vuADDAy(&VU0); }
|
||||
void VU0MI_ADDAz() { _vuADDAz(&VU0); }
|
||||
void VU0MI_ADDAw() { _vuADDAw(&VU0); }
|
||||
void VU0MI_SUB() { _vuSUB(&VU0); }
|
||||
void VU0MI_SUBi() { _vuSUBi(&VU0); }
|
||||
void VU0MI_SUBq() { _vuSUBq(&VU0); }
|
||||
void VU0MI_SUBx() { _vuSUBx(&VU0); }
|
||||
void VU0MI_SUBy() { _vuSUBy(&VU0); }
|
||||
void VU0MI_SUBz() { _vuSUBz(&VU0); }
|
||||
void VU0MI_SUBw() { _vuSUBw(&VU0); }
|
||||
void VU0MI_SUBA() { _vuSUBA(&VU0); }
|
||||
void VU0MI_SUBAi() { _vuSUBAi(&VU0); }
|
||||
void VU0MI_SUBAq() { _vuSUBAq(&VU0); }
|
||||
void VU0MI_SUBAx() { _vuSUBAx(&VU0); }
|
||||
void VU0MI_SUBAy() { _vuSUBAy(&VU0); }
|
||||
void VU0MI_SUBAz() { _vuSUBAz(&VU0); }
|
||||
void VU0MI_SUBAw() { _vuSUBAw(&VU0); }
|
||||
void VU0MI_MUL() { _vuMUL(&VU0); }
|
||||
void VU0MI_MULi() { _vuMULi(&VU0); }
|
||||
void VU0MI_MULq() { _vuMULq(&VU0); }
|
||||
void VU0MI_MULx() { _vuMULx(&VU0); }
|
||||
void VU0MI_MULy() { _vuMULy(&VU0); }
|
||||
void VU0MI_MULz() { _vuMULz(&VU0); }
|
||||
void VU0MI_MULw() { _vuMULw(&VU0); }
|
||||
void VU0MI_MULA() { _vuMULA(&VU0); }
|
||||
void VU0MI_MULAi() { _vuMULAi(&VU0); }
|
||||
void VU0MI_MULAq() { _vuMULAq(&VU0); }
|
||||
void VU0MI_MULAx() { _vuMULAx(&VU0); }
|
||||
void VU0MI_MULAy() { _vuMULAy(&VU0); }
|
||||
void VU0MI_MULAz() { _vuMULAz(&VU0); }
|
||||
void VU0MI_MULAw() { _vuMULAw(&VU0); }
|
||||
void VU0MI_MADD() { _vuMADD(&VU0); }
|
||||
void VU0MI_MADDi() { _vuMADDi(&VU0); }
|
||||
void VU0MI_MADDq() { _vuMADDq(&VU0); }
|
||||
void VU0MI_MADDx() { _vuMADDx(&VU0); }
|
||||
void VU0MI_MADDy() { _vuMADDy(&VU0); }
|
||||
void VU0MI_MADDz() { _vuMADDz(&VU0); }
|
||||
void VU0MI_MADDw() { _vuMADDw(&VU0); }
|
||||
void VU0MI_MADDA() { _vuMADDA(&VU0); }
|
||||
void VU0MI_MADDAi() { _vuMADDAi(&VU0); }
|
||||
void VU0MI_MADDAq() { _vuMADDAq(&VU0); }
|
||||
void VU0MI_MADDAx() { _vuMADDAx(&VU0); }
|
||||
void VU0MI_MADDAy() { _vuMADDAy(&VU0); }
|
||||
void VU0MI_MADDAz() { _vuMADDAz(&VU0); }
|
||||
void VU0MI_MADDAw() { _vuMADDAw(&VU0); }
|
||||
void VU0MI_MSUB() { _vuMSUB(&VU0); }
|
||||
void VU0MI_MSUBi() { _vuMSUBi(&VU0); }
|
||||
void VU0MI_MSUBq() { _vuMSUBq(&VU0); }
|
||||
void VU0MI_MSUBx() { _vuMSUBx(&VU0); }
|
||||
void VU0MI_MSUBy() { _vuMSUBy(&VU0); }
|
||||
void VU0MI_MSUBz() { _vuMSUBz(&VU0); }
|
||||
void VU0MI_MSUBw() { _vuMSUBw(&VU0); }
|
||||
void VU0MI_MSUBA() { _vuMSUBA(&VU0); }
|
||||
void VU0MI_MSUBAi() { _vuMSUBAi(&VU0); }
|
||||
void VU0MI_MSUBAq() { _vuMSUBAq(&VU0); }
|
||||
void VU0MI_MSUBAx() { _vuMSUBAx(&VU0); }
|
||||
void VU0MI_MSUBAy() { _vuMSUBAy(&VU0); }
|
||||
void VU0MI_MSUBAz() { _vuMSUBAz(&VU0); }
|
||||
void VU0MI_MSUBAw() { _vuMSUBAw(&VU0); }
|
||||
void VU0MI_MAX() { _vuMAX(&VU0); }
|
||||
void VU0MI_MAXi() { _vuMAXi(&VU0); }
|
||||
void VU0MI_MAXx() { _vuMAXx(&VU0); }
|
||||
void VU0MI_MAXy() { _vuMAXy(&VU0); }
|
||||
void VU0MI_MAXz() { _vuMAXz(&VU0); }
|
||||
void VU0MI_MAXw() { _vuMAXw(&VU0); }
|
||||
void VU0MI_MINI() { _vuMINI(&VU0); }
|
||||
void VU0MI_MINIi() { _vuMINIi(&VU0); }
|
||||
void VU0MI_MINIx() { _vuMINIx(&VU0); }
|
||||
void VU0MI_MINIy() { _vuMINIy(&VU0); }
|
||||
void VU0MI_MINIz() { _vuMINIz(&VU0); }
|
||||
void VU0MI_MINIw() { _vuMINIw(&VU0); }
|
||||
void VU0MI_OPMULA() { _vuOPMULA(&VU0); }
|
||||
void VU0MI_OPMSUB() { _vuOPMSUB(&VU0); }
|
||||
void VU0MI_NOP() { _vuNOP(&VU0); }
|
||||
void VU0MI_FTOI0() { _vuFTOI0(&VU0); }
|
||||
void VU0MI_FTOI4() { _vuFTOI4(&VU0); }
|
||||
void VU0MI_FTOI12() { _vuFTOI12(&VU0); }
|
||||
void VU0MI_FTOI15() { _vuFTOI15(&VU0); }
|
||||
void VU0MI_ITOF0() { _vuITOF0(&VU0); }
|
||||
void VU0MI_ITOF4() { _vuITOF4(&VU0); }
|
||||
void VU0MI_ITOF12() { _vuITOF12(&VU0); }
|
||||
void VU0MI_ITOF15() { _vuITOF15(&VU0); }
|
||||
void VU0MI_CLIP() { _vuCLIP(&VU0); }
|
||||
|
||||
/*****************************************/
|
||||
/* VU Micromode Lower instructions */
|
||||
/*****************************************/
|
||||
|
||||
void VU0MI_DIV() { _vuDIV(&VU0); }
|
||||
void VU0MI_SQRT() { _vuSQRT(&VU0); }
|
||||
void VU0MI_RSQRT() { _vuRSQRT(&VU0); }
|
||||
void VU0MI_IADD() { _vuIADD(&VU0); }
|
||||
void VU0MI_IADDI() { _vuIADDI(&VU0); }
|
||||
void VU0MI_IADDIU() { _vuIADDIU(&VU0); }
|
||||
void VU0MI_IAND() { _vuIAND(&VU0); }
|
||||
void VU0MI_IOR() { _vuIOR(&VU0); }
|
||||
void VU0MI_ISUB() { _vuISUB(&VU0); }
|
||||
void VU0MI_ISUBIU() { _vuISUBIU(&VU0); }
|
||||
void VU0MI_MOVE() { _vuMOVE(&VU0); }
|
||||
void VU0MI_MFIR() { _vuMFIR(&VU0); }
|
||||
void VU0MI_MTIR() { _vuMTIR(&VU0); }
|
||||
void VU0MI_MR32() { _vuMR32(&VU0); }
|
||||
void VU0MI_LQ() { _vuLQ(&VU0); }
|
||||
void VU0MI_LQD() { _vuLQD(&VU0); }
|
||||
void VU0MI_LQI() { _vuLQI(&VU0); }
|
||||
void VU0MI_SQ() { _vuSQ(&VU0); }
|
||||
void VU0MI_SQD() { _vuSQD(&VU0); }
|
||||
void VU0MI_SQI() { _vuSQI(&VU0); }
|
||||
void VU0MI_ILW() { _vuILW(&VU0); }
|
||||
void VU0MI_ISW() { _vuISW(&VU0); }
|
||||
void VU0MI_ILWR() { _vuILWR(&VU0); }
|
||||
void VU0MI_ISWR() { _vuISWR(&VU0); }
|
||||
void VU0MI_RINIT() { _vuRINIT(&VU0); }
|
||||
void VU0MI_RGET() { _vuRGET(&VU0); }
|
||||
void VU0MI_RNEXT() { _vuRNEXT(&VU0); }
|
||||
void VU0MI_RXOR() { _vuRXOR(&VU0); }
|
||||
void VU0MI_WAITQ() { _vuWAITQ(&VU0); }
|
||||
void VU0MI_FSAND() { _vuFSAND(&VU0); }
|
||||
void VU0MI_FSEQ() { _vuFSEQ(&VU0); }
|
||||
void VU0MI_FSOR() { _vuFSOR(&VU0); }
|
||||
void VU0MI_FSSET() { _vuFSSET(&VU0); }
|
||||
void VU0MI_FMAND() { _vuFMAND(&VU0); }
|
||||
void VU0MI_FMEQ() { _vuFMEQ(&VU0); }
|
||||
void VU0MI_FMOR() { _vuFMOR(&VU0); }
|
||||
void VU0MI_FCAND() { _vuFCAND(&VU0); }
|
||||
void VU0MI_FCEQ() { _vuFCEQ(&VU0); }
|
||||
void VU0MI_FCOR() { _vuFCOR(&VU0); }
|
||||
void VU0MI_FCSET() { _vuFCSET(&VU0); }
|
||||
void VU0MI_FCGET() { _vuFCGET(&VU0); }
|
||||
void VU0MI_IBEQ() { _vuIBEQ(&VU0); }
|
||||
void VU0MI_IBGEZ() { _vuIBGEZ(&VU0); }
|
||||
void VU0MI_IBGTZ() { _vuIBGTZ(&VU0); }
|
||||
void VU0MI_IBLTZ() { _vuIBLTZ(&VU0); }
|
||||
void VU0MI_IBLEZ() { _vuIBLEZ(&VU0); }
|
||||
void VU0MI_IBNE() { _vuIBNE(&VU0); }
|
||||
void VU0MI_B() { _vuB(&VU0); }
|
||||
void VU0MI_BAL() { _vuBAL(&VU0); }
|
||||
void VU0MI_JR() { _vuJR(&VU0); }
|
||||
void VU0MI_JALR() { _vuJALR(&VU0); }
|
||||
void VU0MI_MFP() { _vuMFP(&VU0); }
|
||||
void VU0MI_WAITP() { _vuWAITP(&VU0); }
|
||||
void VU0MI_ESADD() { _vuESADD(&VU0); }
|
||||
void VU0MI_ERSADD() { _vuERSADD(&VU0); }
|
||||
void VU0MI_ELENG() { _vuELENG(&VU0); }
|
||||
void VU0MI_ERLENG() { _vuERLENG(&VU0); }
|
||||
void VU0MI_EATANxy() { _vuEATANxy(&VU0); }
|
||||
void VU0MI_EATANxz() { _vuEATANxz(&VU0); }
|
||||
void VU0MI_ESUM() { _vuESUM(&VU0); }
|
||||
void VU0MI_ERCPR() { _vuERCPR(&VU0); }
|
||||
void VU0MI_ESQRT() { _vuESQRT(&VU0); }
|
||||
void VU0MI_ERSQRT() { _vuERSQRT(&VU0); }
|
||||
void VU0MI_ESIN() { _vuESIN(&VU0); }
|
||||
void VU0MI_EATAN() { _vuEATAN(&VU0); }
|
||||
void VU0MI_EEXP() { _vuEEXP(&VU0); }
|
||||
void VU0MI_XITOP() { _vuXITOP(&VU0); }
|
||||
|
||||
/****************************************/
|
||||
/* VU Micromode Upper instructions */
|
||||
/****************************************/
|
||||
|
||||
void VU0regsMI_ABS(_VURegsNum *VUregsn) { _vuRegsABS(&VU0, VUregsn); }
|
||||
void VU0regsMI_ADD(_VURegsNum *VUregsn) { _vuRegsADD(&VU0, VUregsn); }
|
||||
void VU0regsMI_ADDi(_VURegsNum *VUregsn) { _vuRegsADDi(&VU0, VUregsn); }
|
||||
void VU0regsMI_ADDq(_VURegsNum *VUregsn) { _vuRegsADDq(&VU0, VUregsn); }
|
||||
void VU0regsMI_ADDx(_VURegsNum *VUregsn) { _vuRegsADDx(&VU0, VUregsn); }
|
||||
void VU0regsMI_ADDy(_VURegsNum *VUregsn) { _vuRegsADDy(&VU0, VUregsn); }
|
||||
void VU0regsMI_ADDz(_VURegsNum *VUregsn) { _vuRegsADDz(&VU0, VUregsn); }
|
||||
void VU0regsMI_ADDw(_VURegsNum *VUregsn) { _vuRegsADDw(&VU0, VUregsn); }
|
||||
void VU0regsMI_ADDA(_VURegsNum *VUregsn) { _vuRegsADDA(&VU0, VUregsn); }
|
||||
void VU0regsMI_ADDAi(_VURegsNum *VUregsn) { _vuRegsADDAi(&VU0, VUregsn); }
|
||||
void VU0regsMI_ADDAq(_VURegsNum *VUregsn) { _vuRegsADDAq(&VU0, VUregsn); }
|
||||
void VU0regsMI_ADDAx(_VURegsNum *VUregsn) { _vuRegsADDAx(&VU0, VUregsn); }
|
||||
void VU0regsMI_ADDAy(_VURegsNum *VUregsn) { _vuRegsADDAy(&VU0, VUregsn); }
|
||||
void VU0regsMI_ADDAz(_VURegsNum *VUregsn) { _vuRegsADDAz(&VU0, VUregsn); }
|
||||
void VU0regsMI_ADDAw(_VURegsNum *VUregsn) { _vuRegsADDAw(&VU0, VUregsn); }
|
||||
void VU0regsMI_SUB(_VURegsNum *VUregsn) { _vuRegsSUB(&VU0, VUregsn); }
|
||||
void VU0regsMI_SUBi(_VURegsNum *VUregsn) { _vuRegsSUBi(&VU0, VUregsn); }
|
||||
void VU0regsMI_SUBq(_VURegsNum *VUregsn) { _vuRegsSUBq(&VU0, VUregsn); }
|
||||
void VU0regsMI_SUBx(_VURegsNum *VUregsn) { _vuRegsSUBx(&VU0, VUregsn); }
|
||||
void VU0regsMI_SUBy(_VURegsNum *VUregsn) { _vuRegsSUBy(&VU0, VUregsn); }
|
||||
void VU0regsMI_SUBz(_VURegsNum *VUregsn) { _vuRegsSUBz(&VU0, VUregsn); }
|
||||
void VU0regsMI_SUBw(_VURegsNum *VUregsn) { _vuRegsSUBw(&VU0, VUregsn); }
|
||||
void VU0regsMI_SUBA(_VURegsNum *VUregsn) { _vuRegsSUBA(&VU0, VUregsn); }
|
||||
void VU0regsMI_SUBAi(_VURegsNum *VUregsn) { _vuRegsSUBAi(&VU0, VUregsn); }
|
||||
void VU0regsMI_SUBAq(_VURegsNum *VUregsn) { _vuRegsSUBAq(&VU0, VUregsn); }
|
||||
void VU0regsMI_SUBAx(_VURegsNum *VUregsn) { _vuRegsSUBAx(&VU0, VUregsn); }
|
||||
void VU0regsMI_SUBAy(_VURegsNum *VUregsn) { _vuRegsSUBAy(&VU0, VUregsn); }
|
||||
void VU0regsMI_SUBAz(_VURegsNum *VUregsn) { _vuRegsSUBAz(&VU0, VUregsn); }
|
||||
void VU0regsMI_SUBAw(_VURegsNum *VUregsn) { _vuRegsSUBAw(&VU0, VUregsn); }
|
||||
void VU0regsMI_MUL(_VURegsNum *VUregsn) { _vuRegsMUL(&VU0, VUregsn); }
|
||||
void VU0regsMI_MULi(_VURegsNum *VUregsn) { _vuRegsMULi(&VU0, VUregsn); }
|
||||
void VU0regsMI_MULq(_VURegsNum *VUregsn) { _vuRegsMULq(&VU0, VUregsn); }
|
||||
void VU0regsMI_MULx(_VURegsNum *VUregsn) { _vuRegsMULx(&VU0, VUregsn); }
|
||||
void VU0regsMI_MULy(_VURegsNum *VUregsn) { _vuRegsMULy(&VU0, VUregsn); }
|
||||
void VU0regsMI_MULz(_VURegsNum *VUregsn) { _vuRegsMULz(&VU0, VUregsn); }
|
||||
void VU0regsMI_MULw(_VURegsNum *VUregsn) { _vuRegsMULw(&VU0, VUregsn); }
|
||||
void VU0regsMI_MULA(_VURegsNum *VUregsn) { _vuRegsMULA(&VU0, VUregsn); }
|
||||
void VU0regsMI_MULAi(_VURegsNum *VUregsn) { _vuRegsMULAi(&VU0, VUregsn); }
|
||||
void VU0regsMI_MULAq(_VURegsNum *VUregsn) { _vuRegsMULAq(&VU0, VUregsn); }
|
||||
void VU0regsMI_MULAx(_VURegsNum *VUregsn) { _vuRegsMULAx(&VU0, VUregsn); }
|
||||
void VU0regsMI_MULAy(_VURegsNum *VUregsn) { _vuRegsMULAy(&VU0, VUregsn); }
|
||||
void VU0regsMI_MULAz(_VURegsNum *VUregsn) { _vuRegsMULAz(&VU0, VUregsn); }
|
||||
void VU0regsMI_MULAw(_VURegsNum *VUregsn) { _vuRegsMULAw(&VU0, VUregsn); }
|
||||
void VU0regsMI_MADD(_VURegsNum *VUregsn) { _vuRegsMADD(&VU0, VUregsn); }
|
||||
void VU0regsMI_MADDi(_VURegsNum *VUregsn) { _vuRegsMADDi(&VU0, VUregsn); }
|
||||
void VU0regsMI_MADDq(_VURegsNum *VUregsn) { _vuRegsMADDq(&VU0, VUregsn); }
|
||||
void VU0regsMI_MADDx(_VURegsNum *VUregsn) { _vuRegsMADDx(&VU0, VUregsn); }
|
||||
void VU0regsMI_MADDy(_VURegsNum *VUregsn) { _vuRegsMADDy(&VU0, VUregsn); }
|
||||
void VU0regsMI_MADDz(_VURegsNum *VUregsn) { _vuRegsMADDz(&VU0, VUregsn); }
|
||||
void VU0regsMI_MADDw(_VURegsNum *VUregsn) { _vuRegsMADDw(&VU0, VUregsn); }
|
||||
void VU0regsMI_MADDA(_VURegsNum *VUregsn) { _vuRegsMADDA(&VU0, VUregsn); }
|
||||
void VU0regsMI_MADDAi(_VURegsNum *VUregsn) { _vuRegsMADDAi(&VU0, VUregsn); }
|
||||
void VU0regsMI_MADDAq(_VURegsNum *VUregsn) { _vuRegsMADDAq(&VU0, VUregsn); }
|
||||
void VU0regsMI_MADDAx(_VURegsNum *VUregsn) { _vuRegsMADDAx(&VU0, VUregsn); }
|
||||
void VU0regsMI_MADDAy(_VURegsNum *VUregsn) { _vuRegsMADDAy(&VU0, VUregsn); }
|
||||
void VU0regsMI_MADDAz(_VURegsNum *VUregsn) { _vuRegsMADDAz(&VU0, VUregsn); }
|
||||
void VU0regsMI_MADDAw(_VURegsNum *VUregsn) { _vuRegsMADDAw(&VU0, VUregsn); }
|
||||
void VU0regsMI_MSUB(_VURegsNum *VUregsn) { _vuRegsMSUB(&VU0, VUregsn); }
|
||||
void VU0regsMI_MSUBi(_VURegsNum *VUregsn) { _vuRegsMSUBi(&VU0, VUregsn); }
|
||||
void VU0regsMI_MSUBq(_VURegsNum *VUregsn) { _vuRegsMSUBq(&VU0, VUregsn); }
|
||||
void VU0regsMI_MSUBx(_VURegsNum *VUregsn) { _vuRegsMSUBx(&VU0, VUregsn); }
|
||||
void VU0regsMI_MSUBy(_VURegsNum *VUregsn) { _vuRegsMSUBy(&VU0, VUregsn); }
|
||||
void VU0regsMI_MSUBz(_VURegsNum *VUregsn) { _vuRegsMSUBz(&VU0, VUregsn); }
|
||||
void VU0regsMI_MSUBw(_VURegsNum *VUregsn) { _vuRegsMSUBw(&VU0, VUregsn); }
|
||||
void VU0regsMI_MSUBA(_VURegsNum *VUregsn) { _vuRegsMSUBA(&VU0, VUregsn); }
|
||||
void VU0regsMI_MSUBAi(_VURegsNum *VUregsn) { _vuRegsMSUBAi(&VU0, VUregsn); }
|
||||
void VU0regsMI_MSUBAq(_VURegsNum *VUregsn) { _vuRegsMSUBAq(&VU0, VUregsn); }
|
||||
void VU0regsMI_MSUBAx(_VURegsNum *VUregsn) { _vuRegsMSUBAx(&VU0, VUregsn); }
|
||||
void VU0regsMI_MSUBAy(_VURegsNum *VUregsn) { _vuRegsMSUBAy(&VU0, VUregsn); }
|
||||
void VU0regsMI_MSUBAz(_VURegsNum *VUregsn) { _vuRegsMSUBAz(&VU0, VUregsn); }
|
||||
void VU0regsMI_MSUBAw(_VURegsNum *VUregsn) { _vuRegsMSUBAw(&VU0, VUregsn); }
|
||||
void VU0regsMI_MAX(_VURegsNum *VUregsn) { _vuRegsMAX(&VU0, VUregsn); }
|
||||
void VU0regsMI_MAXi(_VURegsNum *VUregsn) { _vuRegsMAXi(&VU0, VUregsn); }
|
||||
void VU0regsMI_MAXx(_VURegsNum *VUregsn) { _vuRegsMAXx(&VU0, VUregsn); }
|
||||
void VU0regsMI_MAXy(_VURegsNum *VUregsn) { _vuRegsMAXy(&VU0, VUregsn); }
|
||||
void VU0regsMI_MAXz(_VURegsNum *VUregsn) { _vuRegsMAXz(&VU0, VUregsn); }
|
||||
void VU0regsMI_MAXw(_VURegsNum *VUregsn) { _vuRegsMAXw(&VU0, VUregsn); }
|
||||
void VU0regsMI_MINI(_VURegsNum *VUregsn) { _vuRegsMINI(&VU0, VUregsn); }
|
||||
void VU0regsMI_MINIi(_VURegsNum *VUregsn) { _vuRegsMINIi(&VU0, VUregsn); }
|
||||
void VU0regsMI_MINIx(_VURegsNum *VUregsn) { _vuRegsMINIx(&VU0, VUregsn); }
|
||||
void VU0regsMI_MINIy(_VURegsNum *VUregsn) { _vuRegsMINIy(&VU0, VUregsn); }
|
||||
void VU0regsMI_MINIz(_VURegsNum *VUregsn) { _vuRegsMINIz(&VU0, VUregsn); }
|
||||
void VU0regsMI_MINIw(_VURegsNum *VUregsn) { _vuRegsMINIw(&VU0, VUregsn); }
|
||||
void VU0regsMI_OPMULA(_VURegsNum *VUregsn) { _vuRegsOPMULA(&VU0, VUregsn); }
|
||||
void VU0regsMI_OPMSUB(_VURegsNum *VUregsn) { _vuRegsOPMSUB(&VU0, VUregsn); }
|
||||
void VU0regsMI_NOP(_VURegsNum *VUregsn) { _vuRegsNOP(&VU0, VUregsn); }
|
||||
void VU0regsMI_FTOI0(_VURegsNum *VUregsn) { _vuRegsFTOI0(&VU0, VUregsn); }
|
||||
void VU0regsMI_FTOI4(_VURegsNum *VUregsn) { _vuRegsFTOI4(&VU0, VUregsn); }
|
||||
void VU0regsMI_FTOI12(_VURegsNum *VUregsn) { _vuRegsFTOI12(&VU0, VUregsn); }
|
||||
void VU0regsMI_FTOI15(_VURegsNum *VUregsn) { _vuRegsFTOI15(&VU0, VUregsn); }
|
||||
void VU0regsMI_ITOF0(_VURegsNum *VUregsn) { _vuRegsITOF0(&VU0, VUregsn); }
|
||||
void VU0regsMI_ITOF4(_VURegsNum *VUregsn) { _vuRegsITOF4(&VU0, VUregsn); }
|
||||
void VU0regsMI_ITOF12(_VURegsNum *VUregsn) { _vuRegsITOF12(&VU0, VUregsn); }
|
||||
void VU0regsMI_ITOF15(_VURegsNum *VUregsn) { _vuRegsITOF15(&VU0, VUregsn); }
|
||||
void VU0regsMI_CLIP(_VURegsNum *VUregsn) { _vuRegsCLIP(&VU0, VUregsn); }
|
||||
|
||||
/*****************************************/
|
||||
/* VU Micromode Lower instructions */
|
||||
/*****************************************/
|
||||
|
||||
void VU0regsMI_DIV(_VURegsNum *VUregsn) { _vuRegsDIV(&VU0, VUregsn); }
|
||||
void VU0regsMI_SQRT(_VURegsNum *VUregsn) { _vuRegsSQRT(&VU0, VUregsn); }
|
||||
void VU0regsMI_RSQRT(_VURegsNum *VUregsn) { _vuRegsRSQRT(&VU0, VUregsn); }
|
||||
void VU0regsMI_IADD(_VURegsNum *VUregsn) { _vuRegsIADD(&VU0, VUregsn); }
|
||||
void VU0regsMI_IADDI(_VURegsNum *VUregsn) { _vuRegsIADDI(&VU0, VUregsn); }
|
||||
void VU0regsMI_IADDIU(_VURegsNum *VUregsn) { _vuRegsIADDIU(&VU0, VUregsn); }
|
||||
void VU0regsMI_IAND(_VURegsNum *VUregsn) { _vuRegsIAND(&VU0, VUregsn); }
|
||||
void VU0regsMI_IOR(_VURegsNum *VUregsn) { _vuRegsIOR(&VU0, VUregsn); }
|
||||
void VU0regsMI_ISUB(_VURegsNum *VUregsn) { _vuRegsISUB(&VU0, VUregsn); }
|
||||
void VU0regsMI_ISUBIU(_VURegsNum *VUregsn) { _vuRegsISUBIU(&VU0, VUregsn); }
|
||||
void VU0regsMI_MOVE(_VURegsNum *VUregsn) { _vuRegsMOVE(&VU0, VUregsn); }
|
||||
void VU0regsMI_MFIR(_VURegsNum *VUregsn) { _vuRegsMFIR(&VU0, VUregsn); }
|
||||
void VU0regsMI_MTIR(_VURegsNum *VUregsn) { _vuRegsMTIR(&VU0, VUregsn); }
|
||||
void VU0regsMI_MR32(_VURegsNum *VUregsn) { _vuRegsMR32(&VU0, VUregsn); }
|
||||
void VU0regsMI_LQ(_VURegsNum *VUregsn) { _vuRegsLQ(&VU0, VUregsn); }
|
||||
void VU0regsMI_LQD(_VURegsNum *VUregsn) { _vuRegsLQD(&VU0, VUregsn); }
|
||||
void VU0regsMI_LQI(_VURegsNum *VUregsn) { _vuRegsLQI(&VU0, VUregsn); }
|
||||
void VU0regsMI_SQ(_VURegsNum *VUregsn) { _vuRegsSQ(&VU0, VUregsn); }
|
||||
void VU0regsMI_SQD(_VURegsNum *VUregsn) { _vuRegsSQD(&VU0, VUregsn); }
|
||||
void VU0regsMI_SQI(_VURegsNum *VUregsn) { _vuRegsSQI(&VU0, VUregsn); }
|
||||
void VU0regsMI_ILW(_VURegsNum *VUregsn) { _vuRegsILW(&VU0, VUregsn); }
|
||||
void VU0regsMI_ISW(_VURegsNum *VUregsn) { _vuRegsISW(&VU0, VUregsn); }
|
||||
void VU0regsMI_ILWR(_VURegsNum *VUregsn) { _vuRegsILWR(&VU0, VUregsn); }
|
||||
void VU0regsMI_ISWR(_VURegsNum *VUregsn) { _vuRegsISWR(&VU0, VUregsn); }
|
||||
void VU0regsMI_RINIT(_VURegsNum *VUregsn) { _vuRegsRINIT(&VU0, VUregsn); }
|
||||
void VU0regsMI_RGET(_VURegsNum *VUregsn) { _vuRegsRGET(&VU0, VUregsn); }
|
||||
void VU0regsMI_RNEXT(_VURegsNum *VUregsn) { _vuRegsRNEXT(&VU0, VUregsn); }
|
||||
void VU0regsMI_RXOR(_VURegsNum *VUregsn) { _vuRegsRXOR(&VU0, VUregsn); }
|
||||
void VU0regsMI_WAITQ(_VURegsNum *VUregsn) { _vuRegsWAITQ(&VU0, VUregsn); }
|
||||
void VU0regsMI_FSAND(_VURegsNum *VUregsn) { _vuRegsFSAND(&VU0, VUregsn); }
|
||||
void VU0regsMI_FSEQ(_VURegsNum *VUregsn) { _vuRegsFSEQ(&VU0, VUregsn); }
|
||||
void VU0regsMI_FSOR(_VURegsNum *VUregsn) { _vuRegsFSOR(&VU0, VUregsn); }
|
||||
void VU0regsMI_FSSET(_VURegsNum *VUregsn) { _vuRegsFSSET(&VU0, VUregsn); }
|
||||
void VU0regsMI_FMAND(_VURegsNum *VUregsn) { _vuRegsFMAND(&VU0, VUregsn); }
|
||||
void VU0regsMI_FMEQ(_VURegsNum *VUregsn) { _vuRegsFMEQ(&VU0, VUregsn); }
|
||||
void VU0regsMI_FMOR(_VURegsNum *VUregsn) { _vuRegsFMOR(&VU0, VUregsn); }
|
||||
void VU0regsMI_FCAND(_VURegsNum *VUregsn) { _vuRegsFCAND(&VU0, VUregsn); }
|
||||
void VU0regsMI_FCEQ(_VURegsNum *VUregsn) { _vuRegsFCEQ(&VU0, VUregsn); }
|
||||
void VU0regsMI_FCOR(_VURegsNum *VUregsn) { _vuRegsFCOR(&VU0, VUregsn); }
|
||||
void VU0regsMI_FCSET(_VURegsNum *VUregsn) { _vuRegsFCSET(&VU0, VUregsn); }
|
||||
void VU0regsMI_FCGET(_VURegsNum *VUregsn) { _vuRegsFCGET(&VU0, VUregsn); }
|
||||
void VU0regsMI_IBEQ(_VURegsNum *VUregsn) { _vuRegsIBEQ(&VU0, VUregsn); }
|
||||
void VU0regsMI_IBGEZ(_VURegsNum *VUregsn) { _vuRegsIBGEZ(&VU0, VUregsn); }
|
||||
void VU0regsMI_IBGTZ(_VURegsNum *VUregsn) { _vuRegsIBGTZ(&VU0, VUregsn); }
|
||||
void VU0regsMI_IBLTZ(_VURegsNum *VUregsn) { _vuRegsIBLTZ(&VU0, VUregsn); }
|
||||
void VU0regsMI_IBLEZ(_VURegsNum *VUregsn) { _vuRegsIBLEZ(&VU0, VUregsn); }
|
||||
void VU0regsMI_IBNE(_VURegsNum *VUregsn) { _vuRegsIBNE(&VU0, VUregsn); }
|
||||
void VU0regsMI_B(_VURegsNum *VUregsn) { _vuRegsB(&VU0, VUregsn); }
|
||||
void VU0regsMI_BAL(_VURegsNum *VUregsn) { _vuRegsBAL(&VU0, VUregsn); }
|
||||
void VU0regsMI_JR(_VURegsNum *VUregsn) { _vuRegsJR(&VU0, VUregsn); }
|
||||
void VU0regsMI_JALR(_VURegsNum *VUregsn) { _vuRegsJALR(&VU0, VUregsn); }
|
||||
void VU0regsMI_MFP(_VURegsNum *VUregsn) { _vuRegsMFP(&VU0, VUregsn); }
|
||||
void VU0regsMI_WAITP(_VURegsNum *VUregsn) { _vuRegsWAITP(&VU0, VUregsn); }
|
||||
void VU0regsMI_ESADD(_VURegsNum *VUregsn) { _vuRegsESADD(&VU0, VUregsn); }
|
||||
void VU0regsMI_ERSADD(_VURegsNum *VUregsn) { _vuRegsERSADD(&VU0, VUregsn); }
|
||||
void VU0regsMI_ELENG(_VURegsNum *VUregsn) { _vuRegsELENG(&VU0, VUregsn); }
|
||||
void VU0regsMI_ERLENG(_VURegsNum *VUregsn) { _vuRegsERLENG(&VU0, VUregsn); }
|
||||
void VU0regsMI_EATANxy(_VURegsNum *VUregsn) { _vuRegsEATANxy(&VU0, VUregsn); }
|
||||
void VU0regsMI_EATANxz(_VURegsNum *VUregsn) { _vuRegsEATANxz(&VU0, VUregsn); }
|
||||
void VU0regsMI_ESUM(_VURegsNum *VUregsn) { _vuRegsESUM(&VU0, VUregsn); }
|
||||
void VU0regsMI_ERCPR(_VURegsNum *VUregsn) { _vuRegsERCPR(&VU0, VUregsn); }
|
||||
void VU0regsMI_ESQRT(_VURegsNum *VUregsn) { _vuRegsESQRT(&VU0, VUregsn); }
|
||||
void VU0regsMI_ERSQRT(_VURegsNum *VUregsn) { _vuRegsERSQRT(&VU0, VUregsn); }
|
||||
void VU0regsMI_ESIN(_VURegsNum *VUregsn) { _vuRegsESIN(&VU0, VUregsn); }
|
||||
void VU0regsMI_EATAN(_VURegsNum *VUregsn) { _vuRegsEATAN(&VU0, VUregsn); }
|
||||
void VU0regsMI_EEXP(_VURegsNum *VUregsn) { _vuRegsEEXP(&VU0, VUregsn); }
|
||||
void VU0regsMI_XITOP(_VURegsNum *VUregsn) { _vuRegsXITOP(&VU0, VUregsn); }
|
||||
void VU0regsMI_XGKICK(_VURegsNum *VUregsn) { _vuRegsXGKICK(&VU0, VUregsn); }
|
||||
void VU0regsMI_XTOP(_VURegsNum *VUregsn) { _vuRegsXTOP(&VU0, VUregsn); }
|
||||
|
|
|
@ -21,15 +21,13 @@
|
|||
|
||||
extern void _vuFlushAll(VURegs* VU);
|
||||
|
||||
_vuTables(VU0, VU0);
|
||||
|
||||
void _vu0ExecUpper(VURegs* VU, u32 *ptr) {
|
||||
static void _vu0ExecUpper(VURegs* VU, u32 *ptr) {
|
||||
VU->code = ptr[1];
|
||||
IdebugUPPER(VU0);
|
||||
VU0_UPPER_OPCODE[VU->code & 0x3f]();
|
||||
}
|
||||
|
||||
void _vu0ExecLower(VURegs* VU, u32 *ptr) {
|
||||
static void _vu0ExecLower(VURegs* VU, u32 *ptr) {
|
||||
VU->code = ptr[0];
|
||||
IdebugLOWER(VU0);
|
||||
VU0_LOWER_OPCODE[VU->code >> 25]();
|
||||
|
@ -49,15 +47,6 @@ static void _vu0Exec(VURegs* VU)
|
|||
int vireg;
|
||||
int discard=0;
|
||||
|
||||
if(VU0.VI[REG_TPC].UL >= VU0.maxmicro){
|
||||
#ifdef CPU_LOG
|
||||
Console.WriteLn("VU0 memory overflow!!: %x", VU->VI[REG_TPC].UL);
|
||||
#endif
|
||||
VU0.VI[REG_VPU_STAT].UL&= ~0x1;
|
||||
VU->cycle++;
|
||||
return;
|
||||
}
|
||||
|
||||
ptr = (u32*)&VU->Micro[VU->VI[REG_TPC].UL];
|
||||
VU->VI[REG_TPC].UL+=8;
|
||||
|
||||
|
@ -166,21 +155,15 @@ static void _vu0Exec(VURegs* VU)
|
|||
if( VU->ebit-- == 1 ) {
|
||||
_vuFlushAll(VU);
|
||||
VU0.VI[REG_VPU_STAT].UL&= ~0x1; /* E flag */
|
||||
vif0Regs->stat.VEW = false;
|
||||
vif0Regs.stat.VEW = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void vu0Exec(VURegs* VU)
|
||||
{
|
||||
if (VU->VI[REG_TPC].UL >= VU->maxmicro) {
|
||||
#ifdef CPU_LOG
|
||||
Console.Warning("VU0 memory overflow!!: %x", VU->VI[REG_TPC].UL);
|
||||
#endif
|
||||
VU0.VI[REG_VPU_STAT].UL&= ~0x1;
|
||||
} else {
|
||||
_vu0Exec(VU);
|
||||
}
|
||||
VU0.VI[REG_TPC].UL &= VU0_PROGMASK;
|
||||
_vu0Exec(VU);
|
||||
VU->cycle++;
|
||||
|
||||
if (VU->VI[0].UL != 0) DbgCon.Error("VI[0] != 0!!!!\n");
|
||||
|
|
|
@ -24,8 +24,6 @@
|
|||
|
||||
#include "VUmicro.h"
|
||||
|
||||
VURegs* g_pVU1;
|
||||
|
||||
#ifdef PCSX2_DEBUG
|
||||
u32 vudump = 0;
|
||||
#endif
|
||||
|
@ -37,7 +35,7 @@ void vu1ResetRegs()
|
|||
{
|
||||
VU0.VI[REG_VPU_STAT].UL &= ~0xff00; // stop vu1
|
||||
VU0.VI[REG_FBRST].UL &= ~0xff00; // stop vu1
|
||||
vif1Regs->stat.VEW = false;
|
||||
vif1Regs.stat.VEW = false;
|
||||
}
|
||||
|
||||
void vu1Finish() {
|
||||
|
@ -58,373 +56,9 @@ void __fastcall vu1ExecMicro(u32 addr)
|
|||
VU0.VI[REG_VPU_STAT].UL &= ~0xFF00;
|
||||
VU0.VI[REG_VPU_STAT].UL |= 0x0100;
|
||||
|
||||
vif1Regs->stat.VEW = true;
|
||||
vif1Regs.stat.VEW = true;
|
||||
if ((s32)addr != -1) VU1.VI[REG_TPC].UL = addr;
|
||||
_vuExecMicroDebug(VU1);
|
||||
|
||||
CpuVU1->Execute(vu1RunCycles);
|
||||
}
|
||||
|
||||
_vuRegsTables(VU1, VU1regs);
|
||||
|
||||
void VU1unknown() {
|
||||
//assert(0);
|
||||
CPU_LOG("Unknown VU micromode opcode called");
|
||||
}
|
||||
|
||||
void VU1regsunknown(_VURegsNum *VUregsn) {
|
||||
//assert(0);
|
||||
CPU_LOG("Unknown VU micromode opcode called");
|
||||
}
|
||||
|
||||
|
||||
|
||||
/****************************************/
|
||||
/* VU Micromode Upper instructions */
|
||||
/****************************************/
|
||||
|
||||
void VU1MI_ABS() { _vuABS(&VU1); }
|
||||
void VU1MI_ADD() { _vuADD(&VU1); }
|
||||
void VU1MI_ADDi() { _vuADDi(&VU1); }
|
||||
void VU1MI_ADDq() { _vuADDq(&VU1); }
|
||||
void VU1MI_ADDx() { _vuADDx(&VU1); }
|
||||
void VU1MI_ADDy() { _vuADDy(&VU1); }
|
||||
void VU1MI_ADDz() { _vuADDz(&VU1); }
|
||||
void VU1MI_ADDw() { _vuADDw(&VU1); }
|
||||
void VU1MI_ADDA() { _vuADDA(&VU1); }
|
||||
void VU1MI_ADDAi() { _vuADDAi(&VU1); }
|
||||
void VU1MI_ADDAq() { _vuADDAq(&VU1); }
|
||||
void VU1MI_ADDAx() { _vuADDAx(&VU1); }
|
||||
void VU1MI_ADDAy() { _vuADDAy(&VU1); }
|
||||
void VU1MI_ADDAz() { _vuADDAz(&VU1); }
|
||||
void VU1MI_ADDAw() { _vuADDAw(&VU1); }
|
||||
void VU1MI_SUB() { _vuSUB(&VU1); }
|
||||
void VU1MI_SUBi() { _vuSUBi(&VU1); }
|
||||
void VU1MI_SUBq() { _vuSUBq(&VU1); }
|
||||
void VU1MI_SUBx() { _vuSUBx(&VU1); }
|
||||
void VU1MI_SUBy() { _vuSUBy(&VU1); }
|
||||
void VU1MI_SUBz() { _vuSUBz(&VU1); }
|
||||
void VU1MI_SUBw() { _vuSUBw(&VU1); }
|
||||
void VU1MI_SUBA() { _vuSUBA(&VU1); }
|
||||
void VU1MI_SUBAi() { _vuSUBAi(&VU1); }
|
||||
void VU1MI_SUBAq() { _vuSUBAq(&VU1); }
|
||||
void VU1MI_SUBAx() { _vuSUBAx(&VU1); }
|
||||
void VU1MI_SUBAy() { _vuSUBAy(&VU1); }
|
||||
void VU1MI_SUBAz() { _vuSUBAz(&VU1); }
|
||||
void VU1MI_SUBAw() { _vuSUBAw(&VU1); }
|
||||
void VU1MI_MUL() { _vuMUL(&VU1); }
|
||||
void VU1MI_MULi() { _vuMULi(&VU1); }
|
||||
void VU1MI_MULq() { _vuMULq(&VU1); }
|
||||
void VU1MI_MULx() { _vuMULx(&VU1); }
|
||||
void VU1MI_MULy() { _vuMULy(&VU1); }
|
||||
void VU1MI_MULz() { _vuMULz(&VU1); }
|
||||
void VU1MI_MULw() { _vuMULw(&VU1); }
|
||||
void VU1MI_MULA() { _vuMULA(&VU1); }
|
||||
void VU1MI_MULAi() { _vuMULAi(&VU1); }
|
||||
void VU1MI_MULAq() { _vuMULAq(&VU1); }
|
||||
void VU1MI_MULAx() { _vuMULAx(&VU1); }
|
||||
void VU1MI_MULAy() { _vuMULAy(&VU1); }
|
||||
void VU1MI_MULAz() { _vuMULAz(&VU1); }
|
||||
void VU1MI_MULAw() { _vuMULAw(&VU1); }
|
||||
void VU1MI_MADD() { _vuMADD(&VU1); }
|
||||
void VU1MI_MADDi() { _vuMADDi(&VU1); }
|
||||
void VU1MI_MADDq() { _vuMADDq(&VU1); }
|
||||
void VU1MI_MADDx() { _vuMADDx(&VU1); }
|
||||
void VU1MI_MADDy() { _vuMADDy(&VU1); }
|
||||
void VU1MI_MADDz() { _vuMADDz(&VU1); }
|
||||
void VU1MI_MADDw() { _vuMADDw(&VU1); }
|
||||
void VU1MI_MADDA() { _vuMADDA(&VU1); }
|
||||
void VU1MI_MADDAi() { _vuMADDAi(&VU1); }
|
||||
void VU1MI_MADDAq() { _vuMADDAq(&VU1); }
|
||||
void VU1MI_MADDAx() { _vuMADDAx(&VU1); }
|
||||
void VU1MI_MADDAy() { _vuMADDAy(&VU1); }
|
||||
void VU1MI_MADDAz() { _vuMADDAz(&VU1); }
|
||||
void VU1MI_MADDAw() { _vuMADDAw(&VU1); }
|
||||
void VU1MI_MSUB() { _vuMSUB(&VU1); }
|
||||
void VU1MI_MSUBi() { _vuMSUBi(&VU1); }
|
||||
void VU1MI_MSUBq() { _vuMSUBq(&VU1); }
|
||||
void VU1MI_MSUBx() { _vuMSUBx(&VU1); }
|
||||
void VU1MI_MSUBy() { _vuMSUBy(&VU1); }
|
||||
void VU1MI_MSUBz() { _vuMSUBz(&VU1); }
|
||||
void VU1MI_MSUBw() { _vuMSUBw(&VU1); }
|
||||
void VU1MI_MSUBA() { _vuMSUBA(&VU1); }
|
||||
void VU1MI_MSUBAi() { _vuMSUBAi(&VU1); }
|
||||
void VU1MI_MSUBAq() { _vuMSUBAq(&VU1); }
|
||||
void VU1MI_MSUBAx() { _vuMSUBAx(&VU1); }
|
||||
void VU1MI_MSUBAy() { _vuMSUBAy(&VU1); }
|
||||
void VU1MI_MSUBAz() { _vuMSUBAz(&VU1); }
|
||||
void VU1MI_MSUBAw() { _vuMSUBAw(&VU1); }
|
||||
void VU1MI_MAX() { _vuMAX(&VU1); }
|
||||
void VU1MI_MAXi() { _vuMAXi(&VU1); }
|
||||
void VU1MI_MAXx() { _vuMAXx(&VU1); }
|
||||
void VU1MI_MAXy() { _vuMAXy(&VU1); }
|
||||
void VU1MI_MAXz() { _vuMAXz(&VU1); }
|
||||
void VU1MI_MAXw() { _vuMAXw(&VU1); }
|
||||
void VU1MI_MINI() { _vuMINI(&VU1); }
|
||||
void VU1MI_MINIi() { _vuMINIi(&VU1); }
|
||||
void VU1MI_MINIx() { _vuMINIx(&VU1); }
|
||||
void VU1MI_MINIy() { _vuMINIy(&VU1); }
|
||||
void VU1MI_MINIz() { _vuMINIz(&VU1); }
|
||||
void VU1MI_MINIw() { _vuMINIw(&VU1); }
|
||||
void VU1MI_OPMULA() { _vuOPMULA(&VU1); }
|
||||
void VU1MI_OPMSUB() { _vuOPMSUB(&VU1); }
|
||||
void VU1MI_NOP() { _vuNOP(&VU1); }
|
||||
void VU1MI_FTOI0() { _vuFTOI0(&VU1); }
|
||||
void VU1MI_FTOI4() { _vuFTOI4(&VU1); }
|
||||
void VU1MI_FTOI12() { _vuFTOI12(&VU1); }
|
||||
void VU1MI_FTOI15() { _vuFTOI15(&VU1); }
|
||||
void VU1MI_ITOF0() { _vuITOF0(&VU1); }
|
||||
void VU1MI_ITOF4() { _vuITOF4(&VU1); }
|
||||
void VU1MI_ITOF12() { _vuITOF12(&VU1); }
|
||||
void VU1MI_ITOF15() { _vuITOF15(&VU1); }
|
||||
void VU1MI_CLIP() { _vuCLIP(&VU1); }
|
||||
|
||||
/*****************************************/
|
||||
/* VU Micromode Lower instructions */
|
||||
/*****************************************/
|
||||
|
||||
void VU1MI_DIV() { _vuDIV(&VU1); }
|
||||
void VU1MI_SQRT() { _vuSQRT(&VU1); }
|
||||
void VU1MI_RSQRT() { _vuRSQRT(&VU1); }
|
||||
void VU1MI_IADD() { _vuIADD(&VU1); }
|
||||
void VU1MI_IADDI() { _vuIADDI(&VU1); }
|
||||
void VU1MI_IADDIU() { _vuIADDIU(&VU1); }
|
||||
void VU1MI_IAND() { _vuIAND(&VU1); }
|
||||
void VU1MI_IOR() { _vuIOR(&VU1); }
|
||||
void VU1MI_ISUB() { _vuISUB(&VU1); }
|
||||
void VU1MI_ISUBIU() { _vuISUBIU(&VU1); }
|
||||
void VU1MI_MOVE() { _vuMOVE(&VU1); }
|
||||
void VU1MI_MFIR() { _vuMFIR(&VU1); }
|
||||
void VU1MI_MTIR() { _vuMTIR(&VU1); }
|
||||
void VU1MI_MR32() { _vuMR32(&VU1); }
|
||||
void VU1MI_LQ() { _vuLQ(&VU1); }
|
||||
void VU1MI_LQD() { _vuLQD(&VU1); }
|
||||
void VU1MI_LQI() { _vuLQI(&VU1); }
|
||||
void VU1MI_SQ() { _vuSQ(&VU1); }
|
||||
void VU1MI_SQD() { _vuSQD(&VU1); }
|
||||
void VU1MI_SQI() { _vuSQI(&VU1); }
|
||||
void VU1MI_ILW() { _vuILW(&VU1); }
|
||||
void VU1MI_ISW() { _vuISW(&VU1); }
|
||||
void VU1MI_ILWR() { _vuILWR(&VU1); }
|
||||
void VU1MI_ISWR() { _vuISWR(&VU1); }
|
||||
void VU1MI_RINIT() { _vuRINIT(&VU1); }
|
||||
void VU1MI_RGET() { _vuRGET(&VU1); }
|
||||
void VU1MI_RNEXT() { _vuRNEXT(&VU1); }
|
||||
void VU1MI_RXOR() { _vuRXOR(&VU1); }
|
||||
void VU1MI_WAITQ() { _vuWAITQ(&VU1); }
|
||||
void VU1MI_FSAND() { _vuFSAND(&VU1); }
|
||||
void VU1MI_FSEQ() { _vuFSEQ(&VU1); }
|
||||
void VU1MI_FSOR() { _vuFSOR(&VU1); }
|
||||
void VU1MI_FSSET() { _vuFSSET(&VU1); }
|
||||
void VU1MI_FMAND() { _vuFMAND(&VU1); }
|
||||
void VU1MI_FMEQ() { _vuFMEQ(&VU1); }
|
||||
void VU1MI_FMOR() { _vuFMOR(&VU1); }
|
||||
void VU1MI_FCAND() { _vuFCAND(&VU1); }
|
||||
void VU1MI_FCEQ() { _vuFCEQ(&VU1); }
|
||||
void VU1MI_FCOR() { _vuFCOR(&VU1); }
|
||||
void VU1MI_FCSET() { _vuFCSET(&VU1); }
|
||||
void VU1MI_FCGET() { _vuFCGET(&VU1); }
|
||||
void VU1MI_IBEQ() { _vuIBEQ(&VU1); }
|
||||
void VU1MI_IBGEZ() { _vuIBGEZ(&VU1); }
|
||||
void VU1MI_IBGTZ() { _vuIBGTZ(&VU1); }
|
||||
void VU1MI_IBLTZ() { _vuIBLTZ(&VU1); }
|
||||
void VU1MI_IBLEZ() { _vuIBLEZ(&VU1); }
|
||||
void VU1MI_IBNE() { _vuIBNE(&VU1); }
|
||||
void VU1MI_B() { _vuB(&VU1); }
|
||||
void VU1MI_BAL() { _vuBAL(&VU1); }
|
||||
void VU1MI_JR() { _vuJR(&VU1); }
|
||||
void VU1MI_JALR() { _vuJALR(&VU1); }
|
||||
void VU1MI_MFP() { _vuMFP(&VU1); }
|
||||
void VU1MI_WAITP() { _vuWAITP(&VU1); }
|
||||
void VU1MI_ESADD() { _vuESADD(&VU1); }
|
||||
void VU1MI_ERSADD() { _vuERSADD(&VU1); }
|
||||
void VU1MI_ELENG() { _vuELENG(&VU1); }
|
||||
void VU1MI_ERLENG() { _vuERLENG(&VU1); }
|
||||
void VU1MI_EATANxy() { _vuEATANxy(&VU1); }
|
||||
void VU1MI_EATANxz() { _vuEATANxz(&VU1); }
|
||||
void VU1MI_ESUM() { _vuESUM(&VU1); }
|
||||
void VU1MI_ERCPR() { _vuERCPR(&VU1); }
|
||||
void VU1MI_ESQRT() { _vuESQRT(&VU1); }
|
||||
void VU1MI_ERSQRT() { _vuERSQRT(&VU1); }
|
||||
void VU1MI_ESIN() { _vuESIN(&VU1); }
|
||||
void VU1MI_EATAN() { _vuEATAN(&VU1); }
|
||||
void VU1MI_EEXP() { _vuEEXP(&VU1); }
|
||||
void VU1MI_XITOP() { _vuXITOP(&VU1); }
|
||||
void VU1MI_XGKICK() { _vuXGKICK(&VU1); }
|
||||
void VU1MI_XTOP() { _vuXTOP(&VU1); }
|
||||
|
||||
|
||||
|
||||
/****************************************/
|
||||
/* VU Micromode Upper instructions */
|
||||
/****************************************/
|
||||
|
||||
void VU1regsMI_ABS(_VURegsNum *VUregsn) { _vuRegsABS(&VU1, VUregsn); }
|
||||
void VU1regsMI_ADD(_VURegsNum *VUregsn) { _vuRegsADD(&VU1, VUregsn); }
|
||||
void VU1regsMI_ADDi(_VURegsNum *VUregsn) { _vuRegsADDi(&VU1, VUregsn); }
|
||||
void VU1regsMI_ADDq(_VURegsNum *VUregsn) { _vuRegsADDq(&VU1, VUregsn); }
|
||||
void VU1regsMI_ADDx(_VURegsNum *VUregsn) { _vuRegsADDx(&VU1, VUregsn); }
|
||||
void VU1regsMI_ADDy(_VURegsNum *VUregsn) { _vuRegsADDy(&VU1, VUregsn); }
|
||||
void VU1regsMI_ADDz(_VURegsNum *VUregsn) { _vuRegsADDz(&VU1, VUregsn); }
|
||||
void VU1regsMI_ADDw(_VURegsNum *VUregsn) { _vuRegsADDw(&VU1, VUregsn); }
|
||||
void VU1regsMI_ADDA(_VURegsNum *VUregsn) { _vuRegsADDA(&VU1, VUregsn); }
|
||||
void VU1regsMI_ADDAi(_VURegsNum *VUregsn) { _vuRegsADDAi(&VU1, VUregsn); }
|
||||
void VU1regsMI_ADDAq(_VURegsNum *VUregsn) { _vuRegsADDAq(&VU1, VUregsn); }
|
||||
void VU1regsMI_ADDAx(_VURegsNum *VUregsn) { _vuRegsADDAx(&VU1, VUregsn); }
|
||||
void VU1regsMI_ADDAy(_VURegsNum *VUregsn) { _vuRegsADDAy(&VU1, VUregsn); }
|
||||
void VU1regsMI_ADDAz(_VURegsNum *VUregsn) { _vuRegsADDAz(&VU1, VUregsn); }
|
||||
void VU1regsMI_ADDAw(_VURegsNum *VUregsn) { _vuRegsADDAw(&VU1, VUregsn); }
|
||||
void VU1regsMI_SUB(_VURegsNum *VUregsn) { _vuRegsSUB(&VU1, VUregsn); }
|
||||
void VU1regsMI_SUBi(_VURegsNum *VUregsn) { _vuRegsSUBi(&VU1, VUregsn); }
|
||||
void VU1regsMI_SUBq(_VURegsNum *VUregsn) { _vuRegsSUBq(&VU1, VUregsn); }
|
||||
void VU1regsMI_SUBx(_VURegsNum *VUregsn) { _vuRegsSUBx(&VU1, VUregsn); }
|
||||
void VU1regsMI_SUBy(_VURegsNum *VUregsn) { _vuRegsSUBy(&VU1, VUregsn); }
|
||||
void VU1regsMI_SUBz(_VURegsNum *VUregsn) { _vuRegsSUBz(&VU1, VUregsn); }
|
||||
void VU1regsMI_SUBw(_VURegsNum *VUregsn) { _vuRegsSUBw(&VU1, VUregsn); }
|
||||
void VU1regsMI_SUBA(_VURegsNum *VUregsn) { _vuRegsSUBA(&VU1, VUregsn); }
|
||||
void VU1regsMI_SUBAi(_VURegsNum *VUregsn) { _vuRegsSUBAi(&VU1, VUregsn); }
|
||||
void VU1regsMI_SUBAq(_VURegsNum *VUregsn) { _vuRegsSUBAq(&VU1, VUregsn); }
|
||||
void VU1regsMI_SUBAx(_VURegsNum *VUregsn) { _vuRegsSUBAx(&VU1, VUregsn); }
|
||||
void VU1regsMI_SUBAy(_VURegsNum *VUregsn) { _vuRegsSUBAy(&VU1, VUregsn); }
|
||||
void VU1regsMI_SUBAz(_VURegsNum *VUregsn) { _vuRegsSUBAz(&VU1, VUregsn); }
|
||||
void VU1regsMI_SUBAw(_VURegsNum *VUregsn) { _vuRegsSUBAw(&VU1, VUregsn); }
|
||||
void VU1regsMI_MUL(_VURegsNum *VUregsn) { _vuRegsMUL(&VU1, VUregsn); }
|
||||
void VU1regsMI_MULi(_VURegsNum *VUregsn) { _vuRegsMULi(&VU1, VUregsn); }
|
||||
void VU1regsMI_MULq(_VURegsNum *VUregsn) { _vuRegsMULq(&VU1, VUregsn); }
|
||||
void VU1regsMI_MULx(_VURegsNum *VUregsn) { _vuRegsMULx(&VU1, VUregsn); }
|
||||
void VU1regsMI_MULy(_VURegsNum *VUregsn) { _vuRegsMULy(&VU1, VUregsn); }
|
||||
void VU1regsMI_MULz(_VURegsNum *VUregsn) { _vuRegsMULz(&VU1, VUregsn); }
|
||||
void VU1regsMI_MULw(_VURegsNum *VUregsn) { _vuRegsMULw(&VU1, VUregsn); }
|
||||
void VU1regsMI_MULA(_VURegsNum *VUregsn) { _vuRegsMULA(&VU1, VUregsn); }
|
||||
void VU1regsMI_MULAi(_VURegsNum *VUregsn) { _vuRegsMULAi(&VU1, VUregsn); }
|
||||
void VU1regsMI_MULAq(_VURegsNum *VUregsn) { _vuRegsMULAq(&VU1, VUregsn); }
|
||||
void VU1regsMI_MULAx(_VURegsNum *VUregsn) { _vuRegsMULAx(&VU1, VUregsn); }
|
||||
void VU1regsMI_MULAy(_VURegsNum *VUregsn) { _vuRegsMULAy(&VU1, VUregsn); }
|
||||
void VU1regsMI_MULAz(_VURegsNum *VUregsn) { _vuRegsMULAz(&VU1, VUregsn); }
|
||||
void VU1regsMI_MULAw(_VURegsNum *VUregsn) { _vuRegsMULAw(&VU1, VUregsn); }
|
||||
void VU1regsMI_MADD(_VURegsNum *VUregsn) { _vuRegsMADD(&VU1, VUregsn); }
|
||||
void VU1regsMI_MADDi(_VURegsNum *VUregsn) { _vuRegsMADDi(&VU1, VUregsn); }
|
||||
void VU1regsMI_MADDq(_VURegsNum *VUregsn) { _vuRegsMADDq(&VU1, VUregsn); }
|
||||
void VU1regsMI_MADDx(_VURegsNum *VUregsn) { _vuRegsMADDx(&VU1, VUregsn); }
|
||||
void VU1regsMI_MADDy(_VURegsNum *VUregsn) { _vuRegsMADDy(&VU1, VUregsn); }
|
||||
void VU1regsMI_MADDz(_VURegsNum *VUregsn) { _vuRegsMADDz(&VU1, VUregsn); }
|
||||
void VU1regsMI_MADDw(_VURegsNum *VUregsn) { _vuRegsMADDw(&VU1, VUregsn); }
|
||||
void VU1regsMI_MADDA(_VURegsNum *VUregsn) { _vuRegsMADDA(&VU1, VUregsn); }
|
||||
void VU1regsMI_MADDAi(_VURegsNum *VUregsn) { _vuRegsMADDAi(&VU1, VUregsn); }
|
||||
void VU1regsMI_MADDAq(_VURegsNum *VUregsn) { _vuRegsMADDAq(&VU1, VUregsn); }
|
||||
void VU1regsMI_MADDAx(_VURegsNum *VUregsn) { _vuRegsMADDAx(&VU1, VUregsn); }
|
||||
void VU1regsMI_MADDAy(_VURegsNum *VUregsn) { _vuRegsMADDAy(&VU1, VUregsn); }
|
||||
void VU1regsMI_MADDAz(_VURegsNum *VUregsn) { _vuRegsMADDAz(&VU1, VUregsn); }
|
||||
void VU1regsMI_MADDAw(_VURegsNum *VUregsn) { _vuRegsMADDAw(&VU1, VUregsn); }
|
||||
void VU1regsMI_MSUB(_VURegsNum *VUregsn) { _vuRegsMSUB(&VU1, VUregsn); }
|
||||
void VU1regsMI_MSUBi(_VURegsNum *VUregsn) { _vuRegsMSUBi(&VU1, VUregsn); }
|
||||
void VU1regsMI_MSUBq(_VURegsNum *VUregsn) { _vuRegsMSUBq(&VU1, VUregsn); }
|
||||
void VU1regsMI_MSUBx(_VURegsNum *VUregsn) { _vuRegsMSUBx(&VU1, VUregsn); }
|
||||
void VU1regsMI_MSUBy(_VURegsNum *VUregsn) { _vuRegsMSUBy(&VU1, VUregsn); }
|
||||
void VU1regsMI_MSUBz(_VURegsNum *VUregsn) { _vuRegsMSUBz(&VU1, VUregsn); }
|
||||
void VU1regsMI_MSUBw(_VURegsNum *VUregsn) { _vuRegsMSUBw(&VU1, VUregsn); }
|
||||
void VU1regsMI_MSUBA(_VURegsNum *VUregsn) { _vuRegsMSUBA(&VU1, VUregsn); }
|
||||
void VU1regsMI_MSUBAi(_VURegsNum *VUregsn) { _vuRegsMSUBAi(&VU1, VUregsn); }
|
||||
void VU1regsMI_MSUBAq(_VURegsNum *VUregsn) { _vuRegsMSUBAq(&VU1, VUregsn); }
|
||||
void VU1regsMI_MSUBAx(_VURegsNum *VUregsn) { _vuRegsMSUBAx(&VU1, VUregsn); }
|
||||
void VU1regsMI_MSUBAy(_VURegsNum *VUregsn) { _vuRegsMSUBAy(&VU1, VUregsn); }
|
||||
void VU1regsMI_MSUBAz(_VURegsNum *VUregsn) { _vuRegsMSUBAz(&VU1, VUregsn); }
|
||||
void VU1regsMI_MSUBAw(_VURegsNum *VUregsn) { _vuRegsMSUBAw(&VU1, VUregsn); }
|
||||
void VU1regsMI_MAX(_VURegsNum *VUregsn) { _vuRegsMAX(&VU1, VUregsn); }
|
||||
void VU1regsMI_MAXi(_VURegsNum *VUregsn) { _vuRegsMAXi(&VU1, VUregsn); }
|
||||
void VU1regsMI_MAXx(_VURegsNum *VUregsn) { _vuRegsMAXx(&VU1, VUregsn); }
|
||||
void VU1regsMI_MAXy(_VURegsNum *VUregsn) { _vuRegsMAXy(&VU1, VUregsn); }
|
||||
void VU1regsMI_MAXz(_VURegsNum *VUregsn) { _vuRegsMAXz(&VU1, VUregsn); }
|
||||
void VU1regsMI_MAXw(_VURegsNum *VUregsn) { _vuRegsMAXw(&VU1, VUregsn); }
|
||||
void VU1regsMI_MINI(_VURegsNum *VUregsn) { _vuRegsMINI(&VU1, VUregsn); }
|
||||
void VU1regsMI_MINIi(_VURegsNum *VUregsn) { _vuRegsMINIi(&VU1, VUregsn); }
|
||||
void VU1regsMI_MINIx(_VURegsNum *VUregsn) { _vuRegsMINIx(&VU1, VUregsn); }
|
||||
void VU1regsMI_MINIy(_VURegsNum *VUregsn) { _vuRegsMINIy(&VU1, VUregsn); }
|
||||
void VU1regsMI_MINIz(_VURegsNum *VUregsn) { _vuRegsMINIz(&VU1, VUregsn); }
|
||||
void VU1regsMI_MINIw(_VURegsNum *VUregsn) { _vuRegsMINIw(&VU1, VUregsn); }
|
||||
void VU1regsMI_OPMULA(_VURegsNum *VUregsn) { _vuRegsOPMULA(&VU1, VUregsn); }
|
||||
void VU1regsMI_OPMSUB(_VURegsNum *VUregsn) { _vuRegsOPMSUB(&VU1, VUregsn); }
|
||||
void VU1regsMI_NOP(_VURegsNum *VUregsn) { _vuRegsNOP(&VU1, VUregsn); }
|
||||
void VU1regsMI_FTOI0(_VURegsNum *VUregsn) { _vuRegsFTOI0(&VU1, VUregsn); }
|
||||
void VU1regsMI_FTOI4(_VURegsNum *VUregsn) { _vuRegsFTOI4(&VU1, VUregsn); }
|
||||
void VU1regsMI_FTOI12(_VURegsNum *VUregsn) { _vuRegsFTOI12(&VU1, VUregsn); }
|
||||
void VU1regsMI_FTOI15(_VURegsNum *VUregsn) { _vuRegsFTOI15(&VU1, VUregsn); }
|
||||
void VU1regsMI_ITOF0(_VURegsNum *VUregsn) { _vuRegsITOF0(&VU1, VUregsn); }
|
||||
void VU1regsMI_ITOF4(_VURegsNum *VUregsn) { _vuRegsITOF4(&VU1, VUregsn); }
|
||||
void VU1regsMI_ITOF12(_VURegsNum *VUregsn) { _vuRegsITOF12(&VU1, VUregsn); }
|
||||
void VU1regsMI_ITOF15(_VURegsNum *VUregsn) { _vuRegsITOF15(&VU1, VUregsn); }
|
||||
void VU1regsMI_CLIP(_VURegsNum *VUregsn) { _vuRegsCLIP(&VU1, VUregsn); }
|
||||
|
||||
/*****************************************/
|
||||
/* VU Micromode Lower instructions */
|
||||
/*****************************************/
|
||||
|
||||
void VU1regsMI_DIV(_VURegsNum *VUregsn) { _vuRegsDIV(&VU1, VUregsn); }
|
||||
void VU1regsMI_SQRT(_VURegsNum *VUregsn) { _vuRegsSQRT(&VU1, VUregsn); }
|
||||
void VU1regsMI_RSQRT(_VURegsNum *VUregsn) { _vuRegsRSQRT(&VU1, VUregsn); }
|
||||
void VU1regsMI_IADD(_VURegsNum *VUregsn) { _vuRegsIADD(&VU1, VUregsn); }
|
||||
void VU1regsMI_IADDI(_VURegsNum *VUregsn) { _vuRegsIADDI(&VU1, VUregsn); }
|
||||
void VU1regsMI_IADDIU(_VURegsNum *VUregsn) { _vuRegsIADDIU(&VU1, VUregsn); }
|
||||
void VU1regsMI_IAND(_VURegsNum *VUregsn) { _vuRegsIAND(&VU1, VUregsn); }
|
||||
void VU1regsMI_IOR(_VURegsNum *VUregsn) { _vuRegsIOR(&VU1, VUregsn); }
|
||||
void VU1regsMI_ISUB(_VURegsNum *VUregsn) { _vuRegsISUB(&VU1, VUregsn); }
|
||||
void VU1regsMI_ISUBIU(_VURegsNum *VUregsn) { _vuRegsISUBIU(&VU1, VUregsn); }
|
||||
void VU1regsMI_MOVE(_VURegsNum *VUregsn) { _vuRegsMOVE(&VU1, VUregsn); }
|
||||
void VU1regsMI_MFIR(_VURegsNum *VUregsn) { _vuRegsMFIR(&VU1, VUregsn); }
|
||||
void VU1regsMI_MTIR(_VURegsNum *VUregsn) { _vuRegsMTIR(&VU1, VUregsn); }
|
||||
void VU1regsMI_MR32(_VURegsNum *VUregsn) { _vuRegsMR32(&VU1, VUregsn); }
|
||||
void VU1regsMI_LQ(_VURegsNum *VUregsn) { _vuRegsLQ(&VU1, VUregsn); }
|
||||
void VU1regsMI_LQD(_VURegsNum *VUregsn) { _vuRegsLQD(&VU1, VUregsn); }
|
||||
void VU1regsMI_LQI(_VURegsNum *VUregsn) { _vuRegsLQI(&VU1, VUregsn); }
|
||||
void VU1regsMI_SQ(_VURegsNum *VUregsn) { _vuRegsSQ(&VU1, VUregsn); }
|
||||
void VU1regsMI_SQD(_VURegsNum *VUregsn) { _vuRegsSQD(&VU1, VUregsn); }
|
||||
void VU1regsMI_SQI(_VURegsNum *VUregsn) { _vuRegsSQI(&VU1, VUregsn); }
|
||||
void VU1regsMI_ILW(_VURegsNum *VUregsn) { _vuRegsILW(&VU1, VUregsn); }
|
||||
void VU1regsMI_ISW(_VURegsNum *VUregsn) { _vuRegsISW(&VU1, VUregsn); }
|
||||
void VU1regsMI_ILWR(_VURegsNum *VUregsn) { _vuRegsILWR(&VU1, VUregsn); }
|
||||
void VU1regsMI_ISWR(_VURegsNum *VUregsn) { _vuRegsISWR(&VU1, VUregsn); }
|
||||
void VU1regsMI_RINIT(_VURegsNum *VUregsn) { _vuRegsRINIT(&VU1, VUregsn); }
|
||||
void VU1regsMI_RGET(_VURegsNum *VUregsn) { _vuRegsRGET(&VU1, VUregsn); }
|
||||
void VU1regsMI_RNEXT(_VURegsNum *VUregsn) { _vuRegsRNEXT(&VU1, VUregsn); }
|
||||
void VU1regsMI_RXOR(_VURegsNum *VUregsn) { _vuRegsRXOR(&VU1, VUregsn); }
|
||||
void VU1regsMI_WAITQ(_VURegsNum *VUregsn) { _vuRegsWAITQ(&VU1, VUregsn); }
|
||||
void VU1regsMI_FSAND(_VURegsNum *VUregsn) { _vuRegsFSAND(&VU1, VUregsn); }
|
||||
void VU1regsMI_FSEQ(_VURegsNum *VUregsn) { _vuRegsFSEQ(&VU1, VUregsn); }
|
||||
void VU1regsMI_FSOR(_VURegsNum *VUregsn) { _vuRegsFSOR(&VU1, VUregsn); }
|
||||
void VU1regsMI_FSSET(_VURegsNum *VUregsn) { _vuRegsFSSET(&VU1, VUregsn); }
|
||||
void VU1regsMI_FMAND(_VURegsNum *VUregsn) { _vuRegsFMAND(&VU1, VUregsn); }
|
||||
void VU1regsMI_FMEQ(_VURegsNum *VUregsn) { _vuRegsFMEQ(&VU1, VUregsn); }
|
||||
void VU1regsMI_FMOR(_VURegsNum *VUregsn) { _vuRegsFMOR(&VU1, VUregsn); }
|
||||
void VU1regsMI_FCAND(_VURegsNum *VUregsn) { _vuRegsFCAND(&VU1, VUregsn); }
|
||||
void VU1regsMI_FCEQ(_VURegsNum *VUregsn) { _vuRegsFCEQ(&VU1, VUregsn); }
|
||||
void VU1regsMI_FCOR(_VURegsNum *VUregsn) { _vuRegsFCOR(&VU1, VUregsn); }
|
||||
void VU1regsMI_FCSET(_VURegsNum *VUregsn) { _vuRegsFCSET(&VU1, VUregsn); }
|
||||
void VU1regsMI_FCGET(_VURegsNum *VUregsn) { _vuRegsFCGET(&VU1, VUregsn); }
|
||||
void VU1regsMI_IBEQ(_VURegsNum *VUregsn) { _vuRegsIBEQ(&VU1, VUregsn); }
|
||||
void VU1regsMI_IBGEZ(_VURegsNum *VUregsn) { _vuRegsIBGEZ(&VU1, VUregsn); }
|
||||
void VU1regsMI_IBGTZ(_VURegsNum *VUregsn) { _vuRegsIBGTZ(&VU1, VUregsn); }
|
||||
void VU1regsMI_IBLTZ(_VURegsNum *VUregsn) { _vuRegsIBLTZ(&VU1, VUregsn); }
|
||||
void VU1regsMI_IBLEZ(_VURegsNum *VUregsn) { _vuRegsIBLEZ(&VU1, VUregsn); }
|
||||
void VU1regsMI_IBNE(_VURegsNum *VUregsn) { _vuRegsIBNE(&VU1, VUregsn); }
|
||||
void VU1regsMI_B(_VURegsNum *VUregsn) { _vuRegsB(&VU1, VUregsn); }
|
||||
void VU1regsMI_BAL(_VURegsNum *VUregsn) { _vuRegsBAL(&VU1, VUregsn); }
|
||||
void VU1regsMI_JR(_VURegsNum *VUregsn) { _vuRegsJR(&VU1, VUregsn); }
|
||||
void VU1regsMI_JALR(_VURegsNum *VUregsn) { _vuRegsJALR(&VU1, VUregsn); }
|
||||
void VU1regsMI_MFP(_VURegsNum *VUregsn) { _vuRegsMFP(&VU1, VUregsn); }
|
||||
void VU1regsMI_WAITP(_VURegsNum *VUregsn) { _vuRegsWAITP(&VU1, VUregsn); }
|
||||
void VU1regsMI_ESADD(_VURegsNum *VUregsn) { _vuRegsESADD(&VU1, VUregsn); }
|
||||
void VU1regsMI_ERSADD(_VURegsNum *VUregsn) { _vuRegsERSADD(&VU1, VUregsn); }
|
||||
void VU1regsMI_ELENG(_VURegsNum *VUregsn) { _vuRegsELENG(&VU1, VUregsn); }
|
||||
void VU1regsMI_ERLENG(_VURegsNum *VUregsn) { _vuRegsERLENG(&VU1, VUregsn); }
|
||||
void VU1regsMI_EATANxy(_VURegsNum *VUregsn) { _vuRegsEATANxy(&VU1, VUregsn); }
|
||||
void VU1regsMI_EATANxz(_VURegsNum *VUregsn) { _vuRegsEATANxz(&VU1, VUregsn); }
|
||||
void VU1regsMI_ESUM(_VURegsNum *VUregsn) { _vuRegsESUM(&VU1, VUregsn); }
|
||||
void VU1regsMI_ERCPR(_VURegsNum *VUregsn) { _vuRegsERCPR(&VU1, VUregsn); }
|
||||
void VU1regsMI_ESQRT(_VURegsNum *VUregsn) { _vuRegsESQRT(&VU1, VUregsn); }
|
||||
void VU1regsMI_ERSQRT(_VURegsNum *VUregsn) { _vuRegsERSQRT(&VU1, VUregsn); }
|
||||
void VU1regsMI_ESIN(_VURegsNum *VUregsn) { _vuRegsESIN(&VU1, VUregsn); }
|
||||
void VU1regsMI_EATAN(_VURegsNum *VUregsn) { _vuRegsEATAN(&VU1, VUregsn); }
|
||||
void VU1regsMI_EEXP(_VURegsNum *VUregsn) { _vuRegsEEXP(&VU1, VUregsn); }
|
||||
void VU1regsMI_XITOP(_VURegsNum *VUregsn) { _vuRegsXITOP(&VU1, VUregsn); }
|
||||
void VU1regsMI_XGKICK(_VURegsNum *VUregsn) { _vuRegsXGKICK(&VU1, VUregsn); }
|
||||
void VU1regsMI_XTOP(_VURegsNum *VUregsn) { _vuRegsXTOP(&VU1, VUregsn); }
|
||||
|
|
|
@ -21,8 +21,6 @@
|
|||
|
||||
extern void _vuFlushAll(VURegs* VU);
|
||||
|
||||
_vuTables(VU1, VU1);
|
||||
|
||||
void _vu1ExecUpper(VURegs* VU, u32 *ptr) {
|
||||
VU->code = ptr[1];
|
||||
IdebugUPPER(VU1);
|
||||
|
@ -50,13 +48,6 @@ static void _vu1Exec(VURegs* VU)
|
|||
int vireg;
|
||||
int discard=0;
|
||||
|
||||
if(VU->VI[REG_TPC].UL >= VU->maxmicro){
|
||||
CPU_LOG("VU1 memory overflow!!: %x", VU->VI[REG_TPC].UL);
|
||||
VU->VI[REG_TPC].UL &= 0x3FFF;
|
||||
/*VU0.VI[REG_VPU_STAT].UL&= ~0x100;
|
||||
VU->cycle++;
|
||||
return;*/
|
||||
}
|
||||
ptr = (u32*)&VU->Micro[VU->VI[REG_TPC].UL];
|
||||
VU->VI[REG_TPC].UL+=8;
|
||||
|
||||
|
@ -159,7 +150,7 @@ static void _vu1Exec(VURegs* VU)
|
|||
if( VU->ebit-- == 1 ) {
|
||||
_vuFlushAll(VU);
|
||||
VU0.VI[REG_VPU_STAT].UL &= ~0x100;
|
||||
vif1Regs->stat.VEW = false;
|
||||
vif1Regs.stat.VEW = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -184,6 +175,7 @@ InterpVU1::InterpVU1()
|
|||
|
||||
void InterpVU1::Step()
|
||||
{
|
||||
VU1.VI[REG_TPC].UL &= VU1_PROGMASK;
|
||||
vu1Exec( &VU1 );
|
||||
}
|
||||
|
||||
|
@ -192,11 +184,11 @@ void InterpVU1::Execute(u32 cycles)
|
|||
for (int i = (int)cycles; i > 0 ; i--) {
|
||||
if (!(VU0.VI[REG_VPU_STAT].UL & 0x100)) {
|
||||
if (VU1.branch || VU1.ebit) {
|
||||
vu1Exec(&VU1); // run branch delay slot?
|
||||
Step(); // run branch delay slot?
|
||||
}
|
||||
break;
|
||||
}
|
||||
vu1Exec(&VU1);
|
||||
Step();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
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 "VUmicro.h"
|
||||
|
||||
__aligned16 VURegs vuRegs[2];
|
||||
|
||||
static u8* m_vuAllMem = NULL;
|
||||
static const uint m_vuMemSize =
|
||||
0x1000 + // VU0micro memory
|
||||
0x4000+0x800 + // VU0 memory and VU1 registers
|
||||
0x4000 + // VU0 memory
|
||||
0x4000 + // VU1 memory
|
||||
0x4000;
|
||||
|
||||
|
@ -33,12 +35,9 @@ void vuMicroMemAlloc()
|
|||
if( m_vuAllMem == NULL )
|
||||
throw Exception::OutOfMemory( L"VU0 and VU1 on-chip memory" );
|
||||
|
||||
pxAssume( sizeof( VURegs ) <= 0x800 );
|
||||
|
||||
u8* curpos = m_vuAllMem;
|
||||
VU0.Micro = curpos; curpos += 0x1000;
|
||||
VU0.Mem = curpos; curpos += 0x4000;
|
||||
g_pVU1 = (VURegs*)curpos; curpos += 0x800;
|
||||
VU1.Micro = curpos; curpos += 0x4000;
|
||||
VU1.Mem = curpos;
|
||||
//curpos += 0x4000;
|
||||
|
@ -50,7 +49,6 @@ void vuMicroMemShutdown()
|
|||
|
||||
vtlb_free( m_vuAllMem, m_vuMemSize );
|
||||
m_vuAllMem = NULL;
|
||||
g_pVU1 = NULL;
|
||||
}
|
||||
|
||||
void vuMicroMemReset()
|
||||
|
@ -72,17 +70,6 @@ void vuMicroMemReset()
|
|||
memzero_ptr<4*1024>(VU0.Mem);
|
||||
memzero_ptr<4*1024>(VU0.Micro);
|
||||
|
||||
/* this is kinda tricky, maxmem is set to 0x4400 here,
|
||||
tho it's not 100% accurate, since the mem goes from
|
||||
0x0000 - 0x1000 (Mem) and 0x4000 - 0x4400 (VU1 Regs),
|
||||
i guess it shouldn't be a problem,
|
||||
at least hope so :) (linuz)
|
||||
*/
|
||||
VU0.maxmem = 0x4800-4; //We are allocating 0x800 for vu1 reg's
|
||||
VU0.maxmicro = 0x1000-4;
|
||||
VU0.vuExec = vu0Exec;
|
||||
VU0.vifRegs = vif0Regs;
|
||||
|
||||
// === VU1 Initialization ===
|
||||
memzero(VU1.ACC);
|
||||
memzero(VU1.VF);
|
||||
|
@ -94,13 +81,6 @@ void vuMicroMemReset()
|
|||
VU1.VI[0].UL = 0;
|
||||
memzero_ptr<16*1024>(VU1.Mem);
|
||||
memzero_ptr<16*1024>(VU1.Micro);
|
||||
|
||||
VU1.maxmem = 0x4000-4;//16*1024-4;
|
||||
VU1.maxmicro = 0x4000-4;
|
||||
// VU1.VF = (VECTOR*)(VU0.Mem + 0x4000);
|
||||
// VU1.VI = (REG_VI*)(VU0.Mem + 0x4200);
|
||||
VU1.vuExec = vu1Exec;
|
||||
VU1.vifRegs = vif1Regs;
|
||||
}
|
||||
|
||||
void SaveStateBase::vuMicroFreeze()
|
||||
|
|
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)
|
||||
|
||||
struct _VURegsNum {
|
||||
u8 pipe; // if 0xff, COP2
|
||||
u8 VFwrite;
|
||||
u8 VFwxyzw;
|
||||
u8 VFr0xyzw;
|
||||
u8 VFr1xyzw;
|
||||
u8 VFread0;
|
||||
u8 VFread1;
|
||||
u32 VIwrite;
|
||||
u32 VIread;
|
||||
int cycles;
|
||||
};
|
||||
|
||||
#define __vuRegsCall __fastcall
|
||||
typedef void __vuRegsCall FnType_VuRegsN(_VURegsNum *VUregsn);
|
||||
typedef FnType_VuRegsN* Fnptr_VuRegsN;
|
||||
|
||||
extern __aligned16 const Fnptr_Void VU0_LOWER_OPCODE[128];
|
||||
extern __aligned16 const Fnptr_Void VU0_UPPER_OPCODE[64];
|
||||
extern __aligned16 const Fnptr_VuRegsN VU0regs_LOWER_OPCODE[128];
|
||||
extern __aligned16 const Fnptr_VuRegsN VU0regs_UPPER_OPCODE[64];
|
||||
|
||||
extern __aligned16 const Fnptr_Void VU1_LOWER_OPCODE[128];
|
||||
extern __aligned16 const Fnptr_Void VU1_UPPER_OPCODE[64];
|
||||
extern __aligned16 const Fnptr_VuRegsN VU1regs_LOWER_OPCODE[128];
|
||||
extern __aligned16 const Fnptr_VuRegsN VU1regs_UPPER_OPCODE[64];
|
||||
|
||||
extern void _vuTestPipes(VURegs * VU);
|
||||
extern void _vuTestUpperStalls(VURegs * VU, _VURegsNum *VUregsn);
|
||||
extern void _vuTestLowerStalls(VURegs * VU, _VURegsNum *VUregsn);
|
||||
extern void _vuAddUpperStalls(VURegs * VU, _VURegsNum *VUregsn);
|
||||
extern void _vuAddLowerStalls(VURegs * VU, _VURegsNum *VUregsn);
|
||||
|
||||
/******************************/
|
||||
/* VU Upper instructions */
|
||||
/******************************/
|
||||
|
||||
void _vuABS(VURegs * VU);
|
||||
void _vuADD(VURegs * VU);
|
||||
void _vuADDi(VURegs * VU);
|
||||
void _vuADDq(VURegs * VU);
|
||||
void _vuADDx(VURegs * VU);
|
||||
void _vuADDy(VURegs * VU);
|
||||
void _vuADDz(VURegs * VU);
|
||||
void _vuADDw(VURegs * VU);
|
||||
void _vuADDA(VURegs * VU);
|
||||
void _vuADDAi(VURegs * VU);
|
||||
void _vuADDAq(VURegs * VU);
|
||||
void _vuADDAx(VURegs * VU);
|
||||
void _vuADDAy(VURegs * VU);
|
||||
void _vuADDAz(VURegs * VU);
|
||||
void _vuADDAw(VURegs * VU);
|
||||
void _vuSUB(VURegs * VU);
|
||||
void _vuSUBi(VURegs * VU);
|
||||
void _vuSUBq(VURegs * VU);
|
||||
void _vuSUBx(VURegs * VU);
|
||||
void _vuSUBy(VURegs * VU);
|
||||
void _vuSUBz(VURegs * VU);
|
||||
void _vuSUBw(VURegs * VU);
|
||||
void _vuSUBA(VURegs * VU);
|
||||
void _vuSUBAi(VURegs * VU);
|
||||
void _vuSUBAq(VURegs * VU);
|
||||
void _vuSUBAx(VURegs * VU);
|
||||
void _vuSUBAy(VURegs * VU);
|
||||
void _vuSUBAz(VURegs * VU);
|
||||
void _vuSUBAw(VURegs * VU);
|
||||
void _vuMUL(VURegs * VU);
|
||||
void _vuMULi(VURegs * VU);
|
||||
void _vuMULq(VURegs * VU);
|
||||
void _vuMULx(VURegs * VU);
|
||||
void _vuMULy(VURegs * VU);
|
||||
void _vuMULz(VURegs * VU);
|
||||
void _vuMULw(VURegs * VU);
|
||||
void _vuMULA(VURegs * VU);
|
||||
void _vuMULAi(VURegs * VU);
|
||||
void _vuMULAq(VURegs * VU);
|
||||
void _vuMULAx(VURegs * VU);
|
||||
void _vuMULAy(VURegs * VU);
|
||||
void _vuMULAz(VURegs * VU);
|
||||
void _vuMULAw(VURegs * VU);
|
||||
void _vuMADD(VURegs * VU) ;
|
||||
void _vuMADDi(VURegs * VU);
|
||||
void _vuMADDq(VURegs * VU);
|
||||
void _vuMADDx(VURegs * VU);
|
||||
void _vuMADDy(VURegs * VU);
|
||||
void _vuMADDz(VURegs * VU);
|
||||
void _vuMADDw(VURegs * VU);
|
||||
void _vuMADDA(VURegs * VU);
|
||||
void _vuMADDAi(VURegs * VU);
|
||||
void _vuMADDAq(VURegs * VU);
|
||||
void _vuMADDAx(VURegs * VU);
|
||||
void _vuMADDAy(VURegs * VU);
|
||||
void _vuMADDAz(VURegs * VU);
|
||||
void _vuMADDAw(VURegs * VU);
|
||||
void _vuMSUB(VURegs * VU);
|
||||
void _vuMSUBi(VURegs * VU);
|
||||
void _vuMSUBq(VURegs * VU);
|
||||
void _vuMSUBx(VURegs * VU);
|
||||
void _vuMSUBy(VURegs * VU);
|
||||
void _vuMSUBz(VURegs * VU) ;
|
||||
void _vuMSUBw(VURegs * VU) ;
|
||||
void _vuMSUBA(VURegs * VU);
|
||||
void _vuMSUBAi(VURegs * VU);
|
||||
void _vuMSUBAq(VURegs * VU);
|
||||
void _vuMSUBAx(VURegs * VU);
|
||||
void _vuMSUBAy(VURegs * VU);
|
||||
void _vuMSUBAz(VURegs * VU);
|
||||
void _vuMSUBAw(VURegs * VU);
|
||||
void _vuMAX(VURegs * VU);
|
||||
void _vuMAXi(VURegs * VU);
|
||||
void _vuMAXx(VURegs * VU);
|
||||
void _vuMAXy(VURegs * VU);
|
||||
void _vuMAXz(VURegs * VU);
|
||||
void _vuMAXw(VURegs * VU);
|
||||
void _vuMINI(VURegs * VU);
|
||||
void _vuMINIi(VURegs * VU);
|
||||
void _vuMINIx(VURegs * VU);
|
||||
void _vuMINIy(VURegs * VU);
|
||||
void _vuMINIz(VURegs * VU);
|
||||
void _vuMINIw(VURegs * VU);
|
||||
void _vuOPMULA(VURegs * VU);
|
||||
void _vuOPMSUB(VURegs * VU);
|
||||
void _vuNOP(VURegs * VU);
|
||||
void _vuFTOI0(VURegs * VU);
|
||||
void _vuFTOI4(VURegs * VU);
|
||||
void _vuFTOI12(VURegs * VU);
|
||||
void _vuFTOI15(VURegs * VU);
|
||||
void _vuITOF0(VURegs * VU) ;
|
||||
void _vuITOF4(VURegs * VU) ;
|
||||
void _vuITOF12(VURegs * VU);
|
||||
void _vuITOF15(VURegs * VU);
|
||||
void _vuCLIP(VURegs * VU);
|
||||
/******************************/
|
||||
/* VU Lower instructions */
|
||||
/******************************/
|
||||
void _vuDIV(VURegs * VU);
|
||||
void _vuSQRT(VURegs * VU);
|
||||
void _vuRSQRT(VURegs * VU);
|
||||
void _vuIADDI(VURegs * VU);
|
||||
void _vuIADDIU(VURegs * VU);
|
||||
void _vuIADD(VURegs * VU);
|
||||
void _vuIAND(VURegs * VU);
|
||||
void _vuIOR(VURegs * VU);
|
||||
void _vuISUB(VURegs * VU);
|
||||
void _vuISUBIU(VURegs * VU);
|
||||
void _vuMOVE(VURegs * VU);
|
||||
void _vuMFIR(VURegs * VU);
|
||||
void _vuMTIR(VURegs * VU);
|
||||
void _vuMR32(VURegs * VU);
|
||||
void _vuLQ(VURegs * VU) ;
|
||||
void _vuLQD(VURegs * VU);
|
||||
void _vuLQI(VURegs * VU);
|
||||
void _vuSQ(VURegs * VU);
|
||||
void _vuSQD(VURegs * VU);
|
||||
void _vuSQI(VURegs * VU);
|
||||
void _vuILW(VURegs * VU);
|
||||
void _vuISW(VURegs * VU);
|
||||
void _vuILWR(VURegs * VU);
|
||||
void _vuISWR(VURegs * VU);
|
||||
void _vuLOI(VURegs * VU);
|
||||
void _vuRINIT(VURegs * VU);
|
||||
void _vuRGET(VURegs * VU);
|
||||
void _vuRNEXT(VURegs * VU);
|
||||
void _vuRXOR(VURegs * VU);
|
||||
void _vuWAITQ(VURegs * VU);
|
||||
void _vuFSAND(VURegs * VU);
|
||||
void _vuFSEQ(VURegs * VU);
|
||||
void _vuFSOR(VURegs * VU);
|
||||
void _vuFSSET(VURegs * VU);
|
||||
void _vuFMAND(VURegs * VU);
|
||||
void _vuFMEQ(VURegs * VU);
|
||||
void _vuFMOR(VURegs * VU);
|
||||
void _vuFCAND(VURegs * VU);
|
||||
void _vuFCEQ(VURegs * VU);
|
||||
void _vuFCOR(VURegs * VU);
|
||||
void _vuFCSET(VURegs * VU);
|
||||
void _vuFCGET(VURegs * VU);
|
||||
void _vuIBEQ(VURegs * VU);
|
||||
void _vuIBGEZ(VURegs * VU);
|
||||
void _vuIBGTZ(VURegs * VU);
|
||||
void _vuIBLEZ(VURegs * VU);
|
||||
void _vuIBLTZ(VURegs * VU);
|
||||
void _vuIBNE(VURegs * VU);
|
||||
void _vuB(VURegs * VU);
|
||||
void _vuBAL(VURegs * VU);
|
||||
void _vuJR(VURegs * VU);
|
||||
void _vuJALR(VURegs * VU);
|
||||
void _vuMFP(VURegs * VU);
|
||||
void _vuWAITP(VURegs * VU);
|
||||
void _vuESADD(VURegs * VU);
|
||||
void _vuERSADD(VURegs * VU);
|
||||
void _vuELENG(VURegs * VU);
|
||||
void _vuERLENG(VURegs * VU);
|
||||
void _vuEATANxy(VURegs * VU);
|
||||
void _vuEATANxz(VURegs * VU);
|
||||
void _vuESUM(VURegs * VU);
|
||||
void _vuERCPR(VURegs * VU);
|
||||
void _vuESQRT(VURegs * VU);
|
||||
void _vuERSQRT(VURegs * VU);
|
||||
void _vuESIN(VURegs * VU);
|
||||
void _vuEATAN(VURegs * VU);
|
||||
void _vuEEXP(VURegs * VU);
|
||||
void _vuXITOP(VURegs * VU);
|
||||
void _vuXGKICK(VURegs * VU);
|
||||
void _vuXTOP(VURegs * VU);
|
||||
|
||||
/******************************/
|
||||
/* VU Upper instructions */
|
||||
/******************************/
|
||||
|
||||
void _vuRegsABS(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsADD(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsADDi(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsADDq(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsADDx(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsADDy(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsADDz(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsADDw(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsADDA(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsADDAi(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsADDAq(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsADDAx(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsADDAy(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsADDAz(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsADDAw(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsSUB(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsSUBi(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsSUBq(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsSUBx(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsSUBy(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsSUBz(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsSUBw(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsSUBA(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsSUBAi(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsSUBAq(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsSUBAx(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsSUBAy(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsSUBAz(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsSUBAw(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsMUL(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsMULi(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsMULq(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsMULx(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsMULy(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsMULz(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsMULw(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsMULA(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsMULAi(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsMULAq(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsMULAx(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsMULAy(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsMULAz(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsMULAw(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsMADD(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsMADDi(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsMADDq(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsMADDx(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsMADDy(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsMADDz(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsMADDw(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsMADDA(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsMADDAi(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsMADDAq(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsMADDAx(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsMADDAy(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsMADDAz(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsMADDAw(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsMSUB(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsMSUBi(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsMSUBq(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsMSUBx(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsMSUBy(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsMSUBz(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsMSUBw(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsMSUBA(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsMSUBAi(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsMSUBAq(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsMSUBAx(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsMSUBAy(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsMSUBAz(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsMSUBAw(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsMAX(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsMAXi(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsMAXx(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsMAXy(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsMAXz(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsMAXw(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsMINI(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsMINIi(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsMINIx(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsMINIy(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsMINIz(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsMINIw(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsOPMULA(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsOPMSUB(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsNOP(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsFTOI0(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsFTOI4(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsFTOI12(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsFTOI15(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsITOF0(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsITOF4(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsITOF12(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsITOF15(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsCLIP(VURegs * VU, _VURegsNum *VUregsn);
|
||||
/******************************/
|
||||
/* VU Lower instructions */
|
||||
/******************************/
|
||||
void _vuRegsDIV(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsSQRT(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsRSQRT(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsIADDI(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsIADDIU(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsIADD(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsIAND(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsIOR(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsISUB(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsISUBIU(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsMOVE(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsMFIR(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsMTIR(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsMR32(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsLQ(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsLQD(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsLQI(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsSQ(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsSQD(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsSQI(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsILW(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsISW(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsILWR(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsISWR(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsLOI(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsRINIT(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsRGET(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsRNEXT(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsRXOR(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsWAITQ(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsFSAND(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsFSEQ(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsFSOR(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsFSSET(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsFMAND(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsFMEQ(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsFMOR(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsFCAND(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsFCEQ(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsFCOR(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsFCSET(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsFCGET(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsIBEQ(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsIBGEZ(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsIBGTZ(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsIBLEZ(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsIBLTZ(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsIBNE(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsB(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsBAL(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsJR(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsJALR(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsMFP(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsWAITP(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsESADD(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsERSADD(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsELENG(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsERLENG(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsEATANxy(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsEATANxz(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsESUM(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsERCPR(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsESQRT(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsERSQRT(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsESIN(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsEATAN(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsEEXP(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsXITOP(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsXGKICK(VURegs * VU, _VURegsNum *VUregsn);
|
||||
void _vuRegsXTOP(VURegs * VU, _VURegsNum *VUregsn);
|
||||
|
|
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 */
|
||||
memzero(vif0);
|
||||
memzero(*vif0Regs);
|
||||
memzero(vif0Regs);
|
||||
|
||||
psHu64(VIF0_FIFO) = 0;
|
||||
psHu64(VIF0_FIFO + 8) = 0;
|
||||
|
||||
vif0Regs->stat.VPS = VPS_IDLE;
|
||||
vif0Regs->stat.FQC = 0;
|
||||
vif0Regs.stat.VPS = VPS_IDLE;
|
||||
vif0Regs.stat.FQC = 0;
|
||||
|
||||
vif0.done = false;
|
||||
|
||||
|
@ -46,13 +46,13 @@ void vif1Reset()
|
|||
{
|
||||
/* Reset the whole VIF, meaning the internal pcsx2 vars, and all the registers */
|
||||
memzero(vif1);
|
||||
memzero(*vif1Regs);
|
||||
memzero(vif1Regs);
|
||||
|
||||
psHu64(VIF1_FIFO) = 0;
|
||||
psHu64(VIF1_FIFO + 8) = 0;
|
||||
|
||||
vif1Regs->stat.VPS = VPS_IDLE;
|
||||
vif1Regs->stat.FQC = 0; // FQC=0
|
||||
vif1Regs.stat.VPS = VPS_IDLE;
|
||||
vif1Regs.stat.FQC = 0; // FQC=0
|
||||
|
||||
vif1.done = false;
|
||||
cpuRegs.interrupt &= ~((1 << 1) | (1 << 10)); //Stop all vif1 DMA's
|
||||
|
@ -91,16 +91,16 @@ __fi void vif0FBRST(u32 value) {
|
|||
|
||||
if (value & 0x1) // Reset Vif.
|
||||
{
|
||||
//Console.WriteLn("Vif0 Reset %x", vif0Regs->stat._u32);
|
||||
//Console.WriteLn("Vif0 Reset %x", vif0Regs.stat._u32);
|
||||
|
||||
memzero(vif0);
|
||||
vif0ch->qwc = 0; //?
|
||||
vif0ch.qwc = 0; //?
|
||||
cpuRegs.interrupt &= ~1; //Stop all vif0 DMA's
|
||||
psHu64(VIF0_FIFO) = 0;
|
||||
psHu64(VIF0_FIFO + 8) = 0;
|
||||
vif0.done = false;
|
||||
vif0Regs->err.reset();
|
||||
vif0Regs->stat.clear_flags(VIF0_STAT_FQC | VIF0_STAT_INT | VIF0_STAT_VSS | VIF0_STAT_VIS | VIF0_STAT_VFS | VIF0_STAT_VPS); // FQC=0
|
||||
vif0Regs.err.reset();
|
||||
vif0Regs.stat.clear_flags(VIF0_STAT_FQC | VIF0_STAT_INT | VIF0_STAT_VSS | VIF0_STAT_VIS | VIF0_STAT_VFS | VIF0_STAT_VPS); // FQC=0
|
||||
}
|
||||
|
||||
/* Fixme: Forcebreaks are pretty unknown for operation, presumption is it just stops it what its doing
|
||||
|
@ -109,8 +109,8 @@ __fi void vif0FBRST(u32 value) {
|
|||
{
|
||||
/* I guess we should stop the VIF dma here, but not 100% sure (linuz) */
|
||||
cpuRegs.interrupt &= ~1; //Stop all vif0 DMA's
|
||||
vif0Regs->stat.VFS = true;
|
||||
vif0Regs->stat.VPS = VPS_IDLE;
|
||||
vif0Regs.stat.VFS = true;
|
||||
vif0Regs.stat.VPS = VPS_IDLE;
|
||||
Console.WriteLn("vif0 force break");
|
||||
}
|
||||
|
||||
|
@ -118,8 +118,8 @@ __fi void vif0FBRST(u32 value) {
|
|||
{
|
||||
// Not completely sure about this, can't remember what game, used this, but 'draining' the VIF helped it, instead of
|
||||
// just stoppin the VIF (linuz).
|
||||
vif0Regs->stat.VSS = true;
|
||||
vif0Regs->stat.VPS = VPS_IDLE;
|
||||
vif0Regs.stat.VSS = true;
|
||||
vif0Regs.stat.VPS = VPS_IDLE;
|
||||
vif0.vifstalled = true;
|
||||
}
|
||||
|
||||
|
@ -128,10 +128,10 @@ __fi void vif0FBRST(u32 value) {
|
|||
bool cancel = false;
|
||||
|
||||
/* Cancel stall, first check if there is a stall to cancel, and then clear VIF0_STAT VSS|VFS|VIS|INT|ER0|ER1 bits */
|
||||
if (vif0Regs->stat.test(VIF0_STAT_VSS | VIF0_STAT_VIS | VIF0_STAT_VFS))
|
||||
if (vif0Regs.stat.test(VIF0_STAT_VSS | VIF0_STAT_VIS | VIF0_STAT_VFS))
|
||||
cancel = true;
|
||||
|
||||
vif0Regs->stat.clear_flags(VIF0_STAT_VSS | VIF0_STAT_VFS | VIF0_STAT_VIS |
|
||||
vif0Regs.stat.clear_flags(VIF0_STAT_VSS | VIF0_STAT_VFS | VIF0_STAT_VIS |
|
||||
VIF0_STAT_INT | VIF0_STAT_ER0 | VIF0_STAT_ER1);
|
||||
if (cancel)
|
||||
{
|
||||
|
@ -140,8 +140,8 @@ __fi void vif0FBRST(u32 value) {
|
|||
g_vifCycles = 0;
|
||||
|
||||
// loop necessary for spiderman
|
||||
//vif0ch->chcr.STR = true;
|
||||
if(vif0ch->chcr.STR) CPU_INT(DMAC_VIF0, 0); // Gets the timing right - Flatout
|
||||
//vif0ch.chcr.STR = true;
|
||||
if(vif0ch.chcr.STR) CPU_INT(DMAC_VIF0, 0); // Gets the timing right - Flatout
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -154,29 +154,29 @@ __fi void vif1FBRST(u32 value) {
|
|||
{
|
||||
memzero(vif1);
|
||||
//cpuRegs.interrupt &= ~((1 << 1) | (1 << 10)); //Stop all vif1 DMA's
|
||||
vif1ch->qwc -= min((int)vif1ch->qwc, 16); //?
|
||||
vif1ch.qwc -= min((int)vif1ch.qwc, 16); //?
|
||||
psHu64(VIF1_FIFO) = 0;
|
||||
psHu64(VIF1_FIFO + 8) = 0;
|
||||
//vif1.done = false;
|
||||
|
||||
|
||||
//DevCon.Warning("VIF FBRST Reset MSK = %x", vif1Regs->mskpath3);
|
||||
if(vif1Regs->mskpath3 == 1 && GSTransferStatus.PTH3 == STOPPED_MODE && gif->chcr.STR == true)
|
||||
//DevCon.Warning("VIF FBRST Reset MSK = %x", vif1Regs.mskpath3);
|
||||
if(vif1Regs.mskpath3 == 1 && GSTransferStatus.PTH3 == STOPPED_MODE && gifch.chcr.STR == true)
|
||||
{
|
||||
//DevCon.Warning("VIF Path3 Resume on FBRST MSK = %x", vif1Regs->mskpath3);
|
||||
//DevCon.Warning("VIF Path3 Resume on FBRST MSK = %x", vif1Regs.mskpath3);
|
||||
gsInterrupt();
|
||||
vif1Regs->mskpath3 = false;
|
||||
gifRegs->stat.M3P = 0;
|
||||
vif1Regs.mskpath3 = false;
|
||||
gifRegs.stat.M3P = 0;
|
||||
}
|
||||
|
||||
vif1Regs->mskpath3 = false;
|
||||
gifRegs->stat.M3P = 0;
|
||||
vif1Regs->err.reset();
|
||||
vif1Regs.mskpath3 = false;
|
||||
gifRegs.stat.M3P = 0;
|
||||
vif1Regs.err.reset();
|
||||
vif1.inprogress = 0;
|
||||
vif1.cmd = 0;
|
||||
vif1.vifstalled = false;
|
||||
vif1Regs->stat.FQC = 0;
|
||||
vif1Regs->stat.clear_flags(VIF1_STAT_FDR | VIF1_STAT_INT | VIF1_STAT_VSS | VIF1_STAT_VIS | VIF1_STAT_VFS | VIF1_STAT_VPS);
|
||||
vif1Regs.stat.FQC = 0;
|
||||
vif1Regs.stat.clear_flags(VIF1_STAT_FDR | VIF1_STAT_INT | VIF1_STAT_VSS | VIF1_STAT_VIS | VIF1_STAT_VFS | VIF1_STAT_VPS);
|
||||
}
|
||||
|
||||
/* Fixme: Forcebreaks are pretty unknown for operation, presumption is it just stops it what its doing
|
||||
|
@ -185,8 +185,8 @@ __fi void vif1FBRST(u32 value) {
|
|||
if (FBRST(value).FBK) // Forcebreak Vif.
|
||||
{
|
||||
/* I guess we should stop the VIF dma here, but not 100% sure (linuz) */
|
||||
vif1Regs->stat.VFS = true;
|
||||
vif1Regs->stat.VPS = VPS_IDLE;
|
||||
vif1Regs.stat.VFS = true;
|
||||
vif1Regs.stat.VPS = VPS_IDLE;
|
||||
cpuRegs.interrupt &= ~((1 << 1) | (1 << 10)); //Stop all vif1 DMA's
|
||||
Console.WriteLn("vif1 force break");
|
||||
}
|
||||
|
@ -195,8 +195,8 @@ __fi void vif1FBRST(u32 value) {
|
|||
{
|
||||
// Not completely sure about this, can't remember what game used this, but 'draining' the VIF helped it, instead of
|
||||
// just stoppin the VIF (linuz).
|
||||
vif1Regs->stat.VSS = true;
|
||||
vif1Regs->stat.VPS = VPS_IDLE;
|
||||
vif1Regs.stat.VSS = true;
|
||||
vif1Regs.stat.VPS = VPS_IDLE;
|
||||
cpuRegs.interrupt &= ~((1 << 1) | (1 << 10)); //Stop all vif1 DMA's
|
||||
vif1.vifstalled = true;
|
||||
}
|
||||
|
@ -206,12 +206,12 @@ __fi void vif1FBRST(u32 value) {
|
|||
bool cancel = false;
|
||||
|
||||
/* Cancel stall, first check if there is a stall to cancel, and then clear VIF1_STAT VSS|VFS|VIS|INT|ER0|ER1 bits */
|
||||
if (vif1Regs->stat.test(VIF1_STAT_VSS | VIF1_STAT_VIS | VIF1_STAT_VFS))
|
||||
if (vif1Regs.stat.test(VIF1_STAT_VSS | VIF1_STAT_VIS | VIF1_STAT_VFS))
|
||||
{
|
||||
cancel = true;
|
||||
}
|
||||
|
||||
vif1Regs->stat.clear_flags(VIF1_STAT_VSS | VIF1_STAT_VFS | VIF1_STAT_VIS |
|
||||
vif1Regs.stat.clear_flags(VIF1_STAT_VSS | VIF1_STAT_VFS | VIF1_STAT_VIS |
|
||||
VIF1_STAT_INT | VIF1_STAT_ER0 | VIF1_STAT_ER1);
|
||||
|
||||
if (cancel)
|
||||
|
@ -220,22 +220,22 @@ __fi void vif1FBRST(u32 value) {
|
|||
{
|
||||
g_vifCycles = 0;
|
||||
// loop necessary for spiderman
|
||||
switch(dmacRegs->ctrl.MFD)
|
||||
switch(dmacRegs.ctrl.MFD)
|
||||
{
|
||||
case MFD_VIF1:
|
||||
//Console.WriteLn("MFIFO Stall");
|
||||
if(vif1ch->chcr.STR == true) CPU_INT(DMAC_MFIFO_VIF, 0);
|
||||
if(vif1ch.chcr.STR == true) CPU_INT(DMAC_MFIFO_VIF, 0);
|
||||
break;
|
||||
|
||||
case NO_MFD:
|
||||
case MFD_RESERVED:
|
||||
case MFD_GIF: // Wonder if this should be with VIF?
|
||||
// Gets the timing right - Flatout
|
||||
if(vif1ch->chcr.STR == true) CPU_INT(DMAC_VIF1, 0);
|
||||
if(vif1ch.chcr.STR == true) CPU_INT(DMAC_VIF1, 0);
|
||||
break;
|
||||
}
|
||||
|
||||
//vif1ch->chcr.STR = true;
|
||||
//vif1ch.chcr.STR = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -245,16 +245,16 @@ __fi void vif1STAT(u32 value) {
|
|||
VIF_LOG("VIF1_STAT write32 0x%8.8x", value);
|
||||
|
||||
/* Only FDR bit is writable, so mask the rest */
|
||||
if ((vif1Regs->stat.FDR) ^ ((tVIF_STAT&)value).FDR) {
|
||||
if ((vif1Regs.stat.FDR) ^ ((tVIF_STAT&)value).FDR) {
|
||||
// different so can't be stalled
|
||||
if (vif1Regs->stat.test(VIF1_STAT_INT | VIF1_STAT_VSS | VIF1_STAT_VIS | VIF1_STAT_VFS)) {
|
||||
if (vif1Regs.stat.test(VIF1_STAT_INT | VIF1_STAT_VSS | VIF1_STAT_VIS | VIF1_STAT_VFS)) {
|
||||
DevCon.WriteLn("changing dir when vif1 fifo stalled");
|
||||
}
|
||||
}
|
||||
|
||||
vif1Regs->stat.FDR = VIF_STAT(value).FDR;
|
||||
vif1Regs.stat.FDR = VIF_STAT(value).FDR;
|
||||
|
||||
if (vif1Regs->stat.FDR) // Vif transferring to memory.
|
||||
if (vif1Regs.stat.FDR) // Vif transferring to memory.
|
||||
{
|
||||
// Hack but it checks this is true before transfer? (fatal frame)
|
||||
// Update Refraction: Use of this function has been investigated and understood.
|
||||
|
@ -263,7 +263,7 @@ __fi void vif1STAT(u32 value) {
|
|||
// As far as the GS is concerned, the transfer starts as soon as TRXDIR is accessed, which is why fatal frame
|
||||
// was expecting data, the GS should already be sending it over (buffering in the FIFO)
|
||||
|
||||
vif1Regs->stat.FQC = min((u32)16, vif1.GSLastDownloadSize);
|
||||
vif1Regs.stat.FQC = min((u32)16, vif1.GSLastDownloadSize);
|
||||
//Console.Warning("Reversing VIF Transfer for %x QWC", vif1.GSLastDownloadSize);
|
||||
|
||||
}
|
||||
|
@ -271,69 +271,65 @@ __fi void vif1STAT(u32 value) {
|
|||
{
|
||||
//Sometimes the value from the GS is bigger than vif wanted, so it just sets it back and cancels it.
|
||||
//Other times it can read it off ;)
|
||||
vif1Regs->stat.FQC = 0;
|
||||
vif1Regs.stat.FQC = 0;
|
||||
}
|
||||
}
|
||||
|
||||
#define caseVif(x) (idx ? VIF1_##x : VIF0_##x)
|
||||
|
||||
_vifT void vifWrite32(u32 mem, u32 value) {
|
||||
// returns FALSE if no writeback is needed (or writeback is handled internally)
|
||||
// returns TRUE if the caller should writeback the value to the eeHw register map.
|
||||
_vifT __fi bool vifWrite32(u32 mem, u32 value) {
|
||||
switch (mem) {
|
||||
case caseVif(MARK):
|
||||
VIF_LOG("VIF%d_MARK write32 0x%8.8x", idx, value);
|
||||
vifXRegs->stat.MRK = false;
|
||||
vifXRegs->mark = value;
|
||||
break;
|
||||
vifXRegs.stat.MRK = false;
|
||||
//vifXRegs.mark = value;
|
||||
break;
|
||||
|
||||
case caseVif(FBRST):
|
||||
if (!idx) vif0FBRST(value);
|
||||
else vif1FBRST(value);
|
||||
break;
|
||||
|
||||
case caseVif(ERR):
|
||||
VIF_LOG("VIF%d_ERR write32 0x%8.8x", idx, value);
|
||||
vifXRegs->err.write(value);
|
||||
break;
|
||||
return false;
|
||||
|
||||
case caseVif(STAT):
|
||||
if (idx) { // Only Vif1 does this stuff?
|
||||
vif1STAT(value);
|
||||
}
|
||||
else {
|
||||
Console.WriteLn("Unknown Vif%d write to %x", idx, mem);
|
||||
psHu32(mem) = value;
|
||||
}
|
||||
break;
|
||||
return false;
|
||||
|
||||
case caseVif(ERR):
|
||||
case caseVif(MODE):
|
||||
vifXRegs->mode = value;
|
||||
break;
|
||||
// standard register writes -- handled by caller.
|
||||
break;
|
||||
|
||||
case caseVif(R0):
|
||||
case caseVif(R1):
|
||||
case caseVif(R2):
|
||||
case caseVif(R3):
|
||||
if (!idx) g_vifmask.Row0[ (mem>>4)&3 ] = value;
|
||||
else g_vifmask.Row1[ (mem>>4)&3 ] = value;
|
||||
((u32*)&vifXRegs->r0) [((mem>>4)&3)*4] = value;
|
||||
break;
|
||||
case caseVif(ROW0):
|
||||
case caseVif(ROW1):
|
||||
case caseVif(ROW2):
|
||||
case caseVif(ROW3):
|
||||
// Here's a neat way to obfuscate code. This is a super-fancy-complicated version
|
||||
// of a standard psHu32(mem) = value; writeback. Handled by caller for us, thanks! --air
|
||||
//if (!idx) g_vifmask.Row0[ (mem>>4)&3 ] = value;
|
||||
//else g_vifmask.Row1[ (mem>>4)&3 ] = value;
|
||||
//((u32*)&vifXRegs.r0) [((mem>>4)&3)*4] = value;
|
||||
break;
|
||||
|
||||
case caseVif(C0):
|
||||
case caseVif(C1):
|
||||
case caseVif(C2):
|
||||
case caseVif(C3):
|
||||
if (!idx) g_vifmask.Col0[ (mem>>4)&3 ] = value;
|
||||
else g_vifmask.Col1[ (mem>>4)&3 ] = value;
|
||||
((u32*)&vifXRegs->c0) [((mem>>4)&3)*4] = value;
|
||||
break;
|
||||
|
||||
default:
|
||||
Console.WriteLn("Unknown Vif%d write to %x", idx, mem);
|
||||
psHu32(mem) = value;
|
||||
break;
|
||||
case caseVif(COL0):
|
||||
case caseVif(COL1):
|
||||
case caseVif(COL2):
|
||||
case caseVif(COL3):
|
||||
// Here's a neat way to obfuscate code. This is a super-fancy-complicated version
|
||||
// of a standard psHu32(mem) = value; writeback. Handled by caller for us, thanks! --air
|
||||
//if (!idx) g_vifmask.Col0[ (mem>>4)&3 ] = value;
|
||||
//else g_vifmask.Col1[ (mem>>4)&3 ] = value;
|
||||
//((u32*)&vifXRegs.c0) [((mem>>4)&3)*4] = value;
|
||||
break;
|
||||
}
|
||||
/* Other registers are read-only so do nothing for them */
|
||||
|
||||
// fall-through case: issue standard writeback behavior.
|
||||
return true;
|
||||
}
|
||||
|
||||
void vif0Write32(u32 mem, u32 value) { vifWrite32<0>(mem, value); }
|
||||
void vif1Write32(u32 mem, u32 value) { vifWrite32<1>(mem, value); }
|
||||
|
||||
template bool vifWrite32<0>(u32 mem, u32 value);
|
||||
template bool vifWrite32<1>(u32 mem, u32 value);
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "MemoryTypes.h"
|
||||
#include "R5900.h"
|
||||
|
||||
enum vif0_stat_flags
|
||||
|
@ -214,10 +215,8 @@ struct VIFregisters {
|
|||
|
||||
extern VIFregisters *vifRegs;
|
||||
|
||||
#define vif0RegsRef ((VIFregisters&)eeMem->HW[0x3800])
|
||||
#define vif1RegsRef ((VIFregisters&)eeMem->HW[0x3c00])
|
||||
#define vif0Regs (&vif0RegsRef)
|
||||
#define vif1Regs (&vif1RegsRef)
|
||||
static VIFregisters& vif0Regs = (VIFregisters&)eeHw[0x3800];
|
||||
static VIFregisters& vif1Regs = (VIFregisters&)eeHw[0x3C00];
|
||||
|
||||
#define _vifT template <int idx>
|
||||
#define GetVifX (idx ? (vif1) : (vif0))
|
||||
|
|
|
@ -54,28 +54,28 @@ bool _VIF0chain()
|
|||
{
|
||||
u32 *pMem;
|
||||
|
||||
if (vif0ch->qwc == 0)
|
||||
if (vif0ch.qwc == 0)
|
||||
{
|
||||
vif0.inprogress = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
pMem = (u32*)dmaGetAddr(vif0ch->madr, false);
|
||||
pMem = (u32*)dmaGetAddr(vif0ch.madr, false);
|
||||
if (pMem == NULL)
|
||||
{
|
||||
vif0.cmd = 0;
|
||||
vif0.tag.size = 0;
|
||||
vif0ch->qwc = 0;
|
||||
vif0ch.qwc = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
VIF_LOG("VIF0chain size=%d, madr=%lx, tadr=%lx",
|
||||
vif0ch->qwc, vif0ch->madr, vif0ch->tadr);
|
||||
vif0ch.qwc, vif0ch.madr, vif0ch.tadr);
|
||||
|
||||
if (vif0.vifstalled)
|
||||
return VIF0transfer(pMem + vif0.irqoffset, vif0ch->qwc * 4 - vif0.irqoffset);
|
||||
return VIF0transfer(pMem + vif0.irqoffset, vif0ch.qwc * 4 - vif0.irqoffset);
|
||||
else
|
||||
return VIF0transfer(pMem, vif0ch->qwc * 4);
|
||||
return VIF0transfer(pMem, vif0ch.qwc * 4);
|
||||
}
|
||||
|
||||
__fi void vif0SetupTransfer()
|
||||
|
@ -91,21 +91,21 @@ __fi void vif0SetupTransfer()
|
|||
break;
|
||||
|
||||
case VIF_CHAIN_MODE:
|
||||
ptag = dmaGetAddr(vif0ch->tadr, false); //Set memory pointer to TADR
|
||||
ptag = dmaGetAddr(vif0ch.tadr, false); //Set memory pointer to TADR
|
||||
|
||||
if (!(vif0ch->transfer("vif0 Tag", ptag))) return;
|
||||
if (!(vif0ch.transfer("vif0 Tag", ptag))) return;
|
||||
|
||||
vif0ch->madr = ptag[1]._u32; //MADR = ADDR field + SPR
|
||||
vif0ch.madr = ptag[1]._u32; //MADR = ADDR field + SPR
|
||||
g_vifCycles += 1; // Add 1 g_vifCycles from the QW read for the tag
|
||||
|
||||
// Transfer dma tag if tte is set
|
||||
|
||||
VIF_LOG("vif0 Tag %8.8x_%8.8x size=%d, id=%d, madr=%lx, tadr=%lx",
|
||||
ptag[1]._u32, ptag[0]._u32, vif0ch->qwc, ptag->ID, vif0ch->madr, vif0ch->tadr);
|
||||
ptag[1]._u32, ptag[0]._u32, vif0ch.qwc, ptag->ID, vif0ch.madr, vif0ch.tadr);
|
||||
|
||||
vif0.inprogress = 0;
|
||||
|
||||
if (vif0ch->chcr.TTE)
|
||||
if (vif0ch.chcr.TTE)
|
||||
{
|
||||
bool ret;
|
||||
|
||||
|
@ -124,9 +124,9 @@ __fi void vif0SetupTransfer()
|
|||
vif0.irqoffset = 0;
|
||||
vif0.done |= hwDmacSrcChainWithStack(vif0ch, ptag->ID);
|
||||
|
||||
if(vif0ch->qwc > 0) vif0.inprogress = 1;
|
||||
if(vif0ch.qwc > 0) vif0.inprogress = 1;
|
||||
//Check TIE bit of CHCR and IRQ bit of tag
|
||||
if (vif0ch->chcr.TIE && ptag->IRQ)
|
||||
if (vif0ch.chcr.TIE && ptag->IRQ)
|
||||
{
|
||||
VIF_LOG("dmaIrq Set");
|
||||
|
||||
|
@ -144,29 +144,29 @@ __fi void vif0Interrupt()
|
|||
|
||||
g_vifCycles = 0;
|
||||
|
||||
if (!(vif0ch->chcr.STR)) Console.WriteLn("vif0 running when CHCR == %x", vif0ch->chcr._u32);
|
||||
if (!(vif0ch.chcr.STR)) Console.WriteLn("vif0 running when CHCR == %x", vif0ch.chcr._u32);
|
||||
|
||||
if (vif0.cmd)
|
||||
{
|
||||
if(vif0.done == true && vif0ch->qwc == 0) vif0Regs->stat.VPS = VPS_WAITING;
|
||||
if(vif0.done == true && vif0ch.qwc == 0) vif0Regs.stat.VPS = VPS_WAITING;
|
||||
}
|
||||
else
|
||||
{
|
||||
vif0Regs->stat.VPS = VPS_IDLE;
|
||||
vif0Regs.stat.VPS = VPS_IDLE;
|
||||
}
|
||||
|
||||
if (vif0.irq && vif0.tag.size == 0)
|
||||
{
|
||||
vif0Regs->stat.INT = true;
|
||||
vif0Regs.stat.INT = true;
|
||||
hwIntcIrq(VIF0intc);
|
||||
--vif0.irq;
|
||||
if (vif0Regs->stat.test(VIF0_STAT_VSS | VIF0_STAT_VIS | VIF0_STAT_VFS))
|
||||
if (vif0Regs.stat.test(VIF0_STAT_VSS | VIF0_STAT_VIS | VIF0_STAT_VFS))
|
||||
{
|
||||
vif0Regs->stat.FQC = 0;
|
||||
vif0Regs.stat.FQC = 0;
|
||||
|
||||
// One game doesn't like vif stalling at end, can't remember what. Spiderman isn't keen on it tho
|
||||
//vif0ch->chcr.STR = false;
|
||||
if(vif0ch->qwc > 0 || !vif0.done) return;
|
||||
//vif0ch.chcr.STR = false;
|
||||
if(vif0ch.qwc > 0 || !vif0.done) return;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -180,7 +180,7 @@ __fi void vif0Interrupt()
|
|||
if (!vif0.done)
|
||||
{
|
||||
|
||||
if (!(dmacRegs->ctrl.DMAE))
|
||||
if (!(dmacRegs.ctrl.DMAE))
|
||||
{
|
||||
Console.WriteLn("vif0 dma masked");
|
||||
return;
|
||||
|
@ -199,22 +199,22 @@ __fi void vif0Interrupt()
|
|||
return; //Dont want to end if vif is stalled.
|
||||
}
|
||||
#ifdef PCSX2_DEVBUILD
|
||||
if (vif0ch->qwc > 0) Console.WriteLn("vif0 Ending with %x QWC left");
|
||||
if (vif0ch.qwc > 0) Console.WriteLn("vif0 Ending with %x QWC left");
|
||||
if (vif0.cmd != 0) Console.WriteLn("vif0.cmd still set %x tag size %x", vif0.cmd, vif0.tag.size);
|
||||
#endif
|
||||
|
||||
vif0ch->chcr.STR = false;
|
||||
vif0ch.chcr.STR = false;
|
||||
g_vifCycles = 0;
|
||||
hwDmacIrq(DMAC_VIF0);
|
||||
vif0Regs->stat.FQC = 0;
|
||||
vif0Regs.stat.FQC = 0;
|
||||
}
|
||||
|
||||
void dmaVIF0()
|
||||
{
|
||||
VIF_LOG("dmaVIF0 chcr = %lx, madr = %lx, qwc = %lx\n"
|
||||
" tadr = %lx, asr0 = %lx, asr1 = %lx",
|
||||
vif0ch->chcr._u32, vif0ch->madr, vif0ch->qwc,
|
||||
vif0ch->tadr, vif0ch->asr0, vif0ch->asr1);
|
||||
vif0ch.chcr._u32, vif0ch.madr, vif0ch.qwc,
|
||||
vif0ch.tadr, vif0ch.asr0, vif0ch.asr1);
|
||||
|
||||
g_vifCycles = 0;
|
||||
g_vu0Cycles = 0;
|
||||
|
@ -224,18 +224,18 @@ void dmaVIF0()
|
|||
vif0.inprogress = 0;
|
||||
vif0.done = false;*/
|
||||
|
||||
if ((vif0ch->chcr.MOD == NORMAL_MODE) || vif0ch->qwc > 0) // Normal Mode
|
||||
if ((vif0ch.chcr.MOD == NORMAL_MODE) || vif0ch.qwc > 0) // Normal Mode
|
||||
{
|
||||
vif0.dmamode = VIF_NORMAL_TO_MEM_MODE;
|
||||
|
||||
vif0.done = false;
|
||||
|
||||
if(vif0ch->chcr.MOD == CHAIN_MODE && vif0ch->qwc > 0)
|
||||
if(vif0ch.chcr.MOD == CHAIN_MODE && vif0ch.qwc > 0)
|
||||
{
|
||||
vif0.dmamode = VIF_CHAIN_MODE;
|
||||
DevCon.Warning(L"VIF0 QWC on Chain CHCR " + vif0ch->chcr.desc());
|
||||
DevCon.Warning(L"VIF0 QWC on Chain CHCR " + vif0ch.chcr.desc());
|
||||
|
||||
if ((vif0ch->chcr.tag().ID == TAG_REFE) || (vif0ch->chcr.tag().ID == TAG_END))
|
||||
if ((vif0ch.chcr.tag().ID == TAG_REFE) || (vif0ch.chcr.tag().ID == TAG_END))
|
||||
{
|
||||
vif0.done = true;
|
||||
}
|
||||
|
@ -247,7 +247,7 @@ void dmaVIF0()
|
|||
vif0.done = false;
|
||||
}
|
||||
|
||||
vif0Regs->stat.FQC = min((u16)0x8, vif0ch->qwc);
|
||||
vif0Regs.stat.FQC = min((u16)0x8, vif0ch.qwc);
|
||||
|
||||
//Using a delay as Beyond Good and Evil does the DMA twice with 2 different TADR's (no checks in the middle, all one block of code),
|
||||
//the first bit it sends isnt required for it to work.
|
||||
|
|
|
@ -46,10 +46,10 @@ __fi void vif1FLUSH()
|
|||
//DevCon.Warning("VIF1 adding %x cycles", (VU1.cycle - _cycles) * BIAS);
|
||||
g_vifCycles += (VU1.cycle - _cycles) * BIAS;
|
||||
}
|
||||
if(gifRegs->stat.P1Q && ((vif1.cmd & 0x7f) != 0x14) && ((vif1.cmd & 0x7f) != 0x17))
|
||||
if(gifRegs.stat.P1Q && ((vif1.cmd & 0x7f) != 0x14) && ((vif1.cmd & 0x7f) != 0x17))
|
||||
{
|
||||
vif1.vifstalled = true;
|
||||
vif1Regs->stat.VGW = true;
|
||||
vif1Regs.stat.VGW = true;
|
||||
vif1.GifWaitState = 2;
|
||||
}
|
||||
|
||||
|
@ -58,16 +58,16 @@ __fi void vif1FLUSH()
|
|||
void vif1TransferToMemory()
|
||||
{
|
||||
u32 size;
|
||||
u64* pMem = (u64*)dmaGetAddr(vif1ch->madr, false);
|
||||
u64* pMem = (u64*)dmaGetAddr(vif1ch.madr, false);
|
||||
|
||||
// VIF from gsMemory
|
||||
if (pMem == NULL) //Is vif0ptag empty?
|
||||
{
|
||||
Console.WriteLn("Vif1 Tag BUSERR");
|
||||
dmacRegs->stat.BEIS = true; //Bus Error
|
||||
vif1Regs->stat.FQC = 0;
|
||||
dmacRegs.stat.BEIS = true; //Bus Error
|
||||
vif1Regs.stat.FQC = 0;
|
||||
|
||||
vif1ch->qwc = 0;
|
||||
vif1ch.qwc = 0;
|
||||
vif1.done = true;
|
||||
CPU_INT(DMAC_VIF1, 0);
|
||||
return; //An error has occurred.
|
||||
|
@ -76,8 +76,8 @@ void vif1TransferToMemory()
|
|||
// MTGS concerns: The MTGS is inherently disagreeable with the idea of downloading
|
||||
// stuff from the GS. The *only* way to handle this case safely is to flush the GS
|
||||
// completely and execute the transfer there-after.
|
||||
//Console.Warning("Real QWC %x", vif1ch->qwc);
|
||||
size = min((u32)vif1ch->qwc, vif1.GSLastDownloadSize);
|
||||
//Console.Warning("Real QWC %x", vif1ch.qwc);
|
||||
size = min((u32)vif1ch.qwc, vif1.GSLastDownloadSize);
|
||||
|
||||
if (GSreadFIFO2 == NULL)
|
||||
{
|
||||
|
@ -90,10 +90,10 @@ void vif1TransferToMemory()
|
|||
pMem[1] = psHu64(VIF1_FIFO + 8);
|
||||
pMem += 2;
|
||||
}
|
||||
if(vif1ch->qwc > vif1.GSLastDownloadSize)
|
||||
if(vif1ch.qwc > vif1.GSLastDownloadSize)
|
||||
{
|
||||
DevCon.Warning("GS Transfer < VIF QWC, Clearing end of space");
|
||||
for (size = vif1ch->qwc - vif1.GSLastDownloadSize; size > 0; --size)
|
||||
for (size = vif1ch.qwc - vif1.GSLastDownloadSize; size > 0; --size)
|
||||
{
|
||||
psHu64(VIF1_FIFO) = 0;
|
||||
psHu64(VIF1_FIFO + 8) = 0;
|
||||
|
@ -112,10 +112,10 @@ void vif1TransferToMemory()
|
|||
psHu64(VIF1_FIFO) = pMem[2*size-2];
|
||||
psHu64(VIF1_FIFO + 8) = pMem[2*size-1];
|
||||
pMem += size * 2;
|
||||
if(vif1ch->qwc > vif1.GSLastDownloadSize)
|
||||
if(vif1ch.qwc > vif1.GSLastDownloadSize)
|
||||
{
|
||||
DevCon.Warning("GS Transfer < VIF QWC, Clearing end of space");
|
||||
for (size = vif1ch->qwc - vif1.GSLastDownloadSize; size > 0; --size)
|
||||
for (size = vif1ch.qwc - vif1.GSLastDownloadSize; size > 0; --size)
|
||||
{
|
||||
psHu64(VIF1_FIFO) = 0;
|
||||
psHu64(VIF1_FIFO + 8) = 0;
|
||||
|
@ -127,27 +127,27 @@ void vif1TransferToMemory()
|
|||
}
|
||||
|
||||
|
||||
g_vifCycles += vif1ch->qwc * 2;
|
||||
vif1ch->madr += vif1ch->qwc * 16; // mgs3 scene changes
|
||||
if(vif1.GSLastDownloadSize >= vif1ch->qwc)
|
||||
g_vifCycles += vif1ch.qwc * 2;
|
||||
vif1ch.madr += vif1ch.qwc * 16; // mgs3 scene changes
|
||||
if(vif1.GSLastDownloadSize >= vif1ch.qwc)
|
||||
{
|
||||
vif1.GSLastDownloadSize -= vif1ch->qwc;
|
||||
vif1Regs->stat.FQC = min((u32)16, vif1.GSLastDownloadSize);
|
||||
vif1.GSLastDownloadSize -= vif1ch.qwc;
|
||||
vif1Regs.stat.FQC = min((u32)16, vif1.GSLastDownloadSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
vif1Regs->stat.FQC = 0;
|
||||
vif1Regs.stat.FQC = 0;
|
||||
vif1.GSLastDownloadSize = 0;
|
||||
}
|
||||
|
||||
vif1ch->qwc = 0;
|
||||
vif1ch.qwc = 0;
|
||||
}
|
||||
|
||||
bool _VIF1chain()
|
||||
{
|
||||
u32 *pMem;
|
||||
|
||||
if (vif1ch->qwc == 0)
|
||||
if (vif1ch.qwc == 0)
|
||||
{
|
||||
vif1.inprogress &= ~1;
|
||||
vif1.irqoffset = 0;
|
||||
|
@ -162,28 +162,27 @@ bool _VIF1chain()
|
|||
return true;
|
||||
}
|
||||
|
||||
pMem = (u32*)dmaGetAddr(vif1ch->madr, !vif1ch->chcr.DIR);
|
||||
pMem = (u32*)dmaGetAddr(vif1ch.madr, !vif1ch.chcr.DIR);
|
||||
if (pMem == NULL)
|
||||
{
|
||||
vif1.cmd = 0;
|
||||
vif1.tag.size = 0;
|
||||
vif1ch->qwc = 0;
|
||||
vif1ch.qwc = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
VIF_LOG("VIF1chain size=%d, madr=%lx, tadr=%lx",
|
||||
vif1ch->qwc, vif1ch->madr, vif1ch->tadr);
|
||||
vif1ch.qwc, vif1ch.madr, vif1ch.tadr);
|
||||
|
||||
if (vif1.vifstalled)
|
||||
return VIF1transfer(pMem + vif1.irqoffset, vif1ch->qwc * 4 - vif1.irqoffset);
|
||||
return VIF1transfer(pMem + vif1.irqoffset, vif1ch.qwc * 4 - vif1.irqoffset);
|
||||
else
|
||||
return VIF1transfer(pMem, vif1ch->qwc * 4);
|
||||
return VIF1transfer(pMem, vif1ch.qwc * 4);
|
||||
}
|
||||
|
||||
__fi void vif1SetupTransfer()
|
||||
{
|
||||
tDMA_TAG *ptag;
|
||||
DMACh& vif1c = (DMACh&)eeMem->HW[0x9000];
|
||||
|
||||
switch (vif1.dmamode)
|
||||
{
|
||||
|
@ -195,20 +194,20 @@ __fi void vif1SetupTransfer()
|
|||
break;
|
||||
|
||||
case VIF_CHAIN_MODE:
|
||||
ptag = dmaGetAddr(vif1c.tadr, false); //Set memory pointer to TADR
|
||||
ptag = dmaGetAddr(vif1ch.tadr, false); //Set memory pointer to TADR
|
||||
|
||||
if (!(vif1c.transfer("Vif1 Tag", ptag))) return;
|
||||
if (!(vif1ch.transfer("Vif1 Tag", ptag))) return;
|
||||
|
||||
vif1c.madr = ptag[1]._u32; //MADR = ADDR field + SPR
|
||||
vif1ch.madr = ptag[1]._u32; //MADR = ADDR field + SPR
|
||||
g_vifCycles += 1; // Add 1 g_vifCycles from the QW read for the tag
|
||||
|
||||
VIF_LOG("VIF1 Tag %8.8x_%8.8x size=%d, id=%d, madr=%lx, tadr=%lx",
|
||||
ptag[1]._u32, ptag[0]._u32, vif1c.qwc, ptag->ID, vif1c.madr, vif1c.tadr);
|
||||
ptag[1]._u32, ptag[0]._u32, vif1ch.qwc, ptag->ID, vif1ch.madr, vif1ch.tadr);
|
||||
|
||||
if (!vif1.done && ((dmacRegs->ctrl.STD == STD_VIF1) && (ptag->ID == TAG_REFS))) // STD == VIF1
|
||||
if (!vif1.done && ((dmacRegs.ctrl.STD == STD_VIF1) && (ptag->ID == TAG_REFS))) // STD == VIF1
|
||||
{
|
||||
// there are still bugs, need to also check if gif->madr +16*qwc >= stadr, if not, stall
|
||||
if ((vif1c.madr + vif1c.qwc * 16) >= dmacRegs->stadr.ADDR)
|
||||
if ((vif1ch.madr + vif1ch.qwc * 16) >= dmacRegs.stadr.ADDR)
|
||||
{
|
||||
// stalled
|
||||
hwDmacIrq(DMAC_STALL_SIS);
|
||||
|
@ -219,7 +218,7 @@ __fi void vif1SetupTransfer()
|
|||
|
||||
vif1.inprogress &= ~1;
|
||||
|
||||
if (vif1c.chcr.TTE)
|
||||
if (vif1ch.chcr.TTE)
|
||||
{
|
||||
// Transfer dma tag if tte is set
|
||||
|
||||
|
@ -243,10 +242,10 @@ __fi void vif1SetupTransfer()
|
|||
|
||||
vif1.done |= hwDmacSrcChainWithStack(vif1ch, ptag->ID);
|
||||
|
||||
if(vif1c.qwc > 0) vif1.inprogress |= 1;
|
||||
if(vif1ch.qwc > 0) vif1.inprogress |= 1;
|
||||
|
||||
//Check TIE bit of CHCR and IRQ bit of tag
|
||||
if (vif1c.chcr.TIE && ptag->IRQ)
|
||||
if (vif1ch.chcr.TIE && ptag->IRQ)
|
||||
{
|
||||
VIF_LOG("dmaIrq Set");
|
||||
|
||||
|
@ -262,73 +261,73 @@ extern bool SIGNAL_IMR_Pending;
|
|||
|
||||
bool CheckPath2GIF(EE_EventType channel)
|
||||
{
|
||||
if ((vif1Regs->stat.VGW))
|
||||
if ((vif1Regs.stat.VGW))
|
||||
{
|
||||
if( vif1.GifWaitState == 0 ) //DIRECT/HL Check
|
||||
{
|
||||
if(GSTransferStatus.PTH3 < IDLE_MODE || gifRegs->stat.P1Q)
|
||||
if(GSTransferStatus.PTH3 < IDLE_MODE || gifRegs.stat.P1Q)
|
||||
{
|
||||
if(gifRegs->stat.IMT && GSTransferStatus.PTH3 <= IMAGE_MODE && (vif1.cmd & 0x7f) == 0x50 && gifRegs->stat.P1Q == false)
|
||||
if(gifRegs.stat.IMT && GSTransferStatus.PTH3 <= IMAGE_MODE && (vif1.cmd & 0x7f) == 0x50 && gifRegs.stat.P1Q == false)
|
||||
{
|
||||
vif1Regs->stat.VGW = false;
|
||||
vif1Regs.stat.VGW = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
//DevCon.Warning("VIF1-0 stall P1Q %x P2Q %x APATH %x PTH3 %x vif1cmd %x", gifRegs->stat.P1Q, gifRegs->stat.P2Q, gifRegs->stat.APATH, GSTransferStatus.PTH3, vif1.cmd);
|
||||
//DevCon.Warning("VIF1-0 stall P1Q %x P2Q %x APATH %x PTH3 %x vif1cmd %x", gifRegs.stat.P1Q, gifRegs.stat.P2Q, gifRegs.stat.APATH, GSTransferStatus.PTH3, vif1.cmd);
|
||||
CPU_INT(channel, 128);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
vif1Regs->stat.VGW = false;
|
||||
vif1Regs.stat.VGW = false;
|
||||
}
|
||||
}
|
||||
else if( vif1.GifWaitState == 1 ) // Else we're flushing path3 :), but of course waiting for the microprogram to finish
|
||||
{
|
||||
if (gifRegs->stat.P1Q)
|
||||
if (gifRegs.stat.P1Q)
|
||||
{
|
||||
//DevCon.Warning("VIF1-1 stall P1Q %x P2Q %x APATH %x PTH3 %x vif1cmd %x", gifRegs->stat.P1Q, gifRegs->stat.P2Q, gifRegs->stat.APATH, GSTransferStatus.PTH3, vif1.cmd);
|
||||
//DevCon.Warning("VIF1-1 stall P1Q %x P2Q %x APATH %x PTH3 %x vif1cmd %x", gifRegs.stat.P1Q, gifRegs.stat.P2Q, gifRegs.stat.APATH, GSTransferStatus.PTH3, vif1.cmd);
|
||||
CPU_INT(channel, 128);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (GSTransferStatus.PTH3 < IDLE_MODE)
|
||||
{
|
||||
//DevCon.Warning("VIF1-11 stall P1Q %x P2Q %x APATH %x PTH3 %x vif1cmd %x", gifRegs->stat.P1Q, gifRegs->stat.P2Q, gifRegs->stat.APATH, GSTransferStatus.PTH3, vif1.cmd);
|
||||
//DevCon.Warning("PTH3 %x P1Q %x P3Q %x IP3 %x", GSTransferStatus.PTH3, gifRegs->stat.P1Q, gifRegs->stat.P3Q, gifRegs->stat.IP3 );
|
||||
//DevCon.Warning("VIF1-11 stall P1Q %x P2Q %x APATH %x PTH3 %x vif1cmd %x", gifRegs.stat.P1Q, gifRegs.stat.P2Q, gifRegs.stat.APATH, GSTransferStatus.PTH3, vif1.cmd);
|
||||
//DevCon.Warning("PTH3 %x P1Q %x P3Q %x IP3 %x", GSTransferStatus.PTH3, gifRegs.stat.P1Q, gifRegs.stat.P3Q, gifRegs.stat.IP3 );
|
||||
CPU_INT(channel, 8);
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
vif1Regs->stat.VGW = false;
|
||||
vif1Regs.stat.VGW = false;
|
||||
}
|
||||
}
|
||||
else if( vif1.GifWaitState == 3 ) // Else we're flushing path3 :), but of course waiting for the microprogram to finish
|
||||
{
|
||||
if (gifRegs->ctrl.PSE)
|
||||
if (gifRegs.ctrl.PSE)
|
||||
{
|
||||
//DevCon.Warning("VIF1-1 stall P1Q %x P2Q %x APATH %x PTH3 %x vif1cmd %x", gifRegs->stat.P1Q, gifRegs->stat.P2Q, gifRegs->stat.APATH, GSTransferStatus.PTH3, vif1.cmd);
|
||||
//DevCon.Warning("VIF1-1 stall P1Q %x P2Q %x APATH %x PTH3 %x vif1cmd %x", gifRegs.stat.P1Q, gifRegs.stat.P2Q, gifRegs.stat.APATH, GSTransferStatus.PTH3, vif1.cmd);
|
||||
CPU_INT(channel, 128);
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
vif1Regs->stat.VGW = false;
|
||||
vif1Regs.stat.VGW = false;
|
||||
}
|
||||
}
|
||||
else //Normal Flush
|
||||
{
|
||||
if (gifRegs->stat.P1Q)
|
||||
if (gifRegs.stat.P1Q)
|
||||
{
|
||||
//DevCon.Warning("VIF1-2 stall P1Q %x P2Q %x APATH %x PTH3 %x vif1cmd %x", gifRegs->stat.P1Q, gifRegs->stat.P2Q, gifRegs->stat.APATH, GSTransferStatus.PTH3, vif1.cmd);
|
||||
//DevCon.Warning("VIF1-2 stall P1Q %x P2Q %x APATH %x PTH3 %x vif1cmd %x", gifRegs.stat.P1Q, gifRegs.stat.P2Q, gifRegs.stat.APATH, GSTransferStatus.PTH3, vif1.cmd);
|
||||
CPU_INT(channel, 128);
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
vif1Regs->stat.VGW = false;
|
||||
vif1Regs.stat.VGW = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -346,11 +345,11 @@ __fi void vif1Interrupt()
|
|||
|
||||
g_vifCycles = 0;
|
||||
|
||||
if(GSTransferStatus.PTH2 == STOPPED_MODE && gifRegs->stat.APATH == GIF_APATH2)
|
||||
if(GSTransferStatus.PTH2 == STOPPED_MODE && gifRegs.stat.APATH == GIF_APATH2)
|
||||
{
|
||||
gifRegs->stat.OPH = false;
|
||||
gifRegs->stat.APATH = GIF_APATH_IDLE;
|
||||
if(gifRegs->stat.P1Q) gsPath1Interrupt();
|
||||
gifRegs.stat.OPH = false;
|
||||
gifRegs.stat.APATH = GIF_APATH_IDLE;
|
||||
if(gifRegs.stat.P1Q) gsPath1Interrupt();
|
||||
}
|
||||
|
||||
if (schedulepath3msk & 0x10)
|
||||
|
@ -360,48 +359,48 @@ __fi void vif1Interrupt()
|
|||
return;
|
||||
}
|
||||
//Some games (Fahrenheit being one) start vif first, let it loop through blankness while it sets MFIFO mode, so we need to check it here.
|
||||
if (dmacRegs->ctrl.MFD == MFD_VIF1)
|
||||
if (dmacRegs.ctrl.MFD == MFD_VIF1)
|
||||
{
|
||||
//Console.WriteLn("VIFMFIFO\n");
|
||||
// Test changed because the Final Fantasy 12 opening somehow has the tag in *Undefined* mode, which is not in the documentation that I saw.
|
||||
if (vif1ch->chcr.MOD == NORMAL_MODE) Console.WriteLn("MFIFO mode is normal (which isn't normal here)! %x", vif1ch->chcr._u32);
|
||||
vif1Regs->stat.FQC = min((u16)0x10, vif1ch->qwc);
|
||||
if (vif1ch.chcr.MOD == NORMAL_MODE) Console.WriteLn("MFIFO mode is normal (which isn't normal here)! %x", vif1ch.chcr._u32);
|
||||
vif1Regs.stat.FQC = min((u16)0x10, vif1ch.qwc);
|
||||
vifMFIFOInterrupt();
|
||||
return;
|
||||
}
|
||||
|
||||
//We need to check the direction, if it is downloading from the GS, we handle that separately (KH2 for testing)
|
||||
if (vif1ch->chcr.DIR)
|
||||
if (vif1ch.chcr.DIR)
|
||||
{
|
||||
if (!CheckPath2GIF(DMAC_VIF1)) return;
|
||||
|
||||
vif1Regs->stat.FQC = min(vif1ch->qwc, (u16)16);
|
||||
vif1Regs.stat.FQC = min(vif1ch.qwc, (u16)16);
|
||||
//Simulated GS transfer time done, clear the flags
|
||||
}
|
||||
|
||||
if (!vif1ch->chcr.STR) Console.WriteLn("Vif1 running when CHCR == %x", vif1ch->chcr._u32);
|
||||
if (!vif1ch.chcr.STR) Console.WriteLn("Vif1 running when CHCR == %x", vif1ch.chcr._u32);
|
||||
|
||||
if (vif1.cmd)
|
||||
{
|
||||
if (vif1.done && (vif1ch->qwc == 0)) vif1Regs->stat.VPS = VPS_WAITING;
|
||||
if (vif1.done && (vif1ch.qwc == 0)) vif1Regs.stat.VPS = VPS_WAITING;
|
||||
}
|
||||
else
|
||||
{
|
||||
vif1Regs->stat.VPS = VPS_IDLE;
|
||||
vif1Regs.stat.VPS = VPS_IDLE;
|
||||
}
|
||||
|
||||
if (vif1.irq && vif1.tag.size == 0)
|
||||
{
|
||||
vif1Regs->stat.INT = true;
|
||||
vif1Regs.stat.INT = true;
|
||||
hwIntcIrq(VIF1intc);
|
||||
--vif1.irq;
|
||||
if (vif1Regs->stat.test(VIF1_STAT_VSS | VIF1_STAT_VIS | VIF1_STAT_VFS))
|
||||
if (vif1Regs.stat.test(VIF1_STAT_VSS | VIF1_STAT_VIS | VIF1_STAT_VFS))
|
||||
{
|
||||
//vif1Regs->stat.FQC = 0;
|
||||
//vif1Regs.stat.FQC = 0;
|
||||
|
||||
//NFSHPS stalls when the whole packet has gone across (it stalls in the last 32bit cmd)
|
||||
//In this case VIF will end
|
||||
if(vif1ch->qwc > 0 || !vif1.done) return;
|
||||
if(vif1ch.qwc > 0 || !vif1.done) return;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -410,7 +409,7 @@ __fi void vif1Interrupt()
|
|||
_VIF1chain();
|
||||
// VIF_NORMAL_FROM_MEM_MODE is a very slow operation.
|
||||
// Timesplitters 2 depends on this beeing a bit higher than 128.
|
||||
if (vif1ch->chcr.DIR) vif1Regs->stat.FQC = min(vif1ch->qwc, (u16)16);
|
||||
if (vif1ch.chcr.DIR) vif1Regs.stat.FQC = min(vif1ch.qwc, (u16)16);
|
||||
// Refraction - Removing voodoo timings for now, completely messes a lot of Path3 masked games.
|
||||
/*if (vif1.dmamode == VIF_NORMAL_FROM_MEM_MODE ) CPU_INT(DMAC_VIF1, 1024);
|
||||
else */CPU_INT(DMAC_VIF1, g_vifCycles /*VifCycleVoodoo*/);
|
||||
|
@ -420,14 +419,14 @@ __fi void vif1Interrupt()
|
|||
if (!vif1.done)
|
||||
{
|
||||
|
||||
if (!(dmacRegs->ctrl.DMAE))
|
||||
if (!(dmacRegs.ctrl.DMAE))
|
||||
{
|
||||
Console.WriteLn("vif1 dma masked");
|
||||
return;
|
||||
}
|
||||
|
||||
if ((vif1.inprogress & 0x1) == 0) vif1SetupTransfer();
|
||||
if (vif1ch->chcr.DIR) vif1Regs->stat.FQC = min(vif1ch->qwc, (u16)16);
|
||||
if (vif1ch.chcr.DIR) vif1Regs.stat.FQC = min(vif1ch.qwc, (u16)16);
|
||||
CPU_INT(DMAC_VIF1, g_vifCycles);
|
||||
return;
|
||||
}
|
||||
|
@ -439,17 +438,17 @@ __fi void vif1Interrupt()
|
|||
return; //Dont want to end if vif is stalled.
|
||||
}
|
||||
#ifdef PCSX2_DEVBUILD
|
||||
if (vif1ch->qwc > 0) Console.WriteLn("VIF1 Ending with %x QWC left", vif1ch->qwc);
|
||||
if (vif1ch.qwc > 0) Console.WriteLn("VIF1 Ending with %x QWC left", vif1ch.qwc);
|
||||
if (vif1.cmd != 0) Console.WriteLn("vif1.cmd still set %x tag size %x", vif1.cmd, vif1.tag.size);
|
||||
#endif
|
||||
|
||||
if((vif1ch->chcr.DIR == VIF_NORMAL_TO_MEM_MODE) && vif1.GSLastDownloadSize <= 16)
|
||||
if((vif1ch.chcr.DIR == VIF_NORMAL_TO_MEM_MODE) && vif1.GSLastDownloadSize <= 16)
|
||||
{
|
||||
//Reverse fifo has finished and nothing is left, so lets clear the outputting flag
|
||||
gifRegs->stat.OPH = false;
|
||||
gifRegs.stat.OPH = false;
|
||||
}
|
||||
|
||||
vif1ch->chcr.STR = false;
|
||||
vif1ch.chcr.STR = false;
|
||||
vif1.vifstalled = false;
|
||||
g_vifCycles = 0;
|
||||
g_vu1Cycles = 0;
|
||||
|
@ -462,8 +461,8 @@ void dmaVIF1()
|
|||
{
|
||||
VIF_LOG("dmaVIF1 chcr = %lx, madr = %lx, qwc = %lx\n"
|
||||
" tadr = %lx, asr0 = %lx, asr1 = %lx",
|
||||
vif1ch->chcr._u32, vif1ch->madr, vif1ch->qwc,
|
||||
vif1ch->tadr, vif1ch->asr0, vif1ch->asr1);
|
||||
vif1ch.chcr._u32, vif1ch.madr, vif1ch.qwc,
|
||||
vif1ch.tadr, vif1ch.asr0, vif1ch.asr1);
|
||||
|
||||
// vif1.done = false;
|
||||
|
||||
|
@ -475,19 +474,19 @@ void dmaVIF1()
|
|||
g_vu1Cycles = 0;
|
||||
|
||||
#ifdef PCSX2_DEVBUILD
|
||||
if (dmacRegs->ctrl.STD == STD_VIF1)
|
||||
if (dmacRegs.ctrl.STD == STD_VIF1)
|
||||
{
|
||||
//DevCon.WriteLn("VIF Stall Control Source = %x, Drain = %x", (psHu32(0xe000) >> 4) & 0x3, (psHu32(0xe000) >> 6) & 0x3);
|
||||
}
|
||||
#endif
|
||||
|
||||
if ((vif1ch->chcr.MOD == NORMAL_MODE) || vif1ch->qwc > 0) // Normal Mode
|
||||
if ((vif1ch.chcr.MOD == NORMAL_MODE) || vif1ch.qwc > 0) // Normal Mode
|
||||
{
|
||||
|
||||
if (dmacRegs->ctrl.STD == STD_VIF1)
|
||||
if (dmacRegs.ctrl.STD == STD_VIF1)
|
||||
Console.WriteLn("DMA Stall Control on VIF1 normal");
|
||||
|
||||
if (vif1ch->chcr.DIR) // to Memory
|
||||
if (vif1ch.chcr.DIR) // to Memory
|
||||
vif1.dmamode = VIF_NORMAL_FROM_MEM_MODE;
|
||||
else
|
||||
vif1.dmamode = VIF_NORMAL_TO_MEM_MODE;
|
||||
|
@ -495,12 +494,12 @@ void dmaVIF1()
|
|||
vif1.done = false;
|
||||
|
||||
// ignore tag if it's a GS download (Def Jam Fight for NY)
|
||||
if(vif1ch->chcr.MOD == CHAIN_MODE && vif1.dmamode != VIF_NORMAL_TO_MEM_MODE)
|
||||
if(vif1ch.chcr.MOD == CHAIN_MODE && vif1.dmamode != VIF_NORMAL_TO_MEM_MODE)
|
||||
{
|
||||
vif1.dmamode = VIF_CHAIN_MODE;
|
||||
DevCon.Warning(L"VIF1 QWC on Chain CHCR " + vif1ch->chcr.desc());
|
||||
DevCon.Warning(L"VIF1 QWC on Chain CHCR " + vif1ch.chcr.desc());
|
||||
|
||||
if ((vif1ch->chcr.tag().ID == TAG_REFE) || (vif1ch->chcr.tag().ID == TAG_END))
|
||||
if ((vif1ch.chcr.tag().ID == TAG_REFE) || (vif1ch.chcr.tag().ID == TAG_END))
|
||||
{
|
||||
vif1.done = true;
|
||||
}
|
||||
|
@ -512,7 +511,7 @@ void dmaVIF1()
|
|||
vif1.done = false;
|
||||
}
|
||||
|
||||
if (vif1ch->chcr.DIR) vif1Regs->stat.FQC = min((u16)0x10, vif1ch->qwc);
|
||||
if (vif1ch.chcr.DIR) vif1Regs.stat.FQC = min((u16)0x10, vif1ch.qwc);
|
||||
|
||||
// Chain Mode
|
||||
CPU_INT(DMAC_VIF1, 4);
|
||||
|
|
|
@ -33,26 +33,26 @@ extern u32 g_vifCycles;
|
|||
|
||||
static u32 qwctag(u32 mask)
|
||||
{
|
||||
return (dmacRegs->rbor.ADDR + (mask & dmacRegs->rbsr.RMSK));
|
||||
return (dmacRegs.rbor.ADDR + (mask & dmacRegs.rbsr.RMSK));
|
||||
}
|
||||
|
||||
static __fi bool mfifoVIF1rbTransfer()
|
||||
{
|
||||
u32 maddr = dmacRegs->rbor.ADDR;
|
||||
u32 msize = dmacRegs->rbor.ADDR + dmacRegs->rbsr.RMSK + 16;
|
||||
u16 mfifoqwc = std::min(vif1ch->qwc, vifqwc);
|
||||
u32 maddr = dmacRegs.rbor.ADDR;
|
||||
u32 msize = dmacRegs.rbor.ADDR + dmacRegs.rbsr.RMSK + 16;
|
||||
u16 mfifoqwc = std::min(vif1ch.qwc, vifqwc);
|
||||
u32 *src;
|
||||
bool ret;
|
||||
|
||||
/* Check if the transfer should wrap around the ring buffer */
|
||||
if ((vif1ch->madr + (mfifoqwc << 4)) > (msize))
|
||||
if ((vif1ch.madr + (mfifoqwc << 4)) > (msize))
|
||||
{
|
||||
int s1 = ((msize) - vif1ch->madr) >> 2;
|
||||
int s1 = ((msize) - vif1ch.madr) >> 2;
|
||||
|
||||
SPR_LOG("Split MFIFO");
|
||||
|
||||
/* it does, so first copy 's1' bytes from 'addr' to 'data' */
|
||||
src = (u32*)PSM(vif1ch->madr);
|
||||
src = (u32*)PSM(vif1ch.madr);
|
||||
if (src == NULL) return false;
|
||||
|
||||
if (vif1.vifstalled)
|
||||
|
@ -60,18 +60,18 @@ static __fi bool mfifoVIF1rbTransfer()
|
|||
else
|
||||
ret = VIF1transfer(src, s1);
|
||||
|
||||
vif1ch->madr = qwctag(vif1ch->madr);
|
||||
vif1ch.madr = qwctag(vif1ch.madr);
|
||||
|
||||
if (ret)
|
||||
{
|
||||
/* and second copy 's2' bytes from 'maddr' to '&data[s1]' */
|
||||
vif1ch->madr = maddr;
|
||||
vif1ch.madr = maddr;
|
||||
|
||||
src = (u32*)PSM(maddr);
|
||||
if (src == NULL) return false;
|
||||
VIF1transfer(src, ((mfifoqwc << 2) - s1));
|
||||
}
|
||||
vif1ch->madr = qwctag(vif1ch->madr);
|
||||
vif1ch.madr = qwctag(vif1ch.madr);
|
||||
|
||||
}
|
||||
else
|
||||
|
@ -79,7 +79,7 @@ static __fi bool mfifoVIF1rbTransfer()
|
|||
SPR_LOG("Direct MFIFO");
|
||||
|
||||
/* it doesn't, so just transfer 'qwc*4' words */
|
||||
src = (u32*)PSM(vif1ch->madr);
|
||||
src = (u32*)PSM(vif1ch.madr);
|
||||
if (src == NULL) return false;
|
||||
|
||||
if (vif1.vifstalled)
|
||||
|
@ -87,7 +87,7 @@ static __fi bool mfifoVIF1rbTransfer()
|
|||
else
|
||||
ret = VIF1transfer(src, mfifoqwc << 2);
|
||||
|
||||
vif1ch->madr = qwctag(vif1ch->madr);
|
||||
vif1ch.madr = qwctag(vif1ch.madr);
|
||||
|
||||
}
|
||||
return ret;
|
||||
|
@ -96,25 +96,25 @@ static __fi bool mfifoVIF1rbTransfer()
|
|||
static __fi void mfifo_VIF1chain()
|
||||
{
|
||||
/* Is QWC = 0? if so there is nothing to transfer */
|
||||
if ((vif1ch->qwc == 0))
|
||||
if ((vif1ch.qwc == 0))
|
||||
{
|
||||
vif1.inprogress &= ~1;
|
||||
return;
|
||||
}
|
||||
|
||||
if (vif1ch->madr >= dmacRegs->rbor.ADDR &&
|
||||
vif1ch->madr <= (dmacRegs->rbor.ADDR + dmacRegs->rbsr.RMSK))
|
||||
if (vif1ch.madr >= dmacRegs.rbor.ADDR &&
|
||||
vif1ch.madr <= (dmacRegs.rbor.ADDR + dmacRegs.rbsr.RMSK))
|
||||
{
|
||||
//Need to exit on mfifo locations, if the madr is matching the madr of spr, we dont have any data left :(
|
||||
|
||||
u16 startqwc = vif1ch->qwc;
|
||||
u16 startqwc = vif1ch.qwc;
|
||||
mfifoVIF1rbTransfer();
|
||||
vifqwc -= startqwc - vif1ch->qwc;
|
||||
vifqwc -= startqwc - vif1ch.qwc;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
tDMA_TAG *pMem = dmaGetAddr(vif1ch->madr, !vif1ch->chcr.DIR);
|
||||
tDMA_TAG *pMem = dmaGetAddr(vif1ch.madr, !vif1ch.chcr.DIR);
|
||||
SPR_LOG("Non-MFIFO Location");
|
||||
|
||||
//No need to exit on non-mfifo as it is indirect anyway, so it can be transferring this while spr refills the mfifo
|
||||
|
@ -122,9 +122,9 @@ static __fi void mfifo_VIF1chain()
|
|||
if (pMem == NULL) return;
|
||||
|
||||
if (vif1.vifstalled)
|
||||
VIF1transfer((u32*)pMem + vif1.irqoffset, vif1ch->qwc * 4 - vif1.irqoffset);
|
||||
VIF1transfer((u32*)pMem + vif1.irqoffset, vif1ch.qwc * 4 - vif1.irqoffset);
|
||||
else
|
||||
VIF1transfer((u32*)pMem, vif1ch->qwc << 2);
|
||||
VIF1transfer((u32*)pMem, vif1ch.qwc << 2);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -139,23 +139,23 @@ void mfifoVIF1transfer(int qwc)
|
|||
if (qwc > 0)
|
||||
{
|
||||
vifqwc += qwc;
|
||||
SPR_LOG("Added %x qw to mfifo, total now %x - Vif CHCR %x Stalled %x done %x", qwc, vifqwc, vif1ch->chcr._u32, vif1.vifstalled, vif1.done);
|
||||
SPR_LOG("Added %x qw to mfifo, total now %x - Vif CHCR %x Stalled %x done %x", qwc, vifqwc, vif1ch.chcr._u32, vif1.vifstalled, vif1.done);
|
||||
if (vif1.inprogress & 0x10)
|
||||
{
|
||||
if(vif1ch->chcr.STR == true)CPU_INT(DMAC_MFIFO_VIF, 4);
|
||||
if(vif1ch.chcr.STR == true)CPU_INT(DMAC_MFIFO_VIF, 4);
|
||||
|
||||
vif1Regs->stat.FQC = 0x10; // FQC=16
|
||||
vif1Regs.stat.FQC = 0x10; // FQC=16
|
||||
}
|
||||
vif1.inprogress &= ~0x10;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (vif1ch->qwc == 0 && vifqwc > 0)
|
||||
if (vif1ch.qwc == 0 && vifqwc > 0)
|
||||
{
|
||||
ptag = dmaGetAddr(vif1ch->tadr, false);
|
||||
ptag = dmaGetAddr(vif1ch.tadr, false);
|
||||
|
||||
if (vif1ch->chcr.TTE)
|
||||
if (vif1ch.chcr.TTE)
|
||||
{
|
||||
bool ret;
|
||||
|
||||
|
@ -173,62 +173,62 @@ void mfifoVIF1transfer(int qwc)
|
|||
|
||||
vif1.irqoffset = 0;
|
||||
|
||||
vif1ch->unsafeTransfer(ptag);
|
||||
vif1ch.unsafeTransfer(ptag);
|
||||
|
||||
vif1ch->madr = ptag[1]._u32;
|
||||
vif1ch.madr = ptag[1]._u32;
|
||||
vifqwc--;
|
||||
|
||||
SPR_LOG("dmaChain %8.8x_%8.8x size=%d, id=%d, madr=%lx, tadr=%lx mfifo qwc = %x spr0 madr = %x",
|
||||
ptag[1]._u32, ptag[0]._u32, vif1ch->qwc, ptag->ID, vif1ch->madr, vif1ch->tadr, vifqwc, spr0->madr);
|
||||
ptag[1]._u32, ptag[0]._u32, vif1ch.qwc, ptag->ID, vif1ch.madr, vif1ch.tadr, vifqwc, spr0ch.madr);
|
||||
|
||||
switch (ptag->ID)
|
||||
{
|
||||
case TAG_REFE: // Refe - Transfer Packet According to ADDR field
|
||||
vif1ch->tadr = qwctag(vif1ch->tadr + 16);
|
||||
vif1ch.tadr = qwctag(vif1ch.tadr + 16);
|
||||
vif1.done = true; //End Transfer
|
||||
break;
|
||||
|
||||
case TAG_CNT: // CNT - Transfer QWC following the tag.
|
||||
vif1ch->madr = qwctag(vif1ch->tadr + 16); //Set MADR to QW after Tag
|
||||
vif1ch->tadr = qwctag(vif1ch->madr + (vif1ch->qwc << 4)); //Set TADR to QW following the data
|
||||
vif1ch.madr = qwctag(vif1ch.tadr + 16); //Set MADR to QW after Tag
|
||||
vif1ch.tadr = qwctag(vif1ch.madr + (vif1ch.qwc << 4)); //Set TADR to QW following the data
|
||||
vif1.done = false;
|
||||
break;
|
||||
|
||||
case TAG_NEXT: // Next - Transfer QWC following tag. TADR = ADDR
|
||||
{
|
||||
int temp = vif1ch->madr; //Temporarily Store ADDR
|
||||
vif1ch->madr = qwctag(vif1ch->tadr + 16); //Set MADR to QW following the tag
|
||||
vif1ch->tadr = temp; //Copy temporarily stored ADDR to Tag
|
||||
if ((temp & dmacRegs->rbsr.RMSK) != dmacRegs->rbor.ADDR) Console.WriteLn("Next tag = %x outside ring %x size %x", temp, psHu32(DMAC_RBOR), psHu32(DMAC_RBSR));
|
||||
int temp = vif1ch.madr; //Temporarily Store ADDR
|
||||
vif1ch.madr = qwctag(vif1ch.tadr + 16); //Set MADR to QW following the tag
|
||||
vif1ch.tadr = temp; //Copy temporarily stored ADDR to Tag
|
||||
if ((temp & dmacRegs.rbsr.RMSK) != dmacRegs.rbor.ADDR) Console.WriteLn("Next tag = %x outside ring %x size %x", temp, psHu32(DMAC_RBOR), psHu32(DMAC_RBSR));
|
||||
vif1.done = false;
|
||||
break;
|
||||
}
|
||||
|
||||
case TAG_REF: // Ref - Transfer QWC from ADDR field
|
||||
case TAG_REFS: // Refs - Transfer QWC from ADDR field (Stall Control)
|
||||
vif1ch->tadr = qwctag(vif1ch->tadr + 16); //Set TADR to next tag
|
||||
vif1ch.tadr = qwctag(vif1ch.tadr + 16); //Set TADR to next tag
|
||||
vif1.done = false;
|
||||
break;
|
||||
|
||||
case TAG_END: // End - Transfer QWC following the tag
|
||||
vif1ch->madr = qwctag(vif1ch->tadr + 16); //Set MADR to data following the tag
|
||||
vif1ch->tadr = qwctag(vif1ch->madr + (vif1ch->qwc << 4)); //Set TADR to QW following the data
|
||||
vif1ch.madr = qwctag(vif1ch.tadr + 16); //Set MADR to data following the tag
|
||||
vif1ch.tadr = qwctag(vif1ch.madr + (vif1ch.qwc << 4)); //Set TADR to QW following the data
|
||||
vif1.done = true; //End Transfer
|
||||
break;
|
||||
}
|
||||
|
||||
if (vif1ch->chcr.TIE && ptag->IRQ)
|
||||
if (vif1ch.chcr.TIE && ptag->IRQ)
|
||||
{
|
||||
VIF_LOG("dmaIrq Set");
|
||||
vif1.done = true;
|
||||
}
|
||||
|
||||
vif1Regs->stat.FQC = min(vif1ch->qwc, (u16)16);
|
||||
vif1Regs.stat.FQC = min(vif1ch.qwc, (u16)16);
|
||||
vif1.inprogress |= 1;
|
||||
}
|
||||
|
||||
|
||||
SPR_LOG("mfifoVIF1transfer end %x madr %x, tadr %x vifqwc %x", vif1ch->chcr._u32, vif1ch->madr, vif1ch->tadr, vifqwc);
|
||||
SPR_LOG("mfifoVIF1transfer end %x madr %x, tadr %x vifqwc %x", vif1ch.chcr._u32, vif1ch.madr, vif1ch.tadr, vifqwc);
|
||||
}
|
||||
|
||||
void vifMFIFOInterrupt()
|
||||
|
@ -236,52 +236,52 @@ void vifMFIFOInterrupt()
|
|||
g_vifCycles = 0;
|
||||
VIF_LOG("vif mfifo interrupt");
|
||||
|
||||
if(GSTransferStatus.PTH2 == STOPPED_MODE && gifRegs->stat.APATH == GIF_APATH2)
|
||||
if(GSTransferStatus.PTH2 == STOPPED_MODE && gifRegs.stat.APATH == GIF_APATH2)
|
||||
{
|
||||
GSTransferStatus.PTH2 = STOPPED_MODE;
|
||||
if(gifRegs->stat.DIR == 0)gifRegs->stat.OPH = false;
|
||||
gifRegs->stat.APATH = GIF_APATH_IDLE;
|
||||
if(gifRegs->stat.P1Q) gsPath1Interrupt();
|
||||
/*gifRegs->stat.APATH = GIF_APATH_IDLE;
|
||||
if(gifRegs->stat.DIR == 0)gifRegs->stat.OPH = false;*/
|
||||
if(gifRegs.stat.DIR == 0)gifRegs.stat.OPH = false;
|
||||
gifRegs.stat.APATH = GIF_APATH_IDLE;
|
||||
if(gifRegs.stat.P1Q) gsPath1Interrupt();
|
||||
/*gifRegs.stat.APATH = GIF_APATH_IDLE;
|
||||
if(gifRegs.stat.DIR == 0)gifRegs.stat.OPH = false;*/
|
||||
}
|
||||
|
||||
if (schedulepath3msk & 0x10) Vif1MskPath3();
|
||||
|
||||
if(vif1ch->chcr.DIR && CheckPath2GIF(DMAC_MFIFO_VIF) == false) return;
|
||||
if(vif1ch.chcr.DIR && CheckPath2GIF(DMAC_MFIFO_VIF) == false) return;
|
||||
//We need to check the direction, if it is downloading from the GS, we handle that seperately (KH2 for testing)
|
||||
|
||||
//Simulated GS transfer time done, clear the flags
|
||||
|
||||
if (vif1.cmd)
|
||||
{
|
||||
if(vif1.done == true && vif1ch->qwc == 0) vif1Regs->stat.VPS = VPS_WAITING;
|
||||
if(vif1.done == true && vif1ch.qwc == 0) vif1Regs.stat.VPS = VPS_WAITING;
|
||||
}
|
||||
else
|
||||
{
|
||||
vif1Regs->stat.VPS = VPS_IDLE;
|
||||
vif1Regs.stat.VPS = VPS_IDLE;
|
||||
}
|
||||
|
||||
if (vif1.irq && vif1.tag.size == 0)
|
||||
{
|
||||
vif1Regs->stat.INT = true;
|
||||
vif1Regs.stat.INT = true;
|
||||
hwIntcIrq(INTC_VIF1);
|
||||
--vif1.irq;
|
||||
|
||||
if (vif1Regs->stat.test(VIF1_STAT_VSS | VIF1_STAT_VIS | VIF1_STAT_VFS))
|
||||
if (vif1Regs.stat.test(VIF1_STAT_VSS | VIF1_STAT_VIS | VIF1_STAT_VFS))
|
||||
{
|
||||
/*vif1Regs->stat.FQC = 0; // FQC=0
|
||||
vif1ch->chcr.STR = false;*/
|
||||
if(vif1ch->qwc > 0 || !vif1.done) return;
|
||||
/*vif1Regs.stat.FQC = 0; // FQC=0
|
||||
vif1ch.chcr.STR = false;*/
|
||||
if(vif1ch.qwc > 0 || !vif1.done) return;
|
||||
}
|
||||
}
|
||||
|
||||
if (vif1.done == false || vif1ch->qwc)
|
||||
if (vif1.done == false || vif1ch.qwc)
|
||||
{
|
||||
switch(vif1.inprogress & 1)
|
||||
{
|
||||
case 0: //Set up transfer
|
||||
if (vif1ch->tadr == spr0->madr)
|
||||
if (vif1ch.tadr == spr0ch.madr)
|
||||
{
|
||||
// Console.WriteLn("Empty 1");
|
||||
vifqwc = 0;
|
||||
|
@ -290,7 +290,7 @@ void vifMFIFOInterrupt()
|
|||
hwDmacIrq(DMAC_MFIFO_EMPTY);
|
||||
vif1.inprogress |= 0x10;
|
||||
}
|
||||
vif1Regs->stat.FQC = 0;
|
||||
vif1Regs.stat.FQC = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -310,7 +310,7 @@ void vifMFIFOInterrupt()
|
|||
|
||||
//FF7 Dirge of Cerberus seems to like the mfifo to tell it when it's empty, even if it's ending.
|
||||
//Doesn't seem to care about the vif1 dma interrupting (possibly disabled the interrupt?)
|
||||
if (vif1ch->tadr == spr0->madr)
|
||||
if (vif1ch.tadr == spr0ch.madr)
|
||||
{
|
||||
vifqwc = 0;
|
||||
if((vif1.inprogress & 0x10) == 0)
|
||||
|
@ -322,9 +322,9 @@ void vifMFIFOInterrupt()
|
|||
vif1.vifstalled = false;
|
||||
vif1.done = 1;
|
||||
g_vifCycles = 0;
|
||||
vif1ch->chcr.STR = false;
|
||||
vif1ch.chcr.STR = false;
|
||||
hwDmacIrq(DMAC_VIF1);
|
||||
VIF_LOG("vif mfifo dma end");
|
||||
|
||||
vif1Regs->stat.FQC = 0;
|
||||
vif1Regs.stat.FQC = 0;
|
||||
}
|
||||
|
|
|
@ -39,32 +39,33 @@ static __fi void vifFlush(int idx) {
|
|||
|
||||
static __fi void vuExecMicro(int idx, u32 addr) {
|
||||
VURegs* VU = nVif[idx].VU;
|
||||
VIFregisters& vifRegs = VU->GetVifRegs();
|
||||
int startcycles = 0;
|
||||
//vifFlush(idx);
|
||||
|
||||
//if(vifX.vifstalled == true) return;
|
||||
|
||||
if (VU->vifRegs->itops > (idx ? 0x3ffu : 0xffu)) {
|
||||
Console.WriteLn("VIF%d ITOP overrun! %x", idx, VU->vifRegs->itops);
|
||||
VU->vifRegs->itops &= (idx ? 0x3ffu : 0xffu);
|
||||
if (vifRegs.itops > (idx ? 0x3ffu : 0xffu)) {
|
||||
Console.WriteLn("VIF%d ITOP overrun! %x", idx, vifRegs.itops);
|
||||
vifRegs.itops &= (idx ? 0x3ffu : 0xffu);
|
||||
}
|
||||
|
||||
VU->vifRegs->itop = VU->vifRegs->itops;
|
||||
vifRegs.itop = vifRegs.itops;
|
||||
|
||||
if (idx) {
|
||||
// in case we're handling a VIF1 execMicro, set the top with the tops value
|
||||
VU->vifRegs->top = VU->vifRegs->tops & 0x3ff;
|
||||
vifRegs.top = vifRegs.tops & 0x3ff;
|
||||
|
||||
// is DBF flag set in VIF_STAT?
|
||||
if (VU->vifRegs->stat.DBF) {
|
||||
if (vifRegs.stat.DBF) {
|
||||
// it is, so set tops with base, and clear the stat DBF flag
|
||||
VU->vifRegs->tops = VU->vifRegs->base;
|
||||
VU->vifRegs->stat.DBF = false;
|
||||
vifRegs.tops = vifRegs.base;
|
||||
vifRegs.stat.DBF = false;
|
||||
}
|
||||
else {
|
||||
// it is not, so set tops with base + offset, and set stat DBF flag
|
||||
VU->vifRegs->tops = VU->vifRegs->base + VU->vifRegs->ofst;
|
||||
VU->vifRegs->stat.DBF = true;
|
||||
vifRegs.tops = vifRegs.base + vifRegs.ofst;
|
||||
vifRegs.stat.DBF = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -84,16 +85,16 @@ u8 schedulepath3msk = 0;
|
|||
|
||||
void Vif1MskPath3() {
|
||||
|
||||
vif1Regs->mskpath3 = schedulepath3msk & 0x1;
|
||||
GIF_LOG("VIF MSKPATH3 %x gif str %x path3 status %x", vif1Regs->mskpath3, gif->chcr.STR, GSTransferStatus.PTH3);
|
||||
gifRegs->stat.M3P = vif1Regs->mskpath3;
|
||||
vif1Regs.mskpath3 = schedulepath3msk & 0x1;
|
||||
GIF_LOG("VIF MSKPATH3 %x gif str %x path3 status %x", vif1Regs.mskpath3, gifch.chcr.STR, GSTransferStatus.PTH3);
|
||||
gifRegs.stat.M3P = vif1Regs.mskpath3;
|
||||
|
||||
if (!vif1Regs->mskpath3)
|
||||
if (!vif1Regs.mskpath3)
|
||||
{
|
||||
//if(GSTransferStatus.PTH3 > TRANSFER_MODE && gif->chcr.STR) GSTransferStatus.PTH3 = TRANSFER_MODE;
|
||||
//DevCon.Warning("Mask off");
|
||||
//if(GSTransferStatus.PTH3 >= PENDINGSTOP_MODE) GSTransferStatus.PTH3 = IDLE_MODE;
|
||||
if(gifRegs->stat.P3Q)
|
||||
if(gifRegs.stat.P3Q)
|
||||
{
|
||||
gsInterrupt();//gsInterrupt();
|
||||
}
|
||||
|
@ -109,7 +110,7 @@ void Vif1MskPath3() {
|
|||
|
||||
vifOp(vifCode_Base) {
|
||||
vif1Only();
|
||||
pass1 { vif1Regs->base = vif1Regs->code & 0x3ff; vif1.cmd = 0; }
|
||||
pass1 { vif1Regs.base = vif1Regs.code & 0x3ff; vif1.cmd = 0; }
|
||||
pass3 { VifCodeLog("Base"); }
|
||||
return 0;
|
||||
}
|
||||
|
@ -119,15 +120,15 @@ extern bool SIGNAL_IMR_Pending;
|
|||
template<int idx> __fi int _vifCode_Direct(int pass, const u8* data, bool isDirectHL) {
|
||||
pass1 {
|
||||
vif1Only();
|
||||
int vifImm = (u16)vif1Regs->code;
|
||||
int vifImm = (u16)vif1Regs.code;
|
||||
vif1.tag.size = vifImm ? (vifImm*4) : (65536*4);
|
||||
vif1.vifstalled = true;
|
||||
gifRegs->stat.P2Q = true;
|
||||
if (gifRegs->stat.PSE) // temporarily stop
|
||||
gifRegs.stat.P2Q = true;
|
||||
if (gifRegs.stat.PSE) // temporarily stop
|
||||
{
|
||||
Console.WriteLn("Gif dma temp paused? VIF DIRECT");
|
||||
vif1.GifWaitState = 3;
|
||||
vif1Regs->stat.VGW = true;
|
||||
vif1Regs.stat.VGW = true;
|
||||
}
|
||||
//Should cause this to split here to try and time PATH3 right.
|
||||
return 0;
|
||||
|
@ -135,18 +136,18 @@ template<int idx> __fi int _vifCode_Direct(int pass, const u8* data, bool isDire
|
|||
pass2 {
|
||||
vif1Only();
|
||||
|
||||
if (GSTransferStatus.PTH3 < IDLE_MODE || gifRegs->stat.P1Q == true)
|
||||
if (GSTransferStatus.PTH3 < IDLE_MODE || gifRegs.stat.P1Q == true)
|
||||
{
|
||||
if(gifRegs->stat.APATH == GIF_APATH2 || ((GSTransferStatus.PTH3 <= IMAGE_MODE && gifRegs->stat.IMT && (vif1.cmd & 0x7f) == 0x50)) && gifRegs->stat.P1Q == false)
|
||||
if(gifRegs.stat.APATH == GIF_APATH2 || ((GSTransferStatus.PTH3 <= IMAGE_MODE && gifRegs.stat.IMT && (vif1.cmd & 0x7f) == 0x50)) && gifRegs.stat.P1Q == false)
|
||||
{
|
||||
//Do nothing, allow it
|
||||
vif1Regs->stat.VGW = false;
|
||||
//if(gifRegs->stat.APATH != GIF_APATH2)DevCon.Warning("Continue DIRECT/HL %x P3 %x APATH %x P1Q %x", vif1.cmd, GSTransferStatus.PTH3, gifRegs->stat.APATH, gifRegs->stat.P1Q);
|
||||
vif1Regs.stat.VGW = false;
|
||||
//if(gifRegs.stat.APATH != GIF_APATH2)DevCon.Warning("Continue DIRECT/HL %x P3 %x APATH %x P1Q %x", vif1.cmd, GSTransferStatus.PTH3, gifRegs.stat.APATH, gifRegs.stat.P1Q);
|
||||
}
|
||||
else
|
||||
{
|
||||
//DevCon.Warning("Stall DIRECT/HL %x P3 %x APATH %x P1Q %x", vif1.cmd, GSTransferStatus.PTH3, gifRegs->stat.APATH, gifRegs->stat.P1Q);
|
||||
vif1Regs->stat.VGW = true; // PATH3 is in image mode (DIRECTHL), or busy (BOTH no IMT)
|
||||
//DevCon.Warning("Stall DIRECT/HL %x P3 %x APATH %x P1Q %x", vif1.cmd, GSTransferStatus.PTH3, gifRegs.stat.APATH, gifRegs.stat.P1Q);
|
||||
vif1Regs.stat.VGW = true; // PATH3 is in image mode (DIRECTHL), or busy (BOTH no IMT)
|
||||
vif1.GifWaitState = 0;
|
||||
vif1.vifstalled = true;
|
||||
return 0;
|
||||
|
@ -158,19 +159,19 @@ template<int idx> __fi int _vifCode_Direct(int pass, const u8* data, bool isDire
|
|||
vif1.vifstalled = true;
|
||||
return 0;
|
||||
}
|
||||
if (gifRegs->stat.PSE) // temporarily stop
|
||||
if (gifRegs.stat.PSE) // temporarily stop
|
||||
{
|
||||
Console.WriteLn("Gif dma temp paused? VIF DIRECT");
|
||||
vif1.GifWaitState = 3;
|
||||
vif1.vifstalled = true;
|
||||
vif1Regs->stat.VGW = true;
|
||||
vif1Regs.stat.VGW = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// HACK ATTACK!
|
||||
// we shouldn't be clearing the queue flag here at all. Ideally, the queue statuses
|
||||
// should be checked, handled, and cleared from the EOP check in GIFPath only. --air
|
||||
gifRegs->stat.clear_flags(GIF_STAT_P2Q);
|
||||
gifRegs.stat.clear_flags(GIF_STAT_P2Q);
|
||||
|
||||
uint minSize = aMin(vif1.vifpacketsize, vif1.tag.size);
|
||||
uint ret;
|
||||
|
@ -259,12 +260,12 @@ vifOp(vifCode_FlushA) {
|
|||
pass1 {
|
||||
vifFlush(idx);
|
||||
// Gif is already transferring so wait for it.
|
||||
if (gifRegs->stat.P1Q || GSTransferStatus.PTH3 <= PENDINGSTOP_MODE) {
|
||||
//DevCon.Warning("VIF FlushA Wait MSK = %x", vif1Regs->mskpath3);
|
||||
if (gifRegs.stat.P1Q || GSTransferStatus.PTH3 <= PENDINGSTOP_MODE) {
|
||||
//DevCon.Warning("VIF FlushA Wait MSK = %x", vif1Regs.mskpath3);
|
||||
//
|
||||
|
||||
//DevCon.WriteLn("FlushA path3 Wait! PTH3 MD %x STR %x", GSTransferStatus.PTH3, gif->chcr.STR);
|
||||
vif1Regs->stat.VGW = true;
|
||||
vif1Regs.stat.VGW = true;
|
||||
vifX.GifWaitState = 1;
|
||||
vifX.vifstalled = true;
|
||||
} // else DevCon.WriteLn("FlushA path3 no Wait! PTH3 MD %x STR %x", GSTransferStatus.PTH3, gif->chcr.STR);
|
||||
|
@ -284,7 +285,7 @@ vifOp(vifCode_FlushE) {
|
|||
}
|
||||
|
||||
vifOp(vifCode_ITop) {
|
||||
pass1 { vifXRegs->itops = vifXRegs->code & 0x3ff; GetVifX.cmd = 0; }
|
||||
pass1 { vifXRegs.itops = vifXRegs.code & 0x3ff; GetVifX.cmd = 0; }
|
||||
pass3 { VifCodeLog("ITop"); }
|
||||
return 0;
|
||||
}
|
||||
|
@ -292,8 +293,8 @@ vifOp(vifCode_ITop) {
|
|||
vifOp(vifCode_Mark) {
|
||||
vifStruct& vifX = GetVifX;
|
||||
pass1 {
|
||||
vifXRegs->mark = (u16)vifXRegs->code;
|
||||
vifXRegs->stat.MRK = true;
|
||||
vifXRegs.mark = (u16)vifXRegs.code;
|
||||
vifXRegs.stat.MRK = true;
|
||||
vifX.cmd = 0;
|
||||
}
|
||||
pass3 { VifCodeLog("Mark"); }
|
||||
|
@ -316,8 +317,8 @@ static __fi void _vifCode_MPG(int idx, u32 addr, const u32 *data, int size) {
|
|||
vifOp(vifCode_MPG) {
|
||||
vifStruct& vifX = GetVifX;
|
||||
pass1 {
|
||||
int vifNum = (u8)(vifXRegs->code >> 16);
|
||||
vifX.tag.addr = (u16)(vifXRegs->code << 3) & (idx ? 0x3fff : 0xfff);
|
||||
int vifNum = (u8)(vifXRegs.code >> 16);
|
||||
vifX.tag.addr = (u16)(vifXRegs.code << 3) & (idx ? 0x3fff : 0xfff);
|
||||
vifX.tag.size = vifNum ? (vifNum*2) : 512;
|
||||
//vifFlush(idx);
|
||||
return 1;
|
||||
|
@ -349,14 +350,14 @@ vifOp(vifCode_MPG) {
|
|||
|
||||
vifOp(vifCode_MSCAL) {
|
||||
vifStruct& vifX = GetVifX;
|
||||
pass1 { vifFlush(idx); vuExecMicro(idx, (u16)(vifXRegs->code) << 3); vifX.cmd = 0;}
|
||||
pass1 { vifFlush(idx); vuExecMicro(idx, (u16)(vifXRegs.code) << 3); vifX.cmd = 0;}
|
||||
pass3 { VifCodeLog("MSCAL"); }
|
||||
return 0;
|
||||
}
|
||||
|
||||
vifOp(vifCode_MSCALF) {
|
||||
vifStruct& vifX = GetVifX;
|
||||
pass1 { vifFlush(idx); vuExecMicro(idx, (u16)(vifXRegs->code) << 3); vifX.cmd = 0; }
|
||||
pass1 { vifFlush(idx); vuExecMicro(idx, (u16)(vifXRegs.code) << 3); vifX.cmd = 0; }
|
||||
pass3 { VifCodeLog("MSCALF"); }
|
||||
return 0;
|
||||
}
|
||||
|
@ -372,12 +373,12 @@ vifOp(vifCode_MSCNT) {
|
|||
vifOp(vifCode_MskPath3) {
|
||||
vif1Only();
|
||||
pass1 {
|
||||
if (vif1ch->chcr.STR && vif1.lastcmd != 0x13) {
|
||||
schedulepath3msk = 0x10 | ((vif1Regs->code >> 15) & 0x1);
|
||||
if (vif1ch.chcr.STR && vif1.lastcmd != 0x13) {
|
||||
schedulepath3msk = 0x10 | ((vif1Regs.code >> 15) & 0x1);
|
||||
vif1.vifstalled = true;
|
||||
}
|
||||
else {
|
||||
schedulepath3msk = (vif1Regs->code >> 15) & 0x1;
|
||||
schedulepath3msk = (vif1Regs.code >> 15) & 0x1;
|
||||
Vif1MskPath3();
|
||||
}
|
||||
vif1.cmd = 0;
|
||||
|
@ -397,9 +398,9 @@ vifOp(vifCode_Null) {
|
|||
vifStruct& vifX = GetVifX;
|
||||
pass1 {
|
||||
// if ME1, then force the vif to interrupt
|
||||
if (!(vifXRegs->err.ME1)) { // Ignore vifcode and tag mismatch error
|
||||
if (!(vifXRegs.err.ME1)) { // Ignore vifcode and tag mismatch error
|
||||
Console.WriteLn("Vif%d: Unknown VifCmd! [%x]", idx, vifX.cmd);
|
||||
vifXRegs->stat.ER1 = true;
|
||||
vifXRegs.stat.ER1 = true;
|
||||
vifX.vifstalled = true;
|
||||
//vifX.irq++;
|
||||
}
|
||||
|
@ -413,9 +414,9 @@ vifOp(vifCode_Null) {
|
|||
vifOp(vifCode_Offset) {
|
||||
vif1Only();
|
||||
pass1 {
|
||||
vif1Regs->stat.DBF = false;
|
||||
vif1Regs->ofst = vif1Regs->code & 0x3ff;
|
||||
vif1Regs->tops = vif1Regs->base;
|
||||
vif1Regs.stat.DBF = false;
|
||||
vif1Regs.ofst = vif1Regs.code & 0x3ff;
|
||||
vif1Regs.tops = vif1Regs.base;
|
||||
vif1.cmd = 0;
|
||||
}
|
||||
pass3 { VifCodeLog("Offset"); }
|
||||
|
@ -462,7 +463,7 @@ vifOp(vifCode_STCol) {
|
|||
}
|
||||
pass2 {
|
||||
u32* cols = idx ? g_vifmask.Col1 : g_vifmask.Col0;
|
||||
u32* pmem1 = &vifXRegs->c0 + (vifX.tag.addr << 2);
|
||||
u32* pmem1 = &vifXRegs.c0 + (vifX.tag.addr << 2);
|
||||
u32* pmem2 = cols + vifX.tag.addr;
|
||||
return _vifCode_STColRow<idx>(data, pmem1, pmem2);
|
||||
}
|
||||
|
@ -480,7 +481,7 @@ vifOp(vifCode_STRow) {
|
|||
}
|
||||
pass2 {
|
||||
u32* rows = idx ? g_vifmask.Row1 : g_vifmask.Row0;
|
||||
u32* pmem1 = &vifXRegs->r0 + (vifX.tag.addr << 2);
|
||||
u32* pmem1 = &vifXRegs.r0 + (vifX.tag.addr << 2);
|
||||
u32* pmem2 = rows + vifX.tag.addr;
|
||||
return _vifCode_STColRow<idx>(data, pmem1, pmem2);
|
||||
}
|
||||
|
@ -491,8 +492,8 @@ vifOp(vifCode_STRow) {
|
|||
vifOp(vifCode_STCycl) {
|
||||
vifStruct& vifX = GetVifX;
|
||||
pass1 {
|
||||
vifXRegs->cycle.cl = (u8)(vifXRegs->code);
|
||||
vifXRegs->cycle.wl = (u8)(vifXRegs->code >> 8);
|
||||
vifXRegs.cycle.cl = (u8)(vifXRegs.code);
|
||||
vifXRegs.cycle.wl = (u8)(vifXRegs.code >> 8);
|
||||
vifX.cmd = 0;
|
||||
}
|
||||
pass3 { VifCodeLog("STCycl"); }
|
||||
|
@ -502,13 +503,13 @@ vifOp(vifCode_STCycl) {
|
|||
vifOp(vifCode_STMask) {
|
||||
vifStruct& vifX = GetVifX;
|
||||
pass1 { vifX.tag.size = 1; }
|
||||
pass2 { vifXRegs->mask = data[0]; vifX.tag.size = 0; vifX.cmd = 0; }
|
||||
pass2 { vifXRegs.mask = data[0]; vifX.tag.size = 0; vifX.cmd = 0; }
|
||||
pass3 { VifCodeLog("STMask"); }
|
||||
return 1;
|
||||
}
|
||||
|
||||
vifOp(vifCode_STMod) {
|
||||
pass1 { vifXRegs->mode = vifXRegs->code & 0x3; GetVifX.cmd = 0; }
|
||||
pass1 { vifXRegs.mode = vifXRegs.code & 0x3; GetVifX.cmd = 0; }
|
||||
pass3 { VifCodeLog("STMod"); }
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -14,6 +14,8 @@
|
|||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Vif.h"
|
||||
#include "Vif_Unpack.h"
|
||||
|
||||
struct vifCode {
|
||||
|
@ -84,13 +86,13 @@ extern vifStruct* vif;
|
|||
extern vifStruct vif0, vif1;
|
||||
extern u8 schedulepath3msk;
|
||||
|
||||
_vifT extern bool vifWrite32(u32 mem, u32 value);
|
||||
|
||||
extern void vif0Interrupt();
|
||||
extern void vif0Write32(u32 mem, u32 value);
|
||||
extern void vif0Reset();
|
||||
|
||||
extern void vif1Interrupt();
|
||||
extern void Vif1MskPath3();
|
||||
extern void vif1Write32(u32 mem, u32 value);
|
||||
extern void vif1Reset();
|
||||
|
||||
typedef int __fastcall FnType_VifCmdHandler(int pass, const u32 *data);
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
|
||||
// Doesn't stall if the next vifCode is the Mark command
|
||||
_vifT bool runMark(u32* &data) {
|
||||
if (((vifXRegs->code >> 24) & 0x7f) == 0x7) {
|
||||
if (((vifXRegs.code >> 24) & 0x7f) == 0x7) {
|
||||
Console.WriteLn("Vif%d: Running Mark with I-bit", idx);
|
||||
return 1; // No Stall?
|
||||
}
|
||||
|
@ -34,7 +34,7 @@ _vifT bool runMark(u32* &data) {
|
|||
// Returns 1 if i-bit && finished vifcode && i-bit not masked
|
||||
_vifT bool analyzeIbit(u32* &data, int iBit) {
|
||||
vifStruct& vifX = GetVifX;
|
||||
if (iBit && !vifX.cmd && !vifXRegs->err.MII) {
|
||||
if (iBit && !vifX.cmd && !vifXRegs.err.MII) {
|
||||
//DevCon.WriteLn("Vif I-Bit IRQ");
|
||||
vifX.irq++;
|
||||
|
||||
|
@ -75,14 +75,14 @@ _vifT void vifTransferLoop(u32* &data) {
|
|||
u32& pSize = vifX.vifpacketsize;
|
||||
int iBit = vifX.cmd >> 7;
|
||||
|
||||
vifXRegs->stat.VPS |= VPS_TRANSFERRING;
|
||||
vifXRegs->stat.ER1 = false;
|
||||
vifXRegs.stat.VPS |= VPS_TRANSFERRING;
|
||||
vifXRegs.stat.ER1 = false;
|
||||
|
||||
while (pSize > 0 && !vifX.vifstalled) {
|
||||
|
||||
if(!vifX.cmd) { // Get new VifCode
|
||||
vifX.lastcmd = (vifXRegs->code >> 24) & 0x7f;
|
||||
vifXRegs->code = data[0];
|
||||
vifX.lastcmd = (vifXRegs.code >> 24) & 0x7f;
|
||||
vifXRegs.code = data[0];
|
||||
vifX.cmd = data[0] >> 24;
|
||||
iBit = data[0] >> 31;
|
||||
|
||||
|
@ -135,20 +135,20 @@ _vifT static __fi bool vifTransfer(u32 *data, int size) {
|
|||
|
||||
transferred = transferred >> 2;
|
||||
|
||||
vifXch->madr +=(transferred << 4);
|
||||
vifXch->qwc -= transferred;
|
||||
vifXch.madr +=(transferred << 4);
|
||||
vifXch.qwc -= transferred;
|
||||
|
||||
if (!vifXch->qwc && !vifX.irqoffset) vifX.inprogress &= ~0x1;
|
||||
if (!vifXch.qwc && !vifX.irqoffset) vifX.inprogress &= ~0x1;
|
||||
|
||||
if (vifX.irq && vifX.cmd == 0) {
|
||||
//DevCon.WriteLn("Vif IRQ!");
|
||||
if(((vifXRegs->code >> 24) & 0x7f) != 0x7)
|
||||
if(((vifXRegs.code >> 24) & 0x7f) != 0x7)
|
||||
{
|
||||
vifX.vifstalled = true;
|
||||
vifXRegs->stat.VIS = true; // Note: commenting this out fixes WALL-E?
|
||||
vifXRegs.stat.VIS = true; // Note: commenting this out fixes WALL-E?
|
||||
}
|
||||
|
||||
if (!vifXch->qwc && !vifX.irqoffset) vifX.inprogress &= ~1;
|
||||
if (!vifXch.qwc && !vifX.irqoffset) vifX.inprogress &= ~1;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -302,8 +302,8 @@ _vifT void vifUnpackSetup(const u32 *data) {
|
|||
|
||||
vifStruct& vifX = GetVifX;
|
||||
|
||||
if ((vifXRegs->cycle.wl == 0) && (vifXRegs->cycle.wl < vifXRegs->cycle.cl)) {
|
||||
Console.WriteLn("Vif%d CL %d, WL %d", idx, vifXRegs->cycle.cl, vifXRegs->cycle.wl);
|
||||
if ((vifXRegs.cycle.wl == 0) && (vifXRegs.cycle.wl < vifXRegs.cycle.cl)) {
|
||||
Console.WriteLn("Vif%d CL %d, WL %d", idx, vifXRegs.cycle.cl, vifXRegs.cycle.wl);
|
||||
vifX.cmd = 0;
|
||||
return; // Skipping write and 0 write-cycles, so do nothing!
|
||||
}
|
||||
|
@ -311,33 +311,33 @@ _vifT void vifUnpackSetup(const u32 *data) {
|
|||
|
||||
//if (!idx) vif0FLUSH(); // Only VU0?
|
||||
|
||||
vifX.usn = (vifXRegs->code >> 14) & 0x01;
|
||||
int vifNum = (vifXRegs->code >> 16) & 0xff;
|
||||
vifX.usn = (vifXRegs.code >> 14) & 0x01;
|
||||
int vifNum = (vifXRegs.code >> 16) & 0xff;
|
||||
|
||||
if (vifNum == 0) vifNum = 256;
|
||||
vifXRegs->num = vifNum;
|
||||
vifXRegs.num = vifNum;
|
||||
|
||||
if (vifXRegs->cycle.wl <= vifXRegs->cycle.cl) {
|
||||
if (vifXRegs.cycle.wl <= vifXRegs.cycle.cl) {
|
||||
if (!idx) vif0.tag.size = ((vifNum * VIFfuncTable[ vif0.cmd & 0xf ].gsize) + 3) >> 2;
|
||||
else vif1.tag.size = ((vifNum * VIFfuncTable[ vif1.cmd & 0xf ].gsize) + 3) >> 2;
|
||||
}
|
||||
else {
|
||||
int n = vifXRegs->cycle.cl * (vifNum / vifXRegs->cycle.wl) +
|
||||
_limit(vifNum % vifXRegs->cycle.wl, vifXRegs->cycle.cl);
|
||||
int n = vifXRegs.cycle.cl * (vifNum / vifXRegs.cycle.wl) +
|
||||
_limit(vifNum % vifXRegs.cycle.wl, vifXRegs.cycle.cl);
|
||||
|
||||
if (!idx) vif0.tag.size = ((n * VIFfuncTable[ vif0.cmd & 0xf ].gsize) + 3) >> 2;
|
||||
else vif1.tag.size = ((n * VIFfuncTable[ vif1.cmd & 0xf ].gsize) + 3) >> 2;
|
||||
}
|
||||
|
||||
u32 addr = vifXRegs->code;
|
||||
if (idx && ((addr>>15)&1)) addr += vif1Regs->tops;
|
||||
u32 addr = vifXRegs.code;
|
||||
if (idx && ((addr>>15)&1)) addr += vif1Regs.tops;
|
||||
vifX.tag.addr = (addr<<4) & (idx ? 0x3ff0 : 0xff0);
|
||||
|
||||
VIF_LOG("Unpack VIF%x, QWC %x tagsize %x", idx, vifNum, vif0.tag.size);
|
||||
|
||||
vifX.cl = 0;
|
||||
vifX.tag.cmd = vifX.cmd;
|
||||
vifXRegs->offset = 0;
|
||||
vifXRegs.offset = 0;
|
||||
}
|
||||
|
||||
template void vifUnpackSetup<0>(const u32 *data);
|
||||
|
|
|
@ -26,12 +26,12 @@ template<const u32 VIFdmanum> void VIFunpack(u32 *data, vifCode *v, u32 size) {
|
|||
|
||||
if (VIFdmanum == 0) {
|
||||
VU = &VU0;
|
||||
vifRegs = vif0Regs;
|
||||
vifRegs = &vif0Regs;
|
||||
vif = &vif0;
|
||||
}
|
||||
else {
|
||||
VU = &VU1;
|
||||
vifRegs = vif1Regs;
|
||||
vifRegs = &vif1Regs;
|
||||
vif = &vif1;
|
||||
}
|
||||
|
||||
|
|
|
@ -993,7 +993,7 @@ void Pcsx2App::ProgramLog_PostEvent( wxEvent& evt )
|
|||
static void __concall ConsoleToFile_Newline()
|
||||
{
|
||||
#ifdef __LINUX__
|
||||
if (g_Conf->EmuOptions.ConsoleToStdio) ConsoleWriter_Stdout.Newline();
|
||||
if ((g_Conf) && (g_Conf->EmuOptions.ConsoleToStdio)) ConsoleWriter_Stdout.Newline();
|
||||
#endif
|
||||
|
||||
#ifdef __LINUX__
|
||||
|
@ -1006,7 +1006,7 @@ static void __concall ConsoleToFile_Newline()
|
|||
static void __concall ConsoleToFile_DoWrite( const wxString& fmt )
|
||||
{
|
||||
#ifdef __LINUX__
|
||||
if (g_Conf->EmuOptions.ConsoleToStdio) ConsoleWriter_Stdout.WriteRaw(fmt);
|
||||
if ((g_Conf) && (g_Conf->EmuOptions.ConsoleToStdio)) ConsoleWriter_Stdout.WriteRaw(fmt);
|
||||
#endif
|
||||
|
||||
px_fputs( emuLog, fmt.ToUTF8() );
|
||||
|
|
|
@ -358,7 +358,7 @@ static __fi void gsHandler(const u8* pMem)
|
|||
// games must take care to ensure transfer rectangles are exact multiples of a qword
|
||||
vif1.GSLastDownloadSize = vif1.TRXREG.RRW * vif1.TRXREG.RRH * bpp >> 7;
|
||||
//DevCon.Warning("GS download in progress");
|
||||
gifRegs->stat.OPH = true;
|
||||
gifRegs.stat.OPH = true;
|
||||
}
|
||||
}
|
||||
if (reg >= 0x60)
|
||||
|
@ -602,7 +602,7 @@ __fi int GIFPath::CopyTag(const u128* pMem128, u32 size)
|
|||
else GSTransferStatus.PTH2 = TRANSFER_MODE;
|
||||
break;
|
||||
case GIF_PATH_3:
|
||||
if(vif1Regs->mskpath3 == 1 && GSTransferStatus.PTH3 == STOPPED_MODE)
|
||||
if(vif1Regs.mskpath3 == 1 && GSTransferStatus.PTH3 == STOPPED_MODE)
|
||||
{
|
||||
GSTransferStatus.PTH3 = IDLE_MODE;
|
||||
|
||||
|
@ -618,8 +618,8 @@ __fi int GIFPath::CopyTag(const u128* pMem128, u32 size)
|
|||
}
|
||||
if(GSTransferStatus.PTH3 < PENDINGSTOP_MODE || pathidx != 2)
|
||||
{
|
||||
gifRegs->stat.OPH = true;
|
||||
gifRegs->stat.APATH = pathidx + 1;
|
||||
gifRegs.stat.OPH = true;
|
||||
gifRegs.stat.APATH = pathidx + 1;
|
||||
}
|
||||
|
||||
if(pathidx == GIF_PATH_3)
|
||||
|
@ -645,8 +645,8 @@ __fi int GIFPath::CopyTag(const u128* pMem128, u32 size)
|
|||
|
||||
break;
|
||||
}
|
||||
gifRegs->stat.APATH = pathidx + 1;
|
||||
gifRegs->stat.OPH = true;
|
||||
gifRegs.stat.APATH = pathidx + 1;
|
||||
gifRegs.stat.OPH = true;
|
||||
|
||||
switch(tag.FLG) {
|
||||
case GIF_FLG_PACKED:
|
||||
|
@ -809,10 +809,10 @@ __fi int GIFPath::CopyTag(const u128* pMem128, u32 size)
|
|||
// FINISH is *not* a per-path register, and it seems to pretty clearly indicate that all active
|
||||
// drawing *and* image transfer actions must be finished before the IRQ raises.
|
||||
|
||||
if(gifRegs->stat.P1Q || gifRegs->stat.P2Q || gifRegs->stat.P3Q)
|
||||
if(gifRegs.stat.P1Q || gifRegs.stat.P2Q || gifRegs.stat.P3Q)
|
||||
{
|
||||
//GH3 and possibly others have path data queued waiting for another path to finish! we need to check they are done too
|
||||
//DevCon.Warning("Early FINISH signal! P1 %x P2 %x P3 %x", gifRegs->stat.P1Q, gifRegs->stat.P2Q, gifRegs->stat.P3Q);
|
||||
//DevCon.Warning("Early FINISH signal! P1 %x P2 %x P3 %x", gifRegs.stat.P1Q, gifRegs.stat.P2Q, gifRegs.stat.P3Q);
|
||||
}
|
||||
else if (!(GSIMR&0x200) && !s_gifPath.path[0].IsActive() && !s_gifPath.path[1].IsActive() && !s_gifPath.path[2].IsActive())
|
||||
{
|
||||
|
@ -835,8 +835,8 @@ __fi int GIFPath::CopyTag(const u128* pMem128, u32 size)
|
|||
|
||||
if (tag.EOP && nloop == 0) {
|
||||
|
||||
/*if(gifRegs->stat.DIR == 0)gifRegs->stat.OPH = false;
|
||||
gifRegs->stat.APATH = GIF_APATH_IDLE;*/
|
||||
/*if(gifRegs.stat.DIR == 0)gifRegs.stat.OPH = false;
|
||||
gifRegs.stat.APATH = GIF_APATH_IDLE;*/
|
||||
switch(pathidx)
|
||||
{
|
||||
case GIF_PATH_1:
|
||||
|
@ -849,10 +849,10 @@ __fi int GIFPath::CopyTag(const u128* pMem128, u32 size)
|
|||
//For huge chunks we may have delay problems, so we need to stall it till the interrupt, else we get desync (Lemmings)
|
||||
if(size > 8) GSTransferStatus.PTH3 = PENDINGSTOP_MODE;
|
||||
else GSTransferStatus.PTH3 = STOPPED_MODE;
|
||||
if (gif->chcr.STR) { //Make sure we are really doing a DMA and not using FIFO
|
||||
if (gifch.chcr.STR) { //Make sure we are really doing a DMA and not using FIFO
|
||||
//GIF_LOG("Path3 end EOP %x NLOOP %x Status %x", tag.EOP, nloop, GSTransferStatus.PTH3);
|
||||
gif->madr += size * 16;
|
||||
gif->qwc -= size;
|
||||
gifch.madr += size * 16;
|
||||
gifch.qwc -= size;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -860,10 +860,10 @@ __fi int GIFPath::CopyTag(const u128* pMem128, u32 size)
|
|||
else if(pathidx == 2)
|
||||
{
|
||||
//if(nloop <= 16 && GSTransferStatus.PTH3 == IMAGE_MODE)GSTransferStatus.PTH3 = PENDINGIMAGE_MODE;
|
||||
if (gif->chcr.STR) { //Make sure we are really doing a DMA and not using FIFO
|
||||
if (gifch.chcr.STR) { //Make sure we are really doing a DMA and not using FIFO
|
||||
//GIF_LOG("Path3 end EOP %x NLOOP %x Status %x", tag.EOP, nloop, GSTransferStatus.PTH3);
|
||||
gif->madr += size * 16;
|
||||
gif->qwc -= size;
|
||||
gifch.madr += size * 16;
|
||||
gifch.qwc -= size;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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:
|
||||
if( masked_addr >= 0x100 && masked_addr < 0x130 )
|
||||
{
|
||||
DevCon.Warning( "HwRead8 from Counter16 [ignored], addr 0x%08x = 0x%02x", addr, psxHu8(addr) );
|
||||
DevCon.Warning( "HwRead8 from Counter16 [ignored] @ 0x%08x = 0x%02x", addr, psxHu8(addr) );
|
||||
ret = psxHu8( addr );
|
||||
}
|
||||
else if( masked_addr >= 0x480 && masked_addr < 0x4a0 )
|
||||
{
|
||||
DevCon.Warning( "HwRead8 from Counter32 [ignored], addr 0x%08x = 0x%02x", addr, psxHu8(addr) );
|
||||
DevCon.Warning( "HwRead8 from Counter32 [ignored] @ 0x%08x = 0x%02x", addr, psxHu8(addr) );
|
||||
ret = psxHu8( addr );
|
||||
}
|
||||
else if( (masked_addr >= pgmsk(HW_USB_START)) && (masked_addr < pgmsk(HW_USB_END)) )
|
||||
{
|
||||
ret = USBread8( addr );
|
||||
PSXHW_LOG( "HwRead8 from USB, addr 0x%08x = 0x%02x", addr, ret );
|
||||
PSXHW_LOG( "HwRead8 from USB @ 0x%08x = 0x%02x", addr, ret );
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = psxHu8(addr);
|
||||
PSXUnkHW_LOG( "HwRead8 from Unknown, addr 0x%08x = 0x%02x", addr, ret );
|
||||
PSXUnkHW_LOG( "HwRead8 from Unknown @ 0x%08x = 0x%02x", addr, ret );
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
IopHwTraceLog<mem8_t>( addr, ret, "Read" );
|
||||
IopHwTraceLog<mem8_t>( addr, ret, true );
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -89,7 +89,7 @@ mem8_t __fastcall iopHwRead8_Page3( u32 addr )
|
|||
else
|
||||
ret = psxHu8( addr );
|
||||
|
||||
IopHwTraceLog<mem8_t>( addr, ret, "Read" );
|
||||
IopHwTraceLog<mem8_t>( addr, ret, true );
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -107,7 +107,7 @@ mem8_t __fastcall iopHwRead8_Page8( u32 addr )
|
|||
else
|
||||
ret = psxHu8( addr );
|
||||
|
||||
IopHwTraceLog<mem8_t>( addr, ret, "Read" );
|
||||
IopHwTraceLog<mem8_t>( addr, ret, true );
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -216,7 +216,7 @@ static __fi T _HwRead_16or32_Page1( u32 addr )
|
|||
ret = SPU2read( addr );
|
||||
else
|
||||
{
|
||||
DevCon.Warning( "HwRead32 from SPU2? (addr=0x%08X) .. What manner of trickery is this?!", addr );
|
||||
DbgCon.Warning( "HwRead32 from SPU2? @ 0x%08X .. What manner of trickery is this?!", addr );
|
||||
ret = psxHu32(addr);
|
||||
}
|
||||
}
|
||||
|
@ -320,7 +320,7 @@ static __fi T _HwRead_16or32_Page1( u32 addr )
|
|||
}
|
||||
}
|
||||
|
||||
IopHwTraceLog<T>( addr, ret, "Read" );
|
||||
IopHwTraceLog<T>( addr, ret, true );
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -343,7 +343,7 @@ mem16_t __fastcall iopHwRead16_Page3( u32 addr )
|
|||
jASSUME( (addr >> 12) == 0x1f803 );
|
||||
|
||||
mem16_t ret = psxHu16(addr);
|
||||
IopHwTraceLog<mem16_t>( addr, ret, "Read" );
|
||||
IopHwTraceLog<mem16_t>( addr, ret, true );
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -355,7 +355,7 @@ mem16_t __fastcall iopHwRead16_Page8( u32 addr )
|
|||
jASSUME( (addr >> 12) == 0x1f808 );
|
||||
|
||||
mem16_t ret = psxHu16(addr);
|
||||
IopHwTraceLog<mem16_t>( addr, ret, "Read" );
|
||||
IopHwTraceLog<mem16_t>( addr, ret, true );
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -373,7 +373,7 @@ mem32_t __fastcall iopHwRead32_Page3( u32 addr )
|
|||
// all addresses are assumed to be prefixed with 0x1f803xxx:
|
||||
jASSUME( (addr >> 12) == 0x1f803 );
|
||||
const mem32_t ret = psxHu32(addr);
|
||||
IopHwTraceLog<mem32_t>( addr, ret, "Read" );
|
||||
IopHwTraceLog<mem32_t>( addr, ret, true );
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -437,7 +437,7 @@ mem32_t __fastcall iopHwRead32_Page8( u32 addr )
|
|||
}
|
||||
else ret = psxHu32(addr);
|
||||
|
||||
IopHwTraceLog<mem32_t>( addr, ret, "Read" );
|
||||
IopHwTraceLog<mem32_t>( addr, ret, true );
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
@ -33,7 +33,7 @@ template< typename T >
|
|||
static __fi void _generic_write( u32 addr, T val )
|
||||
{
|
||||
//int bitsize = (sizeof(T) == 1) ? 8 : ( (sizeof(T) == 2) ? 16 : 32 );
|
||||
IopHwTraceLog<T>( addr, val, "Write" );
|
||||
IopHwTraceLog<T>( addr, val, false );
|
||||
psxHu(addr) = val;
|
||||
}
|
||||
|
||||
|
@ -49,7 +49,7 @@ static __fi T _generic_read( u32 addr )
|
|||
//int bitsize = (sizeof(T) == 1) ? 8 : ( (sizeof(T) == 2) ? 16 : 32 );
|
||||
|
||||
T ret = psxHu(addr);
|
||||
IopHwTraceLog<T>( addr, ret, "Read" );
|
||||
IopHwTraceLog<T>( addr, ret, true );
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -84,12 +84,12 @@ void __fastcall iopHwWrite8_Page1( u32 addr, mem8_t val )
|
|||
default:
|
||||
if( masked_addr >= 0x100 && masked_addr < 0x130 )
|
||||
{
|
||||
DevCon.Warning( "HwWrite8 to Counter16 [ignored], addr 0x%08x = 0x%02x", addr, psxHu8(addr) );
|
||||
DbgCon.Warning( "HwWrite8 to Counter16 [ignored] @ addr 0x%08x = 0x%02x", addr, psxHu8(addr) );
|
||||
psxHu8( addr ) = val;
|
||||
}
|
||||
else if( masked_addr >= 0x480 && masked_addr < 0x4a0 )
|
||||
{
|
||||
DevCon.Warning( "HwWrite8 to Counter32 [ignored], addr 0x%08x = 0x%02x", addr, psxHu8(addr) );
|
||||
DbgCon.Warning( "HwWrite8 to Counter32 [ignored] @ addr 0x%08x = 0x%02x", addr, psxHu8(addr) );
|
||||
psxHu8( addr ) = val;
|
||||
}
|
||||
else if( (masked_addr >= pgmsk(HW_USB_START)) && (masked_addr < pgmsk(HW_USB_END)) )
|
||||
|
@ -103,7 +103,7 @@ void __fastcall iopHwWrite8_Page1( u32 addr, mem8_t val )
|
|||
break;
|
||||
}
|
||||
|
||||
IopHwTraceLog<mem8_t>( addr, val, "Write" );
|
||||
IopHwTraceLog<mem8_t>( addr, val, false );
|
||||
}
|
||||
|
||||
void __fastcall iopHwWrite8_Page3( u32 addr, mem8_t val )
|
||||
|
@ -137,7 +137,7 @@ void __fastcall iopHwWrite8_Page3( u32 addr, mem8_t val )
|
|||
}
|
||||
|
||||
psxHu8( addr ) = val;
|
||||
IopHwTraceLog<mem8_t>( addr, val, "Write" );
|
||||
IopHwTraceLog<mem8_t>( addr, val, false );
|
||||
}
|
||||
|
||||
void __fastcall iopHwWrite8_Page8( u32 addr, mem8_t val )
|
||||
|
@ -150,7 +150,7 @@ void __fastcall iopHwWrite8_Page8( u32 addr, mem8_t val )
|
|||
else
|
||||
psxHu8( addr ) = val;
|
||||
|
||||
IopHwTraceLog<mem8_t>( addr, val, "Write" );
|
||||
IopHwTraceLog<mem8_t>( addr, val, false );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -244,7 +244,7 @@ static __fi void _HwWrite_16or32_Page1( u32 addr, T val )
|
|||
SPU2write( addr, val );
|
||||
else
|
||||
{
|
||||
DevCon.Warning( "HwWrite32 to SPU2? (addr=0x%08X) .. What manner of trickery is this?!", addr );
|
||||
DbgCon.Warning( "HwWrite32 to SPU2? @ 0x%08X .. What manner of trickery is this?!", addr );
|
||||
//psxHu(addr) = val;
|
||||
}
|
||||
}
|
||||
|
@ -481,7 +481,7 @@ static __fi void _HwWrite_16or32_Page1( u32 addr, T val )
|
|||
}
|
||||
}
|
||||
|
||||
IopHwTraceLog<T>( addr, val, "Write" );
|
||||
IopHwTraceLog<T>( addr, val, false );
|
||||
}
|
||||
|
||||
|
||||
|
@ -497,7 +497,7 @@ void __fastcall iopHwWrite16_Page3( u32 addr, mem16_t val )
|
|||
// all addresses are assumed to be prefixed with 0x1f803xxx:
|
||||
pxAssert( (addr >> 12) == 0x1f803 );
|
||||
psxHu16(addr) = val;
|
||||
IopHwTraceLog<mem16_t>( addr, val, "Write" );
|
||||
IopHwTraceLog<mem16_t>( addr, val, false );
|
||||
}
|
||||
|
||||
void __fastcall iopHwWrite16_Page8( u32 addr, mem16_t val )
|
||||
|
@ -505,7 +505,7 @@ void __fastcall iopHwWrite16_Page8( u32 addr, mem16_t val )
|
|||
// all addresses are assumed to be prefixed with 0x1f808xxx:
|
||||
pxAssert( (addr >> 12) == 0x1f808 );
|
||||
psxHu16(addr) = val;
|
||||
IopHwTraceLog<mem16_t>( addr, val, "Write" );
|
||||
IopHwTraceLog<mem16_t>( addr, val, false );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -520,7 +520,7 @@ void __fastcall iopHwWrite32_Page3( u32 addr, mem32_t val )
|
|||
// all addresses are assumed to be prefixed with 0x1f803xxx:
|
||||
pxAssert( (addr >> 12) == 0x1f803 );
|
||||
psxHu16(addr) = val;
|
||||
IopHwTraceLog<mem32_t>( addr, val, "Write" );
|
||||
IopHwTraceLog<mem32_t>( addr, val, false );
|
||||
}
|
||||
|
||||
void __fastcall iopHwWrite32_Page8( u32 addr, mem32_t val )
|
||||
|
@ -567,7 +567,7 @@ void __fastcall iopHwWrite32_Page8( u32 addr, mem32_t val )
|
|||
}
|
||||
else psxHu32(addr) = val;
|
||||
|
||||
IopHwTraceLog<mem32_t>( addr, val, "Write" );
|
||||
IopHwTraceLog<mem32_t>( addr, val, false );
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -38,7 +38,7 @@ namespace Internal {
|
|||
//
|
||||
|
||||
template< typename T>
|
||||
static __ri const char* _log_GetIopHwName( u32 addr, T val )
|
||||
static __ri const char* _ioplog_GetHwName( u32 addr, T val )
|
||||
{
|
||||
switch( addr )
|
||||
{
|
||||
|
@ -200,20 +200,31 @@ static __ri const char* _log_GetIopHwName( u32 addr, T val )
|
|||
}
|
||||
|
||||
template< typename T>
|
||||
static __ri void IopHwTraceLog( u32 addr, T val, const char* modestr )
|
||||
static __ri void IopHwTraceLog( u32 addr, T val, bool mode )
|
||||
{
|
||||
if( !EmuConfig.Trace.IOP.m_EnableRegisters ) return;
|
||||
if (!IsDevBuild) return;
|
||||
if (!EmuConfig.Trace.IOP.m_EnableRegisters) return;
|
||||
|
||||
static char *temp = "Hw%s%d from %s, addr 0x%08x = 0x%0*x";
|
||||
FastFormatAscii valStr;
|
||||
FastFormatAscii labelStr;
|
||||
labelStr.Write("Hw%s%u", mode ? "Read" : "Write", sizeof (T) * 8);
|
||||
|
||||
// Replace the * above with the operand size (this ensures nicely formatted
|
||||
// zero-fill hex values):
|
||||
temp[(sizeof temp)-3] = '0' + (sizeof(T)*2);
|
||||
switch( sizeof (T) )
|
||||
{
|
||||
case 1: valStr.Write("0x%02x", val); break;
|
||||
case 2: valStr.Write("0x%04x", val); break;
|
||||
case 4: valStr.Write("0x%08x", val); break;
|
||||
|
||||
if( const char* regname = _log_GetIopHwName<T>( addr, val ) )
|
||||
PSXHW_LOG( temp, modestr, (sizeof (T)) * 8, regname, addr, val );
|
||||
case 8: valStr.Write("0x%08x.%08x", ((u32*)&val)[1], ((u32*)&val)[0]); break;
|
||||
case 16: ((u128&)val).WriteTo(valStr);
|
||||
}
|
||||
|
||||
static const char* temp = "%-12s @ 0x%08X/%-16s %s %s";
|
||||
|
||||
if( const char* regname = _ioplog_GetHwName<T>( addr, val ) )
|
||||
PSXHW_LOG( temp, labelStr.c_str(), addr, regname, mode ? "->" : "<-", valStr.c_str() );
|
||||
else
|
||||
PSXUnkHW_LOG( temp, modestr, (sizeof (T)) * 8, "Unknown", addr, val );
|
||||
PSXUnkHW_LOG( temp, labelStr.c_str(), addr, "Unknown", mode ? "->" : "<-", valStr.c_str() );
|
||||
}
|
||||
|
||||
} };
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
void __fastcall vtlb_memRead128(u32 mem, u64 (&out)[2])
|
||||
{
|
||||
vtlb_memRead128(mem, (mem128_t*)out);
|
||||
}
|
||||
|
||||
template< typename DataType >
|
||||
void __fastcall vtlb_memWrite(u32 addr, DataType data)
|
||||
|
@ -159,6 +155,7 @@ void __fastcall vtlb_memWrite(u32 addr, DataType data)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
void __fastcall vtlb_memWrite64(u32 mem, const mem64_t* value)
|
||||
{
|
||||
u32 vmv=vtlbdata.vmap[mem>>VTLB_PAGE_BITS];
|
||||
|
@ -197,11 +194,6 @@ void __fastcall vtlb_memWrite128(u32 mem, const mem128_t *value)
|
|||
}
|
||||
}
|
||||
|
||||
void __fastcall vtlb_memWrite128(u32 mem, const u64 (&out)[2])
|
||||
{
|
||||
vtlb_memWrite128(mem, (const mem128_t*)out);
|
||||
}
|
||||
|
||||
template mem8_t vtlb_memRead<mem8_t>(u32 mem);
|
||||
template mem16_t vtlb_memRead<mem16_t>(u32 mem);
|
||||
template mem32_t vtlb_memRead<mem32_t>(u32 mem);
|
||||
|
|
|
@ -71,13 +71,11 @@ template< typename DataType >
|
|||
extern DataType __fastcall vtlb_memRead(u32 mem);
|
||||
extern void __fastcall vtlb_memRead64(u32 mem, mem64_t *out);
|
||||
extern void __fastcall vtlb_memRead128(u32 mem, mem128_t *out);
|
||||
extern void __fastcall vtlb_memRead128(u32 mem, u64 (&out)[2]);
|
||||
|
||||
template< typename DataType >
|
||||
extern void __fastcall vtlb_memWrite(u32 mem, DataType value);
|
||||
extern void __fastcall vtlb_memWrite64(u32 mem, const mem64_t* value);
|
||||
extern void __fastcall vtlb_memWrite128(u32 mem, const mem128_t* value);
|
||||
extern void __fastcall vtlb_memWrite128(u32 mem, const u64 (&value)[2]);
|
||||
|
||||
extern void vtlb_DynGenWrite(u32 sz);
|
||||
extern void vtlb_DynGenRead32(u32 bits, bool sign);
|
||||
|
|
|
@ -33,14 +33,14 @@ s32 PrepareEERead()
|
|||
"\n\tread tag: %x %x %x %x", hw_dma(9).madr, hw_dma(9).tadr, sif0.iop.counter, sif0words, sif0data,
|
||||
tag[0], tag[1], tag[2], tag[3]);
|
||||
|
||||
sif0dma->unsafeTransfer(((tDMA_TAG*)(tag)));
|
||||
sif0dma->madr = tag[1];
|
||||
sif0dma.unsafeTransfer(((tDMA_TAG*)(tag)));
|
||||
sif0dma.madr = tag[1];
|
||||
tDMA_TAG ptag(tag[0]);
|
||||
|
||||
SIF_LOG("SIF0 EE dest chain tag madr:%08X qwc:%04X id:%X irq:%d(%08X_%08X)",
|
||||
sif0dma->madr, sif0dma->qwc, ptag.ID, ptag.IRQ, tag[1], tag[0]);
|
||||
sif0dma.madr, sif0dma.qwc, ptag.ID, ptag.IRQ, tag[1], tag[0]);
|
||||
|
||||
if (sif0dma->chcr.TIE && ptag.IRQ)
|
||||
if (sif0dma.chcr.TIE && ptag.IRQ)
|
||||
{
|
||||
//Console.WriteLn("SIF0 TIE");
|
||||
sif0.ee.end = true;
|
||||
|
@ -50,13 +50,13 @@ s32 PrepareEERead()
|
|||
{
|
||||
case TAG_REFE:
|
||||
sif0.ee.end = true;
|
||||
if (dmacRegs->ctrl.STS != NO_STS)
|
||||
dmacRegs->stadr.ADDR = sif0dma->madr + (sif0dma->qwc * 16);
|
||||
if (dmacRegs.ctrl.STS != NO_STS)
|
||||
dmacRegs.stadr.ADDR = sif0dma.madr + (sif0dma.qwc * 16);
|
||||
break;
|
||||
|
||||
case TAG_REFS:
|
||||
if (dmacRegs->ctrl.STS != NO_STS)
|
||||
dmacRegs->stadr.ADDR = sif0dma->madr + (sif0dma->qwc * 16);
|
||||
if (dmacRegs.ctrl.STS != NO_STS)
|
||||
dmacRegs.stadr.ADDR = sif0dma.madr + (sif0dma.qwc * 16);
|
||||
break;
|
||||
|
||||
case TAG_END:
|
||||
|
@ -91,7 +91,7 @@ s32 DoSifRead(u32 iopAvailable)
|
|||
|
||||
SIF_LOG("Write IOP to EE: +++++++++++ %lX of %lX", transferSizeWords, sif0.iop.counter);
|
||||
|
||||
tDMA_TAG *ptag = sif0dma->getAddr(sif0dma->madr, DMAC_SIF0, true);
|
||||
tDMA_TAG *ptag = sif0dma.getAddr(sif0dma.madr, DMAC_SIF0, true);
|
||||
if (ptag == NULL)
|
||||
{
|
||||
DevCon.Warning("Write IOP to EE: ptag == NULL");
|
||||
|
@ -101,11 +101,11 @@ s32 DoSifRead(u32 iopAvailable)
|
|||
memcpy((u32*)ptag, (u32*)iopPhysMem(hw_dma(9).madr), transferSizeBytes);
|
||||
|
||||
// Clearing handled by vtlb memory protection and manual blocks.
|
||||
//Cpu->Clear(sif0dma->madr, readSize*4);
|
||||
//Cpu->Clear(sif0dma.madr, readSize*4);
|
||||
|
||||
sif0dma->madr += transferSizeBytes;
|
||||
sif0dma.madr += transferSizeBytes;
|
||||
sif0.ee.cycles += transferSizeQWords * 2;
|
||||
sif0dma->qwc -= transferSizeQWords;
|
||||
sif0dma.qwc -= transferSizeQWords;
|
||||
|
||||
return transferSizeBytes;
|
||||
}
|
||||
|
|
|
@ -513,6 +513,10 @@
|
|||
RelativePath="..\..\Dmac.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\ps2\eeHwTraceLog.inl"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\FiFo.cpp"
|
||||
>
|
||||
|
@ -529,6 +533,10 @@
|
|||
RelativePath="..\..\Hw.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\ps2\HwInternal.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\HwRead.cpp"
|
||||
>
|
||||
|
@ -749,6 +757,10 @@
|
|||
<Filter
|
||||
Name="DMAC"
|
||||
>
|
||||
<File
|
||||
RelativePath="..\..\ps2\LegacyDmac.cpp"
|
||||
>
|
||||
</File>
|
||||
<Filter
|
||||
Name="Sif"
|
||||
>
|
||||
|
@ -1318,6 +1330,14 @@
|
|||
RelativePath="..\..\Ipu\IPU_Fifo.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\IPU\IPUdma.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\IPU\IPUdma.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\Ipu\yuv2rgb.cpp"
|
||||
>
|
||||
|
|
|
@ -670,7 +670,7 @@ void psxRecompileCodeConst1(R3000AFNPTR constcode, R3000AFNPTR_INFO noconstcode)
|
|||
const char *funcname = irxImportFuncname(libname, index);
|
||||
irxDEBUG debug = irxImportDebug(libname, index);
|
||||
|
||||
if (SysTrace.IOP.Bios.IsActive()) {
|
||||
if (SysTraceActive(IOP.Bios)) {
|
||||
xMOV(ecx, (uptr)libname);
|
||||
xMOV(edx, index);
|
||||
xPUSH((uptr)funcname);
|
||||
|
|
|
@ -21,11 +21,6 @@
|
|||
#include "iR5900.h"
|
||||
|
||||
|
||||
#ifdef _WIN32
|
||||
//#pragma warning(disable:4244)
|
||||
//#pragma warning(disable:4761)
|
||||
#endif
|
||||
|
||||
namespace R5900 {
|
||||
namespace Dynarec {
|
||||
namespace OpcodeImpl
|
||||
|
|
|
@ -19,6 +19,21 @@
|
|||
#include "Common.h"
|
||||
#include "microVU.h"
|
||||
|
||||
// Include all the *.inl files (Needed because C++ sucks with templates and *.cpp files)
|
||||
#include "microVU_Clamp.inl"
|
||||
#include "microVU_Misc.inl"
|
||||
#include "microVU_Log.inl"
|
||||
#include "microVU_Analyze.inl"
|
||||
#include "microVU_Alloc.inl"
|
||||
#include "microVU_Upper.inl"
|
||||
#include "microVU_Lower.inl"
|
||||
#include "microVU_Tables.inl"
|
||||
#include "microVU_Flags.inl"
|
||||
#include "microVU_Branch.inl"
|
||||
#include "microVU_Compile.inl"
|
||||
#include "microVU_Execute.inl"
|
||||
#include "microVU_Macro.inl"
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// Micro VU - Global Variables
|
||||
//------------------------------------------------------------------
|
||||
|
@ -70,107 +85,93 @@ static __fi void mVUthrowHardwareDeficiency(const wxChar* extFail, int vuIndex)
|
|||
}
|
||||
|
||||
// Only run this once per VU! ;)
|
||||
static __ri void mVUinit(int vuIndex) {
|
||||
void microVU::init(uint vuIndex) {
|
||||
|
||||
if(!x86caps.hasMultimediaExtensions) mVUthrowHardwareDeficiency( L"MMX", vuIndex );
|
||||
if(!x86caps.hasStreamingSIMDExtensions) mVUthrowHardwareDeficiency( L"SSE", vuIndex );
|
||||
if(!x86caps.hasStreamingSIMD2Extensions) mVUthrowHardwareDeficiency( L"SSE2", vuIndex );
|
||||
|
||||
microVU* mVU = mVUx;
|
||||
memzero(mVU->prog);
|
||||
memzero(prog);
|
||||
|
||||
mVU->index = vuIndex;
|
||||
mVU->cop2 = 0;
|
||||
mVU->vuMemSize = (vuIndex ? 0x4000 : 0x1000);
|
||||
mVU->microMemSize = (vuIndex ? 0x4000 : 0x1000);
|
||||
mVU->progSize = (vuIndex ? 0x4000 : 0x1000) / 4;
|
||||
mVU->progMemMask = mVU->progSize-1;
|
||||
mVU->dispCache = NULL;
|
||||
mVU->cache = NULL;
|
||||
mVU->cacheSize = mVUcacheSize;
|
||||
mVU->regAlloc = new microRegAlloc();
|
||||
index = vuIndex;
|
||||
cop2 = 0;
|
||||
vuMemSize = (index ? 0x4000 : 0x1000);
|
||||
microMemSize = (index ? 0x4000 : 0x1000);
|
||||
progSize = (index ? 0x4000 : 0x1000) / 4;
|
||||
progMemMask = progSize-1;
|
||||
dispCache = NULL;
|
||||
cache = NULL;
|
||||
cacheSize = mVUcacheSize;
|
||||
regAlloc = new microRegAlloc(index);
|
||||
|
||||
for (u32 i = 0; i < (mVU->progSize / 2); i++) {
|
||||
mVU->prog.prog[i] = new deque<microProgram*>();
|
||||
for (u32 i = 0; i < (progSize / 2); i++) {
|
||||
prog.prog[i] = new deque<microProgram*>();
|
||||
}
|
||||
|
||||
mVU->dispCache = SysMmapEx(0, mVUdispCacheSize, 0, (mVU->index ? "Micro VU1 Dispatcher" : "Micro VU0 Dispatcher"));
|
||||
if (!mVU->dispCache) throw Exception::OutOfMemory( mVU->index ? L"Micro VU1 Dispatcher" : L"Micro VU0 Dispatcher" );
|
||||
memset(mVU->dispCache, 0xcc, mVUdispCacheSize);
|
||||
dispCache = SysMmapEx(0, mVUdispCacheSize, 0, (index ? "Micro VU1 Dispatcher" : "Micro VU0 Dispatcher"));
|
||||
if (!dispCache) throw Exception::OutOfMemory( index ? L"Micro VU1 Dispatcher" : L"Micro VU0 Dispatcher" );
|
||||
memset(dispCache, 0xcc, mVUdispCacheSize);
|
||||
|
||||
// Allocates rec-cache and calls mVUreset()
|
||||
mVUresizeCache(mVU, mVU->cacheSize + mVUcacheSafeZone);
|
||||
mVUresizeCache(this, cacheSize + mVUcacheSafeZone);
|
||||
//if (vuIndex) gen_memcpy_vibes();
|
||||
}
|
||||
|
||||
// Resets Rec Data
|
||||
// If vuRegsPtr is NUL, the current regs pointer assigned to the VU compiler is assumed.
|
||||
static __fi void mVUreset(mV, VURegs* vuRegsPtr) {
|
||||
void microVU::reset() {
|
||||
|
||||
static bool dispatchersGenerated = false;
|
||||
|
||||
if (!vuRegsPtr) vuRegsPtr = mVU->regs;
|
||||
if (!dispatchersGenerated || (mVU->regs != vuRegsPtr))
|
||||
{
|
||||
// Setup Entrance/Exit Points
|
||||
// These must be rebuilt whenever the vuRegsPtr has changed.
|
||||
|
||||
dispatchersGenerated = true;
|
||||
mVU->regs = vuRegsPtr;
|
||||
|
||||
x86SetPtr(mVU->dispCache);
|
||||
mVUdispatcherA(mVU);
|
||||
mVUdispatcherB(mVU);
|
||||
mVUemitSearch();
|
||||
}
|
||||
x86SetPtr(dispCache);
|
||||
mVUdispatcherA(this);
|
||||
mVUdispatcherB(this);
|
||||
mVUemitSearch();
|
||||
|
||||
// Clear All Program Data
|
||||
//memset(&mVU->prog, 0, sizeof(mVU->prog));
|
||||
memset(&mVU->prog.lpState, 0, sizeof(mVU->prog.lpState));
|
||||
|
||||
//memset(&prog, 0, sizeof(prog));
|
||||
memset(&prog.lpState, 0, sizeof(prog.lpState));
|
||||
|
||||
if (IsDevBuild) { // Release builds shouldn't need this
|
||||
memset(mVU->cache, 0xcc, mVU->cacheSize);
|
||||
memset(cache, 0xcc, cacheSize);
|
||||
}
|
||||
|
||||
// Program Variables
|
||||
mVU->prog.cleared = 1;
|
||||
mVU->prog.isSame = -1;
|
||||
mVU->prog.cur = NULL;
|
||||
mVU->prog.total = 0;
|
||||
mVU->prog.curFrame = 0;
|
||||
prog.cleared = 1;
|
||||
prog.isSame = -1;
|
||||
prog.cur = NULL;
|
||||
prog.total = 0;
|
||||
prog.curFrame = 0;
|
||||
|
||||
// Setup Dynarec Cache Limits for Each Program
|
||||
u8* z = mVU->cache;
|
||||
mVU->prog.x86start = z;
|
||||
mVU->prog.x86ptr = z;
|
||||
mVU->prog.x86end = (u8*)((uptr)z + (uptr)(mVU->cacheSize - mVUcacheSafeZone)); // "Safe Zone"
|
||||
u8* z = cache;
|
||||
prog.x86start = z;
|
||||
prog.x86ptr = z;
|
||||
prog.x86end = (u8*)((uptr)z + (uptr)(cacheSize - mVUcacheSafeZone)); // "Safe Zone"
|
||||
|
||||
for (u32 i = 0; i < (mVU->progSize / 2); i++) {
|
||||
deque<microProgram*>::iterator it(mVU->prog.prog[i]->begin());
|
||||
for ( ; it != mVU->prog.prog[i]->end(); ++it) {
|
||||
if (!isVU1) mVUdeleteProg<0>(it[0]);
|
||||
else mVUdeleteProg<1>(it[0]);
|
||||
for (u32 i = 0; i < (progSize / 2); i++) {
|
||||
deque<microProgram*>::iterator it(prog.prog[i]->begin());
|
||||
for ( ; it != prog.prog[i]->end(); ++it) {
|
||||
if (index) mVUdeleteProg<1>(it[0]);
|
||||
else mVUdeleteProg<0>(it[0]);
|
||||
}
|
||||
mVU->prog.prog[i]->clear();
|
||||
mVU->prog.quick[i].block = NULL;
|
||||
mVU->prog.quick[i].prog = NULL;
|
||||
prog.prog[i]->clear();
|
||||
prog.quick[i].block = NULL;
|
||||
prog.quick[i].prog = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// Free Allocated Resources
|
||||
static __fi void mVUclose(mV) {
|
||||
void microVU::close() {
|
||||
|
||||
if (mVU->dispCache) { HostSys::Munmap(mVU->dispCache, mVUdispCacheSize); mVU->dispCache = NULL; }
|
||||
if (mVU->cache) { HostSys::Munmap(mVU->cache, mVU->cacheSize); mVU->cache = NULL; }
|
||||
if (dispCache) { HostSys::Munmap(dispCache, mVUdispCacheSize); dispCache = NULL; }
|
||||
if (cache) { HostSys::Munmap(cache, cacheSize); cache = NULL; }
|
||||
|
||||
// Delete Programs and Block Managers
|
||||
for (u32 i = 0; i < (mVU->progSize / 2); i++) {
|
||||
deque<microProgram*>::iterator it(mVU->prog.prog[i]->begin());
|
||||
for ( ; it != mVU->prog.prog[i]->end(); ++it) {
|
||||
if (!isVU1) mVUdeleteProg<0>(it[0]);
|
||||
else mVUdeleteProg<1>(it[0]);
|
||||
for (u32 i = 0; i < (progSize / 2); i++) {
|
||||
deque<microProgram*>::iterator it(prog.prog[i]->begin());
|
||||
for ( ; it != prog.prog[i]->end(); ++it) {
|
||||
if (index) mVUdeleteProg<1>(it[0]);
|
||||
else mVUdeleteProg<0>(it[0]);
|
||||
}
|
||||
safe_delete(mVU->prog.prog[i]);
|
||||
safe_delete(prog.prog[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -181,7 +182,7 @@ static void mVUresizeCache(mV, u32 size) {
|
|||
// We can't grow the rec any larger, so just reset it and start over.
|
||||
//(if we don't reset, the rec will eventually crash)
|
||||
Console.WriteLn(Color_Magenta, "microVU%d: Cannot grow cache, size limit reached! [%dmb]. Resetting rec.", mVU->index, mVU->cacheSize/_1mb);
|
||||
mVUreset(mVU);
|
||||
mVU->reset();
|
||||
return;
|
||||
}
|
||||
size = mVUcacheMaxSize;
|
||||
|
@ -191,7 +192,7 @@ static void mVUresizeCache(mV, u32 size) {
|
|||
|
||||
u8* cache = SysMmapEx(0, size, 0, (mVU->index ? "Micro VU1 RecCache" : "Micro VU0 RecCache"));
|
||||
if(!cache && !mVU->cache) throw Exception::OutOfMemory( wxsFormat( L"Micro VU%d recompiled code cache", mVU->index) );
|
||||
if(!cache) { Console.Error("microVU%d Error - Cache Resize Failed...", mVU->index); mVUreset(mVU); return; }
|
||||
if(!cache) { Console.Error("microVU%d Error - Cache Resize Failed...", mVU->index); mVU->reset(); return; }
|
||||
if (mVU->cache) {
|
||||
HostSys::Munmap(mVU->cache, mVU->cacheSize);
|
||||
ProfilerTerminateSource(isVU1?"mVU1 Rec":"mVU0 Rec");
|
||||
|
@ -200,7 +201,7 @@ static void mVUresizeCache(mV, u32 size) {
|
|||
mVU->cache = cache;
|
||||
mVU->cacheSize = size;
|
||||
ProfilerRegisterSource(isVU1?"mVU1 Rec":"mVU0 Rec", mVU->cache, mVU->cacheSize);
|
||||
mVUreset(mVU);
|
||||
mVU->reset();
|
||||
}
|
||||
|
||||
// Clears Block Data in specified range
|
||||
|
@ -254,8 +255,8 @@ _mVUt __fi microProgram* mVUcreateProg(int startPC) {
|
|||
// Caches Micro Program
|
||||
_mVUt __fi void mVUcacheProg(microProgram& prog) {
|
||||
microVU* mVU = mVUx;
|
||||
if (!vuIndex) memcpy_const(prog.data, mVU->regs->Micro, 0x1000);
|
||||
else memcpy_const(prog.data, mVU->regs->Micro, 0x4000);
|
||||
if (!vuIndex) memcpy_const(prog.data, mVU->regs().Micro, 0x1000);
|
||||
else memcpy_const(prog.data, mVU->regs().Micro, 0x4000);
|
||||
mVUdumpProg(prog);
|
||||
}
|
||||
|
||||
|
@ -265,17 +266,17 @@ _mVUt __fi bool mVUcmpPartial(microProgram& prog) {
|
|||
deque<microRange>::const_iterator it(prog.ranges->begin());
|
||||
for ( ; it != prog.ranges->end(); ++it) {
|
||||
if((it[0].start<0)||(it[0].end<0)) { DevCon.Error("microVU%d: Negative Range![%d][%d]", mVU->index, it[0].start, it[0].end); }
|
||||
if (memcmp_mmx(cmpOffset(prog.data), cmpOffset(mVU->regs->Micro), ((it[0].end + 8) - it[0].start))) {
|
||||
if (memcmp_mmx(cmpOffset(prog.data), cmpOffset(mVU->regs().Micro), ((it[0].end + 8) - it[0].start))) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Compare Cached microProgram to mVU->regs->Micro
|
||||
// Compare Cached microProgram to mVU->regs().Micro
|
||||
_mVUt __fi bool mVUcmpProg(microProgram& prog, const bool cmpWholeProg) {
|
||||
microVU* mVU = mVUx;
|
||||
if ((cmpWholeProg && !memcmp_mmx((u8*)prog.data, mVU->regs->Micro, mVU->microMemSize))
|
||||
if ((cmpWholeProg && !memcmp_mmx((u8*)prog.data, mVU->regs().Micro, mVU->microMemSize))
|
||||
|| (!cmpWholeProg && mVUcmpPartial<vuIndex>(prog))) {
|
||||
mVU->prog.cleared = 0;
|
||||
mVU->prog.cur = &prog;
|
||||
|
@ -334,14 +335,14 @@ void recMicroVU0::Allocate() {
|
|||
if(!m_AllocCount) {
|
||||
m_AllocCount++;
|
||||
if (AtomicExchange(mvu0_allocated, 1) == 0)
|
||||
mVUinit(0);
|
||||
microVU0.init(0);
|
||||
}
|
||||
}
|
||||
void recMicroVU1::Allocate() {
|
||||
if(!m_AllocCount) {
|
||||
m_AllocCount++;
|
||||
if (AtomicExchange(mvu1_allocated, 1) == 0)
|
||||
mVUinit(1);
|
||||
microVU1.init(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -349,24 +350,24 @@ void recMicroVU0::Shutdown() throw() {
|
|||
if (m_AllocCount > 0) {
|
||||
m_AllocCount--;
|
||||
if (AtomicExchange(mvu0_allocated, 0) == 1)
|
||||
mVUclose(µVU0);
|
||||
microVU0.close();
|
||||
}
|
||||
}
|
||||
void recMicroVU1::Shutdown() throw() {
|
||||
if (m_AllocCount > 0) {
|
||||
m_AllocCount--;
|
||||
if (AtomicExchange(mvu1_allocated, 0) == 1)
|
||||
mVUclose(µVU1);
|
||||
microVU1.close();
|
||||
}
|
||||
}
|
||||
|
||||
void recMicroVU0::Reset() {
|
||||
if(!pxAssertDev(m_AllocCount, "MicroVU0 CPU Provider has not been allocated prior to reset!")) return;
|
||||
mVUreset(µVU0, &VU0);
|
||||
microVU0.reset();
|
||||
}
|
||||
void recMicroVU1::Reset() {
|
||||
if(!pxAssertDev(m_AllocCount, "MicroVU1 CPU Provider has not been allocated prior to reset!")) return;
|
||||
mVUreset(µVU1, &VU1);
|
||||
microVU1.reset();
|
||||
}
|
||||
|
||||
void recMicroVU0::Execute(u32 cycles) {
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue