Handle DIV overflow in lightrec and the interpreter
[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_)) {
511         _i32(_rHi_) = _i32(_rRs_);
512         if (_i32(_rRs_) & 0x80000000) {
513             _i32(_rLo_) = 1;
514         } else {
515             _i32(_rLo_) = 0xFFFFFFFF;
516         }
517     } else if (_i32(_rRs_) == 0x80000000 && _i32(_rRt_) == 0xFFFFFFFF) {
518         _i32(_rLo_) = 0x80000000;
519         _i32(_rHi_) = 0;
520     } else {
521         _i32(_rLo_) = _i32(_rRs_) / _i32(_rRt_);
522         _i32(_rHi_) = _i32(_rRs_) % _i32(_rRt_);
523     }
524 }
525
526 void psxDIVU() {
527         if (_rRt_ != 0) {
528                 _rLo_ = _rRs_ / _rRt_;
529                 _rHi_ = _rRs_ % _rRt_;
530         }
531         else {
532                 _i32(_rLo_) = 0xffffffff;
533                 _i32(_rHi_) = _i32(_rRs_);
534         }
535 }
536
537 void psxMULT() {
538         u64 res = (s64)((s64)_i32(_rRs_) * (s64)_i32(_rRt_));
539
540         psxRegs.GPR.n.lo = (u32)(res & 0xffffffff);
541         psxRegs.GPR.n.hi = (u32)((res >> 32) & 0xffffffff);
542 }
543
544 void psxMULTU() {
545         u64 res = (u64)((u64)_u32(_rRs_) * (u64)_u32(_rRt_));
546
547         psxRegs.GPR.n.lo = (u32)(res & 0xffffffff);
548         psxRegs.GPR.n.hi = (u32)((res >> 32) & 0xffffffff);
549 }
550
551 /*********************************************************
552 * Register branch logic                                  *
553 * Format:  OP rs, offset                                 *
554 *********************************************************/
555 #define RepZBranchi32(op)      if(_i32(_rRs_) op 0) doBranch(_BranchTarget_);
556 #define RepZBranchLinki32(op)  if(_i32(_rRs_) op 0) { _SetLink(31); doBranch(_BranchTarget_); }
557
558 void psxBGEZ()   { RepZBranchi32(>=) }      // Branch if Rs >= 0
559 void psxBGEZAL() { RepZBranchLinki32(>=) }  // Branch if Rs >= 0 and link
560 void psxBGTZ()   { RepZBranchi32(>) }       // Branch if Rs >  0
561 void psxBLEZ()   { RepZBranchi32(<=) }      // Branch if Rs <= 0
562 void psxBLTZ()   { RepZBranchi32(<) }       // Branch if Rs <  0
563 void psxBLTZAL() { RepZBranchLinki32(<) }   // Branch if Rs <  0 and link
564
565 /*********************************************************
566 * Shift arithmetic with constant shift                   *
567 * Format:  OP rd, rt, sa                                 *
568 *********************************************************/
569 void psxSLL() { if (!_Rd_) return; _u32(_rRd_) = _u32(_rRt_) << _Sa_; } // Rd = Rt << sa
570 void psxSRA() { if (!_Rd_) return; _i32(_rRd_) = _i32(_rRt_) >> _Sa_; } // Rd = Rt >> sa (arithmetic)
571 void psxSRL() { if (!_Rd_) return; _u32(_rRd_) = _u32(_rRt_) >> _Sa_; } // Rd = Rt >> sa (logical)
572
573 /*********************************************************
574 * Shift arithmetic with variant register shift           *
575 * Format:  OP rd, rt, rs                                 *
576 *********************************************************/
577 void psxSLLV() { if (!_Rd_) return; _u32(_rRd_) = _u32(_rRt_) << _u32(_rRs_); } // Rd = Rt << rs
578 void psxSRAV() { if (!_Rd_) return; _i32(_rRd_) = _i32(_rRt_) >> _u32(_rRs_); } // Rd = Rt >> rs (arithmetic)
579 void psxSRLV() { if (!_Rd_) return; _u32(_rRd_) = _u32(_rRt_) >> _u32(_rRs_); } // Rd = Rt >> rs (logical)
580
581 /*********************************************************
582 * Load higher 16 bits of the first word in GPR with imm  *
583 * Format:  OP rt, immediate                              *
584 *********************************************************/
585 void psxLUI() { if (!_Rt_) return; _u32(_rRt_) = psxRegs.code << 16; } // Upper halfword of Rt = Im
586
587 /*********************************************************
588 * Move from HI/LO to GPR                                 *
589 * Format:  OP rd                                         *
590 *********************************************************/
591 void psxMFHI() { if (!_Rd_) return; _rRd_ = _rHi_; } // Rd = Hi
592 void psxMFLO() { if (!_Rd_) return; _rRd_ = _rLo_; } // Rd = Lo
593
594 /*********************************************************
595 * Move to GPR to HI/LO & Register jump                   *
596 * Format:  OP rs                                         *
597 *********************************************************/
598 void psxMTHI() { _rHi_ = _rRs_; } // Hi = Rs
599 void psxMTLO() { _rLo_ = _rRs_; } // Lo = Rs
600
601 /*********************************************************
602 * Special purpose instructions                           *
603 * Format:  OP                                            *
604 *********************************************************/
605 void psxBREAK() {
606         // Break exception - psx rom doens't handles this
607 }
608
609 void psxSYSCALL() {
610         psxRegs.pc -= 4;
611         psxException(0x20, branch);
612 }
613
614 void psxRFE() {
615 //      SysPrintf("psxRFE\n");
616         psxRegs.CP0.n.Status = (psxRegs.CP0.n.Status & 0xfffffff0) |
617                                                   ((psxRegs.CP0.n.Status & 0x3c) >> 2);
618 }
619
620 /*********************************************************
621 * Register branch logic                                  *
622 * Format:  OP rs, rt, offset                             *
623 *********************************************************/
624 #define RepBranchi32(op)      if(_i32(_rRs_) op _i32(_rRt_)) doBranch(_BranchTarget_);
625
626 void psxBEQ() { RepBranchi32(==) }  // Branch if Rs == Rt
627 void psxBNE() { RepBranchi32(!=) }  // Branch if Rs != Rt
628
629 /*********************************************************
630 * Jump to target                                         *
631 * Format:  OP target                                     *
632 *********************************************************/
633 void psxJ()   {               doBranch(_JumpTarget_); }
634 void psxJAL() { _SetLink(31); doBranch(_JumpTarget_); }
635
636 /*********************************************************
637 * Register jump                                          *
638 * Format:  OP rs, rd                                     *
639 *********************************************************/
640 void psxJR()   {
641         doBranch(_u32(_rRs_));
642         psxJumpTest();
643 }
644
645 void psxJALR() {
646         u32 temp = _u32(_rRs_);
647         if (_Rd_) { _SetLink(_Rd_); }
648         doBranch(temp);
649 }
650
651 /*********************************************************
652 * Load and store for GPR                                 *
653 * Format:  OP rt, offset(base)                           *
654 *********************************************************/
655
656 #define _oB_ (_u32(_rRs_) + _Imm_)
657
658 void psxLB() {
659         if (_Rt_) {
660                 _i32(_rRt_) = (signed char)psxMemRead8(_oB_); 
661         } else {
662                 psxMemRead8(_oB_); 
663         }
664 }
665
666 void psxLBU() {
667         if (_Rt_) {
668                 _u32(_rRt_) = psxMemRead8(_oB_);
669         } else {
670                 psxMemRead8(_oB_); 
671         }
672 }
673
674 void psxLH() {
675         if (_Rt_) {
676                 _i32(_rRt_) = (short)psxMemRead16(_oB_);
677         } else {
678                 psxMemRead16(_oB_);
679         }
680 }
681
682 void psxLHU() {
683         if (_Rt_) {
684                 _u32(_rRt_) = psxMemRead16(_oB_);
685         } else {
686                 psxMemRead16(_oB_);
687         }
688 }
689
690 void psxLW() {
691         if (_Rt_) {
692                 _u32(_rRt_) = psxMemRead32(_oB_);
693         } else {
694                 psxMemRead32(_oB_);
695         }
696 }
697
698 u32 LWL_MASK[4] = { 0xffffff, 0xffff, 0xff, 0 };
699 u32 LWL_SHIFT[4] = { 24, 16, 8, 0 };
700
701 void psxLWL() {
702         u32 addr = _oB_;
703         u32 shift = addr & 3;
704         u32 mem = psxMemRead32(addr & ~3);
705
706         if (!_Rt_) return;
707         _u32(_rRt_) =   ( _u32(_rRt_) & LWL_MASK[shift]) | 
708                                         ( mem << LWL_SHIFT[shift]);
709
710         /*
711         Mem = 1234.  Reg = abcd
712
713         0   4bcd   (mem << 24) | (reg & 0x00ffffff)
714         1   34cd   (mem << 16) | (reg & 0x0000ffff)
715         2   234d   (mem <<  8) | (reg & 0x000000ff)
716         3   1234   (mem      ) | (reg & 0x00000000)
717         */
718 }
719
720 u32 LWR_MASK[4] = { 0, 0xff000000, 0xffff0000, 0xffffff00 };
721 u32 LWR_SHIFT[4] = { 0, 8, 16, 24 };
722
723 void psxLWR() {
724         u32 addr = _oB_;
725         u32 shift = addr & 3;
726         u32 mem = psxMemRead32(addr & ~3);
727
728         if (!_Rt_) return;
729         _u32(_rRt_) =   ( _u32(_rRt_) & LWR_MASK[shift]) | 
730                                         ( mem >> LWR_SHIFT[shift]);
731
732         /*
733         Mem = 1234.  Reg = abcd
734
735         0   1234   (mem      ) | (reg & 0x00000000)
736         1   a123   (mem >>  8) | (reg & 0xff000000)
737         2   ab12   (mem >> 16) | (reg & 0xffff0000)
738         3   abc1   (mem >> 24) | (reg & 0xffffff00)
739         */
740 }
741
742 void psxSB() { psxMemWrite8 (_oB_, _rRt_ &   0xff); }
743 void psxSH() { psxMemWrite16(_oB_, _rRt_ & 0xffff); }
744 void psxSW() { psxMemWrite32(_oB_, _rRt_); }
745
746 u32 SWL_MASK[4] = { 0xffffff00, 0xffff0000, 0xff000000, 0 };
747 u32 SWL_SHIFT[4] = { 24, 16, 8, 0 };
748
749 void psxSWL() {
750         u32 addr = _oB_;
751         u32 shift = addr & 3;
752         u32 mem = psxMemRead32(addr & ~3);
753
754         psxMemWrite32(addr & ~3,  (_u32(_rRt_) >> SWL_SHIFT[shift]) |
755                              (  mem & SWL_MASK[shift]) );
756         /*
757         Mem = 1234.  Reg = abcd
758
759         0   123a   (reg >> 24) | (mem & 0xffffff00)
760         1   12ab   (reg >> 16) | (mem & 0xffff0000)
761         2   1abc   (reg >>  8) | (mem & 0xff000000)
762         3   abcd   (reg      ) | (mem & 0x00000000)
763         */
764 }
765
766 u32 SWR_MASK[4] = { 0, 0xff, 0xffff, 0xffffff };
767 u32 SWR_SHIFT[4] = { 0, 8, 16, 24 };
768
769 void psxSWR() {
770         u32 addr = _oB_;
771         u32 shift = addr & 3;
772         u32 mem = psxMemRead32(addr & ~3);
773
774         psxMemWrite32(addr & ~3,  (_u32(_rRt_) << SWR_SHIFT[shift]) |
775                              (  mem & SWR_MASK[shift]) );
776
777         /*
778         Mem = 1234.  Reg = abcd
779
780         0   abcd   (reg      ) | (mem & 0x00000000)
781         1   bcd4   (reg <<  8) | (mem & 0x000000ff)
782         2   cd34   (reg << 16) | (mem & 0x0000ffff)
783         3   d234   (reg << 24) | (mem & 0x00ffffff)
784         */
785 }
786
787 /*********************************************************
788 * Moves between GPR and COPx                             *
789 * Format:  OP rt, fs                                     *
790 *********************************************************/
791 void psxMFC0() { if (!_Rt_) return; _i32(_rRt_) = (int)_rFs_; }
792 void psxCFC0() { if (!_Rt_) return; _i32(_rRt_) = (int)_rFs_; }
793
794 void psxTestSWInts() {
795         if (psxRegs.CP0.n.Cause & psxRegs.CP0.n.Status & 0x0300 &&
796            psxRegs.CP0.n.Status & 0x1) {
797                 psxRegs.CP0.n.Cause &= ~0x7c;
798                 psxException(psxRegs.CP0.n.Cause, branch);
799         }
800 }
801
802 void MTC0(int reg, u32 val) {
803 //      SysPrintf("MTC0 %d: %x\n", reg, val);
804         switch (reg) {
805                 case 12: // Status
806                         psxRegs.CP0.r[12] = val;
807                         psxTestSWInts();
808                         break;
809
810                 case 13: // Cause
811                         psxRegs.CP0.n.Cause &= ~0x0300;
812                         psxRegs.CP0.n.Cause |= val & 0x0300;
813                         psxTestSWInts();
814                         break;
815
816                 default:
817                         psxRegs.CP0.r[reg] = val;
818                         break;
819         }
820 }
821
822 void psxMTC0() { MTC0(_Rd_, _u32(_rRt_)); }
823 void psxCTC0() { MTC0(_Rd_, _u32(_rRt_)); }
824
825 /*********************************************************
826 * Unknow instruction (would generate an exception)       *
827 * Format:  ?                                             *
828 *********************************************************/
829 void psxNULL() { 
830 #ifdef PSXCPU_LOG
831         PSXCPU_LOG("psx: Unimplemented op %x\n", psxRegs.code);
832 #endif
833 }
834
835 void psxSPECIAL() {
836         psxSPC[_Funct_]();
837 }
838
839 void psxREGIMM() {
840         psxREG[_Rt_]();
841 }
842
843 void psxCOP0() {
844         psxCP0[_Rs_]();
845 }
846
847 void psxCOP2() {
848         psxCP2[_Funct_]((struct psxCP2Regs *)&psxRegs.CP2D);
849 }
850
851 void psxBASIC(struct psxCP2Regs *regs) {
852         psxCP2BSC[_Rs_]();
853 }
854
855 void psxHLE() {
856 //      psxHLEt[psxRegs.code & 0xffff]();
857         psxHLEt[psxRegs.code & 0x07]();         // HDHOSHY experimental patch
858 }
859
860 void (*psxBSC[64])() = {
861         psxSPECIAL, psxREGIMM, psxJ   , psxJAL  , psxBEQ , psxBNE , psxBLEZ, psxBGTZ,
862         psxADDI   , psxADDIU , psxSLTI, psxSLTIU, psxANDI, psxORI , psxXORI, psxLUI ,
863         psxCOP0   , psxNULL  , psxCOP2, psxNULL , psxNULL, psxNULL, psxNULL, psxNULL,
864         psxNULL   , psxNULL  , psxNULL, psxNULL , psxNULL, psxNULL, psxNULL, psxNULL,
865         psxLB     , psxLH    , psxLWL , psxLW   , psxLBU , psxLHU , psxLWR , psxNULL,
866         psxSB     , psxSH    , psxSWL , psxSW   , psxNULL, psxNULL, psxSWR , psxNULL, 
867         psxNULL   , psxNULL  , gteLWC2, psxNULL , psxNULL, psxNULL, psxNULL, psxNULL,
868         psxNULL   , psxNULL  , gteSWC2, psxHLE  , psxNULL, psxNULL, psxNULL, psxNULL 
869 };
870
871
872 void (*psxSPC[64])() = {
873         psxSLL , psxNULL , psxSRL , psxSRA , psxSLLV   , psxNULL , psxSRLV, psxSRAV,
874         psxJR  , psxJALR , psxNULL, psxNULL, psxSYSCALL, psxBREAK, psxNULL, psxNULL,
875         psxMFHI, psxMTHI , psxMFLO, psxMTLO, psxNULL   , psxNULL , psxNULL, psxNULL,
876         psxMULT, psxMULTU, psxDIV , psxDIVU, psxNULL   , psxNULL , psxNULL, psxNULL,
877         psxADD , psxADDU , psxSUB , psxSUBU, psxAND    , psxOR   , psxXOR , psxNOR ,
878         psxNULL, psxNULL , psxSLT , psxSLTU, psxNULL   , psxNULL , psxNULL, psxNULL,
879         psxNULL, psxNULL , psxNULL, psxNULL, psxNULL   , psxNULL , psxNULL, psxNULL,
880         psxNULL, psxNULL , psxNULL, psxNULL, psxNULL   , psxNULL , psxNULL, psxNULL
881 };
882
883 void (*psxREG[32])() = {
884         psxBLTZ  , psxBGEZ  , psxNULL, psxNULL, psxNULL, psxNULL, psxNULL, psxNULL,
885         psxNULL  , psxNULL  , psxNULL, psxNULL, psxNULL, psxNULL, psxNULL, psxNULL,
886         psxBLTZAL, psxBGEZAL, psxNULL, psxNULL, psxNULL, psxNULL, psxNULL, psxNULL,
887         psxNULL  , psxNULL  , psxNULL, psxNULL, psxNULL, psxNULL, psxNULL, psxNULL
888 };
889
890 void (*psxCP0[32])() = {
891         psxMFC0, psxNULL, psxCFC0, psxNULL, psxMTC0, psxNULL, psxCTC0, psxNULL,
892         psxNULL, psxNULL, psxNULL, psxNULL, psxNULL, psxNULL, psxNULL, psxNULL,
893         psxRFE , psxNULL, psxNULL, psxNULL, psxNULL, psxNULL, psxNULL, psxNULL,
894         psxNULL, psxNULL, psxNULL, psxNULL, psxNULL, psxNULL, psxNULL, psxNULL
895 };
896
897 void (*psxCP2[64])(struct psxCP2Regs *regs) = {
898         psxBASIC, gteRTPS , psxNULL , psxNULL, psxNULL, psxNULL , gteNCLIP, psxNULL, // 00
899         psxNULL , psxNULL , psxNULL , psxNULL, gteOP  , psxNULL , psxNULL , psxNULL, // 08
900         gteDPCS , gteINTPL, gteMVMVA, gteNCDS, gteCDP , psxNULL , gteNCDT , psxNULL, // 10
901         psxNULL , psxNULL , psxNULL , gteNCCS, gteCC  , psxNULL , gteNCS  , psxNULL, // 18
902         gteNCT  , psxNULL , psxNULL , psxNULL, psxNULL, psxNULL , psxNULL , psxNULL, // 20
903         gteSQR  , gteDCPL , gteDPCT , psxNULL, psxNULL, gteAVSZ3, gteAVSZ4, psxNULL, // 28 
904         gteRTPT , psxNULL , psxNULL , psxNULL, psxNULL, psxNULL , psxNULL , psxNULL, // 30
905         psxNULL , psxNULL , psxNULL , psxNULL, psxNULL, gteGPF  , gteGPL  , gteNCCT  // 38
906 };
907
908 void (*psxCP2BSC[32])() = {
909         gteMFC2, psxNULL, gteCFC2, psxNULL, gteMTC2, psxNULL, gteCTC2, psxNULL,
910         psxNULL, psxNULL, psxNULL, psxNULL, psxNULL, psxNULL, psxNULL, psxNULL,
911         psxNULL, psxNULL, psxNULL, psxNULL, psxNULL, psxNULL, psxNULL, psxNULL,
912         psxNULL, psxNULL, psxNULL, psxNULL, psxNULL, psxNULL, psxNULL, psxNULL
913 };
914
915
916 ///////////////////////////////////////////
917
918 static int intInit() {
919         return 0;
920 }
921
922 static void intReset() {
923 }
924
925 void intExecute() {
926         extern int stop;
927         for (;!stop;) 
928                 execI();
929 }
930
931 void intExecuteBlock() {
932         branch2 = 0;
933         while (!branch2) execI();
934 }
935
936 static void intClear(u32 Addr, u32 Size) {
937 }
938
939 static void intShutdown() {
940 }
941
942 // interpreter execution
943 void execI() {
944         u32 *code = (u32 *)PSXM(psxRegs.pc);
945         psxRegs.code = ((code == NULL) ? 0 : SWAP32(*code));
946
947         debugI();
948
949         if (Config.Debug) ProcessDebug();
950
951         psxRegs.pc += 4;
952         psxRegs.cycle += BIAS;
953
954         psxBSC[psxRegs.code >> 26]();
955 }
956
957 R3000Acpu psxInt = {
958         intInit,
959         intReset,
960         intExecute,
961         intExecuteBlock,
962         intClear,
963         intShutdown
964 };