diff --git a/src/pse/cpu_core.cpp b/src/pse/cpu_core.cpp index 3f0e7eafc..03eba23d6 100644 --- a/src/pse/cpu_core.cpp +++ b/src/pse/cpu_core.cpp @@ -800,14 +800,14 @@ void Core::ExecuteInstruction(Instruction inst) // bgez is the inverse of bltz, so simply do ltz and xor the result const bool bgez = ConvertToBoolUnchecked(rt & u8(1)); const bool branch = (static_cast(ReadReg(inst.i.rs)) < 0) ^ bgez; - if (branch) - { - const bool link = ConvertToBoolUnchecked((rt >> 4) & u8(1)); - if (link) - m_regs.ra = m_regs.npc; + // register is still linked even if the branch isn't taken + const bool link = (rt & u8(0x1E)) == u8(0x10); + if (link) + m_regs.ra = m_regs.npc; + + if (branch) Branch(m_regs.pc + (inst.i.imm_sext32() << 2)); - } } break; diff --git a/src/pse/cpu_types.h b/src/pse/cpu_types.h index e52e3bb2e..ebe15d3e7 100644 --- a/src/pse/cpu_types.h +++ b/src/pse/cpu_types.h @@ -179,45 +179,45 @@ struct Registers struct { - u32 zero; // r0 - u32 at; // r1 - u32 v0; // r2 - u32 v1; // r3 - u32 a0; // r4 - u32 a1; // r5 - u32 a2; // r6 - u32 a3; // r7 - u32 t0; // r8 - u32 t1; // r9 - u32 t2; // r10 - u32 t3; // r11 - u32 t4; // r12 - u32 t5; // r13 - u32 t6; // r14 - u32 t7; // r15 - u32 s0; // r16 - u32 s1; // r17 - u32 s2; // r18 - u32 s3; // r19 - u32 s4; // r20 - u32 s5; // r21 - u32 s6; // r22 - u32 s7; // r23 - u32 t8; // r24 - u32 t9; // r25 - u32 k0; // r26 - u32 k1; // r27 - u32 gp; // r28 - u32 sp; // r29 - u32 fp; // r30 - u32 ra; // r31 + u32 zero; // r0 + u32 at; // r1 + u32 v0; // r2 + u32 v1; // r3 + u32 a0; // r4 + u32 a1; // r5 + u32 a2; // r6 + u32 a3; // r7 + u32 t0; // r8 + u32 t1; // r9 + u32 t2; // r10 + u32 t3; // r11 + u32 t4; // r12 + u32 t5; // r13 + u32 t6; // r14 + u32 t7; // r15 + u32 s0; // r16 + u32 s1; // r17 + u32 s2; // r18 + u32 s3; // r19 + u32 s4; // r20 + u32 s5; // r21 + u32 s6; // r22 + u32 s7; // r23 + u32 t8; // r24 + u32 t9; // r25 + u32 k0; // r26 + u32 k1; // r27 + u32 gp; // r28 + u32 sp; // r29 + u32 fp; // r30 + u32 ra; // r31 }; }; - u32 pc; u32 hi; u32 lo; - u32 npc; + u32 pc; // at execution time: the address of the next instruction to execute (already fetched) + u32 npc; // at execution time: the address of the next instruction to fetch }; enum class Cop0Reg : u8