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