File tree Expand file tree Collapse file tree 2 files changed +30
-16
lines changed Expand file tree Collapse file tree 2 files changed +30
-16
lines changed Original file line number Diff line number Diff line change @@ -97,20 +97,6 @@ void PCSX::R3000Acpu::psxException(uint32_t code, bool bd) {
97
97
}
98
98
99
99
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
-
114
100
#if 0
115
101
if( SPU_async )
116
102
{
@@ -228,6 +214,18 @@ void PCSX::R3000Acpu::psxBranchTest() {
228
214
}
229
215
}
230
216
}
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
+ }
231
229
}
232
230
233
231
void PCSX::R3000Acpu::psxSetPGXPMode (uint32_t pgxpMode) {
Original file line number Diff line number Diff line change @@ -251,8 +251,24 @@ typedef struct {
251
251
#define _JumpTarget_ ((_Target_ * 4 ) + (_PC_ & 0xf0000000 )) // Calculates the target during a jump instruction
252
252
#define _BranchTarget_ ((int16_t )_Im_ * 4 + _PC_) // Calculates the target during a branch instruction
253
253
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
256
272
257
273
class R3000Acpu {
258
274
public:
You can’t perform that action at this time.
0 commit comments