mirror of https://github.com/PCSX2/pcsx2.git
Added several important variables to the VIFdma savestate, relating to it's SSE unpacker; which should make the gifdone savestate hack obsolete (it broke savestates for most FMVs and some games). Seeing how important the unpacker tables are, it's a miracle VIFdma ever recovered from a savestate without them ;)
Fixed a bug in the memorycard hotswapper. It wasn't reloading the cards correctly after changes. Improved the new INTC hack slightly, and changed its description since it's not quite as universally awesome as Pseudonym and I had hoped when we worked on it last night. -_- Added __fastcall and __forceinline to some of the VIF's unpack functions, where appropriate (very small speedup). Removed some code I added to the MULT/DIV instructions, since it wasn't needed afterall, and fixed some typos in vtlb's API. git-svn-id: http://pcsx2.googlecode.com/svn/trunk@538 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
parent
23336fe987
commit
243e4fba9f
|
@ -813,12 +813,10 @@ void gsDynamicSkipEnable()
|
|||
frameLimitReset();
|
||||
}
|
||||
|
||||
extern unsigned int gifdone;
|
||||
void SaveState::gsFreeze()
|
||||
{
|
||||
FreezeMem(PS2MEM_GS, 0x2000);
|
||||
Freeze(CSRw);
|
||||
if(((DMACh*)&PS2MEM_HW[0xA000])->chcr & 0x100)gifdone = 0;
|
||||
mtgsFreeze();
|
||||
}
|
||||
|
||||
|
|
|
@ -376,6 +376,7 @@ 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 );
|
||||
|
|
|
@ -34,6 +34,19 @@
|
|||
|
||||
using namespace R5900;
|
||||
|
||||
static __forceinline void IntCHackCheck()
|
||||
{
|
||||
if( !CHECK_INTC_STAT_HACK ) return;
|
||||
cpuRegs.cycle = g_nextBranchCycle;
|
||||
|
||||
// Threshold method, might fix games that have problems with the simple
|
||||
// implementation above (none known that break yet)
|
||||
/*if( ( g_nextBranchCycle - cpuRegs.cycle ) > 500 )
|
||||
cpuRegs.cycle += 498;
|
||||
else
|
||||
cpuRegs.cycle = g_nextBranchCycle - 2;*/
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// Hardware READ 8 bit
|
||||
|
||||
|
@ -186,7 +199,8 @@ mem32_t __fastcall hwRead32_page_01(u32 mem)
|
|||
}
|
||||
|
||||
// Reads hardware registers for page 15 (0x0F).
|
||||
mem32_t __fastcall hwRead32_page_0F(u32 mem)
|
||||
// This is used internally to produce two inline versions, one with INTC_HACK, and one without.
|
||||
static __forceinline mem32_t __hwRead32_page_0F( u32 mem, bool intchack )
|
||||
{
|
||||
// *Performance Warning* This function is called -A-LOT. Be weary when making changes. It
|
||||
// could impact FPS significantly.
|
||||
|
@ -196,8 +210,7 @@ mem32_t __fastcall hwRead32_page_0F(u32 mem)
|
|||
switch( mem )
|
||||
{
|
||||
case 0xf000:
|
||||
if( CHECK_INTC_STAT_HACK )
|
||||
cpuRegs.cycle = g_nextBranchCycle;
|
||||
if( intchack ) IntCHackCheck();
|
||||
// This one is checked alot, so leave it commented out unless you love 600 meg logfiles.
|
||||
//HW_LOG("INTC_STAT Read 32bit %x\n", psHu32(0xf010));
|
||||
break;
|
||||
|
@ -247,6 +260,16 @@ mem32_t __fastcall hwRead32_page_0F(u32 mem)
|
|||
return *((u32*)&PS2MEM_HW[mem]);
|
||||
}
|
||||
|
||||
mem32_t __fastcall hwRead32_page_0F(u32 mem)
|
||||
{
|
||||
return __hwRead32_page_0F( mem, false );
|
||||
}
|
||||
|
||||
mem32_t __fastcall hwRead32_page_0F_INTC_HACK(u32 mem)
|
||||
{
|
||||
return __hwRead32_page_0F( mem, true );
|
||||
}
|
||||
|
||||
mem32_t __fastcall hwRead32_page_02(u32 mem)
|
||||
{
|
||||
return ipuRead32( mem );
|
||||
|
@ -327,8 +350,7 @@ void __fastcall hwRead64_page_02(u32 mem, mem64_t* result )
|
|||
|
||||
void __fastcall hwRead64_generic(u32 mem, mem64_t* result )
|
||||
{
|
||||
if( mem == INTC_STAT && CHECK_INTC_STAT_HACK )
|
||||
cpuRegs.cycle = g_nextBranchCycle;
|
||||
if( mem == INTC_STAT ) IntCHackCheck();
|
||||
|
||||
*result = psHu64(mem);
|
||||
HW_LOG("Unknown Hardware Read 64 at %x\n",mem);
|
||||
|
|
|
@ -106,17 +106,6 @@ namespace OpcodeImpl {
|
|||
void MULTU1() {
|
||||
u64 tempu = (u64)cpuRegs.GPR.r[_Rs_].UL[0] * (u64)cpuRegs.GPR.r[_Rt_].UL[0];
|
||||
|
||||
// The EE says that results are "undefined" if the source operands are not correctly
|
||||
// sign extended into the full 64 bits. Since this is InterpreterLand, let's put a
|
||||
// check in and issue a message if it ever happens.
|
||||
// Could be a clue to something else someday.
|
||||
|
||||
if( cpuRegs.GPR.r[_Rs_].SL[0] != cpuRegs.GPR.r[_Rs_].SD[0] )
|
||||
DevCon::Notice( "MULTU1 > Non-extended sign bit on Rs: %8.8x", params cpuRegs.GPR.r[_Rs_].SL[0] );
|
||||
|
||||
if( cpuRegs.GPR.r[_Rt_].SL[0] != cpuRegs.GPR.r[_Rt_].SD[0] )
|
||||
DevCon::Notice( "MULTU1 > Non-extended sign bit on Rt: %8.8x", params cpuRegs.GPR.r[_Rt_].SL[0] );
|
||||
|
||||
// According to docs, sign-extend into 64 bits even though it's an unsigned mult.
|
||||
cpuRegs.LO.UD[1] = (s32)(tempu & 0xffffffff);
|
||||
cpuRegs.HI.UD[1] = (s32)(tempu >> 32);
|
||||
|
@ -134,14 +123,6 @@ namespace OpcodeImpl {
|
|||
void DIVU1() {
|
||||
if (cpuRegs.GPR.r[_Rt_].UL[0] != 0) {
|
||||
|
||||
// See MULTU above for notes on the following sanity check
|
||||
|
||||
if( cpuRegs.GPR.r[_Rs_].SL[0] != cpuRegs.GPR.r[_Rs_].SD[0] )
|
||||
DevCon::Notice( "DIVU1 > Non-extended sign bit on Rs: %8.8x", params cpuRegs.GPR.r[_Rs_].SL[0] );
|
||||
|
||||
if( cpuRegs.GPR.r[_Rt_].SL[0] != cpuRegs.GPR.r[_Rt_].SD[0] )
|
||||
DevCon::Notice( "DIVU1 > Non-extended sign bit on Rt: %8.8x", params cpuRegs.GPR.r[_Rt_].SL[0] );
|
||||
|
||||
// note: DIVU has no sign extension when assigning back to 64 bits
|
||||
cpuRegs.LO.UD[1] = cpuRegs.GPR.r[_Rs_].UL[0] / cpuRegs.GPR.r[_Rt_].UL[0];
|
||||
cpuRegs.HI.UD[1] = cpuRegs.GPR.r[_Rs_].UL[0] % cpuRegs.GPR.r[_Rt_].UL[0];
|
||||
|
|
|
@ -754,8 +754,10 @@ void memReset()
|
|||
_ext_memWrite8<1>, _ext_memWrite16<1>, hwWrite32_page_0E, hwWrite64_page_0E, hwWrite128_generic
|
||||
);
|
||||
|
||||
vtlbMemR32FP* page0F( CHECK_INTC_STAT_HACK ? hwRead32_page_0F_INTC_HACK : hwRead32_page_0F );
|
||||
|
||||
hw_by_page[0xf] = vtlb_RegisterHandler(
|
||||
_ext_memRead8<1>, _ext_memRead16<1>, hwRead32_page_0F, hwRead64_generic, hwRead128_generic,
|
||||
_ext_memRead8<1>, _ext_memRead16<1>, page0F, hwRead64_generic, hwRead128_generic,
|
||||
_ext_memWrite8<1>, _ext_memWrite16<1>, hwWrite32_page_0F, hwWrite64_generic, hwWrite128_generic
|
||||
);
|
||||
|
||||
|
|
|
@ -42,11 +42,16 @@ void MemoryCard::Init()
|
|||
void MemoryCard::Shutdown()
|
||||
{
|
||||
for( int i=0; i<2; i++ )
|
||||
{
|
||||
if(cardfile[0] == NULL) continue;
|
||||
fclose( cardfile[i] );
|
||||
cardfile[0] = NULL;
|
||||
}
|
||||
Unload( i );
|
||||
}
|
||||
|
||||
void MemoryCard::Unload( uint mcd )
|
||||
{
|
||||
jASSUME( mcd < 2 );
|
||||
|
||||
if(cardfile[mcd] == NULL) return;
|
||||
fclose( cardfile[mcd] );
|
||||
cardfile[mcd] = NULL;
|
||||
}
|
||||
|
||||
bool MemoryCard::IsPresent( uint mcd )
|
||||
|
|
|
@ -34,6 +34,8 @@ protected:
|
|||
public:
|
||||
static void Init();
|
||||
static void Shutdown();
|
||||
static void Unload( uint mcd );
|
||||
|
||||
static bool IsPresent( uint mcdId );
|
||||
static void Read( uint mcdId, u8 *data, u32 adr, int size );
|
||||
static void Save( uint mcdId, const u8 *data, u32 adr, int size );
|
||||
|
|
|
@ -153,14 +153,6 @@ void DIV() {
|
|||
void DIVU() {
|
||||
if (cpuRegs.GPR.r[_Rt_].UL[0] != 0) {
|
||||
|
||||
// See MULTU below for notes on the following sanity check
|
||||
|
||||
if( cpuRegs.GPR.r[_Rs_].SL[0] != cpuRegs.GPR.r[_Rs_].SD[0] )
|
||||
DevCon::Notice( "DIVU > Non-extended sign bit on Rs: %8.8x", params cpuRegs.GPR.r[_Rs_].SL[0] );
|
||||
|
||||
if( cpuRegs.GPR.r[_Rt_].SL[0] != cpuRegs.GPR.r[_Rt_].SD[0] )
|
||||
DevCon::Notice( "DIVU > Non-extended sign bit on Rt: %8.8x", params cpuRegs.GPR.r[_Rt_].SL[0] );
|
||||
|
||||
// note: DIVU has no sign extension when assigning back to 64 bits
|
||||
cpuRegs.LO.SD[0] = cpuRegs.GPR.r[_Rs_].UL[0] / cpuRegs.GPR.r[_Rt_].UL[0];
|
||||
cpuRegs.HI.SD[0] = cpuRegs.GPR.r[_Rs_].UL[0] % cpuRegs.GPR.r[_Rt_].UL[0];
|
||||
|
@ -180,17 +172,6 @@ void MULT() { //different in ps2...
|
|||
void MULTU() { //different in ps2..
|
||||
u64 res = (u64)cpuRegs.GPR.r[_Rs_].UL[0] * (u64)cpuRegs.GPR.r[_Rt_].UL[0];
|
||||
|
||||
// The EE says that results are "undefined" if the source operands are not correctly
|
||||
// sign extended into the full 64 bits. Since this is InterpreterLand, let's put a
|
||||
// check in and issue a message if it ever happens.
|
||||
// Could be a clue to something else someday.
|
||||
|
||||
if( cpuRegs.GPR.r[_Rs_].SL[0] != cpuRegs.GPR.r[_Rs_].SD[0] )
|
||||
DevCon::Notice( "MULTU > Non-extended sign bit on Rs: %8.8x", params cpuRegs.GPR.r[_Rs_].SL[0] );
|
||||
|
||||
if( cpuRegs.GPR.r[_Rt_].SL[0] != cpuRegs.GPR.r[_Rt_].SD[0] )
|
||||
DevCon::Notice( "MULTU > Non-extended sign bit on Rt: %8.8x", params cpuRegs.GPR.r[_Rt_].SL[0] );
|
||||
|
||||
// According to docs, sign-extend into 64 bits even though it's an unsigned mult.
|
||||
cpuRegs.LO.UD[0] = (s32)(res & 0xffffffff);
|
||||
cpuRegs.HI.UD[0] = (s32)(res >> 32);
|
||||
|
|
|
@ -113,11 +113,10 @@ void SaveState::FreezeAll()
|
|||
Freeze(g_psxNextBranchCycle);
|
||||
|
||||
Freeze(s_iLastCOP0Cycle);
|
||||
if( m_version >= 0x7a30000e )
|
||||
Freeze(s_iLastPERFCycle);
|
||||
Freeze(s_iLastPERFCycle);
|
||||
|
||||
Freeze(g_psxWriteOk);
|
||||
|
||||
|
||||
//hope didn't forgot any cpu....
|
||||
|
||||
rcntFreeze();
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
// Savestate Versioning!
|
||||
// If you make changes to the savestate version, please increment the value below.
|
||||
|
||||
static const u32 g_SaveVersion = 0x8b400003;
|
||||
static const u32 g_SaveVersion = 0x8b400004;
|
||||
|
||||
// this function is meant to be sued in the place of GSfreeze, and provides a safe layer
|
||||
// between the GS saving function and the MTGS's needs. :)
|
||||
|
|
|
@ -554,6 +554,11 @@ void sioEjectCard( uint mcdId )
|
|||
{
|
||||
jASSUME( mcdId < 2 );
|
||||
m_PostSavestateCards[mcdId] = 64;
|
||||
|
||||
// Reload the new memory card:
|
||||
|
||||
MemoryCard::Unload( mcdId );
|
||||
MemoryCard::Init();
|
||||
}
|
||||
|
||||
void SaveState::sioFreeze()
|
||||
|
|
|
@ -42,7 +42,7 @@ static int n;
|
|||
|
||||
__forceinline static int _limit( int a, int max )
|
||||
{
|
||||
return ( a > max ? max : a );
|
||||
return ( a > max ) ? max : a;
|
||||
}
|
||||
|
||||
#define _UNPACKpart( offnum, func ) \
|
||||
|
@ -58,7 +58,16 @@ __forceinline static int _limit( int a, int max )
|
|||
_vifRegs->offset++; \
|
||||
}
|
||||
|
||||
static void writeX( u32 *dest, u32 data ) {
|
||||
// Forceinline macro that is enabled for RELEASE/PUBLIC builds ONLY.
|
||||
// This is useful because forceinline can make certain types of debugging problematic since
|
||||
// functions that look like they should be called won't breakpoint since their code is inlined.
|
||||
#ifdef PCSX2_DEVBUILD
|
||||
# define __pub_inline
|
||||
#else
|
||||
# define __pub_inline __forceinline
|
||||
#endif
|
||||
|
||||
static __pub_inline void writeX( u32 *dest, u32 data ) {
|
||||
if (_vifRegs->code & 0x10000000) {
|
||||
switch ( _vif->cl ) {
|
||||
case 0: n = (_vifRegs->mask) & 0x3; break;
|
||||
|
@ -97,7 +106,7 @@ static void writeX( u32 *dest, u32 data ) {
|
|||
// VIF_LOG("writeX %8.8x : Mode %d, r0 = %x, data %8.8x\n", *dest,_vifRegs->mode,_vifRegs->r0,data);
|
||||
}
|
||||
|
||||
static void writeY( u32 *dest, u32 data ) {
|
||||
static __pub_inline void writeY( u32 *dest, u32 data ) {
|
||||
if (_vifRegs->code & 0x10000000) {
|
||||
switch ( _vif->cl ) {
|
||||
case 0: n = (_vifRegs->mask >> 2) & 0x3; break;
|
||||
|
@ -136,7 +145,7 @@ static void writeY( u32 *dest, u32 data ) {
|
|||
// VIF_LOG("writeY %8.8x : Mode %d, r1 = %x, data %8.8x\n", *dest,_vifRegs->mode,_vifRegs->r1,data);
|
||||
}
|
||||
|
||||
static void writeZ( u32 *dest, u32 data ) {
|
||||
static __pub_inline void writeZ( u32 *dest, u32 data ) {
|
||||
if (_vifRegs->code & 0x10000000) {
|
||||
switch ( _vif->cl ) {
|
||||
case 0: n = (_vifRegs->mask >> 4) & 0x3; break;
|
||||
|
@ -175,7 +184,7 @@ static void writeZ( u32 *dest, u32 data ) {
|
|||
// VIF_LOG("writeZ %8.8x : Mode %d, r2 = %x, data %8.8x\n", *dest,_vifRegs->mode,_vifRegs->r2,data);
|
||||
}
|
||||
|
||||
static void writeW( u32 *dest, u32 data ) {
|
||||
static __pub_inline void writeW( u32 *dest, u32 data ) {
|
||||
if (_vifRegs->code & 0x10000000) {
|
||||
switch ( _vif->cl ) {
|
||||
case 0: n = (_vifRegs->mask >> 6) & 0x3; break;
|
||||
|
@ -214,7 +223,7 @@ static void writeW( u32 *dest, u32 data ) {
|
|||
// VIF_LOG("writeW %8.8x : Mode %d, r3 = %x, data %8.8x\n", *dest,_vifRegs->mode,_vifRegs->r3,data);
|
||||
}
|
||||
|
||||
void UNPACK_S_32(u32 *dest, u32 *data, int size) {
|
||||
void __fastcall UNPACK_S_32(u32 *dest, u32 *data, int size) {
|
||||
_UNPACKpart(0, writeX(dest++, *data) );
|
||||
_UNPACKpart(1, writeY(dest++, *data) );
|
||||
_UNPACKpart(2, writeZ(dest++, *data) );
|
||||
|
@ -222,7 +231,7 @@ void UNPACK_S_32(u32 *dest, u32 *data, int size) {
|
|||
if (_vifRegs->offset == 4) _vifRegs->offset = 0;
|
||||
}
|
||||
|
||||
void UNPACK_S_16s( u32 *dest, u32 *data, int size) {
|
||||
void __fastcall UNPACK_S_16s( u32 *dest, u32 *data, int size) {
|
||||
s16 *sdata = (s16*)data;
|
||||
_UNPACKpart(0, writeX(dest++, *sdata) );
|
||||
_UNPACKpart(1, writeY(dest++, *sdata) );
|
||||
|
@ -231,8 +240,8 @@ void UNPACK_S_16s( u32 *dest, u32 *data, int size) {
|
|||
if (_vifRegs->offset == 4) _vifRegs->offset = 0;
|
||||
}
|
||||
|
||||
void UNPACK_S_16u( u32 *dest, u32 *data, int size) {
|
||||
u16 *sdata = (u16*)data;
|
||||
void __fastcall UNPACK_S_16u( u32 *dest, u32 *data, int size) {
|
||||
const u16 *sdata = (u16*)data;
|
||||
_UNPACKpart(0, writeX(dest++, *sdata) );
|
||||
_UNPACKpart(1, writeY(dest++, *sdata) );
|
||||
_UNPACKpart(2, writeZ(dest++, *sdata) );
|
||||
|
@ -240,7 +249,7 @@ void UNPACK_S_16u( u32 *dest, u32 *data, int size) {
|
|||
if (_vifRegs->offset == 4) _vifRegs->offset = 0;
|
||||
}
|
||||
|
||||
void UNPACK_S_8s(u32 *dest, u32 *data, int size) {
|
||||
void __fastcall UNPACK_S_8s(u32 *dest, u32 *data, int size) {
|
||||
s8 *cdata = (s8*)data;
|
||||
_UNPACKpart(0, writeX(dest++, *cdata) );
|
||||
_UNPACKpart(1, writeY(dest++, *cdata) );
|
||||
|
@ -249,7 +258,7 @@ void UNPACK_S_8s(u32 *dest, u32 *data, int size) {
|
|||
if (_vifRegs->offset == 4) _vifRegs->offset = 0;
|
||||
}
|
||||
|
||||
void UNPACK_S_8u(u32 *dest, u32 *data, int size) {
|
||||
void __fastcall UNPACK_S_8u(u32 *dest, u32 *data, int size) {
|
||||
u8 *cdata = (u8*)data;
|
||||
_UNPACKpart(0, writeX(dest++, *cdata) );
|
||||
_UNPACKpart(1, writeY(dest++, *cdata) );
|
||||
|
@ -258,7 +267,7 @@ void UNPACK_S_8u(u32 *dest, u32 *data, int size) {
|
|||
if (_vifRegs->offset == 4) _vifRegs->offset = 0;
|
||||
}
|
||||
|
||||
void UNPACK_V2_32( u32 *dest, u32 *data, int size ) {
|
||||
void __fastcall UNPACK_V2_32( u32 *dest, u32 *data, int size ) {
|
||||
_UNPACKpart(0, writeX(dest++, *data++));
|
||||
_UNPACKpart(1, writeY(dest++, *data--));
|
||||
_UNPACKpart_nosize(2, writeZ(dest++, *data));
|
||||
|
@ -267,7 +276,7 @@ void UNPACK_V2_32( u32 *dest, u32 *data, int size ) {
|
|||
|
||||
}
|
||||
|
||||
void UNPACK_V2_16s(u32 *dest, u32 *data, int size) {
|
||||
void __fastcall UNPACK_V2_16s(u32 *dest, u32 *data, int size) {
|
||||
s16 *sdata = (s16*)data;
|
||||
_UNPACKpart(0, writeX(dest++, *sdata++));
|
||||
_UNPACKpart(1, writeY(dest++, *sdata--));
|
||||
|
@ -276,7 +285,7 @@ void UNPACK_V2_16s(u32 *dest, u32 *data, int size) {
|
|||
if (_vifRegs->offset == 4) _vifRegs->offset = 0;
|
||||
}
|
||||
|
||||
void UNPACK_V2_16u(u32 *dest, u32 *data, int size) {
|
||||
void __fastcall UNPACK_V2_16u(u32 *dest, u32 *data, int size) {
|
||||
u16 *sdata = (u16*)data;
|
||||
_UNPACKpart(0, writeX(dest++, *sdata++));
|
||||
_UNPACKpart(1, writeY(dest++, *sdata--));
|
||||
|
@ -285,7 +294,7 @@ void UNPACK_V2_16u(u32 *dest, u32 *data, int size) {
|
|||
if (_vifRegs->offset == 4) _vifRegs->offset = 0;
|
||||
}
|
||||
|
||||
void UNPACK_V2_8s(u32 *dest, u32 *data, int size) {
|
||||
void __fastcall UNPACK_V2_8s(u32 *dest, u32 *data, int size) {
|
||||
s8 *cdata = (s8*)data;
|
||||
_UNPACKpart(0, writeX(dest++, *cdata++));
|
||||
_UNPACKpart(1, writeY(dest++, *cdata--));
|
||||
|
@ -294,7 +303,7 @@ void UNPACK_V2_8s(u32 *dest, u32 *data, int size) {
|
|||
if (_vifRegs->offset == 4) _vifRegs->offset = 0;
|
||||
}
|
||||
|
||||
void UNPACK_V2_8u(u32 *dest, u32 *data, int size) {
|
||||
void __fastcall UNPACK_V2_8u(u32 *dest, u32 *data, int size) {
|
||||
u8 *cdata = (u8*)data;
|
||||
_UNPACKpart(0, writeX(dest++, *cdata++));
|
||||
_UNPACKpart(1, writeY(dest++, *cdata--));
|
||||
|
@ -303,7 +312,7 @@ void UNPACK_V2_8u(u32 *dest, u32 *data, int size) {
|
|||
if (_vifRegs->offset == 4) _vifRegs->offset = 0;
|
||||
}
|
||||
|
||||
void UNPACK_V3_32(u32 *dest, u32 *data, int size) {
|
||||
void __fastcall UNPACK_V3_32(u32 *dest, u32 *data, int size) {
|
||||
_UNPACKpart(0, writeX(dest++, *data++); );
|
||||
_UNPACKpart(1, writeY(dest++, *data++); );
|
||||
_UNPACKpart(2, writeZ(dest++, *data++); );
|
||||
|
@ -311,7 +320,7 @@ void UNPACK_V3_32(u32 *dest, u32 *data, int size) {
|
|||
if (_vifRegs->offset == 4) _vifRegs->offset = 0;
|
||||
}
|
||||
|
||||
void UNPACK_V3_16s(u32 *dest, u32 *data, int size) {
|
||||
void __fastcall UNPACK_V3_16s(u32 *dest, u32 *data, int size) {
|
||||
s16 *sdata = (s16*)data;
|
||||
_UNPACKpart(0, writeX(dest++, *sdata++));
|
||||
_UNPACKpart(1, writeY(dest++, *sdata++));
|
||||
|
@ -320,7 +329,7 @@ void UNPACK_V3_16s(u32 *dest, u32 *data, int size) {
|
|||
if (_vifRegs->offset == 4) _vifRegs->offset = 0;
|
||||
}
|
||||
|
||||
void UNPACK_V3_16u(u32 *dest, u32 *data, int size) {
|
||||
void __fastcall UNPACK_V3_16u(u32 *dest, u32 *data, int size) {
|
||||
u16 *sdata = (u16*)data;
|
||||
_UNPACKpart(0, writeX(dest++, *sdata++));
|
||||
_UNPACKpart(1, writeY(dest++, *sdata++));
|
||||
|
@ -329,7 +338,7 @@ void UNPACK_V3_16u(u32 *dest, u32 *data, int size) {
|
|||
if (_vifRegs->offset == 4) _vifRegs->offset = 0;
|
||||
}
|
||||
|
||||
void UNPACK_V3_8s(u32 *dest, u32 *data, int size) {
|
||||
void __fastcall UNPACK_V3_8s(u32 *dest, u32 *data, int size) {
|
||||
s8 *cdata = (s8*)data;
|
||||
_UNPACKpart(0, writeX(dest++, *cdata++));
|
||||
_UNPACKpart(1, writeY(dest++, *cdata++));
|
||||
|
@ -338,7 +347,7 @@ void UNPACK_V3_8s(u32 *dest, u32 *data, int size) {
|
|||
if (_vifRegs->offset == 4) _vifRegs->offset = 0;
|
||||
}
|
||||
|
||||
void UNPACK_V3_8u(u32 *dest, u32 *data, int size) {
|
||||
void __fastcall UNPACK_V3_8u(u32 *dest, u32 *data, int size) {
|
||||
u8 *cdata = (u8*)data;
|
||||
_UNPACKpart(0, writeX(dest++, *cdata++));
|
||||
_UNPACKpart(1, writeY(dest++, *cdata++));
|
||||
|
@ -347,7 +356,7 @@ void UNPACK_V3_8u(u32 *dest, u32 *data, int size) {
|
|||
if (_vifRegs->offset == 4) _vifRegs->offset = 0;
|
||||
}
|
||||
|
||||
void UNPACK_V4_32( u32 *dest, u32 *data , int size) {
|
||||
void __fastcall UNPACK_V4_32( u32 *dest, u32 *data , int size) {
|
||||
_UNPACKpart(0, writeX(dest++, *data++) );
|
||||
_UNPACKpart(1, writeY(dest++, *data++) );
|
||||
_UNPACKpart(2, writeZ(dest++, *data++) );
|
||||
|
@ -355,7 +364,7 @@ void UNPACK_V4_32( u32 *dest, u32 *data , int size) {
|
|||
if (_vifRegs->offset == 4) _vifRegs->offset = 0;
|
||||
}
|
||||
|
||||
void UNPACK_V4_16s(u32 *dest, u32 *data, int size) {
|
||||
void __fastcall UNPACK_V4_16s(u32 *dest, u32 *data, int size) {
|
||||
s16 *sdata = (s16*)data;
|
||||
_UNPACKpart(0, writeX(dest++, *sdata++) );
|
||||
_UNPACKpart(1, writeY(dest++, *sdata++) );
|
||||
|
@ -364,7 +373,7 @@ void UNPACK_V4_16s(u32 *dest, u32 *data, int size) {
|
|||
if (_vifRegs->offset == 4) _vifRegs->offset = 0;
|
||||
}
|
||||
|
||||
void UNPACK_V4_16u(u32 *dest, u32 *data, int size) {
|
||||
void __fastcall UNPACK_V4_16u(u32 *dest, u32 *data, int size) {
|
||||
u16 *sdata = (u16*)data;
|
||||
_UNPACKpart(0, writeX(dest++, *sdata++) );
|
||||
_UNPACKpart(1, writeY(dest++, *sdata++) );
|
||||
|
@ -373,7 +382,7 @@ void UNPACK_V4_16u(u32 *dest, u32 *data, int size) {
|
|||
if (_vifRegs->offset == 4) _vifRegs->offset = 0;
|
||||
}
|
||||
|
||||
void UNPACK_V4_8s(u32 *dest, u32 *data, int size) {
|
||||
void __fastcall UNPACK_V4_8s(u32 *dest, u32 *data, int size) {
|
||||
s8 *cdata = (s8*)data;
|
||||
_UNPACKpart(0, writeX(dest++, *cdata++) );
|
||||
_UNPACKpart(1, writeY(dest++, *cdata++) );
|
||||
|
@ -382,7 +391,7 @@ void UNPACK_V4_8s(u32 *dest, u32 *data, int size) {
|
|||
if (_vifRegs->offset == 4) _vifRegs->offset = 0;
|
||||
}
|
||||
|
||||
void UNPACK_V4_8u(u32 *dest, u32 *data, int size) {
|
||||
void __fastcall UNPACK_V4_8u(u32 *dest, u32 *data, int size) {
|
||||
u8 *cdata = (u8*)data;
|
||||
_UNPACKpart(0, writeX(dest++, *cdata++) );
|
||||
_UNPACKpart(1, writeY(dest++, *cdata++) );
|
||||
|
@ -391,7 +400,7 @@ void UNPACK_V4_8u(u32 *dest, u32 *data, int size) {
|
|||
if (_vifRegs->offset == 4) _vifRegs->offset = 0;
|
||||
}
|
||||
|
||||
void UNPACK_V4_5(u32 *dest, u32 *data, int size) {
|
||||
void __fastcall UNPACK_V4_5(u32 *dest, u32 *data, int size) {
|
||||
|
||||
_UNPACKpart(0, writeX(dest++, (*data & 0x001f) << 3); );
|
||||
_UNPACKpart(1, writeY(dest++, (*data & 0x03e0) >> 2); );
|
||||
|
|
|
@ -96,7 +96,7 @@ int VIF0transfer(u32 *data, int size, int istag);
|
|||
int VIF1transfer(u32 *data, int size, int istag);
|
||||
void vifMFIFOInterrupt();
|
||||
|
||||
void SetNewMask(u32* vif1masks, u32* hasmask, u32 mask, u32 oldmask);
|
||||
void __fastcall SetNewMask(u32* vif1masks, u32* hasmask, u32 mask, u32 oldmask);
|
||||
|
||||
#define XMM_R0 xmm0
|
||||
#define XMM_R1 xmm1
|
||||
|
|
149
pcsx2/VifDma.cpp
149
pcsx2/VifDma.cpp
|
@ -68,12 +68,12 @@ static const unsigned int VIF1dmanum = 1;
|
|||
int g_vifCycles = 0;
|
||||
int path3hack = 0;
|
||||
|
||||
typedef void (*UNPACKFUNCTYPE)( u32 *dest, u32 *data, int size );
|
||||
typedef void (__fastcall *UNPACKFUNCTYPE)( u32 *dest, u32 *data, int size );
|
||||
typedef int (*UNPACKPARTFUNCTYPESSE)( u32 *dest, u32 *data, int size );
|
||||
extern void (*Vif1CMDTLB[82])();
|
||||
extern void (*Vif0CMDTLB[75])();
|
||||
extern int (*Vif1TransTLB[128])(u32 *data);
|
||||
extern int (*Vif0TransTLB[128])(u32 *data);
|
||||
extern int (__fastcall *Vif1TransTLB[128])(u32 *data);
|
||||
extern int (__fastcall *Vif0TransTLB[128])(u32 *data);
|
||||
|
||||
struct VIFUnpackFuncTable {
|
||||
UNPACKFUNCTYPE funcU;
|
||||
|
@ -395,24 +395,29 @@ static void VIFunpack(u32 *data, vifCode *v, int size, const unsigned int VIFdma
|
|||
#ifdef _DEBUG
|
||||
memsize = size;
|
||||
#endif
|
||||
if( _vifRegs->offset > 0) {
|
||||
if( _vifRegs->offset > 0)
|
||||
{
|
||||
int destinc, unpacksize;
|
||||
|
||||
VIFUNPACK_LOG("aligning packet size = %d offset %d addr %x\n", size, vifRegs->offset, vif->tag.addr);
|
||||
|
||||
// SSE doesn't handle such small data
|
||||
if (v->size != (size>>2))ProcessMemSkip(size, unpackType, VIFdmanum);
|
||||
if (v->size != (size>>2))
|
||||
ProcessMemSkip(size, unpackType, VIFdmanum);
|
||||
|
||||
if(vifRegs->offset < (u32)ft->qsize){
|
||||
if(((u32)size/(u32)ft->dsize) < ((u32)ft->qsize - vifRegs->offset)){
|
||||
if(vifRegs->offset < (u32)ft->qsize)
|
||||
{
|
||||
if(((u32)size/(u32)ft->dsize) < ((u32)ft->qsize - vifRegs->offset))
|
||||
{
|
||||
SysPrintf("wasnt enough left size/dsize = %x left to write %x\n", (size/ft->dsize), (ft->qsize - vifRegs->offset));
|
||||
}
|
||||
unpacksize = min(((u32)size/(u32)ft->dsize), ((u32)ft->qsize - vifRegs->offset));
|
||||
}
|
||||
else {
|
||||
unpacksize = 0;
|
||||
SysPrintf("Unpack align offset = 0\n");
|
||||
}
|
||||
unpacksize = min(((u32)size/(u32)ft->dsize), ((u32)ft->qsize - vifRegs->offset));
|
||||
}
|
||||
else
|
||||
{
|
||||
unpacksize = 0;
|
||||
SysPrintf("Unpack align offset = 0\n");
|
||||
}
|
||||
destinc = (4 - ft->qsize) + unpacksize;
|
||||
|
||||
func(dest, (u32*)cdata, unpacksize);
|
||||
|
@ -434,7 +439,9 @@ static void VIFunpack(u32 *data, vifCode *v, int size, const unsigned int VIFdma
|
|||
}
|
||||
VIFUNPACK_LOG("aligning packet done size = %d offset %d addr %x\n", size, vifRegs->offset, vif->tag.addr);
|
||||
|
||||
} else if (v->size != (size>>2))ProcessMemSkip(size, unpackType, VIFdmanum);
|
||||
}
|
||||
else if (v->size != (size>>2))
|
||||
ProcessMemSkip(size, unpackType, VIFdmanum);
|
||||
|
||||
if (vifRegs->cycle.cl >= vifRegs->cycle.wl) { // skipping write
|
||||
|
||||
|
@ -620,7 +627,7 @@ static void VIFunpack(u32 *data, vifCode *v, int size, const unsigned int VIFdma
|
|||
|
||||
}
|
||||
else { /* filling write */
|
||||
VIF_LOG("*PCSX2*: filling write\n");
|
||||
VIF_LOG("VIFunpack - filling write\n");
|
||||
|
||||
VIFUNPACK_LOG("filling write %d cl %d, wl %d mask %x mode %x unpacktype %x\n", vifRegs->num, vifRegs->cycle.cl, vifRegs->cycle.wl, vifRegs->mask, vifRegs->mode, unpackType);
|
||||
while (size >= ft->gsize || vifRegs->num > 0) {
|
||||
|
@ -656,10 +663,6 @@ static void vuExecMicro( u32 addr, const u32 VIFdmanum )
|
|||
{
|
||||
int _cycles;
|
||||
VURegs * VU;
|
||||
//void (*_vuExecMicro)();
|
||||
|
||||
// MessageBox(NULL, "3d doesn't work\n", "Query", MB_OK);
|
||||
// return;
|
||||
|
||||
if (VIFdmanum == 0) {
|
||||
VU = &VU0;
|
||||
|
@ -773,12 +776,12 @@ static __forceinline void _vif0mpgTransfer(u32 addr, u32 *data, int size) {
|
|||
// Vif1 Data Transfer Commands
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static int Vif0TransNull(u32 *data){ // Shouldnt go here
|
||||
static int __fastcall Vif0TransNull(u32 *data){ // Shouldnt go here
|
||||
SysPrintf("VIF0 Shouldnt go here CMD = %x\n", vif0Regs->code);
|
||||
vif0.cmd = 0;
|
||||
return 0;
|
||||
}
|
||||
static int Vif0TransSTMask(u32 *data){ // STMASK
|
||||
static int __fastcall Vif0TransSTMask(u32 *data){ // STMASK
|
||||
SetNewMask(g_vif0Masks, g_vif0HasMask3, data[0], vif0Regs->mask);
|
||||
vif0Regs->mask = data[0];
|
||||
VIF_LOG("STMASK == %x\n", vif0Regs->mask);
|
||||
|
@ -788,7 +791,7 @@ static int Vif0TransSTMask(u32 *data){ // STMASK
|
|||
return 1;
|
||||
}
|
||||
|
||||
static int Vif0TransSTRow(u32 *data){ // STROW
|
||||
static int __fastcall Vif0TransSTRow(u32 *data){ // STROW
|
||||
int ret;
|
||||
|
||||
u32* pmem = &vif0Regs->r0+(vif0.tag.addr<<2);
|
||||
|
@ -811,7 +814,7 @@ static int Vif0TransSTRow(u32 *data){ // STROW
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int Vif0TransSTCol(u32 *data){ // STCOL
|
||||
static int __fastcall Vif0TransSTCol(u32 *data){ // STCOL
|
||||
int ret;
|
||||
|
||||
u32* pmem = &vif0Regs->c0+(vif0.tag.addr<<2);
|
||||
|
@ -831,7 +834,7 @@ static int Vif0TransSTCol(u32 *data){ // STCOL
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int Vif0TransMPG(u32 *data){ // MPG
|
||||
static int __fastcall Vif0TransMPG(u32 *data){ // MPG
|
||||
if (vif0.vifpacketsize < vif0.tag.size) {
|
||||
_vif0mpgTransfer(vif0.tag.addr, data, vif0.vifpacketsize);
|
||||
vif0.tag.addr += vif0.vifpacketsize << 2;
|
||||
|
@ -847,26 +850,29 @@ static int Vif0TransMPG(u32 *data){ // MPG
|
|||
}
|
||||
}
|
||||
|
||||
static int Vif0TransUnpack(u32 *data){ // UNPACK
|
||||
static int __fastcall Vif0TransUnpack(u32 *data) // UNPACK
|
||||
{
|
||||
FreezeXMMRegs(1);
|
||||
if (vif0.vifpacketsize < vif0.tag.size) {
|
||||
/* size is less that the total size, transfer is
|
||||
'in pieces' */
|
||||
VIFunpack(data, &vif0.tag, vif0.vifpacketsize, VIF0dmanum);
|
||||
vif0.tag.size -= vif0.vifpacketsize;
|
||||
FreezeXMMRegs(0);
|
||||
return vif0.vifpacketsize;
|
||||
} else {
|
||||
int ret;
|
||||
/* we got all the data, transfer it fully */
|
||||
VIFunpack(data, &vif0.tag, vif0.tag.size, VIF0dmanum);
|
||||
ret = vif0.tag.size;
|
||||
vif0.tag.size = 0;
|
||||
vif0.cmd = 0;
|
||||
FreezeXMMRegs(0);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (vif0.vifpacketsize < vif0.tag.size)
|
||||
{
|
||||
/* size is less that the total size, transfer is
|
||||
'in pieces' */
|
||||
VIFunpack(data, &vif0.tag, vif0.vifpacketsize, VIF0dmanum);
|
||||
vif0.tag.size -= vif0.vifpacketsize;
|
||||
FreezeXMMRegs(0);
|
||||
return vif0.vifpacketsize;
|
||||
}
|
||||
else
|
||||
{
|
||||
int ret;
|
||||
/* we got all the data, transfer it fully */
|
||||
VIFunpack(data, &vif0.tag, vif0.tag.size, VIF0dmanum);
|
||||
ret = vif0.tag.size;
|
||||
vif0.tag.size = 0;
|
||||
vif0.cmd = 0;
|
||||
FreezeXMMRegs(0);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -1165,7 +1171,7 @@ void vif0Interrupt() {
|
|||
}
|
||||
|
||||
// Vif1 Data Transfer Table
|
||||
int (*Vif0TransTLB[128])(u32 *data) =
|
||||
int (__fastcall *Vif0TransTLB[128])(u32 *data) =
|
||||
{
|
||||
Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , /*0x7*/
|
||||
Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , /*0xF*/
|
||||
|
@ -1306,8 +1312,10 @@ void vif0Write32(u32 mem, u32 value) {
|
|||
if( mem >= 0x10003900 && mem < 0x10003980 ) {
|
||||
|
||||
assert( (mem&0xf) == 0 );
|
||||
if( mem < 0x10003940 ) g_vifRow0[(mem>>4)&3] = value;
|
||||
else g_vifCol0[(mem>>4)&3] = value;
|
||||
if( mem < 0x10003940 )
|
||||
g_vifRow0[(mem>>4)&3] = value;
|
||||
else
|
||||
g_vifCol0[(mem>>4)&3] = value;
|
||||
} else psHu32(mem) = value;
|
||||
}
|
||||
|
||||
|
@ -1327,10 +1335,19 @@ void vif0Reset() {
|
|||
vif0Regs->stat&= ~0xF000000; // FQC=0
|
||||
}
|
||||
|
||||
void SaveState::vif0Freeze() {
|
||||
Freeze(vif0);
|
||||
if( IsLoading() )
|
||||
SetNewMask(g_vif0Masks, g_vif0HasMask3, vif0Regs->mask, ~vif0Regs->mask);
|
||||
void SaveState::vif0Freeze()
|
||||
{
|
||||
// Dunno if this one is needed, but whatever, it's small. :)
|
||||
Freeze( g_vifCycles );
|
||||
|
||||
Freeze( vif0 );
|
||||
if( GetVersion() >= 0x14 )
|
||||
{
|
||||
Freeze( g_vif1HasMask3 );
|
||||
Freeze( g_vif1Masks );
|
||||
Freeze( g_vifRow1 );
|
||||
Freeze( g_vifCol1 );
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -1402,12 +1419,12 @@ static __forceinline void _vif1mpgTransfer(u32 addr, u32 *data, int size) {
|
|||
// Vif1 Data Transfer Commands
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static int Vif1TransNull(u32 *data){ // Shouldnt go here
|
||||
static int __fastcall Vif1TransNull(u32 *data){ // Shouldnt go here
|
||||
SysPrintf("Shouldnt go here CMD = %x\n", vif1Regs->code);
|
||||
vif1.cmd = 0;
|
||||
return 0;
|
||||
}
|
||||
static int Vif1TransSTMask(u32 *data){ // STMASK
|
||||
static int __fastcall Vif1TransSTMask(u32 *data){ // STMASK
|
||||
SetNewMask(g_vif1Masks, g_vif1HasMask3, data[0], vif1Regs->mask);
|
||||
vif1Regs->mask = data[0];
|
||||
VIF_LOG("STMASK == %x\n", vif1Regs->mask);
|
||||
|
@ -1417,7 +1434,7 @@ static int Vif1TransSTMask(u32 *data){ // STMASK
|
|||
return 1;
|
||||
}
|
||||
|
||||
static int Vif1TransSTRow(u32 *data){
|
||||
static int __fastcall Vif1TransSTRow(u32 *data){
|
||||
int ret;
|
||||
|
||||
u32* pmem = &vif1Regs->r0+(vif1.tag.addr<<2);
|
||||
|
@ -1439,7 +1456,7 @@ static int Vif1TransSTRow(u32 *data){
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int Vif1TransSTCol(u32 *data){
|
||||
static int __fastcall Vif1TransSTCol(u32 *data){
|
||||
int ret;
|
||||
|
||||
u32* pmem = &vif1Regs->c0+(vif1.tag.addr<<2);
|
||||
|
@ -1458,7 +1475,7 @@ static int Vif1TransSTCol(u32 *data){
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int Vif1TransMPG(u32 *data){
|
||||
static int __fastcall Vif1TransMPG(u32 *data){
|
||||
if (vif1.vifpacketsize < vif1.tag.size) {
|
||||
_vif1mpgTransfer(vif1.tag.addr, data, vif1.vifpacketsize);
|
||||
vif1.tag.addr += vif1.vifpacketsize << 2;
|
||||
|
@ -1476,7 +1493,7 @@ static int Vif1TransMPG(u32 *data){
|
|||
u32 splittransfer[4];
|
||||
u32 splitptr = 0;
|
||||
|
||||
static int Vif1TransDirectHL(u32 *data){
|
||||
static int __fastcall Vif1TransDirectHL(u32 *data){
|
||||
int ret = 0;
|
||||
|
||||
|
||||
|
@ -1558,7 +1575,7 @@ static int Vif1TransDirectHL(u32 *data){
|
|||
}
|
||||
|
||||
|
||||
static int Vif1TransUnpack(u32 *data){
|
||||
static int __fastcall Vif1TransUnpack(u32 *data){
|
||||
FreezeXMMRegs(1);
|
||||
|
||||
if (vif1.vifpacketsize < vif1.tag.size)
|
||||
|
@ -1718,7 +1735,7 @@ static void Vif1CMDNull(){ // invalid opcode
|
|||
|
||||
// Vif1 Data Transfer Table
|
||||
|
||||
int (*Vif1TransTLB[128])(u32 *data) =
|
||||
int (__fastcall *Vif1TransTLB[128])(u32 *data) =
|
||||
{
|
||||
Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , /*0x7*/
|
||||
Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , /*0xF*/
|
||||
|
@ -2236,10 +2253,20 @@ void vif1Reset() {
|
|||
vif1Regs->stat&= ~0x1F000000; // FQC=0
|
||||
}
|
||||
|
||||
void SaveState::vif1Freeze() {
|
||||
void SaveState::vif1Freeze()
|
||||
{
|
||||
Freeze(vif1);
|
||||
if( IsLoading() ){
|
||||
|
||||
if( GetVersion() >= 0x14 )
|
||||
{
|
||||
Freeze( g_vif1HasMask3 );
|
||||
Freeze( g_vif1Masks );
|
||||
Freeze( g_vifRow1 );
|
||||
Freeze( g_vifCol1 );
|
||||
}
|
||||
|
||||
/*if( IsLoading() ){
|
||||
SetNewMask(g_vif1Masks, g_vif1HasMask3, vif1Regs->mask, ~vif1Regs->mask);
|
||||
if(vif1ch->chcr & 0x100)vif1.done = 0;
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
|
|
@ -48,39 +48,39 @@ extern int Path3transfer;
|
|||
#define vif0ch ((DMACh*)&PS2MEM_HW[0x8000])
|
||||
#define vif1ch ((DMACh*)&PS2MEM_HW[0x9000])
|
||||
|
||||
void UNPACK_S_32( u32 *dest, u32 *data, int size );
|
||||
void __fastcall UNPACK_S_32( u32 *dest, u32 *data, int size );
|
||||
|
||||
void UNPACK_S_16u( u32 *dest, u32 *data, int size );
|
||||
void UNPACK_S_16s( u32 *dest, u32 *data, int size );
|
||||
void __fastcall UNPACK_S_16u( u32 *dest, u32 *data, int size );
|
||||
void __fastcall UNPACK_S_16s( u32 *dest, u32 *data, int size );
|
||||
|
||||
void UNPACK_S_8u( u32 *dest, u32 *data, int size );
|
||||
void UNPACK_S_8s( u32 *dest, u32 *data, int size );
|
||||
void __fastcall UNPACK_S_8u( u32 *dest, u32 *data, int size );
|
||||
void __fastcall UNPACK_S_8s( u32 *dest, u32 *data, int size );
|
||||
|
||||
void UNPACK_V2_32( u32 *dest, u32 *data, int size );
|
||||
void __fastcall UNPACK_V2_32( u32 *dest, u32 *data, int size );
|
||||
|
||||
void UNPACK_V2_16u( u32 *dest, u32 *data, int size );
|
||||
void UNPACK_V2_16s( u32 *dest, u32 *data, int size );
|
||||
void __fastcall UNPACK_V2_16u( u32 *dest, u32 *data, int size );
|
||||
void __fastcall UNPACK_V2_16s( u32 *dest, u32 *data, int size );
|
||||
|
||||
void UNPACK_V2_8u( u32 *dest, u32 *data, int size );
|
||||
void UNPACK_V2_8s( u32 *dest, u32 *data, int size );
|
||||
void __fastcall UNPACK_V2_8u( u32 *dest, u32 *data, int size );
|
||||
void __fastcall UNPACK_V2_8s( u32 *dest, u32 *data, int size );
|
||||
|
||||
void UNPACK_V3_32( u32 *dest, u32 *data, int size );
|
||||
void __fastcall UNPACK_V3_32( u32 *dest, u32 *data, int size );
|
||||
|
||||
void UNPACK_V3_16u( u32 *dest, u32 *data, int size );
|
||||
void UNPACK_V3_16s( u32 *dest, u32 *data, int size );
|
||||
void __fastcall UNPACK_V3_16u( u32 *dest, u32 *data, int size );
|
||||
void __fastcall UNPACK_V3_16s( u32 *dest, u32 *data, int size );
|
||||
|
||||
void UNPACK_V3_8u( u32 *dest, u32 *data, int size );
|
||||
void UNPACK_V3_8s( u32 *dest, u32 *data, int size );
|
||||
void __fastcall UNPACK_V3_8u( u32 *dest, u32 *data, int size );
|
||||
void __fastcall UNPACK_V3_8s( u32 *dest, u32 *data, int size );
|
||||
|
||||
void UNPACK_V4_32( u32 *dest, u32 *data, int size );
|
||||
void __fastcall UNPACK_V4_32( u32 *dest, u32 *data, int size );
|
||||
|
||||
void UNPACK_V4_16u( u32 *dest, u32 *data, int size );
|
||||
void UNPACK_V4_16s( u32 *dest, u32 *data, int size );
|
||||
void __fastcall UNPACK_V4_16u( u32 *dest, u32 *data, int size );
|
||||
void __fastcall UNPACK_V4_16s( u32 *dest, u32 *data, int size );
|
||||
|
||||
void UNPACK_V4_8u( u32 *dest, u32 *data, int size );
|
||||
void UNPACK_V4_8s( u32 *dest, u32 *data, int size );
|
||||
void __fastcall UNPACK_V4_8u( u32 *dest, u32 *data, int size );
|
||||
void __fastcall UNPACK_V4_8s( u32 *dest, u32 *data, int size );
|
||||
|
||||
void UNPACK_V4_5( u32 *dest, u32 *data, int size );
|
||||
void __fastcall UNPACK_V4_5( u32 *dest, u32 *data, int size );
|
||||
|
||||
void vifDmaInit();
|
||||
void vif0Init();
|
||||
|
|
|
@ -113,9 +113,9 @@ __forceinline DataType __fastcall MemOp_r0(u32 addr)
|
|||
|
||||
switch( DataSize )
|
||||
{
|
||||
case 8: return ((vltbMemR8FP*)RWFT[0][0][hand])(paddr);
|
||||
case 16: return ((vltbMemR16FP*)RWFT[1][0][hand])(paddr);
|
||||
case 32: return ((vltbMemR32FP*)RWFT[2][0][hand])(paddr);
|
||||
case 8: return ((vtlbMemR8FP*)RWFT[0][0][hand])(paddr);
|
||||
case 16: return ((vtlbMemR16FP*)RWFT[1][0][hand])(paddr);
|
||||
case 32: return ((vtlbMemR32FP*)RWFT[2][0][hand])(paddr);
|
||||
|
||||
jNO_DEFAULT;
|
||||
}
|
||||
|
@ -144,8 +144,8 @@ __forceinline void __fastcall MemOp_r1(u32 addr, DataType* data)
|
|||
|
||||
switch( DataSize )
|
||||
{
|
||||
case 64: ((vltbMemR64FP*)RWFT[3][0][hand])(paddr, data); break;
|
||||
case 128: ((vltbMemR128FP*)RWFT[4][0][hand])(paddr, data); break;
|
||||
case 64: ((vtlbMemR64FP*)RWFT[3][0][hand])(paddr, data); break;
|
||||
case 128: ((vtlbMemR128FP*)RWFT[4][0][hand])(paddr, data); break;
|
||||
|
||||
jNO_DEFAULT;
|
||||
}
|
||||
|
@ -170,9 +170,9 @@ __forceinline void __fastcall MemOp_w0(u32 addr, DataType data)
|
|||
|
||||
switch( DataSize )
|
||||
{
|
||||
case 8: return ((vltbMemW8FP*)RWFT[0][1][hand])(paddr, (u8)data);
|
||||
case 16: return ((vltbMemW16FP*)RWFT[1][1][hand])(paddr, (u16)data);
|
||||
case 32: return ((vltbMemW32FP*)RWFT[2][1][hand])(paddr, (u32)data);
|
||||
case 8: return ((vtlbMemW8FP*)RWFT[0][1][hand])(paddr, (u8)data);
|
||||
case 16: return ((vtlbMemW16FP*)RWFT[1][1][hand])(paddr, (u16)data);
|
||||
case 32: return ((vtlbMemW32FP*)RWFT[2][1][hand])(paddr, (u32)data);
|
||||
|
||||
jNO_DEFAULT;
|
||||
}
|
||||
|
@ -198,8 +198,8 @@ __forceinline void __fastcall MemOp_w1(u32 addr,const DataType* data)
|
|||
//SysPrintf("Translted 0x%08X to 0x%08X\n",addr,paddr);
|
||||
switch( DataSize )
|
||||
{
|
||||
case 64: return ((vltbMemW64FP*)RWFT[3][1][hand])(paddr, data);
|
||||
case 128: return ((vltbMemW128FP*)RWFT[4][1][hand])(paddr, data);
|
||||
case 64: return ((vtlbMemW64FP*)RWFT[3][1][hand])(paddr, data);
|
||||
case 128: return ((vtlbMemW128FP*)RWFT[4][1][hand])(paddr, data);
|
||||
|
||||
jNO_DEFAULT;
|
||||
}
|
||||
|
@ -348,8 +348,8 @@ void __fastcall vtlbDefaultPhyWrite128(u32 addr,const mem128_t* data) { Console:
|
|||
// Note: All handlers persist across calls to vtlb_Reset(), but are wiped/invalidated by calls to vtlb_Init()
|
||||
//
|
||||
// Returns a handle for the newly created handler See .vtlb_MapHandler for use of the return value.
|
||||
vtlbHandler vtlb_RegisterHandler( vltbMemR8FP* r8,vltbMemR16FP* r16,vltbMemR32FP* r32,vltbMemR64FP* r64,vltbMemR128FP* r128,
|
||||
vltbMemW8FP* w8,vltbMemW16FP* w16,vltbMemW32FP* w32,vltbMemW64FP* w64,vltbMemW128FP* w128)
|
||||
vtlbHandler vtlb_RegisterHandler( vtlbMemR8FP* r8,vtlbMemR16FP* r16,vtlbMemR32FP* r32,vtlbMemR64FP* r64,vtlbMemR128FP* r128,
|
||||
vtlbMemW8FP* w8,vtlbMemW16FP* w16,vtlbMemW32FP* w32,vtlbMemW64FP* w64,vtlbMemW128FP* w128)
|
||||
{
|
||||
//write the code :p
|
||||
vtlbHandler rv=vtlbHandlerCount++;
|
||||
|
|
24
pcsx2/vtlb.h
24
pcsx2/vtlb.h
|
@ -8,18 +8,18 @@ typedef u64 mem64_t;
|
|||
typedef u64 mem128_t;
|
||||
|
||||
// Specialized function pointers for each read type
|
||||
typedef mem8_t __fastcall vltbMemR8FP(u32 addr);
|
||||
typedef mem16_t __fastcall vltbMemR16FP(u32 addr);
|
||||
typedef mem32_t __fastcall vltbMemR32FP(u32 addr);
|
||||
typedef void __fastcall vltbMemR64FP(u32 addr,mem64_t* data);
|
||||
typedef void __fastcall vltbMemR128FP(u32 addr,mem128_t* data);
|
||||
typedef mem8_t __fastcall vtlbMemR8FP(u32 addr);
|
||||
typedef mem16_t __fastcall vtlbMemR16FP(u32 addr);
|
||||
typedef mem32_t __fastcall vtlbMemR32FP(u32 addr);
|
||||
typedef void __fastcall vtlbMemR64FP(u32 addr,mem64_t* data);
|
||||
typedef void __fastcall vtlbMemR128FP(u32 addr,mem128_t* data);
|
||||
|
||||
// Specialized function pointers for each write type
|
||||
typedef void __fastcall vltbMemW8FP(u32 addr,mem8_t data);
|
||||
typedef void __fastcall vltbMemW16FP(u32 addr,mem16_t data);
|
||||
typedef void __fastcall vltbMemW32FP(u32 addr,mem32_t data);
|
||||
typedef void __fastcall vltbMemW64FP(u32 addr,const mem64_t* data);
|
||||
typedef void __fastcall vltbMemW128FP(u32 addr,const mem128_t* data);
|
||||
typedef void __fastcall vtlbMemW8FP(u32 addr,mem8_t data);
|
||||
typedef void __fastcall vtlbMemW16FP(u32 addr,mem16_t data);
|
||||
typedef void __fastcall vtlbMemW32FP(u32 addr,mem32_t data);
|
||||
typedef void __fastcall vtlbMemW64FP(u32 addr,const mem64_t* data);
|
||||
typedef void __fastcall vtlbMemW128FP(u32 addr,const mem128_t* data);
|
||||
|
||||
typedef u32 vtlbHandler;
|
||||
|
||||
|
@ -31,8 +31,8 @@ extern void vtlb_free( void* pmem, uint size );
|
|||
|
||||
|
||||
//physical stuff
|
||||
vtlbHandler vtlb_RegisterHandler( vltbMemR8FP* r8,vltbMemR16FP* r16,vltbMemR32FP* r32,vltbMemR64FP* r64,vltbMemR128FP* r128,
|
||||
vltbMemW8FP* w8,vltbMemW16FP* w16,vltbMemW32FP* w32,vltbMemW64FP* w64,vltbMemW128FP* w128);
|
||||
vtlbHandler vtlb_RegisterHandler( vtlbMemR8FP* r8,vtlbMemR16FP* r16,vtlbMemR32FP* r32,vtlbMemR64FP* r64,vtlbMemR128FP* r128,
|
||||
vtlbMemW8FP* w8,vtlbMemW16FP* w16,vtlbMemW32FP* w32,vtlbMemW64FP* w64,vtlbMemW128FP* w128);
|
||||
|
||||
extern void vtlb_MapHandler(vtlbHandler handler,u32 start,u32 size);
|
||||
extern void vtlb_MapBlock(void* base,u32 start,u32 size,u32 blocksize=0);
|
||||
|
|
|
@ -1097,8 +1097,8 @@ BEGIN
|
|||
CONTROL "Use x1.5 Cycle Rate",IDC_EESYNC1,"Button",BS_AUTORADIOBUTTON,13,79,87,10
|
||||
CONTROL "Use x2 Cycle Rate",IDC_EESYNC2,"Button",BS_AUTORADIOBUTTON,13,113,83,10
|
||||
CONTROL "Use x3 Cycle Rate",IDC_EESYNC3,"Button",BS_AUTORADIOBUTTON,13,147,80,10
|
||||
CONTROL "Enable IOP x2 Cycle Rate",IDC_IOPSYNC,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,174,97,98,10
|
||||
CONTROL "WaitCycles Sync Hack",IDC_WAITCYCLES,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,174,138,90,10
|
||||
CONTROL "Enable IOP x2 Cycle Rate",IDC_IOPSYNC,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,174,88,98,10
|
||||
CONTROL "WaitCycles Sync Hack",IDC_WAITCYCLES,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,174,127,90,10
|
||||
CONTROL "Escape Hack - Use Esc key to fully exit PCSX2.",IDC_ESCHACK,
|
||||
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,234,180,10
|
||||
DEFPUSHBUTTON "OK",IDOK,217,242,50,14
|
||||
|
@ -1106,15 +1106,15 @@ BEGIN
|
|||
CTEXT "These hacks will speed up emulation but reduce emulation compatibility or cause visual errors. If you have problems, disable all these and try again!",IDC_HACKDESC,18,7,286,19
|
||||
GROUPBOX "EmotionEngine (EE) Sync Hacks",IDC_STATIC,7,31,159,180
|
||||
GROUPBOX "Miscellaneous",IDC_STATIC,7,220,194,33
|
||||
LTEXT "Important: X2 and X3 sync hacks *will* cause choppy/skippy audio on many FMV movies.",IDC_STATIC,13,183,149,25
|
||||
LTEXT "*OBSOLETE* Better off using the INTC Sync Hack instead.",IDC_STATIC,25,158,133,19
|
||||
LTEXT "Important: X2 and X3 sync hacks *will* cause choppy/skippy audio on many FMV movies.",IDC_STATIC,13,188,149,21
|
||||
LTEXT "Known to work well with a couple games, namely Shadow of the Colossus (but breaks most other games).",IDC_STATIC,25,158,133,28
|
||||
LTEXT "Big speedup! Works well with many games.",IDC_STATIC,25,124,125,19
|
||||
LTEXT "Most compatible option - recommended for everyone with high-end machines.",IDC_STATIC,25,55,136,19
|
||||
LTEXT "Small speedup and works well with most games.",IDC_STATIC,186,109,134,22
|
||||
LTEXT "Small speedup. Works well with most games, but may cause certain games to crash or freeze up during bootup or stage changes.",IDC_STATIC,186,150,141,39
|
||||
LTEXT "Small speedup and works well with most games.",IDC_STATIC,186,100,134,22
|
||||
LTEXT "Small speedup. Works well with most games, but may cause certain games to crash or freeze up during bootup or stage changes.",IDC_STATIC,186,139,141,39
|
||||
LTEXT "Moderate speedup and works well with most games.",IDC_STATIC,25,90,129,19
|
||||
CONTROL "INTC Sync Hack (experimental)",IDC_INTCSTATHACK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,174,43,127,10
|
||||
LTEXT "Huge speedup! And few negative side effects in most games. When enabling this it might be best to leave the EE sync hack set to Default.",IDC_STATIC,186,55,140,36
|
||||
LTEXT "Huge speedup in many games, and a pretty high compatibility rate (some games still work better with EE sync hacks).",IDC_STATIC,186,55,140,28
|
||||
END
|
||||
|
||||
|
||||
|
|
|
@ -61,7 +61,7 @@ extern "C" PCSX2_ALIGNED16(u32 s_TempDecompress[4]) = {0};
|
|||
#include <xmmintrin.h>
|
||||
#include <emmintrin.h>
|
||||
|
||||
void SetNewMask(u32* vif1masks, u32* hasmask, u32 mask, u32 oldmask)
|
||||
void __fastcall SetNewMask(u32* vif1masks, u32* hasmask, u32 mask, u32 oldmask)
|
||||
{
|
||||
u32 i;
|
||||
u32 prev = 0;
|
||||
|
@ -98,7 +98,7 @@ void SetNewMask(u32* vif1masks, u32* hasmask, u32 mask, u32 oldmask)
|
|||
|
||||
#else // gcc
|
||||
|
||||
void SetNewMask(u32* vif1masks, u32* hasmask, u32 mask, u32 oldmask)
|
||||
void __fastcall SetNewMask(u32* vif1masks, u32* hasmask, u32 mask, u32 oldmask)
|
||||
{
|
||||
u32 i;
|
||||
u32 prev = 0;
|
||||
|
|
|
@ -742,10 +742,81 @@ void recDIVU1_constt(int info)
|
|||
|
||||
EERECOMPILE_CODE0(DIVU1, XMMINFO_READS|XMMINFO_READT);
|
||||
|
||||
//do EEINST_SETSIGNEXT
|
||||
REC_FUNC_DEL( MADD, _Rd_ );
|
||||
|
||||
static PCSX2_ALIGNED16(u32 s_MaddMask[]) = { 0x80000000, 0, 0x80000000, 0 };
|
||||
void recMADD()
|
||||
{
|
||||
EEINST_SETSIGNEXT(_Rs_);
|
||||
EEINST_SETSIGNEXT(_Rt_);
|
||||
|
||||
if( GPR_IS_CONST2(_Rs_, _Rt_) ) {
|
||||
u64 result = ((s64)g_cpuConstRegs[_Rs_].SL[0] * (s64)g_cpuConstRegs[_Rt_].SL[0]);
|
||||
_deleteEEreg(XMMGPR_LO, 1);
|
||||
_deleteEEreg(XMMGPR_HI, 1);
|
||||
|
||||
// dadd
|
||||
MOV32MtoR( EAX, (int)&cpuRegs.LO.UL[ 0 ] );
|
||||
MOV32MtoR( ECX, (int)&cpuRegs.HI.UL[ 0 ] );
|
||||
ADD32ItoR( EAX, (u32)result&0xffffffff );
|
||||
ADC32ItoR( ECX, (u32)(result>>32) );
|
||||
CDQ();
|
||||
if( _Rd_) {
|
||||
_eeOnWriteReg(_Rd_, 1);
|
||||
_deleteEEreg(_Rd_, 0);
|
||||
MOV32RtoM( (int)&cpuRegs.GPR.r[ _Rd_ ].UL[ 0 ], EAX );
|
||||
MOV32RtoM( (int)&cpuRegs.GPR.r[ _Rd_ ].UL[ 1 ], EDX );
|
||||
}
|
||||
|
||||
MOV32RtoM( (int)&cpuRegs.LO.UL[0], EAX );
|
||||
MOV32RtoM( (int)&cpuRegs.LO.UL[1], EDX );
|
||||
|
||||
MOV32RtoM( (int)&cpuRegs.HI.UL[0], ECX );
|
||||
MOV32RtoR(EAX, ECX);
|
||||
CDQ();
|
||||
MOV32RtoM( (int)&cpuRegs.HI.UL[1], EDX );
|
||||
return;
|
||||
}
|
||||
|
||||
_deleteEEreg(XMMGPR_LO, 1);
|
||||
_deleteEEreg(XMMGPR_HI, 1);
|
||||
_deleteGPRtoXMMreg(_Rs_, 1);
|
||||
_deleteGPRtoXMMreg(_Rt_, 1);
|
||||
_deleteMMXreg(MMX_GPR+_Rs_, 1);
|
||||
_deleteMMXreg(MMX_GPR+_Rt_, 1);
|
||||
|
||||
if( GPR_IS_CONST1(_Rs_) ) {
|
||||
MOV32ItoR( EAX, g_cpuConstRegs[_Rs_].UL[0] );
|
||||
MUL32M( (int)&cpuRegs.GPR.r[ _Rt_ ].UL[ 0 ] );
|
||||
}
|
||||
else if ( GPR_IS_CONST1(_Rt_) ) {
|
||||
MOV32ItoR( EAX, g_cpuConstRegs[_Rt_].UL[0] );
|
||||
MUL32M( (int)&cpuRegs.GPR.r[ _Rs_ ].UL[ 0 ] );
|
||||
}
|
||||
else {
|
||||
MOV32MtoR( EAX, (int)&cpuRegs.GPR.r[ _Rs_ ].UL[ 0 ] );
|
||||
MUL32M( (int)&cpuRegs.GPR.r[ _Rt_ ].UL[ 0 ] );
|
||||
}
|
||||
|
||||
MOV32RtoR( ECX, EDX );
|
||||
ADD32MtoR( EAX, (u32)&cpuRegs.LO.UL[0] );
|
||||
ADC32MtoR( ECX, (u32)&cpuRegs.HI.UL[0] );
|
||||
CDQ();
|
||||
if( _Rd_ ) {
|
||||
_eeOnWriteReg(_Rd_, 1);
|
||||
_deleteEEreg(_Rd_, 0);
|
||||
MOV32RtoM( (int)&cpuRegs.GPR.r[ _Rd_ ].UL[ 0 ], EAX );
|
||||
MOV32RtoM( (int)&cpuRegs.GPR.r[ _Rd_ ].UL[ 1 ], EDX );
|
||||
}
|
||||
|
||||
MOV32RtoM( (int)&cpuRegs.LO.UL[0], EAX );
|
||||
MOV32RtoM( (int)&cpuRegs.LO.UL[1], EDX );
|
||||
|
||||
MOV32RtoM( (int)&cpuRegs.HI.UL[0], ECX );
|
||||
MOV32RtoR(EAX, ECX);
|
||||
CDQ();
|
||||
MOV32RtoM( (int)&cpuRegs.HI.UL[1], EDX );
|
||||
}
|
||||
|
||||
//static PCSX2_ALIGNED16(u32 s_MaddMask[]) = { 0x80000000, 0, 0x80000000, 0 };
|
||||
|
||||
void recMADDU()
|
||||
{
|
||||
|
@ -822,26 +893,153 @@ void recMADDU()
|
|||
|
||||
void recMADD1()
|
||||
{
|
||||
//SysPrintf("MADD1 email zero if abnormal behavior\n");
|
||||
EEINST_SETSIGNEXT(_Rs_);
|
||||
EEINST_SETSIGNEXT(_Rt_);
|
||||
if( _Rd_ ) EEINST_SETSIGNEXT(_Rd_);
|
||||
_deleteEEreg(XMMGPR_LO, 0);
|
||||
_deleteEEreg(XMMGPR_HI, 0);
|
||||
recCall( Interp::MADD1, _Rd_ );
|
||||
|
||||
if( GPR_IS_CONST2(_Rs_, _Rt_) ) {
|
||||
u64 result = ((s64)g_cpuConstRegs[_Rs_].SL[0] * (s64)g_cpuConstRegs[_Rt_].SL[0]);
|
||||
_deleteEEreg(XMMGPR_LO, 1);
|
||||
_deleteEEreg(XMMGPR_HI, 1);
|
||||
|
||||
// dadd
|
||||
MOV32MtoR( EAX, (int)&cpuRegs.LO.UL[ 2 ] );
|
||||
MOV32MtoR( ECX, (int)&cpuRegs.HI.UL[ 2 ] );
|
||||
ADD32ItoR( EAX, (u32)result&0xffffffff );
|
||||
ADC32ItoR( ECX, (u32)(result>>32) );
|
||||
CDQ();
|
||||
if( _Rd_) {
|
||||
_eeOnWriteReg(_Rd_, 1);
|
||||
_deleteEEreg(_Rd_, 0);
|
||||
MOV32RtoM( (int)&cpuRegs.GPR.r[ _Rd_ ].UL[ 0 ], EAX );
|
||||
MOV32RtoM( (int)&cpuRegs.GPR.r[ _Rd_ ].UL[ 1 ], EDX );
|
||||
}
|
||||
|
||||
MOV32RtoM( (int)&cpuRegs.LO.UL[2], EAX );
|
||||
MOV32RtoM( (int)&cpuRegs.LO.UL[3], EDX );
|
||||
|
||||
MOV32RtoM( (int)&cpuRegs.HI.UL[2], ECX );
|
||||
MOV32RtoR(EAX, ECX);
|
||||
CDQ();
|
||||
MOV32RtoM( (int)&cpuRegs.HI.UL[3], EDX );
|
||||
return;
|
||||
}
|
||||
|
||||
_deleteEEreg(XMMGPR_LO, 1);
|
||||
_deleteEEreg(XMMGPR_HI, 1);
|
||||
_deleteGPRtoXMMreg(_Rs_, 1);
|
||||
_deleteGPRtoXMMreg(_Rt_, 1);
|
||||
_deleteMMXreg(MMX_GPR+_Rs_, 1);
|
||||
_deleteMMXreg(MMX_GPR+_Rt_, 1);
|
||||
|
||||
if( GPR_IS_CONST1(_Rs_) ) {
|
||||
MOV32ItoR( EAX, g_cpuConstRegs[_Rs_].UL[0] );
|
||||
IMUL32M( (int)&cpuRegs.GPR.r[ _Rt_ ].UL[ 0 ] );
|
||||
}
|
||||
else if ( GPR_IS_CONST1(_Rt_) ) {
|
||||
MOV32ItoR( EAX, g_cpuConstRegs[_Rt_].UL[0] );
|
||||
IMUL32M( (int)&cpuRegs.GPR.r[ _Rs_ ].UL[ 0 ] );
|
||||
}
|
||||
else {
|
||||
MOV32MtoR( EAX, (int)&cpuRegs.GPR.r[ _Rs_ ].UL[ 0 ] );
|
||||
IMUL32M( (int)&cpuRegs.GPR.r[ _Rt_ ].UL[ 0 ] );
|
||||
}
|
||||
|
||||
MOV32RtoR( ECX, EDX );
|
||||
ADD32MtoR( EAX, (u32)&cpuRegs.LO.UL[2] );
|
||||
ADC32MtoR( ECX, (u32)&cpuRegs.HI.UL[2] );
|
||||
CDQ();
|
||||
if( _Rd_ ) {
|
||||
_eeOnWriteReg(_Rd_, 1);
|
||||
_deleteEEreg(_Rd_, 0);
|
||||
MOV32RtoM( (int)&cpuRegs.GPR.r[ _Rd_ ].UL[ 0 ], EAX );
|
||||
MOV32RtoM( (int)&cpuRegs.GPR.r[ _Rd_ ].UL[ 1 ], EDX );
|
||||
}
|
||||
|
||||
MOV32RtoM( (int)&cpuRegs.LO.UL[2], EAX );
|
||||
MOV32RtoM( (int)&cpuRegs.LO.UL[3], EDX );
|
||||
|
||||
MOV32RtoM( (int)&cpuRegs.HI.UL[2], ECX );
|
||||
MOV32RtoR(EAX, ECX);
|
||||
CDQ();
|
||||
MOV32RtoM( (int)&cpuRegs.HI.UL[3], EDX );
|
||||
}
|
||||
|
||||
//static PCSX2_ALIGNED16(u32 s_MaddMask[]) = { 0x80000000, 0, 0x80000000, 0 };
|
||||
|
||||
void recMADDU1()
|
||||
{
|
||||
//SysPrintf("MADDU1 email zero if abnormal behavior\n");
|
||||
EEINST_SETSIGNEXT(_Rs_);
|
||||
EEINST_SETSIGNEXT(_Rt_);
|
||||
if( _Rd_ ) EEINST_SETSIGNEXT(_Rd_);
|
||||
_deleteEEreg(XMMGPR_LO, 0);
|
||||
_deleteEEreg(XMMGPR_HI, 0);
|
||||
recCall( Interp::MADDU1, _Rd_ );
|
||||
|
||||
if( GPR_IS_CONST2(_Rs_, _Rt_) ) {
|
||||
u64 result = ((u64)g_cpuConstRegs[_Rs_].UL[0] * (u64)g_cpuConstRegs[_Rt_].UL[0]);
|
||||
_deleteEEreg(XMMGPR_LO, 1);
|
||||
_deleteEEreg(XMMGPR_HI, 1);
|
||||
|
||||
// dadd
|
||||
MOV32MtoR( EAX, (int)&cpuRegs.LO.UL[ 2 ] );
|
||||
MOV32MtoR( ECX, (int)&cpuRegs.HI.UL[ 2 ] );
|
||||
ADD32ItoR( EAX, (u32)result&0xffffffff );
|
||||
ADC32ItoR( ECX, (u32)(result>>32) );
|
||||
CDQ();
|
||||
if( _Rd_) {
|
||||
_eeOnWriteReg(_Rd_, 1);
|
||||
_deleteEEreg(_Rd_, 0);
|
||||
MOV32RtoM( (int)&cpuRegs.GPR.r[ _Rd_ ].UL[ 0 ], EAX );
|
||||
MOV32RtoM( (int)&cpuRegs.GPR.r[ _Rd_ ].UL[ 1 ], EDX );
|
||||
}
|
||||
|
||||
MOV32RtoM( (int)&cpuRegs.LO.UL[2], EAX );
|
||||
MOV32RtoM( (int)&cpuRegs.LO.UL[3], EDX );
|
||||
|
||||
MOV32RtoM( (int)&cpuRegs.HI.UL[2], ECX );
|
||||
MOV32RtoR(EAX, ECX);
|
||||
CDQ();
|
||||
MOV32RtoM( (int)&cpuRegs.HI.UL[3], EDX );
|
||||
return;
|
||||
}
|
||||
|
||||
_deleteEEreg(XMMGPR_LO, 1);
|
||||
_deleteEEreg(XMMGPR_HI, 1);
|
||||
_deleteGPRtoXMMreg(_Rs_, 1);
|
||||
_deleteGPRtoXMMreg(_Rt_, 1);
|
||||
_deleteMMXreg(MMX_GPR+_Rs_, 1);
|
||||
_deleteMMXreg(MMX_GPR+_Rt_, 1);
|
||||
|
||||
if( GPR_IS_CONST1(_Rs_) ) {
|
||||
MOV32ItoR( EAX, g_cpuConstRegs[_Rs_].UL[0] );
|
||||
MUL32M( (int)&cpuRegs.GPR.r[ _Rt_ ].UL[ 0 ] );
|
||||
}
|
||||
else if ( GPR_IS_CONST1(_Rt_) ) {
|
||||
MOV32ItoR( EAX, g_cpuConstRegs[_Rt_].UL[0] );
|
||||
MUL32M( (int)&cpuRegs.GPR.r[ _Rs_ ].UL[ 0 ] );
|
||||
}
|
||||
else {
|
||||
MOV32MtoR( EAX, (int)&cpuRegs.GPR.r[ _Rs_ ].UL[ 0 ] );
|
||||
MUL32M( (int)&cpuRegs.GPR.r[ _Rt_ ].UL[ 0 ] );
|
||||
}
|
||||
|
||||
MOV32RtoR( ECX, EDX );
|
||||
ADD32MtoR( EAX, (u32)&cpuRegs.LO.UL[2] );
|
||||
ADC32MtoR( ECX, (u32)&cpuRegs.HI.UL[2] );
|
||||
CDQ();
|
||||
if( _Rd_ ) {
|
||||
_eeOnWriteReg(_Rd_, 1);
|
||||
_deleteEEreg(_Rd_, 0);
|
||||
MOV32RtoM( (int)&cpuRegs.GPR.r[ _Rd_ ].UL[ 0 ], EAX );
|
||||
MOV32RtoM( (int)&cpuRegs.GPR.r[ _Rd_ ].UL[ 1 ], EDX );
|
||||
}
|
||||
|
||||
MOV32RtoM( (int)&cpuRegs.LO.UL[2], EAX );
|
||||
MOV32RtoM( (int)&cpuRegs.LO.UL[3], EDX );
|
||||
|
||||
MOV32RtoM( (int)&cpuRegs.HI.UL[2], ECX );
|
||||
MOV32RtoR(EAX, ECX);
|
||||
CDQ();
|
||||
MOV32RtoM( (int)&cpuRegs.HI.UL[3], EDX );
|
||||
}
|
||||
|
||||
|
||||
#else
|
||||
|
||||
////////////////////////////////////////////////////
|
||||
|
@ -953,4 +1151,4 @@ REC_FUNC_DEL( MADDU1, _Rd_ );
|
|||
|
||||
#endif
|
||||
|
||||
} } }
|
||||
} } }
|
Loading…
Reference in New Issue