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