drc: botched msb bit check
[pcsx_rearmed.git] / libpcsxcore / psxinterpreter.c
1 /***************************************************************************
2  *   Copyright (C) 2007 Ryan Schultz, PCSX-df Team, PCSX team              *
3  *                                                                         *
4  *   This program is free software; you can redistribute it and/or modify  *
5  *   it under the terms of the GNU General Public License as published by  *
6  *   the Free Software Foundation; either version 2 of the License, or     *
7  *   (at your option) any later version.                                   *
8  *                                                                         *
9  *   This program is distributed in the hope that it will be useful,       *
10  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
11  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
12  *   GNU General Public License for more details.                          *
13  *                                                                         *
14  *   You should have received a copy of the GNU General Public License     *
15  *   along with this program; if not, write to the                         *
16  *   Free Software Foundation, Inc.,                                       *
17  *   51 Franklin Street, Fifth Floor, Boston, MA 02111-1307 USA.           *
18  ***************************************************************************/
19
20 /*
21  * PSX assembly interpreter.
22  */
23
24 #include "psxcommon.h"
25 #include "r3000a.h"
26 #include "gte.h"
27 #include "psxhle.h"
28 #include "debug.h"
29 #include "psxinterpreter.h"
30 #include <assert.h>
31
32 static int branch = 0;
33 static int branch2 = 0;
34 static u32 branchPC;
35
36 // These macros are used to assemble the repassembler functions
37
38 #ifdef PSXCPU_LOG
39 #define debugI() PSXCPU_LOG("%s\n", disR3000AF(psxRegs.code, psxRegs.pc)); 
40 #else
41 #define debugI()
42 #endif
43
44 // Subsets
45 void (*psxBSC[64])();
46 void (*psxSPC[64])();
47 void (*psxREG[32])();
48 void (*psxCP0[32])();
49 void (*psxCP2[64])(struct psxCP2Regs *regs);
50 void (*psxCP2BSC[32])();
51
52 static u32 fetchNoCache(u32 pc)
53 {
54         u32 *code = (u32 *)PSXM(pc);
55         return ((code == NULL) ? 0 : SWAP32(*code));
56 }
57
58 /*
59 Formula One 2001 :
60 Use old CPU cache code when the RAM location is updated with new code (affects in-game racing)
61 */
62 static struct cache_entry {
63         u32 tag;
64         u32 data[4];
65 } ICache[256];
66
67 static u32 fetchICache(u32 pc)
68 {
69         // cached?
70         if (pc < 0xa0000000)
71         {
72                 // this is not how the hardware works but whatever
73                 struct cache_entry *entry = &ICache[(pc & 0xff0) >> 4];
74
75                 if (((entry->tag ^ pc) & 0xfffffff0) != 0 || pc < entry->tag)
76                 {
77                         u32 *code = (u32 *)PSXM(pc & ~0x0f);
78                         if (!code)
79                                 return 0;
80
81                         entry->tag = pc;
82                         // treat as 4 words, although other configurations are said to be possible
83                         switch (pc & 0x0c)
84                         {
85                                 case 0x00: entry->data[0] = SWAP32(code[0]);
86                                 case 0x04: entry->data[1] = SWAP32(code[1]);
87                                 case 0x08: entry->data[2] = SWAP32(code[2]);
88                                 case 0x0c: entry->data[3] = SWAP32(code[3]);
89                         }
90                 }
91                 return entry->data[(pc & 0x0f) >> 2];
92         }
93
94         return fetchNoCache(pc);
95 }
96
97 u32 (*fetch)(u32 pc) = fetchNoCache;
98
99 static void delayRead(int reg, u32 bpc) {
100         u32 rold, rnew;
101
102 //      SysPrintf("delayRead at %x!\n", psxRegs.pc);
103
104         rold = psxRegs.GPR.r[reg];
105         psxBSC[psxRegs.code >> 26](); // branch delay load
106         rnew = psxRegs.GPR.r[reg];
107
108         psxRegs.pc = bpc;
109
110         branch = 0;
111
112         psxRegs.GPR.r[reg] = rold;
113         execI(); // first branch opcode
114         psxRegs.GPR.r[reg] = rnew;
115
116         psxBranchTest();
117 }
118
119 static void delayWrite(int reg, u32 bpc) {
120
121 /*      SysPrintf("delayWrite at %x!\n", psxRegs.pc);
122
123         SysPrintf("%s\n", disR3000AF(psxRegs.code, psxRegs.pc-4));
124         SysPrintf("%s\n", disR3000AF(PSXMu32(bpc), bpc));*/
125
126         // no changes from normal behavior
127
128         psxBSC[psxRegs.code >> 26]();
129
130         branch = 0;
131         psxRegs.pc = bpc;
132
133         psxBranchTest();
134 }
135
136 static void delayReadWrite(int reg, u32 bpc) {
137
138 //      SysPrintf("delayReadWrite at %x!\n", psxRegs.pc);
139
140         // the branch delay load is skipped
141
142         branch = 0;
143         psxRegs.pc = bpc;
144
145         psxBranchTest();
146 }
147
148 // this defines shall be used with the tmp 
149 // of the next func (instead of _Funct_...)
150 #define _tFunct_  ((tmp      ) & 0x3F)  // The funct part of the instruction register 
151 #define _tRd_     ((tmp >> 11) & 0x1F)  // The rd part of the instruction register 
152 #define _tRt_     ((tmp >> 16) & 0x1F)  // The rt part of the instruction register 
153 #define _tRs_     ((tmp >> 21) & 0x1F)  // The rs part of the instruction register 
154 #define _tSa_     ((tmp >>  6) & 0x1F)  // The sa part of the instruction register
155
156 int psxTestLoadDelay(int reg, u32 tmp) {
157         if (tmp == 0) return 0; // NOP
158         switch (tmp >> 26) {
159                 case 0x00: // SPECIAL
160                         switch (_tFunct_) {
161                                 case 0x00: // SLL
162                                 case 0x02: case 0x03: // SRL/SRA
163                                         if (_tRd_ == reg && _tRt_ == reg) return 1; else
164                                         if (_tRt_ == reg) return 2; else
165                                         if (_tRd_ == reg) return 3;
166                                         break;
167
168                                 case 0x08: // JR
169                                         if (_tRs_ == reg) return 2;
170                                         break;
171                                 case 0x09: // JALR
172                                         if (_tRd_ == reg && _tRs_ == reg) return 1; else
173                                         if (_tRs_ == reg) return 2; else
174                                         if (_tRd_ == reg) return 3;
175                                         break;
176
177                                 // SYSCALL/BREAK just a break;
178
179                                 case 0x20: case 0x21: case 0x22: case 0x23:
180                                 case 0x24: case 0x25: case 0x26: case 0x27: 
181                                 case 0x2a: case 0x2b: // ADD/ADDU...
182                                 case 0x04: case 0x06: case 0x07: // SLLV...
183                                         if (_tRd_ == reg && (_tRt_ == reg || _tRs_ == reg)) return 1; else
184                                         if (_tRt_ == reg || _tRs_ == reg) return 2; else
185                                         if (_tRd_ == reg) return 3;
186                                         break;
187
188                                 case 0x10: case 0x12: // MFHI/MFLO
189                                         if (_tRd_ == reg) return 3;
190                                         break;
191                                 case 0x11: case 0x13: // MTHI/MTLO
192                                         if (_tRs_ == reg) return 2;
193                                         break;
194
195                                 case 0x18: case 0x19:
196                                 case 0x1a: case 0x1b: // MULT/DIV...
197                                         if (_tRt_ == reg || _tRs_ == reg) return 2;
198                                         break;
199                         }
200                         break;
201
202                 case 0x01: // REGIMM
203                         switch (_tRt_) {
204                                 case 0x00: case 0x01:
205                                 case 0x10: case 0x11: // BLTZ/BGEZ...
206                                         // Xenogears - lbu v0 / beq v0
207                                         // - no load delay (fixes battle loading)
208                                         break;
209
210                                         if (_tRs_ == reg) return 2;
211                                         break;
212                         }
213                         break;
214
215                 // J would be just a break;
216                 case 0x03: // JAL
217                         if (31 == reg) return 3;
218                         break;
219
220                 case 0x04: case 0x05: // BEQ/BNE
221                         // Xenogears - lbu v0 / beq v0
222                         // - no load delay (fixes battle loading)
223                         break;
224
225                         if (_tRs_ == reg || _tRt_ == reg) return 2;
226                         break;
227
228                 case 0x06: case 0x07: // BLEZ/BGTZ
229                         // Xenogears - lbu v0 / beq v0
230                         // - no load delay (fixes battle loading)
231                         break;
232
233                         if (_tRs_ == reg) return 2;
234                         break;
235
236                 case 0x08: case 0x09: case 0x0a: case 0x0b:
237                 case 0x0c: case 0x0d: case 0x0e: // ADDI/ADDIU...
238                         if (_tRt_ == reg && _tRs_ == reg) return 1; else
239                         if (_tRs_ == reg) return 2; else
240                         if (_tRt_ == reg) return 3;
241                         break;
242
243                 case 0x0f: // LUI
244                         if (_tRt_ == reg) return 3;
245                         break;
246
247                 case 0x10: // COP0
248                         switch (_tFunct_) {
249                                 case 0x00: // MFC0
250                                         if (_tRt_ == reg) return 3;
251                                         break;
252                                 case 0x02: // CFC0
253                                         if (_tRt_ == reg) return 3;
254                                         break;
255                                 case 0x04: // MTC0
256                                         if (_tRt_ == reg) return 2;
257                                         break;
258                                 case 0x06: // CTC0
259                                         if (_tRt_ == reg) return 2;
260                                         break;
261                                 // RFE just a break;
262                         }
263                         break;
264
265                 case 0x12: // COP2
266                         switch (_tFunct_) {
267                                 case 0x00: 
268                                         switch (_tRs_) {
269                                                 case 0x00: // MFC2
270                                                         if (_tRt_ == reg) return 3;
271                                                         break;
272                                                 case 0x02: // CFC2
273                                                         if (_tRt_ == reg) return 3;
274                                                         break;
275                                                 case 0x04: // MTC2
276                                                         if (_tRt_ == reg) return 2;
277                                                         break;
278                                                 case 0x06: // CTC2
279                                                         if (_tRt_ == reg) return 2;
280                                                         break;
281                                         }
282                                         break;
283                                 // RTPS... break;
284                         }
285                         break;
286
287                 case 0x22: case 0x26: // LWL/LWR
288                         if (_tRt_ == reg) return 3; else
289                         if (_tRs_ == reg) return 2;
290                         break;
291
292                 case 0x20: case 0x21: case 0x23:
293                 case 0x24: case 0x25: // LB/LH/LW/LBU/LHU
294                         if (_tRt_ == reg && _tRs_ == reg) return 1; else
295                         if (_tRs_ == reg) return 2; else
296                         if (_tRt_ == reg) return 3;
297                         break;
298
299                 case 0x28: case 0x29: case 0x2a:
300                 case 0x2b: case 0x2e: // SB/SH/SWL/SW/SWR
301                         if (_tRt_ == reg || _tRs_ == reg) return 2;
302                         break;
303
304                 case 0x32: case 0x3a: // LWC2/SWC2
305                         if (_tRs_ == reg) return 2;
306                         break;
307         }
308
309         return 0;
310 }
311
312 void psxDelayTest(int reg, u32 bpc) {
313         u32 tmp = fetch(psxRegs.pc);
314         branch = 1;
315
316         switch (psxTestLoadDelay(reg, tmp)) {
317                 case 1:
318                         delayReadWrite(reg, bpc); return;
319                 case 2:
320                         delayRead(reg, bpc); return;
321                 case 3:
322                         delayWrite(reg, bpc); return;
323         }
324         psxBSC[psxRegs.code >> 26]();
325
326         branch = 0;
327         psxRegs.pc = bpc;
328
329         psxBranchTest();
330 }
331
332 static u32 psxBranchNoDelay(void) {
333         u32 temp;
334
335         psxRegs.code = fetch(psxRegs.pc);
336         switch (_Op_) {
337                 case 0x00: // SPECIAL
338                         switch (_Funct_) {
339                                 case 0x08: // JR
340                                         return _u32(_rRs_);
341                                 case 0x09: // JALR
342                                         temp = _u32(_rRs_);
343                                         if (_Rd_) { _SetLink(_Rd_); }
344                                         return temp;
345                         }
346                         break;
347                 case 0x01: // REGIMM
348                         switch (_Rt_) {
349                                 case 0x00: // BLTZ
350                                         if (_i32(_rRs_) < 0)
351                                                 return _BranchTarget_;
352                                         break;
353                                 case 0x01: // BGEZ
354                                         if (_i32(_rRs_) >= 0)
355                                                 return _BranchTarget_;
356                                         break;
357                                 case 0x08: // BLTZAL
358                                         if (_i32(_rRs_) < 0) {
359                                                 _SetLink(31);
360                                                 return _BranchTarget_;
361                                         }
362                                         break;
363                                 case 0x09: // BGEZAL
364                                         if (_i32(_rRs_) >= 0) {
365                                                 _SetLink(31);
366                                                 return _BranchTarget_;
367                                         }
368                                         break;
369                         }
370                         break;
371                 case 0x02: // J
372                         return _JumpTarget_;
373                 case 0x03: // JAL
374                         _SetLink(31);
375                         return _JumpTarget_;
376                 case 0x04: // BEQ
377                         if (_i32(_rRs_) == _i32(_rRt_))
378                                 return _BranchTarget_;
379                         break;
380                 case 0x05: // BNE
381                         if (_i32(_rRs_) != _i32(_rRt_))
382                                 return _BranchTarget_;
383                         break;
384                 case 0x06: // BLEZ
385                         if (_i32(_rRs_) <= 0)
386                                 return _BranchTarget_;
387                         break;
388                 case 0x07: // BGTZ
389                         if (_i32(_rRs_) > 0)
390                                 return _BranchTarget_;
391                         break;
392         }
393
394         return (u32)-1;
395 }
396
397 static int psxDelayBranchExec(u32 tar) {
398         execI();
399
400         branch = 0;
401         psxRegs.pc = tar;
402         psxRegs.cycle += BIAS;
403         psxBranchTest();
404         return 1;
405 }
406
407 static int psxDelayBranchTest(u32 tar1) {
408         u32 tar2, tmp1, tmp2;
409
410         tar2 = psxBranchNoDelay();
411         if (tar2 == (u32)-1)
412                 return 0;
413
414         debugI();
415
416         /*
417          * Branch in delay slot:
418          * - execute 1 instruction at tar1
419          * - jump to tar2 (target of branch in delay slot; this branch
420          *   has no normal delay slot, instruction at tar1 was fetched instead)
421          */
422         psxRegs.pc = tar1;
423         tmp1 = psxBranchNoDelay();
424         if (tmp1 == (u32)-1) {
425                 return psxDelayBranchExec(tar2);
426         }
427         debugI();
428         psxRegs.cycle += BIAS;
429
430         /*
431          * Got a branch at tar1:
432          * - execute 1 instruction at tar2
433          * - jump to target of that branch (tmp1)
434          */
435         psxRegs.pc = tar2;
436         tmp2 = psxBranchNoDelay();
437         if (tmp2 == (u32)-1) {
438                 return psxDelayBranchExec(tmp1);
439         }
440         debugI();
441         psxRegs.cycle += BIAS;
442
443         /*
444          * Got a branch at tar2:
445          * - execute 1 instruction at tmp1
446          * - jump to target of that branch (tmp2)
447          */
448         psxRegs.pc = tmp1;
449         return psxDelayBranchExec(tmp2);
450 }
451
452 static void doBranch(u32 tar) {
453         u32 tmp;
454
455         branch2 = branch = 1;
456         branchPC = tar;
457
458         // check for branch in delay slot
459         if (psxDelayBranchTest(tar))
460                 return;
461
462         psxRegs.code = fetch(psxRegs.pc);
463
464         debugI();
465
466         psxRegs.pc += 4;
467         psxRegs.cycle += BIAS;
468
469         // check for load delay
470         tmp = psxRegs.code >> 26;
471         switch (tmp) {
472                 case 0x10: // COP0
473                         switch (_Rs_) {
474                                 case 0x00: // MFC0
475                                 case 0x02: // CFC0
476                                         psxDelayTest(_Rt_, branchPC);
477                                         return;
478                         }
479                         break;
480                 case 0x12: // COP2
481                         switch (_Funct_) {
482                                 case 0x00:
483                                         switch (_Rs_) {
484                                                 case 0x00: // MFC2
485                                                 case 0x02: // CFC2
486                                                         psxDelayTest(_Rt_, branchPC);
487                                                         return;
488                                         }
489                                         break;
490                         }
491                         break;
492                 case 0x32: // LWC2
493                         psxDelayTest(_Rt_, branchPC);
494                         return;
495                 default:
496                         if (tmp >= 0x20 && tmp <= 0x26) { // LB/LH/LWL/LW/LBU/LHU/LWR
497                                 psxDelayTest(_Rt_, branchPC);
498                                 return;
499                         }
500                         break;
501         }
502
503         psxBSC[psxRegs.code >> 26]();
504
505         branch = 0;
506         psxRegs.pc = branchPC;
507
508         psxBranchTest();
509 }
510
511 /*********************************************************
512 * Arithmetic with immediate operand                      *
513 * Format:  OP rt, rs, immediate                          *
514 *********************************************************/
515 void psxADDI()  { if (!_Rt_) return; _rRt_ = _u32(_rRs_) + _Imm_ ; }            // Rt = Rs + Im         (Exception on Integer Overflow)
516 void psxADDIU() { if (!_Rt_) return; _rRt_ = _u32(_rRs_) + _Imm_ ; }            // Rt = Rs + Im
517 void psxANDI()  { if (!_Rt_) return; _rRt_ = _u32(_rRs_) & _ImmU_; }            // Rt = Rs And Im
518 void psxORI()   { if (!_Rt_) return; _rRt_ = _u32(_rRs_) | _ImmU_; }            // Rt = Rs Or  Im
519 void psxXORI()  { if (!_Rt_) return; _rRt_ = _u32(_rRs_) ^ _ImmU_; }            // Rt = Rs Xor Im
520 void psxSLTI()  { if (!_Rt_) return; _rRt_ = _i32(_rRs_) < _Imm_ ; }            // Rt = Rs < Im         (Signed)
521 void psxSLTIU() { if (!_Rt_) return; _rRt_ = _u32(_rRs_) < ((u32)_Imm_); }              // Rt = Rs < Im         (Unsigned)
522
523 /*********************************************************
524 * Register arithmetic                                    *
525 * Format:  OP rd, rs, rt                                 *
526 *********************************************************/
527 void psxADD()   { if (!_Rd_) return; _rRd_ = _u32(_rRs_) + _u32(_rRt_); }       // Rd = Rs + Rt         (Exception on Integer Overflow)
528 void psxADDU()  { if (!_Rd_) return; _rRd_ = _u32(_rRs_) + _u32(_rRt_); }       // Rd = Rs + Rt
529 void psxSUB()   { if (!_Rd_) return; _rRd_ = _u32(_rRs_) - _u32(_rRt_); }       // Rd = Rs - Rt         (Exception on Integer Overflow)
530 void psxSUBU()  { if (!_Rd_) return; _rRd_ = _u32(_rRs_) - _u32(_rRt_); }       // Rd = Rs - Rt
531 void psxAND()   { if (!_Rd_) return; _rRd_ = _u32(_rRs_) & _u32(_rRt_); }       // Rd = Rs And Rt
532 void psxOR()    { if (!_Rd_) return; _rRd_ = _u32(_rRs_) | _u32(_rRt_); }       // Rd = Rs Or  Rt
533 void psxXOR()   { if (!_Rd_) return; _rRd_ = _u32(_rRs_) ^ _u32(_rRt_); }       // Rd = Rs Xor Rt
534 void psxNOR()   { if (!_Rd_) return; _rRd_ =~(_u32(_rRs_) | _u32(_rRt_)); }// Rd = Rs Nor Rt
535 void psxSLT()   { if (!_Rd_) return; _rRd_ = _i32(_rRs_) < _i32(_rRt_); }       // Rd = Rs < Rt         (Signed)
536 void psxSLTU()  { if (!_Rd_) return; _rRd_ = _u32(_rRs_) < _u32(_rRt_); }       // Rd = Rs < Rt         (Unsigned)
537
538 /*********************************************************
539 * Register mult/div & Register trap logic                *
540 * Format:  OP rs, rt                                     *
541 *********************************************************/
542 void psxDIV() {
543     if (!_i32(_rRt_)) {
544         _i32(_rHi_) = _i32(_rRs_);
545         if (_i32(_rRs_) & 0x80000000) {
546             _i32(_rLo_) = 1;
547         } else {
548             _i32(_rLo_) = 0xFFFFFFFF;
549         }
550 /*
551  * Notaz said that this was "not needed" for ARM platforms and could slow it down so let's disable for ARM. 
552  * This fixes a crash issue that can happen when running Amidog's CPU test.
553  * (It still stays stuck to a black screen but at least it doesn't crash anymore)
554  */
555 #if !defined(__arm__) && !defined(__aarch64__)
556     } else if (_i32(_rRs_) == 0x80000000 && _i32(_rRt_) == 0xFFFFFFFF) {
557         _i32(_rLo_) = 0x80000000;
558         _i32(_rHi_) = 0;
559 #endif
560     } else {
561         _i32(_rLo_) = _i32(_rRs_) / _i32(_rRt_);
562         _i32(_rHi_) = _i32(_rRs_) % _i32(_rRt_);
563     }
564 }
565
566 void psxDIV_stall() {
567         psxRegs.muldivBusyCycle = psxRegs.cycle + 37;
568         psxDIV();
569 }
570
571 void psxDIVU() {
572         if (_rRt_ != 0) {
573                 _rLo_ = _rRs_ / _rRt_;
574                 _rHi_ = _rRs_ % _rRt_;
575         }
576         else {
577                 _i32(_rLo_) = 0xffffffff;
578                 _i32(_rHi_) = _i32(_rRs_);
579         }
580 }
581
582 void psxDIVU_stall() {
583         psxRegs.muldivBusyCycle = psxRegs.cycle + 37;
584         psxDIVU();
585 }
586
587 void psxMULT() {
588         u64 res = (s64)((s64)_i32(_rRs_) * (s64)_i32(_rRt_));
589
590         psxRegs.GPR.n.lo = (u32)(res & 0xffffffff);
591         psxRegs.GPR.n.hi = (u32)((res >> 32) & 0xffffffff);
592 }
593
594 void psxMULT_stall() {
595         // approximate, but maybe good enough
596         u32 rs = _rRs_;
597         u32 lz = __builtin_clz(((rs ^ ((s32)rs >> 21)) | 1));
598         u32 c = 7 + (2 - (lz / 11)) * 4;
599         psxRegs.muldivBusyCycle = psxRegs.cycle + c;
600         psxMULT();
601 }
602
603 void psxMULTU() {
604         u64 res = (u64)((u64)_u32(_rRs_) * (u64)_u32(_rRt_));
605
606         psxRegs.GPR.n.lo = (u32)(res & 0xffffffff);
607         psxRegs.GPR.n.hi = (u32)((res >> 32) & 0xffffffff);
608 }
609
610 void psxMULTU_stall() {
611         // approximate, but maybe good enough
612         u32 lz = __builtin_clz(_rRs_ | 1);
613         u32 c = 7 + (2 - (lz / 11)) * 4;
614         psxRegs.muldivBusyCycle = psxRegs.cycle + c;
615         psxMULTU();
616 }
617
618 /*********************************************************
619 * Register branch logic                                  *
620 * Format:  OP rs, offset                                 *
621 *********************************************************/
622 #define RepZBranchi32(op)      if(_i32(_rRs_) op 0) doBranch(_BranchTarget_);
623 #define RepZBranchLinki32(op)  { _SetLink(31); if(_i32(_rRs_) op 0) { doBranch(_BranchTarget_); } }
624
625 void psxBGEZ()   { RepZBranchi32(>=) }      // Branch if Rs >= 0
626 void psxBGEZAL() { RepZBranchLinki32(>=) }  // Branch if Rs >= 0 and link
627 void psxBGTZ()   { RepZBranchi32(>) }       // Branch if Rs >  0
628 void psxBLEZ()   { RepZBranchi32(<=) }      // Branch if Rs <= 0
629 void psxBLTZ()   { RepZBranchi32(<) }       // Branch if Rs <  0
630 void psxBLTZAL() { RepZBranchLinki32(<) }   // Branch if Rs <  0 and link
631
632 /*********************************************************
633 * Shift arithmetic with constant shift                   *
634 * Format:  OP rd, rt, sa                                 *
635 *********************************************************/
636 void psxSLL() { if (!_Rd_) return; _u32(_rRd_) = _u32(_rRt_) << _Sa_; } // Rd = Rt << sa
637 void psxSRA() { if (!_Rd_) return; _i32(_rRd_) = _i32(_rRt_) >> _Sa_; } // Rd = Rt >> sa (arithmetic)
638 void psxSRL() { if (!_Rd_) return; _u32(_rRd_) = _u32(_rRt_) >> _Sa_; } // Rd = Rt >> sa (logical)
639
640 /*********************************************************
641 * Shift arithmetic with variant register shift           *
642 * Format:  OP rd, rt, rs                                 *
643 *********************************************************/
644 void psxSLLV() { if (!_Rd_) return; _u32(_rRd_) = _u32(_rRt_) << (_u32(_rRs_) & 0x1F); } // Rd = Rt << rs
645 void psxSRAV() { if (!_Rd_) return; _i32(_rRd_) = _i32(_rRt_) >> (_u32(_rRs_) & 0x1F); } // Rd = Rt >> rs (arithmetic)
646 void psxSRLV() { if (!_Rd_) return; _u32(_rRd_) = _u32(_rRt_) >> (_u32(_rRs_) & 0x1F); } // Rd = Rt >> rs (logical)
647
648 /*********************************************************
649 * Load higher 16 bits of the first word in GPR with imm  *
650 * Format:  OP rt, immediate                              *
651 *********************************************************/
652 void psxLUI() { if (!_Rt_) return; _u32(_rRt_) = psxRegs.code << 16; } // Upper halfword of Rt = Im
653
654 /*********************************************************
655 * Move from HI/LO to GPR                                 *
656 * Format:  OP rd                                         *
657 *********************************************************/
658 void psxMFHI() { if (!_Rd_) return; _rRd_ = _rHi_; } // Rd = Hi
659 void psxMFLO() { if (!_Rd_) return; _rRd_ = _rLo_; } // Rd = Lo
660
661 static void mflohiCheckStall(void)
662 {
663         u32 left = psxRegs.muldivBusyCycle - psxRegs.cycle;
664         if (left <= 37) {
665                 //printf("muldiv stall %u\n", left);
666                 psxRegs.cycle = psxRegs.muldivBusyCycle;
667         }
668 }
669
670 void psxMFHI_stall() { mflohiCheckStall(); psxMFHI(); }
671 void psxMFLO_stall() { mflohiCheckStall(); psxMFLO(); }
672
673 /*********************************************************
674 * Move to GPR to HI/LO & Register jump                   *
675 * Format:  OP rs                                         *
676 *********************************************************/
677 void psxMTHI() { _rHi_ = _rRs_; } // Hi = Rs
678 void psxMTLO() { _rLo_ = _rRs_; } // Lo = Rs
679
680 /*********************************************************
681 * Special purpose instructions                           *
682 * Format:  OP                                            *
683 *********************************************************/
684 void psxBREAK() {
685         psxRegs.pc -= 4;
686         psxException(0x24, branch);
687 }
688
689 void psxSYSCALL() {
690         psxRegs.pc -= 4;
691         psxException(0x20, branch);
692 }
693
694 void psxRFE() {
695 //      SysPrintf("psxRFE\n");
696         psxRegs.CP0.n.Status = (psxRegs.CP0.n.Status & 0xfffffff0) |
697                                                   ((psxRegs.CP0.n.Status & 0x3c) >> 2);
698         psxTestSWInts();
699 }
700
701 /*********************************************************
702 * Register branch logic                                  *
703 * Format:  OP rs, rt, offset                             *
704 *********************************************************/
705 #define RepBranchi32(op)      if(_i32(_rRs_) op _i32(_rRt_)) doBranch(_BranchTarget_);
706
707 void psxBEQ() { RepBranchi32(==) }  // Branch if Rs == Rt
708 void psxBNE() { RepBranchi32(!=) }  // Branch if Rs != Rt
709
710 /*********************************************************
711 * Jump to target                                         *
712 * Format:  OP target                                     *
713 *********************************************************/
714 void psxJ()   {               doBranch(_JumpTarget_); }
715 void psxJAL() { _SetLink(31); doBranch(_JumpTarget_); }
716
717 /*********************************************************
718 * Register jump                                          *
719 * Format:  OP rs, rd                                     *
720 *********************************************************/
721 void psxJR()   {
722         doBranch(_rRs_ & ~3);
723         psxJumpTest();
724 }
725
726 void psxJALR() {
727         u32 temp = _u32(_rRs_);
728         if (_Rd_) { _SetLink(_Rd_); }
729         doBranch(temp & ~3);
730 }
731
732 /*********************************************************
733 * Load and store for GPR                                 *
734 * Format:  OP rt, offset(base)                           *
735 *********************************************************/
736
737 #define _oB_ (_u32(_rRs_) + _Imm_)
738
739 void psxLB() {
740         if (_Rt_) {
741                 _i32(_rRt_) = (signed char)psxMemRead8(_oB_); 
742         } else {
743                 psxMemRead8(_oB_); 
744         }
745 }
746
747 void psxLBU() {
748         if (_Rt_) {
749                 _u32(_rRt_) = psxMemRead8(_oB_);
750         } else {
751                 psxMemRead8(_oB_); 
752         }
753 }
754
755 void psxLH() {
756         if (_Rt_) {
757                 _i32(_rRt_) = (short)psxMemRead16(_oB_);
758         } else {
759                 psxMemRead16(_oB_);
760         }
761 }
762
763 void psxLHU() {
764         if (_Rt_) {
765                 _u32(_rRt_) = psxMemRead16(_oB_);
766         } else {
767                 psxMemRead16(_oB_);
768         }
769 }
770
771 void psxLW() {
772         if (_Rt_) {
773                 _u32(_rRt_) = psxMemRead32(_oB_);
774         } else {
775                 psxMemRead32(_oB_);
776         }
777 }
778
779 u32 LWL_MASK[4] = { 0xffffff, 0xffff, 0xff, 0 };
780 u32 LWL_SHIFT[4] = { 24, 16, 8, 0 };
781
782 void psxLWL() {
783         u32 addr = _oB_;
784         u32 shift = addr & 3;
785         u32 mem = psxMemRead32(addr & ~3);
786
787         if (!_Rt_) return;
788         _u32(_rRt_) =   ( _u32(_rRt_) & LWL_MASK[shift]) | 
789                                         ( mem << LWL_SHIFT[shift]);
790
791         /*
792         Mem = 1234.  Reg = abcd
793
794         0   4bcd   (mem << 24) | (reg & 0x00ffffff)
795         1   34cd   (mem << 16) | (reg & 0x0000ffff)
796         2   234d   (mem <<  8) | (reg & 0x000000ff)
797         3   1234   (mem      ) | (reg & 0x00000000)
798         */
799 }
800
801 u32 LWR_MASK[4] = { 0, 0xff000000, 0xffff0000, 0xffffff00 };
802 u32 LWR_SHIFT[4] = { 0, 8, 16, 24 };
803
804 void psxLWR() {
805         u32 addr = _oB_;
806         u32 shift = addr & 3;
807         u32 mem = psxMemRead32(addr & ~3);
808
809         if (!_Rt_) return;
810         _u32(_rRt_) =   ( _u32(_rRt_) & LWR_MASK[shift]) | 
811                                         ( mem >> LWR_SHIFT[shift]);
812
813         /*
814         Mem = 1234.  Reg = abcd
815
816         0   1234   (mem      ) | (reg & 0x00000000)
817         1   a123   (mem >>  8) | (reg & 0xff000000)
818         2   ab12   (mem >> 16) | (reg & 0xffff0000)
819         3   abc1   (mem >> 24) | (reg & 0xffffff00)
820         */
821 }
822
823 void psxSB() { psxMemWrite8 (_oB_, _rRt_ &   0xff); }
824 void psxSH() { psxMemWrite16(_oB_, _rRt_ & 0xffff); }
825 void psxSW() { psxMemWrite32(_oB_, _rRt_); }
826
827 u32 SWL_MASK[4] = { 0xffffff00, 0xffff0000, 0xff000000, 0 };
828 u32 SWL_SHIFT[4] = { 24, 16, 8, 0 };
829
830 void psxSWL() {
831         u32 addr = _oB_;
832         u32 shift = addr & 3;
833         u32 mem = psxMemRead32(addr & ~3);
834
835         psxMemWrite32(addr & ~3,  (_u32(_rRt_) >> SWL_SHIFT[shift]) |
836                              (  mem & SWL_MASK[shift]) );
837         /*
838         Mem = 1234.  Reg = abcd
839
840         0   123a   (reg >> 24) | (mem & 0xffffff00)
841         1   12ab   (reg >> 16) | (mem & 0xffff0000)
842         2   1abc   (reg >>  8) | (mem & 0xff000000)
843         3   abcd   (reg      ) | (mem & 0x00000000)
844         */
845 }
846
847 u32 SWR_MASK[4] = { 0, 0xff, 0xffff, 0xffffff };
848 u32 SWR_SHIFT[4] = { 0, 8, 16, 24 };
849
850 void psxSWR() {
851         u32 addr = _oB_;
852         u32 shift = addr & 3;
853         u32 mem = psxMemRead32(addr & ~3);
854
855         psxMemWrite32(addr & ~3,  (_u32(_rRt_) << SWR_SHIFT[shift]) |
856                              (  mem & SWR_MASK[shift]) );
857
858         /*
859         Mem = 1234.  Reg = abcd
860
861         0   abcd   (reg      ) | (mem & 0x00000000)
862         1   bcd4   (reg <<  8) | (mem & 0x000000ff)
863         2   cd34   (reg << 16) | (mem & 0x0000ffff)
864         3   d234   (reg << 24) | (mem & 0x00ffffff)
865         */
866 }
867
868 /*********************************************************
869 * Moves between GPR and COPx                             *
870 * Format:  OP rt, fs                                     *
871 *********************************************************/
872 void psxMFC0() { if (!_Rt_) return; _i32(_rRt_) = (int)_rFs_; }
873 void psxCFC0() { if (!_Rt_) return; _i32(_rRt_) = (int)_rFs_; }
874
875 void psxTestSWInts() {
876         if (psxRegs.CP0.n.Cause & psxRegs.CP0.n.Status & 0x0300 &&
877            psxRegs.CP0.n.Status & 0x1) {
878                 psxRegs.CP0.n.Cause &= ~0x7c;
879                 psxException(psxRegs.CP0.n.Cause, branch);
880         }
881 }
882
883 void MTC0(int reg, u32 val) {
884 //      SysPrintf("MTC0 %d: %x\n", reg, val);
885         switch (reg) {
886                 case 12: // Status
887                         psxRegs.CP0.r[12] = val;
888                         psxTestSWInts();
889                         break;
890
891                 case 13: // Cause
892                         psxRegs.CP0.n.Cause &= ~0x0300;
893                         psxRegs.CP0.n.Cause |= val & 0x0300;
894                         psxTestSWInts();
895                         break;
896
897                 default:
898                         psxRegs.CP0.r[reg] = val;
899                         break;
900         }
901 }
902
903 void psxMTC0() { MTC0(_Rd_, _u32(_rRt_)); }
904 void psxCTC0() { MTC0(_Rd_, _u32(_rRt_)); }
905
906 /*********************************************************
907 * Unknow instruction (would generate an exception)       *
908 * Format:  ?                                             *
909 *********************************************************/
910 void psxNULL() { 
911 #ifdef PSXCPU_LOG
912         PSXCPU_LOG("psx: Unimplemented op %x\n", psxRegs.code);
913 #endif
914 }
915
916 void psxSPECIAL() {
917         psxSPC[_Funct_]();
918 }
919
920 void psxREGIMM() {
921         psxREG[_Rt_]();
922 }
923
924 void psxCOP0() {
925         psxCP0[_Rs_]();
926 }
927
928 void psxCOP2() {
929         psxCP2[_Funct_]((struct psxCP2Regs *)&psxRegs.CP2D);
930 }
931
932 void psxCOP2_stall() {
933         u32 f = _Funct_;
934         gteCheckStall(f);
935         psxCP2[f]((struct psxCP2Regs *)&psxRegs.CP2D);
936 }
937
938 void psxBASIC(struct psxCP2Regs *regs) {
939         psxCP2BSC[_Rs_]();
940 }
941
942 void psxHLE() {
943 //      psxHLEt[psxRegs.code & 0xffff]();
944 //      psxHLEt[psxRegs.code & 0x07]();         // HDHOSHY experimental patch
945     uint32_t hleCode = psxRegs.code & 0x03ffffff;
946     if (hleCode >= (sizeof(psxHLEt) / sizeof(psxHLEt[0]))) {
947         psxNULL();
948     } else {
949         psxHLEt[hleCode]();
950     }
951 }
952
953 void (*psxBSC[64])() = {
954         psxSPECIAL, psxREGIMM, psxJ   , psxJAL  , psxBEQ , psxBNE , psxBLEZ, psxBGTZ,
955         psxADDI   , psxADDIU , psxSLTI, psxSLTIU, psxANDI, psxORI , psxXORI, psxLUI ,
956         psxCOP0   , psxNULL  , psxCOP2, psxNULL , psxNULL, psxNULL, psxNULL, psxNULL,
957         psxNULL   , psxNULL  , psxNULL, psxNULL , psxNULL, psxNULL, psxNULL, psxNULL,
958         psxLB     , psxLH    , psxLWL , psxLW   , psxLBU , psxLHU , psxLWR , psxNULL,
959         psxSB     , psxSH    , psxSWL , psxSW   , psxNULL, psxNULL, psxSWR , psxNULL, 
960         psxNULL   , psxNULL  , gteLWC2, psxNULL , psxNULL, psxNULL, psxNULL, psxNULL,
961         psxNULL   , psxNULL  , gteSWC2, psxHLE  , psxNULL, psxNULL, psxNULL, psxNULL 
962 };
963
964
965 void (*psxSPC[64])() = {
966         psxSLL , psxNULL , psxSRL , psxSRA , psxSLLV   , psxNULL , psxSRLV, psxSRAV,
967         psxJR  , psxJALR , psxNULL, psxNULL, psxSYSCALL, psxBREAK, psxNULL, psxNULL,
968         psxMFHI, psxMTHI , psxMFLO, psxMTLO, psxNULL   , psxNULL , psxNULL, psxNULL,
969         psxMULT, psxMULTU, psxDIV , psxDIVU, psxNULL   , psxNULL , psxNULL, psxNULL,
970         psxADD , psxADDU , psxSUB , psxSUBU, psxAND    , psxOR   , psxXOR , psxNOR ,
971         psxNULL, psxNULL , psxSLT , psxSLTU, psxNULL   , psxNULL , psxNULL, psxNULL,
972         psxNULL, psxNULL , psxNULL, psxNULL, psxNULL   , psxNULL , psxNULL, psxNULL,
973         psxNULL, psxNULL , psxNULL, psxNULL, psxNULL   , psxNULL , psxNULL, psxNULL
974 };
975
976 void (*psxREG[32])() = {
977         psxBLTZ  , psxBGEZ  , psxNULL, psxNULL, psxNULL, psxNULL, psxNULL, psxNULL,
978         psxNULL  , psxNULL  , psxNULL, psxNULL, psxNULL, psxNULL, psxNULL, psxNULL,
979         psxBLTZAL, psxBGEZAL, psxNULL, psxNULL, psxNULL, psxNULL, psxNULL, psxNULL,
980         psxNULL  , psxNULL  , psxNULL, psxNULL, psxNULL, psxNULL, psxNULL, psxNULL
981 };
982
983 void (*psxCP0[32])() = {
984         psxMFC0, psxNULL, psxCFC0, psxNULL, psxMTC0, psxNULL, psxCTC0, psxNULL,
985         psxNULL, psxNULL, psxNULL, psxNULL, psxNULL, psxNULL, psxNULL, psxNULL,
986         psxRFE , psxNULL, psxNULL, psxNULL, psxNULL, psxNULL, psxNULL, psxNULL,
987         psxNULL, psxNULL, psxNULL, psxNULL, psxNULL, psxNULL, psxNULL, psxNULL
988 };
989
990 void (*psxCP2[64])(struct psxCP2Regs *regs) = {
991         psxBASIC, gteRTPS , psxNULL , psxNULL, psxNULL, psxNULL , gteNCLIP, psxNULL, // 00
992         psxNULL , psxNULL , psxNULL , psxNULL, gteOP  , psxNULL , psxNULL , psxNULL, // 08
993         gteDPCS , gteINTPL, gteMVMVA, gteNCDS, gteCDP , psxNULL , gteNCDT , psxNULL, // 10
994         psxNULL , psxNULL , psxNULL , gteNCCS, gteCC  , psxNULL , gteNCS  , psxNULL, // 18
995         gteNCT  , psxNULL , psxNULL , psxNULL, psxNULL, psxNULL , psxNULL , psxNULL, // 20
996         gteSQR  , gteDCPL , gteDPCT , psxNULL, psxNULL, gteAVSZ3, gteAVSZ4, psxNULL, // 28 
997         gteRTPT , psxNULL , psxNULL , psxNULL, psxNULL, psxNULL , psxNULL , psxNULL, // 30
998         psxNULL , psxNULL , psxNULL , psxNULL, psxNULL, gteGPF  , gteGPL  , gteNCCT  // 38
999 };
1000
1001 void (*psxCP2BSC[32])() = {
1002         gteMFC2, psxNULL, gteCFC2, psxNULL, gteMTC2, psxNULL, gteCTC2, psxNULL,
1003         psxNULL, psxNULL, psxNULL, psxNULL, psxNULL, psxNULL, psxNULL, psxNULL,
1004         psxNULL, psxNULL, psxNULL, psxNULL, psxNULL, psxNULL, psxNULL, psxNULL,
1005         psxNULL, psxNULL, psxNULL, psxNULL, psxNULL, psxNULL, psxNULL, psxNULL
1006 };
1007
1008
1009 ///////////////////////////////////////////
1010
1011 static int intInit() {
1012         return 0;
1013 }
1014
1015 static void intReset() {
1016         memset(&ICache, 0xff, sizeof(ICache));
1017 }
1018
1019 void intExecute() {
1020         extern int stop;
1021         for (;!stop;) 
1022                 execI();
1023 }
1024
1025 void intExecuteBlock() {
1026         branch2 = 0;
1027         while (!branch2) execI();
1028 }
1029
1030 static void intClear(u32 Addr, u32 Size) {
1031 }
1032
1033 void intNotify (int note, void *data) {
1034         /* Gameblabla - Only clear the icache if it's isolated */
1035         if (note == R3000ACPU_NOTIFY_CACHE_ISOLATED)
1036         {
1037                 memset(&ICache, 0xff, sizeof(ICache));
1038         }
1039 }
1040
1041 void intApplyConfig() {
1042         assert(psxBSC[18] == psxCOP2  || psxBSC[18] == psxCOP2_stall);
1043         assert(psxBSC[50] == gteLWC2  || psxBSC[50] == gteLWC2_stall);
1044         assert(psxBSC[58] == gteSWC2  || psxBSC[58] == gteSWC2_stall);
1045         assert(psxSPC[16] == psxMFHI  || psxSPC[16] == psxMFHI_stall);
1046         assert(psxSPC[18] == psxMFLO  || psxSPC[18] == psxMFLO_stall);
1047         assert(psxSPC[24] == psxMULT  || psxSPC[24] == psxMULT_stall);
1048         assert(psxSPC[25] == psxMULTU || psxSPC[25] == psxMULTU_stall);
1049         assert(psxSPC[26] == psxDIV   || psxSPC[26] == psxDIV_stall);
1050         assert(psxSPC[27] == psxDIVU  || psxSPC[27] == psxDIVU_stall);
1051
1052         if (Config.DisableStalls) {
1053                 psxBSC[18] = psxCOP2;
1054                 psxBSC[50] = gteLWC2;
1055                 psxBSC[58] = gteSWC2;
1056                 psxSPC[16] = psxMFHI;
1057                 psxSPC[18] = psxMFLO;
1058                 psxSPC[24] = psxMULT;
1059                 psxSPC[25] = psxMULTU;
1060                 psxSPC[26] = psxDIV;
1061                 psxSPC[27] = psxDIVU;
1062         } else {
1063                 psxBSC[18] = psxCOP2_stall;
1064                 psxBSC[50] = gteLWC2_stall;
1065                 psxBSC[58] = gteSWC2_stall;
1066                 psxSPC[16] = psxMFHI_stall;
1067                 psxSPC[18] = psxMFLO_stall;
1068                 psxSPC[24] = psxMULT_stall;
1069                 psxSPC[25] = psxMULTU_stall;
1070                 psxSPC[26] = psxDIV_stall;
1071                 psxSPC[27] = psxDIVU_stall;
1072         }
1073
1074         // dynarec may occasionally call the interpreter, in such a case the
1075         // cache won't work (cache only works right if all fetches go through it)
1076         if (!Config.icache_emulation || psxCpu != &psxInt)
1077                 fetch = fetchNoCache;
1078         else
1079                 fetch = fetchICache;
1080 }
1081
1082 static void intShutdown() {
1083 }
1084
1085 // interpreter execution
1086 void execI() {
1087         psxRegs.code = fetch(psxRegs.pc);
1088
1089         debugI();
1090
1091         if (Config.Debug) ProcessDebug();
1092
1093         psxRegs.pc += 4;
1094         psxRegs.cycle += BIAS;
1095
1096         psxBSC[psxRegs.code >> 26]();
1097 }
1098
1099 R3000Acpu psxInt = {
1100         intInit,
1101         intReset,
1102         intExecute,
1103         intExecuteBlock,
1104         intClear,
1105         intNotify,
1106         intApplyConfig,
1107         intShutdown
1108 };