Skip to content

Commit 646cfa2

Browse files
committed
Merge branch 'master' of https://github.com/grumpycoders/pcsx-redux into delay-slot-mask
2 parents c9637ef + db26cec commit 646cfa2

File tree

2 files changed

+30
-16
lines changed

2 files changed

+30
-16
lines changed

src/core/r3000a.cc

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -97,20 +97,6 @@ void PCSX::R3000Acpu::psxException(uint32_t code, bool bd) {
9797
}
9898

9999
void PCSX::R3000Acpu::psxBranchTest() {
100-
// GameShark Sampler: Give VSync pin some delay before exception eats it
101-
if (psxHu32(0x1070) & psxHu32(0x1074)) {
102-
if ((m_psxRegs.CP0.n.Status & 0x401) == 0x401) {
103-
uint32_t opcode;
104-
105-
// Crash Bandicoot 2: Don't run exceptions when GTE in pipeline
106-
opcode = SWAP_LE32(*Read_ICache(m_psxRegs.pc, true));
107-
if (((opcode >> 24) & 0xfe) != 0x4a) {
108-
PSXCPU_LOG("Interrupt: %x %x\n", psxHu32(0x1070), psxHu32(0x1074));
109-
psxException(0x400, 0);
110-
}
111-
}
112-
}
113-
114100
#if 0
115101
if( SPU_async )
116102
{
@@ -228,6 +214,18 @@ void PCSX::R3000Acpu::psxBranchTest() {
228214
}
229215
}
230216
}
217+
if (psxHu32(0x1070) & psxHu32(0x1074)) {
218+
if ((m_psxRegs.CP0.n.Status & 0x401) == 0x401) {
219+
uint32_t opcode;
220+
221+
// Crash Bandicoot 2: Don't run exceptions when GTE in pipeline
222+
opcode = SWAP_LE32(*Read_ICache(m_psxRegs.pc, true));
223+
if (((opcode >> 24) & 0xfe) != 0x4a) {
224+
PSXCPU_LOG("Interrupt: %x %x\n", psxHu32(0x1070), psxHu32(0x1074));
225+
psxException(0x400, 0);
226+
}
227+
}
228+
}
231229
}
232230

233231
void PCSX::R3000Acpu::psxSetPGXPMode(uint32_t pgxpMode) {

src/core/r3000a.h

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -251,8 +251,24 @@ typedef struct {
251251
#define _JumpTarget_ ((_Target_ * 4) + (_PC_ & 0xf0000000)) // Calculates the target during a jump instruction
252252
#define _BranchTarget_ ((int16_t)_Im_ * 4 + _PC_) // Calculates the target during a branch instruction
253253

254-
#define _SetLink(x) \
255-
PCSX::g_emulator.m_psxCpu->m_psxRegs.GPR.r[x] = _PC_ + 4 // Sets the return address in the link register
254+
/*
255+
The "SetLink" mechanism uses the delay slot. This may sound counter intuitive, but this is the only way to
256+
properly handle this specific sequence of instructions:
257+
258+
beq someFalseCondition, out
259+
lw $ra, someOffset($sp)
260+
jal someFunction
261+
nop
262+
[...]
263+
out:
264+
jr $ra
265+
nop
266+
267+
Without the change, the lw $ra will apply itself after jal happens, thus overriding the value the jal will
268+
have loaded into this register. This probably means this is also how the real CPU handles this, otherwise,
269+
this wouldn't work at all.
270+
*/
271+
#define _SetLink(x) delayedLoad(x, _PC_ + 4); // Sets the return address in the link register
256272

257273
class R3000Acpu {
258274
public:

0 commit comments

Comments
 (0)