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