diff --git a/pcsx2/DebugTools/DebugInterface.cpp b/pcsx2/DebugTools/DebugInterface.cpp index 6d8bdbb8ad..a7f7d250aa 100644 --- a/pcsx2/DebugTools/DebugInterface.cpp +++ b/pcsx2/DebugTools/DebugInterface.cpp @@ -598,6 +598,12 @@ u32 R5900DebugInterface::getPC() return cpuRegs.pc; } +// Taken from COP0.cpp +bool R5900DebugInterface::getCPCOND0() +{ + return (((dmacRegs.stat.CIS | ~dmacRegs.pcr.CPC) & 0x3FF) == 0x3ff); +} + void R5900DebugInterface::setPc(u32 newPc) { cpuRegs.pc = newPc; @@ -945,6 +951,11 @@ u32 R3000DebugInterface::getPC() return psxRegs.pc; } +bool R3000DebugInterface::getCPCOND0() +{ + return false; +} + void R3000DebugInterface::setPc(u32 newPc) { psxRegs.pc = newPc; diff --git a/pcsx2/DebugTools/DebugInterface.h b/pcsx2/DebugTools/DebugInterface.h index 24a8bdaf8f..9f195d428c 100644 --- a/pcsx2/DebugTools/DebugInterface.h +++ b/pcsx2/DebugTools/DebugInterface.h @@ -77,6 +77,7 @@ public: virtual u128 getHI() = 0; virtual u128 getLO() = 0; virtual u32 getPC() = 0; + virtual bool getCPCOND0() = 0; virtual void setPc(u32 newPc) = 0; virtual void setRegister(int cat, int num, u128 newValue) = 0; @@ -129,6 +130,7 @@ public: u128 getHI() override; u128 getLO() override; u32 getPC() override; + bool getCPCOND0() override; void setPc(u32 newPc) override; void setRegister(int cat, int num, u128 newValue) override; [[nodiscard]] SymbolMap& GetSymbolMap() const override; @@ -168,6 +170,7 @@ public: u128 getHI() override; u128 getLO() override; u32 getPC() override; + bool getCPCOND0() override; void setPc(u32 newPc) override; void setRegister(int cat, int num, u128 newValue) override; [[nodiscard]] SymbolMap& GetSymbolMap() const override; diff --git a/pcsx2/DebugTools/MIPSAnalyst.cpp b/pcsx2/DebugTools/MIPSAnalyst.cpp index 9560531ff2..f6c971d603 100644 --- a/pcsx2/DebugTools/MIPSAnalyst.cpp +++ b/pcsx2/DebugTools/MIPSAnalyst.cpp @@ -59,7 +59,7 @@ namespace MIPSAnalyst const R5900::OPCODE& opcode = R5900::GetInstruction(op); int branchType = (opcode.flags & BRANCHTYPE_MASK); - if ((opcode.flags & IS_BRANCH) && (branchType == BRANCHTYPE_BRANCH || branchType == BRANCHTYPE_BC1)) + if ((opcode.flags & IS_BRANCH) && (branchType == BRANCHTYPE_BRANCH || branchType == BRANCHTYPE_BC1 || branchType == BRANCHTYPE_BC0)) return addr + 4 + ((signed short)(op&0xFFFF)<<2); else return INVALIDTARGET; @@ -71,7 +71,7 @@ namespace MIPSAnalyst const R5900::OPCODE& opcode = R5900::GetInstruction(op); int branchType = (opcode.flags & BRANCHTYPE_MASK); - if ((opcode.flags & IS_BRANCH) && (branchType == BRANCHTYPE_BRANCH || branchType == BRANCHTYPE_BC1)) + if ((opcode.flags & IS_BRANCH) && (branchType == BRANCHTYPE_BRANCH || branchType == BRANCHTYPE_BC1 || branchType == BRANCHTYPE_BC0)) { if (!(opcode.flags & IS_LINKED)) return addr + 4 + ((signed short)(op&0xFFFF)<<2); @@ -409,6 +409,20 @@ namespace MIPSAnalyst value = info.cpu->getRegister(EECAT_FCR,31)._u32[0] & 0x00800000; info.branchTarget = info.opcodeAddress + 4 + ((s16)(op&0xFFFF)<<2); + switch (opcode.flags & CONDTYPE_MASK) + { + case CONDTYPE_EQ: + info.conditionMet = value == 0; + break; + case CONDTYPE_NE: + info.conditionMet = value != 0; + break; + } + break; + case BRANCHTYPE_BC0: + info.isConditional = true; + value = info.cpu->getCPCOND0(); + info.branchTarget = info.opcodeAddress + 4 + ((s16)(op&0xFFFF)<<2); switch (opcode.flags & CONDTYPE_MASK) { case CONDTYPE_EQ: diff --git a/pcsx2/R5900OpcodeTables.cpp b/pcsx2/R5900OpcodeTables.cpp index 356c5e7b07..d1e4b041cd 100644 --- a/pcsx2/R5900OpcodeTables.cpp +++ b/pcsx2/R5900OpcodeTables.cpp @@ -394,10 +394,10 @@ namespace R5900 MakeOpcode0( MFC0, CopDefault, 0 ); MakeOpcode0( MTC0, CopDefault, 0 ); - MakeOpcode0( BC0F, Branch, 0 ); - MakeOpcode0( BC0T, Branch, 0 ); - MakeOpcode0( BC0FL, Branch, 0 ); - MakeOpcode0( BC0TL, Branch, 0 ); + MakeOpcode0(BC0F, Branch, IS_BRANCH | BRANCHTYPE_BC0 | CONDTYPE_EQ); + MakeOpcode0(BC0T, Branch, IS_BRANCH | BRANCHTYPE_BC0 | CONDTYPE_NE); + MakeOpcode0(BC0FL, Branch, IS_BRANCH | BRANCHTYPE_BC0 | CONDTYPE_EQ | IS_LIKELY); + MakeOpcode0(BC0TL, Branch, IS_BRANCH | BRANCHTYPE_BC0 | CONDTYPE_NE | IS_LIKELY); MakeOpcode0( TLBR, CopDefault, 0 ); MakeOpcode0( TLBWI, CopDefault, 0 ); diff --git a/pcsx2/R5900OpcodeTables.h b/pcsx2/R5900OpcodeTables.h index 9067ee4d65..d372d59872 100644 --- a/pcsx2/R5900OpcodeTables.h +++ b/pcsx2/R5900OpcodeTables.h @@ -61,13 +61,14 @@ void COP2_Unknown(); #define CONDTYPE_LTZ (0x05 << 0) #define CONDTYPE_GEZ (0x06 << 0) -#define BRANCHTYPE_MASK (0x07 << 3) +#define BRANCHTYPE_MASK (0x0F << 3) #define BRANCHTYPE_JUMP (0x01 << 3) #define BRANCHTYPE_BRANCH (0x02 << 3) #define BRANCHTYPE_SYSCALL (0x03 << 3) #define BRANCHTYPE_ERET (0x04 << 3) #define BRANCHTYPE_REGISTER (0x05 << 3) #define BRANCHTYPE_BC1 (0x06 << 3) +#define BRANCHTYPE_BC0 (0x08 << 3) #define ALUTYPE_MASK (0x07 << 3) #define ALUTYPE_ADD (0x01 << 3)