VU: Rework VUKickstart in to VUSync, swap behaviour

This commit is contained in:
refractionpcsx2 2022-02-27 21:58:42 +00:00
parent 6dc5087cbd
commit e833a67bb7
10 changed files with 40 additions and 390 deletions

View File

@ -32,7 +32,7 @@ allowed_game_fixes = [
"VIF1StallHack",
"GIFFIFOHack",
"GoemonTlbHack",
"VUKickstartHack",
"VUSyncHack",
"IbitHack",
"VUOverflowHack",
]

File diff suppressed because it is too large Load Diff

View File

@ -42,7 +42,7 @@ enum GamefixId
Fix_VIF1Stall,
Fix_VuAddSub,
Fix_Ibit,
Fix_VUKickstart,
Fix_VUSync,
Fix_VUOverflow,
Fix_XGKick,
@ -726,7 +726,7 @@ struct Pcsx2Config
VIF1StallHack : 1, // Like above, processes FIFO data before the stall is allowed (to make sure data goes over).
VuAddSubHack : 1, // Tri-ace games, they use an encryption algorithm that requires VU ADDI opcode to be bit-accurate.
IbitHack : 1, // I bit hack. Needed to stop constant VU recompilation in some games
VUKickstartHack : 1, // Gives new VU programs a slight head start and runs VU's ahead of EE to avoid VU register reading/writing issues
VUSyncHack : 1, // Makes microVU run behind the EE to avoid VU register reading/writing sync issues. Useful for M-Bit games
VUOverflowHack : 1, // Tries to simulate overflow flag checks (not really possible on x86 without soft floats)
XgKickHack : 1; // Erementar Gerad, adds more delay to VU XGkick instructions. Corrects the color of some graphics, but breaks Tri-ace games and others.
BITFIELD_END

View File

@ -38,7 +38,7 @@ SERIAL-12345: # !required! Serial number for the game, this is how games are loo
- GIFFIFOHack
- GoemonTlbHack
- IbitHack
- VUKickstartHack
- VSyncHack
- VUOverflowHack
# The value of the speedhacks is assumed to be an integer,
# but at the time of writing speedhacks are effectively booleans (0/1)
@ -169,8 +169,8 @@ These values are case-sensitive so take care. If you incorrectly specify a Game
* `IbitHack`
* VU I bit Hack avoid constant recompilation in some games (Scarface The World Is Yours, Crash Tag Team Racing).
* `VUKickstartHack`
* Let the VU's both run ahead of the EE to fix some timing issues.
* `VUSyncHack`
* Make the VU's run behind/in sync with the EE to fix some timing issues.
* `VUOverflowHack`
* VU Overflow hack to check for possible float overflows (Superman Returns).

View File

@ -743,7 +743,7 @@ static const char* const tbl_GamefixNames[] =
"VIF1Stall",
"VuAddSub",
"Ibit",
"VUKickstart",
"VUSync",
"VUOverflow",
"XGKick"};
@ -835,8 +835,8 @@ void Pcsx2Config::GamefixOptions::Set(GamefixId id, bool enabled)
case Fix_Ibit:
IbitHack = enabled;
break;
case Fix_VUKickstart:
VUKickstartHack = enabled;
case Fix_VUSync:
VUSyncHack = enabled;
break;
case Fix_VUOverflow:
VUOverflowHack = enabled;
@ -878,8 +878,8 @@ bool Pcsx2Config::GamefixOptions::Get(GamefixId id) const
return GoemonTlbHack;
case Fix_Ibit:
return IbitHack;
case Fix_VUKickstart:
return VUKickstartHack;
case Fix_VUSync:
return VUSyncHack;
case Fix_VUOverflow:
return VUOverflowHack;
jNO_DEFAULT;
@ -905,7 +905,7 @@ void Pcsx2Config::GamefixOptions::LoadSave(SettingsWrapper& wrap)
SettingsWrapBitBool(GIFFIFOHack);
SettingsWrapBitBool(GoemonTlbHack);
SettingsWrapBitBool(IbitHack);
SettingsWrapBitBool(VUKickstartHack);
SettingsWrapBitBool(VUSyncHack);
SettingsWrapBitBool(VUOverflowHack);
}

View File

@ -38,7 +38,6 @@ void BaseVUmicroCPU::ExecuteBlock(bool startUp)
{
const u32& stat = VU0.VI[REG_VPU_STAT].UL;
const int test = m_Idx ? 0x100 : 1;
const int s = EmuConfig.Gamefixes.VUKickstartHack ? 16 : 0; // Kick Start Cycles (Jak needs at least 4 due to writing values after they're read
if (m_Idx && THREAD_VU1)
{
@ -46,7 +45,6 @@ void BaseVUmicroCPU::ExecuteBlock(bool startUp)
return;
}
if (!(stat & test))
{
// VU currently flushes XGKICK on VU1 end so no need for this, yet
@ -57,26 +55,17 @@ void BaseVUmicroCPU::ExecuteBlock(bool startUp)
return;
}
if (startUp) // Start Executing a microprogram (When kickstarted)
if (startUp)
{
Execute(s); // Kick start VU
Execute(CalculateMinRunCycles(0, false));
}
else // Continue Executing
{
u32 cycle = m_Idx ? VU1.cycle : VU0.cycle;
s32 delta = (s32)(u32)(cpuRegs.cycle - cycle);
s32 nextblockcycles = m_Idx ? VU1.nextBlockCycles : VU0.nextBlockCycles;
if (EmuConfig.Gamefixes.VUKickstartHack)
{
if (delta > 0) // When kickstarting we just need 1 cycle for run ahead
Execute(CalculateMinRunCycles(delta, false));
}
else
{
if (delta >= nextblockcycles && delta > 0) // When running behind, make sure we have enough cycles passed for the block to run
Execute(CalculateMinRunCycles(delta, false));
}
if (delta > 0)
Execute(CalculateMinRunCycles(delta, false));
}
}
@ -87,9 +76,8 @@ void BaseVUmicroCPU::ExecuteBlock(bool startUp)
void BaseVUmicroCPU::ExecuteBlockJIT(BaseVUmicroCPU* cpu, bool interlocked)
{
const u32& stat = VU0.VI[REG_VPU_STAT].UL;
const int test = 1;
constexpr int test = 1;
//DevCon.Warning("Was set %d cycles ago", cpuRegs.cycle - setcycle);
if (stat & test)
{ // VU is running
s32 delta = (s32)(u32)(cpuRegs.cycle - VU0.cycle);

View File

@ -93,7 +93,7 @@ Panels::GameFixesPanel::GameFixesPanel( wxWindow* parent )
wxEmptyString
},
{
_("VU Kickstart (Run ahead) to avoid sync problems when reading or writing VU registers"),
_("VU Sync (Run behind) to avoid sync problems when reading or writing VU registers"),
wxEmptyString
},
{

View File

@ -959,7 +959,7 @@ void recLQC2()
xForwardJZ32 skipvuidle;
xSUB(eax, ptr32[&VU0.cycle]);
xSUB(eax, ptr32[&VU0.nextBlockCycles]);
xCMP(eax, EmuConfig.Gamefixes.VUKickstartHack ? 4 : 0);
xCMP(eax, 4);
xForwardJL32 skip;
_cop2BackupRegs();
xLoadFarAddr(arg1reg, CpuVU0);
@ -1009,7 +1009,7 @@ void recSQC2()
xForwardJZ32 skipvuidle;
xSUB(eax, ptr32[&VU0.cycle]);
xSUB(eax, ptr32[&VU0.nextBlockCycles]);
xCMP(eax, EmuConfig.Gamefixes.VUKickstartHack ? 4 : 0);
xCMP(eax, 4);
xForwardJL32 skip;
_cop2BackupRegs();
xLoadFarAddr(arg1reg, CpuVU0);

View File

@ -469,7 +469,7 @@ void mVUtestCycles(microVU& mVU, microFlagCycles& mFC)
iPC = mVUstartPC;
xMOV(eax, ptr32[&mVU.cycles]);
if (!EmuConfig.Gamefixes.VUKickstartHack)
if (EmuConfig.Gamefixes.VUSyncHack)
xSUB(eax, mVUcycles); // Running behind, make sure we have time to run the block
else
xSUB(eax, 1); // Running ahead, make sure cycles left are above 0

View File

@ -340,7 +340,7 @@ void COP2_Interlock(bool mBitSync)
{
xSUB(eax, ptr32[&VU0.cycle]);
xSUB(eax, ptr32[&VU0.nextBlockCycles]);
xCMP(eax, 0);
xCMP(eax, 4);
xForwardJL32 skip;
xLoadFarAddr(arg1reg, CpuVU0);
xMOV(arg2reg, s_nBlockInterlocked);
@ -385,7 +385,7 @@ static void recCFC2()
xForwardJZ32 skipvuidle;
xSUB(eax, ptr32[&VU0.cycle]);
xSUB(eax, ptr32[&VU0.nextBlockCycles]);
xCMP(eax, EmuConfig.Gamefixes.VUKickstartHack ? 8 : 0);
xCMP(eax, 4);
xForwardJL32 skip;
_cop2BackupRegs();
xLoadFarAddr(arg1reg, CpuVU0);
@ -448,7 +448,7 @@ static void recCTC2()
xForwardJZ32 skipvuidle;
xSUB(eax, ptr32[&VU0.cycle]);
xSUB(eax, ptr32[&VU0.nextBlockCycles]);
xCMP(eax, EmuConfig.Gamefixes.VUKickstartHack ? 8 : 0);
xCMP(eax, 4);
xForwardJL32 skip;
_cop2BackupRegs();
xLoadFarAddr(arg1reg, CpuVU0);
@ -551,7 +551,7 @@ static void recQMFC2()
xForwardJZ32 skipvuidle;
xSUB(eax, ptr32[&VU0.cycle]);
xSUB(eax, ptr32[&VU0.nextBlockCycles]);
xCMP(eax, EmuConfig.Gamefixes.VUKickstartHack ? 8 : 0);
xCMP(eax, 4);
xForwardJL32 skip;
_cop2BackupRegs();
xLoadFarAddr(arg1reg, CpuVU0);
@ -592,7 +592,7 @@ static void recQMTC2()
xForwardJZ32 skipvuidle;
xSUB(eax, ptr32[&VU0.cycle]);
xSUB(eax, ptr32[&VU0.nextBlockCycles]);
xCMP(eax, EmuConfig.Gamefixes.VUKickstartHack ? 8 : 0);
xCMP(eax, 4);
xForwardJL32 skip;
_cop2BackupRegs();
xLoadFarAddr(arg1reg, CpuVU0);