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