mirror of https://github.com/PCSX2/pcsx2.git
VU Interpreter Branch Delays: Rethink of this. As it's completely undocumented and nobody seems to know exactly what goes on, i have made my own guess...
If the first branch is a branch instruction, then ignore the second. If the first branch is a jump instruction, execute 1 instruction from the first jump, then execute the second branch. (This is the only confirmed thing i can find from people testing this) git-svn-id: http://pcsx2.googlecode.com/svn/trunk@5539 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
parent
26cac4d837
commit
73a08536d1
|
@ -140,7 +140,7 @@ struct __aligned16 VURegs {
|
|||
u32 branch;
|
||||
u32 branchpc;
|
||||
u32 delaybranchpc;
|
||||
u32 linkreg;
|
||||
u32 firstbranchisjump;
|
||||
bool takedelaybranch;
|
||||
|
||||
// MAC/Status flags -- these are used by interpreters and superVU, but are kind of hacky
|
||||
|
|
|
@ -145,24 +145,28 @@ static void _vu0Exec(VURegs* VU)
|
|||
_vuTestPipes(VU);
|
||||
|
||||
if (VU->branch > 0) {
|
||||
VU->branch--;
|
||||
if (VU->branch == 0) {
|
||||
if (VU->branch-- == 1) {
|
||||
VU->VI[REG_TPC].UL = VU->branchpc;
|
||||
if(VU->takedelaybranch == true && VU->linkreg == 0)
|
||||
if(VU->takedelaybranch == true)
|
||||
{
|
||||
//DevCon.Warning("Setting VU0 Delay branch to next branch, treating first as delay slot");
|
||||
//DevCon.Warning("VU0 - Branch/Jump in Delay Slot");
|
||||
if(VU->firstbranchisjump == 1)
|
||||
{
|
||||
//DevCon.Warning("Jump first, so reading 1 instruction from first branch, then jumping second");
|
||||
|
||||
VU->branch = 2;
|
||||
VU->branchpc = VU->delaybranchpc;
|
||||
VU->branch = 1;
|
||||
VU->branchpc = VU->delaybranchpc;
|
||||
}
|
||||
else
|
||||
{
|
||||
//DevCon.Warning("Branch first, so ignoring second branch");
|
||||
}
|
||||
|
||||
VU->delaybranchpc = 0;
|
||||
|
||||
VU->takedelaybranch = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
VU->takedelaybranch = false;
|
||||
VU->linkreg = 0;
|
||||
}
|
||||
|
||||
VU->firstbranchisjump = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@ extern void _vuFlushAll(VURegs* VU);
|
|||
|
||||
void _vu1ExecUpper(VURegs* VU, u32 *ptr) {
|
||||
VU->code = ptr[1];
|
||||
IdebugUPPER(VU1);
|
||||
//IdebugUPPER(VU1);
|
||||
VU1_UPPER_OPCODE[VU->code & 0x3f]();
|
||||
}
|
||||
|
||||
|
@ -68,7 +68,7 @@ static void _vu1Exec(VURegs* VU)
|
|||
}
|
||||
}
|
||||
|
||||
VUM_LOG("VU->cycle = %d (flags st=%x;mac=%x;clip=%x,q=%f)", VU->cycle, VU->statusflag, VU->macflag, VU->clipflag, VU->q.F);
|
||||
//VUM_LOG("VU->cycle = %d (flags st=%x;mac=%x;clip=%x,q=%f)", VU->cycle, VU->statusflag, VU->macflag, VU->clipflag, VU->q.F);
|
||||
|
||||
VU->code = ptr[1];
|
||||
VU1regs_UPPER_OPCODE[VU->code & 0x3f](&uregs);
|
||||
|
@ -144,21 +144,26 @@ static void _vu1Exec(VURegs* VU)
|
|||
if (VU->branch > 0) {
|
||||
if (VU->branch-- == 1) {
|
||||
VU->VI[REG_TPC].UL = VU->branchpc;
|
||||
if(VU->takedelaybranch == true && VU->linkreg == 0)
|
||||
if(VU->takedelaybranch == true)
|
||||
{
|
||||
//DevCon.Warning("Setting VU1 Delay branch to next branch, treating first as delay slot");
|
||||
//DevCon.Warning("VU1 - Branch/Jump in Delay Slot");
|
||||
if(VU->firstbranchisjump == 1)
|
||||
{
|
||||
//DevCon.Warning("Jump first, so reading 1 instruction from first branch, then jumping second");
|
||||
|
||||
VU->branch = 2;
|
||||
VU->branchpc = VU->delaybranchpc;
|
||||
VU->branch = 1;
|
||||
VU->branchpc = VU->delaybranchpc;
|
||||
}
|
||||
else
|
||||
{
|
||||
//DevCon.Warning("Branch first, so ignoring second branch");
|
||||
}
|
||||
|
||||
VU->delaybranchpc = 0;
|
||||
|
||||
VU->takedelaybranch = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
VU->takedelaybranch = false;
|
||||
VU->linkreg = 0;
|
||||
}
|
||||
|
||||
VU->firstbranchisjump = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1872,19 +1872,20 @@ s32 _branchAddr(VURegs * VU) {
|
|||
return bpc;
|
||||
}
|
||||
|
||||
static __fi void _setBranch(VURegs * VU, u32 bpc, bool islink) {
|
||||
static __fi void _setBranch(VURegs * VU, u32 bpc, bool isjump) {
|
||||
if(VU->branch == 1)
|
||||
{
|
||||
if(islink)
|
||||
{
|
||||
VU->linkreg = _It_;
|
||||
}
|
||||
{
|
||||
//DevCon.Warning("Branch in Branch Delay slot!");
|
||||
VU->delaybranchpc = bpc;
|
||||
VU->takedelaybranch = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(isjump)
|
||||
{
|
||||
VU->firstbranchisjump = 1;
|
||||
}
|
||||
|
||||
VU->branch = 2;
|
||||
VU->branchpc = bpc;
|
||||
}
|
||||
|
@ -1943,12 +1944,12 @@ static __ri void _vuBAL(VURegs * VU) {
|
|||
|
||||
if (_It_) VU->VI[_It_].US[0] = (VU->VI[REG_TPC].UL + 8)/8;
|
||||
|
||||
_setBranch(VU, bpc, true);
|
||||
_setBranch(VU, bpc, false);
|
||||
}
|
||||
|
||||
static __ri void _vuJR(VURegs * VU) {
|
||||
u32 bpc = VU->VI[_Is_].US[0] * 8;
|
||||
_setBranch(VU, bpc, false);
|
||||
_setBranch(VU, bpc, true);
|
||||
}
|
||||
|
||||
//If this is in a branch delay, the jump isn't taken ( Evil Dead - Fistfull of Boomstick )
|
||||
|
|
Loading…
Reference in New Issue