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"
|
name: "Crash Tag Team Racing"
|
||||||
region: "PAL-M6"
|
region: "PAL-M6"
|
||||||
gameFixes:
|
gameFixes:
|
||||||
- CrashTagTeamRacingIbitHack # Fixes constant recompilation problems.
|
- IbitHack # Fixes constant recompilation problems.
|
||||||
SLES-53441:
|
SLES-53441:
|
||||||
name: "Heroes of the Pacific"
|
name: "Heroes of the Pacific"
|
||||||
region: "PAL-M5"
|
region: "PAL-M5"
|
||||||
|
@ -14329,17 +14329,17 @@ SLES-54182:
|
||||||
name: "Scarface - The World is Yours"
|
name: "Scarface - The World is Yours"
|
||||||
region: "PAL-M4"
|
region: "PAL-M4"
|
||||||
gameFixes:
|
gameFixes:
|
||||||
- ScarfaceIbitHack
|
- IbitHack
|
||||||
SLES-54183:
|
SLES-54183:
|
||||||
name: "Scarface - The World is Yours"
|
name: "Scarface - The World is Yours"
|
||||||
region: "PAL-G"
|
region: "PAL-G"
|
||||||
gameFixes:
|
gameFixes:
|
||||||
- ScarfaceIbitHack
|
- IbitHack
|
||||||
SLES-54184:
|
SLES-54184:
|
||||||
name: "Scarface - The World is Yours"
|
name: "Scarface - The World is Yours"
|
||||||
region: "PAL-R"
|
region: "PAL-R"
|
||||||
gameFixes:
|
gameFixes:
|
||||||
- ScarfaceIbitHack
|
- IbitHack
|
||||||
SLES-54185:
|
SLES-54185:
|
||||||
name: "Dirge of Cerberus - Final Fantasy VII"
|
name: "Dirge of Cerberus - Final Fantasy VII"
|
||||||
region: "PAL-M5"
|
region: "PAL-M5"
|
||||||
|
@ -14509,7 +14509,7 @@ SLES-54271:
|
||||||
name: "Scarface - The World is Yours"
|
name: "Scarface - The World is Yours"
|
||||||
region: "PAL-E"
|
region: "PAL-E"
|
||||||
gameFixes:
|
gameFixes:
|
||||||
- ScarfaceIbitHack
|
- IbitHack
|
||||||
SLES-54305:
|
SLES-54305:
|
||||||
name: "Demon Chaos"
|
name: "Demon Chaos"
|
||||||
region: "PAL-M5"
|
region: "PAL-M5"
|
||||||
|
@ -15040,7 +15040,7 @@ SLES-54534:
|
||||||
name: "Scarface - The World is Yours [Collector's Edition]"
|
name: "Scarface - The World is Yours [Collector's Edition]"
|
||||||
region: "PAL-E"
|
region: "PAL-E"
|
||||||
gameFixes:
|
gameFixes:
|
||||||
- ScarfaceIbitHack
|
- IbitHack
|
||||||
SLES-54536:
|
SLES-54536:
|
||||||
name: "Big Idea's VeggieTales - LarryBoy and the Bad Apple"
|
name: "Big Idea's VeggieTales - LarryBoy and the Bad Apple"
|
||||||
region: "PAL-I"
|
region: "PAL-I"
|
||||||
|
@ -35827,7 +35827,7 @@ SLUS-21111:
|
||||||
region: "NTSC-U"
|
region: "NTSC-U"
|
||||||
compat: 5
|
compat: 5
|
||||||
gameFixes:
|
gameFixes:
|
||||||
- ScarfaceIbitHack
|
- IbitHack
|
||||||
SLUS-21112:
|
SLUS-21112:
|
||||||
name: "L.A. Rush"
|
name: "L.A. Rush"
|
||||||
region: "NTSC-U"
|
region: "NTSC-U"
|
||||||
|
@ -36162,7 +36162,7 @@ SLUS-21191:
|
||||||
region: "NTSC-U"
|
region: "NTSC-U"
|
||||||
compat: 5
|
compat: 5
|
||||||
gameFixes:
|
gameFixes:
|
||||||
- CrashTagTeamRacingIbitHack # Fixes constant recompilation problems.
|
- IbitHack # Fixes constant recompilation problems.
|
||||||
SLUS-21192:
|
SLUS-21192:
|
||||||
name: "Cabela's Outdoor Adventures 2006"
|
name: "Cabela's Outdoor Adventures 2006"
|
||||||
region: "NTSC-U"
|
region: "NTSC-U"
|
||||||
|
@ -37576,7 +37576,7 @@ SLUS-21492:
|
||||||
region: "NTSC-U"
|
region: "NTSC-U"
|
||||||
compat: 5
|
compat: 5
|
||||||
gameFixes:
|
gameFixes:
|
||||||
- ScarfaceIbitHack
|
- IbitHack
|
||||||
SLUS-21493:
|
SLUS-21493:
|
||||||
name: "Need for Speed - Carbon"
|
name: "Need for Speed - Carbon"
|
||||||
region: "NTSC-U"
|
region: "NTSC-U"
|
||||||
|
|
|
@ -40,8 +40,7 @@ enum GamefixId
|
||||||
Fix_VIF1Stall,
|
Fix_VIF1Stall,
|
||||||
Fix_GIFFIFO,
|
Fix_GIFFIFO,
|
||||||
Fix_GoemonTlbMiss,
|
Fix_GoemonTlbMiss,
|
||||||
Fix_ScarfaceIbit,
|
Fix_Ibit,
|
||||||
Fix_CrashTagTeamIbit,
|
|
||||||
Fix_VU0Kickstart,
|
Fix_VU0Kickstart,
|
||||||
|
|
||||||
GamefixId_COUNT
|
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).
|
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)
|
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
|
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
|
IbitHack : 1, // I bit hack. Needed to stop constant VU recompilation in some games
|
||||||
CrashTagTeamRacingIbit : 1, // Crash Tag Team Racing I bit hack. Needed to stop constant VU recompilation
|
|
||||||
VU0KickstartHack : 1; // Speed up VU0 at start of program to avoid some VU1 sync issues
|
VU0KickstartHack : 1; // Speed up VU0 at start of program to avoid some VU1 sync issues
|
||||||
BITFIELD_END
|
BITFIELD_END
|
||||||
|
|
||||||
|
|
|
@ -285,8 +285,7 @@ const wxChar *const tbl_GamefixNames[] =
|
||||||
L"VIF1Stall",
|
L"VIF1Stall",
|
||||||
L"GIFFIFO",
|
L"GIFFIFO",
|
||||||
L"GoemonTlb",
|
L"GoemonTlb",
|
||||||
L"ScarfaceIbit",
|
L"Ibit",
|
||||||
L"CrashTagTeamRacingIbit",
|
|
||||||
L"VU0Kickstart"
|
L"VU0Kickstart"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -347,8 +346,7 @@ void Pcsx2Config::GamefixOptions::Set( GamefixId id, bool enabled )
|
||||||
case Fix_VIF1Stall: VIF1StallHack = enabled; break;
|
case Fix_VIF1Stall: VIF1StallHack = enabled; break;
|
||||||
case Fix_GIFFIFO: GIFFIFOHack = enabled; break;
|
case Fix_GIFFIFO: GIFFIFOHack = enabled; break;
|
||||||
case Fix_GoemonTlbMiss: GoemonTlbHack = enabled; break;
|
case Fix_GoemonTlbMiss: GoemonTlbHack = enabled; break;
|
||||||
case Fix_ScarfaceIbit: ScarfaceIbit = enabled; break;
|
case Fix_Ibit: IbitHack = enabled; break;
|
||||||
case Fix_CrashTagTeamIbit: CrashTagTeamRacingIbit = enabled; break;
|
|
||||||
case Fix_VU0Kickstart: VU0KickstartHack = enabled; break;
|
case Fix_VU0Kickstart: VU0KickstartHack = enabled; break;
|
||||||
jNO_DEFAULT;
|
jNO_DEFAULT;
|
||||||
}
|
}
|
||||||
|
@ -372,8 +370,7 @@ bool Pcsx2Config::GamefixOptions::Get( GamefixId id ) const
|
||||||
case Fix_VIF1Stall: return VIF1StallHack;
|
case Fix_VIF1Stall: return VIF1StallHack;
|
||||||
case Fix_GIFFIFO: return GIFFIFOHack;
|
case Fix_GIFFIFO: return GIFFIFOHack;
|
||||||
case Fix_GoemonTlbMiss: return GoemonTlbHack;
|
case Fix_GoemonTlbMiss: return GoemonTlbHack;
|
||||||
case Fix_ScarfaceIbit: return ScarfaceIbit;
|
case Fix_Ibit: return IbitHack;
|
||||||
case Fix_CrashTagTeamIbit: return CrashTagTeamRacingIbit;
|
|
||||||
case Fix_VU0Kickstart: return VU0KickstartHack;
|
case Fix_VU0Kickstart: return VU0KickstartHack;
|
||||||
jNO_DEFAULT;
|
jNO_DEFAULT;
|
||||||
}
|
}
|
||||||
|
@ -397,8 +394,7 @@ void Pcsx2Config::GamefixOptions::LoadSave( IniInterface& ini )
|
||||||
IniBitBool( VIF1StallHack );
|
IniBitBool( VIF1StallHack );
|
||||||
IniBitBool( GIFFIFOHack );
|
IniBitBool( GIFFIFOHack );
|
||||||
IniBitBool( GoemonTlbHack );
|
IniBitBool( GoemonTlbHack );
|
||||||
IniBitBool( ScarfaceIbit );
|
IniBitBool( IbitHack );
|
||||||
IniBitBool( CrashTagTeamRacingIbit );
|
|
||||||
IniBitBool( VU0KickstartHack );
|
IniBitBool( VU0KickstartHack );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -93,11 +93,7 @@ Panels::GameFixesPanel::GameFixesPanel( wxWindow* parent )
|
||||||
wxEmptyString
|
wxEmptyString
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
_("VU I bit Hack avoid constant recompilation (Scarface The World Is Yours)"),
|
_("VU I bit Hack avoid constant recompilation in some games (Scarface The World Is Yours, Crash Tag Team Racing)"),
|
||||||
wxEmptyString
|
|
||||||
},
|
|
||||||
{
|
|
||||||
_("VU I bit Hack avoid constant recompilation (Crash Tag Team Racing)"),
|
|
||||||
wxEmptyString
|
wxEmptyString
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
@ -250,7 +250,7 @@ __fi bool mVUcmpProg(microVU& mVU, microProgram& prog, const bool cmpWholeProg)
|
||||||
for (const auto& range : *prog.ranges) {
|
for (const auto& range : *prog.ranges) {
|
||||||
auto cmpOffset = [&](void* x) { return (u8*)x + range.start; };
|
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 ((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;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -271,25 +271,7 @@ _mVUt __fi void* mVUsearchProg(u32 startPC, uptr pState) {
|
||||||
std::deque<microProgram*>::iterator it(list->begin());
|
std::deque<microProgram*>::iterator it(list->begin());
|
||||||
for ( ; it != list->end(); ++it) {
|
for ( ; it != list->end(); ++it) {
|
||||||
bool b = mVUcmpProg(mVU, *it[0], 0);
|
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) {
|
if (b) {
|
||||||
quick.block = it[0]->block[startPC/8];
|
quick.block = it[0]->block[startPC/8];
|
||||||
quick.prog = it[0];
|
quick.prog = it[0];
|
||||||
|
|
|
@ -44,19 +44,23 @@ __fi void mVUcheckIsSame(mV) {
|
||||||
// Sets up microProgram PC ranges based on whats been recompiled
|
// Sets up microProgram PC ranges based on whats been recompiled
|
||||||
void mVUsetupRange(microVU& mVU, s32 pc, bool isStartPC) {
|
void mVUsetupRange(microVU& mVU, s32 pc, bool isStartPC) {
|
||||||
std::deque<microRange>*& ranges = mVUcurProg.ranges;
|
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
|
if (isStartPC) { // Check if startPC is already within a block we've recompiled
|
||||||
std::deque<microRange>::const_iterator it(ranges->begin());
|
std::deque<microRange>::const_iterator it(ranges->begin());
|
||||||
for ( ; it != ranges->end(); ++it) {
|
for ( ; it != ranges->end(); ++it) {
|
||||||
if ((pc >= it[0].start) && (pc <= it[0].end)) {
|
if ((pc >= it[0].start) && (pc <= it[0].end)) {
|
||||||
if (it[0].start != 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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,23 +79,22 @@ void mVUsetupRange(microVU& mVU, s32 pc, bool isStartPC) {
|
||||||
std::deque<microRange>::iterator it(ranges->begin());
|
std::deque<microRange>::iterator it(ranges->begin());
|
||||||
for (++it; it != ranges->end(); ++it) {
|
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
|
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;
|
mergedRange = true;
|
||||||
}
|
}
|
||||||
// Make sure we check both as the start on the other one may be later, we don't want to delete that
|
// 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
|
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;
|
mergedRange = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (mergedRange) {
|
if (mergedRange) {
|
||||||
//DevCon.WriteLn(Color_Green, "microVU%d: Prog Range Merging", mVU.index);
|
|
||||||
ranges->erase(ranges->begin());
|
ranges->erase(ranges->begin());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
DevCon.WriteLn(Color_Green, "microVU%d: Prog Range Wrap [%04x] [%d]", mVU.index, mVUrange.start, mVUrange.end);
|
|
||||||
mVUrange.end = mVU.microMemSize;
|
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};
|
microRange mRange = {0, pc};
|
||||||
ranges->push_front(mRange);
|
ranges->push_front(mRange);
|
||||||
}
|
}
|
||||||
|
@ -109,7 +112,7 @@ void doIbit(mV) {
|
||||||
if (mVUup.iBit) {
|
if (mVUup.iBit) {
|
||||||
incPC(-1);
|
incPC(-1);
|
||||||
mVU.regAlloc->clearRegVF(33);
|
mVU.regAlloc->clearRegVF(33);
|
||||||
if (EmuConfig.Gamefixes.ScarfaceIbit || EmuConfig.Gamefixes.CrashTagTeamRacingIbit) {
|
if (EmuConfig.Gamefixes.IbitHack) {
|
||||||
xMOV(gprT1, ptr32[&curI]);
|
xMOV(gprT1, ptr32[&curI]);
|
||||||
xMOV(ptr32[&mVU.getVI(REG_I)], gprT1);
|
xMOV(ptr32[&mVU.getVI(REG_I)], gprT1);
|
||||||
}
|
}
|
||||||
|
@ -580,6 +583,11 @@ void* mVUcompile(microVU& mVU, u32 startPC, uptr pState)
|
||||||
if (curI & _Ibit_) {
|
if (curI & _Ibit_) {
|
||||||
mVUlow.isNOP = true;
|
mVUlow.isNOP = true;
|
||||||
mVUup.iBit = 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 {
|
else {
|
||||||
incPC(-1);
|
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++) {
|
for (size_t i = 0; i < (sizeof(microRegInfo) - 4) / 4; i++, lpS++, cpS++) {
|
||||||
xMOV(ptr32[lpS], cpS[0]);
|
xMOV(ptr32[lpS], cpS[0]);
|
||||||
}
|
}
|
||||||
mVUsetupRange(mVU, xPC, false);
|
|
||||||
incPC(2);
|
incPC(2);
|
||||||
|
mVUsetupRange(mVU, xPC, false);
|
||||||
mVUendProgram(mVU, &mFC, 0);
|
mVUendProgram(mVU, &mFC, 0);
|
||||||
normBranchCompile(mVU, xPC);
|
normBranchCompile(mVU, xPC);
|
||||||
incPC(-2);
|
incPC(-2);
|
||||||
|
@ -689,7 +697,7 @@ void* mVUcompile(microVU& mVU, u32 startPC, uptr pState)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isEvilBlock) {
|
if (isEvilBlock) {
|
||||||
mVUsetupRange(mVU, xPC, false);
|
mVUsetupRange(mVU, xPC+8, false);
|
||||||
normJumpCompile(mVU, mFC, true);
|
normJumpCompile(mVU, mFC, true);
|
||||||
goto perf_and_return;
|
goto perf_and_return;
|
||||||
}
|
}
|
||||||
|
@ -697,15 +705,16 @@ void* mVUcompile(microVU& mVU, u32 startPC, uptr pState)
|
||||||
// Handle range wrapping
|
// Handle range wrapping
|
||||||
if ((xPC + 8) == mVU.microMemSize)
|
if ((xPC + 8) == mVU.microMemSize)
|
||||||
{
|
{
|
||||||
mVUsetupRange(mVU, xPC, false);
|
mVUsetupRange(mVU, xPC+8, false);
|
||||||
mVUsetupRange(mVU, 0, 1);
|
mVUsetupRange(mVU, 0, 1);
|
||||||
}
|
}
|
||||||
incPC(1);
|
incPC(1);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
incPC(1);
|
||||||
mVUsetupRange(mVU, xPC, false);
|
mVUsetupRange(mVU, xPC, false);
|
||||||
mVUdebugPrintBlocks(mVU, true);
|
mVUdebugPrintBlocks(mVU, true);
|
||||||
incPC(-3); // Go back to branch opcode
|
incPC(-4); // Go back to branch opcode
|
||||||
|
|
||||||
switch (mVUlow.branch) {
|
switch (mVUlow.branch) {
|
||||||
case 1: // B/BAL
|
case 1: // B/BAL
|
||||||
|
@ -742,7 +751,7 @@ void* mVUcompile(microVU& mVU, u32 startPC, uptr pState)
|
||||||
}
|
}
|
||||||
|
|
||||||
// E-bit End
|
// E-bit End
|
||||||
mVUsetupRange(mVU, xPC - 8, false);
|
mVUsetupRange(mVU, xPC, false);
|
||||||
mVUendProgram(mVU, &mFC, 1);
|
mVUendProgram(mVU, &mFC, 1);
|
||||||
|
|
||||||
perf_and_return:
|
perf_and_return:
|
||||||
|
|
Loading…
Reference in New Issue