Create Xref-Html Frames                    Remove All Frames
file:/home/jivera/wd/pcsx/PsxInterpreter.c        (Tue Nov 25 22:46:14 2003 )


   1: /*  Pcsx - Pc Psx Emulator
   2:  *  Copyright (C) 1999-2003  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 Free Software
  16:  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  17:  */
  18: 
  19: #include <stdlib.h>
  20: 
  21: #include "PsxCommon.h"
  22: 
  23: #ifdef _MSC_VER_
  24: #pragma warning(disable:4018)
  25: #endif
  26: 
  27: static int branch = 0;
  28: static int branch2 = 0;
  29: static u32 branchPC;
  30: 
  31: // These macros are used to assemble the repassembler functions
  32: 
  33: #ifdef PSXCPU_LOG
  34: #define debugI() \
  35:         if (Log) { \
  36:                 PSXCPU_LOG("%s\n", disR3000AF(psxRegs.code, psxRegs.pc)); \
  37:         }
  38: #else
  39: #define debugI()
  40: #endif
  41: 
  42: #define execI() { \
  43:         u32 *code = PSXM(psxRegs.pc); \
  44:         psxRegs.code = code == NULL ? 0 : *code; \
  45:  \
  46:         debugI(); \
  47:  \
  48:         psxRegs.pc+= 4; psxRegs.cycle++; \
  49:         psxBSC[psxRegs.code >> 26](); \
  50: }
  51: 
  52: // Subsets
  53: void (*psxBSC[64])();
  54: void (*psxSPC[64])();
  55: void (*psxREG[32])();
  56: void (*psxCP0[32])();
  57: void (*psxCP2[64])();
  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:         psxBranchTest();
  72: 
  73:         psxRegs.GPR.r[reg] = rold;
  74:         execI(); // first branch opcode
  75:         psxRegs.GPR.r[reg] = rnew;
  76: 
  77:         branch = 0;
  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 0x02:
 166:                                 case 0x10: case 0x12: // BLTZ/BGEZ...
 167:                                         if (_tRs_ == reg) return 2;
 168:                                         break;
 169:                         }
 170:                         break;
 171: 
 172:                 // J would be just a break;
 173:                 case 0x03: // JAL
 174:                         if (31 == reg) return 3;
 175:                         break;
 176: 
 177:                 case 0x04: case 0x05: // BEQ/BNE
 178:                         if (_tRs_ == reg || _tRt_ == reg) return 2;
 179:                         break;
 180: 
 181:                 case 0x06: case 0x07: // BLEZ/BGTZ
 182:                         if (_tRs_ == reg) return 2;
 183:                         break;
 184: 
 185:                 case 0x08: case 0x09: case 0x0a: case 0x0b:
 186:                 case 0x0c: case 0x0d: case 0x0e: // ADDI/ADDIU...
 187:                         if (_tRt_ == reg && _tRs_ == reg) return 1; else
 188:                         if (_tRs_ == reg) return 2; else
 189:                         if (_tRt_ == reg) return 3;
 190:                         break;
 191: 
 192:                 case 0x0f: // LUI
 193:                         if (_tRt_ == reg) return 3;
 194:                         break;
 195: 
 196:                 case 0x10: // COP0
 197:                         switch (_tFunct_) {
 198:                                 case 0x00: // MFC0
 199:                                         if (_tRt_ == reg) return 3;
 200:                                         break;
 201:                                 case 0x02: // CFC0
 202:                                         if (_tRt_ == reg) return 3;
 203:                                         break;
 204:                                 case 0x04: // MTC0
 205:                                         if (_tRt_ == reg) return 2;
 206:                                         break;
 207:                                 case 0x06: // CTC0
 208:                                         if (_tRt_ == reg) return 2;
 209:                                         break;
 210:                                 // RFE just a break;
 211:                         }
 212:                         break;
 213: 
 214:                 case 0x12: // COP2
 215:                         switch (_tFunct_) {
 216:                                 case 0x00: 
 217:                                         switch (_tRs_) {
 218:                                                 case 0x00: // MFC2
 219:                                                         if (_tRt_ == reg) return 3;
 220:                                                         break;
 221:                                                 case 0x02: // CFC2
 222:                                                         if (_tRt_ == reg) return 3;
 223:                                                         break;
 224:                                                 case 0x04: // MTC2
 225:                                                         if (_tRt_ == reg) return 2;
 226:                                                         break;
 227:                                                 case 0x06: // CTC2
 228:                                                         if (_tRt_ == reg) return 2;
 229:                                                         break;
 230:                                         }
 231:                                         break;
 232:                                 // RTPS... break;
 233:                         }
 234:                         break;
 235: 
 236:                 case 0x22: case 0x26: // LWL/LWR
 237:                         if (_tRt_ == reg) return 3; else
 238:                         if (_tRs_ == reg) return 2;
 239:                         break;
 240: 
 241:                 case 0x20: case 0x21: case 0x23:
 242:                 case 0x24: case 0x25: // LB/LH/LW/LBU/LHU
 243:                         if (_tRt_ == reg && _tRs_ == reg) return 1; else
 244:                         if (_tRs_ == reg) return 2; else
 245:                         if (_tRt_ == reg) return 3;
 246:                         break;
 247: 
 248:                 case 0x28: case 0x29: case 0x2a:
 249:                 case 0x2b: case 0x2e: // SB/SH/SWL/SW/SWR
 250:                         if (_tRt_ == reg || _tRs_ == reg) return 2;
 251:                         break;
 252: 
 253:                 case 0x32: case 0x3a: // LWC2/SWC2
 254:                         if (_tRs_ == reg) return 2;
 255:                         break;
 256:         }
 257: 
 258:         return 0;
 259: }
 260: 
 261: void psxDelayTest(int reg, u32 bpc) {
 262:         u32 *code;
 263:         u32 tmp;
 264: 
 265:         code = PSXM(bpc);
 266:         tmp = code == NULL ? 0 : *code;
 267:         branch = 1;
 268: 
 269:         switch (psxTestLoadDelay(reg, tmp)) {
 270:                 case 1:
 271:                         delayReadWrite(reg, bpc); return;
 272:                 case 2:
 273:                         delayRead(reg, bpc); return;
 274:                 case 3:
 275:                         delayWrite(reg, bpc); return;
 276:         }
 277:         psxBSC[psxRegs.code >> 26]();
 278: 
 279:         branch = 0;
 280:         psxRegs.pc = bpc;
 281: 
 282:         psxBranchTest();
 283: }
 284: 
 285: __inline void doBranch(u32 tar) {
 286:         u32 *code;
 287:         u32 tmp;
 288: 
 289:         branch2 = branch = 1;
 290:         branchPC = tar;
 291: 
 292:         code = PSXM(psxRegs.pc);
 293:         psxRegs.code = code == NULL ? 0 : *code;
 294: 
 295:         debugI();
 296: 
 297:         psxRegs.pc+= 4; psxRegs.cycle++;
 298: 
 299:         // check for load delay
 300:         tmp = psxRegs.code >> 26;
 301:         switch (tmp) {
 302:                 case 0x10: // COP0
 303:                         switch (_Rs_) {
 304:                                 case 0x00: // MFC0
 305:                                 case 0x02: // CFC0
 306:                                         psxDelayTest(_Rt_, branchPC);
 307:                                         return;
 308:                         }
 309:                         break;
 310:                 case 0x12: // COP2
 311:                         switch (_Funct_) {
 312:                                 case 0x00:
 313:                                         switch (_Rs_) {
 314:                                                 case 0x00: // MFC2
 315:                                                 case 0x02: // CFC2
 316:                                                         psxDelayTest(_Rt_, branchPC);
 317:                                                         return;
 318:                                         }
 319:                                         break;
 320:                         }
 321:                         break;
 322:                 case 0x32: // LWC2
 323:                         psxDelayTest(_Rt_, branchPC);
 324:                         return;
 325:                 default:
 326:                         if (tmp >= 0x20 && tmp <= 0x26) { // LB/LH/LWL/LW/LBU/LHU/LWR
 327:                                 psxDelayTest(_Rt_, branchPC);
 328:                                 return;
 329:                         }
 330:                         break;
 331:         }
 332: 
 333:         psxBSC[psxRegs.code >> 26]();
 334: 
 335:         branch = 0;
 336:         psxRegs.pc = branchPC;
 337: 
 338:         psxBranchTest();
 339: }
 340: 
 341: /*********************************************************
 342: * Arithmetic with immediate operand                      *
 343: * Format:  OP rt, rs, immediate                          *
 344: *********************************************************/
 345: void psxADDI()  { if (!_Rt_) return; _rRt_ = _u32(_rRs_) + _Imm_ ; }            // Rt = Rs + Im         (Exception on Integer Overflow)
 346: void psxADDIU() { if (!_Rt_) return; _rRt_ = _u32(_rRs_) + _Imm_ ; }            // Rt = Rs + Im
 347: void psxANDI()  { if (!_Rt_) return; _rRt_ = _u32(_rRs_) & _ImmU_; }            // Rt = Rs And Im
 348: void psxORI()   { if (!_Rt_) return; _rRt_ = _u32(_rRs_) | _ImmU_; }            // Rt = Rs Or  Im
 349: void psxXORI()  { if (!_Rt_) return; _rRt_ = _u32(_rRs_) ^ _ImmU_; }            // Rt = Rs Xor Im
 350: void psxSLTI()  { if (!_Rt_) return; _rRt_ = _i32(_rRs_) < _Imm_ ; }            // Rt = Rs < Im         (Signed)
 351: void psxSLTIU() { if (!_Rt_) return; _rRt_ = _u32(_rRs_) < ((u32)_Imm_); }              // Rt = Rs < Im         (Unsigned)
 352: 
 353: /*********************************************************
 354: * Register arithmetic                                    *
 355: * Format:  OP rd, rs, rt                                 *
 356: *********************************************************/
 357: void psxADD()   { if (!_Rd_) return; _rRd_ = _u32(_rRs_) + _u32(_rRt_); }       // Rd = Rs + Rt         (Exception on Integer Overflow)
 358: void psxADDU()  { if (!_Rd_) return; _rRd_ = _u32(_rRs_) + _u32(_rRt_); }       // Rd = Rs + Rt
 359: void psxSUB()   { if (!_Rd_) return; _rRd_ = _u32(_rRs_) - _u32(_rRt_); }       // Rd = Rs - Rt         (Exception on Integer Overflow)
 360: void psxSUBU()  { if (!_Rd_) return; _rRd_ = _u32(_rRs_) - _u32(_rRt_); }       // Rd = Rs - Rt
 361: void psxAND()   { if (!_Rd_) return; _rRd_ = _u32(_rRs_) & _u32(_rRt_); }       // Rd = Rs And Rt
 362: void psxOR()    { if (!_Rd_) return; _rRd_ = _u32(_rRs_) | _u32(_rRt_); }       // Rd = Rs Or  Rt
 363: void psxXOR()   { if (!_Rd_) return; _rRd_ = _u32(_rRs_) ^ _u32(_rRt_); }       // Rd = Rs Xor Rt
 364: void psxNOR()   { if (!_Rd_) return; _rRd_ =~(_u32(_rRs_) | _u32(_rRt_)); }// Rd = Rs Nor Rt
 365: void psxSLT()   { if (!_Rd_) return; _rRd_ = _i32(_rRs_) < _i32(_rRt_); }       // Rd = Rs < Rt         (Signed)
 366: void psxSLTU()  { if (!_Rd_) return; _rRd_ = _u32(_rRs_) < _u32(_rRt_); }       // Rd = Rs < Rt         (Unsigned)
 367: 
 368: /*********************************************************
 369: * Register mult/div & Register trap logic                *
 370: * Format:  OP rs, rt                                     *
 371: *********************************************************/
 372: void psxDIV() {
 373:         if (_i32(_rRt_) != 0) {
 374:                 _i32(_rLo_) = _i32(_rRs_) / _i32(_rRt_);
 375:                 _i32(_rHi_) = _i32(_rRs_) % _i32(_rRt_);
 376:         }
 377: }
 378: 
 379: void psxDIVU() {
 380:         if (_rRt_ != 0) {
 381:                 _rLo_ = _rRs_ / _rRt_;
 382:                 _rHi_ = _rRs_ % _rRt_;
 383:         }
 384: }
 385: 
 386: void psxMULT() {
 387:         u64 res = (s64)((s64)_i32(_rRs_) * (s64)_i32(_rRt_));
 388: 
 389:         psxRegs.GPR.n.lo = (unsigned long)(res & 0xffffffff);
 390:         psxRegs.GPR.n.hi = (unsigned long)((res >> 32) & 0xffffffff);
 391: }
 392: 
 393: void psxMULTU() {
 394:         u64 res = (u64)((u64)_u32(_rRs_) * (u64)_u32(_rRt_));
 395: 
 396:         psxRegs.GPR.n.lo = (unsigned long)(res & 0xffffffff);
 397:         psxRegs.GPR.n.hi = (unsigned long)((res >> 32) & 0xffffffff);
 398: }
 399: 
 400: /*********************************************************
 401: * Register branch logic                                  *
 402: * Format:  OP rs, offset                                 *
 403: *********************************************************/
 404: #define RepZBranchi32(op)      if(_i32(_rRs_) op 0) doBranch(_BranchTarget_);
 405: #define RepZBranchLinki32(op)  if(_i32(_rRs_) op 0) { _SetLink(31); doBranch(_BranchTarget_); }
 406: 
 407: void psxBGEZ()   { RepZBranchi32(>=) }      // Branch if Rs >= 0
 408: void psxBGEZAL() { RepZBranchLinki32(>=) }  // Branch if Rs >= 0 and link
 409: void psxBGTZ()   { RepZBranchi32(>) }       // Branch if Rs >  0
 410: void psxBLEZ()   { RepZBranchi32(<=) }      // Branch if Rs <= 0
 411: void psxBLTZ()   { RepZBranchi32(<) }       // Branch if Rs <  0
 412: void psxBLTZAL() { RepZBranchLinki32(<) }   // Branch if Rs <  0 and link
 413: 
 414: /*********************************************************
 415: * Shift arithmetic with constant shift                   *
 416: * Format:  OP rd, rt, sa                                 *
 417: *********************************************************/
 418: void psxSLL() { if (!_Rd_) return; _u32(_rRd_) = _u32(_rRt_) << _Sa_; } // Rd = Rt << sa
 419: void psxSRA() { if (!_Rd_) return; _i32(_rRd_) = _i32(_rRt_) >> _Sa_; } // Rd = Rt >> sa (arithmetic)
 420: void psxSRL() { if (!_Rd_) return; _u32(_rRd_) = _u32(_rRt_) >> _Sa_; } // Rd = Rt >> sa (logical)
 421: 
 422: /*********************************************************
 423: * Shift arithmetic with variant register shift           *
 424: * Format:  OP rd, rt, rs                                 *
 425: *********************************************************/
 426: void psxSLLV() { if (!_Rd_) return; _u32(_rRd_) = _u32(_rRt_) << _u32(_rRs_); } // Rd = Rt << rs
 427: void psxSRAV() { if (!_Rd_) return; _i32(_rRd_) = _i32(_rRt_) >> _u32(_rRs_); } // Rd = Rt >> rs (arithmetic)
 428: void psxSRLV() { if (!_Rd_) return; _u32(_rRd_) = _u32(_rRt_) >> _u32(_rRs_); } // Rd = Rt >> rs (logical)
 429: 
 430: /*********************************************************
 431: * Load higher 16 bits of the first word in GPR with imm  *
 432: * Format:  OP rt, immediate                              *
 433: *********************************************************/
 434: void psxLUI() { if (!_Rt_) return; _u32(_rRt_) = psxRegs.code << 16; } // Upper halfword of Rt = Im
 435: 
 436: /*********************************************************
 437: * Move from HI/LO to GPR                                 *
 438: * Format:  OP rd                                         *
 439: *********************************************************/
 440: void psxMFHI() { if (!_Rd_) return; _rRd_ = _rHi_; } // Rd = Hi
 441: void psxMFLO() { if (!_Rd_) return; _rRd_ = _rLo_; } // Rd = Lo
 442: 
 443: /*********************************************************
 444: * Move to GPR to HI/LO & Register jump                   *
 445: * Format:  OP rs                                         *
 446: *********************************************************/
 447: void psxMTHI() { _rHi_ = _rRs_; } // Hi = Rs
 448: void psxMTLO() { _rLo_ = _rRs_; } // Lo = Rs
 449: 
 450: /*********************************************************
 451: * Special purpose instructions                           *
 452: * Format:  OP                                            *
 453: *********************************************************/
 454: void psxBREAK() {
 455:         // Break exception - psx rom doens't handles this
 456: }
 457: 
 458: void psxSYSCALL() {
 459:         psxRegs.pc -= 4;
 460:         psxException(0x20, branch);
 461: }
 462: 
 463: void psxRFE() {
 464: //      SysPrintf("psxRFE\n");
 465:         psxRegs.CP0.n.Status = (psxRegs.CP0.n.Status & 0xfffffff0) |
 466:                                                   ((psxRegs.CP0.n.Status & 0x3c) >> 2);
 467: }
 468: 
 469: /*********************************************************
 470: * Register branch logic                                  *
 471: * Format:  OP rs, rt, offset                             *
 472: *********************************************************/
 473: #define RepBranchi32(op)      if(_i32(_rRs_) op _i32(_rRt_)) doBranch(_BranchTarget_);
 474: 
 475: void psxBEQ() { RepBranchi32(==) }  // Branch if Rs == Rt
 476: void psxBNE() { RepBranchi32(!=) }  // Branch if Rs != Rt
 477: 
 478: /*********************************************************
 479: * Jump to target                                         *
 480: * Format:  OP target                                     *
 481: *********************************************************/
 482: void psxJ()   {               doBranch(_JumpTarget_); }
 483: void psxJAL() { _SetLink(31); doBranch(_JumpTarget_); }
 484: 
 485: /*********************************************************
 486: * Register jump                                          *
 487: * Format:  OP rs, rd                                     *
 488: *********************************************************/
 489: void psxJR()   {
 490:         doBranch(_u32(_rRs_));
 491:         psxJumpTest();
 492: }
 493: 
 494: void psxJALR() {
 495:         u32 temp = _u32(_rRs_);
 496:         if (_Rd_) { _SetLink(_Rd_); }
 497:         doBranch(temp);
 498: }
 499: 
 500: /*********************************************************
 501: * Load and store for GPR                                 *
 502: * Format:  OP rt, offset(base)                           *
 503: *********************************************************/
 504: 
 505: #define _oB_ (_u32(_rRs_) + _Imm_)
 506: 
 507: void psxLB() {
 508:         if (_Rt_) {
 509:                 _i32(_rRt_) = (char)psxMemRead8(_oB_); 
 510:         } else {
 511:                 psxMemRead8(_oB_); 
 512:         }
 513: }
 514: 
 515: void psxLBU() {
 516:         if (_Rt_) {
 517:                 _u32(_rRt_) = psxMemRead8(_oB_);
 518:         } else {
 519:                 psxMemRead8(_oB_); 
 520:         }
 521: }
 522: 
 523: void psxLH() {
 524:         if (_Rt_) {
 525:                 _i32(_rRt_) = (short)psxMemRead16(_oB_);
 526:         } else {
 527:                 psxMemRead16(_oB_);
 528:         }
 529: }
 530: 
 531: void psxLHU() {
 532:         if (_Rt_) {
 533:                 _u32(_rRt_) = psxMemRead16(_oB_);
 534:         } else {
 535:                 psxMemRead16(_oB_);
 536:         }
 537: }
 538: 
 539: void psxLW() {
 540:         if (_Rt_) {
 541:                 _u32(_rRt_) = psxMemRead32(_oB_);
 542:         } else {
 543:                 psxMemRead32(_oB_);
 544:         }
 545: }
 546: 
 547: u32 LWL_MASK[4] = { 0xffffff, 0xffff, 0xff, 0 };
 548: u32 LWL_SHIFT[4] = { 24, 16, 8, 0 };
 549: 
 550: void psxLWL() {
 551:         u32 addr = _oB_;
 552:         u32 shift = addr & 3;
 553:         u32 mem = psxMemRead32(addr & ~3);
 554: 
 555:         if (!_Rt_) return;
 556:         _u32(_rRt_) =   ( _u32(_rRt_) & LWL_MASK[shift]) | 
 557:                                         ( mem << LWL_SHIFT[shift]);
 558: 
 559:         /*
 560:         Mem = 1234.  Reg = abcd
 561: 
 562:         0   4bcd   (mem << 24) | (reg & 0x00ffffff)
 563:         1   34cd   (mem << 16) | (reg & 0x0000ffff)
 564:         2   234d   (mem <<  8) | (reg & 0x000000ff)
 565:         3   1234   (mem      ) | (reg & 0x00000000)
 566:         */
 567: }
 568: 
 569: u32 LWR_MASK[4] = { 0, 0xff000000, 0xffff0000, 0xffffff00 };
 570: u32 LWR_SHIFT[4] = { 0, 8, 16, 24 };
 571: 
 572: void psxLWR() {
 573:         u32 addr = _oB_;
 574:         u32 shift = addr & 3;
 575:         u32 mem = psxMemRead32(addr & ~3);
 576: 
 577:         if (!_Rt_) return;
 578:         _u32(_rRt_) =   ( _u32(_rRt_) & LWR_MASK[shift]) | 
 579:                                         ( mem >> LWR_SHIFT[shift]);
 580: 
 581:         /*
 582:         Mem = 1234.  Reg = abcd
 583: 
 584:         0   1234   (mem      ) | (reg & 0x00000000)
 585:         1   a123   (mem >>  8) | (reg & 0xff000000)
 586:         2   ab12   (mem >> 16) | (reg & 0xffff0000)
 587:         3   abc1   (mem >> 24) | (reg & 0xffffff00)
 588:         */
 589: }
 590: 
 591: void psxSB() { psxMemWrite8 (_oB_, _u8 (_rRt_)); }
 592: void psxSH() { psxMemWrite16(_oB_, _u16(_rRt_)); }
 593: void psxSW() { psxMemWrite32(_oB_, _u32(_rRt_)); }
 594: 
 595: u32 SWL_MASK[4] = { 0xffffff00, 0xffff0000, 0xff000000, 0 };
 596: u32 SWL_SHIFT[4] = { 24, 16, 8, 0 };
 597: 
 598: void psxSWL() {
 599:         u32 addr = _oB_;
 600:         u32 shift = addr & 3;
 601:         u32 mem = psxMemRead32(addr & ~3);
 602: 
 603:         psxMemWrite32(addr & ~3,  (_u32(_rRt_) >> SWL_SHIFT[shift]) |
 604:                              (  mem & SWL_MASK[shift]) );
 605:         /*
 606:         Mem = 1234.  Reg = abcd
 607: 
 608:         0   123a   (reg >> 24) | (mem & 0xffffff00)
 609:         1   12ab   (reg >> 16) | (mem & 0xffff0000)
 610:         2   1abc   (reg >>  8) | (mem & 0xff000000)
 611:         3   abcd   (reg      ) | (mem & 0x00000000)
 612:         */
 613: }
 614: 
 615: u32 SWR_MASK[4] = { 0, 0xff, 0xffff, 0xffffff };
 616: u32 SWR_SHIFT[4] = { 0, 8, 16, 24 };
 617: 
 618: void psxSWR() {
 619:         u32 addr = _oB_;
 620:         u32 shift = addr & 3;
 621:         u32 mem = psxMemRead32(addr & ~3);
 622: 
 623:         psxMemWrite32(addr & ~3,  (_u32(_rRt_) << SWR_SHIFT[shift]) |
 624:                              (  mem & SWR_MASK[shift]) );
 625: 
 626:         /*
 627:         Mem = 1234.  Reg = abcd
 628: 
 629:         0   abcd   (reg      ) | (mem & 0x00000000)
 630:         1   bcd4   (reg <<  8) | (mem & 0x000000ff)
 631:         2   cd34   (reg << 16) | (mem & 0x0000ffff)
 632:         3   d234   (reg << 24) | (mem & 0x00ffffff)
 633:         */
 634: }
 635: 
 636: /*********************************************************
 637: * Moves between GPR and COPx                             *
 638: * Format:  OP rt, fs                                     *
 639: *********************************************************/
 640: void psxMFC0() { if (!_Rt_) return; _i32(_rRt_) = (int)_rFs_; }
 641: void psxCFC0() { if (!_Rt_) return; _i32(_rRt_) = (int)_rFs_; }
 642: 
 643: void psxTestSWInts() {
 644:         // the next code is untested, if u know please
 645:         // tell me if it works ok or not (linuzappz)
 646:         if (psxRegs.CP0.n.Cause & psxRegs.CP0.n.Status & 0x0300 &&
 647:                 psxRegs.CP0.n.Status & 0x1) {
 648:                 psxException(psxRegs.CP0.n.Cause, branch);
 649:         }
 650: }
 651: 
 652: __inline void MTC0(int reg, u32 val) {
 653: //      SysPrintf("MTC0 %d: %x\n", reg, val);
 654:         switch (reg) {
 655:                 case 12: // Status
 656:                         psxRegs.CP0.r[12] = val;
 657:                         psxTestSWInts();
 658:                         psxRegs.interrupt|= 0x80000000;
 659:                         break;
 660: 
 661:                 case 13: // Cause
 662:                         psxRegs.CP0.n.Cause = val & ~(0xfc00);
 663:                         psxTestSWInts();
 664:                         break;
 665: 
 666:                 default:
 667:                         psxRegs.CP0.r[reg] = val;
 668:                         break;
 669:         }
 670: }
 671: 
 672: void psxMTC0() { MTC0(_Rd_, _u32(_rRt_)); }
 673: void psxCTC0() { MTC0(_Rd_, _u32(_rRt_)); }
 674: 
 675: /*********************************************************
 676: * Unknow instruction (would generate an exception)       *
 677: * Format:  ?                                             *
 678: *********************************************************/
 679: void psxNULL() { 
 680: #ifdef PSXCPU_LOG
 681:         PSXCPU_LOG("psx: Unimplemented op %x\n", psxRegs.code);
 682: #endif
 683: }
 684: 
 685: void psxSPECIAL() {
 686:         psxSPC[_Funct_]();
 687: }
 688: 
 689: void psxREGIMM() {
 690:         psxREG[_Rt_]();
 691: }
 692: 
 693: void psxCOP0() {
 694:         psxCP0[_Rs_]();
 695: }
 696: 
 697: void psxCOP2() {
 698:         psxCP2[_Funct_]();
 699: }
 700: 
 701: void psxBASIC() {
 702:         psxCP2BSC[_Rs_]();
 703: }
 704: 
 705: void psxHLE() {
 706:         psxHLEt[psxRegs.code & 0xffff]();
 707: }
 708: 
 709: void (*psxBSC[64])() = {
 710:         psxSPECIAL, psxREGIMM, psxJ   , psxJAL  , psxBEQ , psxBNE , psxBLEZ, psxBGTZ,
 711:         psxADDI   , psxADDIU , psxSLTI, psxSLTIU, psxANDI, psxORI , psxXORI, psxLUI ,
 712:         psxCOP0   , psxNULL  , psxCOP2, psxNULL , psxNULL, psxNULL, psxNULL, psxNULL,
 713:         psxNULL   , psxNULL  , psxNULL, psxNULL , psxNULL, psxNULL, psxNULL, psxNULL,
 714:         psxLB     , psxLH    , psxLWL , psxLW   , psxLBU , psxLHU , psxLWR , psxNULL,
 715:         psxSB     , psxSH    , psxSWL , psxSW   , psxNULL, psxNULL, psxSWR , psxNULL, 
 716:         psxNULL   , psxNULL  , gteLWC2, psxNULL , psxNULL, psxNULL, psxNULL, psxNULL,
 717:         psxNULL   , psxNULL  , gteSWC2, psxHLE  , psxNULL, psxNULL, psxNULL, psxNULL 
 718: };
 719: 
 720: 
 721: void (*psxSPC[64])() = {
 722:         psxSLL , psxNULL , psxSRL , psxSRA , psxSLLV   , psxNULL , psxSRLV, psxSRAV,
 723:         psxJR  , psxJALR , psxNULL, psxNULL, psxSYSCALL, psxBREAK, psxNULL, psxNULL,
 724:         psxMFHI, psxMTHI , psxMFLO, psxMTLO, psxNULL   , psxNULL , psxNULL, psxNULL,
 725:         psxMULT, psxMULTU, psxDIV , psxDIVU, psxNULL   , psxNULL , psxNULL, psxNULL,
 726:         psxADD , psxADDU , psxSUB , psxSUBU, psxAND    , psxOR   , psxXOR , psxNOR ,
 727:         psxNULL, psxNULL , psxSLT , psxSLTU, psxNULL   , psxNULL , psxNULL, psxNULL,
 728:         psxNULL, psxNULL , psxNULL, psxNULL, psxNULL   , psxNULL , psxNULL, psxNULL,
 729:         psxNULL, psxNULL , psxNULL, psxNULL, psxNULL   , psxNULL , psxNULL, psxNULL
 730: };
 731: 
 732: void (*psxREG[32])() = {
 733:         psxBLTZ  , psxBGEZ  , psxNULL, psxNULL, psxNULL, psxNULL, psxNULL, psxNULL,
 734:         psxNULL  , psxNULL  , psxNULL, psxNULL, psxNULL, psxNULL, psxNULL, psxNULL,
 735:         psxBLTZAL, psxBGEZAL, psxNULL, psxNULL, psxNULL, psxNULL, psxNULL, psxNULL,
 736:         psxNULL  , psxNULL  , psxNULL, psxNULL, psxNULL, psxNULL, psxNULL, psxNULL
 737: };
 738: 
 739: void (*psxCP0[32])() = {
 740:         psxMFC0, psxNULL, psxCFC0, psxNULL, psxMTC0, psxNULL, psxCTC0, psxNULL,
 741:         psxNULL, psxNULL, psxNULL, psxNULL, psxNULL, psxNULL, psxNULL, psxNULL,
 742:         psxRFE , psxNULL, psxNULL, psxNULL, psxNULL, psxNULL, psxNULL, psxNULL,
 743:         psxNULL, psxNULL, psxNULL, psxNULL, psxNULL, psxNULL, psxNULL, psxNULL
 744: };
 745: 
 746: void (*psxCP2[64])() = {
 747:         psxBASIC, gteRTPS , psxNULL , psxNULL, psxNULL, psxNULL , gteNCLIP, psxNULL, // 00
 748:         psxNULL , psxNULL , psxNULL , psxNULL, gteOP  , psxNULL , psxNULL , psxNULL, // 08
 749:         gteDPCS , gteINTPL, gteMVMVA, gteNCDS, gteCDP , psxNULL , gteNCDT , psxNULL, // 10
 750:         psxNULL , psxNULL , psxNULL , gteNCCS, gteCC  , psxNULL , gteNCS  , psxNULL, // 18
 751:         gteNCT  , psxNULL , psxNULL , psxNULL, psxNULL, psxNULL , psxNULL , psxNULL, // 20
 752:         gteSQR  , gteDCPL , gteDPCT , psxNULL, psxNULL, gteAVSZ3, gteAVSZ4, psxNULL, // 28 
 753:         gteRTPT , psxNULL , psxNULL , psxNULL, psxNULL, psxNULL , psxNULL , psxNULL, // 30
 754:         psxNULL , psxNULL , psxNULL , psxNULL, psxNULL, gteGPF  , gteGPL  , gteNCCT  // 38
 755: };
 756: 
 757: void (*psxCP2BSC[32])() = {
 758:         gteMFC2, psxNULL, gteCFC2, psxNULL, gteMTC2, psxNULL, gteCTC2, psxNULL,
 759:         psxNULL, psxNULL, psxNULL, psxNULL, psxNULL, psxNULL, psxNULL, psxNULL,
 760:         psxNULL, psxNULL, psxNULL, psxNULL, psxNULL, psxNULL, psxNULL, psxNULL,
 761:         psxNULL, psxNULL, psxNULL, psxNULL, psxNULL, psxNULL, psxNULL, psxNULL
 762: };
 763: 
 764: 
 765: ///////////////////////////////////////////
 766: 
 767: static int intInit() {
 768:         return 0;
 769: }
 770: 
 771: static void intReset() {
 772: }
 773: 
 774: static void intExecute() {
 775:         for (;;) execI();
 776: }
 777: 
 778: static void intExecuteBlock() {
 779:         branch2 = 0;
 780:         while (!branch2) execI();
 781: }
 782: 
 783: static void intClear(u32 Addr, u32 Size) {
 784: }
 785: 
 786: static void intShutdown() {
 787: }
 788: 
 789: R3000Acpu psxInt = {
 790:         intInit,
 791:         intReset,
 792:         intExecute,
 793:         intExecuteBlock,
 794:         intClear,
 795:         intShutdown
 796: };
 797: /* arch-tag: Matthew Dempsky Wed Oct 15 10:34:51 CST 2003 (PsxInterpreter.c)
 798:  */
 799: 








































Html form generated by Xrefactory version 1.6.4 on Fri Dec 12 20:52:56 2003
Trial version.