mirror of https://github.com/PCSX2/pcsx2.git
microVU: Consolidate I-bit hacks in to one generic one
This commit is contained in:
parent
4116aed738
commit
973ebd153d
|
@ -12684,7 +12684,7 @@ SLES-53439:
|
|||
name: "Crash Tag Team Racing"
|
||||
region: "PAL-M6"
|
||||
gameFixes:
|
||||
- CrashTagTeamRacingIbitHack # Fixes constant recompilation problems.
|
||||
- IbitHack # Fixes constant recompilation problems.
|
||||
SLES-53441:
|
||||
name: "Heroes of the Pacific"
|
||||
region: "PAL-M5"
|
||||
|
@ -14329,17 +14329,17 @@ SLES-54182:
|
|||
name: "Scarface - The World is Yours"
|
||||
region: "PAL-M4"
|
||||
gameFixes:
|
||||
- ScarfaceIbitHack
|
||||
- IbitHack
|
||||
SLES-54183:
|
||||
name: "Scarface - The World is Yours"
|
||||
region: "PAL-G"
|
||||
gameFixes:
|
||||
- ScarfaceIbitHack
|
||||
- IbitHack
|
||||
SLES-54184:
|
||||
name: "Scarface - The World is Yours"
|
||||
region: "PAL-R"
|
||||
gameFixes:
|
||||
- ScarfaceIbitHack
|
||||
- IbitHack
|
||||
SLES-54185:
|
||||
name: "Dirge of Cerberus - Final Fantasy VII"
|
||||
region: "PAL-M5"
|
||||
|
@ -14509,7 +14509,7 @@ SLES-54271:
|
|||
name: "Scarface - The World is Yours"
|
||||
region: "PAL-E"
|
||||
gameFixes:
|
||||
- ScarfaceIbitHack
|
||||
- IbitHack
|
||||
SLES-54305:
|
||||
name: "Demon Chaos"
|
||||
region: "PAL-M5"
|
||||
|
@ -15040,7 +15040,7 @@ SLES-54534:
|
|||
name: "Scarface - The World is Yours [Collector's Edition]"
|
||||
region: "PAL-E"
|
||||
gameFixes:
|
||||
- ScarfaceIbitHack
|
||||
- IbitHack
|
||||
SLES-54536:
|
||||
name: "Big Idea's VeggieTales - LarryBoy and the Bad Apple"
|
||||
region: "PAL-I"
|
||||
|
@ -35827,7 +35827,7 @@ SLUS-21111:
|
|||
region: "NTSC-U"
|
||||
compat: 5
|
||||
gameFixes:
|
||||
- ScarfaceIbitHack
|
||||
- IbitHack
|
||||
SLUS-21112:
|
||||
name: "L.A. Rush"
|
||||
region: "NTSC-U"
|
||||
|
@ -36162,7 +36162,7 @@ SLUS-21191:
|
|||
region: "NTSC-U"
|
||||
compat: 5
|
||||
gameFixes:
|
||||
- CrashTagTeamRacingIbitHack # Fixes constant recompilation problems.
|
||||
- IbitHack # Fixes constant recompilation problems.
|
||||
SLUS-21192:
|
||||
name: "Cabela's Outdoor Adventures 2006"
|
||||
region: "NTSC-U"
|
||||
|
@ -37576,7 +37576,7 @@ SLUS-21492:
|
|||
region: "NTSC-U"
|
||||
compat: 5
|
||||
gameFixes:
|
||||
- ScarfaceIbitHack
|
||||
- IbitHack
|
||||
SLUS-21493:
|
||||
name: "Need for Speed - Carbon"
|
||||
region: "NTSC-U"
|
||||
|
|
|
@ -40,8 +40,7 @@ enum GamefixId
|
|||
Fix_VIF1Stall,
|
||||
Fix_GIFFIFO,
|
||||
Fix_GoemonTlbMiss,
|
||||
Fix_ScarfaceIbit,
|
||||
Fix_CrashTagTeamIbit,
|
||||
Fix_Ibit,
|
||||
Fix_VU0Kickstart,
|
||||
|
||||
GamefixId_COUNT
|
||||
|
@ -350,8 +349,7 @@ struct Pcsx2Config
|
|||
VIF1StallHack : 1, // Like above, processes FIFO data before the stall is allowed (to make sure data goes over).
|
||||
GIFFIFOHack : 1, // Enabled the GIF FIFO (more correct but slower)
|
||||
GoemonTlbHack : 1, // Gomeon tlb miss hack. The game need to access unmapped virtual address. Instead to handle it as exception, tlb are preloaded at startup
|
||||
ScarfaceIbit : 1, // Scarface I bit hack. Needed to stop constant VU recompilation
|
||||
CrashTagTeamRacingIbit : 1, // Crash Tag Team Racing I bit hack. Needed to stop constant VU recompilation
|
||||
IbitHack : 1, // I bit hack. Needed to stop constant VU recompilation in some games
|
||||
VU0KickstartHack : 1; // Speed up VU0 at start of program to avoid some VU1 sync issues
|
||||
BITFIELD_END
|
||||
|
||||
|
|
|
@ -285,8 +285,7 @@ const wxChar *const tbl_GamefixNames[] =
|
|||
L"VIF1Stall",
|
||||
L"GIFFIFO",
|
||||
L"GoemonTlb",
|
||||
L"ScarfaceIbit",
|
||||
L"CrashTagTeamRacingIbit",
|
||||
L"Ibit",
|
||||
L"VU0Kickstart"
|
||||
};
|
||||
|
||||
|
@ -347,8 +346,7 @@ void Pcsx2Config::GamefixOptions::Set( GamefixId id, bool enabled )
|
|||
case Fix_VIF1Stall: VIF1StallHack = enabled; break;
|
||||
case Fix_GIFFIFO: GIFFIFOHack = enabled; break;
|
||||
case Fix_GoemonTlbMiss: GoemonTlbHack = enabled; break;
|
||||
case Fix_ScarfaceIbit: ScarfaceIbit = enabled; break;
|
||||
case Fix_CrashTagTeamIbit: CrashTagTeamRacingIbit = enabled; break;
|
||||
case Fix_Ibit: IbitHack = enabled; break;
|
||||
case Fix_VU0Kickstart: VU0KickstartHack = enabled; break;
|
||||
jNO_DEFAULT;
|
||||
}
|
||||
|
@ -372,8 +370,7 @@ bool Pcsx2Config::GamefixOptions::Get( GamefixId id ) const
|
|||
case Fix_VIF1Stall: return VIF1StallHack;
|
||||
case Fix_GIFFIFO: return GIFFIFOHack;
|
||||
case Fix_GoemonTlbMiss: return GoemonTlbHack;
|
||||
case Fix_ScarfaceIbit: return ScarfaceIbit;
|
||||
case Fix_CrashTagTeamIbit: return CrashTagTeamRacingIbit;
|
||||
case Fix_Ibit: return IbitHack;
|
||||
case Fix_VU0Kickstart: return VU0KickstartHack;
|
||||
jNO_DEFAULT;
|
||||
}
|
||||
|
@ -397,8 +394,7 @@ void Pcsx2Config::GamefixOptions::LoadSave( IniInterface& ini )
|
|||
IniBitBool( VIF1StallHack );
|
||||
IniBitBool( GIFFIFOHack );
|
||||
IniBitBool( GoemonTlbHack );
|
||||
IniBitBool( ScarfaceIbit );
|
||||
IniBitBool( CrashTagTeamRacingIbit );
|
||||
IniBitBool( IbitHack );
|
||||
IniBitBool( VU0KickstartHack );
|
||||
}
|
||||
|
||||
|
|
|
@ -93,11 +93,7 @@ Panels::GameFixesPanel::GameFixesPanel( wxWindow* parent )
|
|||
wxEmptyString
|
||||
},
|
||||
{
|
||||
_("VU I bit Hack avoid constant recompilation (Scarface The World Is Yours)"),
|
||||
wxEmptyString
|
||||
},
|
||||
{
|
||||
_("VU I bit Hack avoid constant recompilation (Crash Tag Team Racing)"),
|
||||
_("VU I bit Hack avoid constant recompilation in some games (Scarface The World Is Yours, Crash Tag Team Racing)"),
|
||||
wxEmptyString
|
||||
},
|
||||
{
|
||||
|
|
|
@ -250,7 +250,7 @@ __fi bool mVUcmpProg(microVU& mVU, microProgram& prog, const bool cmpWholeProg)
|
|||
for (const auto& range : *prog.ranges) {
|
||||
auto cmpOffset = [&](void* x) { return (u8*)x + range.start; };
|
||||
if ((range.start < 0) || (range.end < 0)) { DevCon.Error("microVU%d: Negative Range![%d][%d]", mVU.index, range.start, range.end); }
|
||||
if (memcmp_mmx(cmpOffset(prog.data), cmpOffset(mVU.regs().Micro), ((range.end+8) - range.start))) {
|
||||
if (memcmp_mmx(cmpOffset(prog.data), cmpOffset(mVU.regs().Micro), (range.end - range.start))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -271,25 +271,7 @@ _mVUt __fi void* mVUsearchProg(u32 startPC, uptr pState) {
|
|||
std::deque<microProgram*>::iterator it(list->begin());
|
||||
for ( ; it != list->end(); ++it) {
|
||||
bool b = mVUcmpProg(mVU, *it[0], 0);
|
||||
if (EmuConfig.Gamefixes.ScarfaceIbit) {
|
||||
if (isVU1 && ((((u32*)mVU.regs().Micro)[startPC / 4 + 1]) == 0x80200118) &&
|
||||
((((u32*)mVU.regs().Micro)[startPC / 4 + 3]) == 0x81000062)) {
|
||||
b = true;
|
||||
mVU.prog.cleared = 0;
|
||||
mVU.prog.cur = it[0];
|
||||
mVU.prog.isSame = 1;
|
||||
}
|
||||
} else if (EmuConfig.Gamefixes.CrashTagTeamRacingIbit) {
|
||||
// Crash tag team tends to make changes to the I register settings in the addresses 0x2bd0 - 0x3ff8
|
||||
// so detect when the code is only changed in this region and don't recompile. Use the same Scarface hack
|
||||
// to access the new I regsiter settings (Look at doIbit() in microVU_Compile.inl
|
||||
if (isVU1 && (memcmp_mmx((u8 *)(it[0]->data), (u8 *)(mVU.regs().Micro), 0x2bd0) == 0)) {
|
||||
b = true;
|
||||
mVU.prog.cleared = 0;
|
||||
mVU.prog.cur = it[0];
|
||||
mVU.prog.isSame = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (b) {
|
||||
quick.block = it[0]->block[startPC/8];
|
||||
quick.prog = it[0];
|
||||
|
|
|
@ -44,19 +44,23 @@ __fi void mVUcheckIsSame(mV) {
|
|||
// Sets up microProgram PC ranges based on whats been recompiled
|
||||
void mVUsetupRange(microVU& mVU, s32 pc, bool isStartPC) {
|
||||
std::deque<microRange>*& ranges = mVUcurProg.ranges;
|
||||
pc &= mVU.microMemSize - 8;
|
||||
|
||||
pxAssertDev(pc <= mVU.microMemSize, pxsFmt("microVU%d: PC outside of VU memory PC=0x%04x", mVU.index, pc));
|
||||
if (isStartPC) { // Check if startPC is already within a block we've recompiled
|
||||
std::deque<microRange>::const_iterator it(ranges->begin());
|
||||
for ( ; it != ranges->end(); ++it) {
|
||||
if ((pc >= it[0].start) && (pc <= it[0].end)) {
|
||||
if (it[0].start != it[0].end)
|
||||
return; // Last case makes sure its not a 1-opcode EvilBlock
|
||||
{
|
||||
microRange mRange = { it[0].start, it[0].end };
|
||||
ranges->erase(it);
|
||||
ranges->push_front(mRange);
|
||||
return; // new start PC is inside the range of another range
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (mVUrange.end != -1) {
|
||||
// Above case was true
|
||||
else if (mVUrange.end >= pc) {
|
||||
// existing range covers more area than current PC so no need to process it
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -75,23 +79,22 @@ void mVUsetupRange(microVU& mVU, s32 pc, bool isStartPC) {
|
|||
std::deque<microRange>::iterator it(ranges->begin());
|
||||
for (++it; it != ranges->end(); ++it) {
|
||||
if((it[0].start >= rStart) && (it[0].start <= rEnd)) { // Starts after this prog but starts before the end of current prog
|
||||
it[0].end = std::max(it[0].end, rEnd); // Extend the end of this prog to match this program
|
||||
it[0].start = std::min(it[0].start, rStart); // Choose the earlier start
|
||||
mergedRange = true;
|
||||
}
|
||||
// Make sure we check both as the start on the other one may be later, we don't want to delete that
|
||||
if ((it[0].end >= rStart) && (it[0].end <= rEnd)) { // Ends after this prog starts but ends before this one ends
|
||||
it[0].start = std::min(it[0].start, rStart); // Choose the earlier start
|
||||
it[0].end = std::max(it[0].end, rEnd); // Extend the end of this prog to match this program
|
||||
mergedRange = true;
|
||||
}
|
||||
}
|
||||
if (mergedRange) {
|
||||
//DevCon.WriteLn(Color_Green, "microVU%d: Prog Range Merging", mVU.index);
|
||||
ranges->erase(ranges->begin());
|
||||
}
|
||||
}
|
||||
else {
|
||||
DevCon.WriteLn(Color_Green, "microVU%d: Prog Range Wrap [%04x] [%d]", mVU.index, mVUrange.start, mVUrange.end);
|
||||
mVUrange.end = mVU.microMemSize;
|
||||
DevCon.WriteLn(Color_Green, "microVU%d: Prog Range Wrap [%04x] [%d]", mVU.index, mVUrange.start, mVUrange.end);
|
||||
microRange mRange = {0, pc};
|
||||
ranges->push_front(mRange);
|
||||
}
|
||||
|
@ -109,7 +112,7 @@ void doIbit(mV) {
|
|||
if (mVUup.iBit) {
|
||||
incPC(-1);
|
||||
mVU.regAlloc->clearRegVF(33);
|
||||
if (EmuConfig.Gamefixes.ScarfaceIbit || EmuConfig.Gamefixes.CrashTagTeamRacingIbit) {
|
||||
if (EmuConfig.Gamefixes.IbitHack) {
|
||||
xMOV(gprT1, ptr32[&curI]);
|
||||
xMOV(ptr32[&mVU.getVI(REG_I)], gprT1);
|
||||
}
|
||||
|
@ -580,6 +583,11 @@ void* mVUcompile(microVU& mVU, u32 startPC, uptr pState)
|
|||
if (curI & _Ibit_) {
|
||||
mVUlow.isNOP = true;
|
||||
mVUup.iBit = true;
|
||||
if (EmuConfig.Gamefixes.IbitHack) {
|
||||
mVUsetupRange(mVU, xPC, false);
|
||||
if (branch < 2)
|
||||
mVUsetupRange(mVU, xPC+8, true); // Ideally we'd do +4 but the mmx compare only works in 64bits, this should be fine
|
||||
}
|
||||
}
|
||||
else {
|
||||
incPC(-1);
|
||||
|
@ -675,8 +683,8 @@ void* mVUcompile(microVU& mVU, u32 startPC, uptr pState)
|
|||
for (size_t i = 0; i < (sizeof(microRegInfo) - 4) / 4; i++, lpS++, cpS++) {
|
||||
xMOV(ptr32[lpS], cpS[0]);
|
||||
}
|
||||
mVUsetupRange(mVU, xPC, false);
|
||||
incPC(2);
|
||||
mVUsetupRange(mVU, xPC, false);
|
||||
mVUendProgram(mVU, &mFC, 0);
|
||||
normBranchCompile(mVU, xPC);
|
||||
incPC(-2);
|
||||
|
@ -689,7 +697,7 @@ void* mVUcompile(microVU& mVU, u32 startPC, uptr pState)
|
|||
}
|
||||
|
||||
if (isEvilBlock) {
|
||||
mVUsetupRange(mVU, xPC, false);
|
||||
mVUsetupRange(mVU, xPC+8, false);
|
||||
normJumpCompile(mVU, mFC, true);
|
||||
goto perf_and_return;
|
||||
}
|
||||
|
@ -697,15 +705,16 @@ void* mVUcompile(microVU& mVU, u32 startPC, uptr pState)
|
|||
// Handle range wrapping
|
||||
if ((xPC + 8) == mVU.microMemSize)
|
||||
{
|
||||
mVUsetupRange(mVU, xPC, false);
|
||||
mVUsetupRange(mVU, xPC+8, false);
|
||||
mVUsetupRange(mVU, 0, 1);
|
||||
}
|
||||
incPC(1);
|
||||
}
|
||||
else {
|
||||
incPC(1);
|
||||
mVUsetupRange(mVU, xPC, false);
|
||||
mVUdebugPrintBlocks(mVU, true);
|
||||
incPC(-3); // Go back to branch opcode
|
||||
incPC(-4); // Go back to branch opcode
|
||||
|
||||
switch (mVUlow.branch) {
|
||||
case 1: // B/BAL
|
||||
|
@ -742,7 +751,7 @@ void* mVUcompile(microVU& mVU, u32 startPC, uptr pState)
|
|||
}
|
||||
|
||||
// E-bit End
|
||||
mVUsetupRange(mVU, xPC - 8, false);
|
||||
mVUsetupRange(mVU, xPC, false);
|
||||
mVUendProgram(mVU, &mFC, 1);
|
||||
|
||||
perf_and_return:
|
||||
|
|
Loading…
Reference in New Issue