- Various fixes to MMI and more changes to opcodes to mimic ps2 behavior, thanks to Nneeve.

- Brought back a gamefix for Persona games. They still have missing geometry without it (VU clip flag problem)

git-svn-id: http://pcsx2.googlecode.com/svn/trunk@835 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
ramapcsx2 2009-03-22 19:40:43 +00:00
parent 95c7ce1dbc
commit 157e696182
9 changed files with 298 additions and 124 deletions

View File

@ -66,6 +66,7 @@ extern SessionOverrideFlags g_Session;
//------------ SPECIAL GAME FIXES!!! ---------------
#define CHECK_VUADDSUBHACK (Config.GameFixes & 0x1) // Special Fix for Tri-ace games, they use an encryption algorithm that requires VU addi opcode to be bit-accurate.
#define CHECK_FPUCOMPAREHACK (Config.GameFixes & 0x4) // Special Fix for Digimon Rumble Arena 2, fixes spinning/hanging on intro-menu.
#define CHECK_VUCLIPFLAGHACK (Config.GameFixes & 0x2) // Special Fix for Persona games, maybe others. It's to do with the VU clip flag (again).
#define CHECK_FPUMULHACK (Config.GameFixes & 0x8) // Special Fix for Tales of Destiny hangs.
//------------ Advanced Options!!! ---------------
#define CHECK_VU_OVERFLOW (Config.vuOptions & 0x1)

View File

@ -113,11 +113,22 @@ namespace OpcodeImpl {
if (_Rd_) cpuRegs.GPR.r[_Rd_].UD[0] = cpuRegs.LO.UD[1];
}
void DIV1() {
if (cpuRegs.GPR.r[_Rt_].SL[0] != 0) {
void DIV1() {
if (cpuRegs.GPR.r[_Rs_].UL[0] == 0x80000000 && cpuRegs.GPR.r[_Rt_].UL[0] == 0xffffffff)
{
cpuRegs.LO.SD[1] = (s32)0x80000000;
cpuRegs.HI.SD[1] = (s32)0x0;
}
else if (cpuRegs.GPR.r[_Rt_].SL[0] != 0)
{
cpuRegs.LO.SD[1] = cpuRegs.GPR.r[_Rs_].SL[0] / cpuRegs.GPR.r[_Rt_].SL[0];
cpuRegs.HI.SD[1] = cpuRegs.GPR.r[_Rs_].SL[0] % cpuRegs.GPR.r[_Rt_].SL[0];
}
else
{
cpuRegs.LO.SD[1] = (cpuRegs.GPR.r[_Rs_].SL[0] < 0) ? 1 : -1;
cpuRegs.HI.SD[1] = cpuRegs.GPR.r[_Rs_].SL[0];
}
}
void DIVU1()
@ -129,6 +140,11 @@ namespace OpcodeImpl {
cpuRegs.LO.SD[1] = (s32)(cpuRegs.GPR.r[_Rs_].UL[0] / cpuRegs.GPR.r[_Rt_].UL[0]);
cpuRegs.HI.SD[1] = (s32)(cpuRegs.GPR.r[_Rs_].UL[0] % cpuRegs.GPR.r[_Rt_].UL[0]);
}
else
{
cpuRegs.LO.SD[1] = -1;
cpuRegs.HI.SD[1] = cpuRegs.GPR.r[_Rs_].SL[0];
}
}
namespace MMI {
@ -187,19 +203,19 @@ void PMFHL() {
case 0x02: // SLW
{
u64 TempU64 = ((u64)cpuRegs.HI.UL[0] << 32) | (u64)cpuRegs.LO.UL[0];
if (TempU64 >= 0x000000007fffffffLL) {
s64 TempS64 = ((u64)cpuRegs.HI.UL[0] << 32) | (u64)cpuRegs.LO.UL[0];
if (TempS64 >= 0x000000007fffffffLL) {
cpuRegs.GPR.r[_Rd_].UD[0] = 0x000000007fffffffLL;
} else if (TempU64 <= 0xffffffff80000000LL) {
} else if (TempS64 <= 0xffffffff80000000LL) {
cpuRegs.GPR.r[_Rd_].UD[0] = 0xffffffff80000000LL;
} else {
cpuRegs.GPR.r[_Rd_].UD[0] = (s64)cpuRegs.LO.SL[0];
}
TempU64 = ((u64)cpuRegs.HI.UL[2] << 32) | (u64)cpuRegs.LO.UL[2];
if (TempU64 >= 0x000000007fffffffLL) {
TempS64 = ((u64)cpuRegs.HI.UL[2] << 32) | (u64)cpuRegs.LO.UL[2];
if (TempS64 >= 0x000000007fffffffLL) {
cpuRegs.GPR.r[_Rd_].UD[1] = 0x000000007fffffffLL;
} else if (TempU64 <= 0xffffffff80000000LL) {
} else if (TempS64 <= 0xffffffff80000000LL) {
cpuRegs.GPR.r[_Rd_].UD[1] = 0xffffffff80000000LL;
} else {
cpuRegs.GPR.r[_Rd_].UD[1] = (s64)cpuRegs.LO.SL[2];
@ -603,7 +619,7 @@ __forceinline void _PADDSB(int n)
if (sTemp16 > 0x7F)
cpuRegs.GPR.r[_Rd_].UC[n] = 0x7F;
else if ((sTemp16 < 0x180) && (sTemp16 >= 0x100))
else if (sTemp16 < (s16)0xff80)
cpuRegs.GPR.r[_Rd_].UC[n] = 0x80;
else
cpuRegs.GPR.r[_Rd_].UC[n] = (s8)sTemp16;
@ -624,7 +640,7 @@ static __forceinline void _PSUBSB( u8 n )
if (sTemp16 >= 0x7F)
cpuRegs.GPR.r[_Rd_].UC[n] = 0x7F;
else if ((sTemp16 < 0x180) && (sTemp16 >= 0x100))
else if (sTemp16 <= (s16)0xff80)
cpuRegs.GPR.r[_Rd_].UC[n] = 0x80;
else
cpuRegs.GPR.r[_Rd_].UC[n] = (s8)sTemp16;
@ -727,7 +743,12 @@ void PPAC5() {
__forceinline void _PABSW(int n)
{
cpuRegs.GPR.r[_Rd_].UL[n] = abs(cpuRegs.GPR.r[_Rt_].SL[n]);
if (cpuRegs.GPR.r[_Rt_].UL[n] == 0x80000000)
cpuRegs.GPR.r[_Rd_].UL[n] = 0x7fffffff; //clamp
else if (cpuRegs.GPR.r[_Rt_].SL[n] < 0)
cpuRegs.GPR.r[_Rd_].UL[n] = - cpuRegs.GPR.r[_Rt_].SL[n];
else
cpuRegs.GPR.r[_Rd_].UL[n] = cpuRegs.GPR.r[_Rt_].SL[n];
}
void PABSW() {
@ -773,7 +794,12 @@ void PADSBH() {
__forceinline void _PABSH(int n)
{
cpuRegs.GPR.r[_Rd_].US[n] = abs(cpuRegs.GPR.r[_Rt_].SS[n]);
if (cpuRegs.GPR.r[_Rt_].US[n] == 0x8000)
cpuRegs.GPR.r[_Rd_].US[n] = 0x7fff; //clamp
else if (cpuRegs.GPR.r[_Rt_].SS[n] < 0)
cpuRegs.GPR.r[_Rd_].US[n] = - cpuRegs.GPR.r[_Rt_].SS[n];
else
cpuRegs.GPR.r[_Rd_].US[n] = cpuRegs.GPR.r[_Rt_].SS[n];
}
void PABSH() {
@ -994,38 +1020,39 @@ void QFSRV() { // JayteeMaster: changed a bit to avoid screw up
GPR_reg Rd;
if (!_Rd_) return;
if (cpuRegs.sa == 0) {
u32 sa_amt = cpuRegs.sa << 3;
if (sa_amt == 0) {
cpuRegs.GPR.r[_Rd_].UD[0] = cpuRegs.GPR.r[_Rt_].UD[0];
cpuRegs.GPR.r[_Rd_].UD[1] = cpuRegs.GPR.r[_Rt_].UD[1];
//saZero++;
//if( saZero >= 388800 )
//Console::WriteLn( "SA Is Zero, Bitch: %d zeros and counting.", params saZero );
} else {
//Console::WriteLn( "SA Properly Valued at: %d (after %d zeros)", params cpuRegs.sa, saZero );
//Console::WriteLn( "SA Properly Valued at: %d (after %d zeros)", params sa_amt, saZero );
//saZero = 0;
if (cpuRegs.sa < 64) {
if (sa_amt < 64) {
/*
cpuRegs.GPR.r[_Rd_].UD[0] = cpuRegs.GPR.r[_Rt_].UD[0] >> cpuRegs.sa;
cpuRegs.GPR.r[_Rd_].UD[1] = cpuRegs.GPR.r[_Rt_].UD[1] >> cpuRegs.sa;
cpuRegs.GPR.r[_Rd_].UD[0]|= cpuRegs.GPR.r[_Rt_].UD[1] << (64 - cpuRegs.sa);
cpuRegs.GPR.r[_Rd_].UD[1]|= cpuRegs.GPR.r[_Rs_].UD[0] << (64 - cpuRegs.sa);
cpuRegs.GPR.r[_Rd_].UD[0] = cpuRegs.GPR.r[_Rt_].UD[0] >> sa_amt;
cpuRegs.GPR.r[_Rd_].UD[1] = cpuRegs.GPR.r[_Rt_].UD[1] >> sa_amt;
cpuRegs.GPR.r[_Rd_].UD[0]|= cpuRegs.GPR.r[_Rt_].UD[1] << (64 - sa_amt);
cpuRegs.GPR.r[_Rd_].UD[1]|= cpuRegs.GPR.r[_Rs_].UD[0] << (64 - sa_amt);
*/
Rd.UD[0] = cpuRegs.GPR.r[_Rt_].UD[0] >> cpuRegs.sa;
Rd.UD[1] = cpuRegs.GPR.r[_Rt_].UD[1] >> cpuRegs.sa;
Rd.UD[0]|= cpuRegs.GPR.r[_Rt_].UD[1] << (64 - cpuRegs.sa);
Rd.UD[1]|= cpuRegs.GPR.r[_Rs_].UD[0] << (64 - cpuRegs.sa);
Rd.UD[0] = cpuRegs.GPR.r[_Rt_].UD[0] >> sa_amt;
Rd.UD[1] = cpuRegs.GPR.r[_Rt_].UD[1] >> sa_amt;
Rd.UD[0]|= cpuRegs.GPR.r[_Rt_].UD[1] << (64 - sa_amt);
Rd.UD[1]|= cpuRegs.GPR.r[_Rs_].UD[0] << (64 - sa_amt);
cpuRegs.GPR.r[_Rd_] = Rd;
} else {
/*
cpuRegs.GPR.r[_Rd_].UD[0] = cpuRegs.GPR.r[_Rt_].UD[1] >> (cpuRegs.sa - 64);
cpuRegs.GPR.r[_Rd_].UD[1] = cpuRegs.GPR.r[_Rs_].UD[0] >> (cpuRegs.sa - 64);
cpuRegs.GPR.r[_Rd_].UD[0]|= cpuRegs.GPR.r[_Rs_].UD[0] << (128 - cpuRegs.sa);
cpuRegs.GPR.r[_Rd_].UD[1]|= cpuRegs.GPR.r[_Rs_].UD[1] << (128 - cpuRegs.sa);
cpuRegs.GPR.r[_Rd_].UD[0] = cpuRegs.GPR.r[_Rt_].UD[1] >> (sa_amt - 64);
cpuRegs.GPR.r[_Rd_].UD[1] = cpuRegs.GPR.r[_Rs_].UD[0] >> (sa_amt - 64);
cpuRegs.GPR.r[_Rd_].UD[0]|= cpuRegs.GPR.r[_Rs_].UD[0] << (128 - sa_amt);
cpuRegs.GPR.r[_Rd_].UD[1]|= cpuRegs.GPR.r[_Rs_].UD[1] << (128 - sa_amt);
*/
Rd.UD[0] = cpuRegs.GPR.r[_Rt_].UD[1] >> (cpuRegs.sa - 64);
Rd.UD[1] = cpuRegs.GPR.r[_Rs_].UD[0] >> (cpuRegs.sa - 64);
Rd.UD[0]|= cpuRegs.GPR.r[_Rs_].UD[0] << (128 - cpuRegs.sa);
Rd.UD[1]|= cpuRegs.GPR.r[_Rs_].UD[1] << (128 - cpuRegs.sa);
Rd.UD[0] = cpuRegs.GPR.r[_Rt_].UD[1] >> (sa_amt - 64);
Rd.UD[1] = cpuRegs.GPR.r[_Rs_].UD[0] >> (sa_amt - 64);
Rd.UD[0]|= cpuRegs.GPR.r[_Rs_].UD[0] << (128 - sa_amt);
Rd.UD[1]|= cpuRegs.GPR.r[_Rs_].UD[1] << (128 - sa_amt);
cpuRegs.GPR.r[_Rd_] = Rd;
}
}
@ -1132,11 +1159,21 @@ void PMULTW() {
__forceinline void _PDIVW(int dd, int ss)
{
if (cpuRegs.GPR.r[_Rt_].UL[ss] != 0)
if (cpuRegs.GPR.r[_Rs_].UL[ss] == 0x80000000 && cpuRegs.GPR.r[_Rt_].UL[ss] == 0xffffffff)
{
cpuRegs.LO.SD[dd] = (s32)0x80000000;
cpuRegs.HI.SD[dd] = (s32)0;
}
else if (cpuRegs.GPR.r[_Rt_].SL[ss] != 0)
{
cpuRegs.LO.SD[dd] = cpuRegs.GPR.r[_Rs_].SL[ss] / cpuRegs.GPR.r[_Rt_].SL[ss];
cpuRegs.HI.SD[dd] = cpuRegs.GPR.r[_Rs_].SL[ss] % cpuRegs.GPR.r[_Rt_].SL[ss];
}
else
{
cpuRegs.LO.SD[dd] = (cpuRegs.GPR.r[_Rs_].SL[ss] < 0) ? 1 : -1;
cpuRegs.HI.SD[dd] = cpuRegs.GPR.r[_Rs_].SL[ss];
}
}
void PDIVW() {
@ -1196,18 +1233,20 @@ void PMADDH() { // JayteeMaster: changed a bit to avoid screw up
// JayteeMaster: changed a bit to avoid screw up
__forceinline void _PHMADH_LO(int dd, int n)
{
s32 temp = (s32)cpuRegs.GPR.r[_Rs_].SS[n+1] * (s32)cpuRegs.GPR.r[_Rt_].SS[n+1] + \
(s32)cpuRegs.GPR.r[_Rs_].SS[n] * (s32)cpuRegs.GPR.r[_Rt_].SS[n];
s32 firsttemp = (s32)cpuRegs.GPR.r[_Rs_].SS[n+1] * (s32)cpuRegs.GPR.r[_Rt_].SS[n+1];
s32 temp = firsttemp + (s32)cpuRegs.GPR.r[_Rs_].SS[n] * (s32)cpuRegs.GPR.r[_Rt_].SS[n];
cpuRegs.LO.UL[dd] = temp;
cpuRegs.LO.UL[dd+1] = firsttemp;
}
__forceinline void _PHMADH_HI(int dd, int n)
{
s32 temp = (s32)cpuRegs.GPR.r[_Rs_].SS[n+1] * (s32)cpuRegs.GPR.r[_Rt_].SS[n+1] + \
(s32)cpuRegs.GPR.r[_Rs_].SS[n] * (s32)cpuRegs.GPR.r[_Rt_].SS[n];
s32 firsttemp = (s32)cpuRegs.GPR.r[_Rs_].SS[n+1] * (s32)cpuRegs.GPR.r[_Rt_].SS[n+1];
s32 temp = firsttemp + (s32)cpuRegs.GPR.r[_Rs_].SS[n] * (s32)cpuRegs.GPR.r[_Rt_].SS[n];
cpuRegs.HI.UL[dd] = temp;
cpuRegs.HI.UL[dd+1] = firsttemp;
}
void PHMADH() { // JayteeMaster: changed a bit to avoid screw up. Also used 0,2,4,6 instead of 0,1,2,3
@ -1279,17 +1318,19 @@ void PMSUBH() { // JayteeMaster: changed a bit to avoid screw up
// JayteeMaster: changed a bit to avoid screw up
__forceinline void _PHMSBH_LO(int dd, int n, int rdd)
{
s32 temp = (s32)cpuRegs.GPR.r[_Rs_].SS[n+1] * (s32)cpuRegs.GPR.r[_Rt_].SS[n+1] - \
(s32)cpuRegs.GPR.r[_Rs_].SS[n] * (s32)cpuRegs.GPR.r[_Rt_].SS[n];
s32 firsttemp = (s32)cpuRegs.GPR.r[_Rs_].SS[n+1] * (s32)cpuRegs.GPR.r[_Rt_].SS[n+1];
s32 temp = firsttemp - (s32)cpuRegs.GPR.r[_Rs_].SS[n] * (s32)cpuRegs.GPR.r[_Rt_].SS[n];
cpuRegs.LO.UL[dd] = temp;
cpuRegs.LO.UL[dd+1] = ~firsttemp;
}
__forceinline void _PHMSBH_HI(int dd, int n, int rdd)
{
s32 temp = (s32)cpuRegs.GPR.r[_Rs_].SS[n+1] * (s32)cpuRegs.GPR.r[_Rt_].SS[n+1] - \
(s32)cpuRegs.GPR.r[_Rs_].SS[n] * (s32)cpuRegs.GPR.r[_Rt_].SS[n];
s32 firsttemp = (s32)cpuRegs.GPR.r[_Rs_].SS[n+1] * (s32)cpuRegs.GPR.r[_Rt_].SS[n+1];
s32 temp = firsttemp - (s32)cpuRegs.GPR.r[_Rs_].SS[n] * (s32)cpuRegs.GPR.r[_Rt_].SS[n];
cpuRegs.HI.UL[dd] = temp;
cpuRegs.HI.UL[dd+1] = ~firsttemp;
}
void PHMSBH() { // JayteeMaster: changed a bit to avoid screw up
@ -1378,13 +1419,24 @@ void PMULTH() { // JayteeMaster: changed a bit to avoid screw up
__forceinline void _PDIVBW(int n)
{
cpuRegs.LO.UL[n] = (s32)(cpuRegs.GPR.r[_Rs_].SL[n] / cpuRegs.GPR.r[_Rt_].SS[0]);
cpuRegs.HI.UL[n] = (s16)(cpuRegs.GPR.r[_Rs_].SL[n] % cpuRegs.GPR.r[_Rt_].SS[0]);
if (cpuRegs.GPR.r[_Rs_].UL[n] == 0x80000000 && cpuRegs.GPR.r[_Rt_].US[0] == 0xffff)
{
cpuRegs.LO.SL[n] = (s32)0x80000000;
cpuRegs.HI.SL[n] = (s32)0x0;
}
else if (cpuRegs.GPR.r[_Rt_].US[0] != 0)
{
cpuRegs.LO.SL[n] = cpuRegs.GPR.r[_Rs_].SL[n] / cpuRegs.GPR.r[_Rt_].SS[0];
cpuRegs.HI.SL[n] = cpuRegs.GPR.r[_Rs_].SL[n] % cpuRegs.GPR.r[_Rt_].SS[0];
}
else
{
cpuRegs.LO.SL[n] = (cpuRegs.GPR.r[_Rs_].SL[n] < 0) ? 1 : -1;
cpuRegs.HI.SL[n] = cpuRegs.GPR.r[_Rs_].SL[n];
}
}
void PDIVBW() {
if (cpuRegs.GPR.r[_Rt_].US[0] == 0) return;
_PDIVBW(0); _PDIVBW(1); _PDIVBW(2); _PDIVBW(3);
}
@ -1489,6 +1541,11 @@ __forceinline void _PDIVUW(int dd, int ss)
cpuRegs.LO.SD[dd] = (s32)(cpuRegs.GPR.r[_Rs_].UL[ss] / cpuRegs.GPR.r[_Rt_].UL[ss]);
cpuRegs.HI.SD[dd] = (s32)(cpuRegs.GPR.r[_Rs_].UL[ss] % cpuRegs.GPR.r[_Rt_].UL[ss]);
}
else
{
cpuRegs.LO.SD[dd] = -1;
cpuRegs.HI.SD[dd] = cpuRegs.GPR.r[_Rs_].SL[ss];
}
}
void PDIVUW() {

View File

@ -247,14 +247,29 @@ void SLTU() { if (!_Rd_) return; cpuRegs.GPR.r[_Rd_].UD[0] = (cpuRegs.GPR.r[_Rs
* Format: OP rs, rt *
*********************************************************/
// Signed division "overflows" on (0x80000000 / -1), here (LO = 0x80000000, HI = 0) is returned by MIPS
// in division by zero on MIPS, it appears that:
// LO gets 1 if rs is negative (and the division is signed) and -1 otherwise.
// HI gets the value of rs.
// Result is stored in HI/LO [no arithmetic exceptions]
void DIV()
{
if (cpuRegs.GPR.r[_Rt_].SL[0] != 0)
if (cpuRegs.GPR.r[_Rs_].UL[0] == 0x80000000 && cpuRegs.GPR.r[_Rt_].UL[0] == 0xffffffff)
{
cpuRegs.LO.SD[0] = (s32)0x80000000;
cpuRegs.HI.SD[0] = (s32)0x0;
}
else if (cpuRegs.GPR.r[_Rt_].SL[0] != 0)
{
cpuRegs.LO.SD[0] = cpuRegs.GPR.r[_Rs_].SL[0] / cpuRegs.GPR.r[_Rt_].SL[0];
cpuRegs.HI.SD[0] = cpuRegs.GPR.r[_Rs_].SL[0] % cpuRegs.GPR.r[_Rt_].SL[0];
}
else
{
cpuRegs.LO.SD[0] = (cpuRegs.GPR.r[_Rs_].SL[0] < 0) ? 1 : -1;
cpuRegs.HI.SD[0] = cpuRegs.GPR.r[_Rs_].SL[0];
}
}
// Result is stored in HI/LO [no arithmetic exceptions]
@ -267,6 +282,11 @@ void DIVU()
cpuRegs.LO.SD[0] = (s32)(cpuRegs.GPR.r[_Rs_].UL[0] / cpuRegs.GPR.r[_Rt_].UL[0]);
cpuRegs.HI.SD[0] = (s32)(cpuRegs.GPR.r[_Rs_].UL[0] % cpuRegs.GPR.r[_Rt_].UL[0]);
}
else
{
cpuRegs.LO.SD[0] = -1;
cpuRegs.HI.SD[0] = cpuRegs.GPR.r[_Rs_].SL[0];
}
}
// Result is written to both HI/LO and to the _Rd_ (Lo only)
@ -858,7 +878,7 @@ void MFSA( void ) {
}
void MTSA( void ) {
cpuRegs.sa = (s32)cpuRegs.GPR.r[_Rs_].SD[0];
cpuRegs.sa = (s32)cpuRegs.GPR.r[_Rs_].SD[0] & 0xf;
}
// SNY supports three basic modes, two which synchronize memory accesses (related
@ -907,11 +927,11 @@ void TLTIU() { if (cpuRegs.GPR.r[_Rs_].UD[0] < (u64)_Imm_) throw R5900Exception
*********************************************************/
void MTSAB() {
cpuRegs.sa = ((cpuRegs.GPR.r[_Rs_].UL[0] & 0xF) ^ (_Imm_ & 0xF)) << 3;
cpuRegs.sa = ((cpuRegs.GPR.r[_Rs_].UL[0] & 0xF) ^ (_Imm_ & 0xF));
}
void MTSAH() {
cpuRegs.sa = ((cpuRegs.GPR.r[_Rs_].UL[0] & 0x7) ^ (_Imm_ & 0x7)) << 4;
cpuRegs.sa = ((cpuRegs.GPR.r[_Rs_].UL[0] & 0x7) ^ (_Imm_ & 0x7)) << 1;
}
} } } // end namespace R5900::Interpreter::OpcodeImpl

View File

@ -525,6 +525,7 @@ BOOL APIENTRY GameFixes(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
case WM_INITDIALOG:
if(Config.GameFixes & 0x1) CheckDlgButton(hDlg, IDC_GAMEFIX2, TRUE);//Tri-Ace fix
if(Config.GameFixes & 0x4) CheckDlgButton(hDlg, IDC_GAMEFIX3, TRUE);//Digimon FPU compare fix
if(Config.GameFixes & 0x2) CheckDlgButton(hDlg, IDC_GAMEFIX4, TRUE);//Persona3/4 fix
if(Config.GameFixes & 0x8) CheckDlgButton(hDlg, IDC_GAMEFIX5, TRUE);//Tales of Destiny fix
return TRUE;
@ -534,6 +535,7 @@ BOOL APIENTRY GameFixes(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
uint newfixes = 0;
newfixes |= IsDlgButtonChecked(hDlg, IDC_GAMEFIX2) ? 0x1 : 0;
newfixes |= IsDlgButtonChecked(hDlg, IDC_GAMEFIX3) ? 0x4 : 0;
newfixes |= IsDlgButtonChecked(hDlg, IDC_GAMEFIX4) ? 0x2 : 0;
newfixes |= IsDlgButtonChecked(hDlg, IDC_GAMEFIX5) ? 0x8 : 0;
EndDialog(hDlg, TRUE);

View File

@ -74,21 +74,23 @@ LANGUAGE LANG_GERMAN, SUBLANG_GERMAN
// Dialog
//
IDD_GAMEFIXES DIALOGEX 0, 0, 279, 118
IDD_GAMEFIXES DIALOGEX 0, 0, 279, 123
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Game Special Fixes"
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
DEFPUSHBUTTON "OK",IDOK,87,89,50,14
PUSHBUTTON "Cancel",IDCANCEL,142,89,50,14
DEFPUSHBUTTON "OK",IDOK,87,96,50,14
PUSHBUTTON "Cancel",IDCANCEL,142,96,50,14
CTEXT "Some games need special settings.\nConfigure them here.",IDC_STATIC,7,7,265,17
GROUPBOX "PCSX2 Gamefixes",IDC_STATIC,7,28,265,83
GROUPBOX "PCSX2 Gamefixes",IDC_STATIC,7,22,265,94
CONTROL "FPU Compare Hack - Special fix for Digimon Rumble Arena 2.",IDC_GAMEFIX3,
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,43,249,10
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,36,249,10
CONTROL "VU Add Hack - Special fix for Tri-Ace games!",IDC_GAMEFIX2,
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,72,252,10
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,65,252,10
CONTROL "VU Clip Hack - Fixes missing ground geometry in Persona.",IDC_GAMEFIX4,
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,79,238,10
CONTROL "FPU Mul Hack - Special fix for Tales of Destiny (possibly other games).",IDC_GAMEFIX5,
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,57,249,10
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,50,249,10
END
@ -106,7 +108,7 @@ BEGIN
RIGHTMARGIN, 272
VERTGUIDE, 14
TOPMARGIN, 7
BOTTOMMARGIN, 111
BOTTOMMARGIN, 116
HORZGUIDE, 103
END
END

View File

@ -1617,23 +1617,29 @@ REC_FUNC_DEL( QFSRV, _Rd_);
PCSX2_ALIGNED16(int s_MaskHighBitD[4]) = { 0x80000000, 0x80000000, 0x80000000, 0x80000000 };
PCSX2_ALIGNED16(int s_MaskHighBitW[4]) = { 0x80008000, 0x80008000, 0x80008000, 0x80008000 };
void recPABSW()
void recPABSW() //needs clamping
{
if( !_Rd_ ) return;
CPU_SSE2_XMMCACHE_START(XMMINFO_READT|XMMINFO_WRITED)
int t0reg = _allocTempXMMreg(XMMT_INT, -1);
SSE2_PCMPEQD_XMM_to_XMM(t0reg, t0reg);
SSE2_PSLLD_I8_to_XMM(t0reg, 31);
SSE2_PCMPEQD_XMM_to_XMM(t0reg, EEREC_T); //0xffffffff if equal to 0x80000000
if( cpucaps.hasSupplementalStreamingSIMD3Extensions ) {
SSSE3_PABSD_XMM_to_XMM(EEREC_D, EEREC_T);
SSSE3_PABSD_XMM_to_XMM(EEREC_D, EEREC_T); //0x80000000 -> 0x80000000
}
else {
int t0reg = _allocTempXMMreg(XMMT_INT, -1);
SSEX_MOVDQA_XMM_to_XMM(t0reg, EEREC_T);
int t1reg = _allocTempXMMreg(XMMT_INT, -1);
SSEX_MOVDQA_XMM_to_XMM(t1reg, EEREC_T);
SSEX_MOVDQA_XMM_to_XMM(EEREC_D, EEREC_T);
SSE2_PSRAD_I8_to_XMM(t0reg, 31);
SSEX_PXOR_XMM_to_XMM(EEREC_D, t0reg);
SSE2_PSUBD_XMM_to_XMM(EEREC_D, t0reg);
_freeXMMreg(t0reg);
SSE2_PSRAD_I8_to_XMM(t1reg, 31);
SSEX_PXOR_XMM_to_XMM(EEREC_D, t1reg);
SSE2_PSUBD_XMM_to_XMM(EEREC_D, t1reg); //0x80000000 -> 0x80000000
_freeXMMreg(t1reg);
}
SSE2_PXOR_XMM_to_XMM(EEREC_D, t0reg); //0x80000000 -> 0x7fffffff
_freeXMMreg(t0reg);
CPU_SSE_XMMCACHE_END
_deleteEEreg(_Rt_, 1);
@ -1645,24 +1651,31 @@ CPU_SSE_XMMCACHE_END
CALLFunc( (uptr)R5900::Interpreter::OpcodeImpl::MMI::PABSW );
}
////////////////////////////////////////////////////
void recPABSH()
void recPABSH()
{
if( !_Rd_ ) return;
CPU_SSE2_XMMCACHE_START(XMMINFO_READT|XMMINFO_WRITED)
int t0reg = _allocTempXMMreg(XMMT_INT, -1);
SSE2_PCMPEQW_XMM_to_XMM(t0reg, t0reg);
SSE2_PSLLW_I8_to_XMM(t0reg, 15);
SSE2_PCMPEQW_XMM_to_XMM(t0reg, EEREC_T); //0xffff if equal to 0x8000
if( cpucaps.hasSupplementalStreamingSIMD3Extensions ) {
SSSE3_PABSW_XMM_to_XMM(EEREC_D, EEREC_T);
SSSE3_PABSW_XMM_to_XMM(EEREC_D, EEREC_T); //0x8000 -> 0x8000
}
else {
int t0reg = _allocTempXMMreg(XMMT_INT, -1);
SSEX_MOVDQA_XMM_to_XMM(t0reg, EEREC_T);
int t1reg = _allocTempXMMreg(XMMT_INT, -1);
SSEX_MOVDQA_XMM_to_XMM(t1reg, EEREC_T);
SSEX_MOVDQA_XMM_to_XMM(EEREC_D, EEREC_T);
SSE2_PSRAW_I8_to_XMM(t0reg, 15);
SSEX_PXOR_XMM_to_XMM(EEREC_D, t0reg);
SSE2_PSUBW_XMM_to_XMM(EEREC_D, t0reg);
_freeXMMreg(t0reg);
SSE2_PSRAW_I8_to_XMM(t1reg, 15);
SSEX_PXOR_XMM_to_XMM(EEREC_D, t1reg);
SSE2_PSUBW_XMM_to_XMM(EEREC_D, t1reg); //0x8000 -> 0x8000
_freeXMMreg(t1reg);
}
SSE2_PXOR_XMM_to_XMM(EEREC_D, t0reg); //0x8000 -> 0x7fff
_freeXMMreg(t0reg);
CPU_SSE_XMMCACHE_END
_deleteEEreg(_Rt_, 1);
@ -1968,7 +1981,7 @@ void recQFSRV()
SSE2_MOVDQA_XMM_to_XMM(EEREC_D, EEREC_T);
MOV32MtoR(EAX, (uptr)&cpuRegs.sa);
SHL32ItoR(EAX, 1); // Multiply SA bytes by 16 bytes (the amount of bytes in QFSRVhelper() macros)
SHL32ItoR(EAX, 4); // Multiply SA bytes by 16 bytes (the amount of bytes in QFSRVhelper() macros)
AND32I8toR(EAX, 0xf0); // This can possibly be removed but keeping it incase theres garbage in SA (cottonvibes)
ADD32ItoEAX((uptr)x86Ptr[0] + 7); // ADD32 = 5 bytes, JMPR = 2 bytes
JMPR(EAX); // Jumps to a QFSRVhelper() case below (a total of 16 different cases)
@ -2402,8 +2415,8 @@ CPU_SSE2_XMMCACHE_START((_Rs_?XMMINFO_READS:0)|(_Rt_?XMMINFO_READT:0)|XMMINFO_WR
// shamt is 5-bit
SSEX_MOVDQA_XMM_to_XMM(t0reg, EEREC_S);
SSE2_PSLLQ_I8_to_XMM(t0reg, 27);
SSE2_PSRLQ_I8_to_XMM(t0reg, 27);
SSE2_PSLLQ_I8_to_XMM(t0reg, 27+32);
SSE2_PSRLQ_I8_to_XMM(t0reg, 27+32);
// EEREC_D[0] <- Rt[0], t1reg[0] <- Rt[2]
SSE_MOVHLPS_XMM_to_XMM(t1reg, EEREC_T);
@ -2470,8 +2483,8 @@ CPU_SSE2_XMMCACHE_START((_Rs_?XMMINFO_READS:0)|(_Rt_?XMMINFO_READT:0)|XMMINFO_WR
// shamt is 5-bit
SSEX_MOVDQA_XMM_to_XMM(t0reg, EEREC_S);
SSE2_PSLLQ_I8_to_XMM(t0reg, 27);
SSE2_PSRLQ_I8_to_XMM(t0reg, 27);
SSE2_PSLLQ_I8_to_XMM(t0reg, 27+32);
SSE2_PSRLQ_I8_to_XMM(t0reg, 27+32);
// EEREC_D[0] <- Rt[0], t1reg[0] <- Rt[2]
SSE_MOVHLPS_XMM_to_XMM(t1reg, EEREC_T);
@ -2619,9 +2632,18 @@ void recPDIVBW()
////////////////////////////////////////////////////
PCSX2_ALIGNED16(int s_mask1[4]) = {~0, 0, ~0, 0};
//upper word of each doubleword in LO and HI is undocumented/undefined
//contains the upper multiplication result (before the addition with the lower multiplication result)
void recPHMADH()
{
CPU_SSE2_XMMCACHE_START((_Rd_?XMMINFO_WRITED:0)|XMMINFO_READS|XMMINFO_READT|XMMINFO_WRITELO|XMMINFO_WRITEHI)
int t0reg = _allocTempXMMreg(XMMT_INT, -1);
SSEX_MOVDQA_XMM_to_XMM(t0reg, EEREC_S);
SSE2_PSRLD_I8_to_XMM(t0reg, 16);
SSE2_PSLLD_I8_to_XMM(t0reg, 16);
SSE2_PMADDWD_XMM_to_XMM(t0reg, EEREC_T);
if( _Rd_ ) {
if( EEREC_D == EEREC_S ) {
SSE2_PMADDWD_XMM_to_XMM(EEREC_D, EEREC_T);
@ -2641,14 +2663,22 @@ CPU_SSE2_XMMCACHE_START((_Rd_?XMMINFO_WRITED:0)|XMMINFO_READS|XMMINFO_READT|XMMI
}
SSEX_MOVDQA_XMM_to_XMM(EEREC_HI, EEREC_LO);
SSE2_PSRLQ_I8_to_XMM(EEREC_HI, 32);
SSE_SHUFPS_XMM_to_XMM(EEREC_LO, t0reg, 0x88);
SSE_SHUFPS_XMM_to_XMM(EEREC_LO, EEREC_LO, 0xd8);
SSE_SHUFPS_XMM_to_XMM(EEREC_HI, t0reg, 0xdd);
SSE_SHUFPS_XMM_to_XMM(EEREC_HI, EEREC_HI, 0xd8);
_freeXMMreg(t0reg);
CPU_SSE_XMMCACHE_END
recCall( Interp::PHMADH, _Rd_ );
}
////////////////////////////////////////////////////
//upper word of each doubleword in LO and HI is undocumented/undefined
//contains the NOT of the upper multiplication result (before the substraction of the lower multiplication result)
void recPMSUBH()
{
CPU_SSE2_XMMCACHE_START((_Rd_?XMMINFO_WRITED:0)|XMMINFO_READS|XMMINFO_READT|XMMINFO_READLO|XMMINFO_READHI|XMMINFO_WRITELO|XMMINFO_WRITEHI)
@ -2710,22 +2740,41 @@ CPU_SSE_XMMCACHE_END
}
////////////////////////////////////////////////////
// rs = ... a1 a0
// rt = ... b1 b0
// rd = ... a1*b1 - a0*b0
// hi = ...
// lo = ... (undefined by doc)NOT(a1*b1), a1*b1 - a0*b0
void recPHMSBH()
{
CPU_SSE2_XMMCACHE_START((_Rd_?XMMINFO_WRITED:0)|XMMINFO_READS|XMMINFO_READT|XMMINFO_WRITELO|XMMINFO_WRITEHI)
int t0reg = _allocTempXMMreg(XMMT_INT, -1);
SSE2_PCMPEQD_XMM_to_XMM(EEREC_LO, EEREC_LO);
SSE2_PSRLD_XMM_to_XMM(EEREC_LO, 16);
SSE2_PSRLD_I8_to_XMM(EEREC_LO, 16);
SSEX_MOVDQA_XMM_to_XMM(EEREC_HI, EEREC_S);
SSE2_PAND_XMM_to_XMM(EEREC_HI, EEREC_LO);
SSE2_PMADDWD_XMM_to_XMM(EEREC_HI, EEREC_T);
SSE2_PSLLD_XMM_to_XMM(EEREC_LO, 16);
SSE2_PSLLD_I8_to_XMM(EEREC_LO, 16);
SSE2_PAND_XMM_to_XMM(EEREC_LO, EEREC_S);
SSE2_PMADDWD_XMM_to_XMM(EEREC_LO, EEREC_T);
SSEX_MOVDQA_XMM_to_XMM(t0reg, EEREC_LO);
SSE2_PSUBD_XMM_to_XMM(EEREC_LO, EEREC_HI);
if( _Rd_ ) SSEX_MOVDQA_XMM_to_XMM(EEREC_D, EEREC_LO);
SSE2_PCMPEQD_XMM_to_XMM(EEREC_HI, EEREC_HI);
SSE2_PXOR_XMM_to_XMM(t0reg, EEREC_HI);
SSEX_MOVDQA_XMM_to_XMM(EEREC_HI, EEREC_LO);
SSE2_PSRLQ_I8_to_XMM(EEREC_HI, 32);
SSE_SHUFPS_XMM_to_XMM(EEREC_LO, t0reg, 0x88);
SSE_SHUFPS_XMM_to_XMM(EEREC_LO, EEREC_LO, 0xd8);
SSE_SHUFPS_XMM_to_XMM(EEREC_HI, t0reg, 0xdd);
SSE_SHUFPS_XMM_to_XMM(EEREC_HI, EEREC_HI, 0xd8);
_freeXMMreg(t0reg);
CPU_SSE_XMMCACHE_END
recCall( Interp::PHMSBH, _Rd_ );
@ -3278,8 +3327,8 @@ CPU_SSE2_XMMCACHE_START((_Rs_?XMMINFO_READS:0)|(_Rt_?XMMINFO_READT:0)|XMMINFO_WR
// shamt is 5-bit
SSEX_MOVDQA_XMM_to_XMM(t0reg, EEREC_S);
SSE2_PSLLQ_I8_to_XMM(t0reg, 27);
SSE2_PSRLQ_I8_to_XMM(t0reg, 27);
SSE2_PSLLQ_I8_to_XMM(t0reg, 27+32);
SSE2_PSRLQ_I8_to_XMM(t0reg, 27+32);
// EEREC_D[0] <- Rt[0], t1reg[0] <- Rt[2]
SSE_MOVHLPS_XMM_to_XMM(t1reg, EEREC_T);

View File

@ -94,10 +94,11 @@ void recMFSA( void )
}
}
// SA is 4-bit and contains the amount of bytes to shift
void recMTSA( void )
{
if( GPR_IS_CONST1(_Rs_) ) {
MOV32ItoM((uptr)&cpuRegs.sa, g_cpuConstRegs[_Rs_].UL[0] );
MOV32ItoM((uptr)&cpuRegs.sa, g_cpuConstRegs[_Rs_].UL[0] & 0xf );
}
else {
int mmreg;
@ -113,19 +114,19 @@ void recMTSA( void )
MOV32MtoR(EAX, (uptr)&cpuRegs.GPR.r[_Rs_].UL[0]);
MOV32RtoM((uptr)&cpuRegs.sa, EAX);
}
AND32ItoM((uptr)&cpuRegs.sa, 0xf);
}
}
void recMTSAB( void )
{
if( GPR_IS_CONST1(_Rs_) ) {
MOV32ItoM((uptr)&cpuRegs.sa, ((g_cpuConstRegs[_Rs_].UL[0] & 0xF) ^ (_Imm_ & 0xF)) << 3);
MOV32ItoM((uptr)&cpuRegs.sa, ((g_cpuConstRegs[_Rs_].UL[0] & 0xF) ^ (_Imm_ & 0xF)) );
}
else {
_eeMoveGPRtoR(EAX, _Rs_);
AND32ItoR(EAX, 0xF);
XOR32ItoR(EAX, _Imm_&0xf);
SHL32ItoR(EAX, 3);
MOV32RtoM((uptr)&cpuRegs.sa, EAX);
}
}
@ -133,13 +134,13 @@ void recMTSAB( void )
void recMTSAH( void )
{
if( GPR_IS_CONST1(_Rs_) ) {
MOV32ItoM((uptr)&cpuRegs.sa, ((g_cpuConstRegs[_Rs_].UL[0] & 0x7) ^ (_Imm_ & 0x7)) << 4);
MOV32ItoM((uptr)&cpuRegs.sa, ((g_cpuConstRegs[_Rs_].UL[0] & 0x7) ^ (_Imm_ & 0x7)) << 1);
}
else {
_eeMoveGPRtoR(EAX, _Rs_);
AND32ItoR(EAX, 0x7);
XOR32ItoR(EAX, _Imm_&0x7);
SHL32ItoR(EAX, 4);
SHL32ItoR(EAX, 1);
MOV32RtoM((uptr)&cpuRegs.sa, EAX);
}
}

View File

@ -3000,7 +3000,7 @@ void VuInstruction::Recompile(list<VuInstruction>::iterator& itinst, u32 vuxyz)
if( type & INST_CLIP_WRITE ) {
if( nParentPc < s_pCurBlock->startpc || nParentPc >= (int)pc ) {
if( pparentinst != NULL ) {
if( !CHECK_VUCLIPFLAGHACK && pparentinst != NULL ) {
if( nParentCheckForExecution >= 0 ) {
if( pparentinst->pClipWrite == 0 )

View File

@ -595,14 +595,31 @@ void recMULTU1_constt(int info)
EERECOMPILE_CODE0(MULTU1, XMMINFO_READS|XMMINFO_READT|(_Rd_?XMMINFO_WRITED:0));
//// DIV
void recDIVconst(int upper)
{
s32 quot, rem;
if (g_cpuConstRegs[_Rs_].UL[0] == 0x80000000 && g_cpuConstRegs[_Rt_].SL[0] == -1)
{
quot = (s32)0x80000000;
rem = 0;
}
else if (g_cpuConstRegs[_Rt_].SL[0] != 0)
{
quot = g_cpuConstRegs[_Rs_].SL[0] / g_cpuConstRegs[_Rt_].SL[0];
rem = g_cpuConstRegs[_Rs_].SL[0] % g_cpuConstRegs[_Rt_].SL[0];
}
else
{
quot = (g_cpuConstRegs[_Rs_].SL[0] < 0) ? 1 : -1;
rem = g_cpuConstRegs[_Rs_].SL[0];
}
recWritebackConstHILO((u64)quot|((u64)rem<<32), 0, upper);
}
void recDIV_const()
{
if (g_cpuConstRegs[_Rt_].SL[0] != 0) {
s32 quot = g_cpuConstRegs[_Rs_].SL[0] / g_cpuConstRegs[_Rt_].SL[0];
s32 rem = g_cpuConstRegs[_Rs_].SL[0] % g_cpuConstRegs[_Rt_].SL[0];
recWritebackConstHILO((u64)quot|((u64)rem<<32), 0, 0);
}
recDIVconst(0);
}
void recDIVsuper(int info, int sign, int upper, int process)
@ -610,24 +627,46 @@ void recDIVsuper(int info, int sign, int upper, int process)
EEINST_SETSIGNEXT(_Rs_);
EEINST_SETSIGNEXT(_Rt_);
if( process & PROCESS_CONSTT ) {
if( !g_cpuConstRegs[_Rt_].UL[0] )
return;
if( process & PROCESS_CONSTT )
MOV32ItoR( ECX, g_cpuConstRegs[_Rt_].UL[0] );
}
else {
else
MOV32MtoR( ECX, (int)&cpuRegs.GPR.r[ _Rt_ ].UL[ 0 ] );
OR32RtoR( ECX, ECX );
j8Ptr[ 0 ] = JE8( 0 );
}
if( process & PROCESS_CONSTS )
MOV32ItoR( EAX, g_cpuConstRegs[_Rs_].UL[0] );
else {
else
MOV32MtoR( EAX, (int)&cpuRegs.GPR.r[ _Rs_ ].UL[ 0 ] );
u8 *end1;
if (sign) //test for overflow (x86 will just throw an exception)
{
CMP32ItoR( EAX, 0x80000000 );
u8 *cont1 = JNE8(0);
CMP32ItoR( ECX, 0xffffffff );
u8 *cont2 = JNE8(0);
//overflow case:
XOR32RtoR( EDX, EDX ); //EAX remains 0x80000000
end1 = JMP8(0);
x86SetJ8(cont1);
x86SetJ8(cont2);
}
CMP32ItoR( ECX, 0 );
u8 *cont3 = JNE8(0);
//divide by zero
MOV32RtoR( EDX, EAX );
if (sign) //set EAX to (EAX < 0)?1:-1
{
SAR32ItoR( EAX, 31 ); //(EAX < 0)?-1:0
SHL32ItoR( EAX, 1 ); //(EAX < 0)?-2:0
NOT32R( EAX ); //(EAX < 0)?1:-1
}
else
MOV32ItoR( EAX, 0xffffffff );
u8 *end2 = JMP8(0);
x86SetJ8(cont3);
if( sign ) {
CDQ();
IDIV32R( ECX );
@ -636,7 +675,9 @@ void recDIVsuper(int info, int sign, int upper, int process)
XOR32RtoR( EDX, EDX );
DIV32R( ECX );
}
if( !(process & PROCESS_CONSTT) ) x86SetJ8( j8Ptr[ 0 ] );
if (sign) x86SetJ8( end1 );
x86SetJ8( end2 );
// need to execute regardless of bad divide
recWritebackHILO(info, 0, upper);
@ -660,14 +701,25 @@ void recDIV_constt(int info)
EERECOMPILE_CODE0(DIV, XMMINFO_READS|XMMINFO_READT|XMMINFO_WRITELO|XMMINFO_WRITEHI);
//// DIVU
void recDIVUconst(int upper)
{
u32 quot, rem;
if (g_cpuConstRegs[_Rt_].UL[0] != 0) {
quot = g_cpuConstRegs[_Rs_].UL[0] / g_cpuConstRegs[_Rt_].UL[0];
rem = g_cpuConstRegs[_Rs_].UL[0] % g_cpuConstRegs[_Rt_].UL[0];
}
else
{
quot = 0xffffffff;
rem = g_cpuConstRegs[_Rs_].UL[0];
}
recWritebackConstHILO((u64)quot|((u64)rem<<32), 0, upper);
}
void recDIVU_const()
{
if (g_cpuConstRegs[_Rt_].UL[0] != 0) {
u32 quot = g_cpuConstRegs[_Rs_].UL[0] / g_cpuConstRegs[_Rt_].UL[0];
u32 rem = g_cpuConstRegs[_Rs_].UL[0] % g_cpuConstRegs[_Rt_].UL[0];
recWritebackConstHILO((u64)quot|((u64)rem<<32), 0, 0);
}
recDIVUconst(0);
}
void recDIVU_(int info)
@ -689,12 +741,7 @@ EERECOMPILE_CODE0(DIVU, XMMINFO_READS|XMMINFO_READT|XMMINFO_WRITELO|XMMINFO_WRIT
void recDIV1_const()
{
if (g_cpuConstRegs[_Rt_].SL[0] != 0) {
s32 quot = g_cpuConstRegs[_Rs_].SL[0] / g_cpuConstRegs[_Rt_].SL[0];
s32 rem = g_cpuConstRegs[_Rs_].SL[0] % g_cpuConstRegs[_Rt_].SL[0];
recWritebackConstHILO((u64)quot|((u64)rem<<32), 0, 1);
}
recDIVconst(1);
}
void recDIV1_(int info)
@ -716,12 +763,7 @@ EERECOMPILE_CODE0(DIV1, XMMINFO_READS|XMMINFO_READT);
void recDIVU1_const()
{
if (g_cpuConstRegs[_Rt_].UL[0] != 0) {
u32 quot = g_cpuConstRegs[_Rs_].UL[0] / g_cpuConstRegs[_Rt_].UL[0];
u32 rem = g_cpuConstRegs[_Rs_].UL[0] % g_cpuConstRegs[_Rt_].UL[0];
recWritebackConstHILO((u64)quot|((u64)rem<<32), 0, 1);
}
recDIVUconst(1);
}
void recDIVU1_(int info)