Assorted cleanup. A few compilation errors went away, a few useless variables are gone, a few if statements are now case statements. Added comments on a few potential problem areas.

git-svn-id: http://pcsx2.googlecode.com/svn/trunk@904 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
arcum42 2009-04-04 07:48:50 +00:00
parent ebcedccf23
commit 7744205a58
17 changed files with 623 additions and 684 deletions

View File

@ -87,6 +87,7 @@ typedef unsigned int uint;
#define PCSX2_ALIGNED16_EXTERN(x) extern __declspec(align(16)) x #define PCSX2_ALIGNED16_EXTERN(x) extern __declspec(align(16)) x
#define __naked __declspec(naked) #define __naked __declspec(naked)
#define __unused /*unused*/
#define CALLBACK __stdcall #define CALLBACK __stdcall
#else // _MSC_VER #else // _MSC_VER

View File

@ -349,7 +349,7 @@ namespace Exception
StateLoadError_Recoverable( fmt_string( "Unknown or unsupported savestate version: 0x%x", version ) ) StateLoadError_Recoverable( fmt_string( "Unknown or unsupported savestate version: 0x%x", version ) )
{} {}
explicit UnsupportedStateVersion( int version, const std::string& msg ) : explicit UnsupportedStateVersion( __unused int version, const std::string& msg ) :
StateLoadError_Recoverable( msg ) {} StateLoadError_Recoverable( msg ) {}
}; };

View File

@ -1139,7 +1139,7 @@ int __fastcall getBits(u8 *address, u32 size, u32 advance)
{ {
register u32 mask = 0, shift = 0, howmuch; register u32 mask = 0, shift = 0, howmuch;
u8* oldbits, *oldaddr = address; u8* oldbits, *oldaddr = address;
u32 pointer = 0; u32 pointer = 0, temp;
// Check if the current BP has exceeded or reached the limit of 128 // Check if the current BP has exceeded or reached the limit of 128
if (FillInternalBuffer(&g_BP.BP, 1, 8) < 8) return 0; if (FillInternalBuffer(&g_BP.BP, 1, 8) < 8) return 0;
@ -1159,7 +1159,8 @@ int __fastcall getBits(u8 *address, u32 size, u32 advance)
shift = 8; shift = 8;
} }
howmuch = min(min(8 - (pointer & 7), 128 - pointer), min(size, shift)); temp = shift; // Lets not pass a register to min.
howmuch = min(min(8 - (pointer & 7), 128 - pointer), min(size, temp));
if (FillInternalBuffer(&pointer, advance, 8) < 8) if (FillInternalBuffer(&pointer, advance, 8) < 8)
{ {

View File

@ -79,15 +79,15 @@ struct macroblock_rgb16{
}; };
struct decoder_t { struct decoder_t {
/* first, state that carries information from one macroblock to the */ /* first, state that carries information from one macroblock to the */
/* next inside a slice, and is never used outside of mpeg2_slice() */ /* next inside a slice, and is never used outside of mpeg2_slice() */
/* DCT coefficients - should be kept aligned ! */ /* DCT coefficients - should be kept aligned ! */
s16 DCTblock[64]; s16 DCTblock[64];
/* bit parsing stuff */ /* bit parsing stuff */
u32 bitstream_buf; /* current 32 bit working set */ u32 bitstream_buf; /* current 32 bit working set */
int bitstream_bits; /* used bits in working set */ int bitstream_bits; /* used bits in working set */
u8 * bitstream_ptr; /* buffer with stream data; 128 bits buffer */ u8 * bitstream_ptr; /* buffer with stream data; 128 bits buffer */
struct macroblock_8 *mb8; struct macroblock_8 *mb8;
@ -95,42 +95,42 @@ struct decoder_t {
struct macroblock_rgb32 *rgb32; struct macroblock_rgb32 *rgb32;
struct macroblock_rgb16 *rgb16; struct macroblock_rgb16 *rgb16;
int stride; int stride;
/* predictor for DC coefficients in intra blocks */ /* predictor for DC coefficients in intra blocks */
s16 dc_dct_pred[3]; s16 dc_dct_pred[3];
int quantizer_scale; /* remove */ int quantizer_scale; /* remove */
int dmv_offset; /* remove */ int dmv_offset; /* remove */
/* now non-slice-specific information */ /* now non-slice-specific information */
/* sequence header stuff */ /* sequence header stuff */
u8 *intra_quantizer_matrix; u8 *intra_quantizer_matrix;
u8 *non_intra_quantizer_matrix; u8 *non_intra_quantizer_matrix;
/* picture header stuff */ /* picture header stuff */
/* what type of picture this is (I, P, B, D) */ /* what type of picture this is (I, P, B, D) */
int coding_type; int coding_type;
/* picture coding extension stuff */ /* picture coding extension stuff */
/* quantization factor for intra dc coefficients */ /* quantization factor for intra dc coefficients */
int intra_dc_precision; int intra_dc_precision;
/* top/bottom/both fields */ /* top/bottom/both fields */
int picture_structure; int picture_structure;
/* bool to indicate all predictions are frame based */ /* bool to indicate all predictions are frame based */
int frame_pred_frame_dct; int frame_pred_frame_dct;
/* bool to indicate whether intra blocks have motion vectors */ /* bool to indicate whether intra blocks have motion vectors */
/* (for concealment) */ /* (for concealment) */
int concealment_motion_vectors; int concealment_motion_vectors;
/* bit to indicate which quantization table to use */ /* bit to indicate which quantization table to use */
int q_scale_type; int q_scale_type;
/* bool to use different vlc tables */ /* bool to use different vlc tables */
int intra_vlc_format; int intra_vlc_format;
/* used for DMV MC */ /* used for DMV MC */
int top_field_first; int top_field_first;
// Pseudo Sign Offset // Pseudo Sign Offset
int sgn; int sgn;
// Dither Enable // Dither Enable
@ -146,19 +146,18 @@ struct decoder_t {
// Coded block pattern // Coded block pattern
int coded_block_pattern; int coded_block_pattern;
/* stuff derived from bitstream */ /* stuff derived from bitstream */
/* pointer to the zigzag scan we're supposed to be using */ /* pointer to the zigzag scan we're supposed to be using */
const u8 * scan; const u8 * scan;
int second_field;
int second_field; int mpeg1;
int mpeg1;
}; };
extern void (__fastcall *mpeg2_idct_copy) (s16 * block, u8* dest, int stride); extern void (__fastcall *mpeg2_idct_copy) (s16 * block, u8* dest, int stride);
extern void (__fastcall *mpeg2_idct_add) (int last, s16 * block, extern void (__fastcall *mpeg2_idct_add) (int last, s16 * block, s16* dest, int stride);
/*u8*/s16* dest, int stride);
#define IDEC 0 #define IDEC 0
#define BDEC 1 #define BDEC 1
@ -188,11 +187,6 @@ void mpeg2_idct_init ();
#define BigEndian(out, in) out = _byteswap_ulong(in) #define BigEndian(out, in) out = _byteswap_ulong(in)
#else #else
#define BigEndian(out, in) out = __builtin_bswap32(in) // or we could use the asm function bswap... #define BigEndian(out, in) out = __builtin_bswap32(in) // or we could use the asm function bswap...
// No need to reimplement something already in the compiler.
//#define BigEndian(out, in) \
// out = (((((in) >> 24) & 0xFF) << 0) + ((((in) >> 16) & 0xFF) << 8) + \
// ((((in) >> 8) & 0xFF) << 16) + ((((in) >> 0) & 0xFF) << 24));
#endif #endif
#endif//__MPEG_H__ #endif//__MPEG_H__

View File

@ -251,7 +251,5 @@ void OnConf_Cpu(GtkMenuItem *menuitem, gpointer user_data);
void OnConf_Conf(GtkMenuItem *menuitem, gpointer user_data); void OnConf_Conf(GtkMenuItem *menuitem, gpointer user_data);
void SetActiveComboItem(GtkComboBox *widget, char plist[255][255], GList *list, char *conf); void SetActiveComboItem(GtkComboBox *widget, char plist[255][255], GList *list, char *conf);
void SetComboToGList(GtkComboBox *widget, GList *list); void SetComboToGList(GtkComboBox *widget, GList *list);
static void ConfPlugin(PluginConf confs, char* plugin, const char* name);
static void TestPlugin(PluginConf confs, char* plugin, const char* name);
#endif // __CONFIGDLG_H__ #endif // __CONFIGDLG_H__

View File

@ -45,9 +45,6 @@ static const uptr m_pagemask = getpagesize()-1;
// Linux implementation of SIGSEGV handler. Bind it using sigaction(). // Linux implementation of SIGSEGV handler. Bind it using sigaction().
void SysPageFaultExceptionFilter( int signal, siginfo_t *info, void * ) void SysPageFaultExceptionFilter( int signal, siginfo_t *info, void * )
{ {
int err;
//DevCon::Error("SysPageFaultExceptionFilter!");
// get bad virtual address // get bad virtual address
uptr offset = (u8*)info->si_addr - psM; uptr offset = (u8*)info->si_addr - psM;
@ -420,9 +417,6 @@ namespace HostGui
void ResetMenuSlots() void ResetMenuSlots()
{ {
GtkWidget *Item;
char str[g_MaxPath], str2[g_MaxPath];
for (int i = 0; i < 5; i++) for (int i = 0; i < 5; i++)
{ {
Slots[i] = States_isSlotUsed(i); Slots[i] = States_isSlotUsed(i);
@ -450,94 +444,94 @@ namespace HostGui
#define ALT_EVT(evt) ((evt == XK_Alt_L) || (evt == XK_Alt_R)) #define ALT_EVT(evt) ((evt == XK_Alt_L) || (evt == XK_Alt_R))
#define CAPS_LOCK_EVT(evt) (evt == XK_Caps_Lock) #define CAPS_LOCK_EVT(evt) (evt == XK_Caps_Lock)
void __fastcall KeyEvent(keyEvent* ev) void __fastcall KeyEvent(keyEvent* ev)
{ {
struct KeyModifiers *keymod = &keymodifiers; struct KeyModifiers *keymod = &keymodifiers;
if (ev == NULL) return; if (ev == NULL) return;
if (ev->evt == KEYRELEASE) if (GSkeyEvent != NULL) GSkeyEvent(ev);
{
if (SHIFT_EVT(ev->key)) keymod->shift = FALSE;
if (CTRL_EVT(ev->key)) keymod->control = FALSE;
if (ALT_EVT(ev->key)) keymod->alt = FALSE;
if (CAPS_LOCK_EVT(ev->key)) keymod->capslock = FALSE;
GSkeyEvent(ev);
return;
}
if (ev->evt == KEYPRESS) if (ev->evt == KEYPRESS)
{ {
if (SHIFT_EVT(ev->key)) keymod->shift = TRUE; if (SHIFT_EVT(ev->key)) keymod->shift = TRUE;
if (CTRL_EVT(ev->key)) keymod->control = TRUE; if (CTRL_EVT(ev->key)) keymod->control = TRUE;
if (ALT_EVT(ev->key)) keymod->alt = TRUE; if (ALT_EVT(ev->key)) keymod->alt = TRUE;
if (CAPS_LOCK_EVT(ev->key)) keymod->capslock = TRUE; if (CAPS_LOCK_EVT(ev->key)) keymod->capslock = TRUE;
switch (ev->key) switch (ev->key)
{ {
case XK_F1: case XK_F1:
case XK_F2: case XK_F2:
case XK_F3: case XK_F3:
case XK_F4: case XK_F4:
case XK_F5: case XK_F5:
case XK_F6: case XK_F6:
case XK_F7: case XK_F7:
case XK_F8: case XK_F8:
case XK_F9: case XK_F9:
case XK_F10: case XK_F10:
case XK_F11: case XK_F11:
case XK_F12: case XK_F12:
try try
{ {
ProcessFKeys(ev->key - XK_F1 + 1, keymod); ProcessFKeys(ev->key - XK_F1 + 1, keymod);
} }
catch (Exception::CpuStateShutdown&) catch (Exception::CpuStateShutdown&)
{ {
// Woops! Something was unrecoverable. Bummer. // Woops! Something was unrecoverable. Bummer.
// Let's give the user a RunGui! // Let's give the user a RunGui!
g_EmulationInProgress = false; g_EmulationInProgress = false;
SysEndExecution(); SysEndExecution();
} }
break; break;
case XK_Tab: case XK_Tab:
CycleFrameLimit(0); CycleFrameLimit(0);
break; break;
case XK_Escape: case XK_Escape:
signal(SIGINT, SIG_DFL); signal(SIGINT, SIG_DFL);
signal(SIGPIPE, SIG_DFL); signal(SIGPIPE, SIG_DFL);
#ifdef PCSX2_DEVBUILD #ifdef PCSX2_DEVBUILD
if (g_SaveGSStream >= 3) if (g_SaveGSStream >= 3)
{ {
g_SaveGSStream = 4;// gs state g_SaveGSStream = 4;// gs state
break; break;
} }
#endif #endif
SysEndExecution(); SysEndExecution();
if (g_Startup.NoGui) exit(0); if (g_Startup.NoGui) exit(0);
// fixme: The GUI is now capable of receiving control back from the // fixme: The GUI is now capable of receiving control back from the
// emulator. Which means that when we call SysEscapeExecute() here, the // emulator. Which means that when we call SysEscapeExecute() here, the
// emulation loop in ExecuteCpu() will exit. You should be able to set it // emulation loop in ExecuteCpu() will exit. You should be able to set it
// up so that it returns control to the existing GTK event loop, instead of // up so that it returns control to the existing GTK event loop, instead of
// always starting a new one via RunGui(). (but could take some trial and // always starting a new one via RunGui(). (but could take some trial and
// error) -- (air) // error) -- (air)
// Easier said then done; running gtk in two threads at the same time can't be
// done, and working around that is pretty fiddly.
RunGui();
break;
// Easier said then done; running gtk in two threads at the same time can't be default:
// done, and working around that is pretty fiddly. GSkeyEvent(ev);
RunGui(); break;
break; }
}
else if (ev->evt == KEYRELEASE)
{
if (SHIFT_EVT(ev->key)) keymod->shift = FALSE;
if (CTRL_EVT(ev->key)) keymod->control = FALSE;
if (ALT_EVT(ev->key)) keymod->alt = FALSE;
if (CAPS_LOCK_EVT(ev->key)) keymod->capslock = FALSE;
}
default: return;
GSkeyEvent(ev); }
break;
}
}
return;
}
} }

View File

@ -58,7 +58,7 @@ extern u8 *psS; //0.015 mb, scratch pad
extern u8 g_RealGSMem[Ps2MemSize::GSregs]; extern u8 g_RealGSMem[Ps2MemSize::GSregs];
#define PS2MEM_GS g_RealGSMem #define PS2MEM_GS g_RealGSMem
#define PSM(mem) (vtlb_GetPhyPtr(mem&0x1fffffff)) //pcsx2 is a competition.The one with most hacks wins :D #define PSM(mem) (vtlb_GetPhyPtr((mem)&0x1fffffff)) //pcsx2 is a competition.The one with most hacks wins :D
#define psMs8(mem) (*(s8 *)&PS2MEM_BASE[(mem) & 0x1ffffff]) #define psMs8(mem) (*(s8 *)&PS2MEM_BASE[(mem) & 0x1ffffff])
#define psMs16(mem) (*(s16*)&PS2MEM_BASE[(mem) & 0x1ffffff]) #define psMs16(mem) (*(s16*)&PS2MEM_BASE[(mem) & 0x1ffffff])

View File

@ -420,7 +420,7 @@ char *ParseLang(char *id) {
char* mystrlwr( char* string ) char* mystrlwr( char* string )
{ {
assert( string != NULL ); assert( string != NULL );
while ( 0 != ( *string++ = (char)tolower( *string ) ) ); while ( 0 != ( *string++ = (char)tolower( *string ) ) ) ;
return string; return string;
} }
@ -493,102 +493,99 @@ void CycleFrameLimit(int dir)
void ProcessFKeys(int fkey, struct KeyModifiers *keymod) void ProcessFKeys(int fkey, struct KeyModifiers *keymod)
{ {
assert(fkey >= 1 && fkey <= 12 ); assert(fkey >= 1 && fkey <= 12 );
switch(fkey) switch(fkey) {
{ case 1:
case 1: try
try {
{ gzSavingState( SaveState::GetFilename( StatesC ) ).FreezeAll();
gzSavingState( SaveState::GetFilename( StatesC ) ).FreezeAll(); HostGui::ResetMenuSlots();
HostGui::ResetMenuSlots(); }
} catch( Exception::BaseException& ex )
catch( Exception::BaseException& ex ) {
{ // 99% of the time this is a file permission error and the
// 99% of the time this is a file permission error and the // cpu state is intact so just display a passive msg to console.
// cpu state is intact so just display a passive msg to console.
Console::Error( _( "Error > Could not save state to slot %d" ), params StatesC ); Console::Error( _( "Error > Could not save state to slot %d" ), params StatesC );
Console::Error( ex.cMessage() ); Console::Error( ex.cMessage() );
} }
break; break;
case 2: case 2:
if( keymod->shift ) if( keymod->shift )
StatesC = (StatesC+NUM_STATES-1) % NUM_STATES; StatesC = (StatesC+NUM_STATES-1) % NUM_STATES;
else else
StatesC = (StatesC+1) % NUM_STATES; StatesC = (StatesC+1) % NUM_STATES;
Console::Notice( _( " > Selected savestate slot %d" ), params StatesC); Console::Notice( _( " > Selected savestate slot %d" ), params StatesC);
if( GSchangeSaveState != NULL ) if( GSchangeSaveState != NULL )
GSchangeSaveState(StatesC, SaveState::GetFilename(StatesC).c_str()); GSchangeSaveState(StatesC, SaveState::GetFilename(StatesC).c_str());
break; break;
case 3: case 3:
try try
{ {
gzLoadingState joe( SaveState::GetFilename( StatesC ) ); // throws exception on version mismatch gzLoadingState joe( SaveState::GetFilename( StatesC ) ); // throws exception on version mismatch
cpuReset(); cpuReset();
SysClearExecutionCache(); SysClearExecutionCache();
joe.FreezeAll(); joe.FreezeAll();
} }
catch( Exception::StateLoadError_Recoverable& ) catch( Exception::StateLoadError_Recoverable& )
{ {
// At this point the cpu hasn't been reset, so we can return // At this point the cpu hasn't been reset, so we can return
// control to the user safely... (and silently) // control to the user safely... (and silently)
} }
catch( Exception::FileNotFound& ) catch( Exception::FileNotFound& )
{ {
Console::Notice( _("Saveslot %d cannot be loaded; slot does not exist (file not found)"), params StatesC ); Console::Notice( _("Saveslot %d cannot be loaded; slot does not exist (file not found)"), params StatesC );
} }
catch( Exception::RuntimeError& ex ) catch( Exception::RuntimeError& ex )
{ {
// This is the bad one. Chances are the cpu has been reset, so emulation has // This is the bad one. Chances are the cpu has been reset, so emulation has
// to be aborted. Sorry user! We'll give you some info for your trouble: // to be aborted. Sorry user! We'll give you some info for your trouble:
Console::Error( _("An error occured while trying to load saveslot %d"), params StatesC ); Console::Error( _("An error occured while trying to load saveslot %d"), params StatesC );
Console::Error( ex.cMessage() ); Console::Error( ex.cMessage() );
Msgbox::Alert( Msgbox::Alert(
"Pcsx2 encountered an error while trying to load the savestate\n" "Pcsx2 encountered an error while trying to load the savestate\n"
"and emulation had to be aborted." ); "and emulation had to be aborted." );
ClosePlugins( true ); ClosePlugins( true );
throw Exception::CpuStateShutdown( throw Exception::CpuStateShutdown(
"Saveslot load failed; PS2 emulated state had to be shut down." ); // let the GUI handle the error "gracefully" "Saveslot load failed; PS2 emulated state had to be shut down." ); // let the GUI handle the error "gracefully"
} }
break; break;
case 4: case 4:
CycleFrameLimit(keymod->shift ? -1 : 1); CycleFrameLimit(keymod->shift ? -1 : 1);
break; break;
// note: VK_F5-VK_F7 are reserved for GS // note: VK_F5-VK_F7 are reserved for GS
case 8: case 8:
GSmakeSnapshot( SNAPSHOTS_DIR "/" ); GSmakeSnapshot( SNAPSHOTS_DIR "/" );
break; break;
case 9: //gsdx "on the fly" renderer switching case 9: //gsdx "on the fly" renderer switching
if (!renderswitch) if (!renderswitch) {
{ StateRecovery::MakeGsOnly();
StateRecovery::MakeGsOnly(); g_EmulationInProgress = false;
g_EmulationInProgress = false; CloseGS();
CloseGS(); renderswitch = true; //go to dx9 sw
renderswitch = true; //go to dx9 sw StateRecovery::Recover();
StateRecovery::Recover(); HostGui::BeginExecution(); //also sets g_EmulationInProgress to true later
HostGui::BeginExecution(); //also sets g_EmulationInProgress to true later }
} else {
else StateRecovery::MakeGsOnly();
{ g_EmulationInProgress = false;
StateRecovery::MakeGsOnly(); CloseGS();
g_EmulationInProgress = false; renderswitch = false; //return to default renderer
CloseGS(); StateRecovery::Recover();
renderswitch = false; //return to default renderer HostGui::BeginExecution(); //also sets g_EmulationInProgress to true later
StateRecovery::Recover(); }
HostGui::BeginExecution(); //also sets g_EmulationInProgress to true later break;
}
break;
#ifdef PCSX2_DEVBUILD #ifdef PCSX2_DEVBUILD
case 10: case 10:
// There's likely a better way to implement this, but this seemed useful. // There's likely a better way to implement this, but this seemed useful.
@ -602,60 +599,55 @@ void ProcessFKeys(int fkey, struct KeyModifiers *keymod)
GSprintf(10,"Logging Disabled."); GSprintf(10,"Logging Disabled.");
break; break;
case 11:
if( mtgsThread != NULL ) case 11:
{ if( mtgsThread != NULL ) {
Console::Notice( "Cannot make gsstates in MTGS mode" ); Console::Notice( "Cannot make gsstates in MTGS mode" );
} }
else else
{ {
string Text; string Text;
if( strgametitle[0] != 0 ) if( strgametitle[0] != 0 ) {
{ // only take the first two words
// only take the first two words char name[256], *tok;
char name[256], *tok; string gsText;
string gsText;
tok = strtok(strgametitle, " "); tok = strtok(strgametitle, " ");
sprintf(name, "%s_", mystrlwr(tok)); sprintf(name, "%s_", mystrlwr(tok));
tok = strtok(NULL, " ");
tok = strtok(NULL, " "); if( tok != NULL ) strcat(name, tok);
if( tok != NULL ) strcat(name, tok);
ssprintf( gsText, "%s.%d.gs", name, StatesC);
Text = Path::Combine( SSTATES_DIR, gsText ); ssprintf( gsText, "%s.%d.gs", name, StatesC);
} Text = Path::Combine( SSTATES_DIR, gsText );
else }
{ else
Text = GetGSStateFilename(); Text = GetGSStateFilename();
}
SaveGSState(Text);
SaveGSState(Text); }
} break;
break;
#endif #endif
case 12: case 12:
if( keymod->shift ) if( keymod->shift ) {
{
#ifdef PCSX2_DEVBUILD #ifdef PCSX2_DEVBUILD
iDumpRegisters(cpuRegs.pc, 0); iDumpRegisters(cpuRegs.pc, 0);
Console::Notice("hardware registers dumped EE:%x, IOP:%x\n", params cpuRegs.pc, psxRegs.pc); Console::Notice("hardware registers dumped EE:%x, IOP:%x\n", params cpuRegs.pc, psxRegs.pc);
#endif #endif
} }
else else {
{ g_Pcsx2Recording ^= 1;
g_Pcsx2Recording ^= 1; if( mtgsThread != NULL ) {
mtgsThread->SendSimplePacket(GS_RINGTYPE_RECORD, g_Pcsx2Recording, 0, 0);
if( mtgsThread != NULL ) }
mtgsThread->SendSimplePacket(GS_RINGTYPE_RECORD, g_Pcsx2Recording, 0, 0); else {
else if( GSsetupRecording != NULL ) if( GSsetupRecording != NULL ) GSsetupRecording(g_Pcsx2Recording, NULL);
GSsetupRecording(g_Pcsx2Recording, NULL); }
if( SPU2setupRecording != NULL ) SPU2setupRecording(g_Pcsx2Recording, NULL);
if( SPU2setupRecording != NULL ) SPU2setupRecording(g_Pcsx2Recording, NULL); }
} break;
break; }
}
} }
void _memset16_unaligned( void* dest, u16 data, size_t size ) void _memset16_unaligned( void* dest, u16 data, size_t size )

View File

@ -609,9 +609,10 @@ void inifile_read( const char * name )
char* pend = buffer+strlen(buffer); char* pend = buffer+strlen(buffer);
while(pstart != pend ) while(pstart != pend )
{ {
// stop at the first . since we only want to update the hex // stop at the first . since we only want to update the hex
if( *pstart == '.' ) break; if( *pstart == '.' ) break;
*pstart++ = toupper(*pstart); *pstart = toupper(*pstart);
*pstart++;
} }
f1 = fopen(buffer, "rt"); f1 = fopen(buffer, "rt");

View File

@ -1309,25 +1309,27 @@ void _vuMINIw(VURegs * VU) {
} }
void _vuOPMULA(VURegs * VU) { void _vuOPMULA(VURegs * VU) {
VU->ACC.i.x = VU_MACx_UPDATE(VU, vuDouble(VU->VF[_Fs_].i.y) * vuDouble(VU->VF[_Ft_].i.z)); VU->ACC.i.x = VU_MACx_UPDATE(VU, vuDouble(VU->VF[_Fs_].i.y) * vuDouble(VU->VF[_Ft_].i.z));
VU->ACC.i.y = VU_MACy_UPDATE(VU, vuDouble(VU->VF[_Fs_].i.z) * vuDouble(VU->VF[_Ft_].i.x)); VU->ACC.i.y = VU_MACy_UPDATE(VU, vuDouble(VU->VF[_Fs_].i.z) * vuDouble(VU->VF[_Ft_].i.x));
VU->ACC.i.z = VU_MACz_UPDATE(VU, vuDouble(VU->VF[_Fs_].i.x) * vuDouble(VU->VF[_Ft_].i.y)); VU->ACC.i.z = VU_MACz_UPDATE(VU, vuDouble(VU->VF[_Fs_].i.x) * vuDouble(VU->VF[_Ft_].i.y));
VU_STAT_UPDATE(VU); VU_STAT_UPDATE(VU);
}/*last updated 8/05/03 shadow*/ }/*last updated 8/05/03 shadow*/
void _vuOPMSUB(VURegs * VU) { void _vuOPMSUB(VURegs * VU) {
VECTOR * dst; VECTOR * dst;
float ftx, fty, ftz; float ftx, fty, ftz;
float fsx, fsy, fsz; float fsx, fsy, fsz;
if (_Fd_ == 0) dst = &RDzero; if (_Fd_ == 0)
else dst = &VU->VF[_Fd_]; dst = &RDzero;
else
dst = &VU->VF[_Fd_];
ftx = vuDouble(VU->VF[_Ft_].i.x); fty = vuDouble(VU->VF[_Ft_].i.y); ftz = vuDouble(VU->VF[_Ft_].i.z); ftx = vuDouble(VU->VF[_Ft_].i.x); fty = vuDouble(VU->VF[_Ft_].i.y); ftz = vuDouble(VU->VF[_Ft_].i.z);
fsx = vuDouble(VU->VF[_Fs_].i.x); fsy = vuDouble(VU->VF[_Fs_].i.y); fsz = vuDouble(VU->VF[_Fs_].i.z); fsx = vuDouble(VU->VF[_Fs_].i.x); fsy = vuDouble(VU->VF[_Fs_].i.y); fsz = vuDouble(VU->VF[_Fs_].i.z);
dst->i.x = VU_MACx_UPDATE(VU, vuDouble(VU->ACC.i.x) - fsy * ftz); dst->i.x = VU_MACx_UPDATE(VU, vuDouble(VU->ACC.i.x) - fsy * ftz);
dst->i.y = VU_MACy_UPDATE(VU, vuDouble(VU->ACC.i.y) - fsz * ftx); dst->i.y = VU_MACy_UPDATE(VU, vuDouble(VU->ACC.i.y) - fsz * ftx);
dst->i.z = VU_MACz_UPDATE(VU, vuDouble(VU->ACC.i.z) - fsx * fty); dst->i.z = VU_MACz_UPDATE(VU, vuDouble(VU->ACC.i.z) - fsx * fty);
VU_STAT_UPDATE(VU); VU_STAT_UPDATE(VU);
}/*last updated 8/05/03 shadow*/ }/*last updated 8/05/03 shadow*/
void _vuNOP(VURegs * VU) { void _vuNOP(VURegs * VU) {
@ -1410,7 +1412,7 @@ void _vuCLIP(VURegs * VU) {
float value = fabs(vuDouble(VU->VF[_Ft_].i.w)); float value = fabs(vuDouble(VU->VF[_Ft_].i.w));
VU->clipflag <<= 6; VU->clipflag <<= 6;
if ( vuDouble(VU->VF[_Fs_].i.x) > +value ) VU->clipflag|= 0x01; if ( vuDouble(VU->VF[_Fs_].i.x) > +value ) VU->clipflag|= 0x01;
if ( vuDouble(VU->VF[_Fs_].i.x) < -value ) VU->clipflag|= 0x02; if ( vuDouble(VU->VF[_Fs_].i.x) < -value ) VU->clipflag|= 0x02;
if ( vuDouble(VU->VF[_Fs_].i.y) > +value ) VU->clipflag|= 0x04; if ( vuDouble(VU->VF[_Fs_].i.y) > +value ) VU->clipflag|= 0x04;
if ( vuDouble(VU->VF[_Fs_].i.y) < -value ) VU->clipflag|= 0x08; if ( vuDouble(VU->VF[_Fs_].i.y) < -value ) VU->clipflag|= 0x08;
@ -1431,10 +1433,9 @@ void _vuDIV(VURegs * VU) {
float ft = vuDouble(VU->VF[_Ft_].UL[_Ftf_]); float ft = vuDouble(VU->VF[_Ft_].UL[_Ftf_]);
float fs = vuDouble(VU->VF[_Fs_].UL[_Fsf_]); float fs = vuDouble(VU->VF[_Fs_].UL[_Fsf_]);
// _vuFMACTestStall(VU, _Fs_); _vuFMACTestStall(VU, _Ft_);
VU->statusflag = (VU->statusflag&0xfcf)|((VU->statusflag&0x30)<<6); VU->statusflag = (VU->statusflag&0xfcf)|((VU->statusflag&0x30)<<6);
if (ft == 0.0) { if (ft == 0.0) {
if (fs == 0.0) { if (fs == 0.0) {
VU->statusflag |= 0x10; VU->statusflag |= 0x10;
} else { } else {
@ -1455,16 +1456,13 @@ void _vuDIV(VURegs * VU) {
void _vuSQRT(VURegs * VU) { void _vuSQRT(VURegs * VU) {
float ft = vuDouble(VU->VF[_Ft_].UL[_Ftf_]); float ft = vuDouble(VU->VF[_Ft_].UL[_Ftf_]);
// _vuFMACTestStall(VU, _Ft_);
VU->statusflag = (VU->statusflag&0xfcf)|((VU->statusflag&0x30)<<6); VU->statusflag = (VU->statusflag&0xfcf)|((VU->statusflag&0x30)<<6);
if (ft < 0.0 ) if (ft < 0.0 ) VU->statusflag |= 0x10;
VU->statusflag |= 0x10;
VU->q.F = sqrt(fabs(ft)); VU->q.F = sqrt(fabs(ft));
VU->q.F = vuDouble(VU->q.UL); VU->q.F = vuDouble(VU->q.UL);
} //last update 15/01/06 zerofrog } //last update 15/01/06 zerofrog
/* Eminent Bug - Dvisior == 0 Check Missing ( D Flag Not Set ) */ /* Eminent Bug - Dvisior == 0 Check Missing ( D Flag Not Set ) */
/* REFIXED....ASADR; rerefixed....zerofrog */ /* REFIXED....ASADR; rerefixed....zerofrog */
void _vuRSQRT(VURegs * VU) { void _vuRSQRT(VURegs * VU) {
@ -1472,7 +1470,6 @@ void _vuRSQRT(VURegs * VU) {
float fs = vuDouble(VU->VF[_Fs_].UL[_Fsf_]); float fs = vuDouble(VU->VF[_Fs_].UL[_Fsf_]);
float temp; float temp;
// _vuFMACTestStall(VU, _Fs_); _vuFMACTestStall(VU, _Ft_);
VU->statusflag = (VU->statusflag&0xfcf)|((VU->statusflag&0x30)<<6); VU->statusflag = (VU->statusflag&0xfcf)|((VU->statusflag&0x30)<<6);
if ( ft == 0.0 ) { if ( ft == 0.0 ) {
@ -1508,7 +1505,6 @@ void _vuRSQRT(VURegs * VU) {
} }
} //last update 15/01/06 zerofrog } //last update 15/01/06 zerofrog
void _vuIADDI(VURegs * VU) { void _vuIADDI(VURegs * VU) {
s16 imm = ((VU->code >> 6) & 0x1f); s16 imm = ((VU->code >> 6) & 0x1f);
imm = ((imm & 0x10 ? 0xfff0 : 0) | (imm & 0xf)); imm = ((imm & 0x10 ? 0xfff0 : 0) | (imm & 0xf));
@ -1567,7 +1563,7 @@ void _vuMFIR(VURegs * VU) {
// Big bug!!! mov from fs to ft not ft to fs. asadr // Big bug!!! mov from fs to ft not ft to fs. asadr
void _vuMTIR(VURegs * VU) { void _vuMTIR(VURegs * VU) {
if(_Ft_ == 0) return; if(_Ft_ == 0) return;
VU->VI[_Ft_].US[0] = *(u16*)&VU->VF[_Fs_].F[_Fsf_]; VU->VI[_Ft_].US[0] = *(u16*)&VU->VF[_Fs_].F[_Fsf_];
} }
void _vuMR32(VURegs * VU) { void _vuMR32(VURegs * VU) {
@ -1624,8 +1620,8 @@ void _vuLQI(VURegs * VU) {
if (_Y) VU->VF[_Ft_].UL[1] = ptr[1]; if (_Y) VU->VF[_Ft_].UL[1] = ptr[1];
if (_Z) VU->VF[_Ft_].UL[2] = ptr[2]; if (_Z) VU->VF[_Ft_].UL[2] = ptr[2];
if (_W) VU->VF[_Ft_].UL[3] = ptr[3]; if (_W) VU->VF[_Ft_].UL[3] = ptr[3];
} }
if (_Fs_ != 0) VU->VI[_Fs_].US[0]++; if (_Fs_ != 0) VU->VI[_Fs_].US[0]++;
} }
/* addr is now signed. Asadr */ /* addr is now signed. Asadr */
@ -1735,7 +1731,6 @@ As an example for setting the polynomial variable correctly, the 23-bit M-series
would be specified as (1 << 14). would be specified as (1 << 14).
*/ */
//The two-tap 23 stage M-series polynomials are x23+x18 and x23+x14 ((1 << 18) and (1 << 14), respectively). //The two-tap 23 stage M-series polynomials are x23+x18 and x23+x14 ((1 << 18) and (1 << 14), respectively).
//The reverse sequences can be generated by x23+x(23-18) and x23+x(23-14) ((1 << 9) and (1 << 5), respectively) //The reverse sequences can be generated by x23+x(23-18) and x23+x(23-14) ((1 << 9) and (1 << 5), respectively)
u32 poly = 1 << 5; u32 poly = 1 << 5;
@ -1745,23 +1740,13 @@ void SetPoly(u32 newPoly) {
} }
void AdvanceLFSR(VURegs * VU) { void AdvanceLFSR(VURegs * VU) {
// code from www.project-fao.org // code from www.project-fao.org (which is no longer there)
int x = (VU->VI[REG_R].UL >> 4) & 1; int x = (VU->VI[REG_R].UL >> 4) & 1;
int y = (VU->VI[REG_R].UL >> 22) & 1; int y = (VU->VI[REG_R].UL >> 22) & 1;
VU->VI[REG_R].UL <<= 1; VU->VI[REG_R].UL <<= 1;
VU->VI[REG_R].UL ^= x ^ y; VU->VI[REG_R].UL ^= x ^ y;
VU->VI[REG_R].UL = (VU->VI[REG_R].UL&0x7fffff)|0x3f800000; VU->VI[REG_R].UL = (VU->VI[REG_R].UL&0x7fffff)|0x3f800000;
} }
// old
// u32 lfsr = VU->VI[REG_R].UL & 0x007FFFFF;
// u32 oldlfsr = lfsr;
// lfsr <<= 1;
// if (oldlfsr & 0x00400000) {
// lfsr ^= poly;
// lfsr |= 1;
// }
//
// VU->VI[REG_R].UL = 0x3F800000 | (lfsr & 0x007FFFFF);
void _vuRINIT(VURegs * VU) { void _vuRINIT(VURegs * VU) {
VU->VI[REG_R].UL = 0x3F800000 | (VU->VF[_Fs_].UL[_Fsf_] & 0x007FFFFF); VU->VI[REG_R].UL = 0x3F800000 | (VU->VF[_Fs_].UL[_Fsf_] & 0x007FFFFF);
@ -1864,7 +1849,6 @@ void _vuFCGET(VURegs * VU) {
s32 _branchAddr(VURegs * VU) { s32 _branchAddr(VURegs * VU) {
s32 bpc = VU->VI[REG_TPC].SL + ( _Imm11_ * 8 ); s32 bpc = VU->VI[REG_TPC].SL + ( _Imm11_ * 8 );
//if (bpc < 0) bpc = VU->VI[REG_TPC].SL + _UImm11_ * 8;
bpc&= (VU == &VU1) ? 0x3fff : 0x0fff; bpc&= (VU == &VU1) ? 0x3fff : 0x0fff;
return bpc; return bpc;
} }
@ -1872,8 +1856,6 @@ s32 _branchAddr(VURegs * VU) {
void _setBranch(VURegs * VU, u32 bpc) { void _setBranch(VURegs * VU, u32 bpc) {
VU->branch = 2; VU->branch = 2;
VU->branchpc = bpc; VU->branchpc = bpc;
// VU->vuExec(VU);
// VU->VI[REG_TPC].UL = bpc;
} }
void _vuIBEQ(VURegs * VU) { void _vuIBEQ(VURegs * VU) {
@ -1926,9 +1908,7 @@ void _vuB(VURegs * VU) {
void _vuBAL(VURegs * VU) { void _vuBAL(VURegs * VU) {
s32 bpc = _branchAddr(VU); s32 bpc = _branchAddr(VU);
if (_Ft_) { if (_Ft_) VU->VI[_Ft_].US[0] = (VU->VI[REG_TPC].UL + 8)/8;
VU->VI[_Ft_].US[0] = (VU->VI[REG_TPC].UL + 8)/8;
}
_setBranch(VU, bpc); _setBranch(VU, bpc);
} }
@ -1940,9 +1920,7 @@ void _vuJR(VURegs * VU) {
void _vuJALR(VURegs * VU) { void _vuJALR(VURegs * VU) {
u32 bpc = VU->VI[_Fs_].US[0] * 8; u32 bpc = VU->VI[_Fs_].US[0] * 8;
if (_Ft_) { if (_Ft_) VU->VI[_Ft_].US[0] = (VU->VI[REG_TPC].UL + 8)/8;
VU->VI[_Ft_].US[0] = (VU->VI[REG_TPC].UL + 8)/8;
}
_setBranch(VU, bpc); _setBranch(VU, bpc);
} }
@ -2249,8 +2227,6 @@ void _vuRegs##OP(VURegs * VU, _VURegsNum *VUregsn) { \
VUregsn->cycles = _cycles; \ VUregsn->cycles = _cycles; \
} }
VUREGS_FTFS(ABS); VUREGS_FTFS(ABS);
VUREGS_FDFSFT(ADD, 0); VUREGS_FDFSFT(ADD, 0);

View File

@ -35,7 +35,6 @@ PCSX2_ALIGNED16(u32 g_vifCol0[4]);
PCSX2_ALIGNED16(u32 g_vifRow1[4]); PCSX2_ALIGNED16(u32 g_vifRow1[4]);
PCSX2_ALIGNED16(u32 g_vifCol1[4]); PCSX2_ALIGNED16(u32 g_vifCol1[4]);
//static int cycles;
extern int g_vifCycles; extern int g_vifCycles;
u16 vifqwc = 0; u16 vifqwc = 0;
bool mfifodmairq = FALSE; bool mfifodmairq = FALSE;
@ -683,8 +682,11 @@ void mfifoVIF1transfer(int qwc)
if (vif1ch->chcr & 0x40) if (vif1ch->chcr & 0x40)
{ {
if (vif1.stallontag == 1) ret = VIF1transfer(ptag + (2 + vif1.irqoffset), 2 - vif1.irqoffset, 1); //Transfer Tag on Stall if (vif1.stallontag == 1)
else ret = VIF1transfer(ptag + 2, 2, 1); //Transfer Tag ret = VIF1transfer(ptag + (2 + vif1.irqoffset), 2 - vif1.irqoffset, 1); //Transfer Tag on Stall
else
ret = VIF1transfer(ptag + 2, 2, 1); //Transfer Tag
if (ret == -2) if (ret == -2)
{ {
VIF_LOG("MFIFO Stallon tag"); VIF_LOG("MFIFO Stallon tag");
@ -696,7 +698,6 @@ void mfifoVIF1transfer(int qwc)
id = (ptag[0] >> 28) & 0x7; id = (ptag[0] >> 28) & 0x7;
vif1ch->qwc = (ptag[0] & 0xffff); vif1ch->qwc = (ptag[0] & 0xffff);
vif1ch->madr = ptag[1]; vif1ch->madr = ptag[1];
//cycles += 2;
vif1ch->chcr = (vif1ch->chcr & 0xFFFF) | ((*ptag) & 0xFFFF0000); vif1ch->chcr = (vif1ch->chcr & 0xFFFF) | ((*ptag) & 0xFFFF0000);

View File

@ -22,7 +22,6 @@
#include "Vif.h" #include "Vif.h"
#include "VUmicro.h" #include "VUmicro.h"
#include "GS.h" #include "GS.h"
#include "VifDma.h" #include "VifDma.h"
#include <xmmintrin.h> #include <xmmintrin.h>
@ -65,6 +64,7 @@ static const unsigned int VIF1dmanum = 1;
int g_vifCycles = 0; int g_vifCycles = 0;
bool path3hack = FALSE; bool path3hack = FALSE;
bool Path3transfer = FALSE;
typedef void (__fastcall *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); typedef int (*UNPACKPARTFUNCTYPESSE)(u32 *dest, u32 *data, int size);
@ -73,6 +73,9 @@ extern void (*Vif0CMDTLB[75])();
extern int (__fastcall *Vif1TransTLB[128])(u32 *data); extern int (__fastcall *Vif1TransTLB[128])(u32 *data);
extern int (__fastcall *Vif0TransTLB[128])(u32 *data); extern int (__fastcall *Vif0TransTLB[128])(u32 *data);
u32 *vif0ptag, *vif1ptag;
u8 s_maskwrite[256];
struct VIFUnpackFuncTable struct VIFUnpackFuncTable
{ {
UNPACKFUNCTYPE funcU; UNPACKFUNCTYPE funcU;
@ -334,7 +337,7 @@ static void ProcessMemSkip(int size, unsigned int unpackType, const unsigned int
static void VIFunpack(u32 *data, vifCode *v, int size, const unsigned int VIFdmanum) static void VIFunpack(u32 *data, vifCode *v, int size, const unsigned int VIFdmanum)
{ {
u32 *dest; u32 *dest;
unsigned int unpackType; u32 unpackType;
UNPACKFUNCTYPE func; UNPACKFUNCTYPE func;
const VIFUnpackFuncTable *ft; const VIFUnpackFuncTable *ft;
vifStruct *vif; vifStruct *vif;
@ -381,6 +384,7 @@ static void VIFunpack(u32 *data, vifCode *v, int size, const unsigned int VIFdma
{ {
VIF_LOG("*PCSX2*: warning v->size != size"); VIF_LOG("*PCSX2*: warning v->size != size");
} }
if ((v->addr + size*4) > memsize) if ((v->addr + size*4) > memsize)
{ {
Console::Notice("*PCSX2*: fixme unpack overflow"); Console::Notice("*PCSX2*: fixme unpack overflow");
@ -416,7 +420,7 @@ static void VIFunpack(u32 *data, vifCode *v, int size, const unsigned int VIFdma
{ {
int destinc, unpacksize; int destinc, unpacksize;
VIFUNPACK_LOG("aligning packet size = %d offset %d addr %x", size, vifRegs->offset, vif->tag.addr); VIFUNPACK_LOG("Aligning packet size = %d offset %d addr %x", size, vifRegs->offset, vif->tag.addr);
// SSE doesn't handle such small data // SSE doesn't handle such small data
if (v->size != (size >> 2)) if (v->size != (size >> 2))
@ -426,7 +430,7 @@ static void VIFunpack(u32 *data, vifCode *v, int size, const unsigned int VIFdma
{ {
if (((u32)size / (u32)ft->dsize) < ((u32)ft->qsize - vifRegs->offset)) if (((u32)size / (u32)ft->dsize) < ((u32)ft->qsize - vifRegs->offset))
{ {
Console::WriteLn("wasnt enough left size/dsize = %x left to write %x", params(size / ft->dsize), (ft->qsize - vifRegs->offset)); Console::WriteLn("Wasn't enough left size/dsize = %x left to write %x", params(size / ft->dsize), (ft->qsize - vifRegs->offset));
} }
unpacksize = min(((u32)size / (u32)ft->dsize), ((u32)ft->qsize - vifRegs->offset)); unpacksize = min(((u32)size / (u32)ft->dsize), ((u32)ft->qsize - vifRegs->offset));
} }
@ -455,7 +459,7 @@ static void VIFunpack(u32 *data, vifCode *v, int size, const unsigned int VIFdma
{ {
dest += destinc; dest += destinc;
} }
VIFUNPACK_LOG("aligning packet done size = %d offset %d addr %x", size, vifRegs->offset, vif->tag.addr); VIFUNPACK_LOG("Aligning packet done size = %d offset %d addr %x", size, vifRegs->offset, vif->tag.addr);
} }
else if (v->size != (size >> 2)) else if (v->size != (size >> 2))
@ -475,7 +479,8 @@ static void VIFunpack(u32 *data, vifCode *v, int size, const unsigned int VIFdma
// continuation from last stream // continuation from last stream
incdest = ((vifRegs->cycle.cl - vifRegs->cycle.wl) << 2) + 4; incdest = ((vifRegs->cycle.cl - vifRegs->cycle.wl) << 2) + 4;
while (size >= ft->gsize && vifRegs->num > 0)
while ((size >= ft->gsize) && (vifRegs->num > 0))
{ {
func(dest, (u32*)cdata, ft->qsize); func(dest, (u32*)cdata, ft->qsize);
cdata += ft->gsize; cdata += ft->gsize;
@ -501,7 +506,7 @@ static void VIFunpack(u32 *data, vifCode *v, int size, const unsigned int VIFdma
} }
if (size >= ft->gsize && !(v->addr&0xf)) if ((size >= ft->gsize) && !(v->addr&0xf))
{ {
const UNPACKPARTFUNCTYPESSE* pfn; const UNPACKPARTFUNCTYPESSE* pfn;
int writemask; int writemask;
@ -540,6 +545,7 @@ static void VIFunpack(u32 *data, vifCode *v, int size, const unsigned int VIFdma
oldcycle = *(u32*) & vifRegs->cycle; oldcycle = *(u32*) & vifRegs->cycle;
vifRegs->cycle.cl = vifRegs->cycle.wl = 1; vifRegs->cycle.cl = vifRegs->cycle.wl = 1;
} }
size = min(size, (int)vifRegs->num * ft->gsize); //size will always be the same or smaller size = min(size, (int)vifRegs->num * ft->gsize); //size will always be the same or smaller
pfn = vif->usn ? VIFfuncTableSSE[unpackType].funcU : VIFfuncTableSSE[unpackType].funcS; pfn = vif->usn ? VIFfuncTableSSE[unpackType].funcU : VIFfuncTableSSE[unpackType].funcS;
@ -573,10 +579,10 @@ static void VIFunpack(u32 *data, vifCode *v, int size, const unsigned int VIFdma
else else
{ {
if (unpackType == 0xC && vifRegs->cycle.cl == vifRegs->cycle.wl) //No use when SSE is available if ((unpackType == 0xC) && (vifRegs->cycle.cl == vifRegs->cycle.wl)) //No use when SSE is available
{ {
// v4-32 // v4-32
if (vifRegs->mode == 0 && !(vifRegs->code & 0x10000000) && vif->usn == 0) if ((vifRegs->mode == 0) && !(vifRegs->code & 0x10000000) && (vif->usn == 0))
{ {
vifRegs->num -= size >> 4; vifRegs->num -= size >> 4;
memcpy_fast((u8*)dest, cdata, size); memcpy_fast((u8*)dest, cdata, size);
@ -587,7 +593,7 @@ static void VIFunpack(u32 *data, vifCode *v, int size, const unsigned int VIFdma
incdest = ((vifRegs->cycle.cl - vifRegs->cycle.wl) << 2) + 4; incdest = ((vifRegs->cycle.cl - vifRegs->cycle.wl) << 2) + 4;
while (size >= ft->gsize && vifRegs->num > 0) while ((size >= ft->gsize) && (vifRegs->num > 0))
{ {
func(dest, (u32*)cdata, ft->qsize); func(dest, (u32*)cdata, ft->qsize);
cdata += ft->gsize; cdata += ft->gsize;
@ -690,7 +696,6 @@ static void VIFunpack(u32 *data, vifCode *v, int size, const unsigned int VIFdma
static void vuExecMicro(u32 addr, const u32 VIFdmanum) static void vuExecMicro(u32 addr, const u32 VIFdmanum)
{ {
int _cycles;
VURegs * VU; VURegs * VU;
if (VIFdmanum == 0) if (VIFdmanum == 0)
@ -729,21 +734,13 @@ static void vuExecMicro(u32 addr, const u32 VIFdmanum)
} }
if (VIFdmanum == 0) if (VIFdmanum == 0)
{
_cycles = VU0.cycle;
vu0ExecMicro(addr); vu0ExecMicro(addr);
}
else else
{
_cycles = VU1.cycle;
vu1ExecMicro(addr); vu1ExecMicro(addr);
}
} }
u8 s_maskwrite[256];
void vif0Init() void vif0Init()
{ {
u32 i; u32 i;
for (i = 0; i < 256; ++i) for (i = 0; i < 256; ++i)
@ -911,6 +908,7 @@ static int __fastcall Vif0TransMPG(u32 *data) // MPG
else else
{ {
int ret; int ret;
_vif0mpgTransfer(vif0.tag.addr, data, vif0.tag.size); _vif0mpgTransfer(vif0.tag.addr, data, vif0.tag.size);
ret = vif0.tag.size; ret = vif0.tag.size;
vif0.tag.size = 0; vif0.tag.size = 0;
@ -932,8 +930,9 @@ static int __fastcall Vif0TransUnpack(u32 *data) // UNPACK
} }
else else
{ {
int ret;
/* we got all the data, transfer it fully */ /* we got all the data, transfer it fully */
int ret;
VIFunpack(data, &vif0.tag, vif0.tag.size, VIF0dmanum); VIFunpack(data, &vif0.tag, vif0.tag.size, VIF0dmanum);
ret = vif0.tag.size; ret = vif0.tag.size;
vif0.tag.size = 0; vif0.tag.size = 0;
@ -1080,7 +1079,10 @@ int VIF0transfer(u32 *data, int size, int istag)
} }
vif0.cmd = 0; vif0.cmd = 0;
} }
else Vif0CMDTLB[(vif0.cmd & 0x7f)](); else
{
Vif0CMDTLB[(vif0.cmd & 0x7f)]();
}
} }
++data; ++data;
--vif0.vifpacketsize; --vif0.vifpacketsize;
@ -1107,24 +1109,23 @@ int VIF0transfer(u32 *data, int size, int istag)
g_vifCycles += (transferred >> 2) * BIAS; /* guessing */ g_vifCycles += (transferred >> 2) * BIAS; /* guessing */
// use tag.size because some game doesn't like .cmd // use tag.size because some game doesn't like .cmd
if (vif0.irq && vif0.tag.size == 0) if (vif0.irq && (vif0.tag.size == 0))
{ {
vif0.vifstalled = 1; vif0.vifstalled = 1;
if (((vif0Regs->code >> 24) & 0x7f) != 0x7)vif0Regs->stat |= VIF0_STAT_VIS; if (((vif0Regs->code >> 24) & 0x7f) != 0x7)vif0Regs->stat |= VIF0_STAT_VIS;
//else Console::WriteLn("VIF0 IRQ on MARK"); //else Console::WriteLn("VIF0 IRQ on MARK");
// spiderman doesn't break on qw boundaries // spiderman doesn't break on qw boundaries
vif0.irqoffset = transferred % 4; // cannot lose the offset vif0.irqoffset = transferred % 4; // cannot lose the offset
if (istag) if (!istag)
{ {
return -2; transferred = transferred >> 2;
vif0ch->madr += (transferred << 4);
vif0ch->qwc -= transferred;
} }
//else Console::WriteLn("Stall on vif0, FromSPR = %x, Vif0MADR = %x Sif0MADR = %x STADR = %x", params psHu32(0x1000d010), vif0ch->madr, psHu32(0x1000c010), psHu32(DMAC_STADR));
transferred = transferred >> 2;
vif0ch->madr += (transferred << 4);
vif0ch->qwc -= transferred;
//Console::WriteLn("Stall on vif0, FromSPR = %x, Vif0MADR = %x Sif0MADR = %x STADR = %x", params psHu32(0x1000d010), vif0ch->madr, psHu32(0x1000c010), psHu32(DMAC_STADR));
return -2; return -2;
} }
@ -1149,8 +1150,7 @@ int _VIF0chain()
if (vif0ch->qwc == 0 && vif0.vifstalled == 0) return 0; if (vif0ch->qwc == 0 && vif0.vifstalled == 0) return 0;
pMem = (u32*)dmaGetAddr(vif0ch->madr); pMem = (u32*)dmaGetAddr(vif0ch->madr);
if (pMem == NULL) if (pMem == NULL) return -1;
return -1;
if (vif0.vifstalled) if (vif0.vifstalled)
ret = VIF0transfer(pMem + vif0.irqoffset, vif0ch->qwc * 4 - vif0.irqoffset, 0); ret = VIF0transfer(pMem + vif0.irqoffset, vif0ch->qwc * 4 - vif0.irqoffset, 0);
@ -1160,8 +1160,6 @@ int _VIF0chain()
return ret; return ret;
} }
u32 *vif0ptag;
int _chainVIF0() int _chainVIF0()
{ {
int id, ret; int id, ret;
@ -1212,10 +1210,10 @@ int _chainVIF0()
void vif0Interrupt() void vif0Interrupt()
{ {
g_vifCycles = 0; //Reset the cycle count, Wouldnt reset on stall if put lower down. g_vifCycles = 0; //Reset the cycle count, Wouldn't reset on stall if put lower down.
VIF_LOG("vif0Interrupt: %8.8x", cpuRegs.cycle); VIF_LOG("vif0Interrupt: %8.8x", cpuRegs.cycle);
if (vif0.irq && vif0.tag.size == 0) if (vif0.irq && (vif0.tag.size == 0))
{ {
vif0Regs->stat |= VIF0_STAT_INT; vif0Regs->stat |= VIF0_STAT_INT;
hwIntcIrq(VIF0intc); hwIntcIrq(VIF0intc);
@ -1250,8 +1248,11 @@ void vif0Interrupt()
return; return;
} }
if (vif0ch->qwc > 0) _VIF0chain(); if (vif0ch->qwc > 0)
else _chainVIF0(); _VIF0chain();
else
_chainVIF0();
CPU_INT(0, g_vifCycles); CPU_INT(0, g_vifCycles);
return; return;
} }
@ -1330,104 +1331,106 @@ void dmaVIF0()
void vif0Write32(u32 mem, u32 value) void vif0Write32(u32 mem, u32 value)
{ {
if (mem == 0x10003830) // MARK switch (mem)
{ {
VIF_LOG("VIF0_MARK write32 0x%8.8x", value); case 0x10003830: // MARK
VIF_LOG("VIF0_MARK write32 0x%8.8x", value);
/* Clear mark flag in VIF0_STAT and set mark with 'value' */ /* Clear mark flag in VIF0_STAT and set mark with 'value' */
vif0Regs->stat &= ~VIF0_STAT_MRK; vif0Regs->stat &= ~VIF0_STAT_MRK;
vif0Regs->mark = value; vif0Regs->mark = value;
} break;
else if (mem == 0x10003810) // FBRST
{ case 0x10003810: // FBRST
VIF_LOG("VIF0_FBRST write32 0x%8.8x", value); VIF_LOG("VIF0_FBRST write32 0x%8.8x", value);
if (value & 0x1) if (value & 0x1)
{
/* Reset VIF */
//Console::WriteLn("Vif0 Reset %x", params vif0Regs->stat);
memzero_obj(vif0);
vif0ch->qwc = 0; //?
cpuRegs.interrupt &= ~1; //Stop all vif0 DMA's
psHu64(0x10004000) = 0;
psHu64(0x10004008) = 0;
vif0.done = 1;
vif0Regs->err = 0;
vif0Regs->stat &= ~(0xF000000 | VIF0_STAT_INT | VIF0_STAT_VSS | VIF0_STAT_VIS | VIF0_STAT_VFS | VIF0_STAT_VPS); // FQC=0
}
if (value & 0x2)
{
/* Force Break the VIF */
/* I guess we should stop the VIF dma here, but not 100% sure (linuz) */
cpuRegs.interrupt &= ~1; //Stop all vif0 DMA's
vif0Regs->stat |= VIF0_STAT_VFS;
vif0Regs->stat &= ~VIF0_STAT_VPS;
vif0.vifstalled = 1;
Console::WriteLn("vif0 force break");
}
if (value & 0x4)
{
/* Stop VIF */
// 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 |= VIF0_STAT_VSS;
vif0Regs->stat &= ~VIF0_STAT_VPS;
vif0.vifstalled = 1;
}
if (value & 0x8)
{
int cancel = 0;
/* 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 & (VIF0_STAT_VSS | VIF0_STAT_VIS | VIF0_STAT_VFS))
cancel = 1;
vif0Regs->stat &= ~(VIF0_STAT_VSS | VIF0_STAT_VFS | VIF0_STAT_VIS |
VIF0_STAT_INT | VIF0_STAT_ER0 | VIF0_STAT_ER1);
if (cancel)
{ {
if (vif0.vifstalled) /* Reset VIF */
//Console::WriteLn("Vif0 Reset %x", params vif0Regs->stat);
memzero_obj(vif0);
vif0ch->qwc = 0; //?
cpuRegs.interrupt &= ~1; //Stop all vif0 DMA's
psHu64(0x10004000) = 0;
psHu64(0x10004008) = 0;
vif0.done = 1;
vif0Regs->err = 0;
vif0Regs->stat &= ~(0xF000000 | VIF0_STAT_INT | VIF0_STAT_VSS | VIF0_STAT_VIS | VIF0_STAT_VFS | VIF0_STAT_VPS); // FQC=0
}
if (value & 0x2)
{
/* Force Break the VIF */
/* I guess we should stop the VIF dma here, but not 100% sure (linuz) */
cpuRegs.interrupt &= ~1; //Stop all vif0 DMA's
vif0Regs->stat |= VIF0_STAT_VFS;
vif0Regs->stat &= ~VIF0_STAT_VPS;
vif0.vifstalled = 1;
Console::WriteLn("vif0 force break");
}
if (value & 0x4)
{
/* Stop VIF */
// 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 |= VIF0_STAT_VSS;
vif0Regs->stat &= ~VIF0_STAT_VPS;
vif0.vifstalled = 1;
}
if (value & 0x8)
{
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 & (VIF0_STAT_VSS | VIF0_STAT_VIS | VIF0_STAT_VFS))
cancel = TRUE;
vif0Regs->stat &= ~(VIF0_STAT_VSS | VIF0_STAT_VFS | VIF0_STAT_VIS |
VIF0_STAT_INT | VIF0_STAT_ER0 | VIF0_STAT_ER1);
if (cancel)
{ {
g_vifCycles = 0; if (vif0.vifstalled)
{
g_vifCycles = 0;
// loop necessary for spiderman // loop necessary for spiderman
if (vif0.stallontag == 1) if (vif0.stallontag == 1)
_chainVIF0(); _chainVIF0();
else else
_VIF0chain(); _VIF0chain();
vif0ch->chcr |= 0x100; vif0ch->chcr |= 0x100;
CPU_INT(0, g_vifCycles); // Gets the timing right - Flatout CPU_INT(0, g_vifCycles); // Gets the timing right - Flatout
}
} }
} }
} break;
}
else if (mem == 0x10003820) case 0x10003820:
{ // ERR // ERR
VIF_LOG("VIF0_ERR write32 0x%8.8x", value); VIF_LOG("VIF0_ERR write32 0x%8.8x", value);
/* Set VIF0_ERR with 'value' */ /* Set VIF0_ERR with 'value' */
vif0Regs->err = value; vif0Regs->err = value;
} break;
else
{ default:
Console::WriteLn("Unknown Vif0 write to %x", params mem); Console::WriteLn("Unknown Vif0 write to %x", params mem);
if (mem >= 0x10003900 && mem < 0x10003980) if (mem >= 0x10003900 && mem < 0x10003980)
{ {
assert((mem&0xf) == 0); assert((mem&0xf) == 0);
if (mem < 0x10003940) if (mem < 0x10003940)
g_vifRow0[(mem>>4)&3] = value; g_vifRow0[(mem>>4)&3] = value;
else
g_vifCol0[(mem>>4)&3] = value;
}
else else
g_vifCol0[(mem>>4)&3] = value; {
psHu32(mem) = value;
} }
else break;
{
psHu32(mem) = value;
}
} }
/* Other registers are read-only so do nothing for them */ /* Other registers are read-only so do nothing for them */
} }
@ -1753,8 +1756,8 @@ static int __fastcall Vif1TransUnpack(u32 *data)
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Vif1 CMD Base Commands // Vif1 CMD Base Commands
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// fixme: Global variables should not have the same name as local variables, and this probably shouldn't be local anyways.
int transferred = 0; int transferred = 0;
bool Path3transfer = FALSE;
static void Vif1CMDNop() // NOP static void Vif1CMDNop() // NOP
{ {
vif1.cmd &= ~0x7f; vif1.cmd &= ~0x7f;
@ -1810,6 +1813,7 @@ static void Vif1CMDMskPath3() // MSKPATH3
} }
else else
{ {
// fixme: This is the *only* reason 'transferred' is global. Otherwise it'd be local to Vif1Transfer.
if (gif->chcr & 0x100) CPU_INT(2, (transferred >> 2) * BIAS); // Restart Path3 on its own, time it right! if (gif->chcr & 0x100) CPU_INT(2, (transferred >> 2) * BIAS); // Restart Path3 on its own, time it right!
psHu32(GIF_STAT) &= ~0x2; psHu32(GIF_STAT) &= ~0x2;
} }
@ -1951,7 +1955,6 @@ void (*Vif1CMDTLB[82])() =
}; };
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int VIF1transfer(u32 *data, int size, int istag) int VIF1transfer(u32 *data, int size, int istag)
{ {
int ret; int ret;
@ -1969,10 +1972,7 @@ int VIF1transfer(u32 *data, int size, int istag)
if (vif1.cmd) if (vif1.cmd)
{ {
vif1Regs->stat |= VIF1_STAT_VPS_T; //Decompression has started vif1Regs->stat |= VIF1_STAT_VPS_T; //Decompression has started
}
if (vif1.cmd)
{
ret = Vif1TransTLB[vif1.cmd](data); ret = Vif1TransTLB[vif1.cmd](data);
data += ret; data += ret;
vif1.vifpacketsize -= ret; vif1.vifpacketsize -= ret;
@ -2032,10 +2032,8 @@ int VIF1transfer(u32 *data, int size, int istag)
transferred += size - vif1.vifpacketsize; transferred += size - vif1.vifpacketsize;
g_vifCycles += (transferred >> 2) * BIAS; /* guessing */ g_vifCycles += (transferred >> 2) * BIAS; /* guessing */
vif1.irqoffset = transferred % 4; // cannot lose the offset vif1.irqoffset = transferred % 4; // cannot lose the offset
if (vif1.irq && vif1.cmd == 0) if (vif1.irq && vif1.cmd == 0)
{ {
vif1.vifstalled = 1; vif1.vifstalled = 1;
@ -2044,15 +2042,15 @@ int VIF1transfer(u32 *data, int size, int istag)
if (vif1ch->qwc == 0 && (vif1.irqoffset == 0 || istag == 1)) if (vif1ch->qwc == 0 && (vif1.irqoffset == 0 || istag == 1))
vif1.inprogress = 0; vif1.inprogress = 0;
// spiderman doesn't break on qw boundaries // spiderman doesn't break on qw boundaries
if (istag) return -2; if (istag) return -2;
transferred = transferred >> 2; transferred = transferred >> 2;
vif1ch->madr += (transferred << 4); vif1ch->madr += (transferred << 4);
vif1ch->qwc -= transferred; vif1ch->qwc -= transferred;
if (vif1ch->qwc == 0 && vif1.irqoffset == 0) vif1.inprogress = 0; if ((vif1ch->qwc == 0) && (vif1.irqoffset == 0)) vif1.inprogress = 0;
//Console::WriteLn("Stall on vif1, FromSPR = %x, Vif1MADR = %x Sif0MADR = %x STADR = %x", params psHu32(0x1000d010), vif1ch->madr, psHu32(0x1000c010), psHu32(DMAC_STADR)); //Console::WriteLn("Stall on vif1, FromSPR = %x, Vif1MADR = %x Sif0MADR = %x STADR = %x", params psHu32(0x1000d010), vif1ch->madr, psHu32(0x1000c010), psHu32(DMAC_STADR));
return -2; return -2;
} }
@ -2070,7 +2068,6 @@ int VIF1transfer(u32 *data, int size, int istag)
if (vif1ch->qwc == 0 && (vif1.irqoffset == 0 || istag == 1)) if (vif1ch->qwc == 0 && (vif1.irqoffset == 0 || istag == 1))
vif1.inprogress = 0; vif1.inprogress = 0;
return 0; return 0;
} }
@ -2147,8 +2144,7 @@ int _VIF1chain()
} }
pMem = (u32*)dmaGetAddr(vif1ch->madr); pMem = (u32*)dmaGetAddr(vif1ch->madr);
if (pMem == NULL) if (pMem == NULL) return -1;
return -1;
VIF_LOG("VIF1chain size=%d, madr=%lx, tadr=%lx", VIF_LOG("VIF1chain size=%d, madr=%lx, tadr=%lx",
vif1ch->qwc, vif1ch->madr, vif1ch->tadr); vif1ch->qwc, vif1ch->madr, vif1ch->tadr);
@ -2161,10 +2157,6 @@ int _VIF1chain()
return ret; return ret;
} }
static int prevvifcycles = 0;
static u32* prevviftag = NULL;
u32 *vif1ptag;
int _chainVIF1() int _chainVIF1()
{ {
return vif1.done;//Return Done return vif1.done;//Return Done
@ -2172,7 +2164,6 @@ int _chainVIF1()
__forceinline void vif1SetupTransfer() __forceinline void vif1SetupTransfer()
{ {
switch (vif1.dmamode) switch (vif1.dmamode)
{ {
case 0: //Normal case 0: //Normal
@ -2195,17 +2186,19 @@ __forceinline void vif1SetupTransfer()
} }
id = (vif1ptag[0] >> 28) & 0x7; //ID for DmaChain copied from bit 28 of the tag id = (vif1ptag[0] >> 28) & 0x7; //ID for DmaChain copied from bit 28 of the tag
vif1ch->qwc = (u16)vif1ptag[0]; //QWC set to lower 16bits of the tag vif1ch->qwc = (u16)vif1ptag[0]; //QWC set to lower 16bits of the tag
vif1ch->madr = vif1ptag[1]; //MADR = ADDR field vif1ch->madr = vif1ptag[1]; //MADR = ADDR field
vif1ch->chcr = (vif1ch->chcr & 0xFFFF) | ((*vif1ptag) & 0xFFFF0000); //Transfer upper part of tag to CHCR bits 31-15
g_vifCycles += 1; // Add 1 g_vifCycles from the QW read for the tag g_vifCycles += 1; // Add 1 g_vifCycles from the QW read for the tag
vif1ch->chcr = (vif1ch->chcr & 0xFFFF) | ((*vif1ptag) & 0xFFFF0000); //Transfer upper part of tag to CHCR bits 31-15
// Transfer dma tag if tte is set // Transfer dma tag if tte is set
VIF_LOG("VIF1 Tag %8.8x_%8.8x size=%d, id=%d, madr=%lx, tadr=%lx\n", VIF_LOG("VIF1 Tag %8.8x_%8.8x size=%d, id=%d, madr=%lx, tadr=%lx\n",
vif1ptag[1], vif1ptag[0], vif1ch->qwc, id, vif1ch->madr, vif1ch->tadr); vif1ptag[1], vif1ptag[0], vif1ch->qwc, id, vif1ch->madr, vif1ch->tadr);
if (!vif1.done && (psHu32(DMAC_CTRL) & 0xC0) == 0x40 && id == 4) // STD == VIF1 if (!vif1.done && ((psHu32(DMAC_CTRL) & 0xC0) == 0x40) && (id == 4)) // STD == VIF1
{ {
// there are still bugs, need to also check if gif->madr +16*qwc >= stadr, if not, stall // there are still bugs, need to also check if gif->madr +16*qwc >= stadr, if not, stall
if ((vif1ch->madr + vif1ch->qwc * 16) >= psHu32(DMAC_STADR)) if ((vif1ch->madr + vif1ch->qwc * 16) >= psHu32(DMAC_STADR))
@ -2246,6 +2239,7 @@ __forceinline void vif1SetupTransfer()
break; break;
} }
} }
__forceinline void vif1Interrupt() __forceinline void vif1Interrupt()
{ {
VIF_LOG("vif1Interrupt: %8.8x", cpuRegs.cycle); VIF_LOG("vif1Interrupt: %8.8x", cpuRegs.cycle);
@ -2267,7 +2261,7 @@ __forceinline void vif1Interrupt()
vif1ch->chcr &= ~0x100; vif1ch->chcr &= ~0x100;
return; return;
} }
else if (vif1ch->qwc > 0 || vif1.irqoffset > 0) else if ((vif1ch->qwc > 0) || (vif1.irqoffset > 0))
{ {
if (vif1.stallontag == 1) if (vif1.stallontag == 1)
vif1SetupTransfer(); vif1SetupTransfer();
@ -2278,7 +2272,7 @@ __forceinline void vif1Interrupt()
if (vif1.inprogress == 1) _VIF1chain(); if (vif1.inprogress == 1) _VIF1chain();
if (vif1.done == 0 || vif1.inprogress == 1) if ((vif1.done == 0) || (vif1.inprogress == 1))
{ {
if (!(psHu32(DMAC_CTRL) & 0x1)) if (!(psHu32(DMAC_CTRL) & 0x1))
@ -2287,7 +2281,7 @@ __forceinline void vif1Interrupt()
return; return;
} }
if (vif1.inprogress == 0)vif1SetupTransfer(); if (vif1.inprogress == 0) vif1SetupTransfer();
CPU_INT(1, vif1ch->qwc * BIAS); CPU_INT(1, vif1ch->qwc * BIAS);
return; return;
@ -2303,8 +2297,6 @@ __forceinline void vif1Interrupt()
if (vif1.cmd != 0) Console::WriteLn("vif1.cmd still set %x", params vif1.cmd); if (vif1.cmd != 0) Console::WriteLn("vif1.cmd still set %x", params vif1.cmd);
#endif #endif
prevviftag = NULL;
prevvifcycles = 0;
vif1ch->chcr &= ~0x100; vif1ch->chcr &= ~0x100;
g_vifCycles = 0; g_vifCycles = 0;
hwDmacIrq(DMAC_VIF1); hwDmacIrq(DMAC_VIF1);
@ -2365,135 +2357,142 @@ void dmaVIF1()
void vif1Write32(u32 mem, u32 value) void vif1Write32(u32 mem, u32 value)
{ {
if (mem == 0x10003c30) // MARK switch (mem)
{ {
VIF_LOG("VIF1_MARK write32 0x%8.8x", value); case 0x10003c30: // MARK
VIF_LOG("VIF1_MARK write32 0x%8.8x", value);
/* Clear mark flag in VIF1_STAT and set mark with 'value' */ /* Clear mark flag in VIF1_STAT and set mark with 'value' */
vif1Regs->stat &= ~VIF1_STAT_MRK; vif1Regs->stat &= ~VIF1_STAT_MRK;
vif1Regs->mark = value; vif1Regs->mark = value;
} break;
else if (mem == 0x10003c10) // FBRST
{ case 0x10003c10: // FBRST
VIF_LOG("VIF1_FBRST write32 0x%8.8x", value); VIF_LOG("VIF1_FBRST write32 0x%8.8x", value);
if (value & 0x1) if (value & 0x1)
{
/* Reset VIF */
memzero_obj(vif1);
cpuRegs.interrupt &= ~((1 << 1) | (1 << 10)); //Stop all vif1 DMA's
vif1ch->qwc = 0; //?
psHu64(0x10005000) = 0;
psHu64(0x10005008) = 0;
vif1.done = 1;
vif1Regs->err = 0;
vif1.inprogress = 0;
vif1Regs->stat &= ~(0x1F800000 | VIF1_STAT_INT | VIF1_STAT_VSS | VIF1_STAT_VIS | VIF1_STAT_VFS | VIF1_STAT_VPS); // FQC=0
}
if (value & 0x2)
{
/* Force Break the VIF */
/* I guess we should stop the VIF dma here, but not 100% sure (linuz) */
vif1Regs->stat |= VIF1_STAT_VFS;
vif1Regs->stat &= ~VIF1_STAT_VPS;
cpuRegs.interrupt &= ~((1 << 1) | (1 << 10)); //Stop all vif1 DMA's
vif1.vifstalled = 1;
Console::WriteLn("vif1 force break");
}
if (value & 0x4)
{
/* Stop VIF */
// Not completly 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 |= VIF1_STAT_VSS;
vif1Regs->stat &= ~VIF1_STAT_VPS;
cpuRegs.interrupt &= ~((1 << 1) | (1 << 10)); //Stop all vif1 DMA's
vif1.vifstalled = 1;
}
if (value & 0x8)
{
int cancel = 0;
/* 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 & (VIF1_STAT_VSS | VIF1_STAT_VIS | VIF1_STAT_VFS))
{ {
cancel = 1; /* Reset VIF */
memzero_obj(vif1);
cpuRegs.interrupt &= ~((1 << 1) | (1 << 10)); //Stop all vif1 DMA's
vif1ch->qwc = 0; //?
psHu64(0x10005000) = 0;
psHu64(0x10005008) = 0;
vif1.done = 1;
vif1Regs->err = 0;
vif1.inprogress = 0;
vif1Regs->stat &= ~(0x1F800000 | VIF1_STAT_INT | VIF1_STAT_VSS | VIF1_STAT_VIS | VIF1_STAT_VFS | VIF1_STAT_VPS); // FQC=0
} }
if (value & 0x2)
vif1Regs->stat &= ~(VIF1_STAT_VSS | VIF1_STAT_VFS | VIF1_STAT_VIS |
VIF1_STAT_INT | VIF1_STAT_ER0 | VIF1_STAT_ER1);
if (cancel)
{ {
if (vif1.vifstalled) /* Force Break the VIF */
{ /* I guess we should stop the VIF dma here, but not 100% sure (linuz) */
g_vifCycles = 0; vif1Regs->stat |= VIF1_STAT_VFS;
// loop necessary for spiderman vif1Regs->stat &= ~VIF1_STAT_VPS;
if ((psHu32(DMAC_CTRL) & 0xC) == 0x8) cpuRegs.interrupt &= ~((1 << 1) | (1 << 10)); //Stop all vif1 DMA's
{ vif1.vifstalled = 1;
Console::WriteLn("vif1 force break");
}
if (value & 0x4)
{
/* Stop VIF */
// 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 |= VIF1_STAT_VSS;
vif1Regs->stat &= ~VIF1_STAT_VPS;
cpuRegs.interrupt &= ~((1 << 1) | (1 << 10)); //Stop all vif1 DMA's
vif1.vifstalled = 1;
}
if (value & 0x8)
{
bool cancel = FALSE;
//Console::WriteLn("MFIFO Stall"); /* Cancel stall, first check if there is a stall to cancel, and then clear VIF1_STAT VSS|VFS|VIS|INT|ER0|ER1 bits */
CPU_INT(10, vif1ch->qwc * BIAS); if (vif1Regs->stat & (VIF1_STAT_VSS | VIF1_STAT_VIS | VIF1_STAT_VFS))
} {
else cancel = TRUE;
}
vif1Regs->stat &= ~(VIF1_STAT_VSS | VIF1_STAT_VFS | VIF1_STAT_VIS |
VIF1_STAT_INT | VIF1_STAT_ER0 | VIF1_STAT_ER1);
if (cancel)
{
if (vif1.vifstalled)
{ {
// Gets the timing right - Flatout g_vifCycles = 0;
CPU_INT(1, vif1ch->qwc * BIAS); // loop necessary for spiderman
if ((psHu32(DMAC_CTRL) & 0xC) == 0x8)
{
//Console::WriteLn("MFIFO Stall");
CPU_INT(10, vif1ch->qwc * BIAS);
}
else
{
// Gets the timing right - Flatout
CPU_INT(1, vif1ch->qwc * BIAS);
}
vif1ch->chcr |= 0x100;
} }
vif1ch->chcr |= 0x100;
} }
} }
} break;
}
else if (mem == 0x10003c20) // ERR case 0x10003c20: // ERR
{ VIF_LOG("VIF1_ERR write32 0x%8.8x", value);
VIF_LOG("VIF1_ERR write32 0x%8.8x", value);
/* Set VIF1_ERR with 'value' */ /* Set VIF1_ERR with 'value' */
vif1Regs->err = value; vif1Regs->err = value;
} break;
else if (mem == 0x10003c00) // STAT
{ case 0x10003c00: // STAT
VIF_LOG("VIF1_STAT write32 0x%8.8x", value); VIF_LOG("VIF1_STAT write32 0x%8.8x", value);
#ifdef PCSX2_DEVBUILD #ifdef PCSX2_DEVBUILD
/* Only FDR bit is writable, so mask the rest */ /* Only FDR bit is writable, so mask the rest */
if ((vif1Regs->stat & VIF1_STAT_FDR) ^(value & VIF1_STAT_FDR)) if ((vif1Regs->stat & VIF1_STAT_FDR) ^(value & VIF1_STAT_FDR))
{
// different so can't be stalled
if (vif1Regs->stat & (VIF1_STAT_INT | VIF1_STAT_VSS | VIF1_STAT_VIS | VIF1_STAT_VFS))
{ {
Console::WriteLn("changing dir when vif1 fifo stalled"); // different so can't be stalled
if (vif1Regs->stat & (VIF1_STAT_INT | VIF1_STAT_VSS | VIF1_STAT_VIS | VIF1_STAT_VFS))
{
DevCon::WriteLn("changing dir when vif1 fifo stalled");
}
} }
}
#endif #endif
vif1Regs->stat = (vif1Regs->stat & ~VIF1_STAT_FDR) | (value & VIF1_STAT_FDR); vif1Regs->stat = (vif1Regs->stat & ~VIF1_STAT_FDR) | (value & VIF1_STAT_FDR);
if (vif1Regs->stat & VIF1_STAT_FDR) if (vif1Regs->stat & VIF1_STAT_FDR)
{ {
vif1Regs->stat |= 0x01000000; vif1Regs->stat |= 0x01000000;
} }
else else
{ {
vif1ch->qwc = 0; vif1ch->qwc = 0;
vif1.vifstalled = 0; vif1.vifstalled = 0;
vif1.done = 1; vif1.done = 1;
vif1Regs->stat &= ~0x1F000000; // FQC=0 vif1Regs->stat &= ~0x1F000000; // FQC=0
} }
} break;
else if (mem == 0x10003c50) // MODE
{ case 0x10003c50: // MODE
vif1Regs->mode = value; vif1Regs->mode = value;
} break;
else
{ default:
Console::WriteLn("Unknown Vif1 write to %x", params mem); Console::WriteLn("Unknown Vif1 write to %x", params mem);
if (mem >= 0x10003d00 && mem < 0x10003d80) if ((mem >= 0x10003d00) && (mem < 0x10003d80))
{ {
assert((mem&0xf) == 0); assert((mem&0xf) == 0);
if (mem < 0x10003d40) g_vifRow1[(mem>>4)&3] = value; if (mem < 0x10003d40)
else g_vifCol1[(mem>>4)&3] = value; g_vifRow1[(mem>>4)&3] = value;
} else
else psHu32(mem) = value; g_vifCol1[(mem>>4)&3] = value;
}
else
{
psHu32(mem) = value;
}
break;
} }
/* Other registers are read-only so do nothing for them */ /* Other registers are read-only so do nothing for them */

View File

@ -35,7 +35,7 @@ else
DEBUG_FLAGS=" -O0 -g " DEBUG_FLAGS=" -O0 -g "
fi fi
WARNING_FLAGS="-Wno-format -Wno-unused-value" WARNING_FLAGS="-Wno-format -Wno-unused-parameter -Wno-unused-value -Wunused-variable "
EXTRA_WARNING_FLAGS="-Wall -Wextra" EXTRA_WARNING_FLAGS="-Wall -Wextra"
NORMAL_FLAGS=" -pipe -msse -msse2 -O2 ${WARNING_FLAGS}" NORMAL_FLAGS=" -pipe -msse -msse2 -O2 ${WARNING_FLAGS}"
# These optimizations seem to cause issues with GCC 4.3.3, so we'll turn them off. # These optimizations seem to cause issues with GCC 4.3.3, so we'll turn them off.

View File

@ -460,7 +460,7 @@ static void cropzeros(char *buffer)
stop = buffer--; stop = buffer--;
while (*buffer == '0') buffer--; while (*buffer == '0') buffer--;
if (*buffer == '.') buffer--; if (*buffer == '.') buffer--;
while (*++buffer = *stop++); while (*++buffer = *stop++) ;
} }
} }

View File

@ -55,12 +55,12 @@ struct BASEBLOCKEX
class BaseBlocks class BaseBlocks
{ {
private: private:
std::vector<BASEBLOCKEX> blocks;
// switch to a hash map later? // switch to a hash map later?
std::multimap<u32, uptr> links; std::multimap<u32, uptr> links;
typedef std::multimap<u32, uptr>::iterator linkiter_t; typedef std::multimap<u32, uptr>::iterator linkiter_t;
unsigned long size; unsigned long size;
uptr recompiler; uptr recompiler;
std::vector<BASEBLOCKEX> blocks;
public: public:
BaseBlocks(unsigned long size_, uptr recompiler_) : BaseBlocks(unsigned long size_, uptr recompiler_) :
@ -78,8 +78,10 @@ public:
inline int Index (u32 startpc) const inline int Index (u32 startpc) const
{ {
int idx = LastIndex(startpc); int idx = LastIndex(startpc);
if (idx == -1 || startpc < blocks[idx].startpc || // fixme: I changed the parenthesis to be unambiguous, but this needs to be checked to see if ((x or y or z) and w)
blocks[idx].size && (startpc >= blocks[idx].startpc + blocks[idx].size * 4)) // is correct, or ((x or y) or (z and w)), or some other variation. --arcum42
if (((idx == -1) || (startpc < blocks[idx].startpc) ||
(blocks[idx].size)) && (startpc >= blocks[idx].startpc + blocks[idx].size * 4))
return -1; return -1;
else else
return idx; return idx;
@ -99,7 +101,7 @@ public:
inline void Remove(int idx) inline void Remove(int idx)
{ {
u32 startpc = blocks[idx].startpc; //u32 startpc = blocks[idx].startpc;
std::pair<linkiter_t, linkiter_t> range = links.equal_range(blocks[idx].startpc); std::pair<linkiter_t, linkiter_t> range = links.equal_range(blocks[idx].startpc);
for (linkiter_t i = range.first; i != range.second; ++i) for (linkiter_t i = range.first; i != range.second; ++i)
*(u32*)i->second = recompiler - (i->second + 4); *(u32*)i->second = recompiler - (i->second + 4);

View File

@ -168,15 +168,10 @@ void _flushConstRegs()
continue; continue;
if (g_cpuConstRegs[i].SL[j] != -1) if (g_cpuConstRegs[i].SL[j] != -1)
continue; continue;
#if 1
if (eaxval > 0) if (eaxval > 0) XOR32RtoR(EAX, EAX), eaxval = 0;
XOR32RtoR(EAX, EAX), eaxval = 0; if (eaxval == 0) NOT32R(EAX), eaxval = -1;
#else
if (eaxval > 0)
MOV32ItoR(EAX, -1), eaxval = -1;
#endif
if (eaxval == 0)
NOT32R(EAX), eaxval = -1;
MOV32RtoM((uptr)&cpuRegs.GPR.r[i].SL[j], EAX); MOV32RtoM((uptr)&cpuRegs.GPR.r[i].SL[j], EAX);
done[j + 2] |= 1<<i; done[j + 2] |= 1<<i;
minusone_cnt++; minusone_cnt++;
@ -198,28 +193,8 @@ void _flushConstRegs()
MOV32ItoM((uptr)&cpuRegs.GPR.r[i].UL[1], g_cpuConstRegs[i].UL[1]); MOV32ItoM((uptr)&cpuRegs.GPR.r[i].UL[1], g_cpuConstRegs[i].UL[1]);
g_cpuFlushedConstReg |= 1<<i; g_cpuFlushedConstReg |= 1<<i;
} }
#if defined(_DEBUG)&&0 if (g_cpuHasConstReg == g_cpuFlushedConstReg)
else {
// make sure the const regs are the same
u8* ptemp[3];
CMP32ItoM((u32)&cpuRegs.GPR.r[i].UL[0], g_cpuConstRegs[i].UL[0]);
ptemp[0] = JNE8(0);
if( EEINST_ISLIVE1(i) ) {
CMP32ItoM((u32)&cpuRegs.GPR.r[i].UL[1], g_cpuConstRegs[i].UL[1]);
ptemp[1] = JNE8(0);
}
ptemp[2] = JMP8(0);
x86SetJ8( ptemp[0] );
if( EEINST_ISLIVE1(i) ) x86SetJ8( ptemp[1] );
CALLFunc((uptr)checkconstreg);
x86SetJ8( ptemp[2] );
}
#else
if( g_cpuHasConstReg == g_cpuFlushedConstReg )
break; break;
#endif
} }
} }
} }
@ -228,9 +203,6 @@ int _allocX86reg(int x86reg, int type, int reg, int mode)
{ {
int i; int i;
assert( reg >= 0 && reg < 32 ); assert( reg >= 0 && reg < 32 );
// if( X86_ISVI(type) )
// assert( reg < 16 || reg == REG_R );
// don't alloc EAX and ESP,EBP if MODE_NOFRAME // don't alloc EAX and ESP,EBP if MODE_NOFRAME
int oldmode = mode; int oldmode = mode;
@ -265,9 +237,8 @@ int _allocX86reg(int x86reg, int type, int reg, int mode)
if (!x86regs[i].inuse || x86regs[i].type != type || x86regs[i].reg != reg) continue; if (!x86regs[i].inuse || x86regs[i].type != type || x86regs[i].reg != reg) continue;
if( (noframe && i == EBP) || (i >= maxreg) ) { if( (noframe && i == EBP) || (i >= maxreg) ) {
if( x86regs[i].mode & MODE_READ ) if (x86regs[i].mode & MODE_READ) readfromreg = i;
readfromreg = i;
//if( xmmregs[i].mode & MODE_WRITE ) mode |= MODE_WRITE;
mode |= x86regs[i].mode&MODE_WRITE; mode |= x86regs[i].mode&MODE_WRITE;
x86regs[i].inuse = 0; x86regs[i].inuse = 0;
break; break;
@ -277,7 +248,6 @@ int _allocX86reg(int x86reg, int type, int reg, int mode)
// requested specific reg, so return that instead // requested specific reg, so return that instead
if( i != x86reg ) { if( i != x86reg ) {
if( x86regs[i].mode & MODE_READ ) readfromreg = i; if( x86regs[i].mode & MODE_READ ) readfromreg = i;
//if( x86regs[i].mode & MODE_WRITE ) mode |= MODE_WRITE;
mode |= x86regs[i].mode&MODE_WRITE; mode |= x86regs[i].mode&MODE_WRITE;
x86regs[i].inuse = 0; x86regs[i].inuse = 0;
break; break;
@ -288,8 +258,10 @@ int _allocX86reg(int x86reg, int type, int reg, int mode)
if( type == X86TYPE_GPR ) _flushConstReg(reg); if( type == X86TYPE_GPR ) _flushConstReg(reg);
if( X86_ISVI(type) && reg < 16 ) MOVZX32M16toR(i, _x86GetAddr(type, reg)); if( X86_ISVI(type) && reg < 16 )
else MOV32MtoR(i, _x86GetAddr(type, reg)); MOVZX32M16toR(i, _x86GetAddr(type, reg));
else
MOV32MtoR(i, _x86GetAddr(type, reg));
x86regs[i].mode |= MODE_READ; x86regs[i].mode |= MODE_READ;
} }
@ -314,7 +286,8 @@ int _allocX86reg(int x86reg, int type, int reg, int mode)
x86regs[x86reg].inuse = 1; x86regs[x86reg].inuse = 1;
if( mode & MODE_READ ) { if( mode & MODE_READ ) {
if( readfromreg >= 0 ) MOV32RtoR(x86reg, readfromreg); if( readfromreg >= 0 )
MOV32RtoR(x86reg, readfromreg);
else { else {
if( type == X86TYPE_GPR ) { if( type == X86TYPE_GPR ) {
@ -334,8 +307,10 @@ int _allocX86reg(int x86reg, int type, int reg, int mode)
} }
else { else {
if( X86_ISVI(type) && reg < 16 ) { if( X86_ISVI(type) && reg < 16 ) {
if( reg == 0 ) XOR32RtoR(x86reg, x86reg); if( reg == 0 )
else MOVZX32M16toR(x86reg, _x86GetAddr(type, reg)); XOR32RtoR(x86reg, x86reg);
else
MOVZX32M16toR(x86reg, _x86GetAddr(type, reg));
} }
else MOV32MtoR(x86reg, _x86GetAddr(type, reg)); else MOV32MtoR(x86reg, _x86GetAddr(type, reg));
} }
@ -353,8 +328,10 @@ int _checkX86reg(int type, int reg, int mode)
if (x86regs[i].inuse && x86regs[i].reg == reg && x86regs[i].type == type) { if (x86regs[i].inuse && x86regs[i].reg == reg && x86regs[i].type == type) {
if( !(x86regs[i].mode & MODE_READ) && (mode&MODE_READ) ) { if( !(x86regs[i].mode & MODE_READ) && (mode&MODE_READ) ) {
if( X86_ISVI(type) ) MOVZX32M16toR(i, _x86GetAddr(type, reg)); if( X86_ISVI(type) )
else MOV32MtoR(i, _x86GetAddr(type, reg)); MOVZX32M16toR(i, _x86GetAddr(type, reg));
else
MOV32MtoR(i, _x86GetAddr(type, reg));
} }
x86regs[i].mode |= mode; x86regs[i].mode |= mode;
@ -404,8 +381,10 @@ void _deleteX86reg(int type, int reg, int flush)
case 1: case 1:
if( x86regs[i].mode & MODE_WRITE) { if( x86regs[i].mode & MODE_WRITE) {
if( X86_ISVI(type) && x86regs[i].reg < 16 ) MOV16RtoM(_x86GetAddr(type, x86regs[i].reg), i); if( X86_ISVI(type) && x86regs[i].reg < 16 )
else MOV32RtoM(_x86GetAddr(type, x86regs[i].reg), i); MOV16RtoM(_x86GetAddr(type, x86regs[i].reg), i);
else
MOV32RtoM(_x86GetAddr(type, x86regs[i].reg), i);
// get rid of MODE_WRITE since don't want to flush again // get rid of MODE_WRITE since don't want to flush again
x86regs[i].mode &= ~MODE_WRITE; x86regs[i].mode &= ~MODE_WRITE;
@ -476,7 +455,8 @@ __forceinline void* _MMXGetAddr(int reg)
int _getFreeMMXreg() int _getFreeMMXreg()
{ {
int i, tempi; int i;
int tempi = -1;
u32 bestcount = 0x10000; u32 bestcount = 0x10000;
for (i=0; i<MMXREGS; i++) { for (i=0; i<MMXREGS; i++) {
@ -513,7 +493,6 @@ int _getFreeMMXreg()
} }
} }
tempi = -1;
for (i=0; i<MMXREGS; i++) { for (i=0; i<MMXREGS; i++) {
if (mmxregs[i].needed) continue; if (mmxregs[i].needed) continue;
if (mmxregs[i].reg != MMX_TEMP) { if (mmxregs[i].reg != MMX_TEMP) {
@ -564,9 +543,8 @@ int _allocMMXreg(int mmxreg, int reg, int mode)
if( MMX_ISGPR(reg) ) _flushConstReg(reg-MMX_GPR); if( MMX_ISGPR(reg) ) _flushConstReg(reg-MMX_GPR);
if( (mode & MODE_READHALF) || (MMX_IS32BITS(reg)&&(mode&MODE_READ)) ) if( (mode & MODE_READHALF) || (MMX_IS32BITS(reg)&&(mode&MODE_READ)) )
MOVDMtoMMX(i, (u32)_MMXGetAddr(reg)); MOVDMtoMMX(i, (u32)_MMXGetAddr(reg));
else { else
MOVQMtoR(i, (u32)_MMXGetAddr(reg)); MOVQMtoR(i, (u32)_MMXGetAddr(reg));
}
} }
mmxregs[i].mode |= MODE_READ; mmxregs[i].mode |= MODE_READ;
@ -578,10 +556,8 @@ int _allocMMXreg(int mmxreg, int reg, int mode)
} }
} }
if (mmxreg == -1) { if (mmxreg == -1) mmxreg = _getFreeMMXreg();
mmxreg = _getFreeMMXreg();
}
mmxregs[mmxreg].inuse = 1; mmxregs[mmxreg].inuse = 1;
mmxregs[mmxreg].reg = reg; mmxregs[mmxreg].reg = reg;
mmxregs[mmxreg].mode = mode&~MODE_READHALF; mmxregs[mmxreg].mode = mode&~MODE_READHALF;
@ -673,9 +649,7 @@ void _clearNeededMMXregs()
int i; int i;
for (i=0; i<MMXREGS; i++) { for (i=0; i<MMXREGS; i++) {
if( mmxregs[i].needed ) { if( mmxregs[i].needed ) {
// setup read to any just written regs // setup read to any just written regs
if( mmxregs[i].inuse && (mmxregs[i].mode&MODE_WRITE) ) if( mmxregs[i].inuse && (mmxregs[i].mode&MODE_WRITE) )
mmxregs[i].mode |= MODE_READ; mmxregs[i].mode |= MODE_READ;
@ -684,8 +658,6 @@ void _clearNeededMMXregs()
} }
} }
// when flush is 0 - frees all of the reg, when flush is 1, flushes all of the reg, when
// it is 2, just stops using the reg (no flushing)
void _deleteMMXreg(int reg, int flush) void _deleteMMXreg(int reg, int flush)
{ {
int i; int i;
@ -693,11 +665,11 @@ void _deleteMMXreg(int reg, int flush)
if (mmxregs[i].inuse && mmxregs[i].reg == reg ) { if (mmxregs[i].inuse && mmxregs[i].reg == reg ) {
switch(flush) { switch(flush) {
case 0: case 0: // frees all of the reg
_freeMMXreg(i); _freeMMXreg(i);
break; break;
case 1: case 1: // flushes all of the reg
if( mmxregs[i].mode & MODE_WRITE) { if( mmxregs[i].mode & MODE_WRITE) {
assert( mmxregs[i].reg != MMX_GPR ); assert( mmxregs[i].reg != MMX_GPR );
@ -712,12 +684,10 @@ void _deleteMMXreg(int reg, int flush)
mmxregs[i].mode |= MODE_READ; mmxregs[i].mode |= MODE_READ;
} }
return; return;
case 2: case 2: // just stops using the reg (no flushing)
mmxregs[i].inuse = 0; mmxregs[i].inuse = 0;
break; break;
} }
return; return;
} }
} }
@ -817,9 +787,7 @@ void _flushMMXregs()
if (mmxregs[i].inuse == 0) continue; if (mmxregs[i].inuse == 0) continue;
if( mmxregs[i].mode & MODE_WRITE ) { if( mmxregs[i].mode & MODE_WRITE ) {
assert( !(g_cpuHasConstReg & (1<<mmxregs[i].reg)) ); assert( !(g_cpuHasConstReg & (1<<mmxregs[i].reg)) );
assert( mmxregs[i].reg != MMX_TEMP ); assert( mmxregs[i].reg != MMX_TEMP );
assert( mmxregs[i].mode & MODE_READ ); assert( mmxregs[i].mode & MODE_READ );
assert( mmxregs[i].reg != MMX_GPR ); assert( mmxregs[i].reg != MMX_GPR );
@ -853,22 +821,29 @@ void SetFPUstate() {
_freeMMXreg(6); _freeMMXreg(6);
_freeMMXreg(7); _freeMMXreg(7);
if (x86FpuState==MMX_STATE) { if (x86FpuState == MMX_STATE) {
if (cpucaps.has3DNOWInstructionExtensions) FEMMS(); if (cpucaps.has3DNOWInstructionExtensions)
else EMMS(); FEMMS();
x86FpuState=FPU_STATE; else
EMMS();
x86FpuState = FPU_STATE;
} }
} }
__forceinline void _callPushArg(u32 arg, uptr argmem) __forceinline void _callPushArg(u32 arg, uptr argmem)
{ {
if( IS_X86REG(arg) ) PUSH32R(arg&0xff); if( IS_X86REG(arg) ) {
else if( IS_CONSTREG(arg) ) PUSH32I(argmem); PUSH32R(arg&0xff);
else if( IS_GPRREG(arg) ) { }
SUB32ItoR(ESP, 4); else if( IS_CONSTREG(arg) ) {
PUSH32I(argmem);
}
else if( IS_GPRREG(arg) ) {
SUB32ItoR(ESP, 4);
_eeMoveGPRtoRm(ESP, arg&0xff); _eeMoveGPRtoRm(ESP, arg&0xff);
} }
else if( IS_XMMREG(arg) ) { else if( IS_XMMREG(arg) ) {
SUB32ItoR(ESP, 4); SUB32ItoR(ESP, 4);
SSEX_MOVD_XMM_to_Rm(ESP, arg&0xf); SSEX_MOVD_XMM_to_Rm(ESP, arg&0xf);
} }
@ -882,36 +857,38 @@ __forceinline void _callPushArg(u32 arg, uptr argmem)
else if( IS_PSXCONSTREG(arg) ) { else if( IS_PSXCONSTREG(arg) ) {
PUSH32I(g_psxConstRegs[(arg>>16)&0x1f]); PUSH32I(g_psxConstRegs[(arg>>16)&0x1f]);
} }
else if( IS_MEMORYREG(arg) ) PUSH32M(argmem); else if( IS_MEMORYREG(arg) ) {
else { PUSH32M(argmem);
assert( (arg&0xfff0) == 0 ); }
// assume it is a GPR reg else {
PUSH32R(arg&0xf); assert( (arg&0xfff0) == 0 );
} // assume it is a GPR reg
PUSH32R(arg&0xf);
}
} }
__forceinline void _callFunctionArg1(uptr fn, u32 arg1, uptr arg1mem) __forceinline void _callFunctionArg1(uptr fn, u32 arg1, uptr arg1mem)
{ {
_callPushArg(arg1, arg1mem); _callPushArg(arg1, arg1mem);
CALLFunc((uptr)fn); CALLFunc((uptr)fn);
ADD32ItoR(ESP, 4); ADD32ItoR(ESP, 4);
} }
__forceinline void _callFunctionArg2(uptr fn, u32 arg1, u32 arg2, uptr arg1mem, uptr arg2mem) __forceinline void _callFunctionArg2(uptr fn, u32 arg1, u32 arg2, uptr arg1mem, uptr arg2mem)
{ {
_callPushArg(arg2, arg2mem); _callPushArg(arg2, arg2mem);
_callPushArg(arg1, arg1mem); _callPushArg(arg1, arg1mem);
CALLFunc((uptr)fn); CALLFunc((uptr)fn);
ADD32ItoR(ESP, 8); ADD32ItoR(ESP, 8);
} }
__forceinline void _callFunctionArg3(uptr fn, u32 arg1, u32 arg2, u32 arg3, uptr arg1mem, uptr arg2mem, uptr arg3mem) __forceinline void _callFunctionArg3(uptr fn, u32 arg1, u32 arg2, u32 arg3, uptr arg1mem, uptr arg2mem, uptr arg3mem)
{ {
_callPushArg(arg3, arg3mem); _callPushArg(arg3, arg3mem);
_callPushArg(arg2, arg2mem); _callPushArg(arg2, arg2mem);
_callPushArg(arg1, arg1mem); _callPushArg(arg1, arg1mem);
CALLFunc((uptr)fn); CALLFunc((uptr)fn);
ADD32ItoR(ESP, 12); ADD32ItoR(ESP, 12);
} }
void _recPushReg(int mmreg) void _recPushReg(int mmreg)
@ -931,8 +908,8 @@ void _recPushReg(int mmreg)
PUSH32I(g_psxConstRegs[(mmreg>>16)&0x1f]); PUSH32I(g_psxConstRegs[(mmreg>>16)&0x1f]);
} }
else { else {
assert( (mmreg&0xfff0) == 0 ); assert( (mmreg&0xfff0) == 0 );
PUSH32R(mmreg); PUSH32R(mmreg);
} }
} }
@ -947,11 +924,13 @@ void _signExtendSFtoM(u32 mem)
int _signExtendMtoMMX(x86MMXRegType to, u32 mem) int _signExtendMtoMMX(x86MMXRegType to, u32 mem)
{ {
int t0reg = _allocMMXreg(-1, MMX_TEMP, 0); int t0reg = _allocMMXreg(-1, MMX_TEMP, 0);
MOVDMtoMMX(t0reg, mem); MOVDMtoMMX(t0reg, mem);
MOVQRtoR(to, t0reg); MOVQRtoR(to, t0reg);
PSRADItoR(t0reg, 31); PSRADItoR(t0reg, 31);
PUNPCKLDQRtoR(to, t0reg); PUNPCKLDQRtoR(to, t0reg);
_freeMMXreg(t0reg); _freeMMXreg(t0reg);
return to; return to;
} }
@ -1054,7 +1033,7 @@ int _allocCheckGPRtoMMX(EEINST* pinst, int reg, int mode)
return _checkMMXreg(MMX_GPR+reg, mode); return _checkMMXreg(MMX_GPR+reg, mode);
} }
// fixme - yay stupid? This sucks, and is used form iCOp2.cpp only. // fixme - yay stupid? This sucks, and is used from iCOP2.cpp only.
// Surely there is a better way! // Surely there is a better way!
void _recMove128MtoM(u32 to, u32 from) void _recMove128MtoM(u32 to, u32 from)
{ {

View File

@ -607,8 +607,9 @@ static void recShutdown( void )
s_nInstCacheSize = 0; s_nInstCacheSize = 0;
} }
// Ignored by Linux #ifdef _MSC_VER
#pragma warning(disable:4731) // frame pointer register 'ebp' modified by inline assembly code #pragma warning(disable:4731) // frame pointer register 'ebp' modified by inline assembly code
#endif
void recStep( void ) { void recStep( void ) {
} }