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