From 26cac4d8379b62851af608110b3a723357accfcf Mon Sep 17 00:00:00 2001 From: "refraction@gmail.com" Date: Sun, 27 Jan 2013 16:56:58 +0000 Subject: [PATCH] VU Interpreter: It seems doing JALR in a delay slot is not taken ( Evil Dead - Fistfull of Boomstick) So the game now works in VU1 interpreter only. Tried fixing up MicroVU but its too confusing. Got close but lots of missing textures :( git-svn-id: http://pcsx2.googlecode.com/svn/trunk@5538 96395faa-99c1-11dd-bbfe-3dabce05a288 --- pcsx2/VU.h | 1 + pcsx2/VU0microInterp.cpp | 13 ++++++++++--- pcsx2/VU1microInterp.cpp | 13 ++++++++++--- pcsx2/VUops.cpp | 28 +++++++++++++++++----------- 4 files changed, 38 insertions(+), 17 deletions(-) diff --git a/pcsx2/VU.h b/pcsx2/VU.h index af87cd16b6..95d4d67d33 100644 --- a/pcsx2/VU.h +++ b/pcsx2/VU.h @@ -140,6 +140,7 @@ struct __aligned16 VURegs { u32 branch; u32 branchpc; u32 delaybranchpc; + u32 linkreg; bool takedelaybranch; // MAC/Status flags -- these are used by interpreters and superVU, but are kind of hacky diff --git a/pcsx2/VU0microInterp.cpp b/pcsx2/VU0microInterp.cpp index debbee9fd3..068300807c 100644 --- a/pcsx2/VU0microInterp.cpp +++ b/pcsx2/VU0microInterp.cpp @@ -148,14 +148,21 @@ static void _vu0Exec(VURegs* VU) VU->branch--; if (VU->branch == 0) { VU->VI[REG_TPC].UL = VU->branchpc; - if(VU->takedelaybranch == true) - { + if(VU->takedelaybranch == true && VU->linkreg == 0) + { //DevCon.Warning("Setting VU0 Delay branch to next branch, treating first as delay slot"); + + VU->branch = 2; VU->branchpc = VU->delaybranchpc; VU->delaybranchpc = 0; - VU->branch = 2; + VU->takedelaybranch = false; } + else + { + VU->takedelaybranch = false; + VU->linkreg = 0; + } } } diff --git a/pcsx2/VU1microInterp.cpp b/pcsx2/VU1microInterp.cpp index 8e3b7e32d5..47dc3511e2 100644 --- a/pcsx2/VU1microInterp.cpp +++ b/pcsx2/VU1microInterp.cpp @@ -144,14 +144,21 @@ static void _vu1Exec(VURegs* VU) if (VU->branch > 0) { if (VU->branch-- == 1) { VU->VI[REG_TPC].UL = VU->branchpc; - if(VU->takedelaybranch == true) - { + if(VU->takedelaybranch == true && VU->linkreg == 0) + { //DevCon.Warning("Setting VU1 Delay branch to next branch, treating first as delay slot"); + + VU->branch = 2; VU->branchpc = VU->delaybranchpc; VU->delaybranchpc = 0; - VU->branch = 2; + VU->takedelaybranch = false; } + else + { + VU->takedelaybranch = false; + VU->linkreg = 0; + } } } diff --git a/pcsx2/VUops.cpp b/pcsx2/VUops.cpp index 6ce659cdf3..7522649c90 100644 --- a/pcsx2/VUops.cpp +++ b/pcsx2/VUops.cpp @@ -1872,9 +1872,13 @@ s32 _branchAddr(VURegs * VU) { return bpc; } -static __fi void _setBranch(VURegs * VU, u32 bpc) { +static __fi void _setBranch(VURegs * VU, u32 bpc, bool islink) { if(VU->branch == 1) { + if(islink) + { + VU->linkreg = _It_; + } //DevCon.Warning("Branch in Branch Delay slot!"); VU->delaybranchpc = bpc; VU->takedelaybranch = true; @@ -1889,68 +1893,70 @@ static __fi void _setBranch(VURegs * VU, u32 bpc) { static __ri void _vuIBEQ(VURegs * VU) { if (VU->VI[_It_].US[0] == VU->VI[_Is_].US[0]) { s32 bpc = _branchAddr(VU); - _setBranch(VU, bpc); + _setBranch(VU, bpc, false); } } static __ri void _vuIBGEZ(VURegs * VU) { if (VU->VI[_Is_].SS[0] >= 0) { s32 bpc = _branchAddr(VU); - _setBranch(VU, bpc); + _setBranch(VU, bpc, false); } } static __ri void _vuIBGTZ(VURegs * VU) { if (VU->VI[_Is_].SS[0] > 0) { s32 bpc = _branchAddr(VU); - _setBranch(VU, bpc); + _setBranch(VU, bpc, false); } } static __ri void _vuIBLEZ(VURegs * VU) { if (VU->VI[_Is_].SS[0] <= 0) { s32 bpc = _branchAddr(VU); - _setBranch(VU, bpc); + _setBranch(VU, bpc, false); } } static __ri void _vuIBLTZ(VURegs * VU) { if (VU->VI[_Is_].SS[0] < 0) { s32 bpc = _branchAddr(VU); - _setBranch(VU, bpc); + _setBranch(VU, bpc, false); } } static __ri void _vuIBNE(VURegs * VU) { if (VU->VI[_It_].US[0] != VU->VI[_Is_].US[0]) { s32 bpc = _branchAddr(VU); - _setBranch(VU, bpc); + _setBranch(VU, bpc, false); } } static __ri void _vuB(VURegs * VU) { s32 bpc = _branchAddr(VU); - _setBranch(VU, bpc); + _setBranch(VU, bpc, false); } +// NOTE!! This might fall in a delay slot, if it does, the BAL won't be taken. Not sure if this is correct static __ri void _vuBAL(VURegs * VU) { s32 bpc = _branchAddr(VU); if (_It_) VU->VI[_It_].US[0] = (VU->VI[REG_TPC].UL + 8)/8; - _setBranch(VU, bpc); + _setBranch(VU, bpc, true); } static __ri void _vuJR(VURegs * VU) { u32 bpc = VU->VI[_Is_].US[0] * 8; - _setBranch(VU, bpc); + _setBranch(VU, bpc, false); } +//If this is in a branch delay, the jump isn't taken ( Evil Dead - Fistfull of Boomstick ) static __ri void _vuJALR(VURegs * VU) { u32 bpc = VU->VI[_Is_].US[0] * 8; if (_It_) VU->VI[_It_].US[0] = (VU->VI[REG_TPC].UL + 8)/8; - _setBranch(VU, bpc); + _setBranch(VU, bpc, true); } static __ri void _vuMFP(VURegs * VU) {