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